// Adviser portal design tokens + shell components.
// Tokens reproduce the production palette from globals.css (light-only).

const { useState, useEffect, useRef } = React;

// ---------------------------------------------------------------- Responsive
// Three breakpoints: mobile <640, tablet <1024, desktop. Scenes & shells branch
// inline-style values on the result. Keeps the inline-style architecture intact
// while still adapting layouts at narrow widths.

function readBp() {
  const w = window.innerWidth;
  if (w < 640) return 'mobile';
  if (w < 1024) return 'tablet';
  return 'desktop';
}
function useBreakpoint() {
  const [bp, setBp] = useState(() => readBp());
  useEffect(() => {
    const onResize = () => setBp(readBp());
    window.addEventListener('resize', onResize);
    return () => window.removeEventListener('resize', onResize);
  }, []);
  return bp;
}

// ---------------------------------------------------------------- Primitives

function Icon({ d, size = 16, stroke = 'currentColor', fill = 'none' }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={fill}
         stroke={stroke} strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"
         style={{ flexShrink: 0 }}>
      <path d={d}></path>
    </svg>
  );
}
const ICONS = {
  home:     'M3 11L12 4l9 7v9a1 1 0 0 1-1 1h-5v-6h-6v6H4a1 1 0 0 1-1-1z',
  users:    'M16 11a4 4 0 1 0-4-4 4 4 0 0 0 4 4zm-8 0a4 4 0 1 0-4-4 4 4 0 0 0 4 4zm0 2c-4 0-7 2-7 5v3h8m7-8c-4 0-7 2-7 5v3h14v-3c0-3-3-5-7-5z',
  file:     'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z M14 2v6h6',
  shield:   'M12 2l9 4v6c0 5-3.8 9.5-9 10-5.2-.5-9-5-9-10V6z',
  folder:   'M3 7a2 2 0 0 1 2-2h4l2 3h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z',
  upload:   'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M17 8l-5-5-5 5 M12 3v12',
  activity: 'M22 12h-4l-3 9L9 3l-3 9H2',
  scroll:   'M8 21h8a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2H10a2 2 0 0 0-2 2v16zm0 0a2 2 0 0 1-2-2v-3h4',
  tree:     'M3 5a2 2 0 0 1 2-2h4l2 3h8a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z M9 13h6 M9 17h6',
  archive:  'M21 8v13H3V8 M1 3h22v5H1z M10 12h4',
  check:    'M5 13l4 4L19 7',
  chevR:    'M9 18l6-6-6-6',
  chevD:    'M6 9l6 6 6-6',
  chevU:    'M18 15l-6-6-6 6',
  chevL:    'M15 18l-9-6 9-6',
  x:        'M18 6L6 18 M6 6l12 12',
  plus:     'M12 5v14 M5 12h14',
  search:   'M11 19a8 8 0 1 1 0-16 8 8 0 0 1 0 16z M21 21l-4.35-4.35',
  edit:     'M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7 M18.5 2.5a2.1 2.1 0 0 1 3 3L12 15l-4 1 1-4z',
  download: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4 M7 10l5 5 5-5 M12 15V3',
  warn:     'M10.3 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.41 0z M12 9v4 M12 17h.01',
  info:     'M12 22c5.5 0 10-4.5 10-10S17.5 2 12 2 2 6.5 2 12s4.5 10 10 10z M12 16v-4 M12 8h.01',
  doc:      'M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8L14 2z M14 2v6h6 M16 13H8 M16 17H8 M10 9H8',
  signature:'M3 17c4-1 8-1 12-3 4-2 5-7 0-7-3 0-3 5 0 6 4 1 5 5 6 4',
  bell:     'M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9 M13.7 21a2 2 0 0 1-3.4 0',
  link:     'M10 13a5 5 0 0 0 7 0l3-3a5 5 0 0 0-7-7l-1 1 M14 11a5 5 0 0 0-7 0l-3 3a5 5 0 0 0 7 7l1-1',
  spark:    'M12 2v6 M12 16v6 M2 12h6 M16 12h6 M4.9 4.9l4.2 4.2 M14.9 14.9l4.2 4.2 M4.9 19.1l4.2-4.2 M14.9 9.1l4.2-4.2',
  shieldDot:'M12 2l9 4v6c0 5-3.8 9.5-9 10-5.2-.5-9-5-9-10V6z M9 12l2 2 4-4',
  history:  'M3 12a9 9 0 1 0 3-6.7 M3 4v5h5 M12 7v5l3 3',
  filter:   'M22 3H2l8 9.5V19l4 2v-8.5z',
  send:     'M22 2L11 13 M22 2l-7 20-4-9-9-4z',
  pen:      'M12 19l7-7 3 3-7 7-3-3z M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z',
  menu:     'M3 12h18 M3 6h18 M3 18h18',
};

