// Opalus — Auth (INV-01/02) + Account cluster (INV-30→36)
const AC = window.OpalusDesignSystem_1dce4b;

/* ============================================================ INV-01 · EMAIL VERIFICATION ============================================================ */
function VerifyEmailScreen() {
  const { state, update, go } = window.useOpalus();
  const { Button, Card, Logo } = AC;
  const [secs, setSecs] = useState(30);
  const [expired, setExpired] = useState(false);
  useEffect(() => { if (secs <= 0) return; const id = setTimeout(() => setSecs((s) => s - 1), 1000); return () => clearTimeout(id); }, [secs]);
  const verified = () => { update((s) => { s.investor.emailVerified = true; }); go('twofa'); };
  if (expired) {
    return (
      <AuthShell>
        <Card padding="lg" radius="xl" shadow="card" style={{ padding: 40, maxWidth: 440, width: '100%' }}>
          <div style={{ width: 56, height: 56, borderRadius: 'var(--radius-md)', background: 'var(--danger-50)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: 18 }}><span style={{ color: 'var(--danger-600)', fontSize: 24, fontWeight: 700 }}>!</span></div>
          <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 24, color: 'var(--ink)', margin: '0 0 8px' }}>This link is no longer valid</h2>
          <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)', lineHeight: 1.6, margin: '0 0 24px' }}>Links expire after 24 hours and can be used once.</p>
          <Button variant="primary" block onClick={() => { setExpired(false); setSecs(30); }}>Send a new link</Button>
        </Card>
      </AuthShell>
    );
  }
  return (
    <AuthShell>
      <Card padding="lg" radius="xl" shadow="card" style={{ padding: 40, maxWidth: 440, width: '100%' }}>
        <div style={{ width: 56, height: 56, borderRadius: 'var(--radius-md)', background: 'var(--cream-100)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', marginBottom: 18 }}>
          <AC.IconlyRegularLightProfile style={{ width: 26, height: 26, color: 'var(--bronze-600)' }} />
        </div>
        <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 26, color: 'var(--ink)', margin: '0 0 8px' }}>Check your inbox</h2>
        <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)', lineHeight: 1.6, margin: '0 0 24px' }}>We've sent a verification link to <b style={{ color: 'var(--ink)' }}>{state.investor.email}</b>. The link is valid for 24 hours.</p>
        <Button variant="primary" block onClick={verified}>I've verified my email (demo)</Button>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 20, alignItems: 'center' }}>
          <span className={secs > 0 ? '' : 'opx-link'} style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: secs > 0 ? 'var(--text-muted)' : undefined, cursor: secs > 0 ? 'default' : 'pointer' }} onClick={() => secs <= 0 && setSecs(30)}>{secs > 0 ? `Resend available in ${secs}s` : 'Resend link'}</span>
          <span className="opx-link" style={{ fontSize: 13 }} onClick={() => go('welcome')}>Use a different email address</span>
          <span className="opx-link" style={{ fontSize: 12, color: 'var(--text-muted)' }} onClick={() => setExpired(true)}>Simulate an expired link (demo)</span>
        </div>
      </Card>
    </AuthShell>
  );
}

