// ════════════════════════════════════════════════════════════════
// PEXXIE · app shell — router, collapsible rail, proactive Pex panel,
// topbar, command palette. Screens register into window.SCREENS.
// ════════════════════════════════════════════════════════════════
const { Icon, Spark, Pex, PXLogo, Avatar, Card, Btn, Pill, Label, Num, Toggle, Field, Tabs } = window;

window.SCREENS = window.SCREENS || {};
const AppCtx = React.createContext(null);
window.useApp = () => React.useContext(AppCtx);

// Navigation map ----------------------------------------------------
const NAV = [
  { group: 'Business', items: [
    { k: 'home',    icon: 'home',      label: 'Home' },
    { k: 'money',   icon: 'dollar',    label: 'Money' },
    { k: 'team',    icon: 'briefcase', label: 'Team' },
    { k: 'people',  icon: 'users',     label: 'People' },
    { k: 'website', icon: 'globe',     label: 'Website' },
  ]},
  { group: 'Workspace', items: [
    { k: 'mail',    icon: 'mail',      label: 'Email',    badge: 3 },
    { k: 'calendar',icon: 'calendar',  label: 'Calendar' },
    { k: 'files',   icon: 'folder',    label: 'Files' },
    { k: 'chat',    icon: 'message',   label: 'Chat',     badge: 2 },
  ]},
  { group: 'Grow', items: [
    { k: 'marketing',icon: 'megaphone', label: 'Marketing' },
    { k: 'catalog', icon: 'grid',      label: 'Catalog' },
    { k: 'insights',icon: 'barchart',  label: 'Insights' },
    { k: 'projects',icon: 'layers',    label: 'Projects' },
  ]},
  { group: 'Tools', items: [
    { k: 'signatures', icon: 'penTool',  label: 'Signatures' },
    { k: 'orders',      icon: 'package',  label: 'Orders' },
    { k: 'import',       icon: 'upload',   label: 'Import' },
  ]},
];
window.NAV = NAV;

// Sections that render their OWN secondary sidebar — entering one auto-collapses
// the primary rail to icons (active icon stays lit). Proper two-pane nav.
const SECONDARY = ['money', 'website', 'settings', 'people', 'team', 'mail', 'marketing', 'signatures', 'orders', 'import'];
window.SECONDARY = SECONDARY;

// Notification unread count — shared so the topbar bell dot and "Mark all read" agree.
window.PXNotif = window.makeStore({ unread: 5 });

