/* ───────────────────────────────────────────────────────────
   BankApp.jsx — Application web « Banque Démo » (propulsée par Doxallia)
   Écrans : home · choose · qr · verifying · summary
   Props : stage, walletStage, profile, claims, sharedKeys,
           handlers {onStart,onChooseWallet,onNext,onReset}, anim
   ─────────────────────────────────────────────────────────── */

const { Ic: BIc, IDPhoto: BIDPhoto, QRCode: BQR } = window;

// — primitives stylées —
function BtnPrimary({ children, onClick, full, icon, disabled }) {
  const [h, setH] = React.useState(false);
  return (
    <button onClick={onClick} disabled={disabled}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 10,
        width: full ? '100%' : 'auto', padding: '14px 26px', border: 'none', whiteSpace: 'nowrap',
        borderRadius: 10, fontSize: 16, fontWeight: 700, letterSpacing: '.01em',
        color: '#fff', background: disabled ? '#aeb8c8' : (h ? 'var(--bank-primary-700)' : 'var(--bank-primary)'),
        boxShadow: disabled ? 'none' : '0 8px 22px -10px rgba(22,87,200,.7)',
        cursor: disabled ? 'not-allowed' : 'pointer', transition: 'background .18s, transform .18s',
        transform: h && !disabled ? 'translateY(-1px)' : 'none',
      }}>
      {children}{icon && <BIc.arrow s={20} c="#fff" />}
    </button>
  );
}
function BtnGhost({ children, onClick }) {
  const [h, setH] = React.useState(false);
  return (
    <button onClick={onClick} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        display: 'inline-flex', alignItems: 'center', gap: 8, padding: '13px 22px', whiteSpace: 'nowrap',
        borderRadius: 10, fontSize: 15, fontWeight: 600,
        color: 'var(--bank-primary)', background: h ? 'var(--bank-soft)' : 'transparent',
        border: '1.5px solid var(--bank-line)', transition: 'background .18s',
      }}>{children}</button>
  );
}
function Notice({ children, tone = 'info' }) {
  const c = tone === 'ok' ? 'var(--bank-ok)' : 'var(--bank-primary)';
  const bg = tone === 'ok' ? 'rgba(21,122,82,.07)' : 'rgba(22,87,200,.06)';
  return (
    <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start', padding: '14px 16px',
      borderRadius: 12, background: bg, border: `1px solid ${tone === 'ok' ? 'rgba(21,122,82,.18)' : 'rgba(22,87,200,.16)'}` }}>
      <div style={{ color: c, flexShrink: 0, marginTop: 1 }}><BIc.shield s={20} c={c} /></div>
      <div style={{ fontSize: 13.5, lineHeight: 1.5, color: 'var(--bank-ink)' }}>{children}</div>
    </div>
  );
}

// — en-tête —
function BankHeader() {
  return (
    <header style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between',
      padding: '0 40px', height: 64, borderBottom: '1px solid var(--bank-line)', background: '#fff',
      position: 'sticky', top: 0, zIndex: 10 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
        <div style={{ width: 34, height: 34, borderRadius: 9, background: 'var(--bank-primary)',
          display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <BIc.bank s={19} c="#fff" />
        </div>
        <div style={{ fontSize: 19, fontWeight: 800, letterSpacing: '-.01em', color: 'var(--bank-ink)' }}>
          Banque<span style={{ color: 'var(--bank-primary)' }}> Démo</span>
        </div>
      </div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 22, fontSize: 14, color: 'var(--bank-muted)', fontWeight: 600 }}>
        <span>Particuliers</span><span>Professionnels</span><span>Aide</span>
        <div style={{ width: 1, height: 20, background: 'var(--bank-line)' }} />
        <span style={{ color: 'var(--bank-primary)' }}>Espace client</span>
      </div>
    </header>
  );
}

