/* Atlas Ledger — Compliance tab, expanded into the company-secretary centre.
   Registers view, NAR1 review-and-sign flow, and guided change-request flows
   (share transfer, director/secretary, registered address, allotment).
   Numbers mirror comsec/comsec-data.jsx (same hero entity) — keep in sync. */

const CSD = {
  company: 'ABC Trading Ltd', zh: '安栢貿易有限公司', crNo: '2678903',
  incorporated: '19 May 2018', anniversary: '19 May', office: 'Unit 12A, Harbour Centre, 25 Harbour Road, Wan Chai',
  capital: 'HKD 10,000 · 10,000 ordinary shares',
  secretary: 'Atlas Corporate Services Ltd', tcsp: 'TC006789',
  nar1Fee: 105, brFee: 2200,
  late: [['More than 42 days', 870], ['More than 3 months', 1740], ['More than 6 months', 2610], ['More than 9 months', 3480]],
  members: [
    { name: 'Chan Tai Wai, David 陳大偉', shares: 5500, pct: '55%' },
    { name: 'Chan Mei Ling, Michelle 陳美玲', shares: 3000, pct: '30%' },
    { name: 'Harbour Ventures Ltd', shares: 1500, pct: '15%' },
  ],
  members2025: [
    { name: 'Chan Tai Wai, David 陳大偉', shares: 7000, pct: '70%' },
    { name: 'Chan Mei Ling, Michelle 陳美玲', shares: 3000, pct: '30%' },
  ],
  directors: [
    { name: 'Chan Tai Wai, David', since: '19 May 2018' },
    { name: 'Chan Mei Ling, Michelle', since: '3 Feb 2020' },
  ],
  scr: [
    { name: 'Chan Tai Wai, David', nature: '55% of shares' },
    { name: 'Chan Mei Ling, Michelle', nature: '30% of shares' },
  ],
  nar1Summary: [
    ['Company name', 'ABC Trading Limited'], ['CR number', '2678903'],
    ['Registered office', 'Unit 12A, Harbour Centre, Wan Chai'], ['Share capital', 'HKD 10,000 · 10,000 ordinary'],
    ['Directors', '2 — David Chan · Michelle Chan'], ['Members', '3 — see register'],
    ['Company secretary', 'Atlas Corporate Services Ltd (TCSP TC006789)'],
  ],
  mail: [
    { when: '12 Jun', from: 'Inland Revenue Department', what: 'BR renewal demand note · HKD 2,200', st: ['answer', 'We’re preparing it'], note: 'Renewal handled by your secretary · due 14 Aug' },
    { when: '4 Jun', from: 'Inland Revenue Department', what: 'BIR51 Profits Tax Return', st: ['sign', 'Sign in Tasks →'], go: 'tasks', note: 'Prepared and checked by your team' },
    { when: '28 May', from: 'Companies Registry', what: 'NAR1 2025 acknowledgement', st: ['green', 'Filed & archived'], note: 'Copy saved under Documents' },
    { when: 'May', from: 'Various senders', what: '3 marketing circulars', st: ['confirm', 'Filtered'], note: 'Not forwarded — junk never reaches you' },
  ],
};

const CS_CHANGES = {
  transfer: { title: 'Transfer shares', meta: 'Bought & sold notes + stamping · we calculate the duty', tag: 'Stamp duty 0.2% + HKD 5' },
  director: {
    title: 'Change director or secretary', meta: 'Form ND2A · must be filed within 15 days', tag: 'ND2A',
    docs: ['Form ND2A', 'Board resolution', 'Resignation letter / consent to act'],
    deadline: 'Filed within 15 days of the change — we track it',
    statusRow: { label: 'Director / secretary change in progress', note: 'ND2A + resolution drafted today → licensed review → filed with the Companies Registry (15-day rule)' },
    doneNote: 'If a new director is joining we’ll collect their HKID copy and signed consent to act — WhatsApp works.',
  },
  address: {
    title: 'Change registered address', meta: 'Form NR1 · must be filed within 15 days', tag: 'NR1',
    docs: ['Form NR1', 'Board resolution'],
    deadline: 'Filed within 15 days of the move — we track it',
    statusRow: { label: 'Registered address change in progress', note: 'NR1 + resolution drafted today → licensed review → filed with the Companies Registry (15-day rule)' },
    doneNote: 'Your BR record updates too — we handle the IRD notification with the same change.',
  },
  allot: {
    title: 'Allot new shares', meta: 'Form NSC1 · filed within 1 month', tag: 'NSC1',
    docs: ['Form NSC1 (return of allotment)', 'Board + members’ resolutions', 'New share certificate'],
    deadline: 'NSC1 filed within 1 month of allotment — we track it',
    statusRow: { label: 'Share allotment in progress', note: 'NSC1 + resolutions drafted today → licensed review → filed with the Companies Registry (1-month rule)' },
    doneNote: 'The Register of Members and SCR update automatically once the allotment completes.',
  },
};

