// Owner persona — desktop business dashboard.
// Owner has all clinician permissions PLUS revenue/utilisation/owner KPIs.

// Owner sidebar — restructured 17 May. Enquiries + Templates + Workflows now
// live inside Marketing (the the demo CRM replacement). Revenue + Reports +
// Utilisation now live inside Finance (the KPI/cashflow tracker). Settings
// keeps everything else (clinic details, team, hours, rooms, treatments,
// pricing, notifications, integrations).
const OwNav = [
  { id: 'today',     label: 'Today',     icon: 'home',     section: 'Run the clinic' },
  { id: 'bookings',  label: 'Bookings',  icon: 'calendar', section: 'Run the clinic' },
  { id: 'inbox',     label: 'Inbox',     icon: 'mail',     section: 'Run the clinic' },
  { id: 'queue',     label: 'Queue',     icon: 'clock',    section: 'Run the clinic' },
  { id: 'customers', label: 'Customers', icon: 'users',    section: 'Records' },
  { id: 'capture',   label: 'Capture',   icon: 'camera',   section: 'Records' },
  { id: 'calendar',  label: 'Calendar',  icon: 'calendar', section: 'Records' },
  { id: 'marketing', label: 'Marketing', icon: 'sparkle',  section: 'Business' },
  { id: 'bookingpage', label: 'Booking page', icon: 'phone', section: 'Business' },
  { id: 'reports',   label: 'Reports',   icon: 'chart',    section: 'Business' },
  { id: 'finance',   label: 'Finance',   icon: 'pound',    section: 'Business' },
];

function OwnerShell({ route, setRoute, tweaks, theme, onToggleTheme, runtimePhotos, setRuntimePhotos, runtimeNotes, setRuntimeNotes }) {
  const screen = route.screen || 'today';
  const [settings, setSettings] = React.useState(false);
  const [walkIn, setWalkIn] = React.useState({ open: false, mode: 'walkin' });
  const [newCust, setNewCust] = React.useState(false);
  const [cashUp, setCashUp] = React.useState(null);
  const [showForm, setShowForm] = React.useState(null);
  const [notifs, setNotifs] = React.useState(false);
  const [help, setHelp] = React.useState(false);
  // Master switch for the dashed-blue demo notes scattered through the app
  const [notesOn, setNotesOn] = React.useState(false);
  React.useEffect(() => {
    document.documentElement.setAttribute('data-demo-notes', notesOn ? 'on' : 'off');
  }, [notesOn]);
  const [activeCustomer, setActiveCustomer] = React.useState('sophie');

  const unreadNotifs = NOTIFICATIONS.length;
  const handleNotifAction = (n) => {
    if (n.link?.customerId) {
      setActiveCustomer(n.link.customerId);
      setRoute({ screen: 'record', customerId: n.link.customerId });
    } else if (n.link?.pendingId) {
      setRoute({ screen: 'today' });
    }
  };

  const navId =
    screen === 'record' ? 'customers' :
    screen === 'lead'   ? 'marketing' :
    screen === 'enquiries' ? 'marketing' :
    screen === 'revenue' || screen === 'utilisation' ? 'finance' :
    screen;
  // On mobile we render a flat 8-button nav; on desktop we keep the grouped
  // sidebar with section headers ("Run the clinic" / "Records" / "Business").
  // display:contents on the section .cl-nav doesn't reliably flatten flex
  // children in iOS Safari so we branch on viewport here instead.
  const isPhone = useMediaQuery('(max-width: 900px)');

  // group nav by section
  const grouped = OwNav.reduce((acc, n) => {
    (acc[n.section] = acc[n.section] || []).push(n);
    return acc;
  }, {});

  return (
    <div className={'owner-shell' + (tweaks.ownerLayout === 'compact' ? ' compact' : '')}>
      <aside className="cl-side">
        <div className="cl-brand"><span className="dot"/>Demo Clinic · owner</div>
        {isPhone ? (
          <div className="cl-nav">
            {OwNav.map(n => (
              <button key={n.id} className={navId === n.id ? 'active' : ''} onClick={() => setRoute({ screen: n.id })}>
                <Icon name={n.icon} size={16}/><span className="nav-label">{n.label}</span>
              </button>
            ))}
          </div>
        ) : Object.entries(grouped).map(([sec, items]) => (
          <React.Fragment key={sec}>
            <div style={{ fontSize: 10, letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--fg-3)', padding: '14px 12px 6px' }}>{sec}</div>
            <div className="cl-nav">
              {items.map(n => (
                <button key={n.id} className={navId === n.id ? 'active' : ''} onClick={() => setRoute({ screen: n.id })}>
                  <Icon name={n.icon} size={16}/><span className="nav-label">{n.label}</span>
                </button>
              ))}
          </div>
          </React.Fragment>
        ))}
        <div className="cl-side-foot">
          <span className="avatar" style={{ background: 'var(--ink)', color: '#fff' }}>EC</span>
          <div className="who"><b>Emma Carter</b><span>Clinical director</span></div>
        </div>
      </aside>
      <main className="cl-main">
        {/* Notification bell sits in the top-right of the main area */}
        <div className="cl-toolbar">
          <button className={'notif-bell' + (notesOn ? '' : ' toggle-off')} onClick={() => setNotesOn(o => !o)}
            aria-label={notesOn ? 'Hide demo notes' : 'Show demo notes'}
            title={notesOn ? 'Hide the dashed demo notes' : 'Show the dashed demo notes'}><span style={{ fontFamily: 'var(--font-display)', fontStyle: 'italic', fontSize: 15, lineHeight: 1 }}>i</span></button>
          <button className="notif-bell" onClick={onToggleTheme} aria-label={theme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'} title={theme === 'dark' ? 'Light mode' : 'Dark mode'}>
            {theme === 'dark' ? (
              <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
                <circle cx="12" cy="12" r="4"/>
                <path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4"/>
              </svg>
            ) : (
              <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
                <path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8z"/>
              </svg>
            )}
          </button>
          <button className="notif-bell" onClick={() => setHelp(true)} aria-label="Help" title="Help">
            <span style={{ fontSize: 15, fontWeight: 500, lineHeight: 1 }}>?</span>
          </button>
          <NotificationBell count={unreadNotifs} onOpen={() => setNotifs(true)}/>
        </div>
        {screen === 'today' && <OwToday onSettings={() => setSettings(true)} onOpenForm={(cid) => setShowForm(cid)}/>}
        {screen === 'bookings' && <ClToday viewerName="Emma" setRoute={setRoute} setActive={setActiveCustomer} onWalkIn={() => setWalkIn({ open: true, mode: 'walkin' })} onNewBooking={() => setWalkIn({ open: true, mode: 'future' })} onNewCustomer={() => setNewCust(true)} onCheckOut={(a) => setCashUp(a)} tweaks={tweaks}/>}
        {screen === 'inbox' && <ClInbox/>}
        {screen === 'queue' && <OwQueue onOpenRecord={(id) => { setActiveCustomer(id); setRoute({ screen: 'record', customerId: id }); }}/>}
        {screen === 'customers' && <ClCustomerList setActive={(id) => { setActiveCustomer(id); setRoute({ screen: 'record', customerId: id }); }} onNew={() => setNewCust(true)}/>}
        {screen === 'record' && <ClRecord customerId={route.customerId || activeCustomer} setRoute={setRoute} tweaks={tweaks} runtimePhotos={runtimePhotos} setRuntimePhotos={setRuntimePhotos} runtimeNotes={runtimeNotes} setRuntimeNotes={setRuntimeNotes}/>}
        {screen === 'capture' && <ClCapture customerId={route.customerId || activeCustomer} setRoute={setRoute} runtimePhotos={runtimePhotos} setRuntimePhotos={setRuntimePhotos}/>}
        {screen === 'calendar' && <OwCalendar onNewBooking={() => setWalkIn({ open: true, mode: 'future' })}/>}
        {/* Marketing — the demo CRM replacement. Holds Enquiries, Workflows, Templates, Performance. */}
        {screen === 'marketing' && <OwMarketing route={route} setRoute={setRoute}/>}
        {screen === 'bookingpage' && <OwBookingPage/>}
        {screen === 'enquiries' && <OwMarketing route={route} setRoute={setRoute} forceTab="enquiries"/>}
        {screen === 'lead' && <LeadDetail leadId={route.leadId} onBack={() => setRoute({ screen: 'marketing', tab: 'enquiries' })} onOpenCompose={(channel) => { /* hooked into a future SendMessageModal */ }}/>}
        {/* Finance — KPI tracker, weekly input, VAT, projections, pay rates, pricing calc.
            PIN-gated and blur-on-blur (owner private financial data). */}
        {screen === 'finance' && <OwFinance route={route} setRoute={setRoute}/>}
        {screen === 'revenue' && <OwFinance route={{ ...route, tab: 'revenue' }} setRoute={setRoute}/>}
        {screen === 'reports' && <OwReports onOpenRecord={(id) => { setActiveCustomer(id); setRoute({ screen: 'record', customerId: id }); }}/>}
        {screen === 'utilisation' && <OwFinance route={{ ...route, tab: 'utilisation' }} setRoute={setRoute}/>}
      </main>

      {settings && <SettingsModal onClose={() => setSettings(false)}/>}
      {walkIn.open && <WalkInModal mode={walkIn.mode} onClose={() => setWalkIn({ open: false, mode: 'walkin' })}/>}
      {newCust && <NewCustomerModal onClose={() => setNewCust(false)}/>}
      {cashUp && <CashUpModal appt={cashUp} onClose={() => setCashUp(null)} onRebook={() => { setCashUp(null); setWalkIn({ open: true, mode: 'future' }); }}/>}
      {showForm && <MedicalFormModal customerId={showForm} onClose={() => setShowForm(null)}/>}
      {notifs && <NotificationPanel onClose={() => setNotifs(false)} onAction={handleNotifAction}/>}
      {help && <HelpModal onClose={() => setHelp(false)}/>}
    </div>
  );
}

function Sparkline({ values, color = 'var(--blush-deep)' }) {
  const w = 100, h = 32;
  const max = Math.max(...values), min = Math.min(...values);
  const pts = values.map((v, i) => {
    const x = (i / (values.length - 1)) * w;
    const y = h - ((v - min) / (max - min || 1)) * h;
    return `${x.toFixed(1)},${y.toFixed(1)}`;
  }).join(' ');
  return (
    <svg className="spark" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
      <polyline fill="none" stroke={color} strokeWidth="1.5" points={pts}/>
    </svg>
  );
}


// Help — quick guides + how team access works. All demo content.
function HelpModal({ onClose }) {
  const topics = [
    { icon: 'sparkle',  title: 'Getting started',               sub: 'A 10-minute tour of the day-to-day' },
    { icon: 'calendar', title: 'The booking journey',            sub: 'Requests, approvals, deposits and forms' },
    { icon: 'mail',     title: 'Automations and the queue',      sub: 'What sends, when, and why things get skipped' },
    { icon: 'pound',    title: 'Payments, deposits and cash-up', sub: 'Taking money and closing the day' },
  ];
  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <div><span className="eyebrow">Help</span><h2>Guides &amp; support</h2></div>
          <button className="app-btn ghost icon-only" onClick={onClose}><Icon name="close" size={16}/></button>
        </div>
        {topics.map(t => (
          <div key={t.title} className="option-card" style={{ cursor: 'pointer' }}>
            <span className="leading"><Icon name={t.icon} size={16}/></span>
            <div className="body"><h4>{t.title}</h4><p>{t.sub}</p></div>
            <span className="trail"><Icon name="chevR" size={14}/></span>
          </div>
        ))}
        <div style={{ padding: '12px 14px', marginTop: 12, borderRadius: 4, background: 'var(--blush-soft)', border: '1px solid var(--line)', fontSize: 13, lineHeight: 1.55, color: 'var(--fg-2)' }}>
          <b style={{ color: 'var(--fg-1)' }}>In the finished system</b> these open illustrated, step-by-step guides written around your clinic’s own setup — so training doesn’t depend on whoever is on shift.
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 16 }}>
          <span style={{ fontSize: 12, color: 'var(--fg-3)' }}>Stuck? We reply the same working day.</span>
          <button className="app-btn primary"><Icon name="mail" size={14}/>Message us</button>
        </div>
      </div>
    </div>
  );
}