// — fil de progression du parcours —
const STEPS = ['Identité', 'Méthode', 'Connexion', 'Consentement', 'Vérification', 'Synthèse'];
function Stepper({ index }) {
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 0, padding: '16px 30px',
      background: '#fff', borderBottom: '1px solid var(--bank-line)' }}>
      {STEPS.map((s, i) => {
        const done = i < index, active = i === index;
        return (
          <React.Fragment key={s}>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
              <div style={{ width: 22, height: 22, borderRadius: '50%', flexShrink: 0,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontSize: 11.5, fontWeight: 700,
                background: done ? 'var(--bank-ok)' : active ? 'var(--bank-primary)' : '#eef1f6',
                color: done || active ? '#fff' : 'var(--bank-faint)',
                boxShadow: active ? '0 0 0 4px rgba(22,87,200,.14)' : 'none',
                transition: 'all .3s' }}>
                {done ? <BIc.check s={12} c="#fff" /> : i + 1}
              </div>
              <span style={{ fontSize: 12.5, fontWeight: active ? 700 : 600, whiteSpace: 'nowrap',
                color: active ? 'var(--bank-ink)' : done ? 'var(--bank-muted)' : 'var(--bank-faint)' }}>{s}</span>
            </div>
            {i < STEPS.length - 1 && (
              <div style={{ flex: 1, minWidth: 8, height: 2, margin: '0 9px', borderRadius: 2,
                background: i < index ? 'var(--bank-ok)' : 'var(--bank-line)', transition: 'background .3s' }} />
            )}
          </React.Fragment>
        );
      })}
    </div>
  );
}

// — écran ACCUEIL —
function ScreenHome({ onStart }) {
  return (
    <div className="rise" style={{ padding: '56px 40px 48px', maxWidth: 760, margin: '0 auto',
      display: 'flex', flexDirection: 'column', alignItems: 'flex-start' }}>
      <div style={{ display: 'inline-flex', alignItems: 'center', gap: 8, padding: '6px 12px',
        borderRadius: 999, background: 'var(--bank-soft)', color: 'var(--bank-primary)',
        fontSize: 12.5, fontWeight: 700, marginBottom: 22 }}>
        <BIc.shield s={15} /> Ouverture de compte 100 % en ligne
      </div>
      <h1 style={{ fontSize: 40, lineHeight: 1.14, fontWeight: 800, letterSpacing: '-.02em',
        color: 'var(--bank-ink)', margin: '0 0 16px', maxWidth: 680 }}>
        Ouvrez votre compte en quelques minutes, sans pièce justificative à photographier.
      </h1>
      <p style={{ fontSize: 17, lineHeight: 1.6, color: 'var(--bank-muted)', margin: '0 0 32px', maxWidth: 600 }}>
        Identifiez-vous avec votre portefeuille d'identité numérique européen.
        Vos données sont vérifiées à la source — fini la saisie manuelle et l'envoi de documents.
      </p>
      <div style={{ display: 'flex', gap: 14, alignItems: 'center', marginBottom: 40 }}>
        <BtnPrimary onClick={onStart} icon>Ouvrir un compte</BtnPrimary>
        <BtnGhost>J'ai déjà un compte</BtnGhost>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 16, width: '100%' }}>
        {[
          ['Vérifié à la source', 'Données issues de votre identité numérique certifiée.'],
          ['Vous gardez le contrôle', 'Vous choisissez ce que vous partagez, et avec qui.'],
          ['Conforme eIDAS2', 'Cadre réglementaire européen sur l\'identité numérique.'],
        ].map(([t, d]) => (
          <div key={t} style={{ padding: '18px 18px', borderRadius: 14, background: '#fff',
            border: '1px solid var(--bank-line)' }}>
            <div style={{ width: 30, height: 30, borderRadius: 8, background: 'var(--bank-soft)',
              display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 12 }}>
              <BIc.check s={17} c="var(--bank-primary)" />
            </div>
            <div style={{ fontSize: 14.5, fontWeight: 700, color: 'var(--bank-ink)', marginBottom: 4 }}>{t}</div>
            <div style={{ fontSize: 13, lineHeight: 1.45, color: 'var(--bank-muted)' }}>{d}</div>
          </div>
        ))}
      </div>
    </div>
  );
}