const fmtHK = (n) => 'HKD ' + Math.round(n).toLocaleString('en-US');
const csInput = { width: '100%', height: 42, borderRadius: 10, border: '1px solid var(--hb-line)', padding: '0 13px', fontSize: 13, fontFamily: 'var(--hb-grot)', background: '#fff', outline: 'none' };

/* ── small pieces ── */

function CsStepper({ step, labels }) {
  return (
    <div className="hb-stepper">
      {labels.map((l, i) => {
        const n = i + 1;
        const st = n < step ? 'done' : n === step ? 'cur' : '';
        return (
          <div key={l} className={'hb-step ' + st}>
            <span className="n">{n < step ? '✓' : n}</span>
            <span className="l">{l}</span>
            {i < labels.length - 1 && <span className="bar"></span>}
          </div>
        );
      })}
    </div>
  );
}

function CsCard({ children, style }) {
  return <div style={{ background: '#fff', border: '1px solid var(--hb-line)', borderRadius: 12, padding: '16px 18px', ...style }}>{children}</div>;
}

function CsDoneCard({ title, lines, onBack, backLabel }) {
  return (
    <CsCard style={{ marginTop: 18, textAlign: 'center', padding: '36px 24px' }}>
      <div style={{ width: 52, height: 52, margin: '0 auto', borderRadius: '50%', background: 'var(--hb-green-tint)', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <HIcon name="check" size={24} color="var(--hb-green)" sw={2.2} />
      </div>
      <div style={{ fontSize: 16.5, fontWeight: 700, marginTop: 12 }}>{title}</div>
      <div style={{ fontSize: 13, color: 'var(--hb-muted)', marginTop: 6, lineHeight: 1.6 }}>{lines}</div>
      <button className="hb-btn ghost" style={{ marginTop: 16 }} onClick={onBack}>{backLabel || 'Track it on the status page'}</button>
    </CsCard>
  );
}

function CsFlowShell({ title, sub, backTo, step, labels, children }) {
  return (
    <div style={{ maxWidth: 620 }}>
      <a className="hb-link" style={{ fontSize: 12.5 }} onClick={backTo}>← Back</a>
      <div style={{ fontSize: 18, fontWeight: 700, marginTop: 10 }}>{title}</div>
      <div style={{ fontSize: 12.5, color: 'var(--hb-muted)', marginTop: 3 }}>{sub}</div>
      <div style={{ marginTop: 16 }}><CsStepper step={step} labels={labels} /></div>
      {children}
    </div>
  );
}

function CsRegList({ title, rows, foot, right, notify }) {
  return (
    <CsCard style={{ marginTop: 14, padding: '14px 18px' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
        <span style={{ fontSize: 13.5, fontWeight: 700 }}>{title}</span>
        {right}
        <button className="hb-btn ghost" style={{ marginLeft: 'auto', padding: '5px 11px', fontSize: 12 }}
          onClick={() => notify('Certified copy of the ' + title + ' issued ✓ — find it under Documents')}>Download certified copy</button>
      </div>
      <div style={{ marginTop: 6 }}>
        {rows.map((r, i) => (
          <div key={i} className="hb-row hb-reg-row" style={{ minHeight: 46, padding: '6px 0', borderBottom: i === rows.length - 1 ? 'none' : '1px solid var(--hb-line-soft)' }}>
            <div style={{ flex: 1, minWidth: 0, fontSize: 13.5, fontWeight: 600 }}>{r[0]}</div>
            <div style={{ fontSize: 12.5, color: 'var(--hb-muted)' }}>{r[1]}</div>
            {r[2] && <div className="hb-num" style={{ width: 90, textAlign: 'right', fontSize: 13, fontWeight: 600, flexShrink: 0 }}>{r[2]}</div>}
          </div>
        ))}
      </div>
      {foot && <div style={{ fontSize: 11.5, color: 'var(--hb-faint)', marginTop: 8 }}>{foot}</div>}
    </CsCard>
  );
}

/* ── views ── */

function CsStatusView({ cs, setView, go }) {
  const dot = { green: 'var(--hb-green)', amber: '#D9A23E', red: 'var(--hb-red)' };
  const signed = cs.nar1.signed;
  const items = [
    signed
      ? { due: '30 Jun', label: 'NAR1 Annual Return', status: 'green', note: 'Signed 12 Jun · your licensed secretary reviews and files it with the Companies Registry' }
      : { due: '30 Jun', label: 'NAR1 Annual Return', status: 'amber', note: 'Prefilled from your registers — review & sign, about 1 minute', act: ['Review & sign →', () => setView('nar1')] },
    { due: '30 Jun', label: 'BIR51 Profits Tax Return', status: 'amber', note: 'Ready for your signature', act: ['Sign in Tasks →', () => go('tasks')] },
    { due: '14 Aug', label: 'Business Registration renewal', status: 'green', note: 'We prepare the renewal · government fee ~HKD 2,200' },
    { due: '30 Sep', label: 'AGM — written resolution', status: 'green', note: 'We circulate a written resolution — no meeting needed' },
    { due: 'Done', label: 'Significant Controllers Register', status: 'green', note: 'Up to date · annual review completed 12 Jun' },
    { due: 'Linked', label: 'Audited accounts', status: 'green', note: 'Tracked with your bookkeeping year-end — one timeline' },
  ];
  const inflight = [];
  if (cs.transfer.submitted) inflight.push({ due: 'Now', label: 'Share transfer in progress', note: 'AI drafting → licensed review → stamping within 2 days → registers updated' });
  ['director', 'address', 'allot'].forEach((k) => {
    if (cs.changes[k]) inflight.push({ due: 'Now', label: CS_CHANGES[k].statusRow.label, note: CS_CHANGES[k].statusRow.note });
  });
  inflight.forEach((r, i) => items.splice(2 + i, 0, { ...r, status: 'amber', teal: true }));

  return (
    <div>
      <div style={{ marginTop: 6, borderTop: '1px solid var(--hb-line)' }}>
        {items.map((c) => (
          <div key={c.label} className="hb-row" style={{ minHeight: 58, padding: '8px 0', height: 'auto', flexWrap: 'wrap', rowGap: 4 }}>
            <span style={{ width: 10, height: 10, borderRadius: '50%', background: c.teal ? 'var(--hb-teal)' : dot[c.status], marginRight: 14, flexShrink: 0 }}></span>
            <span className="hb-num" style={{ width: 70, fontSize: 12.5, color: 'var(--hb-muted)', flexShrink: 0 }}>{c.due}</span>
            <div style={{ flex: 1, minWidth: 180 }}>
              <div style={{ fontSize: 14, fontWeight: 600 }}>{c.label}</div>
              <div style={{ fontSize: 12, color: 'var(--hb-muted)', marginTop: 1 }}>{c.note}</div>
            </div>
            {c.act && <a className="hb-link" style={{ fontSize: 13, whiteSpace: 'nowrap' }} onClick={c.act[1]}>{c.act[0]}</a>}
          </div>
        ))}
      </div>
      <CsCard style={{ marginTop: 18, fontSize: 12.5, color: 'var(--hb-muted)', lineHeight: 1.7, padding: '13px 18px' }}>
        <b style={{ color: 'var(--hb-ink)' }}>Filing on time costs HKD 105.</b> Late annual returns escalate: HKD 870 → 1,740 → 2,610 → 3,480.
        Your company secretary prepares everything; you only confirm and sign.
      </CsCard>
    </div>
  );
}

function CsRegistersView({ notify }) {
  const [hist, setHist] = React.useState(false);
  const members = hist ? CSD.members2025 : CSD.members;
  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 14, flexWrap: 'wrap' }}>
        <span style={{ fontSize: 12.5, color: 'var(--hb-muted)' }}>Your statutory registers are live data — every document is generated from them.</span>
        <div className="hb-seg" style={{ marginLeft: 'auto' }}>
          <span className={'seg' + (!hist ? ' active' : '')} onClick={() => setHist(false)}>Today</span>
          <span className={'seg' + (hist ? ' active' : '')} onClick={() => setHist(true)}>As at 1 Jan 2025</span>
        </div>
      </div>
      {hist && (
        <div style={{ marginTop: 10, background: 'var(--hb-amber-tint)', borderRadius: 9, padding: '8px 12px', fontSize: 12, color: 'var(--hb-amber)', fontWeight: 600 }}>
          Historical snapshot — before the Jan 2025 transfer of 1,500 shares to Harbour Ventures Ltd. Any date can be rebuilt.
        </div>
      )}
      <CsRegList notify={notify} title="Register of Members"
        rows={members.map((m) => [m.name, 'Ordinary shares', m.shares.toLocaleString('en-US') + ' · ' + m.pct])}
        foot={hist ? '2 members · 10,000 shares' : '3 members · 10,000 shares · matches the NAR1 draft'} />
      <CsRegList notify={notify} title="Register of Directors & Secretary"
        rows={[...CSD.directors.map((d) => [d.name, 'Director · appointed ' + d.since, 'HKID ✓']), [CSD.secretary, 'Company secretary · TCSP licence ' + CSD.tcsp, '']]} />
      <CsRegList notify={notify} title="Significant Controllers Register"
        rows={CSD.scr.map((s) => [s.name, 'Registrable person · ' + s.nature, ''])}
        foot={'Kept at the registered office · designated representative: ' + CSD.secretary + ' · anyone holding over 25% is registrable'} />
    </div>
  );
}

function CsMailView({ go }) {
  return (
    <div>
      <div style={{ fontSize: 12.5, color: 'var(--hb-muted)', marginTop: 14 }}>
        Your registered office is with us — every letter is scanned, classified and handled the day it arrives. You never touch paper.
      </div>
      <div style={{ marginTop: 10, borderTop: '1px solid var(--hb-line)' }}>
        {CSD.mail.map((m) => (
          <div key={m.what} className="hb-row hb-reg-row" style={{ minHeight: 58, padding: '9px 0', height: 'auto' }}>
            <span className="hb-num" style={{ width: 62, fontSize: 12.5, color: 'var(--hb-muted)', flexShrink: 0 }}>{m.when}</span>
            <div style={{ flex: 1, minWidth: 180 }}>
              <div style={{ fontSize: 14, fontWeight: 600 }}>{m.what}</div>
              <div style={{ fontSize: 12, color: 'var(--hb-muted)', marginTop: 1 }}>{m.from} · {m.note}</div>
            </div>
            {m.go
              ? <a className="hb-link" style={{ fontSize: 13, whiteSpace: 'nowrap' }} onClick={() => go(m.go)}>{m.st[1]}</a>
              : <span className={'hb-tag ' + m.st[0]}>{m.st[1]}</span>}
          </div>
        ))}
      </div>
      <CsCard style={{ marginTop: 18, fontSize: 12.5, color: 'var(--hb-muted)', lineHeight: 1.7, padding: '13px 18px' }}>
        <b style={{ color: 'var(--hb-ink)' }}>Why letters matter:</b> government mail is how deadlines arrive — a BR demand note becomes a
        renewal task the minute it's scanned. Nothing depends on someone opening an envelope in time.
      </CsCard>
    </div>
  );
}

function CsRequestsView({ cs, setView }) {
  return (
    <div>
      <div style={{ fontSize: 12.5, color: 'var(--hb-muted)', marginTop: 14 }}>Tell us what changed — AI drafts the full pack the same day, your licensed secretary reviews and files it.</div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: 12, marginTop: 12 }}>
        {Object.entries(CS_CHANGES).map(([id, r]) => {
          const submitted = id === 'transfer' ? cs.transfer.submitted : cs.changes[id];
          return (
            <CsCard key={id} style={{ padding: '15px 17px', cursor: 'pointer', opacity: submitted ? 0.65 : 1 }}>
              <div onClick={() => setView(id)}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                  <span style={{ fontSize: 14, fontWeight: 700, flex: 1 }}>{r.title}</span>
                  <HIcon name="chevR" size={15} color="var(--hb-faint)" />
                </div>
                <div style={{ fontSize: 12, color: 'var(--hb-muted)', marginTop: 5, lineHeight: 1.5 }}>{r.meta}</div>
                <span className="hb-tag confirm" style={{ marginTop: 9 }}>{r.tag}</span>
                <div style={{ fontSize: 11.5, color: submitted ? 'var(--hb-green)' : 'var(--hb-teal)', fontWeight: 600, marginTop: 8 }}>
                  {submitted ? '✓ In progress — see status' : 'Start →'}
                </div>
              </div>
            </CsCard>
          );
        })}
      </div>
      <div style={{ fontSize: 11.5, color: 'var(--hb-faint)', marginTop: 12 }}>Something else? <a className="hb-link" onClick={() => setView('status')}>Check your status page</a> or message your secretary from any task.</div>
    </div>
  );
}