// Full activity feed — the target for "View all activity" (was a dead-end).
window.SCREENS['activity'] = function Activity() {
  const P = window.PX; const { go } = window.useApp();
  const feed = [
    { icon: 'dollar', tone: 'sage', t: 'Lila Events paid Invoice #1025', s: '$1,850.00', when: '4 min ago', r: 'money/invoices' },
    { icon: 'sparkles', tone: 'spark', t: 'Pex finished the class email draft', s: 'Waiting for approval', when: '12 min ago', r: 'pex' },
    { icon: 'mail', tone: 'sky', t: 'Marc Lefèvre replied', s: 'Re: Invoice #1024', when: '41 min ago', r: 'mail' },
    { icon: 'alert', tone: 'rose', t: 'Invoice #1024 is 11 days overdue', s: 'Café Bleu · $1,420.00', when: '1 hr ago', r: 'money/invoices' },
    { icon: 'users', tone: 'amber', t: 'New lead from your website form', s: 'Wedding cake inquiry', when: '2 hr ago', r: 'people' },
    { icon: 'send', tone: 'sage', t: 'Invoice #1027 sent to BK Food Co-op', s: '$460.00', when: 'Yesterday', r: 'money/invoices' },
    { icon: 'refresh', tone: 'sky', t: 'Auto tax sweep · 18%', s: 'Operating → Tax reserve', when: 'Yesterday', r: 'money/transactions' },
    { icon: 'check', tone: 'sage', t: 'Reorder flour completed by Pex', s: '$340.00 · King Arthur', when: 'Wed', r: 'money/bills' },
  ];
  return (
    <window.Page title="Activity" sub="Everything happening across your business">
      <window.Card pad={0} style={{ maxWidth: 720 }}>
        {feed.map((n, i) => (
          <div key={i} onClick={() => go(n.r)} style={{ padding: '13px 18px', display: 'flex', gap: 12, alignItems: 'center', borderBottom: i < feed.length - 1 ? `1px solid ${P.line}` : 'none', cursor: 'pointer' }}
            onMouseEnter={e => e.currentTarget.style.background = P.hover} onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
            <div style={{ width: 32, height: 32, borderRadius: 8, background: P[n.tone + 'Tint'], color: P[n.tone], display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><window.Icon name={n.icon} size={16}/></div>
            <div style={{ flex: 1, minWidth: 0 }}><div style={{ fontSize: 13.5, color: P.ink, fontWeight: 500 }}>{n.t}</div><div style={{ fontSize: 11.5, color: P.ink3 }}>{n.s}</div></div>
            <span style={{ fontSize: 11, color: P.ink4, flexShrink: 0 }}>{n.when}</span>
          </div>
        ))}
      </window.Card>
    </window.Page>
  );
};

// ── Sidebar ────────────────────────────────────────────────────
function Sidebar() {
  const { route, go, collapsed, setCollapsed, railLocked, sparks, toast } = window.useApp();
  const top = route.split('/')[0];
  const P = window.PX;
  const W = collapsed ? 66 : 234;
  const [wsMenu, setWsMenu] = React.useState(false);
  const [ws, setWs] = React.useState('Honest Loaves');

  const Item = ({ it }) => {
    const on = top === it.k;
    return (
      <div onClick={() => go(it.k)} title={collapsed ? it.label : ''} style={{ display: 'flex', alignItems: 'center', gap: 11,
        padding: collapsed ? '9px 0' : '8px 10px', justifyContent: collapsed ? 'center' : 'flex-start',
        borderRadius: 9, margin: '1px 0', cursor: 'pointer', position: 'relative',
        background: on ? P.card : 'transparent', boxShadow: on ? P.shSm : 'none',
        border: `1px solid ${on ? P.line : 'transparent'}`,
        color: on ? P.ink : P.ink2, transition: 'background .12s' }}
        onMouseEnter={e => { if (!on) e.currentTarget.style.background = P.hover; }}
        onMouseLeave={e => { if (!on) e.currentTarget.style.background = 'transparent'; }}>
        <Icon name={it.icon} size={18} stroke={on ? 2 : 1.75} color={on ? P.spark : P.ink2}/>
        {!collapsed && <span style={{ flex: 1, fontSize: 13.5, fontWeight: on ? 600 : 500 }}>{it.label}</span>}
        {!collapsed && it.badge && <span style={{ fontSize: 10.5, fontWeight: 600, color: P.sparkDim, background: P.sparkTint, padding: '1px 6px', borderRadius: 999 }}>{it.badge}</span>}
        {collapsed && it.badge && <span style={{ position: 'absolute', top: 5, right: 12, width: 7, height: 7, borderRadius: 7, background: P.spark }}/>}
      </div>
    );
  };

  return (
    <aside style={{ flex: `0 0 ${W}px`, width: W, minWidth: W, maxWidth: W, background: P.sidebar, borderRight: `1px solid ${P.line}`, display: 'flex', flexDirection: 'column', transition: 'flex-basis .16s ease, width .16s ease', fontFamily: P.sans }}>
      {/* brand + workspace switcher */}
      <div style={{ padding: collapsed ? '14px 0' : '14px 14px 10px', display: 'flex', alignItems: 'center', justifyContent: collapsed ? 'center' : 'space-between' }}>
        {collapsed
          ? <svg width="26" height="26" viewBox="0 0 40 40"><rect x="2" y="2" width="36" height="36" rx="11" fill={P.spark}/><path d="M23 9 L11 23 H20 L18 32 L30 17 H22 Z" fill="#fff"/></svg>
          : <PXLogo size={21}/>}
        {!collapsed && <div onClick={() => setCollapsed(true)} style={{ cursor: 'pointer', color: P.ink3, padding: 3 }} title="Collapse"><Icon name="panelLeft" size={17}/></div>}
      </div>
      {collapsed && !railLocked && <div onClick={() => setCollapsed(false)} style={{ cursor: 'pointer', color: P.ink3, display: 'flex', justifyContent: 'center', padding: '2px 0 8px' }} title="Expand"><Icon name="panelLeft" size={17}/></div>}

      {/* workspace chip — distinct from white active tabs */}
      {!collapsed && (
        <div style={{ margin: '0 12px 8px', position: 'relative' }}>
          <div onClick={() => setWsMenu(v => !v)} style={{ padding: '8px 10px', background: P.hover, border: `1px solid ${P.lineStrong}`, borderRadius: 10, display: 'flex', alignItems: 'center', gap: 9, cursor: 'pointer' }}>
            <div style={{ width: 26, height: 26, borderRadius: 7, background: '#3A2A1C', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: P.serif, fontStyle: 'italic', color: '#F5D8A8', fontSize: 14, flexShrink: 0 }}>{ws.slice(0, 2).toLowerCase()}</div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 12.5, fontWeight: 600, color: P.ink, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{ws}</div>
              <div style={{ fontSize: 10.5, color: P.ink3 }}>Free plan</div>
            </div>
            <Icon name="chevD" size={14} color={P.ink3}/>
          </div>
          {wsMenu && (
            <div style={{ position: 'absolute', top: 46, left: 0, right: 0, background: P.card, border: `1px solid ${P.line}`, borderRadius: 10, boxShadow: P.shPop, zIndex: 60, overflow: 'hidden' }}>
              {['Honest Loaves', 'Loaves Wholesale Co.'].map(w => (
                <div key={w} onClick={() => { setWs(w); setWsMenu(false); if (w !== 'Honest Loaves') toast(`Switched to ${w}.`, { icon: 'check' }); }} style={{ padding: '9px 12px', fontSize: 12.5, color: P.ink, cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 8 }}
                  onMouseEnter={e => e.currentTarget.style.background = P.hover} onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
                  {ws === w && <Icon name="check" size={13} color={P.spark}/>}<span style={{ marginLeft: ws === w ? 0 : 21 }}>{w}</span>
                </div>
              ))}
              <div onClick={() => { setWsMenu(false); toast('Create a new workspace — setup would open here.', { icon: 'plus' }); }} style={{ padding: '9px 12px', fontSize: 12.5, color: P.spark, cursor: 'pointer', borderTop: `1px solid ${P.line}`, display: 'flex', alignItems: 'center', gap: 8 }}
                onMouseEnter={e => e.currentTarget.style.background = P.hover} onMouseLeave={e => e.currentTarget.style.background = 'transparent'}><Icon name="plus" size={13}/>New workspace</div>
            </div>
          )}
        </div>
      )}

      {/* nav groups */}
      <div style={{ flex: 1, overflow: 'auto', padding: collapsed ? '4px 12px' : '4px 12px' }}>
        {NAV.map((g, i) => (
          <div key={i} style={{ marginBottom: 12 }}>
            {!collapsed && <Label style={{ padding: '6px 10px 4px' }}>{g.group}</Label>}
            {collapsed && i > 0 && <div style={{ height: 1, background: P.line, margin: '8px 6px' }}/>}
            {g.items.map(it => <Item key={it.k} it={it}/>)}
          </div>
        ))}
      </div>

      {/* Sparks well */}
      <div style={{ padding: 12, borderTop: `1px solid ${P.line}` }}>
        {collapsed ? (
          <div onClick={() => go('settings/sparks')} title="Sparks" style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3, cursor: 'pointer' }}>
            <Spark size={18}/><span style={{ fontSize: 11, fontWeight: 700, color: P.ink }}>{sparks}</span>
          </div>
        ) : (
          <div style={{ background: P.card, border: `1px solid ${P.line}`, borderRadius: 11, padding: 11 }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
              <Label>Sparks</Label><Spark size={13}/>
            </div>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginTop: 3 }}>
              <Num size={24}>{sparks}</Num>
              <span style={{ fontSize: 10.5, color: P.ink3 }}>≈ 11 days</span>
            </div>
            <div style={{ height: 4, background: P.sunk, borderRadius: 4, margin: '8px 0', overflow: 'hidden' }}>
              <div style={{ width: '46%', height: '100%', background: P.spark }}/>
            </div>
            <Btn kind="primary" size="sm" full onClick={() => go('settings/sparks')}>Top up</Btn>
          </div>
        )}
      </div>

      {/* user */}
      <div onClick={() => go('settings/profile')} style={{ padding: collapsed ? '10px 0' : '10px 14px', borderTop: `1px solid ${P.line}`, display: 'flex', alignItems: 'center', gap: 10, cursor: 'pointer', justifyContent: collapsed ? 'center' : 'flex-start' }}>
        <Avatar name="Amara Okafor" size={28}/>
        {!collapsed && <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 12.5, fontWeight: 600, color: P.ink }}>Amara Okafor</div>
          <div style={{ fontSize: 10.5, color: P.ink3 }}>Owner</div>
        </div>}
        {!collapsed && <Icon name="settings" size={15} color={P.ink3}/>}
      </div>
    </aside>
  );
}