/* ============================================================ INV-02 · TWO-FACTOR SETUP ============================================================ */
function TwoFAScreen() {
  const { update, go } = window.useOpalus();
  const { Button, Card } = AC;
  const [showKey, setShowKey] = useState(false);
  const [code, setCode] = useState('');
  const [stage, setStage] = useState('totp'); // totp | sms | recovery
  const [stored, setStored] = useState(false);
  const [method, setMethod] = useState('app');
  const [phone, setPhone] = useState('');
  const [smsSent, setSmsSent] = useState(false);
  const [smsCode, setSmsCode] = useState('');
  const codeErr = code.length === 6 && code !== '123456';
  const RECOVERY = ['4F2A-9KQ1', '7H3M-2LP8', 'X9C4-1RT6', 'BN52-7WQ3', '0K8D-3FH9', 'M6V2-8YT1', 'P4R9-5JC7', 'A1L8-6QW2', 'E7T3-9MN4', 'Z2X5-4KD8'];
  return (
    <AuthShell>
      <Card padding="lg" radius="xl" shadow="card" style={{ padding: 40, maxWidth: 520, width: '100%' }}>
        {stage === 'totp' && (
          <>
            <window.Eyebrow>Step 2 of 2</window.Eyebrow>
            <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 26, color: 'var(--ink)', margin: '8px 0 8px' }}>Secure your account</h2>
            <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)', lineHeight: 1.6, margin: '0 0 24px' }}>Two-factor authentication is required for every Opalus account. It protects your money and your data even if your password is compromised.</p>
            <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 16, color: 'var(--ink)', margin: '0 0 14px' }}>Set up with an authenticator app</h3>
            <div style={{ display: 'flex', gap: 22, alignItems: 'flex-start', flexWrap: 'wrap' }}>
              <div style={{ width: 130, height: 130, borderRadius: 'var(--radius-md)', background: 'repeating-conic-gradient(var(--navy-950) 0% 25%, #fff 0% 50%) 50% / 16px 16px', border: '1px solid var(--border-subtle)', flex: '0 0 auto' }} />
              <ol style={{ margin: 0, paddingLeft: 18, fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-body)', lineHeight: 1.7, flex: 1, minWidth: 200 }}>
                <li>Open your authenticator app (Google Authenticator, Microsoft Authenticator, or similar).</li>
                <li>Scan this QR code, or enter the key manually.</li>
                <li>Enter the 6-digit code the app shows.</li>
              </ol>
            </div>
            <button type="button" className="opx-link" onClick={() => setShowKey(!showKey)} style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 12.5, marginTop: 14, padding: 0 }}>Can't scan? Show the key</button>
            {showKey && <div style={{ fontFamily: 'var(--font-display)', fontSize: 16, letterSpacing: '0.12em', color: 'var(--ink)', marginTop: 8, background: 'var(--surface-inset)', padding: '10px 14px', borderRadius: 'var(--radius-md)' }}>JBSWY3DPEHPK3PXP</div>}
            <div style={{ marginTop: 20 }}>
              <window.Field label="6-digit code">
                <input className="opx-amount" style={{ fontSize: 22, letterSpacing: '0.3em', maxWidth: 200 }} inputMode="numeric" maxLength={6} value={code} onChange={(e) => setCode(e.target.value.replace(/\D/g, '').slice(0, 6))} placeholder="123456" />
              </window.Field>
              {codeErr && <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--danger-600)', marginTop: 8 }}>That code isn't valid. Codes change every 30 seconds — try the current one.</div>}
            </div>
            <Button variant="primary" style={{ marginTop: 20 }} disabled={code.length !== 6 || codeErr} onClick={() => setStage('recovery')}>Verify code</Button>
            <div style={{ marginTop: 16, fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--text-muted)' }}><span className="opx-link" onClick={() => setStage('sms')}>Can't use an authenticator app?</span></div>
          </>
        )}
        {stage === 'sms' && (
          <>
            <window.Eyebrow>Two-factor · SMS</window.Eyebrow>
            <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 24, color: 'var(--ink)', margin: '8px 0 18px' }}>Set up with SMS</h2>
            {!smsSent ? (
              <>
                <window.Field label="Phone number (with country code)">
                  <input className="opx-amount" style={{ fontSize: 16, fontWeight: 500 }} value={phone} onChange={(e) => setPhone(e.target.value)} placeholder="+33 6 12 34 56 78" />
                </window.Field>
                <Button variant="primary" style={{ marginTop: 18 }} disabled={phone.trim().length < 6} onClick={() => setSmsSent(true)}>Send code</Button>
              </>
            ) : (
              <>
                <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)', margin: '0 0 14px' }}>We've sent a code to {phone}.</p>
                <window.Field label="6-digit code">
                  <input className="opx-amount" style={{ fontSize: 22, letterSpacing: '0.3em', maxWidth: 200 }} inputMode="numeric" maxLength={6} value={smsCode} onChange={(e) => setSmsCode(e.target.value.replace(/\D/g, '').slice(0, 6))} placeholder="123456" />
                </window.Field>
                <Button variant="primary" style={{ marginTop: 18 }} disabled={smsCode.length !== 6} onClick={() => { setMethod('sms'); setStage('recovery'); }}>Verify code</Button>
              </>
            )}
            <div style={{ marginTop: 16 }}><span className="opx-link" style={{ fontSize: 12.5 }} onClick={() => { setStage('totp'); setSmsSent(false); }}>Use an authenticator app instead</span></div>
          </>
        )}
        {stage === 'recovery' && (
          <>
            <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 24, color: 'var(--ink)', margin: '0 0 8px' }}>Save your recovery codes</h2>
            <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)', lineHeight: 1.6, margin: '0 0 18px' }}>These 10 codes are your way back in if you lose your authenticator. Each works once. <b style={{ color: 'var(--ink)' }}>They are shown only now.</b></p>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: 8, background: 'var(--surface-inset)', borderRadius: 'var(--radius-md)', padding: 16, marginBottom: 16 }}>
              {RECOVERY.map((c) => <span key={c} style={{ fontFamily: 'var(--font-display)', fontSize: 15, letterSpacing: '0.06em', color: 'var(--ink)' }}>{c}</span>)}
            </div>
            <div style={{ display: 'flex', gap: 12, marginBottom: 18 }}>
              <Button variant="soft" size="sm" leadingIcon={<AC.IconlyRegularLightDownload style={{ width: 16, height: 16, color: 'var(--bronze-700)' }} />}>Download codes</Button>
              <Button variant="soft" size="sm">Copy codes</Button>
            </div>
            {method === 'sms' && <window.Note tone="info" title="SMS is enabled" style={{ marginBottom: 16 }}>SMS codes work, but an authenticator app is more secure. You can switch anytime in Settings → Security.</window.Note>}
            <window.AckBox checked={stored} onChange={setStored}>I've stored my recovery codes somewhere safe</window.AckBox>
            <Button variant="primary" style={{ marginTop: 20 }} disabled={!stored} onClick={() => { update((s) => { s.investor.twoFA = { enabled: true, method }; }); go(state_onboarded() ? 'dashboard' : 'onboarding'); }}>Finish setup</Button>
          </>
        )}
      </Card>
    </AuthShell>
  );
}
function state_onboarded() { try { return JSON.parse(localStorage.getItem('opalus_investor_v1') || '{}').onboarded; } catch (e) { return false; } }

function AuthShell({ children }) {
  const { Logo } = AC;
  return (
    <div style={{ minHeight: '100vh', background: 'var(--surface-page)', display: 'flex', flexDirection: 'column' }}>
      <header style={{ height: 68, background: '#fff', borderBottom: '1px solid var(--border-faint)', display: 'flex', alignItems: 'center', padding: '0 28px' }}>
        <Logo variant="navy" height={30} base="assets/logo" />
        <span style={{ marginLeft: 16, paddingLeft: 16, borderLeft: '1px solid var(--border-subtle)', fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)' }}>Account security</span>
      </header>
      <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: '40px 24px' }}>
        <div className="opx-fade" style={{ width: '100%', maxWidth: 560, display: 'flex', justifyContent: 'center' }}>{children}</div>
      </div>
    </div>
  );
}

/* ============================================================ ACCOUNT HUB ============================================================ */
const ACCOUNT_TABS = [
  { key: 'settings', label: 'Settings' },
  { key: 'notifications', label: 'Notifications' },
  { key: 'messages', label: 'Messages' },
  { key: 'complaints', label: 'Complaints' },
  { key: 'data', label: 'Data & privacy' },
];

