// Simple Pro Mobile — Shared primitives
// Tab bar, headers, badges, cells, bottom sheets, quick action tiles
const { useState, useEffect, useRef } = React;

// ── SCREEN LABELS — for back-button "back to X" hints ─────────
const SCREEN_LABELS = {
  home:'Home', jobs:'Jobs', schedule:'Schedule', belle:'Belle', more:'More',
  billing:'Billing', conversations:'Conversations',
  'conversation-detail':'Conversation',
  customers:'Customers', 'customer-detail':'Customer', 'job-detail':'Job', 'new-job':'New Job',
  'new-customer':'New Customer', 'edit-customer':'Edit Customer', 'call-detail':'Call Detail',
  'invoice-detail':'Invoice', 'estimate-detail':'Estimate',
  payment:'Payment',
  settings:'Settings',
  'settings-account':'Account', 'settings-company-group':'Company',
  'settings-billing-group':'Billing', 'settings-automation':'Automation',
  'settings-integrations-group':'Integrations', 'settings-help-group':'Help',
  'settings-profile':'Profile', 'settings-security':'Security',
  'settings-notifications':'Notifications', 'settings-company':'Company',
  'settings-payments':'Payments', 'settings-billing':'Billing', 'settings-pricebook':'Price Book',
  'settings-belle':'Belle AI', 'settings-templates':'Templates', 'settings-integrations':'Integrations',
  'settings-data':'Data', 'settings-privacy':'Privacy', 'settings-help':'Help',
  'settings-contact':'Contact', 'settings-about':'About', 'settings-team':'Team',
  'team-member':'Member',
  plans:'Plans', 'billing-pdf':'Statement',
  approvals:'Approvals', 'job-costing':'Job Costing', handoff:'Handoff',
  'escalation-rules':'Escalation Rules', inventory:'Parts', reports:'Reports',
  'feature-detail':'Feature', 'tech-schedule':'Tech Schedule',
  'pricebook-category':'Price Book', campaigns:'Campaigns', 'campaign-detail':'Campaign',
  'customer-financing':'Financing', 'custom-branding':'Branding', 'priority-support':'Support',
};
function screenLabel(key) { return SCREEN_LABELS[key] || 'Back'; }

// ── NAV CONTEXT — provides goBack + backLabel to every screen ─
const NavContext = React.createContext({ goBack: null, backLabel: 'Back' });
function useNav() { return React.useContext(NavContext); }

// ── BELLE-ONLINE CONTEXT — gates Belle CTAs + health banner ─────
const BelleOnlineContext = React.createContext({ belleOnline: true, setBelleOnline: ()=>{} });
function useBelleOnline() { return React.useContext(BelleOnlineContext); }

// ── IOS VISUAL SYSTEM ────────────────────────────────────────
// Static inline-style tokens used by the prototype screens. Keep these
// deliberately simple so every page can share the Home direction without
// introducing a CSS framework or changing product behavior.
const IOS = {
  bg:'linear-gradient(180deg,#f8f8fb 0%,#f2f2f7 56%,#eeeeF4 100%)',
  card:'rgba(255,255,255,0.86)',
  cardStrong:'rgba(255,255,255,0.94)',
  line:'0.5px solid rgba(0,0,0,0.06)',
  shadow:'0 8px 22px rgba(15,23,42,0.055)',
  shadowStrong:'0 14px 30px rgba(15,23,42,0.12)',
  text:'#111827',
  sub:'rgba(17,24,39,0.52)',
  faint:'rgba(17,24,39,0.38)',
  blue:'#007aff',
  purple:'#7c3aed',
};

function screenBg(extra={}) { return { minHeight:'100%', paddingBottom:100, background:IOS.bg, color:IOS.text, overflowX:'hidden', ...extra }; }

function glassStyle(extra={}) {
  return {
    background:IOS.card,
    border:IOS.line,
    borderRadius:22,
    boxShadow:IOS.shadow,
    backdropFilter:'blur(18px)',
    WebkitBackdropFilter:'blur(18px)',
    ...extra,
  };
}

function IOSPlusButton({ onTap, label='Add' }) {
  return (
    <div className="sp-pressable" onClick={onTap} aria-label={label}
      style={{width:34,height:34,borderRadius:'50%',background:'rgba(0,122,255,0.10)',
        border:'0.5px solid rgba(0,122,255,0.18)',color:IOS.blue,
        display:'flex',alignItems:'center',justifyContent:'center',cursor:'pointer'}}>
      {React.cloneElement(Icons.plus,{width:15,height:15,strokeWidth:2.4})}
    </div>
  );
}

// ── ICONS ─────────────────────────────────────────────────────
const Icons = {
  home:     <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M3 9.5L12 3l9 6.5V20a1 1 0 01-1 1H4a1 1 0 01-1-1V9.5z"/><path d="M9 21V12h6v9"/></svg>,
  jobs:     <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="2" y="7" width="20" height="14" rx="2"/><path d="M16 7V5a2 2 0 00-2-2h-4a2 2 0 00-2 2v2"/><line x1="12" y1="12" x2="12" y2="16"/><line x1="10" y1="14" x2="14" y2="14"/></svg>,
  schedule: <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/><line x1="8" y1="14" x2="8" y2="14"/><line x1="12" y1="14" x2="12" y2="14"/><line x1="16" y1="14" x2="16" y2="14"/></svg>,
  invoices: <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><line x1="10" y1="9" x2="8" y2="9"/></svg>,
  more:     <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><circle cx="5" cy="12" r="1.5" fill="currentColor" stroke="none"/><circle cx="12" cy="12" r="1.5" fill="currentColor" stroke="none"/><circle cx="19" cy="12" r="1.5" fill="currentColor" stroke="none"/></svg>,
  belle:    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2z"/><path d="M8 12s1.5 2 4 2 4-2 4-2"/><line x1="9" y1="9" x2="9.01" y2="9"/><line x1="15" y1="9" x2="15.01" y2="9"/></svg>,
  back:     <svg width="10" height="17" viewBox="0 0 10 17" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round"><path d="M8.5 1.5L1.5 8.5l7 7"/></svg>,
  plus:     <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><line x1="8" y1="2" x2="8" y2="14"/><line x1="2" y1="8" x2="14" y2="8"/></svg>,
  phone:    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M22 16.92v3a2 2 0 01-2.18 2 19.79 19.79 0 01-8.63-3.07A19.5 19.5 0 013.7 10.74 19.79 19.79 0 01.67 2.18 2 2 0 012.65 0h3a2 2 0 012 1.72c.127.96.361 1.903.7 2.81a2 2 0 01-.45 2.11L6.91 7.6a16 16 0 006.29 6.29l.97-1.97a2 2 0 012.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0122 16.92z"/></svg>,
  message:  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z"/></svg>,
  map:      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><polygon points="3 6 9 3 15 6 21 3 21 18 15 21 9 18 3 21"/><line x1="9" y1="3" x2="9" y2="18"/><line x1="15" y1="6" x2="15" y2="21"/></svg>,
  camera:   <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M23 19a2 2 0 01-2 2H3a2 2 0 01-2-2V8a2 2 0 012-2h4l2-3h6l2 3h4a2 2 0 012 2z"/><circle cx="12" cy="13" r="4"/></svg>,
  note:     <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z"/></svg>,
  dollar:   <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 000 7h5a3.5 3.5 0 010 7H6"/></svg>,
  check:    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round"><polyline points="20 6 9 17 4 12"/></svg>,
  clock:    <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>,
  user:     <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round" strokeLinejoin="round"><path d="M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>,
  warning:  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>,
  send:     <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>,
  chevronR: <svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round"><path d="M1 1l5 5-5 5"/></svg>,
  pin:      <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 10c0 7-9 13-9 13S3 17 3 10a9 9 0 0118 0z"/><circle cx="12" cy="10" r="3"/></svg>,
  wifi:     <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><path d="M1.42 9A16 16 0 0122.58 9"/><path d="M5.5 12.7A10 10 0 0118.5 12.7"/><path d="M10 16.5a4 4 0 014 0"/><line x1="12" y1="20" x2="12.01" y2="20" strokeWidth="3"/></svg>,
  team:     <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 00-3-3.87"/><path d="M16 3.13a4 4 0 010 7.75"/></svg>,
  sparkle:  <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.4 7.2H22l-6.3 4.6 2.4 7.2L12 17l-6.1 4 2.4-7.2L2 9.2h7.6L12 2z"/></svg>,
};