// ── Topbar ────────────────────────────────────────────────────
function Topbar() {
  const { route, go, openCmdK, pexOpen, setPexOpen, notifOpen, setNotifOpen, openOverlay, setBrand } = window.useApp();
  const P = window.PX;
  return (
    <header style={{ height: 54, borderBottom: `1px solid ${P.line}`, background: P.canvas, display: 'flex', alignItems: 'center', padding: '0 18px', gap: 12, flexShrink: 0, fontFamily: P.sans }}>
      {/* Mercury-style universal search — the primary topbar surface */}
      <div onClick={openCmdK} style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '8px 12px', background: P.card, border: `1px solid ${P.line}`, borderRadius: 10, color: P.ink3, fontSize: 13, cursor: 'pointer', width: 400, maxWidth: '42vw' }}>
        <Icon name="search" size={16}/><span style={{ flex: 1, minWidth: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>Search transactions, people, invoices… or ask Pex</span>
        <span style={{ fontSize: 10.5, background: P.sunk, padding: '1px 5px', borderRadius: 4, border: `1px solid ${P.line}`, flexShrink: 0 }}>⌘K</span>
      </div>
      <div style={{ flex: 1 }}/>
      <div onClick={() => openOverlay('create')} style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '7px 12px 7px 10px', background: P.spark, color: '#fff', borderRadius: 9, fontSize: 12.5, fontWeight: 500, cursor: 'pointer' }}>
        <Icon name="plus" size={15} color="#fff" stroke={2}/>Create
      </div>
      <div onClick={() => setBrand({ mode: window.PX_MODE === 'dark' ? 'light' : 'dark' })} title="Toggle light / dark" style={{ cursor: 'pointer', color: P.ink2, padding: 6 }}>
        <Icon name={window.PX_MODE === 'dark' ? 'sun' : 'moon'} size={18}/>
      </div>
      <div onClick={() => setNotifOpen(!notifOpen)} style={{ position: 'relative', cursor: 'pointer', color: P.ink2, padding: 6 }}>
        <Icon name="bell" size={18}/>
        {window.useStore(window.PXNotif).unread > 0 && <span style={{ position: 'absolute', top: 4, right: 5, width: 7, height: 7, borderRadius: 7, background: P.spark, border: `1.5px solid ${P.canvas}` }}/>}
      </div>
      <div onClick={() => setPexOpen(!pexOpen)} title="Toggle Pex" style={{ cursor: 'pointer', display: 'flex', alignItems: 'center', gap: 6, padding: '5px 9px 5px 5px', borderRadius: 999, border: `1px solid ${pexOpen ? P.sparkTint : P.line}`, background: pexOpen ? P.sparkWash : P.card }}>
        <Pex size={22}/><span style={{ fontSize: 12, fontWeight: 600, color: pexOpen ? P.sparkDim : P.ink2 }}>Pex</span>
      </div>
      {notifOpen && <NotifPanel/>}
    </header>
  );
}