// — écran CHOIX de la méthode —
function ScreenChoose({ onChooseWallet }) {
  const opts = [
    { id: 'wallet', title: 'Avec mon portefeuille d\'identité numérique', sub: 'ID Wallet · EUDI Wallet — recommandé',
      icon: <BIc.phone s={24} c="var(--bank-primary)" />, on: true, badge: 'Le plus rapide' },
    { id: 'fc', title: 'Avec FranceConnect', sub: 'Identifiants d\'un service public',
      icon: <BIc.key s={24} c="var(--bank-faint)" />, on: false },
    { id: 'doc', title: 'En photographiant ma pièce d\'identité', sub: 'Vérification manuelle sous 48 h',
      icon: <BIc.scan s={24} c="var(--bank-faint)" />, on: false },
  ];
  return (
    <div className="rise" style={{ padding: '48px 40px', maxWidth: 700, margin: '0 auto' }}>
      <h2 style={{ fontSize: 28, fontWeight: 800, letterSpacing: '-.01em', color: 'var(--bank-ink)', margin: '0 0 8px' }}>
        Comment souhaitez-vous vous identifier ?
      </h2>
      <p style={{ fontSize: 15.5, color: 'var(--bank-muted)', margin: '0 0 28px' }}>
        Pour ouvrir votre compte, nous devons vérifier votre identité.
      </p>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        {opts.map(o => (
          <OptionTile key={o.id} {...o} onClick={o.on ? onChooseWallet : undefined} />
        ))}
      </div>
    </div>
  );
}
function OptionTile({ title, sub, icon, on, badge, onClick }) {
  const [h, setH] = React.useState(false);
  return (
    <button onClick={onClick} disabled={!on}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{ display: 'flex', alignItems: 'center', gap: 18, width: '100%', textAlign: 'left',
        padding: '20px 22px', borderRadius: 16, background: '#fff', cursor: on ? 'pointer' : 'not-allowed',
        border: `1.5px solid ${h && on ? 'var(--bank-primary)' : 'var(--bank-line)'}`,
        boxShadow: h && on ? '0 12px 30px -16px rgba(22,87,200,.5)' : 'none',
        opacity: on ? 1 : .62, transition: 'all .18s', transform: h && on ? 'translateY(-2px)' : 'none' }}>
      <div style={{ width: 52, height: 52, borderRadius: 13, flexShrink: 0,
        background: on ? 'var(--bank-soft)' : '#f1f3f7', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        {icon}
      </div>
      <div style={{ flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column', gap: 3 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
          <span style={{ fontSize: 16.5, fontWeight: 700, lineHeight: 1.3, color: 'var(--bank-ink)' }}>{title}</span>
          {badge && <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--bank-ok)', whiteSpace: 'nowrap',
            background: 'rgba(21,122,82,.1)', padding: '3px 9px', borderRadius: 999 }}>{badge}</span>}
        </div>
        <div style={{ fontSize: 13.5, lineHeight: 1.4, color: 'var(--bank-muted)' }}>{sub}</div>
      </div>
      {on && <BIc.arrow s={22} c="var(--bank-primary)" />}
    </button>
  );
}