// ── STATUS BADGE ──────────────────────────────────────────────
function Badge({ status, small }) {
  const map = {
    'paid':        { bg:'#e6f7ef', color:'#0f6b3c', dot:'#1a9e5c', label:'Paid' },
    'sent':        { bg:'#eff6ff', color:'#1e40af', dot:'#2563eb', label:'Sent' },
    'completed':   { bg:'#e6f7ef', color:'#0f6b3c', dot:'#1a9e5c', label:'Completed' },
    'overdue':     { bg:'#fef3e2', color:'#92520a', dot:'#d97706', label:'Overdue' },
    'attention':   { bg:'#fef3e2', color:'#92520a', dot:'#d97706', label:'Attention' },
    'canceled':    { bg:'#fef2f2', color:'#991b1b', dot:'#dc2626', label:'Canceled' },
    'past due':    { bg:'#fef2f2', color:'#991b1b', dot:'#dc2626', label:'Past due' },
    'scheduled':   { bg:'#eff6ff', color:'#1e40af', dot:'#2563eb', label:'Scheduled' },
    'in progress': { bg:'#eff6ff', color:'#1e40af', dot:'#2563eb', label:'In Progress' },
    'on my way':   { bg:'#f0fdf4', color:'#166534', dot:'#16a34a', label:'On My Way' },
    'arrived':     { bg:'#f0fdf4', color:'#166534', dot:'#16a34a', label:'Arrived' },
    'draft':       { bg:'#f3f4f6', color:'#374151', dot:'#6b7280', label:'Draft' },
    'unpaid':      { bg:'#fef3e2', color:'#92520a', dot:'#d97706', label:'Unpaid' },
    'approved':    { bg:'#e6f7ef', color:'#0f6b3c', dot:'#1a9e5c', label:'Approved' },
    'unassigned':  { bg:'#f3f4f6', color:'#374151', dot:'#9ca3af', label:'Unassigned' },
    'cancelled':   { bg:'#fef2f2', color:'#991b1b', dot:'#dc2626', label:'Cancelled' },
    'urgent':      { bg:'#fef2f2', color:'#991b1b', dot:'#dc2626', label:'Urgent' },
  };
  const s = map[status] || map.draft;
  const sz = small ? 10 : 11;
  return (
    <div style={{display:'inline-flex',alignItems:'center',gap:4,background:s.bg,color:s.color,
      fontSize:sz,fontWeight:600,padding: small ? '2px 7px':'3px 8px',borderRadius:999,whiteSpace:'nowrap'}}>
      <div style={{width:small?5:6,height:small?5:6,borderRadius:'50%',background:s.dot,flexShrink:0}}/>
      {s.label}
    </div>
  );
}

// ── BOTTOM TAB BAR ────────────────────────────────────────────
// IA spec: exactly 5 tabs — Home · Jobs · Belle · Schedule · More.
function TabBar({ active, onTab }) {
  const tabs = [
    { id:'home',     label:'Home',     icon: Icons.home },
    { id:'jobs',     label:'Jobs',     icon: Icons.jobs },
    { id:'belle',    label:'Belle',    icon: null },
    { id:'schedule', label:'Schedule', icon: Icons.schedule },
    { id:'more',     label:'More',     icon: Icons.more },
  ];
  return (
    <div style={{
      position:'absolute', bottom:0, left:0, right:0, zIndex:100,
      height:83,
      background:'rgba(248,248,250,0.97)',
      backdropFilter:'saturate(200%) blur(32px)',
      WebkitBackdropFilter:'saturate(200%) blur(32px)',
      borderTop:'0.5px solid rgba(0,0,0,0.08)',
      display:'flex', alignItems:'flex-start', paddingTop:10,
    }}>
      {tabs.map(t => {
        if (t.id === 'belle') {
          const isActive = active === 'belle';
          return (
            <div key="belle" className={`sp-tab-item ${isActive ? 'sp-tab-active' : ''}`} onClick={() => onTab('belle')}
              style={{flex:1,display:'flex',flexDirection:'column',
                alignItems:'center',cursor:'pointer',gap:0,paddingTop:2}}>
              <div className="sp-belle-orb" style={{
                width:40, height:40, borderRadius:'50%',
                background: isActive ? '#0062c4' : '#0071e3',
                display:'flex',alignItems:'center',justifyContent:'center',
                boxShadow:'0 2px 10px rgba(0,113,227,0.38)',
              }}>
                {/* Bell icon — matching real app */}
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M18 8A6 6 0 006 8c0 7-3 9-3 9h18s-3-2-3-9"/>
                  <path d="M13.73 21a2 2 0 01-3.46 0"/>
                </svg>
              </div>
              <span style={{
                fontSize:10, lineHeight:1, marginTop:3,
                fontWeight: isActive ? 600 : 500,
                color: isActive ? '#0071e3' : 'rgba(0,113,227,0.75)',
                letterSpacing:'0.01em',
              }}>Belle</span>
            </div>
          );
        }
        const isActive = active === t.id;
        return (
          <div key={t.id} className={`sp-tab-item ${isActive ? 'sp-tab-active' : ''}`} onClick={() => onTab(t.id)}
            style={{flex:1, display:'flex', flexDirection:'column', alignItems:'center',
              gap:3, cursor:'pointer', paddingTop:2,
              color: isActive ? '#0071e3' : 'rgba(0,0,0,0.26)',
              transition:'color 0.1s'}}>
            <div style={{width:24,height:24,display:'flex',alignItems:'center',justifyContent:'center'}}>
              {React.cloneElement(t.icon, {
                width:22, height:22,
                strokeWidth: isActive ? 2.05 : 1.6,
              })}
            </div>
            <span style={{
              fontSize:10, lineHeight:1,
              fontWeight: isActive ? 600 : 400,
              letterSpacing:'0.01em',
            }}>{t.label}</span>
          </div>
        );
      })}
    </div>
  );
}