// ---------------------------------------------------------------- Tokens

const EPG = {
  ink:      '#1C2D30',
  ink2:     '#3A4E52',
  muted:    '#5B6E72',
  soft:     '#94A5A9',
  page:     '#F5F8F9',
  card:     '#FFFFFF',
  line:     '#E2E8EA',
  line2:    '#CBD5D8',
  brand:    '#1D5563',
  brand2:   '#2B7A8C',
  brandInk: '#0B2E36',
  gold:     '#B58A3E',
  green:    '#2F7A4A',
  amber:    '#B07823',
  red:      '#A23A34',
  amberBg:  'rgba(176, 120, 35, 0.07)',
  redBg:    'rgba(162, 58, 52, 0.07)',
  greenBg:  'rgba(47, 122, 74, 0.07)',
  goldBg:   'rgba(181, 138, 62, 0.10)',
  brandBg:  'rgba(29, 85, 99, 0.08)',
  radius:   '10px',
  radiusSm: '6px',
  radiusLg: '14px',
  shadowCard: '0 1px 2px rgba(28,45,48,0.04), 0 1px 3px rgba(28,45,48,0.06)',
  shadowDeep: '0 8px 30px rgba(28,45,48,0.08), 0 2px 8px rgba(28,45,48,0.04)',
  serif: '"Libre Caslon Text", Georgia, serif',
  sans:  '"Inter", -apple-system, BlinkMacSystemFont, system-ui, sans-serif',
  mono:  '"JetBrains Mono", ui-monospace, "SFMono-Regular", monospace',
};

// ---------------------------------------------------------------- Logo

function EpgLogo({ size = 28, white = false }) {
  const color = white ? '#FFFFFF' : EPG.brand;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
      <svg width={size} height={size} viewBox="0 0 40 40">
        <rect x="2" y="2" width="36" height="36" rx="6" fill={color}/>
        <text x="20" y="26" textAnchor="middle"
              fontFamily={EPG.serif} fontSize="18" fontWeight="600"
              fill={white ? color : '#fff'} style={{letterSpacing:'-0.02em'}}>
          E
        </text>
      </svg>
      <div style={{ display: 'flex', flexDirection: 'column', lineHeight: 1.1 }}>
        <span style={{ fontFamily: EPG.serif, fontSize: 14, fontWeight: 600, color: white ? '#fff' : EPG.ink, letterSpacing: '-0.005em' }}>Financial Advisory Firm</span>
        <span style={{ fontFamily: EPG.sans, fontSize: 10, color: white ? 'rgba(255,255,255,0.6)' : EPG.muted, letterSpacing: '0.06em', textTransform: 'uppercase' }}>Adviser portal</span>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------- Buttons

function Btn({ children, variant = 'default', size = 'default', icon, onClick, disabled, style = {} }) {
  const v = {
    default:  { bg: EPG.brand, fg: '#fff', bd: EPG.brand },
    outline:  { bg: '#fff', fg: EPG.ink, bd: EPG.line2 },
    ghost:    { bg: 'transparent', fg: EPG.ink2, bd: 'transparent' },
    destructive: { bg: EPG.red, fg: '#fff', bd: EPG.red },
    soft:     { bg: EPG.brandBg, fg: EPG.brand, bd: 'transparent' },
  }[variant];
  const h = size === 'sm' ? 28 : size === 'lg' ? 36 : 32;
  return (
    <button onClick={onClick} disabled={disabled}
      style={{
        height: h, lineHeight: 1, display: 'inline-flex', alignItems: 'center', gap: 6,
        padding: size === 'sm' ? '0 10px' : '0 12px',
        background: v.bg, color: v.fg,
        border: `1px solid ${v.bd}`,
        borderRadius: EPG.radius,
        fontFamily: EPG.sans, fontSize: size === 'sm' ? 12.5 : 13, fontWeight: 500,
        cursor: disabled ? 'not-allowed' : 'pointer',
        opacity: disabled ? 0.55 : 1,
        whiteSpace: 'nowrap',
        transition: 'all 120ms ease',
        ...style,
      }}>
      {icon && <Icon d={ICONS[icon]} size={14}/>}
      {children}
    </button>
  );
}

// ---------------------------------------------------------------- Card

function Card({ children, style = {}, padding = 20 }) {
  return (
    <div style={{
      background: EPG.card,
      border: `1px solid ${EPG.line}`,
      borderRadius: EPG.radius,
      boxShadow: EPG.shadowCard,
      padding,
      ...style,
    }}>{children}</div>
  );
}
function CardHeader({ title, eyebrow, description, actions, style = {} }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16, marginBottom: 16, ...style }}>
      <div>
        {eyebrow && <div style={{ fontFamily: EPG.mono, fontSize: 10, color: EPG.muted, letterSpacing: '0.12em', textTransform: 'uppercase', marginBottom: 6 }}>{eyebrow}</div>}
        <div style={{ fontFamily: EPG.serif, fontSize: 16, fontWeight: 600, color: EPG.ink, lineHeight: 1.3 }}>{title}</div>
        {description && <div style={{ fontFamily: EPG.sans, fontSize: 13, color: EPG.muted, marginTop: 4 }}>{description}</div>}
      </div>
      {actions && <div style={{ display: 'flex', gap: 8 }}>{actions}</div>}
    </div>
  );
}