function AccountScreen() {
  const { state, go } = window.useOpalus();
  const tab = state.route.params.tab || 'settings';
  return (
    <div className="opx-container opx-fade" style={{ maxWidth: 960 }}>
      <window.Eyebrow>Account</window.Eyebrow>
      <h1 className="opx-section-title" style={{ margin: '8px 0 22px' }}>Manage your account</h1>
      <div className="opx-detail" style={{ gridTemplateColumns: '210px 1fr', gap: 28, alignItems: 'start' }}>
        <nav style={{ display: 'flex', flexDirection: 'column', gap: 4, position: 'sticky', top: 96 }}>
          {ACCOUNT_TABS.map((t) => {
            const on = tab === t.key;
            return <button key={t.key} type="button" onClick={() => go('account', { tab: t.key })} style={{ textAlign: 'left', cursor: 'pointer', border: 'none', background: on ? 'var(--cream-100)' : 'transparent', color: on ? 'var(--bronze-700)' : 'var(--text-body)', fontFamily: 'var(--font-body)', fontSize: 14, fontWeight: on ? 600 : 400, padding: '11px 14px', borderRadius: 'var(--radius-md)' }}>{t.label}</button>;
          })}
        </nav>
        <div style={{ minWidth: 0 }}>
          {tab === 'settings' && <SettingsTab />}
          {tab === 'notifications' && <NotificationsTab />}
          {tab === 'messages' && <MessagesTab />}
          {tab === 'complaints' && <ComplaintsTab />}
          {tab === 'data' && <DataTab />}
        </div>
      </div>
    </div>
  );
}

/* ---------- INV-33 · Settings ---------- */
function SettingsTab() {
  const { state, go } = window.useOpalus();
  const { Card, Button } = AC;
  const [resi, setResi] = useState(false);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
      <Card padding="lg" radius="lg" shadow="sm">
        <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: '0 0 16px' }}>Profile</h3>
        <window.Field label="Legal name" hint="Your legal name comes from identity verification and can't be edited here. Contact support for corrections.">
          <input className="opx-amount" style={{ fontSize: 16, fontWeight: 500, background: 'var(--surface-inset)', color: 'var(--text-muted)' }} value={state.investor.name} readOnly />
        </window.Field>
        <div style={{ marginTop: 18 }}>
          <window.Field label="Country of residence">
            <input className="opx-amount" style={{ fontSize: 16, fontWeight: 500 }} value={state.investor.country} readOnly />
          </window.Field>
        </div>
        <div style={{ marginTop: 18 }}>
          <window.Field label="Country of fiscal residence" hint="Used on your tax documents. Snapshotted at the time of each investment.">
            <input className="opx-amount" style={{ fontSize: 16, fontWeight: 500 }} value={state.investor.fiscalResidence || state.investor.country} readOnly />
          </window.Field>
        </div>
        <button type="button" className="opx-link" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 13, marginTop: 12, padding: 0 }} onClick={() => setResi(true)}>Change country of residence</button>
        {resi && (
          <div style={{ marginTop: 14 }}>
            <window.Note tone="warn" title="Changing your country of residence requires re-verification" icon={<span style={{ fontWeight: 700 }}>!</span>}>
              Your eligibility for some projects may change. Existing investments are unaffected.
              <div style={{ display: 'flex', gap: 10, marginTop: 12 }}>
                <Button variant="primary" size="sm" onClick={() => setResi(false)}>Continue</Button>
                <Button variant="ghost" size="sm" onClick={() => setResi(false)}>Cancel</Button>
              </div>
            </window.Note>
          </div>
        )}
      </Card>

      <BankAccountsCard />

      <Card padding="lg" radius="lg" shadow="sm">
        <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: '0 0 4px' }}>Security</h3>
        <p style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--text-muted)', margin: '0 0 12px' }}>You'll stay signed in here; all other sessions will be signed out when you change your password.</p>
        {[['Change password', null], ['Two-factor method', 'Authenticator app'], ['Regenerate recovery codes', null], ['Active sessions', '2 devices']].map(([k, v], i) => (
          <div key={k} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, padding: '13px 0', borderTop: i ? '1px solid var(--border-faint)' : 'none' }}>
            <div><div style={{ fontFamily: 'var(--font-body)', fontSize: 14, fontWeight: 500, color: 'var(--text-strong)' }}>{k}</div>{v && <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--text-muted)' }}>{v}</div>}</div>
            <button type="button" className="opx-link" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 13 }} onClick={() => k === 'Two-factor method' && go('twofa')}>Manage</button>
          </div>
        ))}
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, padding: '13px 0', borderTop: '1px solid var(--border-faint)' }}>
          <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-body)' }}>iPhone · Paris · current</div>
          <span style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-muted)' }}>This device</span>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, padding: '13px 0', borderTop: '1px solid var(--border-faint)' }}>
          <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-body)' }}>MacBook Pro · Paris · 2 days ago</div>
          <button type="button" className="opx-link" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 13 }}>Sign out this device</button>
        </div>
      </Card>
    </div>
  );
}

/* ---------- INV-24 · Bank-account management (own-name beneficiaries) ----------
   Saved SEPA withdrawal destinations. Must be in the investor's own legal name (matched to their
   verified identity). Added accounts start 'pending' until a (mocked) micro-deposit verification. */
const ibanClean = (v) => v.replace(/\s/g, '').toUpperCase();
const ibanValid = (v) => ibanClean(v).length >= 15 && ibanClean(v).length <= 34 && /^[A-Z]{2}[0-9A-Z]+$/.test(ibanClean(v));
const ibanMask = (v) => { const c = ibanClean(v); return c.slice(0, 4) + ' ···· ' + c.slice(-4); };