function NotifPanel() {
  const { setNotifOpen, go, toast } = window.useApp(); const P = window.PX;
  const unread = window.useStore(window.PXNotif).unread;
  const items = [
    { icon: 'dollar', tone: 'sage', t: 'Lila Events paid Invoice #1025', s: '$1,850.00 · 4 min ago', r: 'money/invoices' },
    { icon: 'sparkles', tone: 'spark', t: 'Pex finished the class email draft', s: 'Waiting for your approval · 12 min ago', r: 'pex' },
    { icon: 'mail', tone: 'sky', t: 'Marc Lefèvre replied', s: 'Re: Invoice #1024 · 41 min ago', r: 'mail' },
    { icon: 'alert', tone: 'rose', t: 'Invoice #1024 is now 11 days overdue', s: 'Café Bleu · $1,420.00 · 1 hr ago', r: 'money/invoices' },
    { icon: 'users', tone: 'amber', t: 'New lead from your website form', s: '"Wedding cake inquiry" · 2 hr ago', r: 'people' },
  ];
  return (
    <div style={{ position: 'absolute', top: 50, right: 70, width: 360, background: P.card, border: `1px solid ${P.line}`, borderRadius: 14, boxShadow: P.shPop, zIndex: 60, overflow: 'hidden', fontFamily: P.sans }}>
      <div style={{ padding: '13px 16px', borderBottom: `1px solid ${P.line}`, display: 'flex', alignItems: 'center' }}>
        <span style={{ fontSize: 14, fontWeight: 600, color: P.ink, flex: 1 }}>Notifications{unread > 0 ? ` · ${unread}` : ''}</span>
        <span onClick={() => { window.PXNotif.set({ unread: 0 }); toast('All caught up.', { icon: 'check' }); }} style={{ fontSize: 12, color: unread > 0 ? P.spark : P.ink4, cursor: unread > 0 ? 'pointer' : 'default' }}>Mark all read</span>
      </div>
      {items.map((n, i) => (
        <div key={i} onClick={() => { setNotifOpen(false); go(n.r); }} style={{ padding: '11px 16px', display: 'flex', gap: 11, borderBottom: i < items.length - 1 ? `1px solid ${P.line}` : 'none', cursor: 'pointer' }}
          onMouseEnter={e => e.currentTarget.style.background = P.hover} onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
          <div style={{ width: 30, height: 30, borderRadius: 8, background: P[n.tone + 'Tint'], color: P[n.tone], display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}><Icon name={n.icon} size={15}/></div>
          <div style={{ flex: 1 }}>
            <div style={{ fontSize: 13, color: P.ink, lineHeight: 1.35 }}>{n.t}</div>
            <div style={{ fontSize: 11, color: P.ink3, marginTop: 2 }}>{n.s}</div>
          </div>
        </div>
      ))}
      <div style={{ padding: 10, textAlign: 'center' }}><span onClick={() => { setNotifOpen(false); go('activity'); }} style={{ fontSize: 12, color: P.spark, cursor: 'pointer' }}>View all activity</span></div>
    </div>
  );
}

// ── Proactive Pex panel (right) ─────────────────────────────────
function PexPanel() {
  const { go, sparks, setSparks, pexProposals, actProposal, openOverlay, isMobile } = window.useApp();
  const P = window.PX;
  const [mode, setMode] = React.useState('inbox');   // inbox | chat
  const [tab, setTab] = React.useState('today');
  const [draft, setDraft] = React.useState('');
  const [msgs, setMsgs] = React.useState([
    { who: 'pex', t: 'Morning, Amara. I worked through the weekend — there are 5 things waiting in your Inbox. Two are time-sensitive.', time: '6:40am' },
    { who: 'pex', t: 'Want me to start with the Café Bleu invoice? It\u2019s 11 days late and the draft is ready to send.', time: '6:41am' },
  ]);
  const scrollRef = React.useRef(null);
  const pending = pexProposals.filter(p => p.status === 'pending');
  const totalCost = pending.reduce((a, p) => a + p.cost, 0);
  const runs = window.useStore(window.PXPex).runs;
  const liveRuns = runs.filter(r => r.status !== 'done').map(window.pexRunView);
  const doneRuns = runs.filter(r => r.status === 'done').map(window.pexRunView);
  const demoDoing = [{ title: 'Café Bleu payment reminder', d: 'Sent 7:12am · Marc opened 7:14am', p: 100, done: true }, { title: 'March class email · drafting', d: 'Writing block 4 of 5', p: 64, done: false }];
  const doing = [...liveRuns, ...demoDoing];

  React.useEffect(() => { if (mode === 'chat' && scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight; }, [mode, msgs]);

  const send = () => {
    const v = draft.trim(); if (!v) return;
    setMode('chat');
    setMsgs(m => [...m, { who: 'you', t: v, time: 'now' }]);
    setDraft('');
    setTimeout(() => setMsgs(m => [...m, { who: 'pex', t: 'On it — I\u2019ll scope that, come back with a short plan and a Spark estimate in a moment.', time: 'now' }]), 650);
  };

  const Seg = ({ k, label, icon, badge }) => {
    const on = mode === k;
    return (
      <div onClick={() => setMode(k)} style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6, padding: '6px 0', borderRadius: 8, cursor: 'pointer',
        background: on ? P.card : 'transparent', boxShadow: on ? P.shSm : 'none', border: `1px solid ${on ? P.line : 'transparent'}`, transition: 'background .12s',
        fontSize: 12.5, fontWeight: 600, color: on ? P.ink : P.ink3 }}>
        <Icon name={icon} size={15} color={on ? P.spark : P.ink3}/>{label}
        {badge != null && badge > 0 && <span style={{ fontSize: 10, fontWeight: 700, color: on ? P.sparkDim : P.ink3, background: on ? P.sparkTint : P.sunk, padding: '0 6px', borderRadius: 999 }}>{badge}</span>}
      </div>
    );
  };

  return (
    <aside style={{ width: isMobile ? '100%' : 340, height: isMobile ? '100%' : 'auto', background: P.card, borderLeft: isMobile ? 'none' : `1px solid ${P.line}`, display: 'flex', flexDirection: 'column', flexShrink: 0, fontFamily: P.sans }}>
      <div style={{ padding: '14px 16px', borderBottom: `1px solid ${P.line}`, display: 'flex', alignItems: 'center', gap: 11 }}>
        <Pex size={34} glow/>
        <div style={{ flex: 1 }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: P.ink, display: 'flex', alignItems: 'center', gap: 6 }}>Pex <span style={{ width: 7, height: 7, borderRadius: 7, background: P.sage }}/></div>
          <div style={{ fontSize: 11, color: P.ink3 }}>Working since 6:40am · {sparks} ⚡</div>
        </div>
        <div onClick={() => { setMode('chat'); setMsgs([{ who: 'pex', t: 'Fresh chat. What do you want to get done?', time: 'now' }]); }} title="New chat" style={{ cursor: 'pointer', color: P.ink3, padding: 4 }}><Icon name="pencil" size={16}/></div>
        <div onClick={() => go('pex')} title="Open full view" style={{ cursor: 'pointer', color: P.ink3, padding: 4 }}><Icon name="ext" size={16}/></div>
      </div>

      <div style={{ padding: '11px 14px 0' }}>
        <div style={{ display: 'flex', gap: 4, background: P.sunk, borderRadius: 10, padding: 3 }}>
          <Seg k="inbox" label="Inbox" icon="inbox" badge={pending.length}/>
          <Seg k="chat" label="Chat" icon="message"/>
        </div>
      </div>

      {mode === 'inbox' && (
        <div style={{ padding: '8px 16px 0' }}>
          <Tabs tabs={[{ k: 'today', label: 'Proposals', count: pending.length }, { k: 'doing', label: 'In progress', count: doing.length }, { k: 'done', label: 'Done', count: doneRuns.length + 4 }]} active={tab} onChange={setTab}/>
        </div>
      )}

      <div ref={scrollRef} style={{ flex: 1, overflow: 'auto', padding: '12px 16px' }}>
        {mode === 'chat' && (
          <>
            {msgs.map((m, i) => m.who === 'pex' ? (
              <div key={i} style={{ display: 'flex', gap: 9, marginBottom: 12 }}>
                <Pex size={26}/>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ background: P.card, border: `1px solid ${P.line}`, padding: '9px 12px', borderRadius: '4px 12px 12px 12px', fontSize: 12.5, color: P.ink, lineHeight: 1.5 }}>{m.t}</div>
                  <div style={{ fontSize: 10, color: P.ink4, marginTop: 3 }}>Pex · {m.time}</div>
                </div>
              </div>
            ) : (
              <div key={i} style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 12 }}>
                <div style={{ maxWidth: '82%' }}>
                  <div style={{ background: P.sparkWash, border: `1px solid ${P.sparkTint}`, color: P.ink, padding: '9px 12px', borderRadius: '12px 4px 12px 12px', fontSize: 12.5, lineHeight: 1.5 }}>{m.t}</div>
                  <div style={{ fontSize: 10, color: P.ink4, marginTop: 3, textAlign: 'right' }}>You · {m.time}</div>
                </div>
              </div>
            ))}
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginTop: 4 }}>
              {['Chase Café Bleu', 'Draft the class email', 'What needs me today?'].map((s, i) => (
                <span key={i} onClick={() => { setMsgs(m => [...m, { who: 'you', t: s, time: 'now' }]); setTimeout(() => setMsgs(m => [...m, { who: 'pex', t: 'Got it — pulling that together now.', time: 'now' }]), 600); }} style={{ fontSize: 11.5, color: P.ink2, background: P.sunk, border: `1px solid ${P.line}`, padding: '5px 10px', borderRadius: 999, cursor: 'pointer' }}>{s}</span>
              ))}
            </div>
          </>
        )}
        {mode === 'inbox' && tab === 'today' && (
          <>
            <div style={{ fontSize: 12.5, color: P.ink2, lineHeight: 1.5, marginBottom: 12, padding: '10px 12px', background: P.sparkWash, borderRadius: 10, border: `1px solid ${P.sparkTint}` }}>
              Morning, Amara. I worked through the weekend — <b style={{ color: P.ink }}>{pending.length} things</b> are ready for you. Two are time-sensitive.
            </div>
            {pending.map(p => (
              <div key={p.id} style={{ border: `1px solid ${P.line}`, borderRadius: 12, padding: 12, marginBottom: 9, background: P.card }}>
                <div style={{ display: 'flex', alignItems: 'flex-start', gap: 8, marginBottom: 7 }}>
                  <div style={{ width: 3, alignSelf: 'stretch', minHeight: 28, background: P[p.tone], borderRadius: 3, flexShrink: 0 }}/>
                  <div style={{ flex: 1 }}>
                    <div style={{ display: 'flex', gap: 6, marginBottom: 4 }}>
                      <Pill tone={p.tone} style={{ fontSize: 10 }}>{p.tag}</Pill>
                      {p.urgent && <Pill tone="rose" style={{ fontSize: 10 }}>urgent</Pill>}
                    </div>
                    <div style={{ fontSize: 13, color: P.ink, fontWeight: 600, lineHeight: 1.35 }}>{p.title}</div>
                    <div style={{ fontSize: 11.5, color: P.ink3, marginTop: 3, lineHeight: 1.4 }}>{p.ctx}</div>
                  </div>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                  <Btn kind="primary" size="sm" onClick={() => actProposal(p.id, 'approved')}>Approve · {p.cost} ⚡</Btn>
                  <Btn kind="ghost" size="sm" onClick={() => actProposal(p.id, 'snoozed')}>Snooze</Btn>
                  <span onClick={() => openOverlay('proposalPreview', { proposal: p })} style={{ marginLeft: 'auto', fontSize: 11, color: P.spark, cursor: 'pointer', fontWeight: 500 }}>Preview</span>
                </div>
              </div>
            ))}
            {pending.length === 0 && <div style={{ textAlign: 'center', padding: 30, color: P.ink3, fontSize: 13 }}><Icon name="check" size={28} color={P.sage}/><div style={{ marginTop: 8 }}>All caught up. Nicely done.</div></div>}
            {pending.length > 0 && (
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '10px 12px', background: P.sunk, borderRadius: 10, marginTop: 4 }}>
                <span style={{ flex: 1, fontSize: 12, color: P.ink2 }}>Approve all · <b>{totalCost} ⚡</b></span>
                <Btn kind="spark" size="sm" onClick={() => pending.forEach(p => actProposal(p.id, 'approved'))}>Do it all</Btn>
              </div>
            )}
          </>
        )}
        {mode === 'inbox' && tab === 'doing' && (
          <>
            {doing.map((x, i) => (
              <div key={i} style={{ border: `1px solid ${P.line}`, borderRadius: 12, padding: 12, marginBottom: 9 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 7, marginBottom: 6 }}>
                  <span style={{ width: 8, height: 8, borderRadius: 8, background: x.p === 100 ? P.sage : P.spark }}/>
                  <span style={{ fontSize: 13, fontWeight: 600, color: P.ink, flex: 1 }}>{x.title}</span>
                  <span style={{ fontSize: 11, color: P.ink3 }}>{x.p}%</span>
                </div>
                <div style={{ height: 3, background: P.sunk, borderRadius: 3, overflow: 'hidden' }}><div style={{ width: x.p + '%', height: '100%', background: x.p === 100 ? P.sage : P.spark, transition: 'width .4s' }}/></div>
                <div style={{ fontSize: 11, color: P.ink3, marginTop: 6 }}>{x.d}</div>
                {x.steps && x.p < 100 && (
                  <div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 3 }}>
                    {x.steps.map((st, j) => (
                      <div key={j} style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 11, color: st.state === 'done' ? P.ink2 : P.ink4 }}>
                        <Icon name={st.state === 'done' ? 'check' : 'clock'} size={11} color={st.state === 'done' ? P.sage : P.ink4}/>{st.label}
                      </div>
                    ))}
                  </div>
                )}
              </div>
            ))}
          </>
        )}
        {mode === 'inbox' && tab === 'done' && (
          <>
            {[...doneRuns.map(r => ({ t: r.title, d: r.d, ic: 'sparkles' })), { t: 'Logo v3 · 3 directions', d: 'Fri · 5 ⚡', ic: 'penTool' }, { t: 'Q1 tax estimate', d: 'Thu · 2 ⚡', ic: 'receipt' }, { t: 'Instagram · 3 posts', d: 'Wed · 4 ⚡', ic: 'image' }, { t: 'Reorder flour', d: 'Wed · 1 ⚡', ic: 'truck' }].map((r, i, arr) => (
              <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 11, padding: '10px 0', borderBottom: i < 3 ? `1px solid ${P.line}` : 'none' }}>
                <div style={{ width: 30, height: 30, borderRadius: 8, background: P.sunk, display: 'flex', alignItems: 'center', justifyContent: 'center', color: P.ink2 }}><Icon name={r.ic} size={15}/></div>
                <div style={{ flex: 1 }}><div style={{ fontSize: 13, color: P.ink, fontWeight: 500 }}>{r.t}</div><div style={{ fontSize: 11, color: P.ink3 }}>{r.d}</div></div>
                <Icon name="check" size={15} color={P.sage}/>
              </div>
            ))}
          </>
        )}
      </div>

      {/* composer */}
      <div style={{ padding: 12, borderTop: `1px solid ${P.line}` }}>
        <div style={{ background: P.sunk, borderRadius: 11, padding: 10, border: `1px solid ${P.line}` }}>
          <input value={draft} onChange={e => setDraft(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); send(); } }} placeholder={mode === 'chat' ? 'Message Pex…' : 'Tell Pex to do something…'} style={{ width: '100%', border: 'none', background: 'transparent', outline: 'none', fontSize: 13, color: P.ink, fontFamily: P.sans }}/>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, marginTop: 8 }}>
            <Icon name="paperclip" size={15} color={P.ink3}/>
            <Icon name="at" size={15} color={P.ink3}/>
            <div style={{ flex: 1 }}/>
            <Btn kind="spark" size="sm" iconR="arrowRight" onClick={send}>Send</Btn>
          </div>
        </div>
      </div>
    </aside>
  );
}