// The client-facing booking page, storyboarded. What a prospect's clients would see.
function OwBookingPage() {
  const Frame = ({ step, title, children, caption }) => (
    <div style={{ flex: '1 1 260px', maxWidth: 420 }}>
      <div style={{ border: '1px solid var(--line)', borderRadius: 22, background: 'var(--bg-card)', padding: '18px 14px', minHeight: 330, boxShadow: 'var(--shadow-1)' }}>
        <div style={{ fontSize: 10, letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--fg-3)', marginBottom: 2 }}>Step {step}</div>
        <div style={{ fontFamily: 'var(--font-display)', fontSize: 19, color: 'var(--fg-1)', marginBottom: 12 }}>{title}</div>
        {children}
      </div>
      <div style={{ fontSize: 12, color: 'var(--fg-3)', marginTop: 8, lineHeight: 1.5 }}>{caption}</div>
    </div>
  );
  const Row = ({ l, r }) => (
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '10px 10px', border: '1px solid var(--line)', borderRadius: 8, marginBottom: 8, fontSize: 13 }}>
      <span style={{ color: 'var(--fg-1)' }}>{l}</span><span style={{ color: 'var(--fg-3)' }}>{r}</span>
    </div>
  );
  return (
    <>
      <div className="cl-head">
        <div>
          <span className="eyebrow">What your clients see</span>
          <h1>Your booking page<DemoNote title="Your page, your name" text="This page lives at your own web address, in your branding. Clients book you directly — no marketplace listing in the middle, no commission on your own clients, and no login wall or internal codes on the menu."/></h1>
        </div>
      </div>

      <div style={{ display: 'flex', gap: 20, flexWrap: 'wrap', alignItems: 'flex-start' }}>
        <Frame step={1} title="Choose a treatment" caption="Plain treatment names and real prices.">
          <Row l="Laser Hair Removal" r="£105"/>
          <Row l="HydraFacial" r="£145"/>
          <Row l="Anti-Wrinkle Injections" r="£250"/>
          <Row l="RF Microneedling" r="£295"/>
          <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 10 }}>New to laser? The page offers the patch-test consultation first.</div>
        </Frame>
        <Frame step={2} title="Pick a real time" caption="Only genuinely free times are offered, straight from the live diary.">
          <div style={{ fontSize: 12, color: 'var(--fg-3)', marginBottom: 8 }}>Thursday 3 September</div>
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 6 }}>
            {['09:30','10:15','11:45','14:00','15:30','16:15'].map(t => (
              <span key={t} style={{ textAlign: 'center', padding: '8px 0', border: '1px solid ' + (t === '14:00' ? 'var(--ink)' : 'var(--line)'), borderRadius: 6, fontSize: 12.5, background: t === '14:00' ? 'var(--blush-soft)' : 'transparent' }}>{t}</span>
            ))}
          </div>
          <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 10 }}>With Grace · 60 min</div>
        </Frame>
        <Frame step={3} title="Secure the booking" caption="Deposit taken up front; the medical form is signed before they arrive.">
          <Row l="HydraFacial · Thu 14:00" r="£145"/>
          <Row l="Deposit due now" r="£72.50"/>
          <div style={{ textAlign: 'center', padding: '11px 0', borderRadius: 8, background: 'var(--ink)', color: 'var(--bone)', fontSize: 12.5, letterSpacing: '0.08em', textTransform: 'uppercase', marginBottom: 10 }}>Pay £72.50 deposit</div>
          <div style={{ fontSize: 11, color: 'var(--fg-3)', lineHeight: 1.5 }}>Free cancellation until 72 hours before. Your medical form arrives with the confirmation — two minutes on your phone.</div>
        </Frame>
      </div>

      <div className="panel" style={{ marginTop: 24, padding: '14px 18px', display: 'flex', gap: 12, alignItems: 'center', flexWrap: 'wrap' }}>
        <Icon name="sparkle" size={16}/>
        <div style={{ fontSize: 13, color: 'var(--fg-2)', flex: 1, minWidth: 220 }}>
          <b style={{ color: 'var(--fg-1)' }}>Your own address, zero commission.</b> Clients book at your website — not through a marketplace that lists your competitors next to you and takes a cut of your own clients.
        </div>
      </div>
    </>
  );
}

function OwToday({ onSettings, onOpenForm }) {
  const [closeDay, setCloseDay] = React.useState(false);
  const kpis = [
    { lbl: 'Today bookings', val: 6, delta: '+1 vs avg', up: true, spark: [3,5,4,6,4,5,6] },
    { lbl: 'Revenue (today)', val: '£1,510', delta: '+£295', up: true, spark: [800,1100,950,1200,1300,1100,1510] },
    { lbl: 'Pending approval', val: PENDING_BOOKINGS.length, delta: 'online bookings', up: true, spark: [1,2,3,2,4,3,4] },
    { lbl: 'No-shows (week)', val: 2, delta: '-1', up: true, spark: [4,3,5,3,2,3,2] },
  ];
  return (
    <>
      <div className="cl-head">
        <div><span className="eyebrow">{new Date().toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long' })}</span><h1>The clinic, at a glance.<DemoNote title="Team logins" text="Every member of staff gets their own login with its own permissions — a therapist sees their diary, clients and tasks; reception sees bookings and payments; finance stays owner-only. This demo shows the owner’s view of everything."/></h1></div>
        <div className="actions">
          <button className="app-btn"><Icon name="upload" size={14}/>Export</button>
          <button className="app-btn" onClick={() => setCloseDay(true)}><Icon name="pound" size={14}/>Close day</button>
          <button className="app-btn primary" onClick={onSettings}><Icon name="settings" size={14}/>Settings</button>
        </div>
      </div>

      <div className="kpi-grid">
        {kpis.map(k => (
          <div key={k.lbl} className="kpi">
            <div className="lbl">{k.lbl}</div>
            <div className="val">{k.val}</div>
            <div className={'delta ' + (k.up ? 'up' : 'down')}>
              <Icon name="arrow" size={12} style={{ transform: k.up ? 'rotate(-45deg)' : 'rotate(45deg)' }}/>
              {k.delta}
            </div>
            <Sparkline values={k.spark}/>
          </div>
        ))}
      </div>

      {(() => {
        const tomorrow = APPOINTMENTS.filter(a => a.date === offsetDay(1) && a.status !== 'cancelled');
        const total = tomorrow.length; const signed = Math.max(0, total - 2);
        return (
          <div className="panel" style={{ padding: '12px 18px', marginBottom: 24, display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
            <Icon name="check" size={16} style={{ color: 'var(--success)' }}/>
            <div style={{ fontSize: 13, color: 'var(--fg-2)', flex: 1, minWidth: 220 }}>
              <b style={{ color: 'var(--fg-1)' }}>Tomorrow's medical forms: {signed} of {total} signed</b> · 2 chased automatically this morning.
            </div>
            <DemoNote align="right" title="Forms before arrival" text="The medical form goes out with the booking confirmation, gets a reminder at 24 hours, and raises a call task for reception at 48 if still unsigned. Consent forms are signed on screen and stored on the client's record."/>
          </div>
        );
      })()}

      {/* Pending bookings — needs to be top-line for the owner too (§2 + §12) */}
      <div style={{ marginBottom: 24 }}>
        <PendingBookingsPanel onOpenForm={onOpenForm}/>
      </div>

      {/* Daily tasks — shared running list across team (§14) */}
      <div style={{ marginBottom: 24 }}>
        <TasksPanel currentClinicianId="emma"/>
      </div>

      <div className="cl-grid">
        <section className="panel">
          <div className="panel-head"><h3>This week's revenue</h3><span className="meta">£ vs target</span></div>
          <div className="bar-chart">
            {[
              { d: 'Mon', a: 1200, b: 1500 },
              { d: 'Tue', a: 1800, b: 1800 },
              { d: 'Wed', a: 2100, b: 1800 },
              { d: 'Thu', a: 1510, b: 1800 },
              { d: 'Fri', a: 0, b: 2200 },
              { d: 'Sat', a: 0, b: 2400 },
            ].map(d => {
              const max = 2400;
              return (
                <div key={d.d} className="bar">
                  <span className="b1" style={{ height: (d.a / max) * 100 + '%' }}/>
                  <span className="b2" style={{ height: ((d.b - Math.min(d.a, d.b)) / max) * 100 + '%', opacity: d.a >= d.b ? 0 : 1 }}/>
                  <span className="lbl">{d.d}</span>
                </div>
              );
            })}
          </div>
          <div className="legend">
            <span><span className="swatch" style={{ background: 'var(--ink)' }}/>Actual</span>
            <span><span className="swatch" style={{ background: 'var(--blush)' }}/>Target shortfall</span>
          </div>
        </section>

        <aside style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div className="panel">
            <div className="panel-head"><h3>Top treatments</h3><span className="meta">30 days</span></div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              {[
                { n: 'CO2 Laser Resurfacing', val: '£8,450', share: 0.9 },
                { n: 'HIFU', val: '£5,940', share: 0.7 },
                { n: 'HydraFacial', val: '£3,625', share: 0.5 },
                { n: 'Microneedling', val: '£2,950', share: 0.4 },
                { n: 'Cryolipolysis', val: '£2,100', share: 0.3 },
              ].map(t => (
                <div key={t.n}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13, marginBottom: 6 }}>
                    <span style={{ color: 'var(--fg-1)' }}>{t.n}</span>
                    <span style={{ color: 'var(--fg-2)', fontVariantNumeric: 'tabular-nums' }}>{t.val}</span>
                  </div>
                  <div style={{ height: 4, background: 'var(--cream)', borderRadius: 2, overflow: 'hidden' }}>
                    <div style={{ height: '100%', width: (t.share * 100) + '%', background: 'var(--blush-deep)' }}/>
                  </div>
                </div>
              ))}
            </div>
          </div>

          <div className="panel">
            <div className="panel-head"><h3>Pulse</h3></div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12, fontSize: 13 }}>
              <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}><Icon name="info" size={14}/><div>Hannah W left a <b>5★ Google review</b> this morning.</div></div>
              <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}><Icon name="bell" size={14}/><div>2 customers waiting on consent forms before next visit.</div></div>
              <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}><Icon name="pound" size={14}/><div>Stripe payout of <b>£4,820</b> arrives Monday.</div></div>
            </div>
          </div>
        </aside>
      </div>

      {closeDay && <EndOfDayPanel onClose={() => setCloseDay(false)}/>}
    </>
  );
}

// Proper month-grid: 6 rows × 7 cols of day cells. Each cell shows the date
// number + an appointment count + small coloured dots for each appt (capped at 3).
function MonthGrid({ onPickDay, monthISO = todayISO }) {
  const base = new Date(monthISO + 'T12:00:00');
  const year = base.getFullYear();
  const month = base.getMonth(); // 0-indexed
  const firstOfMonth = new Date(year, month, 1);
  const startWeekday = (firstOfMonth.getDay() + 6) % 7; // Mon=0..Sun=6
  const daysInMonth = new Date(year, month + 1, 0).getDate();

  // Build a 6×7 grid of dates; some are previous/next month (greyed out)
  const cells = [];
  for (let i = 0; i < 42; i++) {
    const dom = i - startWeekday + 1;
    const cellDate = new Date(year, month, dom, 12);
    const iso = cellDate.getFullYear() + '-' + String(cellDate.getMonth() + 1).padStart(2, '0') + '-' + String(cellDate.getDate()).padStart(2, '0');
    const inMonth = dom >= 1 && dom <= daysInMonth;
    const isToday = iso === todayISO;
    const isPast = iso < todayISO;
    const dayAppts = APPOINTMENTS.filter(a => a.date === iso);
    cells.push({ iso, dom: cellDate.getDate(), inMonth, isToday, isPast, appts: dayAppts });
  }

  const headers = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
  return (
    <div className="month-grid-wrap">
      <div className="month-headers">
        {headers.map(h => <div key={h} className="month-header">{h}</div>)}
      </div>
      <div className="month-grid">
        {cells.map((c, i) => (
          <button
            key={i}
            className={'month-cell' + (c.inMonth ? '' : ' out') + (c.isToday ? ' today' : '') + (c.isPast ? ' past' : '')}
            onClick={() => c.inMonth && onPickDay && onPickDay(c.iso)}
          >
            <div className="mc-num">{c.dom}</div>
            {c.appts.length > 0 && (
              <>
                <div className="mc-count">{c.appts.length} {c.appts.length === 1 ? 'appt' : 'appts'}</div>
                <div className="mc-dots">
                  {c.appts.slice(0, 3).map((a, j) => {
                    const t = treatmentById(a.treatmentId);
                    return <span key={j} className={'mc-dot ' + (a.status === 'pending' ? 'warn' : '')} title={a.time + ' ' + t.name}/>;
                  })}
                  {c.appts.length > 3 && <span className="mc-more">+{c.appts.length - 3}</span>}
                </div>
              </>
            )}
          </button>
        ))}
      </div>
    </div>
  );
}