// — écran QR / attente —
function ScreenQR({ walletStage, annotate, onFocusDox }) {
  const DoxMark = window.DoxMark;
  const map = {
    idle:    { t: 'En attente de connexion', d: 'Scannez ce code avec votre application ID Wallet.', pulse: false },
    scan:    { t: 'En attente de connexion', d: 'Scannez ce code avec votre application ID Wallet.', pulse: false },
    consent: { t: 'Demande reçue', d: 'Validez le partage de vos données sur votre téléphone.', pulse: true },
    auth:    { t: 'Authentification en cours', d: 'Confirmez votre identité sur votre téléphone…', pulse: true },
  };
  const s = map[walletStage] || map.idle;
  return (
    <div className="rise" style={{ padding: '44px 40px', maxWidth: 720, margin: '0 auto',
      display: 'grid', gridTemplateColumns: '1fr auto', gap: 40, alignItems: 'center' }}>
      <div>
        <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--bank-primary)', letterSpacing: '.04em',
          textTransform: 'uppercase', marginBottom: 12 }}>Identification par portefeuille</div>
        <h2 style={{ fontSize: 26, fontWeight: 800, color: 'var(--bank-ink)', margin: '0 0 14px', letterSpacing: '-.01em' }}>
          Scannez pour vous identifier
        </h2>
        <ol style={{ margin: '0 0 22px', padding: 0, listStyle: 'none', display: 'flex', flexDirection: 'column', gap: 12 }}>
          {['Ouvrez votre application d\'identité numérique', 'Scannez le QR code ci-contre', 'Validez le partage des données demandées'].map((x, i) => (
            <li key={i} style={{ display: 'flex', gap: 12, alignItems: 'center', fontSize: 14.5, color: 'var(--bank-ink)' }}>
              <span style={{ width: 22, height: 22, borderRadius: '50%', background: 'var(--bank-soft)',
                color: 'var(--bank-primary)', fontSize: 12, fontWeight: 700, flexShrink: 0,
                display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{i + 1}</span>
              {x}
            </li>
          ))}
        </ol>
        <div style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '14px 16px', borderRadius: 12,
          background: s.pulse ? 'rgba(22,87,200,.06)' : 'var(--bank-soft)', border: '1px solid var(--bank-line)' }}>
          <Dots active={s.pulse} />
          <div>
            <div style={{ fontSize: 14.5, fontWeight: 700, color: 'var(--bank-ink)' }}>{s.t}</div>
            <div style={{ fontSize: 13, color: 'var(--bank-muted)' }}>{s.d}</div>
          </div>
        </div>
        <div style={{ marginTop: 14, fontSize: 11.5, color: 'var(--bank-faint)', fontFamily: 'monospace' }}>
          Protocole&nbsp;: OpenID4VP · presentation_definition: pid_basic
        </div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 14 }}>
        {(() => {
          const qrBox = (
            <div style={{ padding: 16, borderRadius: 22, background: '#fff', border: '1px solid var(--bank-line)',
              boxShadow: '0 24px 50px -28px rgba(14,23,38,.45)' }}>
              <BQR size={184} logo={<div style={{ width: 26, height: 26, borderRadius: 7, background: 'var(--bank-primary)',
                display: 'flex', alignItems: 'center', justifyContent: 'center' }}><BIc.bank s={15} c="#fff" /></div>} />
            </div>
          );
          return (annotate && DoxMark)
            ? <DoxMark label="QR code — Web Element Doxallia" sub="injecté en marque blanche — voir schéma ↓"
                onFocus={onFocusDox}>{qrBox}</DoxMark>
            : qrBox;
        })()}
        <div style={{ fontSize: 12, color: 'var(--bank-faint)', marginTop: annotate ? 8 : 0 }}>Le code expire dans 04:58</div>
      </div>
    </div>
  );
}
function Dots({ active }) {
  return (
    <div style={{ display: 'flex', gap: 5, flexShrink: 0 }}>
      {[0, 1, 2].map(i => (
        <span key={i} style={{ width: 8, height: 8, borderRadius: '50%', background: 'var(--bank-primary)',
          animation: active ? `pulse-soft 1.1s ${i * 0.18}s infinite` : 'none', opacity: active ? undefined : .35 }} />
      ))}
    </div>
  );
}

// — écran VÉRIFICATION —
function ScreenVerifying() {
  return (
    <div className="rise" style={{ padding: '90px 40px', display: 'flex', flexDirection: 'column',
      alignItems: 'center', textAlign: 'center' }}>
      <div style={{ position: 'relative', width: 84, height: 84, marginBottom: 28 }}>
        <div style={{ position: 'absolute', inset: 0, borderRadius: '50%', border: '4px solid var(--bank-line)' }} />
        <div style={{ position: 'absolute', inset: 0, borderRadius: '50%',
          border: '4px solid var(--bank-primary)', borderTopColor: 'transparent', borderRightColor: 'transparent',
          animation: 'spin .9s linear infinite' }} />
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: 'var(--bank-primary)' }}><BIc.shield s={32} /></div>
      </div>
      <h2 style={{ fontSize: 24, fontWeight: 800, color: 'var(--bank-ink)', margin: '0 0 10px' }}>
        Vérification de l'attestation…
      </h2>
      <p style={{ fontSize: 15, color: 'var(--bank-muted)', maxWidth: 420, margin: 0, lineHeight: 1.5 }}>
        Nous vérifions la signature cryptographique de vos données et la validité de l'émetteur (eIDAS2).
      </p>
    </div>
  );
}