function BankAccountsCard() {
  const { state } = window.useOpalus();
  const { Card, Button } = AC;
  const [adding, setAdding] = useState(false);
  return (
    <Card padding="lg" radius="lg" shadow="sm">
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: 6 }}>
        <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: 0 }}>Bank accounts</h3>
        {!adding && <Button variant="soft" size="sm" onClick={() => setAdding(true)}>Add account</Button>}
      </div>
      <p style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--text-muted)', margin: '0 0 14px', lineHeight: 1.6 }}>Withdrawals can only be sent to a verified account in your own name, matching your verified identity. Add and manage your destinations here.</p>
      <window.BankAccountList editable addOpen={adding} onCloseAdd={() => setAdding(false)} />
    </Card>
  );
}

/* Shared bank-account list — reused in account settings (editable) and the withdraw flow (selectable).
   Props: editable (show verify/remove + add), selectable (radio select), selectedId, onSelect,
   addOpen / onCloseAdd to drive the inline add form. */
function BankAccountList({ editable, selectable, selectedId, onSelect, addOpen, onCloseAdd }) {
  const { state, update } = window.useOpalus();
  const { Button } = AC;
  const accounts = state.investor.bankAccounts || [];
  const [label, setLabel] = useState('');
  const [iban, setIban] = useState('');
  const holder = state.investor.name;
  const ibanOk = ibanValid(iban);

  const add = () => {
    if (!ibanOk) return;
    update((s) => { (s.investor.bankAccounts = s.investor.bankAccounts || []).push({ id: 'ba' + Date.now(), label: label.trim() || 'Bank account', iban: iban.trim(), holder, status: 'pending', addedAt: new Date().toISOString() }); });
    setLabel(''); setIban(''); if (onCloseAdd) onCloseAdd();
  };
  const verify = (id) => update((s) => { const a = (s.investor.bankAccounts || []).find((x) => x.id === id); if (a) a.status = 'verified'; });
  const remove = (id) => update((s) => { s.investor.bankAccounts = (s.investor.bankAccounts || []).filter((x) => x.id !== id); });

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
      {accounts.length === 0 && !addOpen && <div style={{ fontFamily: 'var(--font-body)', fontSize: 13.5, color: 'var(--text-muted)', padding: '8px 0' }}>No saved bank accounts yet.</div>}
      {accounts.map((a) => {
        const verified = a.status === 'verified';
        const on = selectable && selectedId === a.id;
        return (
          <div key={a.id} onClick={() => selectable && verified && onSelect(a.id)} style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '13px 16px', border: `1.5px solid ${on ? 'var(--bronze-500)' : 'var(--border-faint)'}`, borderRadius: 'var(--radius-md)', background: on ? 'var(--cream-100)' : '#fff', cursor: selectable && verified ? 'pointer' : 'default', opacity: selectable && !verified ? 0.55 : 1 }}>
            {selectable && <span style={{ width: 18, height: 18, borderRadius: '50%', border: `2px solid ${on ? 'var(--bronze-600)' : 'var(--border-strong)'}`, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: '0 0 auto' }}>{on && <span style={{ width: 9, height: 9, borderRadius: '50%', background: 'var(--bronze-600)' }} />}</span>}
            <span style={{ width: 40, height: 40, borderRadius: 'var(--radius-md)', background: 'var(--cream-100)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: '0 0 auto' }}><AC.IconlyRegularLightActivity style={{ width: 20, height: 20, color: 'var(--bronze-600)' }} /></span>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>{a.label}</div>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--text-muted)' }}>{ibanMask(a.iban)} · {a.holder}</div>
            </div>
            <span style={{ fontFamily: 'var(--font-body)', fontSize: 11, fontWeight: 600, padding: '4px 10px', borderRadius: 999, background: verified ? 'var(--success-50)' : 'var(--cream-100)', color: verified ? 'var(--success-600)' : 'var(--bronze-700)', whiteSpace: 'nowrap' }}>{verified ? 'Verified' : 'Pending'}</span>
            {editable && (
              <div style={{ display: 'flex', gap: 10, flex: '0 0 auto' }}>
                {!verified && <button type="button" className="opx-link" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 12.5 }} onClick={() => verify(a.id)}>Verify</button>}
                <button type="button" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 12.5, color: 'var(--danger-600)', fontWeight: 600 }} onClick={() => remove(a.id)}>Remove</button>
              </div>
            )}
          </div>
        );
      })}

      {addOpen && (
        <div style={{ border: '1px solid var(--border-faint)', borderRadius: 'var(--radius-md)', padding: 16, background: 'var(--surface-inset)', display: 'flex', flexDirection: 'column', gap: 14 }}>
          <window.Field label="Account label" hint="A name to recognise this account, e.g. 'BNP current account'.">
            <input className="opx-amount" style={{ fontSize: 15, fontWeight: 500 }} value={label} onChange={(e) => setLabel(e.target.value)} placeholder="My bank account" />
          </window.Field>
          <window.Field label="IBAN">
            <input className="opx-amount" style={{ fontSize: 15, fontWeight: 500 }} value={iban} onChange={(e) => setIban(e.target.value)} placeholder="FR76 ····" />
          </window.Field>
          {iban && !ibanOk && <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--danger-600)', marginTop: -6 }}>Check the IBAN — it doesn't pass validation.</div>}
          <window.Field label="Account holder" hint="Must match your verified legal name. We send a small verification deposit to confirm the account is yours.">
            <input className="opx-amount" style={{ fontSize: 15, fontWeight: 500, background: '#fff', color: 'var(--text-muted)' }} value={holder} readOnly />
          </window.Field>
          <div style={{ display: 'flex', gap: 12 }}>
            <Button variant="primary" size="sm" disabled={!ibanOk} onClick={add}>Save account</Button>
            <Button variant="ghost" size="sm" onClick={onCloseAdd}>Cancel</Button>
          </div>
        </div>
      )}
    </div>
  );
}