function CsNar1Flow({ state, setState, setView, go }) {
  const n = state.cs.nar1;
  const [showForm, setShowForm] = React.useState(false);
  const set = (patch) => setState((s) => ({ ...s, cs: { ...s.cs, nar1: { ...s.cs.nar1, ...patch } } }));

  return (
    <CsFlowShell title="NAR1 Annual Return · 2026"
      sub={'Anniversary ' + CSD.anniversary + ' + 42 days = due 30 Jun · prepared from your registers by AI, checked by your licensed secretary'}
      backTo={() => setView('status')} step={n.signed ? 4 : n.step} labels={['Review', 'Confirm', 'Sign']}>

      {n.signed ? (
        <CsDoneCard title="Signed · 12 Jun, 14:02"
          lines={<span>Your licensed secretary counter-signs and files it with the Companies Registry.<br />You don't need to do anything else.</span>}
          onBack={() => setView('status')} backLabel="Back to status" />
      ) : n.step === 1 ? (
        <CsCard style={{ marginTop: 18 }}>
          <div style={{ fontSize: 13.5, fontWeight: 700 }}>Everything below was prefilled from your registers</div>
          <div style={{ marginTop: 8 }}>
            {CSD.nar1Summary.map(([k, v]) => (
              <div key={k} className="hb-row hb-reg-row" style={{ minHeight: 44, padding: '5px 0', height: 'auto' }}>
                <span style={{ width: 150, fontSize: 12, color: 'var(--hb-muted)', flexShrink: 0 }}>{k}</span>
                <span style={{ flex: 1, fontSize: 13, fontWeight: 600, minWidth: 160 }}>{v}</span>
                <span style={{ fontSize: 11.5, color: 'var(--hb-green)', fontWeight: 600, whiteSpace: 'nowrap' }}>✓ matches registers</span>
              </div>
            ))}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 14, marginTop: 16, flexWrap: 'wrap' }}>
            <button className="hb-btn" onClick={() => set({ step: 2 })}>All correct — continue</button>
            <a className="hb-link" style={{ fontSize: 12.5, color: 'var(--hb-muted)' }} onClick={() => setView('requests')}>Something changed? Start a change request →</a>
          </div>
        </CsCard>
      ) : n.step === 2 ? (
        <CsCard style={{ marginTop: 18 }}>
          <div style={{ fontSize: 13.5, fontWeight: 700 }}>Filing fee</div>
          <div style={{ display: 'flex', justifyContent: 'space-between', padding: '10px 0', borderBottom: '1px solid var(--hb-line)', fontSize: 14, fontWeight: 700, marginTop: 4 }}>
            <span>On time (by 30 Jun)</span><span className="hb-num" style={{ color: 'var(--hb-green)' }}>HKD 105</span>
          </div>
          {CSD.late.map(([l, v]) => (
            <div key={l} style={{ display: 'flex', justifyContent: 'space-between', padding: '7px 0', fontSize: 12.5, color: 'var(--hb-muted)', borderBottom: '1px solid var(--hb-line-soft)' }}>
              <span>{l} late</span><span className="hb-num">HKD {v.toLocaleString('en-US')}</span>
            </div>
          ))}
          <div style={{ fontSize: 11.5, color: 'var(--hb-faint)', marginTop: 10 }}>The 42-day window runs from your incorporation anniversary ({CSD.anniversary}). We always file on time — this table is why it matters.</div>
          <div style={{ display: 'flex', gap: 10, marginTop: 16 }}>
            <button className="hb-btn ghost" onClick={() => set({ step: 1 })}>Back</button>
            <button className="hb-btn" onClick={() => set({ step: 3 })}>Confirm details</button>
          </div>
        </CsCard>
      ) : (
        <CsCard style={{ marginTop: 18 }}>
          <div style={{ fontSize: 13.5, color: 'var(--hb-muted)' }}>Annual return to 19 May 2026 · reviewed against your registers · fee HKD 105</div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginTop: 14, flexWrap: 'wrap' }}>
            <button className="hb-btn" style={{ height: 44, fontSize: 14 }} onClick={() => set({ signed: true })}>
              <HIcon name="pen" size={15} color="#fff" /> Sign electronically
            </button>
            <button className="hb-btn ghost" style={{ height: 44 }} onClick={() => setShowForm(!showForm)}>{showForm ? 'Hide full form' : 'View full form'}</button>
          </div>
          {showForm && (
            <div style={{ marginTop: 14, border: '1px solid var(--hb-line)', borderRadius: 8, background: '#FDFDFC', padding: '18px 20px', fontSize: 12, color: '#57606b', boxShadow: 'inset 0 1px 3px rgba(13,27,42,.04)' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between' }}>
                <b style={{ color: 'var(--hb-ink)', fontSize: 13 }}>FORM NAR1 — ANNUAL RETURN</b>
                <span style={{ fontSize: 10, color: 'var(--hb-faint)' }}>Companies Ordinance s.662 · Draft v2</span>
              </div>
              <div style={{ borderTop: '1px solid var(--hb-line-soft)', margin: '10px 0' }}></div>
              <div style={{ lineHeight: 2 }}>
                {[['Return date', '19 May 2026'], ...CSD.nar1Summary, ['Filing fee', 'HKD 105 (on time)']].map(([k, v]) => (
                  <div key={k}>{k}: <b style={{ color: 'var(--hb-ink)' }}>{v}</b></div>
                ))}
              </div>
              <div style={{ borderTop: '1px solid var(--hb-line-soft)', margin: '10px 0' }}></div>
              <div style={{ fontSize: 10.5, color: 'var(--hb-faint)' }}>Generated from register data — nothing typed by hand. The filed copy is archived under Documents.</div>
            </div>
          )}
          <div style={{ fontSize: 11.5, color: 'var(--hb-faint)', marginTop: 10 }}>Signing authorises your licensed company secretary to file the NAR1 with the Companies Registry.</div>
        </CsCard>
      )}
    </CsFlowShell>
  );
}