// — écran SYNTHÈSE —
function ScreenSummary({ profile, claims, sharedKeys, onNext }) {
  const shown = claims.filter(c => c.required || sharedKeys.includes(c.key));
  const fields = shown.filter(c => !c.isPhoto);
  return (
    <div className="rise" style={{ padding: '40px 40px 32px', maxWidth: 820, margin: '0 auto',
      display: 'flex', flexDirection: 'column', gap: 20 }}>
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 16 }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          <div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--bank-ok)', letterSpacing: '.04em',
            textTransform: 'uppercase' }}>Identité vérifiée</div>
          <h2 style={{ fontSize: 27, fontWeight: 800, color: 'var(--bank-ink)', margin: 0, letterSpacing: '-.01em', lineHeight: 1.15 }}>
            Synthèse de votre dossier
          </h2>
        </div>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 7, fontSize: 12.5, fontWeight: 700, flexShrink: 0,
          color: 'var(--bank-ok)', background: 'rgba(21,122,82,.1)', padding: '7px 13px', borderRadius: 999 }}>
          <BIc.check s={15} c="var(--bank-ok)" /> Source : carte nationale d'identité
        </span>
      </div>

      <Notice tone="ok">
        Ces informations ont été <strong>transmises et signées</strong> par votre portefeuille d'identité numérique
        via le protocole eIDAS2. Elles n'ont pas été saisies manuellement et sont réputées exactes.
      </Notice>

      <div style={{ display: 'grid', gridTemplateColumns: '232px 1fr', gap: 22 }}>
        {/* carte identité */}
        <div style={{ padding: 20, borderRadius: 16, background: '#fff', border: '1px solid var(--bank-line)',
          display: 'flex', flexDirection: 'column', alignItems: 'center', textAlign: 'center', gap: 6, height: 'fit-content' }}>
          <BIDPhoto hue={profile.hue} size={96} radius={12} />
          <div style={{ fontSize: 18, fontWeight: 800, lineHeight: 1.2, color: 'var(--bank-ink)', marginTop: 10, whiteSpace: 'nowrap' }}>
            {profile.prenom} {profile.nom}
          </div>
          <div style={{ fontSize: 13, lineHeight: 1.3, color: 'var(--bank-muted)' }}>{profile.age} ans · {profile.sexe}</div>
          <div style={{ marginTop: 8, padding: '7px 12px', borderRadius: 8, background: 'var(--bank-soft)',
            fontSize: 11.5, fontFamily: 'monospace', color: 'var(--bank-primary)', fontWeight: 600 }}>
            {profile.docNum}
          </div>
        </div>
        {/* champs */}
        <div style={{ background: '#fff', border: '1px solid var(--bank-line)', borderRadius: 16, overflow: 'hidden' }}>
          {fields.map((c, i) => (
            <Field key={c.key} label={c.label} value={profile[c.key]} last={i === fields.length - 1} />
          ))}
        </div>
      </div>

      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', marginTop: 8 }}>
        <BtnPrimary onClick={onNext} icon>Suivant — étape suivante du parcours</BtnPrimary>
      </div>
    </div>
  );
}
function Field({ label, value, last }) {
  return (
    <div style={{ display: 'flex', alignItems: 'flex-start', gap: 16, padding: '15px 20px',
      borderBottom: last ? 'none' : '1px solid var(--bank-line)' }}>
      <div style={{ width: 150, flexShrink: 0, fontSize: 13, fontWeight: 600, color: 'var(--bank-muted)', paddingTop: 1 }}>{label}</div>
      <div style={{ flex: 1, fontSize: 15, fontWeight: 600, color: 'var(--bank-ink)', whiteSpace: 'pre-line' }}>{value}</div>
      <span title="Donnée vérifiée" style={{ color: 'var(--bank-ok)', flexShrink: 0, marginTop: 2 }}>
        <BIc.check s={16} c="var(--bank-ok)" />
      </span>
    </div>
  );
}