// ── Command palette ─────────────────────────────────────────────
function CmdK() {
  const { cmdkOpen, closeCmdK, go } = window.useApp(); const P = window.PX;
  const [q, setQ] = React.useState('');
  const [sel, setSel] = React.useState(0);
  React.useEffect(() => { if (cmdkOpen) { setQ(''); setSel(0); } }, [cmdkOpen]);
  React.useEffect(() => { setSel(0); }, [q]);
  if (!cmdkOpen) return null;
  const groups = [
    { label: 'Go to', items: [
      { icon: 'home', t: 'Home', r: 'home' }, { icon: 'dollar', t: 'Money · Overview', r: 'money' },
      { icon: 'receipt', t: 'Money · Invoices', r: 'money/invoices' }, { icon: 'users', t: 'People · Contacts', r: 'people' },
      { icon: 'globe', t: 'Website · Analytics', r: 'website/analytics' }, { icon: 'grid', t: 'Catalog', r: 'catalog' },
    ]},
    { label: 'Actions', items: [
      { icon: 'send', t: 'Send an invoice', r: 'money/invoices/new' }, { icon: 'plus', t: 'Add a contact', r: 'people' },
      { icon: 'pencil', t: 'Edit the website', r: 'website/editor' },
    ]},
    { label: 'Ask Pex', items: [
      { icon: 'sparkles', t: 'Chase Café Bleu\'s overdue invoice', spark: true, r: 'pex' },
      { icon: 'sparkles', t: 'Draft the March class campaign', spark: true, r: 'pex' },
    ]},
  ];
  const match = (it) => !q || it.t.toLowerCase().includes(q.toLowerCase());
  const flat = groups.flatMap(g => g.items.filter(match));
  const openItem = (it) => { closeCmdK(); go(it.r); };
  const askPex = () => { closeCmdK(); if (q.trim() && window.PXPex) window.PXPex.setDraftPrompt(q.trim()); go('pex'); };
  const onKey = (e) => {
    if (e.key === 'ArrowDown') { e.preventDefault(); setSel(s => Math.min(s + 1, Math.max(0, flat.length - 1))); }
    else if (e.key === 'ArrowUp') { e.preventDefault(); setSel(s => Math.max(0, s - 1)); }
    else if (e.key === 'Enter') { e.preventDefault(); if (e.metaKey || e.ctrlKey) askPex(); else if (flat[sel]) openItem(flat[sel]); }
  };
  return (
    <div onClick={closeCmdK} style={{ position: 'fixed', inset: 0, background: 'rgba(27,25,21,0.34)', backdropFilter: 'blur(2px)', zIndex: 200, display: 'flex', justifyContent: 'center', alignItems: 'flex-start', paddingTop: 120 }}>
      <div onClick={e => e.stopPropagation()} style={{ width: 620, maxHeight: 520, background: P.card, borderRadius: 16, border: `1px solid ${P.line}`, boxShadow: P.shPop, overflow: 'hidden', fontFamily: P.sans, display: 'flex', flexDirection: 'column' }}>
        <div style={{ padding: '14px 16px', display: 'flex', alignItems: 'center', gap: 11, borderBottom: `1px solid ${P.line}` }}>
          <Icon name="search" size={18} color={P.ink3}/>
          <input autoFocus value={q} onChange={e => setQ(e.target.value)} onKeyDown={onKey} placeholder="Search anything, or ask Pex to do it…" style={{ flex: 1, border: 'none', background: 'transparent', outline: 'none', fontSize: 16, color: P.ink, fontFamily: P.sans }}/>
          <span style={{ fontSize: 10.5, color: P.ink3, background: P.sunk, padding: '3px 6px', borderRadius: 5, border: `1px solid ${P.line}` }}>esc</span>
        </div>
        <div style={{ flex: 1, overflow: 'auto', padding: '8px 0' }}>
          {groups.map((g, i) => (
            <div key={i}>
              <Label style={{ padding: '8px 16px 4px' }}>{g.label}</Label>
              {g.items.filter(match).map((it, j) => {
                const active = flat.indexOf(it) === sel;
                return (
                <div key={j} onClick={() => openItem(it)} onMouseEnter={() => setSel(flat.indexOf(it))} style={{ padding: '8px 16px', display: 'flex', alignItems: 'center', gap: 11, cursor: 'pointer', background: active ? P.hover : 'transparent' }}>
                  {it.spark ? <Pex size={24}/> : <div style={{ width: 26, height: 26, borderRadius: 7, background: P.sunk, display: 'flex', alignItems: 'center', justifyContent: 'center', color: P.ink2 }}><Icon name={it.icon} size={15}/></div>}
                  <span style={{ fontSize: 13.5, color: P.ink, flex: 1 }}>{it.t}</span>
                  {it.spark && <Pill tone="spark" style={{ fontSize: 10 }}>1 ⚡</Pill>}
                  <Icon name="arrowRight" size={14} color={active ? P.spark : P.ink4}/>
                </div>
                );
              })}
            </div>
          ))}
          {flat.length === 0 && <div style={{ padding: '24px 16px', textAlign: 'center', fontSize: 13, color: P.ink3 }}>No matches. Press <b style={{ color: P.ink2 }}>⌘↵</b> to ask Pex instead.</div>}
        </div>
        <div style={{ padding: '10px 16px', borderTop: `1px solid ${P.line}`, display: 'flex', gap: 16, fontSize: 11, color: P.ink3 }}>
          <span><b style={{ color: P.ink2 }}>↑↓</b> navigate</span><span><b style={{ color: P.ink2 }}>↵</b> open</span><span><b style={{ color: P.ink2 }}>⌘↵</b> ask Pex</span>
        </div>
      </div>
    </div>
  );
}