function CsTransferFlow({ state, setState, setView }) {
  const t = state.cs.transfer;
  const set = (patch) => setState((s) => ({ ...s, cs: { ...s.cs, transfer: { ...s.cs.transfer, ...patch } } }));
  const duty = Math.round(t.price * 0.002) + 5;

  return (
    <CsFlowShell title="Transfer shares" sub="AI drafts the full pack today · licensed review · stamped within 2 days · registers updated"
      backTo={() => setView(t.submitted ? 'status' : 'requests')} step={t.submitted ? 4 : t.step} labels={['Details', 'Review', 'Submit']}>

      {t.submitted ? (
        <CsDoneCard title="Request submitted"
          lines={<span>Draft documents are usually ready within the hour.<br />{t.to === 'new' ? 'We’ll message you for the new shareholder’s HKID and address proof (WhatsApp works).' : 'No new KYC needed — both parties are on file.'}</span>}
          onBack={() => setView('status')} />
      ) : t.step === 1 ? (
        <CsCard style={{ marginTop: 18 }}>
          <div style={{ display: 'grid', gap: 14 }}>
            <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Transferor (selling)
              <select value={t.from} onChange={(e) => set({ from: e.target.value })} style={{ ...csInput, marginTop: 6 }}>
                {CSD.members.map((m) => <option key={m.name} value={m.name}>{m.name} — holds {m.shares.toLocaleString('en-US')}</option>)}
              </select>
            </label>
            <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Transferee (buying)
              <select value={t.to} onChange={(e) => set({ to: e.target.value })} style={{ ...csInput, marginTop: 6 }}>
                <option value="new">A new shareholder</option>
                {CSD.members.map((m) => <option key={m.name} value={m.name}>{m.name}</option>)}
              </select>
            </label>
            {t.to === 'new' && (
              <div style={{ background: 'var(--hb-teal-tint)', borderRadius: 9, padding: '9px 12px', fontSize: 12, color: 'var(--hb-teal-deep)', lineHeight: 1.5 }}>
                New shareholder → we'll need their HKID copy and address proof. Send by WhatsApp or upload — AI checks completeness and expiry.
              </div>
            )}
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Number of shares
                <input type="number" value={t.shares} onChange={(e) => set({ shares: +e.target.value || 0 })} style={{ ...csInput, marginTop: 6 }} />
              </label>
              <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Consideration (HKD)
                <input type="number" value={t.price} onChange={(e) => set({ price: +e.target.value || 0 })} style={{ ...csInput, marginTop: 6 }} />
              </label>
            </div>
          </div>
          <button className="hb-btn" style={{ marginTop: 16 }} disabled={!t.shares || !t.price} onClick={() => set({ step: 2 })}>Continue</button>
        </CsCard>
      ) : (
        <CsCard style={{ marginTop: 18 }}>
          <div style={{ fontSize: 13.5, fontWeight: 700 }}>Review — calculated instantly</div>
          <div style={{ marginTop: 8 }}>
            {[['Transfer', t.shares.toLocaleString('en-US') + ' ordinary shares'],
              ['From', t.from],
              ['To', t.to === 'new' ? 'New shareholder (KYC to follow)' : t.to],
              ['Consideration', fmtHK(t.price)],
              ['Stamp duty (0.2% + HKD 5)', fmtHK(duty)]].map(([k, v], i, arr) => (
              <div key={k} style={{ display: 'flex', justifyContent: 'space-between', gap: 14, padding: '8px 0', fontSize: 13, borderBottom: i === arr.length - 1 ? 'none' : '1px solid var(--hb-line-soft)', fontWeight: i === arr.length - 1 ? 700 : 400 }}>
                <span style={{ color: 'var(--hb-muted)' }}>{k}</span><span className="hb-num" style={{ textAlign: 'right' }}>{v}</span>
              </div>
            ))}
          </div>
          <div style={{ background: 'var(--hb-bg)', borderRadius: 9, padding: '10px 13px', fontSize: 12, color: 'var(--hb-muted)', marginTop: 10, lineHeight: 1.6 }}>
            <b style={{ color: 'var(--hb-ink)' }}>We generate:</b> Bought &amp; Sold Notes · Instrument of Transfer · board resolution · new share certificate — then your licensed secretary reviews, arranges stamping within 2 days, and updates the Register of Members and SCR.
          </div>
          <div style={{ display: 'flex', gap: 10, marginTop: 16 }}>
            <button className="hb-btn ghost" onClick={() => set({ step: 1 })}>Back</button>
            <button className="hb-btn" onClick={() => set({ submitted: true })}>Submit request</button>
          </div>
        </CsCard>
      )}
    </CsFlowShell>
  );
}