function OwCalendar({ onNewBooking }) {
  const [view, setView] = React.useState('week'); // 'day' | 'week' | 'month'
  const [anchor, setAnchor] = React.useState(todayISO);

  const mondayOf = (iso) => { const d = new Date(iso + 'T12:00:00'); return shiftDay(iso, -((d.getDay() + 6) % 7)); };
  const weekStart = mondayOf(anchor);
  const weekDates = Array.from({ length: 6 }, (_, k) => shiftDay(weekStart, k)); // Mon-Sat
  const eyebrow = view === 'day'
    ? new Date(anchor + 'T12:00:00').toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long' })
    : view === 'week'
      ? fmtDate(weekStart) + ' — ' + fmtDate(shiftDay(weekStart, 5))
      : new Date(anchor + 'T12:00:00').toLocaleDateString('en-GB', { month: 'long', year: 'numeric' });
  const move = (dir) => {
    if (view === 'month') {
      const d = new Date(anchor + 'T12:00:00'); d.setDate(1); d.setMonth(d.getMonth() + dir);
      setAnchor(d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-01');
    } else {
      setAnchor(shiftDay(anchor, (view === 'day' ? 1 : 7) * dir));
    }
  };

  const times = ['09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19'];
  const weekAppts = APPOINTMENTS.filter(a => a.status !== 'cancelled' && weekDates.includes(a.date));

  return (
    <>
      <div className="cl-head">
        <div style={{ minWidth: 'min(340px, 55vw)' }}><span className="eyebrow">{eyebrow}</span><h1>Calendar<DemoNote title="Moving appointments" text="In the day view, drag an appointment to a new time or column to move it — tap and hold on a phone. The system re-checks clashes, rooms and the client's other bookings before it lets go."/></h1></div>
        <div className="actions">
          <div className="view-toggle">
            <button onClick={() => move(-1)} aria-label="Back"><Icon name="chevL" size={12}/></button>
            <button style={{ minWidth: 58 }} className={anchor === todayISO ? 'active' : ''} onClick={() => setAnchor(todayISO)}>Today</button>
            <button onClick={() => move(1)} aria-label="Forward"><Icon name="chevR" size={12}/></button>
          </div>
          <div className="view-toggle">
            <button className={view === 'day' ? 'active' : ''} onClick={() => setView('day')}>Day</button>
            <button className={view === 'week' ? 'active' : ''} onClick={() => setView('week')}>Week</button>
            <button className={view === 'month' ? 'active' : ''} onClick={() => setView('month')}>Month</button>
          </div>
          <button className="app-btn primary" onClick={onNewBooking}><Icon name="plus" size={14}/>New</button>
        </div>
      </div>

      {/* Day view = the full diary (per-clinician columns + drag-drop) for the anchor date */}
      {view === 'day' && (
        <DiaryView
          key={anchor}
          date={anchor}
          appointments={APPOINTMENTS.filter(a => a.date === anchor && a.status !== 'cancelled')}
          defaultClinician="emma"
        />
      )}

      {/* Week view = Mon-Sat grid built from the live diary */}
      {view === 'week' && (
        <>
          <div className="tbl-scroll">
          <div className="cal-week">
            <div className="col-head"></div>
            {weekDates.map(d => (
              <div key={d} className={'col-head' + (d === todayISO ? '' : '')}>
                {new Date(d + 'T12:00:00').toLocaleDateString('en-GB', { weekday: 'short' })} {parseInt(d.slice(8), 10)}
              </div>
            ))}
            {times.map(t => (
              <React.Fragment key={t}>
                <div className="row-time">{t}:00</div>
                {weekDates.map(d => {
                  const cellAppts = weekAppts.filter(a => a.date === d && a.time.slice(0, 2) === t)
                    .sort((a, b) => a.time.localeCompare(b.time));
                  const shown = cellAppts.slice(0, 2);
                  return (
                    <div key={d + t} className="col-cell">
                      {shown.map(a => {
                        const cust = customerById(a.customerId);
                        const tr = treatmentById(a.treatmentId);
                        const tone = a.status === 'pending' ? 'warn' : a.status === 'completed' ? 'ghost' : (a.clinicianId === 'emma' || a.clinicianId === 'daniel') ? 'ink' : '';
                        const label = cust ? cust.name.split(' ')[0] + ' ' + ((cust.name.split(' ')[1] || '')[0] || '') : '—';
                        return (
                          <div key={a.id} className={'cal-chip ' + tone} title={a.time + ' · ' + (cust ? cust.name : '') + ' · ' + (tr ? tr.name : '')}>
                            <b>{a.time}</b> {label}
                          </div>
                        );
                      })}
                      {cellAppts.length > 2 && <div className="cal-more">+{cellAppts.length - 2} more</div>}
                    </div>
                  );
                })}
              </React.Fragment>
            ))}
          </div>
          </div>
          <div className="legend" style={{ marginTop: 28 }}>
            <span><span className="swatch" style={{ background: 'var(--blush-soft)', borderLeft: '2px solid var(--blush-deep)' }}/>Confirmed</span>
            <span><span className="swatch" style={{ background: 'var(--ink)', borderLeft: '2px solid var(--ink)' }}/>Doctor-led team</span>
            <span><span className="swatch" style={{ background: 'transparent', border: '1px solid var(--line)' }}/>Completed</span>
            <span><span className="swatch" style={{ background: 'rgba(166,69,62,0.16)', borderLeft: '2px solid var(--alert)' }}/>Awaiting approval</span>
          </div>
        </>
      )}

      {/* Month view = month grid with real appointment counts; click a day to open it */}
      {view === 'month' && <div className="tbl-scroll"><MonthGrid monthISO={anchor} onPickDay={(iso) => { setAnchor(iso); setView('day'); }}/></div>}
    </>
  );
}

function OwRevenue() {
  return (
    <>
      <div className="cl-head">
        <div><span className="eyebrow">Last 30 days</span><h1>Revenue</h1></div>
        <div className="actions">
          <select className="app-btn" style={{ padding: '8px 14px' }}>
            <option>Last 30 days</option><option>Quarter to date</option><option>Year to date</option>
          </select>
          <button className="app-btn"><Icon name="upload" size={14}/>Export CSV</button>
        </div>
      </div>

      <div className="kpi-grid">
        <div className="kpi"><div className="lbl">Gross revenue</div><div className="val">£42,180</div><div className="delta up"><Icon name="arrow" size={12} style={{ transform: 'rotate(-45deg)' }}/>+12% vs prev</div></div>
        <div className="kpi"><div className="lbl">Avg ticket</div><div className="val">£238</div><div className="delta up"><Icon name="arrow" size={12} style={{ transform: 'rotate(-45deg)' }}/>+£14</div></div>
        <div className="kpi"><div className="lbl">Repeat rate</div><div className="val">68%</div><div className="delta up"><Icon name="arrow" size={12} style={{ transform: 'rotate(-45deg)' }}/>+3 pts</div></div>
        <div className="kpi"><div className="lbl">Refunds</div><div className="val">£280</div><div className="delta down"><Icon name="arrow" size={12} style={{ transform: 'rotate(45deg)' }}/>+£90</div></div>
      </div>

      <div className="cl-grid">
        <section className="panel">
          <div className="panel-head"><h3>Daily revenue</h3><span className="meta">30 days</span></div>
          <div className="bar-chart" style={{ height: 200 }}>
            {Array.from({ length: 22 }).map((_, i) => {
              const seed = [1200,1450,1100,1700,1900,1300,1600,1850,1450,2100,1750,1400,1650,1900,2050,1550,1700,1500,1820,2000,1480,1510][i] || 1500;
              const max = 2400;
              return (
                <div key={i} className="bar">
                  <span className="b1" style={{ height: (seed / max) * 100 + '%' }}/>
                </div>
              );
            })}
          </div>
        </section>

        <aside className="panel">
          <div className="panel-head"><h3>By category</h3></div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            {[
              { n: 'Laser', val: 14620, share: 0.95 },
              { n: 'Skin & facials', val: 12480, share: 0.8 },
              { n: 'Body / fat', val: 7820, share: 0.5 },
              { n: 'Injectables', val: 5740, share: 0.38 },
              { n: 'Retail', val: 1520, share: 0.1 },
            ].map(t => (
              <div key={t.n}>
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13, marginBottom: 6 }}>
                  <span style={{ color: 'var(--fg-1)' }}>{t.n}</span>
                  <span style={{ color: 'var(--fg-2)', fontVariantNumeric: 'tabular-nums' }}>{fmtMoney(t.val)}</span>
                </div>
                <div style={{ height: 4, background: 'var(--cream)', borderRadius: 2, overflow: 'hidden' }}>
                  <div style={{ height: '100%', width: (t.share * 100) + '%', background: 'var(--ink)' }}/>
                </div>
              </div>
            ))}
          </div>
        </aside>
      </div>

      <div className="panel" style={{ marginTop: 24 }}>
        <div className="panel-head"><h3>Recent transactions</h3><span className="meta">via Stripe</span></div>
        <div className="tbl-scroll"><table className="tbl">
          <thead><tr><th>Date</th><th>Customer</th><th>Treatment</th><th>Type</th><th style={{ textAlign: 'right' }}>Amount</th></tr></thead>
          <tbody>
            {[
              { d: '02 May', c: 'Hannah Whitlock', t: 'CO2 Laser · session 3', k: 'Treatment', a: 650 },
              { d: '02 May', c: 'Mark Daley', t: 'HIFU', k: 'Treatment', a: 495 },
              { d: '01 May', c: 'Sophie Reynolds', t: 'HydraFacial', k: 'Treatment', a: 145 },
              { d: '01 May', c: 'Lucy Bennett', t: 'Cryolipolysis · deposit', k: 'Deposit', a: 50 },
              { d: '30 Apr', c: 'Jess Okafor', t: 'Fire & Ice Facial', k: 'Treatment', a: 125 },
              { d: '30 Apr', c: 'Hannah Whitlock', t: 'Obagi Vit C serum', k: 'Retail', a: 78 },
            ].map((r, i) => (
              <tr key={i}>
                <td>{r.d}</td>
                <td><div className="cell-cust"><span className="avatar sm" style={{ background: 'var(--blush-soft)' }}>{r.c.split(' ').map(s => s[0]).join('')}</span><b>{r.c}</b></div></td>
                <td>{r.t}</td>
                <td><span className="tag">{r.k}</span></td>
                <td style={{ textAlign: 'right' }}>{fmtMoney(r.a)}</td>
              </tr>
            ))}
          </tbody>
        </table></div>
      </div>
    </>
  );
}

function OwUtilisation() {
  const days = ['Tue','Wed','Thu','Fri','Sat','Sun'];
  const hours = ['09','10','11','12','13','14','15','16'];
  // utilisation 0..1 grid by clinician × day average
  const data = {
    'Emma':   [0.9, 0.95, 0.85, 0.9, 0.8, 0.0],
    'Grace':  [0.85, 0.7, 0.9, 0.6, 0.95, 0.0],
    'Daniel':    [0.5, 0.0, 0.8, 0.7, 0.0, 0.0],
    'Sofia':    [0.7, 0.9, 0.6, 0.95, 0.85, 0.0],
  };
  const heat = (v) => {
    if (v === 0) return { bg: 'var(--cream)', col: 'var(--fg-3)' };
    const a = Math.min(1, Math.max(0.1, v));
    return { bg: `rgba(201,154,138,${a})`, col: a > 0.5 ? '#fff' : 'var(--ink)' };
  };
  return (
    <>
      <div className="cl-head">
        <div><span className="eyebrow">Studio & specialist</span><h1>Utilisation</h1></div>
        <div className="actions">
          <select className="app-btn" style={{ padding: '8px 14px' }}>
            <option>This week</option><option>Last week</option><option>Last 4 weeks</option>
          </select>
        </div>
      </div>

      <div className="kpi-grid">
        <div className="kpi"><div className="lbl">Avg utilisation</div><div className="val">78%</div><div className="delta up"><Icon name="arrow" size={12} style={{ transform: 'rotate(-45deg)' }}/>+4 pts</div></div>
        <div className="kpi"><div className="lbl">Best day</div><div className="val">Saturday</div><div className="delta">88% utilisation</div></div>
        <div className="kpi"><div className="lbl">Quietest hour</div><div className="val">12:00</div><div className="delta">52% — lunch dip</div></div>
        <div className="kpi"><div className="lbl">Studio idle (hrs)</div><div className="val">14.2</div><div className="delta down">+1.8 vs target</div></div>
      </div>

      <div className="panel" style={{ marginBottom: 24 }}>
        <div className="panel-head"><h3>By specialist × day</h3><span className="meta">% of bookable hours used</span></div>
        <div className="util-grid" style={{ gridTemplateColumns: '120px repeat(6, 1fr)' }}>
          <div></div>
          {days.map(d => <div key={d} className="h">{d}</div>)}
          {Object.entries(data).map(([who, row]) => (
            <React.Fragment key={who}>
              <div className="row-lbl">{who}</div>
              {row.map((v, i) => {
                const s = heat(v);
                return <div key={i} className="cell" style={{ background: s.bg, color: s.col, borderColor: 'transparent' }}>{v === 0 ? '—' : Math.round(v * 100) + '%'}</div>;
              })}
            </React.Fragment>
          ))}
        </div>
      </div>

      <div className="panel">
        <div className="panel-head"><h3>Hour of day</h3><span className="meta">across the week</span></div>
        <div className="util-grid">
          <div></div>
          {hours.map(h => <div key={h} className="h">{h}</div>)}
          <div className="row-lbl">All</div>
          {[0.6, 0.78, 0.85, 0.52, 0.74, 0.88, 0.92, 0.78].map((v, i) => {
            const s = heat(v);
            return <div key={i} className="cell" style={{ background: s.bg, color: s.col, borderColor: 'transparent' }}>{Math.round(v * 100)}%</div>;
          })}
        </div>
      </div>
    </>
  );
}