/* ---------- INV-31/32 · Notifications & preferences ---------- */
function NotificationsTab() {
  const { state, update } = window.useOpalus();
  const { Card, Button } = AC;
  const markAll = () => update((s) => { s.notifications.forEach((n) => { n.read = true; }); });
  const locked = [['Regulatory notices', true], ['KIIS changes', true], ['Reflection-period reminders', true], ['Security alerts', true], ['Distribution notices (email)', true]];
  const optional = [['projectUpdates', 'Project updates'], ['productNews', 'Product news'], ['marketing', 'Marketing (off by default)']];
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
      <Card padding="lg" radius="lg" shadow="sm">
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
          <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: 0 }}>Notifications</h3>
          <button type="button" className="opx-link" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 13 }} onClick={markAll}>Mark all as read</button>
        </div>
        {state.notifications.length === 0 ? <div style={{ fontFamily: 'var(--font-body)', fontSize: 14, color: 'var(--text-muted)', padding: '8px 0' }}>You're all caught up.</div> :
          state.notifications.map((n, i) => (
            <div key={n.id} style={{ display: 'flex', gap: 14, padding: '13px 0', borderTop: i ? '1px solid var(--border-faint)' : 'none', alignItems: 'flex-start' }}>
              <span style={{ width: 8, height: 8, borderRadius: '50%', background: n.read ? 'var(--gray-300)' : 'var(--bronze-600)', marginTop: 6, flex: '0 0 auto' }} />
              <div style={{ flex: 1 }}>
                <div style={{ fontFamily: 'var(--font-body)', fontSize: 14, fontWeight: 600, color: 'var(--text-strong)' }}>{n.title}</div>
                <div style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-body)', lineHeight: 1.5 }}>{n.body}</div>
                <div style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--text-muted)', marginTop: 3 }}>{n.kind} · {n.date}</div>
              </div>
            </div>
          ))}
      </Card>

      <Card padding="lg" radius="lg" shadow="sm">
        <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: '0 0 4px' }}>Preferences</h3>
        <p style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--text-muted)', margin: '0 0 14px' }}>Choose how we contact you. Some categories are required by regulation and can't be turned off.</p>
        {locked.map(([label]) => (
          <div key={label} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, padding: '12px 0', borderTop: '1px solid var(--border-faint)' }}>
            <span style={{ display: 'inline-flex', alignItems: 'center', gap: 8, fontFamily: 'var(--font-body)', fontSize: 14, color: 'var(--text-body)' }}><AC.IconlyRegularLightLock style={{ width: 15, height: 15, color: 'var(--text-muted)' }} />{label}</span>
            <span title="Required by regulation" style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--text-muted)' }}>Required by regulation</span>
          </div>
        ))}
        {optional.map(([key, label]) => (
          <div key={key} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, padding: '12px 0', borderTop: '1px solid var(--border-faint)' }}>
            <span style={{ fontFamily: 'var(--font-body)', fontSize: 14, color: 'var(--text-body)' }}>{label}</span>
            <Toggle on={state.investor.notifPrefs[key]} onClick={() => update((s) => { s.investor.notifPrefs[key] = !s.investor.notifPrefs[key]; })} />
          </div>
        ))}
      </Card>
    </div>
  );
}

function Toggle({ on, onClick }) {
  return <button type="button" onClick={onClick} style={{ width: 42, height: 24, borderRadius: 999, border: 'none', cursor: 'pointer', background: on ? 'var(--bronze-600)' : 'var(--gray-300)', position: 'relative', transition: 'background .15s' }}><span style={{ position: 'absolute', top: 3, left: on ? 21 : 3, width: 18, height: 18, borderRadius: '50%', background: '#fff', transition: 'left .15s' }} /></button>;
}