// ── App shell + router ──────────────────────────────────────────
function getRoute() { return (location.hash || '#login').replace(/^#\/?/, '') || 'login'; }

// ── Mobile shell — bottom-tab layout under the responsive breakpoint ──
function MobileShell({ Screen, route }) {
  const { go, pexOpen, setPexOpen, openCmdK, notifOpen, setNotifOpen } = window.useApp();
  const P = window.PX;
  const top = route.split('/')[0];
  const tabs = [
    { k: 'home',  icon: 'home',     label: 'Home' },
    { k: 'money', icon: 'dollar',   label: 'Money' },
    { k: 'people',icon: 'users',    label: 'People' },
    { k: 'mail',  icon: 'mail',     label: 'Mail' },
    { k: 'pex',   icon: 'sparkles', label: 'Pex' },
  ];
  return (
    <div style={{ height: '100vh', width: '100vw', display: 'flex', flexDirection: 'column', overflow: 'hidden', background: P.canvas, fontFamily: P.sans }}>
      <header style={{ height: 52, borderBottom: `1px solid ${P.line}`, display: 'flex', alignItems: 'center', padding: '0 14px', gap: 12, flexShrink: 0, background: P.canvas }}>
        <PXLogo size={18}/>
        <div style={{ flex: 1 }}/>
        <div onClick={openCmdK} style={{ cursor: 'pointer', padding: 4 }}><Icon name="search" size={18} color={P.ink2}/></div>
        <div onClick={() => setNotifOpen(!notifOpen)} style={{ position: 'relative', cursor: 'pointer', padding: 4 }}>
          <Icon name="bell" size={18} color={P.ink2}/>
          {window.useStore(window.PXNotif).unread > 0 && <span style={{ position: 'absolute', top: 0, right: 1, width: 6, height: 6, borderRadius: 6, background: P.spark }}/>}
        </div>
      </header>
      {notifOpen && <NotifPanel/>}
      <div id="scroll-main" style={{ flex: 1, overflow: 'auto' }}><Screen sub={route.split('/').slice(1).join('/')}/></div>
      <nav style={{ height: 58, borderTop: `1px solid ${P.line}`, background: P.card, display: 'flex', flexShrink: 0 }}>
        {tabs.map(t => {
          const on = top === t.k;
          return (
            <div key={t.k} onClick={() => go(t.k)} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 3, cursor: 'pointer', color: on ? P.spark : P.ink3 }}>
              <Icon name={t.icon} size={19} stroke={on ? 2.1 : 1.75}/>
              <span style={{ fontSize: 10, fontWeight: on ? 600 : 500 }}>{t.label}</span>
            </div>
          );
        })}
      </nav>
      {pexOpen && (
        <div onClick={() => setPexOpen(false)} style={{ position: 'fixed', inset: 0, background: 'rgba(27,25,21,0.34)', zIndex: 150 }}>
          <div onClick={e => e.stopPropagation()} style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: '78vh', borderRadius: '16px 16px 0 0', overflow: 'hidden' }}>
            <PexPanel/>
          </div>
        </div>
      )}
    </div>
  );
}