function OwCustomers() {
  const rows = CUSTOMERS.map(c => ({
    ...c,
    visits: APPOINTMENTS.filter(a => a.customerId === c.id).length + Math.floor(Math.random() * 3) + 4,
    spend: 250 + Math.floor(Math.random() * 12) * 100,
  }));
  rows.sort((a, b) => b.spend - a.spend);
  return (
    <>
      <div className="cl-head">
        <div><span className="eyebrow">Records · all time</span><h1>Customers</h1></div>
        <div className="actions">
          <button className="app-btn"><Icon name="upload" size={14}/>Export</button>
          <button className="app-btn primary"><Icon name="plus" size={14}/>New</button>
        </div>
      </div>

      <div className="kpi-grid">
        <div className="kpi"><div className="lbl">Active</div><div className="val">412</div><div className="delta up"><Icon name="arrow" size={12} style={{ transform: 'rotate(-45deg)' }}/>+18</div></div>
        <div className="kpi"><div className="lbl">New this month</div><div className="val">26</div><div className="delta up"><Icon name="arrow" size={12} style={{ transform: 'rotate(-45deg)' }}/>+4</div></div>
        <div className="kpi"><div className="lbl">Lifetime value (avg)</div><div className="val">£1,840</div><div className="delta">+£60 YoY</div></div>
        <div className="kpi"><div className="lbl">5★ reviews</div><div className="val">243</div><div className="delta up">Google</div></div>
      </div>

      <div className="panel">
        <div className="tbl-scroll"><table className="tbl">
          <thead><tr><th>Customer</th><th>Joined</th><th>Visits</th><th>Lifetime spend</th><th>Concerns</th><th>Last seen</th></tr></thead>
          <tbody>
            {rows.map(c => {
              const last = APPOINTMENTS.filter(a => a.customerId === c.id).sort((a,b) => b.date.localeCompare(a.date))[0];
              return (
                <tr key={c.id}>
                  <td><div className="cell-cust"><span className="avatar sm" style={{ background: 'var(--blush-soft)' }}>{c.initials}</span><b>{c.name}</b></div></td>
                  <td>{c.joined}</td>
                  <td>{c.visits}</td>
                  <td>{fmtMoney(c.spend * 6)}</td>
                  <td>{c.concerns.join(', ')}</td>
                  <td>{last ? fmtDate(last.date) : '—'}</td>
                </tr>
              );
            })}
          </tbody>
        </table></div>
      </div>
    </>
  );
}

// ── Settings modal ───────────────────────────────────────────
function SettingsModal({ onClose }) {
  const [tab, setTab] = React.useState('clinic');
  return (
    <div className="modal-scrim" onClick={onClose}>
      <div className="modal settings-modal" style={{ width: 'min(820px, 94vw)', padding: 0 }} onClick={e => e.stopPropagation()}>
        <div className="settings-head">
          <div>
            <span className="eyebrow">Owner only</span>
            <h2 style={{ margin: '4px 0 0', fontSize: 28 }}>Clinic settings</h2>
          </div>
          <button className="app-btn ghost icon-only" onClick={onClose}><Icon name="close" size={16}/></button>
        </div>
        <div className="settings-grid">
          <div className="settings-sidebar">
            {[
              { id: 'clinic', label: 'Clinic details' },
              { id: 'team', label: 'Team & roles' },
              { id: 'hours', label: 'Hours & studios' },
              { id: 'treatments', label: 'Treatment menu' },
              { id: 'pricing', label: 'Pricing & deposits' },
              { id: 'templates', label: 'Templates' },
              { id: 'workflows', label: 'Workflows' },
              { id: 'notifications', label: 'Notifications' },
              { id: 'integrations', label: 'Integrations' },
            ].map(t => (
              <button key={t.id} onClick={() => setTab(t.id)}
                className={'settings-tab' + (tab === t.id ? ' active' : '')}>{t.label}</button>
            ))}
          </div>
          <div className="settings-content">
            {tab === 'clinic' && (
              <>
                <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Clinic details</h3>
                <div className="field"><label>Trading name</label><input className="stripe-input" defaultValue="Demo Clinic"/></div>
                <div className="settings-row-2">
                  <div className="field"><label>Phone</label><input className="stripe-input" defaultValue="01234 567890"/></div>
                  <div className="field"><label>Email</label><input className="stripe-input" defaultValue="info@clientloop.uk"/></div>
                </div>
                <div className="field"><label>Address</label><textarea className="stripe-input" rows="3" style={{ resize: 'vertical', fontFamily: 'inherit' }} defaultValue="12 High Street"/></div>
                <div className="field"><label>Companies House</label><input className="stripe-input" defaultValue="12345678"/></div>
              </>
            )}
            {tab === 'team' && (
              <>
                <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Team & roles</h3>
                {CLINICIANS.map(c => (
                  <div key={c.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 14, border: '1px solid var(--line)', borderRadius: 'var(--radius-md)', marginBottom: 8 }}>
                    <span className="avatar" style={{ background: c.avatarTint, color: c.avatarTint === '#6E7D6B' ? '#fff' : 'var(--ink)' }}>{c.initials}</span>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontSize: 14, color: 'var(--fg-1)', fontWeight: 500 }}>{c.name}</div>
                      <div style={{ fontSize: 12, color: 'var(--fg-3)' }}>{c.role}</div>
                    </div>
                    <select className="app-btn" style={{ padding: '6px 10px' }}>
                      <option>Specialist</option><option>Owner</option><option>Reception</option>
                    </select>
                  </div>
                ))}
                <button className="app-btn" style={{ marginTop: 12 }}><Icon name="plus" size={14}/>Invite team member</button>
              </>
            )}
            {tab === 'hours' && (
              <>
                <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Hours & studios</h3>
                {[
                  ['Monday', 'Closed'],
                  ['Tuesday', '09:00 — 18:00'],
                  ['Wednesday', '09:00 — 19:30'],
                  ['Thursday', '09:00 — 19:30'],
                  ['Friday', '09:00 — 18:00'],
                  ['Saturday', '09:00 — 16:00'],
                  ['Sunday', 'Closed'],
                ].map(([d, h]) => (
                  <div key={d} style={{ display: 'flex', justifyContent: 'space-between', padding: '10px 0', borderBottom: '1px solid var(--line)', fontSize: 13 }}>
                    <span style={{ color: 'var(--fg-1)' }}>{d}</span>
                    <span style={{ color: 'var(--fg-2)', fontVariantNumeric: 'tabular-nums' }}>{h}</span>
                  </div>
                ))}
                <div style={{ marginTop: 24, fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--fg-3)' }}>Treatment rooms · treatment routing</div>
                <div style={{ marginTop: 8, display: 'flex', flexDirection: 'column', gap: 8 }}>
                  {ROOMS.map(r => (
                    <div key={r.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 14px', border: '1px solid var(--line)', borderRadius: 'var(--radius-md)' }}>
                      <span className="tag blush" style={{ flexShrink: 0 }}>{r.name}{r.alias ? ' · ' + r.alias : ''}</span>
                      <span style={{ fontSize: 12, color: 'var(--fg-3)' }}>
                        {r.allowedTreatments && r.allowedTreatments.length
                          ? r.allowedTreatments.map(tid => treatmentById(tid)?.name || tid).join(', ')
                          : 'No treatments mapped'}
                      </span>
                    </div>
                  ))}
                </div>
              </>
            )}
            {tab === 'treatments' && (
              <>
                <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Treatment menu</h3>
                {TREATMENTS.slice(0, 6).map(t => (
                  <div key={t.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 12, borderBottom: '1px solid var(--line)' }}>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontSize: 14, color: 'var(--fg-1)', fontWeight: 500 }}>{t.name}</div>
                      <div style={{ fontSize: 12, color: 'var(--fg-3)' }}>{t.cat} · {t.mins} min</div>
                    </div>
                    <span style={{ fontSize: 14, color: 'var(--fg-1)', fontVariantNumeric: 'tabular-nums' }}>{fmtMoney(t.price)}</span>
                    <button className="app-btn ghost icon-only"><Icon name="edit" size={14}/></button>
                  </div>
                ))}
                <button className="app-btn" style={{ marginTop: 16 }}><Icon name="plus" size={14}/>Add treatment</button>
              </>
            )}
            {tab === 'pricing' && (
              <>
                <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Pricing & deposits</h3>
                <div className="field"><label>Default deposit</label><input className="stripe-input" defaultValue="50% of treatment cost"/></div>
                <div className="field"><label>Cancellation window</label>
                  <select className="stripe-input"><option>24 hours</option><option>48 hours</option><option>72 hours</option></select>
                </div>
                <div className="field"><label>Late cancel fee</label><input className="stripe-input" defaultValue="50% of deposit"/></div>
                <div className="field"><label>VAT rate</label><input className="stripe-input" defaultValue="20%"/></div>
              </>
            )}
            {tab === 'templates' && <TemplatesEditor/>}
            {tab === 'workflows' && <WorkflowsEditor/>}
            {tab === 'notifications' && (
              <>
                <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Notifications</h3>
                {[
                  ['Booking confirmation', 'Instantly on booking'],
                  ['Medical form reminder', '24 h after booking, if still unsigned'],
                  ['Pre-care reminder', '72 h before the appointment'],
                  ['Aftercare + review request', '1 h after the appointment'],
                  ['No-show follow-up', 'After a missed appointment'],
                ].map(([t, sub]) => (
                  <label key={t} style={{ display: 'flex', alignItems: 'flex-start', gap: 12, padding: 12, borderBottom: '1px solid var(--line)' }}>
                    <input type="checkbox" defaultChecked style={{ marginTop: 4 }}/>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontSize: 14, color: 'var(--fg-1)', fontWeight: 500 }}>{t}</div>
                      <div style={{ fontSize: 12, color: 'var(--fg-3)', marginTop: 2 }}>{sub}</div>
                    </div>
                  </label>
                ))}
              </>
            )}
            {tab === 'integrations' && (
              <>
                <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Integrations</h3>
                {[
                  { n: 'Stripe', sub: 'Online deposits & payment links',                       state: 'connected' },
                  { n: 'Gmail',  sub: 'Send all clinic email from your own address · replies land in the inbox', state: 'connected' },
                ].map(i => (
                  <div key={i.n} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 14, border: '1px solid var(--line)', borderRadius: 'var(--radius-md)', marginBottom: 8 }}>
                    <span className="avatar sm" style={{ background: 'var(--cream)' }}><Icon name="sparkle" size={14}/></span>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontSize: 14, color: 'var(--fg-1)', fontWeight: 500 }}>{i.n}</div>
                      <div style={{ fontSize: 12, color: 'var(--fg-3)' }}>{i.sub}</div>
                    </div>
                    <span className={'tag ' + (i.state === 'connected' ? 'ok' : 'ghost')}>{i.state}</span>
                  </div>
                ))}
              </>
            )}
          </div>
        </div>
        <div className="settings-foot">
          <button className="app-btn ghost" onClick={onClose}>Cancel</button>
          <button className="app-btn primary" onClick={onClose}>Save changes</button>
        </div>
      </div>
    </div>
  );
}