/* ---------- INV-30 · Messages ---------- */
function MessagesTab() {
  const { Card, Button } = AC;
  const threads = [
    { id: 'support', name: 'Support', last: 'How can we help?', closed: false },
    { id: 'saint-cloud', name: 'Saint-Cloud Garden Villa (issuer)', last: 'Works update posted.', closed: false },
    { id: 'saint-germain', name: 'Saint-Germain Collection (issuer)', last: 'Project completed.', closed: true },
  ];
  const [active, setActive] = useState('support');
  const [draft, setDraft] = useState('');
  const [sent, setSent] = useState({}); // threadId -> [text] — messages sent this session
  const t = threads.find((x) => x.id === active);
  const send = () => {
    if (!draft.trim() || t.closed) return;
    setSent((prev) => ({ ...prev, [active]: [...(prev[active] || []), draft.trim()] }));
    setDraft('');
  };
  return (
    <Card padding="lg" radius="lg" shadow="sm" style={{ padding: 0, overflow: 'hidden' }}>
      <div style={{ display: 'grid', gridTemplateColumns: '230px 1fr', minHeight: 420 }}>
        <div style={{ borderRight: '1px solid var(--border-faint)' }}>
          {threads.map((th) => (
            <button key={th.id} type="button" onClick={() => { setActive(th.id); setDraft(''); }} style={{ display: 'block', width: '100%', textAlign: 'left', cursor: 'pointer', border: 'none', borderBottom: '1px solid var(--border-faint)', background: active === th.id ? 'var(--cream-100)' : '#fff', padding: '14px 16px' }}>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 13.5, fontWeight: 600, color: 'var(--ink)' }}>{th.name}</div>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--text-muted)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{th.last}</div>
            </button>
          ))}
        </div>
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <div style={{ padding: '12px 18px', borderBottom: '1px solid var(--border-faint)', fontFamily: 'var(--font-body)', fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>{t.name}</div>
          <div style={{ background: 'var(--surface-inset)', padding: '10px 18px', fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--text-muted)', borderBottom: '1px solid var(--border-faint)', display: 'flex', gap: 7, alignItems: 'center' }}>
            <AC.IconlyRegularLightLock style={{ width: 13, height: 13 }} /> Messages are not investment advice and are subject to compliance review.
          </div>
          <div style={{ flex: 1, padding: 18, display: 'flex', flexDirection: 'column', justifyContent: 'flex-end', gap: 10 }}>
            <div style={{ alignSelf: 'flex-start', maxWidth: '75%', background: '#fff', border: '1px solid var(--border-faint)', borderRadius: '12px 12px 12px 4px', padding: '10px 14px', fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-body)' }}>{t.last}</div>
            {(sent[active] || []).map((m, i) => (
              <div key={i} style={{ alignSelf: 'flex-end', maxWidth: '75%', background: 'var(--navy-700)', color: '#fff', borderRadius: '12px 12px 4px 12px', padding: '10px 14px', fontFamily: 'var(--font-body)', fontSize: 13 }}>{m}</div>
            ))}
          </div>
          <div style={{ padding: 14, borderTop: '1px solid var(--border-faint)' }}>
            {t.closed
              ? <div style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--text-muted)', textAlign: 'center', padding: '6px 0' }}>This project is completed; the thread is read-only. For anything else, message support.</div>
              : <div style={{ display: 'flex', gap: 10 }}>
                  <input type="text" placeholder="Write your message (max 5,000 characters)" maxLength={5000} value={draft} onChange={(e) => setDraft(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && send()} style={{ flex: 1, border: '1.5px solid var(--border-subtle)', borderRadius: 'var(--radius-md)', padding: '10px 14px', fontFamily: 'var(--font-body)', fontSize: 13, outline: 'none' }} />
                  <Button variant="primary" size="sm" disabled={!draft.trim()} onClick={send}>Send</Button>
                </div>}
          </div>
        </div>
      </div>
    </Card>
  );
}

/* ---------- Complaints (Art 7) — standard template + status, free of charge ----------
   BP-103 / BRD-6.1.11 / DM complaints + content_pages (Art 7(3) template). */
const COMPLAINT_CATEGORIES = ['Service quality', 'A specific project or offer', 'Payments & withdrawals', 'KYC / verification', 'Fees', 'Data & privacy', 'Other'];
const COMPLAINT_STATUS = {
  received: ['Received', 'var(--info-50)', 'var(--info-600)'],
  in_progress: ['In progress', 'var(--cream-100)', 'var(--bronze-700)'],
  resolved: ['Resolved', 'var(--success-50)', 'var(--success-600)'],
};

function ComplaintsTab() {
  const { state, update } = window.useOpalus();
  const { Card, Button } = AC;
  const [open, setOpen] = useState(false);
  const [category, setCategory] = useState(COMPLAINT_CATEGORIES[0]);
  const [subject, setSubject] = useState('');
  const [body, setBody] = useState('');
  const complaints = state.complaints || [];
  const valid = subject.trim().length >= 3 && body.trim().length >= 10;

  const fmtToday = () => new Date().toLocaleDateString('en-GB', { day: 'numeric', month: 'short', year: 'numeric' });
  const submit = () => {
    const ref = 'CMP-' + Math.floor(100000 + Math.random() * 899999);
    update((s) => { (s.complaints = s.complaints || []).unshift({ id: 'c' + Date.now(), ref, category, subject: subject.trim(), body: body.trim(), status: 'received', date: fmtToday() }); });
    setOpen(false); setSubject(''); setBody(''); setCategory(COMPLAINT_CATEGORIES[0]);
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
      <Card padding="lg" radius="lg" shadow="sm">
        <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap', marginBottom: 6 }}>
          <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: 0 }}>Complaints</h3>
          {!open && <Button variant="primary" size="sm" onClick={() => setOpen(true)}>Submit a complaint</Button>}
        </div>
        <p style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--text-muted)', margin: '0 0 4px', lineHeight: 1.6 }}>You can raise a complaint free of charge. We acknowledge every complaint and aim to resolve it promptly, keeping you informed of its status. This is separate from messaging support.</p>
      </Card>

      {open && (
        <Card padding="lg" radius="lg" shadow="sm">
          <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: '0 0 16px' }}>New complaint</h3>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <window.Field label="What is this about?">
              <select className="opx-amount" style={{ fontSize: 15, fontWeight: 500 }} value={category} onChange={(e) => setCategory(e.target.value)}>
                {COMPLAINT_CATEGORIES.map((c) => <option key={c}>{c}</option>)}
              </select>
            </window.Field>
            <window.Field label="Subject">
              <input className="opx-amount" style={{ fontSize: 16, fontWeight: 500 }} value={subject} onChange={(e) => setSubject(e.target.value)} placeholder="A short summary" />
            </window.Field>
            <window.Field label="Describe your complaint" hint="Include dates, amounts and any reference numbers so we can investigate.">
              <textarea className="opx-amount" style={{ fontSize: 14, fontWeight: 400, minHeight: 120, resize: 'vertical', fontFamily: 'var(--font-body)' }} value={body} onChange={(e) => setBody(e.target.value)} placeholder="Tell us what happened…" />
            </window.Field>
          </div>
          <div style={{ display: 'flex', gap: 12, marginTop: 20 }}>
            <Button variant="primary" disabled={!valid} onClick={submit}>Submit complaint</Button>
            <Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button>
          </div>
        </Card>
      )}

      <Card padding="lg" radius="lg" shadow="sm">
        <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: '0 0 12px' }}>Your complaints</h3>
        {complaints.length === 0 ? (
          <div style={{ fontFamily: 'var(--font-body)', fontSize: 14, color: 'var(--text-muted)', padding: '8px 0' }}>You have no complaints on record.</div>
        ) : complaints.map((c, i) => {
          const [label, bg, fg] = COMPLAINT_STATUS[c.status] || COMPLAINT_STATUS.received;
          return (
            <div key={c.id} style={{ padding: '14px 0', borderTop: i ? '1px solid var(--border-faint)' : 'none' }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap' }}>
                <div style={{ fontFamily: 'var(--font-body)', fontSize: 14, fontWeight: 600, color: 'var(--text-strong)' }}>{c.subject}</div>
                <span style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, fontWeight: 600, padding: '4px 11px', borderRadius: 999, background: bg, color: fg, whiteSpace: 'nowrap' }}>{label}</span>
              </div>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 12.5, color: 'var(--text-body)', lineHeight: 1.5, margin: '6px 0 0' }}>{c.body}</div>
              <div style={{ fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--text-muted)', marginTop: 5 }}>{c.category} · {c.ref} · {c.date}</div>
            </div>
          );
        })}
      </Card>
    </div>
  );
}