// ── TOP NAV HEADER ────────────────────────────────────────────
function NavHeader({ title, subtitle, backLabel, onBack, action, transparent }) {
  const nav = useNav();
  // Special sentinel: onBack="__back" means "use context goBack, hide if unavailable"
  let effectiveOnBack;
  if (onBack === '__back') {
    effectiveOnBack = nav.goBack;  // null when stack is empty → back button hides
  } else if (onBack !== undefined) {
    effectiveOnBack = onBack;
  } else {
    effectiveOnBack = nav.goBack;
  }
  const effectiveLabel = backLabel !== undefined ? backLabel : nav.backLabel;
  const showBack = !!effectiveOnBack;
  return (
    <div className="sp-screen" style={{
      paddingTop: showBack ? 48 : 52,
      paddingBottom: showBack ? 10 : 14,
      paddingLeft: 20,
      paddingRight: 16,
      display:'flex',
      alignItems: showBack ? 'center' : 'flex-end',
      justifyContent:'space-between',
      background: transparent ? 'transparent' : 'linear-gradient(180deg,rgba(248,248,251,0.96),rgba(248,248,251,0.82))',
      backdropFilter:'blur(22px)',
      WebkitBackdropFilter:'blur(22px)',
      borderBottom: transparent ? 'none' : IOS.line,
      position:'sticky',top:0,zIndex:40,
    }}>
      {showBack ? (
        <div style={{display:'flex',alignItems:'center',gap:0,flex:1,minWidth:0}}>
          <div onClick={effectiveOnBack}
            style={{display:'flex',alignItems:'center',gap:5,color:IOS.blue,cursor:'pointer',marginRight:12,
              fontSize:16,fontWeight:500,padding:'4px 0',flexShrink:0}}>
            <span style={{display:'flex',alignItems:'center',color:IOS.blue}}>{Icons.back}</span>
            {effectiveLabel && <span style={{marginLeft:2,maxWidth:110,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{effectiveLabel}</span>}
          </div>
          <div style={{fontSize:17,fontWeight:760,color:IOS.text,letterSpacing:'-0.018em',overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{title}</div>
        </div>
      ) : (
        <div style={{flex:1}}>
          {subtitle && <div style={{fontSize:13,fontWeight:650,color:IOS.faint,marginBottom:2}}>{subtitle}</div>}
          <div style={{fontSize:30,fontWeight:850,color:IOS.text,letterSpacing:'-0.045em',lineHeight:1.08}}>{title}</div>
        </div>
      )}
      {action && <div style={{flexShrink:0}}>{action}</div>}
    </div>
  );
}

// ── SECTION HEADER ────────────────────────────────────────────
function SectionHeader({ title, action, onAction }) {
  return (
    <div style={{padding:'18px 20px 8px',display:'flex',justifyContent:'space-between',alignItems:'baseline'}}>
      <span style={{fontSize:17,fontWeight:800,color:IOS.text,letterSpacing:'-0.025em'}}>{title}</span>
      {action && <span onClick={onAction} style={{fontSize:13.5,color:IOS.blue,cursor:'pointer',fontWeight:700}}>{action}</span>}
    </div>
  );
}

// ── CARD CONTAINER ────────────────────────────────────────────
function Card({ children, style, onClick, mx = 16 }) {
  const [pressed, setPressed] = useState(false);
  return (
    <div
      onClick={onClick}
      onMouseDown={onClick ? () => setPressed(true) : undefined}
      onMouseUp={onClick ? () => setPressed(false) : undefined}
      onMouseLeave={onClick ? () => setPressed(false) : undefined}
      style={{
        margin: `0 ${mx}px`,
        background: pressed ? 'rgba(247,247,248,0.92)' : IOS.card,
        borderRadius:22,
        border:IOS.line,
        overflow:'hidden',
        cursor: onClick ? 'pointer' : undefined,
        transition:'background 0.1s, transform 0.1s',
        boxShadow:IOS.shadow,
        backdropFilter:'blur(18px)',
        WebkitBackdropFilter:'blur(18px)',
        transform: pressed ? 'scale(0.995)' : 'scale(1)',
        ...style,
      }}>
      {children}
    </div>
  );
}

// ── LIST CELL ─────────────────────────────────────────────────
function ListCell({ icon, iconBg, title, subtitle, right, badge, onTap, isLast, chevron=true }) {
  const [pressed, setPressed] = useState(false);
  return (
    <div className="sp-row"
      onClick={onTap}
      onMouseDown={onTap ? () => setPressed(true) : undefined}
      onMouseUp={onTap ? () => setPressed(false) : undefined}
      onMouseLeave={onTap ? () => setPressed(false) : undefined}
      style={{
        padding:'13px 16px',
        display:'flex',alignItems:'center',gap:12,
        background: pressed ? 'rgba(242,242,244,0.74)' : 'transparent',
        borderBottom: isLast ? 'none' : IOS.line,
        cursor: onTap ? 'pointer' : 'default',
        transition:'background 0.1s',
      }}>
      {icon && (
        <div style={{width:38,height:38,borderRadius:10,background:iconBg||'#e8f2fd',
          display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0,color:IOS.blue}}>
          {icon}
        </div>
      )}
      <div style={{flex:1,minWidth:0}}>
        <div style={{fontSize:15,fontWeight:680,color:IOS.text,letterSpacing:'-0.012em',lineHeight:1.3,
          whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{title}</div>
        {subtitle && <div style={{fontSize:13,color:IOS.sub,marginTop:2,letterSpacing:'-0.005em',
          whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>{subtitle}</div>}
      </div>
      {badge && <div style={{flexShrink:0}}>{badge}</div>}
      {right && <div style={{fontSize:13,fontWeight:500,color:'#111',fontVariantNumeric:'tabular-nums',flexShrink:0}}>{right}</div>}
      {chevron && onTap && <div style={{color:'rgba(0,0,0,0.25)',flexShrink:0,marginLeft:4}}>{Icons.chevronR}</div>}
    </div>
  );
}

// ── BIG ACTION BUTTON ─────────────────────────────────────────
function PrimaryButton({ label, icon, onTap, color='#0071e3', textColor='white', style }) {
  const [pressed, setPressed] = useState(false);
  return (
    <div className="sp-pressable" onClick={onTap}
      onMouseDown={() => setPressed(true)} onMouseUp={() => setPressed(false)} onMouseLeave={() => setPressed(false)}
      style={{
        height:52, borderRadius:16, background: pressed ? '#0062c4' : color,
        display:'flex',alignItems:'center',justifyContent:'center',gap:8,
        color:textColor, fontSize:16, fontWeight:600, cursor:'pointer',
        letterSpacing:'-0.012em', transition:'all 0.1s',
        transform: pressed ? 'scale(0.98)' : 'scale(1)',
        ...style,
      }}>
      {icon && <span style={{display:'flex',alignItems:'center'}}>{icon}</span>}
      <span style={{minWidth:0,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{label}</span>
    </div>
  );
}

function SecondaryButton({ label, icon, onTap, style }) {
  const [pressed, setPressed] = useState(false);
  return (
    <div className="sp-pressable" onClick={onTap}
      onMouseDown={() => setPressed(true)} onMouseUp={() => setPressed(false)} onMouseLeave={() => setPressed(false)}
      style={{
        height:48, borderRadius:16, background: pressed ? '#eaeaec' : 'rgba(255,255,255,0.82)',
        display:'flex',alignItems:'center',justifyContent:'center',gap:7,
        color:'#111', fontSize:15, fontWeight:500, cursor:'pointer',
        letterSpacing:'-0.008em', transition:'background 0.1s, transform 0.1s',
        transform: pressed ? 'scale(0.985)' : 'scale(1)',
        ...style,
      }}>
      {icon && <span style={{display:'flex',alignItems:'center',color:'rgba(0,0,0,0.5)'}}>{icon}</span>}
      <span style={{minWidth:0,overflow:'hidden',textOverflow:'ellipsis',whiteSpace:'nowrap'}}>{label}</span>
    </div>
  );
}

// ── QUICK ACTION TILE ─────────────────────────────────────────
function QuickTile({ icon, label, color, bg, onTap }) {
  const [pressed, setPressed] = useState(false);
  return (
    <div className="sp-pressable" onClick={onTap}
      onMouseDown={() => setPressed(true)} onMouseUp={() => setPressed(false)} onMouseLeave={() => setPressed(false)}
      style={{
        flex:1, display:'flex', flexDirection:'column', alignItems:'center',
        gap:6, padding:'12px 4px', background: pressed ? '#eaeaec' : bg||'rgba(255,255,255,0.78)',
        borderRadius:16, cursor:'pointer', transition:'background 0.1s, transform 0.1s', transform: pressed ? 'scale(0.985)' : 'scale(1)', border:IOS.line, minWidth:0,
      }}>
      <div style={{width:40,height:40,borderRadius:11,background:color||'#0071e3',
        display:'flex',alignItems:'center',justifyContent:'center',color:'white'}}>
        {icon}
      </div>
      <span style={{fontSize:11,fontWeight:600,color:'#111',letterSpacing:'-0.005em',textAlign:'center',lineHeight:1.25,maxWidth:'100%',overflow:'hidden',textOverflow:'ellipsis',display:'-webkit-box',WebkitLineClamp:2,WebkitBoxOrient:'vertical'}}>{label}</span>
    </div>
  );
}

// ── BOTTOM SHEET ──────────────────────────────────────────────
function BottomSheet({ open, onClose, title, children, halfHeight }) {
  // Important: fully unmount when closed. Hidden translated sheets were still
  // visible in snapshots and could look like frozen menus inside the phone frame.
  if (!open) return null;
  return (
    <>
      <div className="sp-overlay" onClick={onClose}
        style={{position:'absolute',inset:0,background:'rgba(0,0,0,0.36)',zIndex:200,animation:'spFadeIn 0.16s ease-out'}}/>
      <div className="sp-sheet" role="dialog" aria-modal="true" style={{
        position:'absolute', bottom:0, left:0, right:0, zIndex:201,
        background:'rgba(255,255,255,0.96)', borderRadius:'26px 26px 0 0',
        animation:'spSheetUp 0.28s cubic-bezier(0.32,0.72,0,1)',
        maxHeight: halfHeight ? '55%' : '85%',
        display:'flex', flexDirection:'column',
        boxShadow:'0 -4px 32px rgba(0,0,0,0.12)',
        pointerEvents:'auto', overflow:'hidden',
      }}>
        <div style={{display:'flex',justifyContent:'center',paddingTop:8,paddingBottom:6,flexShrink:0}}>
          <div style={{width:36,height:4,borderRadius:2,background:'rgba(0,0,0,0.15)'}}/>
        </div>
        {title && (
          <div style={{display:'flex',justifyContent:'space-between',alignItems:'center',
            padding:'4px 20px 12px',borderBottom:'0.5px solid rgba(0,0,0,0.08)',flexShrink:0}}>
            <span style={{fontSize:16,fontWeight:600,color:'#111'}}>{title}</span>
            <div onClick={onClose} style={{fontSize:14,color:'#0071e3',cursor:'pointer',fontWeight:500}}>Done</div>
          </div>
        )}
        <div style={{overflowY:'auto',WebkitOverflowScrolling:'touch',overscrollBehavior:'contain',flex:1,paddingBottom:8}}>
          {children}
        </div>
      </div>
    </>
  );
}

// ── BELLE SUGGESTION CARD ─────────────────────────────────────
function BelleSuggestion({ text, actions, onAction }) {
  return (
    <div style={{margin:'10px 16px',background:'#f5f0ff',border:'1px solid rgba(124,58,237,0.14)',
      borderRadius:14,padding:'12px 14px'}}>
      <div style={{display:'flex',alignItems:'center',gap:6,marginBottom:7}}>
        <div style={{width:18,height:18,borderRadius:'50%',background:'linear-gradient(135deg,#7c3aed,#4f46e5)',
          display:'flex',alignItems:'center',justifyContent:'center',flexShrink:0}}>
          <svg width="9" height="9" viewBox="0 0 24 24" fill="white"><path d="M12 2l2.09 6.26L20 9.27l-4.91 4.73 1.18 6.88L12 17.77l-6.27 3.11 1.18-6.88L2 9.27l5.91-1.01L12 2z"/></svg>
        </div>
        <span style={{fontSize:11,fontWeight:700,color:'#7c3aed',letterSpacing:'0.04em',textTransform:'uppercase'}}>Belle</span>
      </div>
      <div style={{fontSize:14,color:'#111',lineHeight:1.55,letterSpacing:'-0.005em'}}>{text}</div>
      {actions && actions.length > 0 && (
        <div style={{display:'flex',gap:8,marginTop:10}}>
          {actions.map((a,i) => (
            <button key={i} onClick={() => onAction && onAction(a)}
              style={{flex: i===0 ? 1.5 : 1, height:34, borderRadius:8,
                background: i===0 ? '#7c3aed' : 'rgba(124,58,237,0.1)',
                color: i===0 ? 'white' : '#4c1d95',
                border:'none',fontSize:13,fontWeight: i===0 ? 600:400,cursor:'pointer'}}>
              {a}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}

// ── STAT CARD ─────────────────────────────────────────────────
function StatCard({ label, value, color, bg, sub, onTap }) {
  const [pressed, setPressed] = useState(false);
  return (
    <div onClick={onTap}
      onMouseDown={onTap?()=>setPressed(true):undefined} onMouseUp={onTap?()=>setPressed(false):undefined} onMouseLeave={onTap?()=>setPressed(false):undefined}
      style={{background:pressed?'#eaeaec':bg||'#e8f2fd',borderRadius:14,padding:'14px 16px',cursor:onTap?'pointer':'default',transition:'background 0.1s'}}>
      <div style={{fontSize:28,fontWeight:700,color:color||'#0071e3',lineHeight:1.1,fontVariantNumeric:'tabular-nums',letterSpacing:'-0.02em'}}>{value}</div>
      <div style={{fontSize:13,fontWeight:500,color:'rgba(0,0,0,0.55)',marginTop:3}}>{label}</div>
      {sub && <div style={{fontSize:11,color:'rgba(0,0,0,0.35)',marginTop:2}}>{sub}</div>}
    </div>
  );
}

// ── AVATAR ────────────────────────────────────────────────────
function Avatar({ name, size=36, color='#e8f2fd', textColor='#0071e3' }) {
  const initials = name.split(' ').map(w=>w[0]).slice(0,2).join('');
  return (
    <div style={{width:size,height:size,borderRadius:'50%',background:color,
      display:'flex',alignItems:'center',justifyContent:'center',
      fontSize:size*0.36,fontWeight:600,color:textColor,flexShrink:0,letterSpacing:'-0.01em'}}>
      {initials}
    </div>
  );
}

// ── OFFLINE BANNER ─────────────────────────────────────────────
function OfflineBanner() {
  return (
    <div style={{margin:'8px 16px',background:'#1a1a1c',borderRadius:10,padding:'10px 14px',
      display:'flex',alignItems:'center',gap:8}}>
      <div style={{color:'#d97706',display:'flex',alignItems:'center'}}>{Icons.wifi}</div>
      <div>
        <div style={{fontSize:13,fontWeight:600,color:'white'}}>Offline mode</div>
        <div style={{fontSize:12,color:'rgba(255,255,255,0.5)'}}>Changes saved locally. Syncing when connection returns.</div>
      </div>
    </div>
  );
}

// ── BELLE HEALTH BANNER ────────────────────────────────────────
// App-root banner shown when Belle is offline. Spec:
// "⚠ Belle is offline. You're in manual mode. Your work will sync when she's back."
function BelleHealthBanner({ belleOnline }) {
  if (belleOnline) return null;
  return (
    <div style={{
      background:'#fef3c7',
      borderBottom:'1px solid #f59e0b',
      padding:'10px 14px',
      display:'flex',alignItems:'center',gap:10,
    }}>
      <div style={{fontSize:15,lineHeight:1}}>⚠</div>
      <div style={{flex:1,minWidth:0}}>
        <div style={{fontSize:12.5,fontWeight:700,color:'#92400e',letterSpacing:'-0.005em'}}>Belle is offline. You're in manual mode.</div>
        <div style={{fontSize:11,color:'#92400e',opacity:0.8,marginTop:1}}>Your work will sync when she's back.</div>
      </div>
    </div>
  );
}

// ── QUICK ACTION RAIL ──────────────────────────────────────────
// Tier-1 horizontally-scrollable manual actions for JobDetailScreen.
// Never routes through Belle. Each item is a direct manual action with
// a simple confirmation. Pass `actions` = [{label, icon, onTap, color}]
function QuickActionRail({ actions }) {
  const [flash, setFlash] = useState(null);
  return (
    <div style={{
      background:'white',
      borderBottom:'0.5px solid rgba(0,0,0,0.07)',
      padding:'10px 0 12px',
    }}>
      <div style={{padding:'0 16px 8px',fontSize:10,fontWeight:700,
        color:'rgba(0,0,0,0.35)',letterSpacing:'0.08em',textTransform:'uppercase'}}>Quick actions</div>
      <div style={{display:'flex',gap:8,padding:'0 16px',overflowX:'auto',
        WebkitOverflowScrolling:'touch',scrollbarWidth:'none'}}>
        {actions.map((a,i) => (
          <div key={a.label} onClick={() => {
              setFlash(a.label);
              setTimeout(()=>setFlash(null), 900);
              a.onTap && a.onTap();
            }}
            style={{flexShrink:0,minWidth:86,height:70,borderRadius:12,
              background: flash===a.label ? '#e6f7ef' : '#f7f7f8',
              border:'0.5px solid rgba(0,0,0,0.08)',
              display:'flex',flexDirection:'column',alignItems:'center',justifyContent:'center',
              gap:6,padding:'6px 10px',cursor:'pointer',transition:'background 0.18s'}}>
            <div style={{width:26,height:26,borderRadius:8,
              background: a.color || '#0071e3',color:'white',
              display:'flex',alignItems:'center',justifyContent:'center'}}>
              {a.icon || <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"><polyline points="20 6 9 17 4 12"/></svg>}
            </div>
            <div style={{fontSize:10.5,fontWeight:600,color:'#111',
              letterSpacing:'-0.005em',textAlign:'center',lineHeight:1.15,
              whiteSpace:'normal'}}>
              {flash===a.label ? '✓ Done' : a.label}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

// ── OVERFLOW MENU (⋯) ─────────────────────────────────────────
// Triggered from a detail screen header. Every item is the manual
// override path for an entity verb. Tag each item with (manual).
function OverflowMenu({ items, title }) {
  const [open, setOpen] = useState(false);
  const [toast, setToast] = useState(null);
  return (
    <>
      <div onClick={() => setOpen(true)}
        style={{width:32,height:32,borderRadius:'50%',
          background:'rgba(255,255,255,0.14)',
          border:'1px solid rgba(255,255,255,0.18)',
          display:'flex',alignItems:'center',justifyContent:'center',cursor:'pointer',color:'white'}}>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor">
          <circle cx="5" cy="12" r="2"/><circle cx="12" cy="12" r="2"/><circle cx="19" cy="12" r="2"/>
        </svg>
      </div>
      <BottomSheet open={open} onClose={()=>setOpen(false)} title={title || 'Manual overrides'} halfHeight>
        <div style={{padding:'4px 12px 8px'}}>
          <div style={{padding:'8px 8px 14px',fontSize:12,color:'rgba(0,0,0,0.5)',lineHeight:1.45}}>
            These are the manual override paths. Belle owns the default flow — use these when you need to bypass her.
          </div>
          {items.map((it, i) => (
            <div key={it.label} onClick={() => {
                setOpen(false);
                if (it.onTap) it.onTap();
                else { setToast(`${it.label} — manual`); setTimeout(()=>setToast(null), 1400); }
              }}
              style={{padding:'13px 14px',display:'flex',alignItems:'center',gap:12,
                borderBottom: i<items.length-1?'0.5px solid rgba(0,0,0,0.06)':'none',
                cursor:'pointer',borderRadius:10}}>
              <div style={{flex:1,minWidth:0}}>
                <div style={{fontSize:15,fontWeight:500,color: it.destructive ? '#dc2626' : '#111',
                  letterSpacing:'-0.008em'}}>{it.label}</div>
                <div style={{fontSize:11.5,color:'rgba(0,0,0,0.4)',marginTop:2}}>{it.sub || '(manual)'}</div>
              </div>
              {Icons.chevronR}
            </div>
          ))}
        </div>
      </BottomSheet>
      {toast && (
        <div style={{position:'absolute',bottom:100,left:'50%',transform:'translateX(-50%)',
          background:'#111',color:'white',padding:'9px 14px',borderRadius:10,
          fontSize:13,fontWeight:500,zIndex:500,boxShadow:'0 6px 24px rgba(0,0,0,0.25)'}}>
          {toast}
        </div>
      )}
    </>
  );
}

// ── BELLE CTA ─────────────────────────────────────────────────
// Primary "Ask Belle to X" button with a small "or do it yourself"
// secondary link. When belleOnline===false the labels flip: manual
// becomes primary, Belle goes away.
function BelleCTA({ askLabel, manualLabel, onAsk, onManual, color, style }) {
  const { belleOnline } = useBelleOnline();
  if (!belleOnline) {
    return (
      <div style={{display:'flex',flexDirection:'column',gap:6,...style}}>
        <PrimaryButton label={manualLabel || 'Do it manually'} color={color || '#0071e3'}
          onTap={onManual || onAsk}/>
        <div style={{textAlign:'center',fontSize:11.5,color:'rgba(0,0,0,0.4)'}}>
          Belle is offline — you're in manual mode.
        </div>
      </div>
    );
  }
  return (
    <div style={{display:'flex',flexDirection:'column',gap:6,...style}}>
      <PrimaryButton
        label={askLabel || 'Ask Belle'}
        color={color || '#7c3aed'}
        onTap={onAsk}
        icon={<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.09 6.26L20 9.27l-4.91 4.73 1.18 6.88L12 17.77l-6.27 3.11 1.18-6.88L2 9.27l5.91-1.01L12 2z"/></svg>}
      />
      {onManual && (
        <div onClick={onManual}
          style={{textAlign:'center',fontSize:12.5,color:'#0071e3',cursor:'pointer',
            padding:'4px 0',fontWeight:500,letterSpacing:'-0.005em'}}>
          or do it yourself
        </div>
      )}
    </div>
  );
}

// ── EMPTY STATE (Ask Belle to [verb]) ──────────────────────────
function EmptyState({ verb, manualLabel, onAsk, onManual, icon }) {
  const { belleOnline } = useBelleOnline();
  return (
    <div style={{display:'flex',flexDirection:'column',alignItems:'center',
      padding:'48px 24px',gap:14,textAlign:'center'}}>
      <div style={{width:56,height:56,borderRadius:'50%',
        background:'linear-gradient(135deg,#f5f0ff,#e8f2fd)',
        display:'flex',alignItems:'center',justifyContent:'center',
        color:'#7c3aed'}}>
        {icon || <svg width="26" height="26" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.09 6.26L20 9.27l-4.91 4.73 1.18 6.88L12 17.77l-6.27 3.11 1.18-6.88L2 9.27l5.91-1.01L12 2z"/></svg>}
      </div>
      <div>
        <div style={{fontSize:16,fontWeight:600,color:'#111',letterSpacing:'-0.01em'}}>
          {belleOnline ? `Ask Belle to ${verb}` : `Ready to ${verb} manually`}
        </div>
        <div style={{fontSize:12.5,color:'rgba(0,0,0,0.45)',marginTop:6,lineHeight:1.45,maxWidth:260}}>
          {belleOnline
            ? "She'll handle the flow end-to-end. You can always take over."
            : "Belle is offline — you're in manual mode until she's back."}
        </div>
      </div>
      <div style={{display:'flex',flexDirection:'column',gap:8,width:'100%',maxWidth:280}}>
        {belleOnline ? (
          <>
            <PrimaryButton label={`Ask Belle to ${verb}`} color="#7c3aed" onTap={onAsk}
              icon={<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2l2.09 6.26L20 9.27l-4.91 4.73 1.18 6.88L12 17.77l-6.27 3.11 1.18-6.88L2 9.27l5.91-1.01L12 2z"/></svg>}/>
            {onManual && (
              <div onClick={onManual}
                style={{textAlign:'center',fontSize:13,color:'#0071e3',cursor:'pointer',fontWeight:500}}>
                or do it yourself
              </div>
            )}
          </>
        ) : (
          <PrimaryButton label={manualLabel || 'Do it manually'} color="#0071e3"
            onTap={onManual || onAsk}/>
        )}
      </div>
    </div>
  );
}


function PermissionLimitedScreen({ onNav, title }) {
  return (
    <div style={{minHeight:'100%',paddingBottom:110,background:'linear-gradient(180deg,#f8f8fb 0%,#f2f2f7 100%)'}}>
      <NavHeader title="Limited access" onBack="__back"/>
      <div style={{padding:'18px 16px'}}>
        <div style={{borderRadius:24,padding:18,background:'rgba(255,255,255,0.86)',border:'0.5px solid rgba(0,0,0,0.06)',boxShadow:'0 10px 24px rgba(15,23,42,0.06)',textAlign:'center'}}>
          <div style={{width:52,height:52,borderRadius:18,background:'#eef6ff',color:'#007aff',display:'inline-flex',alignItems:'center',justifyContent:'center',fontSize:24}}>🔐</div>
          <div style={{fontSize:22,fontWeight:850,letterSpacing:'-0.045em',marginTop:12}}>{title || 'Owner-only area'}</div>
          <div style={{fontSize:13,color:'rgba(17,24,39,0.52)',lineHeight:1.45,marginTop:7}}>Technician mode is field-safe: jobs, schedule, handoff notes, parts used, photos, and issue reporting only.</div>
          <PrimaryButton label="Back to field work" onTap={()=>onNav('jobs')} style={{marginTop:16}}/>
        </div>
      </div>
    </div>
  );
}

// ── MENU OVERLAY (slide-up sheet) ─────────────────────────────
// IA spec: More menu → Jobs, Customers, Billing, Conversations, Settings
function MenuOverlay({ open, onClose, onNav, role, onRoleChange, plan='standard', onPlanChange, belleOnline, onToggleBelle }) {
  const isTech = role === 'technician';
  const premium = (typeof isPremiumPlan === 'function') ? isPremiumPlan(plan) : !!String(plan||'').toLowerCase().match(/premium|pro|ops/);
  const settingsIcon = <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.9" strokeLinecap="round"><circle cx="12" cy="12" r="3"/><path d="M19.07 4.93l-1.41 1.41M5.93 5.93l-1.41-1.41M4 12H2M22 12h-2M19.07 19.07l-1.41-1.41M5.93 18.07l-1.41 1.41M12 22v-2M12 4V2"/></svg>;
  const lockRoute = (feature) => ({ screen:'feature-detail', params:{feature} });
  const premiumItem = (item, feature) => premium ? item : { ...item, label:item.label + ' · Premium', locked:true, ...lockRoute(feature) };
  const sections = isTech ? [
    { title:'FIELD WORK', items:[
      { icon: Icons.home, label:'Home', screen:'home' },
      { icon: Icons.jobs, label:'My Jobs', screen:'jobs' },
      { icon: Icons.schedule, label:'My Schedule', screen:'schedule' },
      { icon: Icons.note, label:'Belle handoff', screen:'handoff' },
      ...(premium ? [
        { icon: Icons.sparkle, label:'Voice commands', screen:'feature-detail', params:{feature:'voice-commands'} },
        { icon: Icons.camera, label:'Parts used', screen:'inventory' },
      ] : []),
    ]},
    { title:'REPORT', items:[
      { icon: Icons.sparkle, label:'Report scope / price issue', screen:'belle', params:{prompt:'Report a scope or pricing issue to the owner'} },
      { icon: Icons.message, label:'Job messages', screen:'conversations' },
    ]},
    { title:'SYSTEM', items:[{ icon: settingsIcon, label:'Settings', screen:'settings' }]},
  ] : [
    { title:'CORE', items:[
      { icon: Icons.home, label:'Home', screen:'home' },
      { icon: Icons.jobs, label:'Jobs', screen:'jobs' },
      { icon: Icons.user, label:'Customers', screen:'customers' },
      { icon: Icons.schedule, label:'Schedule', screen:'schedule' },
    ]},
    { title:'OPERATIONS', items:[
      premiumItem({ icon: Icons.warning, label:'Approval Center', screen:'approvals' }, 'approvals'),
      premiumItem({ icon: Icons.dollar, label:'Job Costing', screen:'job-costing' }, 'job-costing'),
      premiumItem({ icon: Icons.camera, label:'Parts + Inventory', screen:'inventory' }, 'receipts-inventory'),
      premiumItem({ icon: Icons.team, label:'Reports', screen:'reports' }, 'reports'),
    ]},
    { title:'MONEY & COMMS', items:[
      { icon: Icons.invoices, label:'Billing', screen:'billing' },
      { icon: Icons.message, label:'Conversations', screen:'conversations' },
      premiumItem({ icon: Icons.phone, label:'Outbound Belle', screen:'feature-detail', params:{feature:'outbound-belle'} }, 'outbound-belle'),
    ]},
    { title:'SYSTEM', items:[{ icon: settingsIcon, label:'Settings', screen:'settings' }, { icon: Icons.check, label:'Plans', screen:'plans' }]},
  ];

  function handleNav(itemOrScreen) {
    const item = typeof itemOrScreen === 'string' ? { screen:itemOrScreen } : itemOrScreen;
    onClose();
    onNav(item.screen, { ...(item.params||{}), __fromMenu: true });
  }

  return (
    <>
      {open && (
        <div className="sp-overlay" onClick={onClose}
          style={{position:'absolute',inset:0,background:'rgba(0,0,0,0.4)',zIndex:200}}/>
      )}
      <div className="sp-sheet" style={{
        position:'absolute', bottom:0, right:0, zIndex:201,
        width:'76%',
        height:'70%',
        background:'rgba(242,242,247,0.96)',
        backdropFilter:'blur(24px)',
        WebkitBackdropFilter:'blur(24px)',
        borderRadius:'26px 0 0 0',
        borderTop:'0.5px solid rgba(255,255,255,0.8)',
        borderLeft:'0.5px solid rgba(255,255,255,0.8)',
        transform: open ? 'translateY(0)' : 'translateY(100%)',
        transition:'transform 0.32s cubic-bezier(0.32,0.72,0,1)',
        pointerEvents: open ? 'auto' : 'none',
        display:'flex', flexDirection:'column',
        boxShadow:'-4px -4px 32px rgba(0,0,0,0.18)',
        overflow:'hidden',
      }}>
        {/* Handle */}
        <div style={{display:'flex',justifyContent:'center',padding:'10px 0 6px',flexShrink:0}}>
          <div style={{width:32,height:4,borderRadius:2,background:'rgba(0,0,0,0.15)'}}/>
        </div>

        <div style={{overflowY:'auto',WebkitOverflowScrolling:'touch',overscrollBehavior:'contain',flex:1,paddingBottom:96}}>
          <div style={{marginBottom:6}}>
            <div style={{padding:'8px 14px 4px',fontSize:11,fontWeight:600,
              color:'rgba(0,0,0,0.35)',letterSpacing:'0.05em'}}>
              VIEW AS
            </div>
            <div style={{margin:'0 10px',background:IOS.card,borderRadius:18,
              overflow:'hidden',border:IOS.line,boxShadow:IOS.shadow}}>
              {[
                { id:'technician', label:'Technician', sub:'Next job + schedule' },
                { id:'owner-solo', label:'Solo Owner', sub:'Schedule plus revenue' },
                { id:'owner-team', label:'Team Owner', sub:'Dispatch plus revenue' },
              ].map((opt, i) => {
                const active = role === opt.id || (opt.id === 'owner-team' && (role === 'owner' || role === 'dispatcher'));
                return (
                  <div key={opt.id} onClick={() => { onRoleChange && onRoleChange(opt.id); handleNav('home'); }}
                    style={{minHeight:54,padding:'0 12px',display:'flex',alignItems:'center',gap:10,
                      borderBottom: i < 2 ? '0.5px solid rgba(0,0,0,0.07)' : 'none',cursor:'pointer',
                      background: active ? '#eef6ff' : 'white'}}>
                    <div style={{width:22,height:22,borderRadius:'50%',background:active?'#007aff':'#f2f2f7',
                      display:'flex',alignItems:'center',justifyContent:'center',color:'white',flexShrink:0}}>
                      {active ? React.cloneElement(Icons.check,{width:13,height:13,strokeWidth:2.4}) : null}
                    </div>
                    <div style={{flex:1,minWidth:0}}>
                      <div style={{fontSize:14,fontWeight:650,color:'#111',letterSpacing:'-0.01em'}}>{opt.label}</div>
                      <div style={{fontSize:11,color:'rgba(0,0,0,0.45)',marginTop:2}}>{opt.sub}</div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>


          {!isTech && onPlanChange && (
            <div style={{marginBottom:6}}>
              <div style={{padding:'8px 14px 4px',fontSize:11,fontWeight:600,color:'rgba(0,0,0,0.35)',letterSpacing:'0.05em'}}>PLAN PREVIEW</div>
              <div style={{margin:'0 10px',background:IOS.card,borderRadius:18,overflow:'hidden',border:IOS.line,boxShadow:IOS.shadow}}>
                {['standard','premium'].map((p,i)=>(
                  <div key={p} onClick={()=>onPlanChange(p)} style={{minHeight:46,padding:'0 12px',display:'flex',alignItems:'center',gap:10,borderBottom:i===0?'0.5px solid rgba(0,0,0,0.07)':'none',cursor:'pointer',background:plan===p?'#eef6ff':'white'}}>
                    <div style={{width:20,height:20,borderRadius:'50%',background:plan===p?'#007aff':'#f2f2f7',display:'flex',alignItems:'center',justifyContent:'center',color:'white'}}>{plan===p && React.cloneElement(Icons.check,{width:12,height:12})}</div>
                    <div style={{flex:1,fontSize:14,fontWeight:650,color:'#111',textTransform:'capitalize'}}>{p}</div>
                    {p==='premium' && <div style={{fontSize:10,fontWeight:800,color:'#7c3aed'}}>OPS+</div>}
                  </div>
                ))}
              </div>
            </div>
          )}

          {sections.map(sec => (
            <div key={sec.title} style={{marginBottom:6}}>
              <div style={{padding:'8px 14px 4px',fontSize:11,fontWeight:600,
                color:'rgba(0,0,0,0.35)',letterSpacing:'0.05em'}}>
                {sec.title}
              </div>
              <div style={{margin:'0 10px',background:IOS.card,borderRadius:18,
                overflow:'hidden',border:IOS.line,boxShadow:IOS.shadow}}>
                {sec.items.map((item, i) => (
                  <div key={item.label} onClick={() => handleNav(item)}
                    style={{
                      minHeight:50,
                      padding:'0 12px',
                      display:'flex', alignItems:'center', gap:10,
                      borderBottom: i < sec.items.length-1
                        ? '0.5px solid rgba(0,0,0,0.07)' : 'none',
                      cursor:'pointer', opacity:item.locked?0.62:1,
                    }}>
                    <div style={{width:24,height:24,borderRadius:6,
                      background:'#f2f2f7',
                      display:'flex',alignItems:'center',justifyContent:'center',
                      color:'rgba(0,0,0,0.45)',flexShrink:0}}>
                      {React.cloneElement(item.icon, {width:14,height:14,strokeWidth:1.8})}
                    </div>
                    <div style={{flex:1,fontSize:14,fontWeight:400,color:'#111',
                      letterSpacing:'-0.01em',lineHeight:1}}>{item.label}</div>
                    {item.locked && <div style={{fontSize:12}}>🔒</div>}
                    <svg width="6" height="10" viewBox="0 0 7 12" fill="none"
                      stroke="rgba(0,0,0,0.18)" strokeWidth="2" strokeLinecap="round">
                      <path d="M1 1l5 5-5 5"/>
                    </svg>
                  </div>
                ))}
              </div>
            </div>
          ))}

          {/* Dev toggle: Belle online/offline (demo only) */}
          {onToggleBelle && (
            <div style={{marginTop:10}}>
              <div style={{padding:'8px 14px 4px',fontSize:11,fontWeight:600,
                color:'rgba(0,0,0,0.35)',letterSpacing:'0.05em'}}>
                DEMO
              </div>
              <div style={{margin:'0 10px 10px',background:IOS.card,borderRadius:18,
                border:IOS.line,padding:'10px 14px',boxShadow:IOS.shadow,
                display:'flex',alignItems:'center',gap:10}}>
                <div style={{fontSize:17,lineHeight:1}}>{belleOnline ? '🟢' : '🟡'}</div>
                <div style={{flex:1}}>
                  <div style={{fontSize:13.5,fontWeight:600,color:'#111'}}>
                    Belle is {belleOnline ? 'online' : 'offline'}
                  </div>
                  <div style={{fontSize:11,color:'rgba(0,0,0,0.45)',marginTop:1}}>
                    Flip to preview manual-mode state
                  </div>
                </div>
                <div onClick={(e) => { e.stopPropagation(); onToggleBelle(); }}
                  style={{width:42,height:24,borderRadius:12,cursor:'pointer',
                    background: belleOnline ? '#34c759' : '#e2e2e6',
                    padding:'0 3px',display:'flex',alignItems:'center',
                    transition:'background 0.18s'}}>
                  <div style={{width:18,height:18,borderRadius:'50%',background:'white',
                    transform: belleOnline ? 'translateX(18px)' : 'translateX(0)',
                    transition:'transform 0.2s',
                    boxShadow:'0 1px 4px rgba(0,0,0,0.15)'}}/>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    </>
  );
}

Object.assign(window, {
  Icons, Badge, TabBar, NavHeader, SectionHeader, Card, ListCell,
  PrimaryButton, SecondaryButton, QuickTile, BottomSheet,
  BelleSuggestion, StatCard, Avatar, OfflineBanner, MenuOverlay,
  BelleHealthBanner, PermissionLimitedScreen, QuickActionRail, OverflowMenu, BelleCTA, EmptyState,
  BelleOnlineContext, useBelleOnline,
  IOS, screenBg, glassStyle, IOSPlusButton,
  SCREEN_LABELS, screenLabel, NavContext, useNav,
});