function AppShell() {
  const P = window.PX;
  const [route, setRoute] = React.useState(getRoute());
  const [collapsed, setCollapsed] = React.useState(false);
  const [pexOpen, setPexOpen] = React.useState(true);
  const [cmdkOpen, setCmdkOpen] = React.useState(false);
  const [notifOpen, setNotifOpen] = React.useState(false);
  const [sparks, setSparks] = React.useState(142);
  const [pexProposals, setPexProposals] = React.useState(window.PROPOSALS_SEED);
  const [overlay, setOverlay] = React.useState(null);      // { type, props }
  const [toasts, setToasts] = React.useState([]);
  const [, bumpTheme] = React.useReducer(x => x + 1, 0);
  const [isMobile, setIsMobile] = React.useState(() => window.matchMedia('(max-width: 760px)').matches);

  React.useEffect(() => {
    const mq = window.matchMedia('(max-width: 760px)');
    const h = () => setIsMobile(mq.matches);
    mq.addEventListener('change', h);
    return () => mq.removeEventListener('change', h);
  }, []);

  React.useEffect(() => {
    const h = () => { setRoute(getRoute()); setNotifOpen(false); document.querySelector('#scroll-main')?.scrollTo(0, 0); };
    window.addEventListener('hashchange', h);
    const k = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); setCmdkOpen(o => !o); }
      if (e.key === 'Escape') { setCmdkOpen(false); setOverlay(null); }
      if ((e.metaKey || e.ctrlKey) && e.key === '\\') { e.preventDefault(); setCollapsed(c => !c); }
    };
    window.addEventListener('keydown', k);
    return () => { window.removeEventListener('hashchange', h); window.removeEventListener('keydown', k); };
  }, []);

  const go = (r) => { location.hash = r; };  const toast = (msg, opts = {}) => {
    const id = Math.random().toString(36).slice(2);
    setToasts(t => [...t, { id, msg, ...opts }]);
    setTimeout(() => setToasts(t => t.filter(x => x.id !== id)), opts.duration || 3600);
  };
  const openOverlay = (type, props = {}) => setOverlay({ type, props });
  const closeOverlay = () => setOverlay(null);
  const actProposal = (id, status) => {
    const p = pexProposals.find(x => x.id === id);
    if (status === 'approved' && p && p.cost > sparks) {
      openOverlay('creditGate', { needed: p.cost, balance: sparks });
      return;
    }
    setPexProposals(ps => ps.map(x => x.id === id ? { ...x, status } : x));
    if (status === 'approved' && p) {
      setSparks(s => Math.max(0, s - p.cost));
      window.startPexRun && window.startPexRun(p);
      toast(`Approved — Pex is on it. ${p.cost} ⚡ spent.`, { tone: 'sage', icon: 'check' });
    } else if (status === 'snoozed' && p) {
      toast('Snoozed until tomorrow morning.', { tone: 'neutral', icon: 'clock' });
    }
  };
  // Design-system customization — mode/accent/radius/font all live as
  // mutable globals on window.PX*; this just applies + forces the tree
  // to re-render so every screen picks up the new values.
  const setBrand = (patch) => {
    if (patch.mode) window.setPXMode(patch.mode);
    if (patch.accent) window.setPXAccent(patch.accent);
    if (patch.radius) window.setPXRadius(patch.radius);
    if (patch.font) window.setPXFont(patch.font);
    bumpTheme();
  };

  const topSection = route.split('/')[0];
  const railLocked = SECONDARY.includes(topSection);
  const effCollapsed = railLocked ? true : collapsed;
  const ctx = { route, go, collapsed: effCollapsed, setCollapsed, railLocked, pexOpen, setPexOpen, cmdkOpen, openCmdK: () => setCmdkOpen(true), closeCmdK: () => setCmdkOpen(false), notifOpen, setNotifOpen, sparks, setSparks, pexProposals, actProposal, overlay, openOverlay, closeOverlay, toast, toasts, setBrand, isMobile };

  // resolve screen by longest matching prefix
  const keys = Object.keys(window.SCREENS).sort((a, b) => b.length - a.length);
  const matchKey = keys.find(k => route === k || route.startsWith(k + '/')) || 'home';
  const Screen = window.SCREENS[matchKey] || (() => <div style={{ padding: 40, fontFamily: P.sans, color: P.ink3 }}>Screen “{route}” coming soon.</div>);

  // onboarding routes render full-bleed (no shell)
  if (route.startsWith('onboard') || route === 'landing' || route === 'login') {
    const OB = window.SCREENS[matchKey];
    return <AppCtx.Provider value={ctx}><div style={{ height: '100vh', width: '100vw', overflow: 'auto', background: P.canvas }}>{OB ? <OB/> : null}</div><CmdK/>{window.Overlays && <window.Overlays/>}{window.Toaster && <window.Toaster/>}</AppCtx.Provider>;
  }

  if (isMobile) {
    return (
      <AppCtx.Provider value={ctx}>
        <MobileShell Screen={Screen} route={route}/>
        {window.Overlays && <window.Overlays/>}
        {window.Toaster && <window.Toaster/>}
      </AppCtx.Provider>
    );
  }

  return (
    <AppCtx.Provider value={ctx}>
      <div style={{ height: '100vh', width: '100vw', display: 'flex', overflow: 'hidden', background: P.canvas }}>
        <Sidebar/>
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', overflow: 'hidden', minWidth: 0 }}>
          <Topbar/>
          <div id="scroll-main" style={{ flex: 1, overflow: 'auto' }}><Screen sub={route.split('/').slice(1).join('/')}/></div>
        </div>
        {pexOpen && <PexPanel/>}
      </div>
      <CmdK/>
      {window.Overlays && <window.Overlays/>}
      {window.Toaster && <window.Toaster/>}
    </AppCtx.Provider>
  );
}
window.AppShell = AppShell;