/* ---------- INV-34 · Data export + INV-35 · Account deletion ---------- */
function DataTab() {
  const { state, go } = window.useOpalus();
  const { Card, Button } = AC;
  const [exp, setExp] = useState('idle'); // idle | pending | ready
  const [oneActive, setOneActive] = useState(false);
  const [confirm, setConfirm] = useState('');
  const hasOffers = state.holdings.some((h) => h.status === 'offer' || h.status === 'confirmed' || h.status === 'awaiting-signature' || h.status === 'active');
  const hasBalance = state.wallet.balance > 0;
  const canDelete = !hasOffers && !hasBalance && confirm === 'DELETE';
  const consents = window.consentRows(state);
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 22 }}>
      {/* Consents — current Terms / Privacy / cookie consents with version + timestamp (GDPR Art 7) */}
      <Card padding="lg" radius="lg" shadow="sm">
        <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: '0 0 6px' }}>Your consents</h3>
        <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)', lineHeight: 1.6, margin: '0 0 16px' }}>The agreements you've accepted, with the exact version and the date and time you accepted each. We keep this record for as long as you hold an account.</p>
        <div style={{ border: '1px solid var(--border-faint)', borderRadius: 'var(--radius-md)', overflow: 'hidden' }}>
          {consents.map((c, i) => (
            <div key={c.key} style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '14px 16px', borderTop: i ? '1px solid var(--border-faint)' : 'none', flexWrap: 'wrap' }}>
              <span style={{ width: 40, height: 40, borderRadius: 'var(--radius-md)', background: 'var(--cream-100)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', flex: '0 0 auto' }}><AC.IconlyRegularLightPaper style={{ width: 20, height: 20, color: 'var(--bronze-600)' }} /></span>
              <div style={{ flex: 1, minWidth: 180 }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                  <span style={{ fontFamily: 'var(--font-body)', fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>{c.label}</span>
                  <span className="opx-link" style={{ fontSize: 12 }}>View</span>
                </div>
                <div style={{ fontFamily: 'var(--font-body)', fontSize: 12, color: 'var(--text-muted)' }}>
                  {c.accepted ? <>Accepted {c.version} on {window.opalusFmtDateTimeShort(c.acceptedAt)}</> : 'Not accepted'}
                </div>
              </div>
              {c.accepted && !c.stale && <span style={{ fontFamily: 'var(--font-body)', fontSize: 11, fontWeight: 600, padding: '4px 10px', borderRadius: 999, background: 'var(--success-50)', color: 'var(--success-600)', whiteSpace: 'nowrap' }}>Current</span>}
              {c.stale && <span title={`Current version is ${c.currentVersion}, updated ${c.updated}`} style={{ fontFamily: 'var(--font-body)', fontSize: 11, fontWeight: 600, padding: '4px 10px', borderRadius: 999, background: 'var(--cream-100)', color: 'var(--bronze-700)', whiteSpace: 'nowrap' }}>Update available · {c.currentVersion}</span>}
              {!c.accepted && <span style={{ fontFamily: 'var(--font-body)', fontSize: 11, fontWeight: 600, padding: '4px 10px', borderRadius: 999, background: 'var(--surface-inset)', color: 'var(--text-muted)', whiteSpace: 'nowrap' }}>Not given</span>}
            </div>
          ))}
        </div>
        <div style={{ marginTop: 12, fontFamily: 'var(--font-body)', fontSize: 11.5, color: 'var(--text-muted)', lineHeight: 1.5 }}>You may withdraw optional consents at any time; this does not affect the lawfulness of processing before withdrawal. Required agreements are necessary to keep your account.</div>
      </Card>

      {/* Art 8(2) — connection to Opalus + public-register disclosure consent (declared at onboarding) */}
      <Card padding="lg" radius="lg" shadow="sm">
        <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: '0 0 6px' }}>Connection to Opalus</h3>
        <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)', lineHeight: 1.6, margin: '0 0 16px' }}>Whether you are a person connected to Opalus. Connected persons may invest, but their participation is published on our public register, with their consent.</p>
        {(() => {
          const rp = state.investor.restrictedPerson;
          const relLabels = { shareholder: 'Shareholder (≥20%)', manager: 'Manager / management body', director: 'Director', employee: 'Employee', controlled: 'Controlled person or entity' };
          if (!rp) {
            return <window.Note tone="warn" title="Not yet declared" icon={<span style={{ fontWeight: 700 }}>!</span>}>You haven't declared whether you're connected to Opalus. <span className="opx-link" onClick={() => go('onboarding')}>Complete this in account setup →</span></window.Note>;
          }
          return (
            <div style={{ border: '1px solid var(--border-faint)', borderRadius: 'var(--radius-md)', overflow: 'hidden' }}>
              {[
                ['Connected to Opalus', rp.connected ? 'Yes' : 'No'],
                ...(rp.connected ? [['Relationship', relLabels[rp.relationship] || rp.relationship]] : []),
                ['Public-register disclosure consent', rp.connected ? (rp.disclosureConsent ? 'Given' : 'Not given') : 'Not applicable'],
                ['Declared', window.opalusFmtDateTimeShort(rp.declaredAt)],
              ].map(([k, v], i) => (
                <div key={k} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, padding: '13px 16px', background: i % 2 ? 'var(--surface-inset)' : '#fff' }}>
                  <span style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-muted)' }}>{k}</span>
                  <span style={{ fontFamily: 'var(--font-body)', fontSize: 13, fontWeight: 600, color: 'var(--ink)', textAlign: 'right' }}>{v}</span>
                </div>
              ))}
            </div>
          );
        })()}
        <button type="button" className="opx-link" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 13, marginTop: 12, padding: 0 }} onClick={() => go('onboarding')}>Update my declaration</button>
      </Card>

      {/* Data export */}
      <Card padding="lg" radius="lg" shadow="sm">
        <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: '0 0 6px' }}>Your data</h3>
        <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)', lineHeight: 1.6, margin: '0 0 18px' }}>Request a complete copy of the personal data we hold about you — profile, verification records, investments, transactions, messages and consents.</p>
        {exp === 'idle' && <Button variant="primary" onClick={() => { setExp('pending'); setTimeout(() => setExp('ready'), 1600); }}>Request my data</Button>}
        {exp === 'pending' && <><window.Note tone="info" title="Preparing your export">We'll notify you when it's ready to download.</window.Note><div style={{ marginTop: 12 }}><button type="button" className="opx-link" style={{ background: 'none', border: 'none', cursor: 'pointer', fontSize: 13, padding: 0 }} onClick={() => setOneActive(true)}>Request another export</button>{oneActive && <div style={{ marginTop: 10 }}><window.Note tone="warn" title="An export is already in progress" icon={<span style={{ fontWeight: 700 }}>!</span>}>We'll notify you when it's ready.</window.Note></div>}</div></>}
        {exp === 'ready' && <window.Note tone="success" title="Your export is ready">The download link works for 7 days and only from your account. <span className="opx-link">Download (ZIP)</span></window.Note>}
      </Card>

      {/* Account deletion */}
      <Card padding="lg" radius="lg" shadow="sm">
        <h3 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 'var(--fs-h4)', color: 'var(--ink)', margin: '0 0 14px' }}>Delete your account</h3>
        {hasOffers ? (
          <window.Note tone="warn" title="Active investments" icon={<span style={{ fontWeight: 700 }}>!</span>}>You have active investments or offers in their reflection period. These must conclude before the account can be deleted.</window.Note>
        ) : hasBalance ? (
          <window.Note tone="warn" title="Withdraw your funds first" icon={<span style={{ fontWeight: 700 }}>!</span>}>Your wallet balance is {window.eurC(state.wallet.balance)}. Withdraw your funds first. <span className="opx-link" onClick={() => go('wallet')}>Withdraw funds →</span></window.Note>
        ) : (
          <>
            {/* ASSUMPTION (confirm Lithuanian counsel): AML retention floor = 8 years from end of
                business relationship (LT AML Law Art 19; longest-applicable-wins). — see Sync_Audit_Report open Q6 */}
            <p style={{ fontFamily: 'var(--font-body)', fontSize: 13, color: 'var(--text-body)', lineHeight: 1.6, margin: '0 0 16px' }}>Your access ends immediately. Anti-money-laundering rules require us to retain your KYC/AML records for at least 8 years from the end of our business relationship before they are permanently erased — we keep them secure and use them only for legal obligations.</p>
            <window.Field label="Type DELETE to confirm, then verify with your authenticator">
              <input className="opx-amount" style={{ fontSize: 16, fontWeight: 600, maxWidth: 260 }} value={confirm} onChange={(e) => setConfirm(e.target.value)} placeholder="DELETE" />
            </window.Field>
            <Button variant="primary" style={{ marginTop: 16 }} disabled={!canDelete}>Delete my account</Button>
          </>
        )}
      </Card>
    </div>
  );
}