/* generic guided flow for director / address / allotment changes */
function CsChangeFlow({ type, state, setState, setView }) {
  const def = CS_CHANGES[type];
  const submitted = state.cs.changes[type];
  const [step, setStep] = React.useState(1);
  const [f, setF] = React.useState(() => (
    type === 'director' ? { action: 'A director resigns', who: 'Chan Mei Ling, Michelle', when: '15 Jun 2026' }
    : type === 'address' ? { addr: 'Suite 2001, Tower 2, Harbour Centre, Wan Chai', when: '1 Jul 2026' }
    : { shares: 2000, price: 100000, to: 'new' }
  ));
  const setField = (k) => (e) => setF((o) => ({ ...o, [k]: e.target.value }));
  const submit = () => setState((s) => ({ ...s, cs: { ...s.cs, changes: { ...s.cs.changes, [type]: true } } }));

  const allotTotal = 10000 + (+f.shares || 0);
  const allotPct = ((+f.shares || 0) / allotTotal * 100).toFixed(1);

  const reviewRows = type === 'director'
    ? [['Change', f.action], ['Person', f.who], ['Effective', f.when]]
    : type === 'address'
      ? [['Current address', CSD.office], ['New address', f.addr], ['Effective', f.when]]
      : [['New shares', (+f.shares).toLocaleString('en-US') + ' ordinary'], ['Consideration', fmtHK(+f.price)], ['Allotted to', f.to === 'new' ? 'New investor (KYC to follow)' : f.to], ['After allotment', allotTotal.toLocaleString('en-US') + ' shares · new holder ' + allotPct + '%']];

  return (
    <CsFlowShell title={def.title} sub={def.meta + ' · AI drafts today, your licensed secretary reviews and files'}
      backTo={() => setView(submitted ? 'status' : 'requests')} step={submitted ? 4 : step} labels={['Details', 'Review', 'Submit']}>

      {submitted ? (
        <CsDoneCard title="Request submitted"
          lines={<span>Draft documents are usually ready within the hour.<br />{def.doneNote}</span>}
          onBack={() => setView('status')} />
      ) : step === 1 ? (
        <CsCard style={{ marginTop: 18 }}>
          <div style={{ display: 'grid', gap: 14 }}>
            {type === 'director' && (
              <React.Fragment>
                <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>What's changing
                  <select value={f.action} onChange={setField('action')} style={{ ...csInput, marginTop: 6 }}>
                    {['A director resigns', 'Appoint a new director', 'Change company secretary'].map((o) => <option key={o}>{o}</option>)}
                  </select>
                </label>
                {f.action === 'A director resigns' ? (
                  <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Who
                    <select value={f.who} onChange={setField('who')} style={{ ...csInput, marginTop: 6 }}>
                      {CSD.directors.map((d) => <option key={d.name}>{d.name}</option>)}
                    </select>
                  </label>
                ) : (
                  <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Name
                    <input value={f.who} onChange={setField('who')} placeholder="Full name as on HKID / passport" style={{ ...csInput, marginTop: 6 }} />
                  </label>
                )}
                <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Effective date
                  <input value={f.when} onChange={setField('when')} style={{ ...csInput, marginTop: 6 }} />
                </label>
                {f.action !== 'A director resigns' && (
                  <div style={{ background: 'var(--hb-teal-tint)', borderRadius: 9, padding: '9px 12px', fontSize: 12, color: 'var(--hb-teal-deep)', lineHeight: 1.5 }}>
                    New appointee → we'll collect their HKID copy and signed consent to act. Send by WhatsApp or upload.
                  </div>
                )}
              </React.Fragment>
            )}
            {type === 'address' && (
              <React.Fragment>
                <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>New registered address
                  <input value={f.addr} onChange={setField('addr')} style={{ ...csInput, marginTop: 6 }} />
                </label>
                <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Effective date
                  <input value={f.when} onChange={setField('when')} style={{ ...csInput, marginTop: 6 }} />
                </label>
                <div style={{ background: 'var(--hb-teal-tint)', borderRadius: 9, padding: '9px 12px', fontSize: 12, color: 'var(--hb-teal-deep)', lineHeight: 1.5 }}>
                  Must be a physical Hong Kong address — P.O. boxes aren't accepted. No office? {CSD.secretary} can host your registered office (included in your plan).
                </div>
              </React.Fragment>
            )}
            {type === 'allot' && (
              <React.Fragment>
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                  <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>New shares to issue
                    <input type="number" value={f.shares} onChange={setField('shares')} style={{ ...csInput, marginTop: 6 }} />
                  </label>
                  <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Total consideration (HKD)
                    <input type="number" value={f.price} onChange={setField('price')} style={{ ...csInput, marginTop: 6 }} />
                  </label>
                </div>
                <label style={{ fontSize: 12, fontWeight: 600, color: 'var(--hb-muted)' }}>Allotted to
                  <select value={f.to} onChange={setField('to')} style={{ ...csInput, marginTop: 6 }}>
                    <option value="new">A new investor</option>
                    {CSD.members.map((m) => <option key={m.name} value={m.name}>{m.name}</option>)}
                  </select>
                </label>
                <div style={{ background: 'var(--hb-bg)', borderRadius: 9, padding: '9px 12px', fontSize: 12, color: 'var(--hb-muted)', lineHeight: 1.5 }}>
                  Dilution preview: share capital becomes <b className="hb-num" style={{ color: 'var(--hb-ink)' }}>{allotTotal.toLocaleString('en-US')}</b> shares — the new holder gets <b className="hb-num" style={{ color: 'var(--hb-ink)' }}>{allotPct}%</b>.
                </div>
              </React.Fragment>
            )}
          </div>
          <button className="hb-btn" style={{ marginTop: 16 }} onClick={() => setStep(2)}>Continue</button>
        </CsCard>
      ) : (
        <CsCard style={{ marginTop: 18 }}>
          <div style={{ fontSize: 13.5, fontWeight: 700 }}>Review</div>
          <div style={{ marginTop: 8 }}>
            {reviewRows.map(([k, v], i, arr) => (
              <div key={k} style={{ display: 'flex', justifyContent: 'space-between', gap: 14, padding: '8px 0', fontSize: 13, borderBottom: i === arr.length - 1 ? 'none' : '1px solid var(--hb-line-soft)' }}>
                <span style={{ color: 'var(--hb-muted)', flexShrink: 0 }}>{k}</span><span style={{ textAlign: 'right', fontWeight: 600 }}>{v}</span>
              </div>
            ))}
          </div>
          <div style={{ background: 'var(--hb-bg)', borderRadius: 9, padding: '10px 13px', fontSize: 12, color: 'var(--hb-muted)', marginTop: 10, lineHeight: 1.6 }}>
            <b style={{ color: 'var(--hb-ink)' }}>We generate:</b> {def.docs.join(' · ')} — then your licensed secretary reviews, signs and files. {def.deadline}.
          </div>
          <div style={{ display: 'flex', gap: 10, marginTop: 16 }}>
            <button className="hb-btn ghost" onClick={() => setStep(1)}>Back</button>
            <button className="hb-btn" onClick={submit}>Submit request</button>
          </div>
        </CsCard>
      )}
    </CsFlowShell>
  );
}