// ============================================================
// Marketing — the demo CRM replacement. Templates + Workflows + Enquiries +
// Campaign performance, presented as a sub-tabbed page rather than a modal.
// ============================================================
function OwMarketing({ route, setRoute, forceTab }) {
  const [tab, setTab] = React.useState(forceTab || route.tab || 'enquiries');
  React.useEffect(() => { if (forceTab) setTab(forceTab); }, [forceTab]);
  const tabs = [
    { id: 'enquiries',  label: 'Enquiries',   count: ENQUIRIES?.length || 0 },
    { id: 'workflows',  label: 'Workflows',   count: WORKFLOWS.filter(w => w.active).length },
    { id: 'templates',  label: 'Templates',   count: COMM_TEMPLATES.length },
    { id: 'performance', label: 'Performance', count: null },
  ];
  return (
    <>
      <div className="cl-head">
        <div><span className="eyebrow">Marketing & comms</span><h1>Reach &amp; respond.<DemoNote title="Enquiries to advice" text="Assessment-form enquiries land here with photos and answers attached. A specialist replies with personalised advice, and the system follows up on a gentle long cadence — stopping the moment the client replies or books."/></h1></div>
        <div className="actions">
          <button className="app-btn"><Icon name="upload" size={14}/>Export</button>
          <button className="app-btn primary"><Icon name="plus" size={14}/>New campaign</button>
        </div>
      </div>

      <div className="sub-tabs">
        {tabs.map(t => (
          <button key={t.id} className={'sub-tab' + (tab === t.id ? ' active' : '')} onClick={() => setTab(t.id)}>
            {t.label}{t.count !== null && t.count > 0 ? <span className="sub-tab-count">{t.count}</span> : null}
          </button>
        ))}
      </div>

      <div className="sub-tab-body">
        {tab === 'enquiries'   && <EnquiriesInbox onOpenLead={(id) => setRoute({ screen: 'lead', leadId: id })}/>}
        {tab === 'workflows'   && <div className="panel" style={{ padding: 20 }}><WorkflowsEditor/></div>}
        {tab === 'templates'   && <div className="panel" style={{ padding: 20 }}><TemplatesEditor/></div>}
        {tab === 'performance' && <MarketingPerformance/>}
      </div>
    </>
  );
}

function MarketingPerformance() {
  // Visual stub — would aggregate workflow open/click rates, enquiry-to-booking
  // conversion %, channel breakdown, etc. once we have real send data.
  return (
    <>
      <div className="kpi-grid">
        <div className="kpi"><div className="lbl">Enquiries this month</div><div className="val">{ENQUIRIES?.length || 0}</div><div className="delta up"><Icon name="arrow" size={12} style={{ transform: 'rotate(-45deg)' }}/>+3 vs prev</div></div>
        <div className="kpi"><div className="lbl">Enquiry → booking</div><div className="val">42%</div><div className="delta up"><Icon name="arrow" size={12} style={{ transform: 'rotate(-45deg)' }}/>+5 pts</div></div>
        <div className="kpi"><div className="lbl">Avg reply time</div><div className="val">2h 14m</div><div className="delta down">target &lt;1h</div></div>
        <div className="kpi"><div className="lbl">Workflow open rate</div><div className="val">61%</div><div className="delta up"><Icon name="arrow" size={12} style={{ transform: 'rotate(-45deg)' }}/>+4 pts</div></div>
      </div>
      <div className="cl-grid" style={{ marginTop: 20 }}>
        <section className="panel">
          <div className="panel-head"><h3>Top-performing templates</h3><span className="meta">Last 30 days</span></div>
          <div className="tbl-scroll"><table className="tbl">
            <thead><tr><th>Template</th><th>Sends</th><th>Open</th><th>Click</th><th>Bookings</th></tr></thead>
            <tbody>
              {COMM_TEMPLATES.slice(0, 6).map((t, i) => (
                <tr key={t.id}>
                  <td><b>{t.name}</b></td>
                  <td>{[124, 88, 215, 56, 73, 41][i]}</td>
                  <td>{[68, 72, 54, 81, 62, 49][i]}%</td>
                  <td>{[24, 31, 18, 42, 28, 12][i]}%</td>
                  <td>{[14, 8, 22, 18, 9, 3][i]}</td>
                </tr>
              ))}
            </tbody>
          </table></div>
        </section>
        <aside className="panel">
          <div className="panel-head"><h3>Email performance</h3><span className="meta">last 30 days</span></div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            {[
              { n: 'Sent', val: 482, share: 0.95 },
              { n: 'Opened', val: 348, share: 0.72 },
              { n: 'Replied', val: 96, share: 0.2 },
            ].map(c => (
              <div key={c.n}>
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13, marginBottom: 6 }}>
                  <span style={{ color: 'var(--fg-1)' }}>{c.n}</span>
                  <span style={{ color: 'var(--fg-2)', fontVariantNumeric: 'tabular-nums' }}>{c.val}</span>
                </div>
                <div style={{ height: 4, background: 'var(--cream)', borderRadius: 2, overflow: 'hidden' }}>
                  <div style={{ height: '100%', width: (c.share * 100) + '%', background: 'var(--blush-deep)' }}/>
                </div>
              </div>
            ))}
          </div>
        </aside>
      </div>
    </>
  );
}

// ============================================================
// Finance — KPI tracker. Owner-only. PIN-gated. Blur-on-blur.
// Sub-tabs: Dashboard / Weekly input / VAT / Projections / Trends /
//           Pay rates / Pricing calc / (legacy) Revenue / Reports / Utilisation
// ============================================================
function OwFinance({ route, setRoute, onOpenRecord }) {
  // All hooks must run on every render — keep them at the top, BEFORE any
  // early return. (Previous bug: `tab` useState + its effect lived after the
  // `if (!unlocked) return …` guard, so unlocking changed the hook count
  // mid-life and React threw "Rendered more hooks than during the previous
  // render".)
  const [unlocked, setUnlocked] = React.useState(!FINANCE_SETTINGS.pinRequired);
  const [windowBlurred, setWindowBlurred] = React.useState(false);
  const [tab, setTab] = React.useState(route.tab || 'dashboard');

  React.useEffect(() => {
    if (!FINANCE_SETTINGS.blurOnBlur) return;
    const onBlur = () => setWindowBlurred(true);
    const onFocus = () => setWindowBlurred(false);
    window.addEventListener('blur', onBlur);
    window.addEventListener('focus', onFocus);
    return () => { window.removeEventListener('blur', onBlur); window.removeEventListener('focus', onFocus); };
  }, []);

  React.useEffect(() => { if (route.tab) setTab(route.tab); }, [route.tab]);

  if (!unlocked) return <FinancePinGate onUnlock={() => setUnlocked(true)}/>;

  const tabs = [
    { id: 'dashboard',   label: 'Dashboard' },
    { id: 'weekly',      label: 'Weekly input' },
    { id: 'vat',         label: 'VAT' },
    { id: 'projections', label: 'Projections' },
    { id: 'trends',      label: 'Trends' },
    { id: 'payrates',    label: 'Pay rates' },
    { id: 'pricing',     label: 'Pricing calc' },
    { id: 'revenue',     label: 'Revenue', divider: true },
    { id: 'reports',     label: 'Reports' },
    { id: 'utilisation', label: 'Utilisation' },
    { id: 'settings',    label: 'Settings', divider: true },
  ];

  return (
    <div className={'finance-shell' + (windowBlurred ? ' obscured' : '')}>
      <div className="cl-head">
        <div>
          <span className="eyebrow">
            <Icon name="bell" size={11}/> Owner only · private
          </span>
          <h1>Finance &amp; KPIs.</h1>
        </div>
        <div className="actions">
          <button className="app-btn"><Icon name="upload" size={14}/>Export CSV</button>
          <button className="app-btn" onClick={() => setUnlocked(false)} title="Lock the tab"><Icon name="close" size={14}/>Lock</button>
        </div>
      </div>

      {windowBlurred && (
        <div className="finance-obscure-banner">
          <Icon name="info" size={14}/>
          Figures blurred while window inactive · tap to bring back
        </div>
      )}

      <div className="sub-tabs">
        {tabs.map(t => (
          <React.Fragment key={t.id}>
            {t.divider && <span className="sub-tab-divider" aria-hidden="true"/>}
            <button className={'sub-tab' + (tab === t.id ? ' active' : '')} onClick={() => setTab(t.id)}>{t.label}</button>
          </React.Fragment>
        ))}
      </div>

      <div className={'sub-tab-body finance-body' + (windowBlurred ? ' blur-figures' : '')}>
        {tab === 'dashboard'   && <FinanceDashboard/>}
        {tab === 'weekly'      && <FinanceWeeklyInput/>}
        {tab === 'vat'         && <FinanceVat/>}
        {tab === 'projections' && <FinanceProjections/>}
        {tab === 'trends'      && <FinanceTrends/>}
        {tab === 'payrates'    && <FinancePayRates/>}
        {tab === 'pricing'     && <FinancePricingCalc/>}
        {tab === 'revenue'     && <OwRevenue/>}
        {tab === 'reports'     && <OwReports onOpenRecord={onOpenRecord}/>}
        {tab === 'utilisation' && <OwUtilisation/>}
        {tab === 'settings'    && <FinanceSettings/>}
      </div>
    </div>
  );
}

function FinancePinGate({ onUnlock }) {
  const [pin, setPin] = React.useState('');
  const [error, setError] = React.useState(false);

  // Use a ref-based check so the auto-submit fires against the LATEST pin
  // value, not a stale closure copy. (Previous bug: setTimeout(submit,100)
  // captured the pre-update `pin` so the 4th digit was never included in the
  // comparison, making the correct PIN appear wrong.)
  const tryUnlock = (candidate) => {
    if (candidate === FINANCE_SETTINGS.pin) onUnlock();
    else { setError(true); setPin(''); }
  };

  const handleChange = (e) => {
    setError(false);
    const next = e.target.value.replace(/\D/g, '').slice(0, 4);
    setPin(next);
    if (next.length === 4) {
      // tiny delay so the 4th dot fills visually before unlock/error
      setTimeout(() => tryUnlock(next), 120);
    }
  };

  return (
    <div className="finance-pin-gate">
      <div className="finance-pin-card">
        <div className="finance-pin-icon"><Icon name="bell" size={28}/></div>
        <h2>Finance is locked</h2>
        <p>Enter your 4-digit PIN to view private business figures.</p>
        <div className="finance-pin-dots">
          {[0,1,2,3].map(i => (
            <span key={i} className={'dot' + (pin.length > i ? ' filled' : '') + (error ? ' err' : '')}/>
          ))}
        </div>
        <input
          className="stripe-input"
          type="password"
          inputMode="numeric"
          maxLength={4}
          autoFocus
          value={pin}
          onChange={handleChange}
          onKeyDown={e => { if (e.key === 'Enter') tryUnlock(pin); }}
          style={{ textAlign: 'center', letterSpacing: '0.4em', fontSize: 22, marginTop: 14, maxWidth: 200 }}
          placeholder="••••"
        />
        {error && <div className="finance-pin-error">Incorrect PIN · try again</div>}
        <div className="finance-pin-hint">PIN for this demo: <code>4729</code> — in your clinic, only you would know it.</div>
      </div>
    </div>
  );
}

// ---- Finance sub-screens ----------------------------------------------