// — coquille banque —
function BankApp(props) {
  const { stage } = props;
  return (
    <div style={{ minHeight: '100%', background: 'var(--bank-bg)', display: 'flex', flexDirection: 'column', overflowX: 'hidden' }}>
      <BankHeader />
      {stage !== 'home' && <Stepper index={props.stepIndex} />}
      <div style={{ flex: 1 }}>
        {stage === 'home'      && <ScreenHome onStart={props.onStart} />}
        {stage === 'choose'    && <ScreenChoose onChooseWallet={props.onChooseWallet} />}
        {stage === 'qr'        && <ScreenQR walletStage={props.walletStage} annotate={props.annotate} onFocusDox={props.onFocusDox} />}
        {stage === 'verifying' && <ScreenVerifying />}
        {stage === 'summary'   && <ScreenSummary profile={props.profile} claims={props.claims}
                                     sharedKeys={props.sharedKeys} onNext={props.onNext} />}
      </div>
      <footer style={{ padding: '14px 40px', borderTop: '1px solid var(--bank-line)', background: '#fff',
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        fontSize: 12, color: 'var(--bank-faint)' }}>
        <span>© Banque Démo — Démonstrateur eIDAS2</span>
        <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, whiteSpace: 'nowrap' }}>
          Parcours sécurisé <strong style={{ color: 'var(--bank-muted)' }}>propulsé par Doxallia</strong>
        </span>
      </footer>
    </div>
  );
}

Object.assign(window, { BankApp });

/* ═══════════════════════════════════════════════════════════
   MobileBankApp — site mobile « Banque Démo » (flux same-device)
   Rendu DANS un <IOSDevice>. Écrans : home · choose · verifying · summary
   ═══════════════════════════════════════════════════════════ */
const MB_TOP = 56, MB_BOT = 26;

function MobileHeader() {
  return (
    <header style={{ padding: `${MB_TOP}px 18px 12px`, background: '#fff',
      borderBottom: '1px solid var(--bank-line)', display: 'flex', alignItems: 'center',
      justifyContent: 'space-between', flexShrink: 0 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
        <div style={{ width: 28, height: 28, borderRadius: 8, background: 'var(--bank-primary)',
          display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
          <BIc.bank s={16} c="#fff" />
        </div>
        <div style={{ fontSize: 16, fontWeight: 800, letterSpacing: '-.01em', color: 'var(--bank-ink)' }}>
          Banque<span style={{ color: 'var(--bank-primary)' }}> Démo</span>
        </div>
      </div>
      <span style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--bank-primary)' }}>Menu</span>
    </header>
  );
}

function MobileProgress({ stage }) {
  const map = { choose: 1, verifying: 3, summary: 4 };
  const n = map[stage]; if (!n) return null;
  return (
    <div style={{ padding: '10px 18px', background: '#fff', borderBottom: '1px solid var(--bank-line)',
      display: 'flex', alignItems: 'center', gap: 10, flexShrink: 0 }}>
      <div style={{ flex: 1, display: 'flex', gap: 5 }}>
        {[1, 2, 3, 4].map(i => (
          <span key={i} style={{ flex: 1, height: 4, borderRadius: 3,
            background: i <= n ? 'var(--bank-primary)' : 'var(--bank-line)', transition: 'background .3s' }} />
        ))}
      </div>
      <span style={{ fontSize: 11.5, fontWeight: 700, color: 'var(--bank-muted)', whiteSpace: 'nowrap' }}>Étape {n} / 4</span>
    </div>
  );
}

function MBHome({ onStart }) {
  return (
    <div className="rise" style={{ padding: '26px 20px 30px' }}>
      <div style={{ display: 'inline-flex', alignItems: 'center', gap: 7, padding: '5px 11px',
        borderRadius: 999, background: 'var(--bank-soft)', color: 'var(--bank-primary)',
        fontSize: 11.5, fontWeight: 700, marginBottom: 16 }}>
        <BIc.shield s={13} /> Ouverture 100 % en ligne
      </div>
      <h1 style={{ fontSize: 27, lineHeight: 1.16, fontWeight: 800, letterSpacing: '-.02em',
        color: 'var(--bank-ink)', margin: '0 0 12px' }}>
        Ouvrez votre compte en quelques minutes.
      </h1>
      <p style={{ fontSize: 14.5, lineHeight: 1.55, color: 'var(--bank-muted)', margin: '0 0 22px' }}>
        Identifiez-vous avec votre portefeuille d'identité numérique. Vos données sont vérifiées à la source.
      </p>
      <BtnPrimary onClick={onStart} icon full>Ouvrir un compte</BtnPrimary>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12, marginTop: 24 }}>
        {[['Vérifié à la source', 'Données issues de votre identité certifiée.'],
          ['Vous gardez le contrôle', 'Vous choisissez ce que vous partagez.'],
          ['Conforme eIDAS2', 'Cadre européen sur l\'identité numérique.']].map(([t, d]) => (
          <div key={t} style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
            <div style={{ width: 26, height: 26, borderRadius: 7, background: 'var(--bank-soft)', flexShrink: 0,
              display: 'flex', alignItems: 'center', justifyContent: 'center', marginTop: 1 }}>
              <BIc.check s={15} c="var(--bank-primary)" />
            </div>
            <div>
              <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--bank-ink)' }}>{t}</div>
              <div style={{ fontSize: 12.5, lineHeight: 1.4, color: 'var(--bank-muted)' }}>{d}</div>
            </div>
          </div>
        ))}
      </div>
    </div>
  );
}