/* ============================================================ INV-36 · COMPLIANCE INTERSTITIALS ============================================================ */
const INTERSTITIALS = {
  simulation: { title: 'Before you invest: refresh your loss simulation', body: 'Your last simulation is over 12 months old. EU rules require an annual update — it takes two minutes.', cta: 'Update simulation' },
  test: { title: 'Before you invest: refresh your knowledge assessment', body: 'Your last assessment is over 24 months old.', cta: 'Retake assessment' },
  sophExpired: { title: 'Your sophisticated status has expired', body: "You're now a non-sophisticated investor. To invest, complete the knowledge assessment and loss simulation. Your existing investments are unaffected.", cta: 'Continue setup' },
  sophExpiring: { title: 'Your sophisticated status expires soon', body: 'Your sophisticated status expires on 14 Mar 2028. Renew now to keep investing without the non-sophisticated protections and steps.', cta: 'Renew now' },
};
function InterstitialScreen() {
  const { state, go } = window.useOpalus();
  const { Card, Button } = AC;
  const it = INTERSTITIALS[state.route.params.kind] || INTERSTITIALS.simulation;
  return (
    <div className="opx-container opx-fade" style={{ maxWidth: 620 }}>
      <Card padding="lg" radius="xl" shadow="card" style={{ padding: 40, textAlign: 'center' }}>
        <div style={{ width: 60, height: 60, borderRadius: '50%', background: 'var(--cream-100)', color: 'var(--bronze-600)', display: 'inline-flex', alignItems: 'center', justifyContent: 'center', margin: '0 auto 18px' }}><AC.IconlyRegularOutlineCalendar style={{ width: 28, height: 28 }} /></div>
        <h2 style={{ fontFamily: 'var(--font-display)', fontWeight: 600, fontSize: 24, color: 'var(--ink)', margin: '0 0 10px' }}>{it.title}</h2>
        <p style={{ fontFamily: 'var(--font-body)', fontSize: 'var(--fs-sm)', color: 'var(--text-body)', lineHeight: 1.6, margin: '0 auto 24px', maxWidth: 440 }}>{it.body}</p>
        <div style={{ display: 'flex', gap: 12, justifyContent: 'center' }}>
          <Button variant="primary" onClick={() => go('onboarding')}>{it.cta}</Button>
          <Button variant="ghost" onClick={() => go('dashboard')}>Later</Button>
        </div>
      </Card>
    </div>
  );
}

Object.assign(window, { VerifyEmailScreen, TwoFAScreen, AccountScreen, InterstitialScreen, BankAccountList });