// Page header helper for screens
window.Page = ({ title, sub, actions, tabs, activeTab, onTab, children, pad = 22, max }) => {
  const P = window.PX;
  return (
    <div style={{ fontFamily: P.sans, minHeight: '100%' }}>
      {(title || actions) && (
        <div style={{ padding: tabs ? '20px 22px 0' : '20px 22px', borderBottom: tabs ? 'none' : `1px solid ${P.line}`, display: 'flex', alignItems: 'flex-end', gap: 16 }}>
          <div style={{ flex: 1, minWidth: 0 }}>
            {sub && <Label style={{ marginBottom: 5 }}>{sub}</Label>}
            <div style={{ fontFamily: P.serif, fontStyle: 'italic', fontSize: 30, color: P.ink, letterSpacing: -0.5, lineHeight: 1 }}>{title}</div>
          </div>
          {actions && <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexShrink: 0 }}>{actions}</div>}
        </div>
      )}
      {tabs && <div style={{ padding: '14px 22px 0' }}><Tabs tabs={tabs} active={activeTab} onChange={onTab}/></div>}
      <div style={{ padding: pad, maxWidth: max, margin: max ? '0 auto' : undefined }}>{children}</div>
    </div>
  );
};

// Seed proposals (shared with home + pex)
window.PROPOSALS_SEED = [
  { id: 'p1', tag: 'Money', tone: 'rose', urgent: true, cost: 1, title: 'Chase Café Bleu\'s overdue invoice', ctx: 'Invoice #1024 · $1,420 · 11 days late. I drafted a warm nudge.', preview: 'Hi Marc, just a gentle reminder about invoice #1024 — no rush at all…', status: 'pending' },
  { id: 'p2', tag: 'Website', tone: 'amber', cost: 3, title: 'Fix 2 stale facts on your About page', ctx: '"Since 2018" → 2019, "two bakers" → five.', preview: 'Honest Loaves started in 2019 out of a single Brooklyn oven…', status: 'pending' },
  { id: 'p3', tag: 'Marketing', tone: 'sage', cost: 4, title: 'Launch the March class email', ctx: 'Past customers · send Wed 9am · previous class filled.', preview: 'Our March class is open — same oven, smaller group…', status: 'pending' },
  { id: 'p4', tag: 'People', tone: 'sky', cost: 2, title: 'Re-engage 3 quiet leads', ctx: 'Jenna, Marcus, Lila — no contact in 2+ weeks.', status: 'pending' },
  { id: 'p5', tag: 'Ops', tone: 'spark', cost: 1, title: 'Reorder flour before Thursday', ctx: 'You\'ll run out at current pace. Same supplier, $340.', status: 'pending' },
];