function MBChoose({ onChooseWallet }) {
  const opts = [
    { id: 'wallet', title: 'Mon portefeuille d\'identité', sub: 'ID Wallet · EUDI Wallet',
      icon: <BIc.phone s={22} c="var(--bank-primary)" />, on: true, badge: 'Rapide' },
    { id: 'fc', title: 'FranceConnect', sub: 'Identifiants service public',
      icon: <BIc.key s={22} c="var(--bank-faint)" />, on: false },
    { id: 'doc', title: 'Photo de ma pièce', sub: 'Vérification sous 48 h',
      icon: <BIc.scan s={22} c="var(--bank-faint)" />, on: false },
  ];
  return (
    <div className="rise" style={{ padding: '24px 20px 30px' }}>
      <h2 style={{ fontSize: 21, fontWeight: 800, letterSpacing: '-.01em', color: 'var(--bank-ink)', margin: '0 0 6px' }}>
        Comment vous identifier ?
      </h2>
      <p style={{ fontSize: 13.5, color: 'var(--bank-muted)', margin: '0 0 20px', lineHeight: 1.45 }}>
        Nous devons vérifier votre identité pour ouvrir le compte.
      </p>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
        {opts.map(o => <MBOption key={o.id} {...o} onClick={o.on ? onChooseWallet : undefined} />)}
      </div>
    </div>
  );
}
function MBOption({ title, sub, icon, on, badge, onClick }) {
  return (
    <button onClick={onClick} disabled={!on}
      style={{ display: 'flex', alignItems: 'center', gap: 13, width: '100%', textAlign: 'left',
        padding: '15px 15px', borderRadius: 14, background: '#fff', cursor: on ? 'pointer' : 'not-allowed',
        border: `1.5px solid ${on ? 'var(--bank-primary)' : 'var(--bank-line)'}`, opacity: on ? 1 : .6 }}>
      <div style={{ width: 44, height: 44, borderRadius: 11, flexShrink: 0,
        background: on ? 'var(--bank-soft)' : '#f1f3f7', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        {icon}
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ fontSize: 15, fontWeight: 700, lineHeight: 1.25, color: 'var(--bank-ink)' }}>{title}</span>
          {badge && <span style={{ fontSize: 10, fontWeight: 700, color: 'var(--bank-ok)',
            background: 'rgba(21,122,82,.1)', padding: '2px 7px', borderRadius: 999 }}>{badge}</span>}
        </div>
        <div style={{ fontSize: 12.5, color: 'var(--bank-muted)', marginTop: 2 }}>{sub}</div>
      </div>
      {on && <BIc.arrow s={19} c="var(--bank-primary)" />}
    </button>
  );
}