function FinanceDashboard() {
  const weeks = WEEKLY_FINANCE;
  const currentWeek = weeks[weeks.length - 1];
  const prevWeek    = weeks[weeks.length - 2];

  const revenueAll  = weeks.reduce((s, w) => s + weekRevenue(w), 0);
  const expensesAll = weeks.reduce((s, w) => s + weekExpenses(w), 0);
  const profitAll   = revenueAll - expensesAll;
  const wagesAll    = weeks.reduce((s, w) => s + weekTotal(w, 'wages'), 0);
  const wagesPct    = revenueAll > 0 ? wagesAll / revenueAll : 0;
  const mainRevenue12wk = weeks.reduce((s, w) => s + weekRevenue(w, 'main'), 0);
  const annualisedMain = (mainRevenue12wk / 12) * 52;
  const vatLiability = annualisedMain * FINANCE_SETTINGS.vatRate;
  const runRate = (revenueAll / weeks.length) * 52;

  const wkRev = weekRevenue(currentWeek);
  const wkPrev = weekRevenue(prevWeek);
  const wkDelta = wkRev - wkPrev;

  return (
    <>
      <div className="kpi-grid">
        <div className="kpi"><div className="lbl">Revenue · 12 wks</div><div className="val">{fmtMoney(revenueAll)}</div><div className="delta">{fmtMoney(Math.round(revenueAll / 12))} / wk avg</div></div>
        <div className="kpi"><div className="lbl">Expenses · 12 wks</div><div className="val">{fmtMoney(expensesAll)}</div><div className="delta">{Math.round((expensesAll/revenueAll)*100)}% of revenue</div></div>
        <div className="kpi"><div className="lbl">Net profit</div><div className="val">{fmtMoney(profitAll)}</div><div className={'delta ' + (profitAll > 0 ? 'up' : 'down')}>{Math.round((profitAll/revenueAll)*100)}% margin</div></div>
        <div className="kpi"><div className="lbl">VAT estimate (Demo Clinic)</div><div className="val">{fmtMoney(Math.round(vatLiability))}</div><div className="delta">at current run rate</div></div>
        <div className="kpi"><div className="lbl">Annual run rate</div><div className="val">{fmtMoney(Math.round(runRate))}</div><div className="delta">based on last 12 wks</div></div>
        <div className="kpi"><div className="lbl">Wages % of rev</div><div className="val">{Math.round(wagesPct * 100)}%</div><div className="delta">benchmark 25–32%</div></div>
      </div>

      <div className="cl-grid" style={{ marginTop: 24 }}>
        <section className="panel">
          <div className="panel-head"><h3>This week vs last week</h3><span className="meta">Mon { fmtDate(currentWeek.weekStart) }</span></div>
          <div className="tbl-scroll"><table className="tbl">
            <thead><tr><th>Business</th><th style={{textAlign:'right'}}>This week</th><th style={{textAlign:'right'}}>Last week</th><th style={{textAlign:'right'}}>Δ</th></tr></thead>
            <tbody>
              {BUSINESSES.map(b => {
                const cur = weekRevenue(currentWeek, b.id);
                const prv = weekRevenue(prevWeek, b.id);
                const d = cur - prv;
                return (
                  <tr key={b.id}>
                    <td><span className="biz-dot" style={{background:b.tint}}/> <b>{b.short}</b>{b.vatRegistered && <span className="tag ghost" style={{marginLeft:6,fontSize:10}}>VAT</span>}</td>
                    <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>{fmtMoney(cur)}</td>
                    <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums',color:'var(--fg-3)'}}>{fmtMoney(prv)}</td>
                    <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums',color:d>=0?'var(--success)':'var(--alert)'}}>{d>=0?'+':''}{fmtMoney(d)}</td>
                  </tr>
                );
              })}
              <tr style={{borderTop:'2px solid var(--ink)'}}>
                <td><b>Total</b></td>
                <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}><b>{fmtMoney(wkRev)}</b></td>
                <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums',color:'var(--fg-3)'}}>{fmtMoney(wkPrev)}</td>
                <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums',color:wkDelta>=0?'var(--success)':'var(--alert)'}}><b>{wkDelta>=0?'+':''}{fmtMoney(wkDelta)}</b></td>
              </tr>
            </tbody>
          </table></div>
        </section>
        <aside style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div className="panel">
            <div className="panel-head"><h3>Revenue · 12 wk trend</h3><span className="meta">All businesses</span></div>
            <div className="bar-chart" style={{ height: 140 }}>
              {weeks.map((w, i) => {
                const v = weekRevenue(w);
                const max = Math.max(...weeks.map(x => weekRevenue(x)));
                return (
                  <div key={i} className="bar" title={fmtDate(w.weekStart) + ' · ' + fmtMoney(v)}>
                    <span className="b1" style={{ height: (v / max) * 100 + '%' }}/>
                  </div>
                );
              })}
            </div>
          </div>
          <div className="panel">
            <div className="panel-head"><h3>Heads-up</h3></div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 12, fontSize: 13 }}>
              <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}><Icon name="bell" size={14}/><div>Demo Clinic 12-mo rolling = <b>{fmtMoney(Math.round(annualisedMain))}</b> · {annualisedMain > FINANCE_SETTINGS.vatThreshold * 0.8 ? <span style={{color:'var(--alert)'}}>{Math.round((annualisedMain/FINANCE_SETTINGS.vatThreshold)*100)}% of VAT threshold</span> : 'under VAT threshold'}.</div></div>
              <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}><Icon name="info" size={14}/><div>Weekly input for <b>{fmtDate(currentWeek.weekStart)}</b> is unlocked — go to Weekly Input.</div></div>
              <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}><Icon name="pound" size={14}/><div>Card terminal totals for Demo Clinic pull automatically from Close-day.</div></div>
            </div>
          </div>
        </aside>
      </div>
    </>
  );
}

function FinanceWeeklyInput() {
  const weeks = WEEKLY_FINANCE;
  const [weekIdx, setWeekIdx] = React.useState(weeks.length - 1);
  const week = weeks[weekIdx];
  const [draft, setDraft] = React.useState(week.perBusiness);
  React.useEffect(() => setDraft(week.perBusiness), [weekIdx]);
  const lines = [
    { key: 'terminal', label: 'Card terminal', hint: 'Auto-pulled from Close-day for Demo Clinic' },
    { key: 'cash',     label: 'Cash takings',   hint: 'Reconcile against till' },
    { key: 'transfer', label: 'Bank transfers', hint: 'Manual entry' },
    { key: 'bills',    label: 'Bills paid',     hint: 'Suppliers, rent, etc.' },
    { key: 'wages',    label: 'Wages',          hint: 'Auto-calc available · see Pay rates' },
    { key: 'other',    label: 'Other costs',    hint: '' },
  ];
  const setVal = (bizId, key, v) => {
    const n = parseFloat(v) || 0;
    setDraft(prev => ({ ...prev, [bizId]: { ...prev[bizId], [key]: n } }));
  };
  const totalRev = BUSINESSES.reduce((s, b) => s + (draft[b.id].terminal||0) + (draft[b.id].cash||0) + (draft[b.id].transfer||0), 0);
  const totalExp = BUSINESSES.reduce((s, b) => s + (draft[b.id].bills||0) + (draft[b.id].wages||0) + (draft[b.id].other||0), 0);

  return (
    <>
      <div className="weekly-head">
        <div>
          <button className="app-btn ghost small" onClick={() => setWeekIdx(Math.max(0, weekIdx - 1))} disabled={weekIdx === 0}><Icon name="back" size={12}/></button>
          <div className="weekly-week">
            <div className="weekly-week-num">Week of {fmtDate(week.weekStart)}</div>
            <div className="weekly-week-status">
              {week.locked ? <span className="tag">Locked · submitted</span> : <span className="tag warn">Open · enter Monday</span>}
            </div>
          </div>
          <button className="app-btn ghost small" onClick={() => setWeekIdx(Math.min(weeks.length - 1, weekIdx + 1))} disabled={weekIdx === weeks.length - 1}><Icon name="chevR" size={12}/></button>
        </div>
        <div className="actions">
          <button className="app-btn"><Icon name="upload" size={14}/>Import CSV</button>
          {!week.locked && <button className="app-btn primary"><Icon name="check" size={14}/>Submit & lock week</button>}
        </div>
      </div>

      <div className="weekly-table-wrap">
        <table className="weekly-table">
          <thead>
            <tr>
              <th>Line</th>
              {BUSINESSES.map(b => (
                <th key={b.id}>
                  <div className="weekly-biz-head" style={{ borderTopColor: b.tint }}>
                    <div className="weekly-biz-short">{b.short}</div>
                    <div className="weekly-biz-term">{b.terminal}</div>
                  </div>
                </th>
              ))}
              <th className="weekly-total-head">Total</th>
            </tr>
          </thead>
          <tbody>
            {lines.map(line => (
              <tr key={line.key} className={['bills','wages','other'].includes(line.key) ? 'expense-row' : 'revenue-row'}>
                <td>
                  <div className="weekly-line-label">{line.label}</div>
                  {line.hint && <div className="weekly-line-hint">{line.hint}</div>}
                </td>
                {BUSINESSES.map(b => (
                  <td key={b.id}>
                    <div className="weekly-input-wrap">
                      <span className="weekly-input-prefix">£</span>
                      <input
                        type="number"
                        className="weekly-input"
                        value={draft[b.id][line.key] || ''}
                        onChange={e => setVal(b.id, line.key, e.target.value)}
                        disabled={week.locked}
                        placeholder="0"
                      />
                      {b.id === 'main' && line.key === 'terminal' && <span className="weekly-input-badge" title="Auto-pulled from Close-day">auto</span>}
                    </div>
                  </td>
                ))}
                <td className="weekly-row-total">{fmtMoney(BUSINESSES.reduce((s, b) => s + (draft[b.id][line.key] || 0), 0))}</td>
              </tr>
            ))}
            <tr className="weekly-totals-row">
              <td><b>Revenue (cards + cash + transfer)</b></td>
              {BUSINESSES.map(b => {
                const r = (draft[b.id].terminal||0) + (draft[b.id].cash||0) + (draft[b.id].transfer||0);
                return <td key={b.id} style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}><b>{fmtMoney(r)}</b></td>;
              })}
              <td className="weekly-row-total"><b>{fmtMoney(totalRev)}</b></td>
            </tr>
            <tr className="weekly-totals-row">
              <td><b>Expenses (bills + wages + other)</b></td>
              {BUSINESSES.map(b => {
                const e = (draft[b.id].bills||0) + (draft[b.id].wages||0) + (draft[b.id].other||0);
                return <td key={b.id} style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}><b>{fmtMoney(e)}</b></td>;
              })}
              <td className="weekly-row-total"><b>{fmtMoney(totalExp)}</b></td>
            </tr>
            <tr className="weekly-totals-row profit-row">
              <td><b>Net (revenue − expenses)</b></td>
              {BUSINESSES.map(b => {
                const d = (draft[b.id].terminal||0) + (draft[b.id].cash||0) + (draft[b.id].transfer||0) - ((draft[b.id].bills||0) + (draft[b.id].wages||0) + (draft[b.id].other||0));
                return <td key={b.id} style={{textAlign:'right',fontVariantNumeric:'tabular-nums',color:d>=0?'var(--success)':'var(--alert)'}}><b>{fmtMoney(d)}</b></td>;
              })}
              <td className="weekly-row-total" style={{color: totalRev - totalExp >= 0 ? 'var(--success)' : 'var(--alert)'}}><b>{fmtMoney(totalRev - totalExp)}</b></td>
            </tr>
          </tbody>
        </table>
      </div>

      <div className="panel" style={{ marginTop: 24, padding: 18 }}>
        <div style={{ fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--fg-3)', marginBottom: 6 }}>Weekly notes (private)</div>
        <textarea className="stripe-input" rows="3" placeholder="e.g. Mark D paid £50 outstanding balance · Demo Clinic EFTPOS was down Wed AM" style={{ fontFamily: 'inherit', resize: 'vertical' }} disabled={week.locked}/>
      </div>
    </>
  );
}

function FinanceVat() {
  const weeks = WEEKLY_FINANCE;
  const mainRolling = weeks.reduce((s, w) => s + weekRevenue(w, 'main'), 0);
  // 12 wks ≈ 12/52 of a year. Annualise.
  const annualised = (mainRolling / 12) * 52;
  const threshold = FINANCE_SETTINGS.vatThreshold;
  const pct = Math.min(1, annualised / threshold);
  const headroom = threshold - annualised;
  const weeksToBreach = annualised > 0 ? Math.max(0, (threshold - annualised) / (mainRolling / 12)) : null;

  return (
    <>
      <div className="kpi-grid">
        <div className="kpi"><div className="lbl">Demo Clinic · 12 wk × 52/12 annualised</div><div className="val">{fmtMoney(Math.round(annualised))}</div><div className="delta">vs £{(threshold/1000)}k threshold</div></div>
        <div className="kpi"><div className="lbl">Headroom</div><div className="val">{fmtMoney(Math.round(headroom))}</div><div className={'delta ' + (headroom > 0 ? 'up' : 'down')}>{headroom > 0 ? 'under threshold' : 'over threshold'}</div></div>
        <div className="kpi"><div className="lbl">% of threshold</div><div className="val">{Math.round(pct * 100)}%</div><div className="delta">{pct > 0.85 ? 'register soon' : 'monitor monthly'}</div></div>
        <div className="kpi"><div className="lbl">Weeks to breach</div><div className="val">{weeksToBreach !== null ? Math.round(weeksToBreach) : '—'}</div><div className="delta">at current pace</div></div>
      </div>

      <div className="panel" style={{ marginTop: 24 }}>
        <div className="panel-head"><h3>VAT threshold meter · Demo Clinic only</h3><span className="meta">{fmtMoney(Math.round(annualised))} / {fmtMoney(threshold)}</span></div>
        <div className="vat-meter">
          <div className="vat-meter-fill" style={{ width: (pct * 100) + '%', background: pct > 0.85 ? 'var(--alert)' : pct > 0.7 ? '#E4A347' : 'var(--blush-deep)' }}/>
          <div className="vat-meter-marker" style={{ left: '80%' }} title="80% warning"/>
          <div className="vat-meter-marker" style={{ left: '100%' }} title="Threshold"/>
        </div>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: 'var(--fg-3)', marginTop: 6 }}>
          <span>£0</span><span>80% · £72k</span><span>£90k threshold</span>
        </div>
      </div>

      <div className="cl-grid" style={{ marginTop: 24 }}>
        <section className="panel">
          <div className="panel-head"><h3>Other businesses · monitoring only</h3><span className="meta">Not VAT-registered</span></div>
          <div className="tbl-scroll"><table className="tbl">
            <thead><tr><th>Business</th><th style={{textAlign:'right'}}>12 wk revenue</th><th style={{textAlign:'right'}}>Annualised</th><th style={{textAlign:'right'}}>% of £90k</th></tr></thead>
            <tbody>
              {BUSINESSES.filter(b => !b.vatRegistered).map(b => {
                const r = weeks.reduce((s, w) => s + weekRevenue(w, b.id), 0);
                const ann = (r / 12) * 52;
                return (
                  <tr key={b.id}>
                    <td><span className="biz-dot" style={{background:b.tint}}/> <b>{b.short}</b></td>
                    <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>{fmtMoney(r)}</td>
                    <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>{fmtMoney(Math.round(ann))}</td>
                    <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums',color:'var(--fg-3)'}}>{Math.round((ann/threshold)*100)}%</td>
                  </tr>
                );
              })}
            </tbody>
          </table></div>
        </section>
        <aside className="panel">
          <div className="panel-head"><h3>VAT return estimate</h3><span className="meta">If registered today</span></div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14, fontSize: 14 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>Demo Clinic annualised revenue</span><b>{fmtMoney(Math.round(annualised))}</b></div>
            <div style={{ display: 'flex', justifyContent: 'space-between' }}><span>× VAT rate ({Math.round(FINANCE_SETTINGS.vatRate * 100)}%)</span><b>{fmtMoney(Math.round(annualised * FINANCE_SETTINGS.vatRate))}</b></div>
            <div style={{ display: 'flex', justifyContent: 'space-between', borderTop: '1px solid var(--line)', paddingTop: 10, fontSize: 16 }}><span>Quarterly liability est.</span><b>{fmtMoney(Math.round((annualised * FINANCE_SETTINGS.vatRate) / 4))}</b></div>
            <div style={{ fontSize: 11, color: 'var(--fg-3)', lineHeight: 1.5 }}>This is a flat estimate. Real liability depends on input VAT reclaimable on supplies/equipment. Cross-check with accountant before submitting.</div>
          </div>
        </aside>
      </div>
    </>
  );
}