// ---------------------------------------------------------------- Confidence dot

function ConfidenceDot({ confidence, withBadge = false }) {
  const c = {
    high:   { bg: EPG.green, label: 'high' },
    medium: { bg: EPG.amber, label: 'medium' },
    low:    { bg: EPG.red,   label: 'low' },
  }[confidence];
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6 }}>
      <span style={{ width: 8, height: 8, borderRadius: '50%', background: c.bg, boxShadow: '0 0 0 2px rgba(0,0,0,0.04)', flexShrink: 0 }}/>
      {withBadge && (
        <span style={{
          fontFamily: EPG.mono, fontSize: 9.5, fontWeight: 500,
          color: c.bg,
          border: `1px solid ${c.bg}`,
          padding: '1px 5px', borderRadius: 4,
          textTransform: 'uppercase', letterSpacing: '0.04em',
          background: 'transparent',
        }}>{c.label}</span>
      )}
    </span>
  );
}

// ---------------------------------------------------------------- Confidence bar (sidebar tri-stack)

function ConfidenceBar({ high, medium, low }) {
  const total = high + medium + low;
  const pct = (n) => `${(n / total) * 100}%`;
  return (
    <div>
      <div style={{ display: 'flex', gap: 4, height: 8, borderRadius: 99, overflow: 'hidden' }}>
        <div style={{ width: pct(high),   background: EPG.green }}/>
        <div style={{ width: pct(medium), background: EPG.amber }}/>
        <div style={{ width: pct(low),    background: EPG.red }}/>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', marginTop: 8, fontFamily: EPG.mono, fontSize: 10.5, color: EPG.muted }}>
        <span><ConfidenceDot confidence="high"/> <span style={{marginLeft:4, color:EPG.ink2}}>{high}</span> high</span>
        <span><ConfidenceDot confidence="medium"/> <span style={{marginLeft:4, color:EPG.ink2}}>{medium}</span> medium</span>
        <span><ConfidenceDot confidence="low"/> <span style={{marginLeft:4, color:EPG.ink2}}>{low}</span> low</span>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------- Adviser shell

function AdviserShell({ activeNav, pageHeader, children }) {
  const bp = useBreakpoint();
  const isMobile = bp === 'mobile';
  const isTablet = bp === 'tablet';
  const [drawerOpen, setDrawerOpen] = useState(false);

  // Close drawer when breakpoint changes back to non-mobile
  useEffect(() => { if (!isMobile) setDrawerOpen(false); }, [isMobile]);

  const navItems = [
    { id: 'home',    label: 'Home',         icon: 'home' },
    { id: 'clients', label: 'Clients',      icon: 'users', count: 47 },
    { id: 'subs',    label: 'Submissions',  icon: 'file', count: 8 },
  ];
  const adminItems = [
    { id: 'sp',      label: 'SharePoint',         icon: 'folder' },
    { id: 'bulk',    label: 'Bulk import',        icon: 'upload' },
    { id: 'sessions',label: 'Active sessions',    icon: 'activity' },
    { id: 'audit',   label: 'Audit log',          icon: 'scroll' },
    { id: 'clone',   label: 'SP clone',           icon: 'tree' },
    { id: 'archived',label: 'Archived clients',   icon: 'archive' },
  ];
  const adminOpen = ['sp','bulk','sessions','audit','clone','archived'].includes(activeNav);

  const sidebarWidth = isTablet ? 200 : 240;
  const mainPadH     = isMobile ? 16 : isTablet ? 20 : 32;
  const mainPadBot   = isMobile ? 32 : 56;
  const showAdmin    = !isTablet || adminOpen; // hide admin section on tablet by default

  const sidebarContent = (
    <>
      <div style={{ padding: '18px 18px 14px', borderBottom: `1px solid ${EPG.line}`, display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <EpgLogo size={26}/>
        {isMobile && (
          <button onClick={() => setDrawerOpen(false)} aria-label="Close menu"
            style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: EPG.muted, padding: 4 }}>
            <Icon d={ICONS.x} size={18}/>
          </button>
        )}
      </div>
      <nav style={{ padding: '14px 10px', flex: 1, overflowY: 'auto' }}>
        {navItems.map(item => (
          <NavRow key={item.id} item={item} active={activeNav === item.id}/>
        ))}
        {showAdmin && (
          <div style={{ marginTop: 14, padding: '0 8px' }}>
            <div style={{
              display: 'flex', alignItems: 'center', gap: 8,
              padding: '6px 8px',
              fontSize: 10.5, fontWeight: 600, color: EPG.muted,
              letterSpacing: '0.1em', textTransform: 'uppercase',
            }}>
              <Icon d={ICONS.shield} size={12}/>
              <span>Admin</span>
            </div>
            {adminOpen && adminItems.map(item => (
              <NavRow key={item.id} item={item} active={activeNav === item.id} indent={true}/>
            ))}
          </div>
        )}
      </nav>
      <div style={{ padding: '14px 16px', borderTop: `1px solid ${EPG.line}`, display: 'flex', alignItems: 'center', gap: 10 }}>
        <div style={{
          width: 32, height: 32, borderRadius: '50%',
          background: EPG.brand, color: '#fff',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          fontFamily: EPG.sans, fontSize: 12, fontWeight: 600, flexShrink: 0,
        }}>LB</div>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 12.5, fontWeight: 500, color: EPG.ink }}>Lachlan Brooks</div>
          <div style={{ fontSize: 10.5, color: EPG.muted, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>lachlan@advisory.example.com.au</div>
        </div>
      </div>
    </>
  );

  return (
    <div style={{ display: 'flex', minHeight: '100%', background: EPG.page, fontFamily: EPG.sans, color: EPG.ink, position: 'relative' }}>
      {/* Sidebar — fixed drawer on mobile, inline column otherwise */}
      {isMobile ? (
        <>
          {drawerOpen && (
            <div onClick={() => setDrawerOpen(false)}
              style={{
                position: 'fixed', inset: 0, zIndex: 50,
                background: 'rgba(11,46,54,0.55)', backdropFilter: 'blur(2px)',
              }}/>
          )}
          <aside style={{
            position: 'fixed', top: 0, bottom: 0, left: 0, zIndex: 51,
            width: 280, maxWidth: '85vw',
            background: EPG.card,
            borderRight: `1px solid ${EPG.line}`,
            display: 'flex', flexDirection: 'column',
            transform: drawerOpen ? 'translateX(0)' : 'translateX(-100%)',
            transition: 'transform 220ms cubic-bezier(0.25, 0.46, 0.45, 0.94)',
            boxShadow: drawerOpen ? '4px 0 24px rgba(0,0,0,0.18)' : 'none',
          }}>
            {sidebarContent}
          </aside>
        </>
      ) : (
        <aside style={{
          width: sidebarWidth, flexShrink: 0,
          background: EPG.card,
          borderRight: `1px solid ${EPG.line}`,
          display: 'flex', flexDirection: 'column',
        }}>
          {sidebarContent}
        </aside>
      )}

      {/* Main column */}
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
        {/* Top bar */}
        <header style={{
          height: isMobile ? 56 : 64, flexShrink: 0,
          background: EPG.card,
          borderBottom: `1px solid ${EPG.line}`,
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: `0 ${mainPadH}px`,
          gap: 12,
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: isMobile ? 10 : 12, color: EPG.muted, fontSize: 13, minWidth: 0, flex: 1 }}>
            {isMobile && (
              <button onClick={() => setDrawerOpen(true)} aria-label="Open menu"
                style={{ background: 'transparent', border: 'none', cursor: 'pointer', color: EPG.ink2, padding: 4, display: 'flex' }}>
                <Icon d={ICONS.menu} size={20}/>
              </button>
            )}
            <Icon d={ICONS.search} size={15}/>
            {!isMobile && (
              <>
                <span style={{ fontFamily: EPG.sans, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>Search clients, submissions…</span>
                <span style={{ fontFamily: EPG.mono, fontSize: 10, color: EPG.soft, marginLeft: 8, border: `1px solid ${EPG.line}`, borderRadius: 4, padding: '1px 5px', flexShrink: 0 }}>⌘K</span>
              </>
            )}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: isMobile ? 8 : 14, flexShrink: 0 }}>
            {!isMobile && <Icon d={ICONS.bell} size={16} stroke={EPG.muted}/>}
            {!isMobile && !isTablet && <div style={{ width: 1, height: 20, background: EPG.line }}/>}
            {!isMobile && !isTablet && <span style={{ fontSize: 12.5, color: EPG.ink2 }}>Lachlan Brooks</span>}
            <div style={{
              width: 32, height: 32, borderRadius: '50%',
              background: EPG.brand, color: '#fff',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: 12, fontWeight: 600, flexShrink: 0,
            }}>LB</div>
          </div>
        </header>

        {/* Page content */}
        <main style={{ flex: 1, overflowY: 'auto', padding: `${isMobile ? 20 : 32}px ${mainPadH}px ${mainPadBot}px` }}>
          <div style={{ maxWidth: 1280, margin: '0 auto' }}>
            {pageHeader && <PageHeader {...pageHeader} bp={bp}/>}
            {children}
          </div>
        </main>
      </div>
    </div>
  );
}

function NavRow({ item, active, indent }) {
  return (
    <div style={{ position: 'relative' }}>
      {active && (
        <div style={{
          position: 'absolute', left: 0, top: 6, bottom: 6,
          width: 3, borderRadius: '0 2px 2px 0', background: EPG.brand,
        }}/>
      )}
      <a style={{
        display: 'flex', alignItems: 'center', gap: 10,
        padding: indent ? '6px 8px 6px 16px' : '7px 10px',
        marginBottom: 2,
        borderRadius: EPG.radius,
        textDecoration: 'none',
        color: active ? EPG.brand : EPG.ink2,
        background: active ? EPG.brandBg : 'transparent',
        fontWeight: active ? 600 : 500,
        fontSize: indent ? 12.5 : 13,
        cursor: 'pointer',
      }}>
        <Icon d={ICONS[item.icon]} size={indent ? 13 : 15} stroke={active ? EPG.brand : EPG.muted}/>
        <span style={{ flex: 1 }}>{item.label}</span>
        {item.count != null && (
          <span style={{
            background: active ? EPG.brand : EPG.line,
            color: active ? '#fff' : EPG.muted,
            fontSize: 10, fontWeight: 600,
            padding: '1px 6px', borderRadius: 99,
            fontFamily: EPG.mono,
          }}>{item.count}</span>
        )}
      </a>
    </div>
  );
}

function PageHeader({ title, eyebrow, description, count, actions, breadcrumb, bp }) {
  const isMobile = bp === 'mobile';
  // On mobile show only the last 2 breadcrumb items to avoid overflow.
  const trimmedCrumbs = isMobile && breadcrumb && breadcrumb.length > 2
    ? ['…', breadcrumb[breadcrumb.length - 1]]
    : breadcrumb;
  return (
    <div style={{ marginBottom: isMobile ? 20 : 24 }}>
      {trimmedCrumbs && (
        <div style={{ fontSize: 12, color: EPG.muted, marginBottom: 8, display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
          {trimmedCrumbs.map((b, i) => (
            <React.Fragment key={i}>
              {i > 0 && <Icon d={ICONS.chevR} size={11} stroke={EPG.soft}/>}
              <span style={{ color: i === trimmedCrumbs.length - 1 ? EPG.ink2 : EPG.muted }}>{b}</span>
            </React.Fragment>
          ))}
        </div>
      )}
      {eyebrow && <div style={{ fontFamily: EPG.mono, fontSize: 10.5, color: EPG.brand2, letterSpacing: '0.14em', textTransform: 'uppercase', marginBottom: 6 }}>{eyebrow}</div>}
      <div style={{
        display: 'flex',
        flexDirection: isMobile ? 'column' : 'row',
        justifyContent: 'space-between',
        alignItems: isMobile ? 'stretch' : 'flex-start',
        gap: isMobile ? 14 : 16,
      }}>
        <div>
          <h1 style={{ display: 'flex', alignItems: 'center', gap: 10, margin: 0, fontFamily: EPG.serif, fontSize: isMobile ? 20 : 24, fontWeight: 600, color: EPG.ink, letterSpacing: '-0.01em', lineHeight: 1.2 }}>
            {title}
            {count != null && (
              <span style={{
                height: 24, minWidth: 28, padding: '0 8px',
                background: EPG.brand, color: '#fff',
                borderRadius: 99, fontSize: 11, fontWeight: 600,
                display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                fontFamily: EPG.sans,
              }}>{count}</span>
            )}
          </h1>
          {description && <div style={{ fontSize: 13.5, color: EPG.muted, marginTop: 6, maxWidth: 640 }}>{description}</div>}
        </div>
        {actions && (
          <div style={{
            display: 'flex', gap: 8,
            overflowX: isMobile ? 'auto' : 'visible',
            paddingBottom: isMobile ? 2 : 0,
            margin: isMobile ? '0 -4px' : 0,
            padding: isMobile ? '0 4px 2px' : 0,
          }}>{actions}</div>
        )}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------- Client shell (magic-link splash card)

function ClientMagicShell({ children }) {
  const bp = useBreakpoint();
  const isMobile = bp === 'mobile';
  return (
    <div style={{
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      minHeight: '100%', background: EPG.page,
      fontFamily: EPG.sans, color: EPG.ink,
      padding: isMobile ? '24px 12px' : '40px 16px',
    }}>
      <div style={{
        width: '100%', maxWidth: 460,
        background: EPG.card,
        border: `1px solid ${EPG.line}`,
        borderRadius: EPG.radiusLg,
        boxShadow: EPG.shadowDeep,
        padding: isMobile ? 24 : 36,
      }}>
        <div style={{ display: 'flex', justifyContent: 'center', marginBottom: isMobile ? 22 : 28 }}>
          <EpgLogo size={isMobile ? 30 : 36}/>
        </div>
        {children}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------- Client form shell (top strip + max-w-5xl)

function ClientFormShell({ title, saveStatus, progress, children }) {
  const bp = useBreakpoint();
  const isMobile = bp === 'mobile';
  const padH = isMobile ? 16 : 24;
  const headerH = isMobile ? 56 : 64;
  return (
    <div style={{ minHeight: '100%', background: EPG.page, fontFamily: EPG.sans, color: EPG.ink, display: 'flex', flexDirection: 'column' }}>
      {/* Top strip */}
      <header style={{
        height: headerH, flexShrink: 0,
        background: EPG.card,
        borderBottom: `1px solid ${EPG.line}`,
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: `0 ${padH}px`,
        position: 'sticky', top: 0, zIndex: 5,
        gap: 10,
      }}>
        <EpgLogo size={isMobile ? 22 : 26}/>
        <div style={{ display: 'flex', alignItems: 'center', gap: isMobile ? 8 : 16 }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, fontSize: 12, color: EPG.muted }}>
            <Icon d={ICONS.check} size={12} stroke={EPG.green}/>
            {!isMobile && <span>{saveStatus || 'All changes saved'}</span>}
          </div>
          <Btn variant="ghost" size="sm">{isMobile ? 'Exit' : 'Save & exit'}</Btn>
        </div>
      </header>
      {progress != null && (
        <div style={{ height: 3, background: EPG.line, position: 'sticky', top: headerH, zIndex: 4 }}>
          <div style={{ height: '100%', width: `${progress}%`, background: EPG.brand, transition: 'width 200ms' }}/>
        </div>
      )}
      <main style={{ flex: 1, overflowY: 'auto', padding: `${isMobile ? 22 : 32}px ${padH}px ${isMobile ? 40 : 56}px` }}>
        <div style={{ maxWidth: 880, margin: '0 auto' }}>
          {title && (
            <div style={{ marginBottom: isMobile ? 22 : 28 }}>
              <h1 style={{ margin: 0, fontFamily: EPG.serif, fontSize: isMobile ? 22 : 28, fontWeight: 600, color: EPG.ink, letterSpacing: '-0.01em' }}>{title}</h1>
            </div>
          )}
          {children}
        </div>
      </main>
    </div>
  );
}

// ---------------------------------------------------------------- Chip / Pill

function Chip({ children, tone = 'muted', icon, style = {} }) {
  const t = {
    muted:    { bg: EPG.page, fg: EPG.muted, bd: EPG.line },
    primary:  { bg: EPG.brandBg, fg: EPG.brand, bd: 'rgba(29, 85, 99, 0.25)' },
    success:  { bg: EPG.greenBg, fg: EPG.green, bd: 'rgba(47, 122, 74, 0.25)' },
    warning:  { bg: EPG.amberBg, fg: EPG.amber, bd: 'rgba(176, 120, 35, 0.30)' },
    danger:   { bg: EPG.redBg,   fg: EPG.red,   bd: 'rgba(162, 58, 52, 0.30)' },
    gold:     { bg: EPG.goldBg,  fg: EPG.gold,  bd: 'rgba(181, 138, 62, 0.30)' },
  }[tone];
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      height: 22, padding: '0 8px',
      borderRadius: 99,
      background: t.bg, color: t.fg,
      border: `1px solid ${t.bd}`,
      fontFamily: EPG.sans, fontSize: 11, fontWeight: 500,
      whiteSpace: 'nowrap',
      ...style,
    }}>
      {icon && <Icon d={ICONS[icon]} size={11}/>}
      {children}
    </span>
  );
}

// ---------------------------------------------------------------- Money formatter

function aud(n, opts = {}) {
  if (n == null || n === '') return '—';
  if (typeof n === 'string') return n;
  const f = new Intl.NumberFormat('en-AU', { style: 'currency', currency: 'AUD', maximumFractionDigits: opts.cents ? 2 : 0, minimumFractionDigits: 0 });
  return f.format(n);
}

function formatAest(d) {
  if (!d) return '';
  const date = typeof d === 'string' ? new Date(d) : d;
  const opts = { day: '2-digit', month: 'short', hour: '2-digit', minute: '2-digit', second: '2-digit', timeZone: 'Australia/Sydney', hour12: false };
  return date.toLocaleString('en-AU', opts).replace(',', '') + ' AEST';
}

// ---------------------------------------------------------------- Export to window

Object.assign(window, {
  React, useState, useEffect, useRef,
  EPG, EpgLogo, Btn, Card, CardHeader, Icon, ICONS,
  ConfidenceDot, ConfidenceBar, Chip,
  AdviserShell, ClientMagicShell, ClientFormShell, PageHeader,
  aud, formatAest,
  useBreakpoint, readBp,
});