function MBVerifying() {
  return (
    <div className="rise" style={{ padding: '70px 30px', display: 'flex', flexDirection: 'column',
      alignItems: 'center', textAlign: 'center' }}>
      <div style={{ position: 'relative', width: 70, height: 70, marginBottom: 22 }}>
        <div style={{ position: 'absolute', inset: 0, borderRadius: '50%', border: '4px solid var(--bank-line)' }} />
        <div style={{ position: 'absolute', inset: 0, borderRadius: '50%', border: '4px solid var(--bank-primary)',
          borderTopColor: 'transparent', borderRightColor: 'transparent', animation: 'spin .9s linear infinite' }} />
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
          color: 'var(--bank-primary)' }}><BIc.shield s={28} /></div>
      </div>
      <h2 style={{ fontSize: 19, fontWeight: 800, color: 'var(--bank-ink)', margin: '0 0 8px' }}>
        Vérification de l'attestation…
      </h2>
      <p style={{ fontSize: 13.5, color: 'var(--bank-muted)', margin: 0, lineHeight: 1.5 }}>
        Nous vérifions la signature cryptographique de vos données (eIDAS2).
      </p>
    </div>
  );
}

function MBSummary({ profile, claims, sharedKeys, onNext }) {
  const shown = claims.filter(c => c.required || sharedKeys.includes(c.key));
  const fields = shown.filter(c => !c.isPhoto);
  return (
    <div className="rise" style={{ padding: '22px 18px 26px', display: 'flex', flexDirection: 'column', gap: 16 }}>
      <div>
        <div style={{ fontSize: 11.5, fontWeight: 700, color: 'var(--bank-ok)', letterSpacing: '.04em',
          textTransform: 'uppercase' }}>Identité vérifiée</div>
        <h2 style={{ fontSize: 21, fontWeight: 800, color: 'var(--bank-ink)', margin: '4px 0 0', letterSpacing: '-.01em' }}>
          Synthèse de votre dossier
        </h2>
      </div>

      {/* carte identité */}
      <div style={{ padding: 16, borderRadius: 14, background: '#fff', border: '1px solid var(--bank-line)',
        display: 'flex', gap: 14, alignItems: 'center' }}>
        <BIDPhoto hue={profile.hue} size={62} radius={10} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 17, fontWeight: 800, lineHeight: 1.2, color: 'var(--bank-ink)' }}>
            {profile.prenom} {profile.nom}
          </div>
          <div style={{ fontSize: 12.5, color: 'var(--bank-muted)', marginTop: 2 }}>{profile.age} ans · {profile.sexe}</div>
          <div style={{ display: 'inline-block', marginTop: 7, padding: '5px 10px', borderRadius: 7, background: 'var(--bank-soft)',
            fontSize: 11, fontFamily: 'monospace', color: 'var(--bank-primary)', fontWeight: 600 }}>
            {profile.docNum}
          </div>
        </div>
      </div>

      <Notice tone="ok">
        Données <strong>transmises et signées</strong> par votre portefeuille via eIDAS2. Non saisies manuellement.
      </Notice>

      <div style={{ background: '#fff', border: '1px solid var(--bank-line)', borderRadius: 14, overflow: 'hidden' }}>
        {fields.map((c, i) => (
          <Field key={c.key} label={c.label} value={profile[c.key]} last={i === fields.length - 1} />
        ))}
      </div>

      <BtnPrimary onClick={onNext} icon full>Suivant</BtnPrimary>
    </div>
  );
}

function MobileBankApp(props) {
  const { stage } = props;
  return (
    <div style={{ height: '100%', background: 'var(--bank-bg)', display: 'flex', flexDirection: 'column' }}>
      <MobileHeader />
      <MobileProgress stage={stage} />
      <div className="thin-scroll" style={{ flex: 1, overflowY: 'auto', overflowX: 'hidden' }}>
        {stage === 'home'      && <MBHome onStart={props.onStart} />}
        {stage === 'choose'    && <MBChoose onChooseWallet={props.onChooseWallet} />}
        {stage === 'verifying' && <MBVerifying />}
        {stage === 'summary'   && <MBSummary profile={props.profile} claims={props.claims}
                                     sharedKeys={props.sharedKeys} onNext={props.onNext} />}
      </div>
    </div>
  );
}

Object.assign(window, { BankApp, MobileBankApp });