function FinanceProjections() {
  const weeks = WEEKLY_FINANCE;
  // Wrap helper calls — Array.map passes (item, index, array), and the index
  // would land in weekRevenue's optional `businessId` arg, crashing on
  // week.perBusiness[1]. Use explicit single-arg lambdas.
  const revWk = weeks.map(w => weekRevenue(w));
  const expWk = weeks.map(w => weekExpenses(w));
  const avgRev = revWk.reduce((a,b) => a+b, 0) / revWk.length;
  const avgExp = expWk.reduce((a,b) => a+b, 0) / expWk.length;
  const annualRev = avgRev * 52;
  const annualExp = avgExp * 52;
  const fixedAnnual = FIXED_COSTS.reduce((s, c) => s + c.monthly * 12, 0);
  const annualProfit = annualRev - annualExp;
  return (
    <>
      <div className="kpi-grid">
        <div className="kpi"><div className="lbl">Projected annual revenue</div><div className="val">{fmtMoney(Math.round(annualRev))}</div><div className="delta">at 12 wk run rate</div></div>
        <div className="kpi"><div className="lbl">Projected annual expenses</div><div className="val">{fmtMoney(Math.round(annualExp))}</div><div className="delta">weekly avg × 52</div></div>
        <div className="kpi"><div className="lbl">Projected annual profit</div><div className="val">{fmtMoney(Math.round(annualProfit))}</div><div className={'delta ' + (annualProfit > 0 ? 'up' : 'down')}>{Math.round((annualProfit/annualRev)*100)}% margin</div></div>
        <div className="kpi"><div className="lbl">Fixed costs / yr</div><div className="val">{fmtMoney(fixedAnnual)}</div><div className="delta">{Math.round((fixedAnnual/annualRev)*100)}% of revenue</div></div>
      </div>

      <div className="panel" style={{ marginTop: 24 }}>
        <div className="panel-head"><h3>Fixed recurring costs</h3><span className="meta">Editable</span></div>
        <div className="tbl-scroll"><table className="tbl">
          <thead><tr><th>Item</th><th>Business</th><th>Category</th><th style={{textAlign:'right'}}>Monthly</th><th style={{textAlign:'right'}}>Annual</th></tr></thead>
          <tbody>
            {FIXED_COSTS.map(c => {
              const b = businessById(c.businessId);
              return (
                <tr key={c.id}>
                  <td><b>{c.label}</b></td>
                  <td><span className="biz-dot" style={{background:b?.tint}}/> {b?.short}</td>
                  <td><span className="tag ghost">{c.category}</span></td>
                  <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>{fmtMoney(c.monthly)}</td>
                  <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>{fmtMoney(c.monthly * 12)}</td>
                </tr>
              );
            })}
            <tr style={{borderTop:'2px solid var(--ink)'}}>
              <td colSpan="3"><b>Total fixed</b></td>
              <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}><b>{fmtMoney(FIXED_COSTS.reduce((s,c)=>s+c.monthly,0))}</b></td>
              <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}><b>{fmtMoney(fixedAnnual)}</b></td>
            </tr>
          </tbody>
        </table></div>
        <button className="app-btn small" style={{ marginTop: 12 }}><Icon name="plus" size={12}/>Add fixed cost</button>
      </div>

      <div className="cl-grid" style={{ marginTop: 24 }}>
        <section className="panel">
          <div className="panel-head"><h3>12-month forecast</h3><span className="meta">Revenue minus expenses</span></div>
          <div className="bar-chart" style={{ height: 200 }}>
            {Array.from({ length: 12 }).map((_, i) => {
              const seasonal = 1 + Math.sin(i / 12 * Math.PI * 2) * 0.08;
              const projected = (avgRev * 4.33) * seasonal;
              const max = avgRev * 4.33 * 1.2;
              return (
                <div key={i} className="bar" title={'Month ' + (i+1) + ' · ' + fmtMoney(Math.round(projected))}>
                  <span className="b1" style={{ height: (projected / max) * 100 + '%' }}/>
                </div>
              );
            })}
          </div>
          <div className="legend" style={{ marginTop: 16 }}>
            <span><span className="swatch" style={{ background: 'var(--ink)' }}/>Projected monthly revenue (seasonal adj.)</span>
          </div>
        </section>
        <aside className="panel">
          <div className="panel-head"><h3>Goal tracker</h3></div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            {[
              { n: 'Annual revenue target', target: 450000, actual: annualRev },
              { n: 'Net profit target',     target: 180000, actual: annualProfit },
              { n: 'Demo Clinic under VAT threshold', target: 90000, actual: (revWk.slice(-12).reduce((s,r)=>s+r,0)/12)*52, invert: true },
            ].map(g => {
              const pct = g.invert ? Math.min(1, g.actual / g.target) : Math.min(1, g.actual / g.target);
              return (
                <div key={g.n}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13, marginBottom: 6 }}>
                    <span style={{ color: 'var(--fg-1)' }}>{g.n}</span>
                    <span style={{ color: 'var(--fg-2)', fontVariantNumeric: 'tabular-nums' }}>{fmtMoney(Math.round(g.actual))} / {fmtMoney(g.target)}</span>
                  </div>
                  <div style={{ height: 6, background: 'var(--cream)', borderRadius: 3, overflow: 'hidden' }}>
                    <div style={{ height: '100%', width: (pct * 100) + '%', background: g.invert && pct > 0.85 ? 'var(--alert)' : 'var(--blush-deep)' }}/>
                  </div>
                </div>
              );
            })}
          </div>
        </aside>
      </div>
    </>
  );
}

function FinanceTrends() {
  const weeks = WEEKLY_FINANCE;
  return (
    <>
      <div className="panel">
        <div className="panel-head"><h3>Revenue · per business · 12 wks</h3><span className="meta">Weekly</span></div>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 18, padding: '8px 4px' }}>
          {BUSINESSES.map(b => {
            const vals = weeks.map(w => weekRevenue(w, b.id));
            const max = Math.max(...vals, 1);
            return (
              <div key={b.id}>
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13, marginBottom: 6 }}>
                  <span><span className="biz-dot" style={{background:b.tint}}/> <b>{b.short}</b></span>
                  <span style={{ color: 'var(--fg-3)', fontVariantNumeric: 'tabular-nums' }}>{fmtMoney(vals.reduce((a,b)=>a+b,0))} total · {fmtMoney(Math.round(vals.reduce((a,b)=>a+b,0)/12))}/wk</span>
                </div>
                <div className="trend-sparkbar">
                  {vals.map((v, i) => (
                    <span key={i} className="trend-sparkbar-cell" style={{ height: (v / max) * 100 + '%', background: b.tint }} title={fmtDate(weeks[i].weekStart) + ' · ' + fmtMoney(v)}/>
                  ))}
                </div>
              </div>
            );
          })}
        </div>
      </div>

      <div className="cl-grid" style={{ marginTop: 24 }}>
        <section className="panel">
          <div className="panel-head"><h3>Expense breakdown · 12 wks</h3></div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
            {[
              { n: 'Bills paid',  key: 'bills' },
              { n: 'Wages',       key: 'wages' },
              { n: 'Other costs', key: 'other' },
            ].map(line => {
              const total = weeks.reduce((s, w) => s + weekTotal(w, line.key), 0);
              const allExp = weeks.reduce((s, w) => s + weekExpenses(w), 0);
              const share = allExp > 0 ? total / allExp : 0;
              return (
                <div key={line.key}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13, marginBottom: 6 }}>
                    <span style={{ color: 'var(--fg-1)' }}>{line.n}</span>
                    <span style={{ color: 'var(--fg-2)', fontVariantNumeric: 'tabular-nums' }}>{fmtMoney(total)} · {Math.round(share*100)}%</span>
                  </div>
                  <div style={{ height: 6, background: 'var(--cream)', borderRadius: 3, overflow: 'hidden' }}>
                    <div style={{ height: '100%', width: (share * 100) + '%', background: 'var(--ink)' }}/>
                  </div>
                </div>
              );
            })}
          </div>
        </section>
        <aside className="panel">
          <div className="panel-head"><h3>Best / worst week</h3></div>
          {(() => {
            const ranked = [...weeks].map(w => ({ w, rev: weekRevenue(w) })).sort((a,b) => b.rev - a.rev);
            const best = ranked[0]; const worst = ranked[ranked.length - 1];
            return (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 14, fontSize: 14 }}>
                <div style={{ padding: 12, background: 'var(--cream)', borderRadius: 'var(--radius-md)' }}>
                  <div style={{ fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--fg-3)' }}>Best</div>
                  <div style={{ fontFamily: 'var(--font-display)', fontSize: 24, fontWeight: 300 }}>{fmtMoney(best.rev)}</div>
                  <div style={{ fontSize: 12, color: 'var(--fg-3)' }}>Week of {fmtDate(best.w.weekStart)}</div>
                </div>
                <div style={{ padding: 12, background: 'var(--cream)', borderRadius: 'var(--radius-md)' }}>
                  <div style={{ fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--fg-3)' }}>Worst</div>
                  <div style={{ fontFamily: 'var(--font-display)', fontSize: 24, fontWeight: 300 }}>{fmtMoney(worst.rev)}</div>
                  <div style={{ fontSize: 12, color: 'var(--fg-3)' }}>Week of {fmtDate(worst.w.weekStart)}</div>
                </div>
              </div>
            );
          })()}
        </aside>
      </div>
    </>
  );
}