/* ── page ── */

function CompliancePage({ state, setState, go }) {
  const [view, setView] = React.useState('status');
  const [toast, setToast] = React.useState(null);
  const toastTimer = React.useRef(null);
  const notify = (msg) => {
    setToast(msg);
    clearTimeout(toastTimer.current);
    toastTimer.current = setTimeout(() => setToast(null), 2800);
  };
  const inFlow = ['nar1', 'transfer', 'director', 'address', 'allot'].includes(view);
  const cs = state.cs;
  const dueSoon = (cs.nar1.signed ? 0 : 1) + 1; /* NAR1 + BIR51 */

  return (
    <div className="hb-page hb-shell" style={{ paddingTop: 26, paddingBottom: 40 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
        <span style={{ fontSize: 22, fontWeight: 700 }}>Compliance</span>
        <span className="hb-tag answer">{dueSoon} due within 30 days</span>
        <span style={{ marginLeft: 'auto', fontSize: 12.5, color: 'var(--hb-muted)' }} className="hb-desktop-only">{CSD.secretary} · TCSP {CSD.tcsp}</span>
      </div>

      {!inFlow && (
        <div className="hb-seg" style={{ marginTop: 14 }}>
          {[['status', 'Status'], ['registers', 'Registers'], ['mail', 'Mail'], ['requests', 'Make a change']].map(([id, label]) => (
            <span key={id} className={'seg' + (view === id ? ' active' : '')} onClick={() => setView(id)}>{label}</span>
          ))}
        </div>
      )}

      {view === 'status' && <CsStatusView cs={cs} setView={setView} go={go} />}
      {view === 'registers' && <CsRegistersView notify={notify} />}
      {view === 'mail' && <CsMailView go={go} />}
      {view === 'requests' && <CsRequestsView cs={cs} setView={setView} />}
      {view === 'nar1' && <CsNar1Flow state={state} setState={setState} setView={setView} go={go} />}
      {view === 'transfer' && <CsTransferFlow state={state} setState={setState} setView={setView} />}
      {(view === 'director' || view === 'address' || view === 'allot') && <CsChangeFlow type={view} state={state} setState={setState} setView={setView} />}

      {toast && (
        <div style={{ position: 'fixed', bottom: 22, left: '50%', transform: 'translateX(-50%)', zIndex: 55, background: 'var(--hb-ink)', color: '#fff', borderRadius: 12, padding: '13px 18px', boxShadow: '0 18px 44px rgba(13,27,42,.4)', display: 'flex', alignItems: 'center', gap: 12, maxWidth: 'calc(100vw - 32px)' }}>
          <HIcon name="check" size={17} color="#fff" sw={2.2} />
          <span style={{ fontSize: 13, fontWeight: 600 }}>{toast}</span>
        </div>
      )}
    </div>
  );
}

Object.assign(window, { CompliancePage });