function FinancePayRates() {
  const [rates, setRates] = React.useState(PAY_RATES);
  const update = (id, patch) => setRates(prev => prev.map(r => r.staffId === id ? { ...r, ...patch } : r));
  const autoCalcEnabled = rates.some(r => r.autoCalc);

  return (
    <>
      <div className="panel" style={{ padding: 18, marginBottom: 16, background: 'var(--cream)' }}>
        <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
          <Icon name="info" size={16}/>
          <div style={{ fontSize: 13, lineHeight: 1.5 }}>
            <b>Optional auto-calc for wages.</b> Turn on per staff member to derive their weekly wage figure from rota hours × hourly rate (+ commission %). When off, you enter wages manually in Weekly Input.{' '}
            {autoCalcEnabled
              ? <span style={{color:'var(--success)'}}>Auto-calc is on for {rates.filter(r => r.autoCalc).length} of {rates.length} staff.</span>
              : <span>Currently all manual.</span>}
          </div>
        </div>
      </div>

      <div className="panel">
        <div className="panel-head"><h3>Staff pay configuration</h3><span className="meta">Owner only · private</span></div>
        <div className="tbl-scroll"><table className="tbl">
          <thead><tr><th>Staff</th><th>Role</th><th>Type</th><th style={{textAlign:'right'}}>Hourly £</th><th style={{textAlign:'right'}}>Salary £/mo</th><th style={{textAlign:'right'}}>Commission %</th><th>Auto-calc</th></tr></thead>
          <tbody>
            {rates.map(r => (
              <tr key={r.staffId}>
                <td><b>{r.name}</b></td>
                <td><span className="tag ghost">{r.role}</span></td>
                <td>
                  <select className="stripe-input" style={{padding:'4px 8px',fontSize:12,width:'auto'}} value={r.type} onChange={e => update(r.staffId, { type: e.target.value })}>
                    <option value="hourly">Hourly</option>
                    <option value="salary">Salary</option>
                    <option value="session">Per session</option>
                  </select>
                </td>
                <td><input type="number" className="stripe-input" style={{textAlign:'right',padding:'4px 8px',fontSize:12,maxWidth:80}} value={r.hourlyRate || ''} onChange={e => update(r.staffId, { hourlyRate: parseFloat(e.target.value)||0 })} placeholder="—"/></td>
                <td><input type="number" className="stripe-input" style={{textAlign:'right',padding:'4px 8px',fontSize:12,maxWidth:90}} value={r.monthlyGross || ''} onChange={e => update(r.staffId, { monthlyGross: parseFloat(e.target.value)||0 })} placeholder="—"/></td>
                <td><input type="number" className="stripe-input" style={{textAlign:'right',padding:'4px 8px',fontSize:12,maxWidth:60}} value={r.commissionPct || ''} onChange={e => update(r.staffId, { commissionPct: parseFloat(e.target.value)||0 })} placeholder="—"/></td>
                <td>
                  <label className="auto-toggle">
                    <input type="checkbox" checked={!!r.autoCalc} onChange={e => update(r.staffId, { autoCalc: e.target.checked })}/>
                    <span className="auto-toggle-pill"/>
                  </label>
                </td>
              </tr>
            ))}
          </tbody>
        </table></div>
        <button className="app-btn small" style={{ marginTop: 12 }}><Icon name="plus" size={12}/>Add staff member</button>
      </div>

      <div className="panel" style={{ marginTop: 16, padding: 18 }}>
        <div style={{ fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--fg-3)', marginBottom: 8 }}>Estimated weekly wages bill</div>
        <div style={{ fontFamily: 'var(--font-display)', fontSize: 32, fontWeight: 300 }}>
          {fmtMoney(rates.reduce((s, r) => {
            if (r.type === 'salary') return s + (r.monthlyGross / 4.33);
            if (r.type === 'hourly') return s + (r.hourlyRate * FINANCE_SETTINGS.clinicHoursPerWeek * 0.6);
            return s;
          }, 0).toFixed(0))}
        </div>
        <div style={{ fontSize: 12, color: 'var(--fg-3)', marginTop: 4 }}>Based on configured rates × {FINANCE_SETTINGS.clinicHoursPerWeek}h/week × 60% loading (illustrative — wire to real rota for production)</div>
      </div>
    </>
  );
}

function FinancePricingCalc() {
  const [tid, setTid] = React.useState('co2');
  const treatment = treatmentById(tid);
  const cost = TREATMENT_COSTS[tid];
  const [overrideMargin, setOverrideMargin] = React.useState(FINANCE_SETTINGS.targetMarginPct);
  const [overrideLabour, setOverrideLabour] = React.useState(FINANCE_SETTINGS.defaultLabourCostPerMin);

  if (!cost) {
    return (
      <>
        <div className="cl-head" style={{ padding: '0 0 16px' }}>
          <select className="app-btn" style={{ padding: '8px 14px' }} value={tid} onChange={e => setTid(e.target.value)}>
            {TREATMENTS.map(t => <option key={t.id} value={t.id}>{t.name}</option>)}
          </select>
        </div>
        <div className="panel" style={{ padding: 32, textAlign: 'center', color: 'var(--fg-3)' }}>
          <Icon name="info" size={24}/>
          <div style={{ marginTop: 12, fontSize: 14 }}>No cost build-up yet for <b>{treatment.name}</b>.</div>
          <button className="app-btn primary" style={{ marginTop: 16 }}><Icon name="plus" size={14}/>Build cost recipe</button>
        </div>
      </>
    );
  }

  const matCost = cost.materials.reduce((s, m) => {
    const mat = MATERIALS.find(x => x.id === m.id);
    return s + (mat ? mat.costPerUnit * m.qty : 0);
  }, 0);
  const labCost = cost.labourMins * overrideLabour;
  const overhead = (matCost + labCost) * cost.overheadPct;
  const totalCost = matCost + labCost + overhead;
  const suggestedPrice = totalCost / (1 - overrideMargin);
  const currentMargin = (treatment.price - totalCost) / treatment.price;

  return (
    <>
      <div className="cl-head" style={{ padding: '0 0 16px' }}>
        <div>
          <span className="eyebrow">Treatment pricing calculator</span>
          <h2 style={{ margin: '4px 0 0', fontSize: 22, fontFamily: 'var(--font-display)', fontWeight: 300 }}>{treatment.name}</h2>
        </div>
        <div className="actions">
          <select className="app-btn" style={{ padding: '8px 14px' }} value={tid} onChange={e => setTid(e.target.value)}>
            {TREATMENTS.map(t => <option key={t.id} value={t.id}>{t.name}</option>)}
          </select>
        </div>
      </div>

      <div className="cl-grid">
        <section className="panel">
          <div className="panel-head"><h3>Cost build-up</h3><span className="meta">Materials + labour + overhead</span></div>
          <div className="tbl-scroll"><table className="tbl">
            <thead><tr><th>Item</th><th>Unit</th><th style={{textAlign:'right'}}>Qty</th><th style={{textAlign:'right'}}>Unit cost</th><th style={{textAlign:'right'}}>Line cost</th></tr></thead>
            <tbody>
              {cost.materials.map((m, i) => {
                const mat = MATERIALS.find(x => x.id === m.id);
                if (!mat) return null;
                return (
                  <tr key={i}>
                    <td><b>{mat.name}</b><div style={{fontSize:11,color:'var(--fg-3)'}}>{mat.supplier}</div></td>
                    <td>{mat.unit}</td>
                    <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>{m.qty}</td>
                    <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>£{mat.costPerUnit.toFixed(3)}</td>
                    <td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>£{(mat.costPerUnit * m.qty).toFixed(2)}</td>
                  </tr>
                );
              })}
              <tr><td colSpan="4"><b>Materials subtotal</b></td><td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}><b>£{matCost.toFixed(2)}</b></td></tr>
              <tr><td colSpan="2"><b>Labour</b></td><td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>{cost.labourMins} min</td><td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>£{overrideLabour.toFixed(2)}/min</td><td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>£{labCost.toFixed(2)}</td></tr>
              <tr><td colSpan="4"><b>Overhead</b> ({Math.round(cost.overheadPct*100)}%)</td><td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}>£{overhead.toFixed(2)}</td></tr>
              <tr style={{borderTop:'2px solid var(--ink)'}}><td colSpan="4"><b>Total cost</b></td><td style={{textAlign:'right',fontVariantNumeric:'tabular-nums'}}><b>£{totalCost.toFixed(2)}</b></td></tr>
            </tbody>
          </table></div>
        </section>
        <aside style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <div className="panel" style={{ padding: 18 }}>
            <div style={{ fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--fg-3)', marginBottom: 4 }}>Current price</div>
            <div style={{ fontFamily: 'var(--font-display)', fontSize: 36, fontWeight: 300 }}>{fmtMoney(treatment.price)}</div>
            <div style={{ fontSize: 12, color: currentMargin > 0.5 ? 'var(--success)' : 'var(--alert)', marginTop: 4 }}>
              {Math.round(currentMargin * 100)}% margin · {currentMargin > 0.5 ? 'healthy' : 'tight'}
            </div>

            <div style={{ marginTop: 18, fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--fg-3)' }}>Suggested price</div>
            <div style={{ fontFamily: 'var(--font-display)', fontSize: 36, fontWeight: 300, color: 'var(--blush-deep)' }}>£{suggestedPrice.toFixed(0)}</div>
            <div style={{ fontSize: 12, color: 'var(--fg-3)', marginTop: 4 }}>at {Math.round(overrideMargin * 100)}% target margin</div>
          </div>
          <div className="panel" style={{ padding: 18 }}>
            <div className="field"><label>Target margin</label>
              <input type="range" min="0.3" max="0.85" step="0.05" value={overrideMargin} onChange={e => setOverrideMargin(parseFloat(e.target.value))} style={{ width: '100%' }}/>
              <div style={{ fontSize: 12, color: 'var(--fg-3)', textAlign: 'right' }}>{Math.round(overrideMargin * 100)}%</div>
            </div>
            <div className="field"><label>Labour cost £/min</label>
              <input type="number" step="0.05" className="stripe-input" value={overrideLabour} onChange={e => setOverrideLabour(parseFloat(e.target.value) || 0)}/>
            </div>
            <div style={{ fontSize: 11, color: 'var(--fg-3)', lineHeight: 1.5, marginTop: 8 }}>Defaults from Finance Settings · adjust per-treatment to test scenarios.</div>
          </div>
        </aside>
      </div>
    </>
  );
}

function FinanceSettings() {
  return (
    <>
      <div className="panel" style={{ padding: 24 }}>
        <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Privacy</h3>
        <div className="field"><label>Owner PIN</label>
          <input className="stripe-input" type="password" defaultValue={FINANCE_SETTINGS.pin} maxLength="4" style={{ maxWidth: 160, textAlign: 'center', letterSpacing: '0.4em' }}/>
          <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 4 }}>4-digit PIN required to view Finance tab.</div>
        </div>
        <label className="settings-checkbox">
          <input type="checkbox" defaultChecked={FINANCE_SETTINGS.pinRequired}/>
          <div>
            <div className="settings-checkbox-title">Require PIN on entry</div>
            <div className="settings-checkbox-sub">Prompts every time the Finance tab is opened. Recommended.</div>
          </div>
        </label>
        <label className="settings-checkbox">
          <input type="checkbox" defaultChecked={FINANCE_SETTINGS.blurOnBlur}/>
          <div>
            <div className="settings-checkbox-title">Blur figures when window loses focus</div>
            <div className="settings-checkbox-sub">All numbers blur out automatically when you switch tabs or apps. Stops over-the-shoulder reads.</div>
          </div>
        </label>
      </div>

      <div className="panel" style={{ padding: 24, marginTop: 16 }}>
        <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Automation</h3>
        <label className="settings-checkbox">
          <input type="checkbox" defaultChecked={FINANCE_SETTINGS.autoPullCardTotals}/>
          <div>
            <div className="settings-checkbox-title">Auto-pull Demo Clinic card terminal totals from Close-day</div>
            <div className="settings-checkbox-sub">When you run Close-day in the clinic, weekly Card terminal field is pre-filled for Demo Clinic. You can still edit before submitting.</div>
          </div>
        </label>
        <label className="settings-checkbox">
          <input type="checkbox" defaultChecked={FINANCE_SETTINGS.autoCalcWages}/>
          <div>
            <div className="settings-checkbox-title">Auto-calculate wages from rota</div>
            <div className="settings-checkbox-sub">Use clinician shift hours × hourly rates from Pay rates table. Off by default — wages are manually entered.</div>
          </div>
        </label>
      </div>

      <div className="panel" style={{ padding: 24, marginTop: 16 }}>
        <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>VAT</h3>
        <div className="settings-row-2">
          <div className="field"><label>VAT threshold (annual)</label><input className="stripe-input" defaultValue={FINANCE_SETTINGS.vatThreshold}/></div>
          <div className="field"><label>VAT rate</label><input className="stripe-input" defaultValue={(FINANCE_SETTINGS.vatRate * 100) + '%'}/></div>
        </div>
        <div className="field"><label>VAT-registered businesses</label>
          {BUSINESSES.map(b => (
            <label key={b.id} className="settings-checkbox" style={{ padding: '8px 12px' }}>
              <input type="checkbox" defaultChecked={b.vatRegistered}/>
              <div><b>{b.name}</b><div style={{ fontSize: 11, color: 'var(--fg-3)' }}>{b.terminal}</div></div>
            </label>
          ))}
        </div>
      </div>

      <div className="panel" style={{ padding: 24, marginTop: 16 }}>
        <h3 style={{ margin: '0 0 16px', fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: 20 }}>Businesses</h3>
        {BUSINESSES.map(b => (
          <div key={b.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: 14, border: '1px solid var(--line)', borderRadius: 'var(--radius-md)', marginBottom: 8 }}>
            <span className="biz-dot" style={{ background: b.tint, width: 12, height: 12 }}/>
            <div style={{ flex: 1 }}>
              <div style={{ fontSize: 14, color: 'var(--fg-1)', fontWeight: 500 }}>{b.name}</div>
              <div style={{ fontSize: 12, color: 'var(--fg-3)' }}>{b.terminal} · {b.vatRegistered ? 'VAT registered' : 'Not VAT registered'}</div>
            </div>
            <button className="app-btn ghost icon-only"><Icon name="edit" size={14}/></button>
          </div>
        ))}
        <button className="app-btn"><Icon name="plus" size={14}/>Add business</button>
      </div>
    </>
  );
}

Object.assign(window, {
  OwnerShell, SettingsModal,
  OwMarketing, MarketingPerformance,
  OwFinance, FinancePinGate,
  FinanceDashboard, FinanceWeeklyInput, FinanceVat, FinanceProjections,
  FinanceTrends, FinancePayRates, FinancePricingCalc, FinanceSettings,
});
