// Tirelire.ch — screens (web app: Auth, Onboarding, Dashboard, Transactions, Settings, Modal)

// ────────────────────────────────────────────────────────────
// CONFIRM EMAIL
// ────────────────────────────────────────────────────────────
function ConfirmEmailScreen() {
  return (
    <div style={{
      minHeight: '100svh', display: 'flex', alignItems: 'center',
      justifyContent: 'center', padding: '24px', background: 'var(--bg)',
    }}>
      <div style={{ maxWidth: 400, textAlign: 'center' }}>
        <div style={{ fontSize: 48, marginBottom: 16 }}>📬</div>
        <h2 style={{
          fontFamily: 'var(--serif)', fontSize: 26, margin: '0 0 12px',
          color: 'var(--ink)',
        }}>Vérifie ta boîte mail</h2>
        <p style={{ color: 'var(--muted)', lineHeight: 1.6, margin: 0 }}>
          On t'a envoyé un lien de confirmation. Clique dessus pour activer ton compte et accéder à Tirelire.ch.
        </p>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// AUTH (login / signup)
// ────────────────────────────────────────────────────────────
function AuthScreen({ mode, onSubmit, onSwitch, dark, onToggleDark, authError, loading }) {
  const [email, setEmail] = React.useState('');
  const [pw, setPw] = React.useState('');
  const isLogin = mode === 'login';

  return (
    <div style={{
      minHeight: '100%', background: 'var(--bg)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: '40px 20px', position: 'relative',
    }}>
      {/* Theme toggle */}
      <button onClick={onToggleDark} aria-label="theme" style={{
        position: 'absolute', top: 24, right: 24,
        background: 'var(--surface)', border: '1px solid var(--border)',
        width: 38, height: 38, borderRadius: 999, cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: 'var(--ink)',
      }}>{dark ? Icon.sun(16) : Icon.moon(16)}</button>

      {/* Marketing left (desktop only) */}
      <div style={{
        flex: 1, maxWidth: 460, paddingRight: 60,
        display: 'none',
      }} className="auth-aside">
        <div className="section-num">Tirelire.ch</div>
        <h1 style={{
          margin: '12px 0 18px', fontSize: 56, fontWeight: 700,
          letterSpacing: '-0.03em', lineHeight: 1.0, color: 'var(--ink)',
        }}>Tes finances,<br/>
          <em style={{ fontFamily: 'var(--serif)', fontWeight: 400 }}>sans le jargon.</em>
        </h1>
        <p style={{
          margin: 0, fontSize: 16, color: 'var(--muted)', lineHeight: 1.55,
        }}>
          Un budget mensuel clair, en CHF, avec la règle 50/30/20.
          Pas de banque connectée, pas de complexité — juste toi et tes chiffres.
        </p>
        <div style={{
          marginTop: 32, padding: 18, background: 'var(--surface)',
          borderRadius: 12, border: '1px solid var(--border)',
          maxWidth: 360,
        }}>
          <div style={{
            display: 'flex', alignItems: 'baseline', justifyContent: 'space-between',
            marginBottom: 10,
          }}>
            <span className="section-num">Mai 2026</span>
            <span style={{
              fontFamily: 'var(--mono)', fontSize: 10, color: 'var(--green)',
              fontWeight: 600,
            }}>+1 850 CHF</span>
          </div>
          <div style={{
            fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 38,
            color: 'var(--green)', lineHeight: 1, letterSpacing: '-0.02em',
          }}>3 240.50<span style={{
            fontFamily: 'var(--mono)', fontSize: 13, color: 'var(--muted)',
            marginLeft: 6, fontStyle: 'normal', fontWeight: 500,
          }}>CHF</span></div>
          <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 4 }}>
            Tu peux investir ce mois
          </div>
        </div>
      </div>

      {/* Auth card */}
      <div style={{
        width: '100%', maxWidth: 440,
        background: 'var(--surface)',
        borderRadius: 16, padding: 36,
        boxShadow: 'var(--shadow-md)',
        border: '1px solid var(--border)',
      }}>
        <div style={{
          display: 'flex', flexDirection: 'column', alignItems: 'center',
          marginBottom: 28,
        }}>
          <LogoMark size={48} />
          <div style={{ height: 12 }} />
          <Wordmark size={24} />
          <div style={{
            marginTop: 8, fontFamily: 'var(--serif)', fontStyle: 'italic',
            fontSize: 16, color: 'var(--muted)', textAlign: 'center',
          }}>Tes finances, sans le jargon.</div>
        </div>

        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 22,
          paddingBottom: 14, borderBottom: '1px solid var(--border)',
        }}>
          <h2 style={{
            margin: 0, fontSize: 22, fontWeight: 700,
            letterSpacing: '-0.02em', color: 'var(--ink)',
          }}>
            {isLogin ? 'Connexion' : 'Créer mon compte'}
          </h2>
        </div>

        <form onSubmit={(e) => { e.preventDefault(); onSubmit({ email, password: pw }); }}
          style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
          <Input id="email" label="Email" type="email" value={email}
            placeholder="prenom@example.ch" onChange={setEmail} />
          <Input id="pw" label="Mot de passe" type="password" value={pw}
            placeholder="••••••••" onChange={setPw} />

          {isLogin && (
            <a href="#" onClick={(e) => e.preventDefault()} style={{
              fontSize: 12, color: 'var(--muted)', textDecoration: 'none',
              marginTop: -4, alignSelf: 'flex-end', whiteSpace: 'nowrap',
            }}>Mot de passe oublié ?</a>
          )}

          {authError && (
            <div style={{
              background: '#FEE2E2', border: '1px solid #FECACA',
              borderRadius: 8, padding: '10px 14px',
              fontSize: 13, color: '#B91C1C',
            }}>{authError}</div>
          )}

          <Button type="submit" size="lg" full disabled={loading} style={{ marginTop: 6 }}>
            {loading ? 'Chargement...' : (isLogin ? 'Connexion' : 'Créer mon compte')}
          </Button>
        </form>

        <div style={{ textAlign: 'center', fontSize: 13, color: 'var(--muted)', padding: '20px 0 8px' }}>
          {isLogin ? 'Pas encore de compte ? ' : 'Déjà inscrit ? '}
          <a href="#" onClick={(e) => { e.preventDefault(); onSwitch(); }} style={{
            color: 'var(--ink)', textDecoration: 'none', fontWeight: 600,
            borderBottom: '1.5px solid var(--yellow)',
          }}>
            {isLogin ? 'Inscription' : 'Connexion'}
          </a>
        </div>

        <div style={{
          marginTop: 18, paddingTop: 18, borderTop: '1px solid var(--border)',
          display: 'flex', justifyContent: 'center', gap: 18, flexWrap: 'wrap',
        }}>
          <TrustChip icon={Icon.shield(13)} text="Données hébergées en Suisse" />
          <TrustChip icon={Icon.bank(13)} text="Aucune banque connectée" />
        </div>
      </div>

      <style>{`
        @media (min-width: 960px) {
          .auth-aside { display: block !important; }
        }
      `}</style>
    </div>
  );
}

function TrustChip({ icon, text }) {
  return (
    <div style={{
      display: 'inline-flex', alignItems: 'center', gap: 6,
      color: 'var(--muted)', fontSize: 11, fontWeight: 500,
    }}>
      <span style={{ color: 'var(--green)', display: 'inline-flex' }}>{icon}</span>
      <span>{text}</span>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// ONBOARDING — Revenu mensuel
// ────────────────────────────────────────────────────────────
function OnboardingScreen({ onComplete, dark, onToggleDark }) {
  const [step, setStep] = React.useState(1);
  const [income, setIncome] = React.useState('6850');
  const [goal, setGoal] = React.useState('300');

  const inputStyle = {
    fontFamily: 'var(--mono)', fontSize: 64, fontWeight: 500,
    background: 'transparent', border: 0, outline: 0,
    textAlign: 'right', color: 'var(--ink)', padding: 0,
    letterSpacing: '-0.02em',
  };

  return (
    <div style={{
      minHeight: '100%', background: 'var(--bg)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      padding: '40px 20px', position: 'relative',
    }}>
      <button onClick={onToggleDark} aria-label="theme" style={{
        position: 'absolute', top: 24, right: 24,
        background: 'var(--surface)', border: '1px solid var(--border)',
        width: 38, height: 38, borderRadius: 999, cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: 'var(--ink)',
      }}>{dark ? Icon.sun(16) : Icon.moon(16)}</button>

      <div style={{
        width: '100%', maxWidth: 560,
        background: 'var(--surface)',
        borderRadius: 16, padding: 48,
        boxShadow: 'var(--shadow-md)',
        border: '1px solid var(--border)',
        position: 'relative',
      }}>
        {/* Progress */}
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'center',
          marginBottom: 32,
        }}>
          <span className="section-num">Étape {step} / 2</span>
          <div style={{ width: 80, height: 3, background: 'var(--surface-2)', borderRadius: 999 }}>
            <div style={{
              width: step === 1 ? '50%' : '100%', height: '100%',
              background: 'var(--green)', borderRadius: 999,
              transition: 'width 0.3s ease',
            }} />
          </div>
        </div>

        {step === 1 ? (
          <>
            <h1 style={{ margin: 0, fontSize: 36, fontWeight: 700, letterSpacing: '-0.025em', color: 'var(--ink)', lineHeight: 1.1 }}>
              Quel est ton<br/>
              <span style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontWeight: 400 }}>revenu mensuel net</span> ?
            </h1>
            <p style={{ margin: '16px 0 0', fontSize: 15, color: 'var(--muted)', lineHeight: 1.5 }}>
              On utilise ça pour calculer ton budget idéal. Tu pourras modifier à tout moment.
            </p>

            <div style={{ margin: '40px 0 28px', display: 'flex', alignItems: 'baseline', gap: 16, padding: '20px 8px 14px', borderBottom: '2px solid var(--ink)', justifyContent: 'center' }}>
              <input value={income} onChange={(e) => setIncome(e.target.value.replace(/\D/g, ''))}
                autoFocus style={{ ...inputStyle, width: `${Math.max(2, income.length)}ch` }} />
              <span style={{ fontFamily: 'var(--mono)', fontSize: 24, color: 'var(--muted)', fontWeight: 500 }}>CHF</span>
            </div>

            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'center', marginBottom: 32 }}>
              {[4500, 5500, 6500, 7500, 9000].map(v => (
                <button key={v} onClick={() => setIncome(String(v))} style={{
                  padding: '8px 14px', borderRadius: 999,
                  background: String(v) === income ? 'var(--ink)' : 'var(--surface)',
                  color: String(v) === income ? 'var(--bg)' : 'var(--muted)',
                  border: '1px solid ' + (String(v) === income ? 'var(--ink)' : 'var(--border)'),
                  fontFamily: 'var(--mono)', fontSize: 12, cursor: 'pointer', fontWeight: 500,
                }}>{fmtCHFnoDec(v)}</button>
              ))}
            </div>

            <div style={{ marginBottom: 24, padding: 14, background: 'var(--surface-2)', borderRadius: 8, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <div style={{ fontSize: 12, color: 'var(--muted)' }}>
                Soit <strong style={{ color: 'var(--ink)', fontFamily: 'var(--mono)' }}>{fmtCHFnoDec(Math.round((+income || 0) * 12))} CHF</strong> sur l'année
              </div>
              <div style={{ fontSize: 10, fontFamily: 'var(--mono)', color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.04em' }}>≈ projection</div>
            </div>

            <Button size="lg" full onClick={() => setStep(2)} icon={Icon.arrowRight(18)} style={{ flexDirection: 'row-reverse', gap: 10 }}>
              Continuer
            </Button>
          </>
        ) : (
          <>
            <h1 style={{ margin: 0, fontSize: 36, fontWeight: 700, letterSpacing: '-0.025em', color: 'var(--ink)', lineHeight: 1.1 }}>
              Combien veux-tu<br/>
              <span style={{ fontFamily: 'var(--serif)', fontStyle: 'italic', fontWeight: 400 }}>investir par mois</span> ?
            </h1>
            <p style={{ margin: '16px 0 0', fontSize: 15, color: 'var(--muted)', lineHeight: 1.5 }}>
              On affichera ta progression chaque mois. Pas de pression — tu peux ignorer et ajuster plus tard.
            </p>

            <div style={{ margin: '40px 0 28px', display: 'flex', alignItems: 'baseline', gap: 16, padding: '20px 8px 14px', borderBottom: '2px solid var(--green)', justifyContent: 'center' }}>
              <input value={goal} onChange={(e) => setGoal(e.target.value.replace(/\D/g, ''))}
                autoFocus style={{ ...inputStyle, width: `${Math.max(2, goal.length)}ch` }} />
              <span style={{ fontFamily: 'var(--mono)', fontSize: 24, color: 'var(--muted)', fontWeight: 500 }}>CHF/mois</span>
            </div>

            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'center', marginBottom: 32 }}>
              {[100, 200, 300, 500, 1000].map(v => (
                <button key={v} onClick={() => setGoal(String(v))} style={{
                  padding: '8px 14px', borderRadius: 999,
                  background: String(v) === goal ? 'var(--green)' : 'var(--surface)',
                  color: String(v) === goal ? '#fff' : 'var(--muted)',
                  border: '1px solid ' + (String(v) === goal ? 'var(--green)' : 'var(--border)'),
                  fontFamily: 'var(--mono)', fontSize: 12, cursor: 'pointer', fontWeight: 500,
                }}>{fmtCHFnoDec(v)}</button>
              ))}
            </div>

            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              <Button size="lg" full onClick={() => onComplete({ income: +income, investmentGoal: +goal || 0 })}
                icon={Icon.arrowRight(18)} style={{ flexDirection: 'row-reverse', gap: 10 }}>
                Découvrir ma capacité d'investissement
              </Button>
              <button onClick={() => onComplete({ income: +income, investmentGoal: 0 })} style={{
                background: 'none', border: 'none', cursor: 'pointer',
                fontSize: 13, color: 'var(--muted)', textDecoration: 'underline', padding: 8,
              }}>
                Ignorer pour l'instant
              </button>
            </div>
          </>
        )}
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// BOTTOM NAV (mobile)
// ────────────────────────────────────────────────────────────
function BottomNav({ current, onNav }) {
  const items = [
    { id: 'dashboard',    icon: Icon.home(22),     label: 'Budget' },
    { id: 'transactions', icon: Icon.list(22),     label: 'Historique' },
    { id: 'annuel',       icon: Icon.barChart(22), label: 'Analyse' },
    { id: 'assurances',   icon: Icon.umbrella(22), label: 'Assurances' },
    { id: 'settings',     icon: Icon.settings(22), label: 'Paramètres' },
  ];
  return (
    <nav className="bottom-nav">
      {items.map(item => (
        <button key={item.id}
          className={'bottom-nav-item' + (current === item.id ? ' active' : '')}
          onClick={() => onNav(item.id)}>
          {item.icon}
          <span>{item.label}</span>
        </button>
      ))}
    </nav>
  );
}

// ────────────────────────────────────────────────────────────
// SHELL — Sidebar + Top bar + content area
// ────────────────────────────────────────────────────────────
function AppShell({ children, current, onNav, onAddTx, onSignOut, dark, onToggleDark, income, monthLabel, onPrev, onNext, canGoNext, showMonth, pageTitle, pageSub, user }) {
  React.useEffect(() => { window.scrollTo(0, 0); }, [current]);
  return (
    <div className="shell">
      <aside className="shell-sidebar">
        <div style={{
          padding: '4px 8px 22px', display: 'flex', alignItems: 'center', gap: 10,
        }}>
          <LogoMark size={32} />
          <div className="sidebar-wordmark"><Wordmark size={18} /></div>
        </div>

        <nav style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
          <NavItem icon={Icon.home(18)} label="Dashboard"
            active={current === 'dashboard'} onClick={() => onNav('dashboard')} />
          <NavItem icon={Icon.list(18)} label="Transactions"
            active={current === 'transactions'} onClick={() => onNav('transactions')} />
          <NavItem icon={Icon.barChart(18)} label="Analyse annuelle"
            active={current === 'annuel'} onClick={() => onNav('annuel')} />
          <NavItem icon={Icon.umbrella(18)} label="Assurances"
            active={current === 'assurances'} onClick={() => onNav('assurances')} />
          <NavItem icon={Icon.settings(18)} label="Paramètres"
            active={current === 'settings'} onClick={() => onNav('settings')} />
        </nav>

        <div style={{ flex: 1 }} />

        {/* User pill */}
        <div className="sidebar-user" style={{
          padding: 12, borderRadius: 10,
          background: 'var(--surface)', border: '1px solid var(--border)',
          display: 'flex', alignItems: 'center', gap: 10,
          marginBottom: 12,
        }}>
          <div style={{
            width: 32, height: 32, borderRadius: 999, background: 'var(--ink)',
            color: 'var(--bg)', display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontFamily: 'var(--serif)', fontStyle: 'italic', fontSize: 17, fontWeight: 400,
            flexShrink: 0,
          }}>{(user?.email?.[0] || 'U').toUpperCase()}</div>
          <div style={{ minWidth: 0, flex: 1 }}>
            <div style={{
              fontSize: 12, fontWeight: 600, color: 'var(--ink)',
              overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
            }}>{user?.email?.split('@')[0] || ''}</div>
            <div style={{
              fontSize: 11, color: 'var(--muted)',
              overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
            }}>{user?.email || ''}</div>
          </div>
        </div>

        <div className="sidebar-footer" style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '8px 4px',
        }}>
          <div style={{ fontSize: 11, color: 'var(--muted)', fontFamily: 'var(--mono)' }}>
            v0.1 · 🇨🇭
          </div>
          <button onClick={onToggleDark} aria-label="theme" style={{
            background: 'transparent', border: 0, cursor: 'pointer',
            color: 'var(--muted)', display: 'flex', alignItems: 'center',
            padding: 6, borderRadius: 6,
          }}>{dark ? Icon.sun(16) : Icon.moon(16)}</button>
        </div>
      </aside>

      <main className="shell-main">
        <div className="topbar">
          <div style={{ display: 'flex', flexDirection: 'column', gap: 2, minWidth: 0 }}>
            <span className="section-num">{pageSub}</span>
            <h1 className={showMonth ? 'topbar-month-title' : ''} style={{
              margin: 0, fontSize: 22, fontWeight: 700, letterSpacing: '-0.02em',
              color: 'var(--ink)', whiteSpace: 'nowrap',
            }}>{pageTitle}</h1>
          </div>

          <div style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
            {showMonth && (
              <div style={{
                display: 'flex', alignItems: 'center', gap: 4,
                background: 'var(--surface)', border: '1px solid var(--border)',
                borderRadius: 999, padding: 4,
              }}>
                <button onClick={onPrev} style={monthBtnStyle}>{Icon.chevronLeft(15)}</button>
                <div style={{
                  fontSize: 13, fontWeight: 600, color: 'var(--ink)',
                  padding: '0 12px', letterSpacing: '-0.005em', whiteSpace: 'nowrap',
                }}>{monthLabel}</div>
                <button onClick={onNext} disabled={!canGoNext}
                  style={{ ...monthBtnStyle, opacity: canGoNext ? 1 : 0.3, cursor: canGoNext ? 'pointer' : 'default' }}>
                  {Icon.chevronRight(15)}
                </button>
              </div>
            )}
            <Button icon={Icon.plus(16)} onClick={onAddTx}><span className="btn-add-label">Ajouter une transaction</span></Button>
          </div>
        </div>

        <div className="content-wrap">{children}</div>
      </main>
      <BottomNav current={current} onNav={onNav} />
    </div>
  );
}

const monthBtnStyle = {
  width: 28, height: 28, borderRadius: 999, border: 0,
  background: 'transparent', cursor: 'pointer',
  display: 'flex', alignItems: 'center', justifyContent: 'center',
  color: 'var(--ink)',
};

function NavItem({ icon, label, active, onClick, badge }) {
  return (
    <button className={'nav-item' + (active ? ' active' : '')} onClick={onClick}>
      <span style={{ display: 'inline-flex', color: active ? 'var(--green)' : 'currentColor' }}>{icon}</span>
      <span>{label}</span>
      {badge && <span className="badge">{badge}</span>}
    </button>
  );
}

// ────────────────────────────────────────────────────────────
// DASHBOARD
// ────────────────────────────────────────────────────────────
function DashboardScreen({ state, onAddTx, onOpenAll, onDelete, investmentGoal }) {
  const { transactions, income } = state;
  const isEmpty = transactions.length === 0;

  const incomeTotal = transactions.filter(t => t.amount > 0).reduce((s, t) => s + t.amount, 0);
  const expenseTotal = transactions.filter(t => t.amount < 0).reduce((s, t) => s + t.amount, 0);
  const balance = incomeTotal + expenseTotal;
  const expenses = Math.abs(expenseTotal);

  const target = { besoins: income * 0.5, envies: income * 0.3, epargne: income * 0.2 };
  const used = { besoins: 0, envies: 0, epargne: 0 };
  transactions.forEach(t => {
    if (t.amount >= 0) return;
    const cat = CATEGORIES.find(c => c.id === t.categoryId);
    if (cat && used[cat.bucket] !== undefined) used[cat.bucket] += Math.abs(t.amount);
  });

  const byCat = {};
  transactions.forEach(t => {
    if (t.amount >= 0) return;
    byCat[t.categoryId] = (byCat[t.categoryId] || 0) + Math.abs(t.amount);
  });
  const segments = Object.entries(byCat)
    .map(([cid, v]) => {
      const c = CATEGORIES.find(x => x.id === cid);
      return { label: c.label, value: v, color: c.color, emoji: c.emoji, id: cid };
    })
    .sort((a, b) => b.value - a.value);

  return (
    <div className="fade-in" style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>

      {/* §01 Résumé du mois */}
      <section>
        <SectionLabel num="01" title="Résumé du mois" />
        <Card padding={0}>
          {/* Headline */}
          <div className="summary-grid" style={{
            padding: '24px 28px 8px',
            borderBottom: '1px solid var(--border)',
            display: 'grid',
            gridTemplateColumns: 'repeat(3, 1fr)',
            gap: 0,
          }}>
            <MetricBlock label="Revenus" amount={incomeTotal} tone="positive" />
            <MetricBlock label="Dépenses" amount={-expenses} tone="negative" />
            <MetricBlock label="Tu peux investir" amount={balance}
              tone={balance >= 0 ? 'positive' : 'negative'} big />
          </div>

          {/* Barre objectif d'investissement */}
          {investmentGoal > 0 && balance > 0 && (
            <div style={{ padding: '14px 28px', borderBottom: '1px solid var(--border)' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
                <span style={{ fontSize: 12, fontWeight: 600, color: 'var(--muted)', letterSpacing: '-0.005em' }}>
                  Objectif investissement
                </span>
                <span style={{ fontFamily: 'var(--mono)', fontSize: 12, color: 'var(--ink)', fontWeight: 600 }}>
                  {Math.min(100, Math.round(balance / investmentGoal * 100))}% — cible {fmtCHFnoDec(investmentGoal)} CHF/mois
                </span>
              </div>
              <div style={{ height: 6, background: 'var(--surface-2)', borderRadius: 999, overflow: 'hidden' }}>
                <div style={{
                  width: Math.min(100, Math.round(balance / investmentGoal * 100)) + '%',
                  height: '100%', background: 'var(--green)', borderRadius: 999,
                  transition: 'width 0.4s ease',
                }} />
              </div>
            </div>
          )}

          {/* Sub: 50/30/20 */}
          {!isEmpty ? (
            <div style={{
              padding: '20px 28px 22px',
              background: 'var(--surface-2)',
              borderRadius: '0 0 12px 12px',
            }}>
              <div style={{
                display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
                marginBottom: 16, gap: 12, flexWrap: 'wrap',
              }}>
                <div style={{
                  fontSize: 13, fontWeight: 700, color: 'var(--ink)',
                  letterSpacing: '-0.005em', whiteSpace: 'nowrap',
                }}>
                  Règle&nbsp;50&nbsp;/&nbsp;30&nbsp;/&nbsp;20
                </div>
                <span className="section-num" style={{ fontSize: 10, whiteSpace: 'nowrap' }}>
                  Cible sur {fmtCHFnoDec(income)} CHF / mois
                </span>
              </div>
              <div className="rule-grid" style={{
                display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 24,
              }}>
                <RuleBar label="Besoins" pct="50%" used={used.besoins} target={target.besoins} color="var(--green)" />
                <RuleBar label="Envies"  pct="30%" used={used.envies}  target={target.envies}  color="var(--yellow)" />
                <RuleBar label="Investissement" pct="20%" used={used.epargne} target={target.epargne} color="var(--ink)" />
              </div>
            </div>
          ) : (
            <div style={{
              padding: '28px', textAlign: 'center', color: 'var(--muted)',
              background: 'var(--surface-2)', borderRadius: '0 0 12px 12px',
            }}>
              <div style={{ fontSize: 14 }}>Ajoute ta première transaction pour voir ton budget prendre forme →</div>
              <div style={{ marginTop: 14 }}>
                <Button onClick={onAddTx} icon={Icon.plus(16)}>Ajouter une transaction</Button>
              </div>
            </div>
          )}
        </Card>
      </section>

      {/* Two-column: categories + transactions */}
      {!isEmpty && (
        <div className="grid-2">
          {/* §02 Répartition */}
          <section>
            <SectionLabel num="02" title="Répartition par catégorie" />
            <Card padding={24}>
              <StackedBar segments={segments} total={expenses} height={14} />
              <div style={{
                display: 'flex', justifyContent: 'space-between',
                marginTop: 12, marginBottom: 18,
                fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--muted)',
              }}>
                <span>Total dépensé</span>
                <span style={{ color: 'var(--ink)', fontWeight: 600 }}>{fmtCHF(expenses)} CHF</span>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
                {segments.map(s => (
                  <div key={s.id} style={{
                    display: 'flex', alignItems: 'center', gap: 14,
                  }}>
                    <div style={{
                      width: 30, height: 30, borderRadius: 8,
                      background: 'var(--surface-2)',
                      display: 'flex', alignItems: 'center', justifyContent: 'center',
                      fontSize: 14, flexShrink: 0,
                    }}>{s.emoji}</div>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{
                        display: 'flex', justifyContent: 'space-between', alignItems: 'baseline',
                        marginBottom: 4,
                      }}>
                        <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{s.label}</div>
                        <div style={{ fontFamily: 'var(--mono)', fontSize: 12, fontWeight: 600, color: 'var(--ink)' }}>
                          {fmtCHF(s.value)}
                          <span style={{ color: 'var(--muted)', marginLeft: 4, fontSize: 10 }}>CHF</span>
                        </div>
                      </div>
                      <div style={{
                        height: 3, background: 'var(--surface-2)', borderRadius: 999,
                        overflow: 'hidden',
                      }}>
                        <div style={{
                          width: `${(s.value / expenses) * 100}%`,
                          height: '100%', background: s.color,
                          transition: 'width 400ms ease',
                        }} />
                      </div>
                    </div>
                    <div style={{
                      width: 36, textAlign: 'right',
                      fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--muted)',
                    }}>{Math.round((s.value / expenses) * 100)}%</div>
                  </div>
                ))}
              </div>
            </Card>
          </section>

          {/* §03 Transactions */}
          <section>
            <SectionLabel num="03" title="Transactions récentes"
              action={
                <a href="#" onClick={(e) => { e.preventDefault(); onOpenAll(); }}
                  style={{
                    fontSize: 12, color: 'var(--ink)', textDecoration: 'none',
                    fontWeight: 600, borderBottom: '1.5px solid var(--yellow)',
                  }}>Voir tout</a>
              } />
            <Card padding={0}>
              {transactions.slice(0, 8).map((tx, i, arr) => (
                <TransactionRow key={tx.id} tx={tx} categories={CATEGORIES}
                  last={i === arr.length - 1} onDelete={onDelete} />
              ))}
            </Card>
          </section>
        </div>
      )}

      {/* Footer */}
      <div style={{
        textAlign: 'center', fontSize: 11, color: 'var(--muted-2)',
        padding: '12px 0 0', fontFamily: 'var(--mono)',
      }}>
        Tirelire.ch · MVP v0.1 · Données en CHF
      </div>
    </div>
  );
}

function MetricBlock({ label, amount, tone, big }) {
  const color = tone === 'positive' ? 'var(--green)'
    : tone === 'negative' ? 'var(--coral)' : 'var(--ink)';
  return (
    <div style={{ padding: '8px 8px 18px', minWidth: 0 }}>
      <div style={{
        fontSize: 11, fontWeight: 600, color: 'var(--muted)',
        textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: 8,
      }}>{label}</div>
      <div style={{
        fontFamily: big ? 'var(--serif)' : 'var(--mono)',
        fontStyle: big ? 'italic' : 'normal',
        fontSize: big ? 'clamp(28px, 3.4vw, 44px)' : 'clamp(18px, 1.85vw, 24px)',
        fontWeight: big ? 400 : 600,
        color, letterSpacing: big ? '-0.025em' : '-0.01em',
        lineHeight: 1.05, whiteSpace: 'nowrap',
        overflow: 'hidden', textOverflow: 'ellipsis',
      }}>
        {tone === 'positive' && !big && amount > 0 ? '+' : ''}{fmtCHF(amount)}
        <span style={{
          fontFamily: 'var(--mono)', fontStyle: 'normal',
          fontSize: big ? 13 : 11, color: 'var(--muted)', marginLeft: 6,
          fontWeight: 500,
        }}>CHF</span>
      </div>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// TransactionRow
// ────────────────────────────────────────────────────────────
function TransactionRow({ tx, categories, last, onDelete }) {
  const cat = categories.find(c => c.id === tx.categoryId) || categories[0];
  const isIncome = tx.amount > 0;

  return (
    <div style={{
      display: 'flex', alignItems: 'center', gap: 14,
      padding: '14px 20px',
      borderBottom: last ? 0 : '1px solid var(--border)',
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: 10,
        background: 'var(--surface-2)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontSize: 17, flexShrink: 0,
      }}>{cat.emoji}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{
          fontSize: 14, fontWeight: 600, color: 'var(--ink)',
          overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
          letterSpacing: '-0.005em',
        }}>{tx.description || cat.label}</div>
        <div style={{
          fontSize: 12, color: 'var(--muted)', marginTop: 2,
          display: 'flex', alignItems: 'center', gap: 6,
        }}>
          <span>{cat.label}</span>
          <span style={{ width: 3, height: 3, borderRadius: 999, background: 'var(--muted-2)' }} />
          <span>{tx.dateLabel}</span>
        </div>
      </div>
      <div style={{
        fontFamily: 'var(--mono)', fontSize: 14, fontWeight: 600,
        color: isIncome ? 'var(--green)' : 'var(--ink)',
        whiteSpace: 'nowrap',
      }}>
        {isIncome ? '+' : '−'}{fmtCHF(Math.abs(tx.amount))}
        <span style={{ color: 'var(--muted)', marginLeft: 4, fontSize: 11 }}>CHF</span>
      </div>
      {onDelete && (
        <button onClick={() => onDelete(tx.id)} title="Supprimer" style={{
          width: 28, height: 28, borderRadius: 6, border: 0, cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
          background: 'transparent', color: 'var(--muted)',
          transition: 'color 0.15s',
        }}>
          {Icon.trash(14)}
        </button>
      )}
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// 50/30/20 Bar
// ────────────────────────────────────────────────────────────
function RuleBar({ label, pct, used, target, color }) {
  const pctUsed = Math.min(100, (used / target) * 100);
  const over = used > target;
  return (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 8 }}>
        <div>
          <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{label}</span>
          <span style={{ fontSize: 11, color: 'var(--muted)', marginLeft: 6, fontFamily: 'var(--mono)' }}>{pct}</span>
        </div>
        <div style={{ fontFamily: 'var(--mono)', fontSize: 11, color: over ? 'var(--coral)' : 'var(--muted)' }}>
          {fmtCHFnoDec(used)} / {fmtCHFnoDec(target)}
        </div>
      </div>
      <div style={{
        height: 6, background: 'var(--surface-3)', borderRadius: 999,
        overflow: 'hidden', position: 'relative',
      }}>
        <div style={{
          width: `${pctUsed}%`, height: '100%',
          background: over ? 'var(--coral)' : color,
          transition: 'width 500ms cubic-bezier(.2,.8,.2,1)',
          borderRadius: 999,
        }} />
      </div>
    </div>
  );
}

function TxTableRow({ tx, cat, isIncome, onDelete }) {
  return (
    <div className="tx-row" style={{
      display: 'grid', gridTemplateColumns: '36px 1fr 140px 120px 36px',
      gap: 14, padding: '14px 20px',
      borderBottom: '1px solid var(--border)',
      alignItems: 'center',
    }}>
      <div style={{
        width: 36, height: 36, borderRadius: 10, background: 'var(--surface-2)',
        display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 17,
      }}>{cat.emoji}</div>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
          {tx.description || cat.label}
        </div>
        <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 2 }}>{tx.dateLabel}</div>
      </div>
      <div className="tx-date-cell" style={{ fontFamily: 'var(--mono)', fontSize: 12, color: 'var(--muted)' }}>{tx.dateLabel}</div>
      <div style={{
        fontFamily: 'var(--mono)', fontSize: 14, fontWeight: 600,
        color: isIncome ? 'var(--green)' : 'var(--ink)', textAlign: 'right',
      }}>
        {isIncome ? '+' : '−'}{fmtCHF(Math.abs(tx.amount))}
        <span style={{ color: 'var(--muted)', marginLeft: 4, fontSize: 11 }}>CHF</span>
      </div>
      <button onClick={() => onDelete && onDelete(tx.id)} title="Supprimer" style={{
        width: 28, height: 28, borderRadius: 6, border: 0, cursor: 'pointer',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        background: 'transparent', color: 'var(--muted)',
        transition: 'color 0.15s',
      }}>
        {Icon.trash(14)}
      </button>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// ALL TRANSACTIONS
// ────────────────────────────────────────────────────────────
function TransactionsScreen({ state, onDelete }) {
  const { transactions } = state;
  const [filter, setFilter] = React.useState('all');
  const [q, setQ] = React.useState('');

  const filtered = transactions.filter(t => {
    if (filter === 'income' && t.amount < 0) return false;
    if (filter === 'expense' && t.amount > 0) return false;
    if (q && !(t.description || '').toLowerCase().includes(q.toLowerCase())) return false;
    return true;
  });

  const total = filtered.reduce((s, t) => s + t.amount, 0);

  // group by date label
  const groups = {};
  filtered.forEach(t => {
    if (!groups[t.dateLabel]) groups[t.dateLabel] = [];
    groups[t.dateLabel].push(t);
  });

  return (
    <div className="fade-in" style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
      <Card padding={20}>
        <div style={{
          display: 'flex', flexWrap: 'wrap', gap: 12,
          alignItems: 'center', justifyContent: 'space-between',
        }}>
          <div style={{
            display: 'flex', gap: 4, background: 'var(--surface-2)',
            padding: 4, borderRadius: 999,
          }}>
            {[
              { v: 'all', l: 'Tout', n: transactions.length },
              { v: 'expense', l: 'Dépenses', n: transactions.filter(t => t.amount < 0).length },
              { v: 'income', l: 'Revenus', n: transactions.filter(t => t.amount > 0).length },
            ].map(o => (
              <button key={o.v} onClick={() => setFilter(o.v)}
                style={{
                  padding: '7px 14px', borderRadius: 999, border: 0,
                  background: filter === o.v ? 'var(--surface)' : 'transparent',
                  color: filter === o.v ? 'var(--ink)' : 'var(--muted)',
                  fontWeight: 600, fontSize: 13, cursor: 'pointer',
                  display: 'flex', alignItems: 'center', gap: 6,
                  boxShadow: filter === o.v ? 'var(--shadow-sm)' : 'none',
                }}>
                {o.l}
                <span style={{
                  fontFamily: 'var(--mono)', fontSize: 10,
                  color: filter === o.v ? 'var(--muted)' : 'var(--muted-2)',
                }}>{o.n}</span>
              </button>
            ))}
          </div>

          <div style={{ flex: 1, maxWidth: 320 }}>
            <Input value={q} onChange={setQ} placeholder="Rechercher une transaction…" />
          </div>
        </div>
      </Card>

      <Card padding={0}>
        {/* Header row */}
        <div className="tx-header" style={{
          display: 'grid', gridTemplateColumns: '36px 1fr 140px 120px 36px',
          gap: 14, padding: '12px 20px',
          borderBottom: '1px solid var(--border)',
          fontSize: 11, color: 'var(--muted)', fontWeight: 600,
          textTransform: 'uppercase', letterSpacing: '0.04em',
        }}>
          <div></div>
          <div>Transaction</div>
          <div>Date</div>
          <div style={{ textAlign: 'right' }}>Montant</div>
          <div></div>
        </div>

        {Object.entries(groups).map(([label, txs]) => (
          <React.Fragment key={label}>
            {txs.map((tx) => {
              const cat = CATEGORIES.find(c => c.id === tx.categoryId) || CATEGORIES[0];
              const isIncome = tx.amount > 0;
              return (
                <TxTableRow key={tx.id} tx={tx} cat={cat} isIncome={isIncome} onDelete={onDelete} />
              );
            })}
          </React.Fragment>
        ))}

        {filtered.length === 0 && (
          <div style={{
            padding: 48, textAlign: 'center', color: 'var(--muted)', fontSize: 14,
          }}>Aucune transaction ne correspond à ta recherche.</div>
        )}

        {/* Footer total */}
        {filtered.length > 0 && (
          <div className="tx-solde" style={{
            display: 'grid', gridTemplateColumns: '36px 1fr 140px 120px 36px',
            gap: 14, padding: '14px 20px',
            background: 'var(--surface-2)',
            borderRadius: '0 0 12px 12px',
            alignItems: 'center',
          }}>
            <div></div>
            <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--ink)' }}>
              Solde {filter === 'all' ? '' : '(' + (filter === 'income' ? 'revenus' : 'dépenses') + ')'}
            </div>
            <div className="tx-solde-date" style={{ fontFamily: 'var(--mono)', fontSize: 12, color: 'var(--muted)' }}>
              {filtered.length} ligne{filtered.length > 1 ? 's' : ''}
            </div>
            <div style={{
              fontFamily: 'var(--mono)', fontSize: 14, fontWeight: 700,
              color: total >= 0 ? 'var(--green)' : 'var(--coral)', textAlign: 'right',
            }}>
              {total >= 0 ? '+' : '−'}{fmtCHF(Math.abs(total))}
              <span style={{ color: 'var(--muted)', marginLeft: 4, fontSize: 11 }}>CHF</span>
            </div>
            <div></div>
          </div>
        )}
      </Card>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// SETTINGS
// ────────────────────────────────────────────────────────────
function SettingsScreen({ state, onIncomeChange, onSignOut, dark, onToggleDark, investmentGoal, onInvestmentGoalChange, user }) {
  const [income, setIncome] = React.useState(String(state.income));
  const [goalInput, setGoalInput] = React.useState(String(investmentGoal || 0));
  const [waitlistEmail, setWaitlistEmail] = React.useState('');
  const [joined, setJoined] = React.useState(false);

  return (
    <div className="fade-in" style={{
      display: 'grid', gridTemplateColumns: '1.2fr 1fr', gap: 20,
    }} data-settings>
      {/* Profile */}
      <section>
        <SectionLabel num="01" title="Mon profil" />
        <Card padding={24}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
            <div>
              <Input label="Revenu mensuel net" suffix="CHF"
                value={income} onChange={(v) => setIncome(v.replace(/\D/g, ''))} />
              {String(state.income) !== income && (
                <div style={{ marginTop: 10, display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
                  <Button size="sm" variant="ghost" onClick={() => setIncome(String(state.income))}>Annuler</Button>
                  <Button size="sm" onClick={() => onIncomeChange(+income)}>Enregistrer</Button>
                </div>
              )}
            </div>

            <div>
              <Input label="Objectif d'investissement mensuel" suffix="CHF/mois"
                value={goalInput} onChange={(v) => setGoalInput(v.replace(/\D/g, ''))} />
              {String(investmentGoal || 0) !== goalInput && (
                <div style={{ marginTop: 10, display: 'flex', justifyContent: 'flex-end', gap: 8 }}>
                  <Button size="sm" variant="ghost" onClick={() => setGoalInput(String(investmentGoal || 0))}>Annuler</Button>
                  <Button size="sm" onClick={() => onInvestmentGoalChange && onInvestmentGoalChange(+goalInput)}>Enregistrer</Button>
                </div>
              )}
            </div>

            <div>
              <div style={lblStyle}>Email</div>
              <div style={readonlyFieldStyle}>{user?.email || ''}</div>
            </div>

            <div style={{
              display: 'flex', justifyContent: 'space-between', alignItems: 'center',
              padding: '6px 0',
            }}>
              <div>
                <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>Mode sombre</div>
                <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 2 }}>
                  Plus reposant le soir
                </div>
              </div>
              <DarkToggle dark={dark} onToggle={onToggleDark} />
            </div>

            <hr className="hairline" />

            <div style={{
              display: 'flex', justifyContent: 'space-between', alignItems: 'center',
            }}>
              <div>
                <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>Session</div>
                <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 2 }}>
                  Connecté depuis Lausanne · 19 mai
                </div>
              </div>
              <Button variant="outline" onClick={onSignOut}>Se déconnecter</Button>
            </div>
          </div>
        </Card>
      </section>

      {/* Premium teaser */}
      <section>
        <SectionLabel num="02" title="Premium — bientôt" />
        <Card padding={0} style={{ overflow: 'hidden', position: 'relative' }}>
          {/* Decorative top */}
          <div style={{
            background: 'linear-gradient(180deg, var(--yellow-soft) 0%, transparent 100%)',
            padding: '28px 24px 18px',
          }}>
            <div style={{
              display: 'inline-flex', alignItems: 'center', gap: 8,
              background: 'var(--surface)', border: '1px solid var(--border)',
              padding: '5px 11px', borderRadius: 999, marginBottom: 12,
              fontSize: 10, fontWeight: 700, letterSpacing: '0.06em',
              textTransform: 'uppercase', color: 'var(--ink)',
            }}>
              <span style={{ color: 'var(--yellow)' }}>{Icon.lock(11)}</span>
              Bientôt disponible
            </div>
            <h3 style={{
              margin: 0, fontSize: 26, fontWeight: 700, letterSpacing: '-0.025em',
              color: 'var(--ink)',
            }}>
              <em style={{ fontFamily: 'var(--serif)', fontWeight: 400 }}>Tirelire</em> Premium
            </h3>
            <p style={{
              margin: '6px 0 0', fontSize: 13, color: 'var(--muted)', lineHeight: 1.45,
            }}>Va plus loin avec ton budget et optimise tes impôts suisses.</p>
          </div>

          <div style={{ padding: '4px 24px 24px' }}>
            <ul style={{
              margin: 0, padding: 0, listStyle: 'none',
              display: 'flex', flexDirection: 'column', gap: 10, marginBottom: 20,
            }}>
              {['Historique complet sur les années précédentes',
                '3e Pilier optimizer — déduction fiscale',
                'Alertes budget intelligentes',
                'Export PDF mensuel — rapport propre'].map((f, i) => (
                <li key={i} style={{
                  display: 'flex', gap: 10, alignItems: 'flex-start',
                  fontSize: 13, color: 'var(--ink)', fontWeight: 500,
                }}>
                  <span style={{
                    width: 18, height: 18, borderRadius: 999, background: 'var(--green-soft)',
                    color: 'var(--green)', flexShrink: 0,
                    display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
                    marginTop: 1,
                  }}>{Icon.check(12)}</span>
                  {f}
                </li>
              ))}
            </ul>

            {!joined ? (
              <form onSubmit={(e) => { e.preventDefault(); if (waitlistEmail) setJoined(true); }}
                style={{ display: 'flex', gap: 8 }}>
                <div style={{ flex: 1 }}>
                  <Input placeholder="ton@email.ch" value={waitlistEmail} onChange={setWaitlistEmail} />
                </div>
                <Button type="submit">Rejoindre</Button>
              </form>
            ) : (
              <div style={{
                padding: 14, borderRadius: 8, background: 'var(--green-soft)',
                color: 'var(--green)', fontSize: 13, fontWeight: 600,
                display: 'flex', alignItems: 'center', gap: 10,
              }}>
                {Icon.check(16)} Tu es inscrit · on te tient au courant
              </div>
            )}

            <div style={{
              marginTop: 16, paddingTop: 16, borderTop: '1px dashed var(--border)',
              display: 'flex', alignItems: 'center', gap: 12,
              fontSize: 12, color: 'var(--muted)',
            }}>
              <div style={{ display: 'flex' }}>
                {[0,1,2,3].map(i => (
                  <div key={i} style={{
                    width: 24, height: 24, borderRadius: 999, background: 'var(--surface-2)',
                    border: '2px solid var(--surface)',
                    marginLeft: i ? -8 : 0, fontSize: 10, fontWeight: 700,
                    color: 'var(--muted)',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                  }}>{['AB','MJ','LR','+'][i]}</div>
                ))}
              </div>
              <span><strong style={{ color: 'var(--ink)' }}>247 personnes</strong> en attente</span>
            </div>
          </div>
        </Card>
      </section>

      {/* §03 Aide & Retours */}
      <section>
        <SectionLabel num="03" title="Aide & Retours" />
        <Card padding={24}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
            <p style={{ margin: 0, fontSize: 13, color: 'var(--muted)', lineHeight: 1.5 }}>
              Tu as trouvé un bug ou tu as une idée pour améliorer l'app ? Fais-nous signe,
              chaque retour compte.
            </p>
            <div style={{ display: 'flex', gap: 10, flexWrap: 'wrap' }}>
              <Button variant="outline"
                onClick={() => window.open('https://tally.so/r/aQAMRq', '_blank')}>
                🐛 Signaler un bug
              </Button>
              <Button variant="outline"
                onClick={() => window.open('https://tally.so/r/aQAMRq', '_blank')}>
                💡 Suggérer une amélioration
              </Button>
            </div>
            <div style={{ fontSize: 11, color: 'var(--muted-2)', fontFamily: 'var(--mono)' }}>
              tirelire.ch · v0.2
            </div>
          </div>
        </Card>
      </section>

      <style>{`
        @media (max-width: 1040px) {
          [data-settings] { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </div>
  );
}

const lblStyle = {
  fontSize: 12, fontWeight: 600, color: 'var(--muted)',
  letterSpacing: '0.02em', textTransform: 'uppercase', marginBottom: 8,
};
const readonlyFieldStyle = {
  padding: '13px 14px', background: 'var(--surface-2)', borderRadius: 8,
  fontSize: 15, color: 'var(--ink)', fontWeight: 500,
};

function DarkToggle({ dark, onToggle }) {
  return (
    <button onClick={onToggle} style={{
      width: 52, height: 30, borderRadius: 999,
      background: dark ? 'var(--ink)' : 'var(--surface-2)',
      border: '1px solid var(--border)',
      position: 'relative', cursor: 'pointer',
      transition: 'background 200ms ease', padding: 0,
    }}>
      <div style={{
        position: 'absolute', top: 2, left: dark ? 24 : 2,
        width: 24, height: 24, borderRadius: 999,
        background: dark ? 'var(--yellow)' : 'var(--surface)',
        transition: 'left 220ms cubic-bezier(.2,.8,.2,1)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        color: dark ? 'var(--ink)' : 'var(--muted)',
        boxShadow: 'var(--shadow-sm)',
      }}>
        {dark ? Icon.moon(13) : Icon.sun(13)}
      </div>
    </button>
  );
}

// ────────────────────────────────────────────────────────────
// ADD TRANSACTION MODAL
// ────────────────────────────────────────────────────────────
function AddTransactionModal({ open, onClose, onSave, defaultIncome, defaultDate, todayStr }) {
  const [type, setType] = React.useState('expense');
  const [amount, setAmount] = React.useState('');
  const [catId, setCatId] = React.useState('alimentation');
  const [desc, setDesc] = React.useState('');
  const [date, setDate] = React.useState(defaultDate || todayStr || '');

  const pad = n => String(n).padStart(2, '0');
  const localDateStr = (d) => `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
  const today = new Date();
  const effectiveTodayStr = todayStr || localDateStr(today);
  const yesterdayStr = localDateStr(new Date(today.getFullYear(), today.getMonth(), today.getDate() - 1));

  React.useEffect(() => {
    if (open) {
      setType('expense'); setAmount(''); setCatId('alimentation'); setDesc('');
      setDate(defaultDate || effectiveTodayStr);
    }
  }, [open]);

  // Auto-fill avec le revenu du profil quand on sélectionne "salaire"
  React.useEffect(() => {
    if (catId === 'salaire' && type === 'income' && defaultIncome) {
      setAmount(String(defaultIncome));
    }
  }, [catId, type]);

  React.useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    return () => window.removeEventListener('keydown', onKey);
  }, [open, onClose]);

  if (!open) return null;

  const expenseCats = CATEGORIES.filter(c => !c.income);
  const incomeCats = CATEGORIES.filter(c => c.income);
  const cats = type === 'income' ? incomeCats : expenseCats;
  const canSave = +amount > 0;

  return (
    <>
      <div className="backdrop-enter" style={{
        position: 'fixed', inset: 0, background: 'rgba(15,18,15,0.5)',
        backdropFilter: 'blur(2px)',
        zIndex: 100,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        padding: 20,
      }}>
      <div className="modal-enter" onClick={e => e.stopPropagation()} style={{
        width: '100%', maxWidth: 520,
        maxHeight: '100%',
        display: 'flex', flexDirection: 'column',
        background: 'var(--surface)', borderRadius: 16,
        boxShadow: 'var(--shadow-lg)',
        border: '1px solid var(--border)',
      }}><div className="modal-inner" style={{ flex: 1, overflow: 'auto', padding: 28, paddingBottom: 16 }}>
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          marginBottom: 20,
        }}>
          <div>
            <h2 style={{
              margin: '2px 0 0', fontSize: 22, fontWeight: 700, letterSpacing: '-0.02em',
            }}>Ajouter une transaction</h2>
          </div>
          <button onClick={onClose} style={{
            width: 36, height: 36, borderRadius: 999, background: 'var(--surface-2)',
            border: 0, display: 'flex', alignItems: 'center', justifyContent: 'center',
            cursor: 'pointer', color: 'var(--ink)',
          }}>{Icon.close(18)}</button>
        </div>

        <div style={{ marginBottom: 18 }}>
          <Segmented value={type} onChange={(v) => {
            setType(v);
            setCatId(v === 'income' ? 'salaire' : 'alimentation');
          }} options={[
            { value: 'expense', label: 'Dépense', tone: 'expense' },
            { value: 'income',  label: 'Revenu',  tone: 'income'  },
          ]} />
        </div>

        <div style={{ marginBottom: 18 }}>
          <div style={lblStyle}>Catégorie</div>
          <div className="cat-grid">
            {cats.map(c => (
              <CategoryPill key={c.id} category={c} selected={catId === c.id}
                onClick={() => setCatId(c.id)} size="sm" />
            ))}
          </div>
        </div>

        <div style={{
          display: 'flex', alignItems: 'baseline', gap: 12,
          padding: '20px 8px 14px', marginBottom: 20,
          borderBottom: '2px solid var(--ink)', justifyContent: 'center',
        }}>
          <input value={amount} onChange={(e) => setAmount(e.target.value.replace(/[^\d.]/g, ''))}
            placeholder="0"
            className="amount-input"
            style={{
              fontFamily: 'var(--mono)', fontSize: 48, fontWeight: 500,
              background: 'transparent', border: 0, outline: 0,
              width: `${Math.max(2, (amount || '0').length)}ch`, textAlign: 'right',
              color: type === 'expense' ? 'var(--coral)' : 'var(--green)', padding: 0,
              letterSpacing: '-0.02em',
            }}/>
          <span style={{
            fontFamily: 'var(--mono)', fontSize: 20, color: 'var(--muted)', fontWeight: 500,
          }}>CHF</span>
        </div>

        <div style={{ marginBottom: 16 }}>
          <Input label="Description (optionnel)" value={desc} onChange={setDesc}
            placeholder="Migros, Coop, café…" />
        </div>

        <div style={{ marginBottom: 24 }}>
          <div style={lblStyle}>Date</div>
          <div style={{ display: 'flex', gap: 8, alignItems: 'center', flexWrap: 'wrap' }}>
            {[
              { label: "Aujourd'hui", value: effectiveTodayStr },
              { label: 'Hier', value: yesterdayStr },
            ].map(({ label, value }) => (
              <button key={label} onClick={() => setDate(value)} style={{
                padding: '9px 14px', borderRadius: 999,
                background: date === value ? 'var(--ink)' : 'var(--surface)',
                color: date === value ? 'var(--bg)' : 'var(--ink)',
                border: '1px solid ' + (date === value ? 'var(--ink)' : 'var(--border)'),
                fontSize: 13, fontWeight: 500, cursor: 'pointer',
              }}>{label}</button>
            ))}
            <input type="date" value={date} onChange={e => setDate(e.target.value)} style={{
              padding: '8px 12px', borderRadius: 12,
              border: '1px solid var(--border)',
              background: 'var(--surface)', color: 'var(--ink)',
              fontSize: 13, fontFamily: 'var(--mono)',
            }} />
          </div>
        </div>

        </div>
        <div style={{
          padding: '14px 28px 24px', flexShrink: 0,
          borderTop: '1px solid var(--border)',
          display: 'flex', gap: 10, justifyContent: 'flex-end',
          background: 'var(--surface)', borderRadius: '0 0 16px 16px',
        }}>
          <Button variant="ghost" onClick={onClose}>Annuler</Button>
          <Button disabled={!canSave} onClick={() => onSave({
            type, amount: +amount, categoryId: catId, description: desc, date,
          })}>Ajouter</Button>
        </div>
      </div>
      </div>
    </>
  );
}

// ────────────────────────────────────────────────────────────
// ANALYSE ANNUELLE
// ────────────────────────────────────────────────────────────
function AnnualScreen({ allTransactions, income, selectedYear }) {
  const yearTx = allTransactions.filter(tx => tx.date && tx.date.startsWith(String(selectedYear)));

  const totalIncome  = yearTx.filter(t => t.amount > 0).reduce((s, t) => s + t.amount, 0);
  const totalExpense = Math.abs(yearTx.filter(t => t.amount < 0).reduce((s, t) => s + t.amount, 0));
  const savingsRate  = totalIncome > 0 ? Math.round(((totalIncome - totalExpense) / totalIncome) * 100) : 0;

  // Dépenses par mois (jan=0 … déc=11)
  const monthlyExpenses = Array.from({ length: 12 }, (_, i) => {
    const m = String(i + 1).padStart(2, '0');
    const key = `${selectedYear}-${m}`;
    return yearTx
      .filter(t => t.date.startsWith(key) && t.amount < 0)
      .reduce((s, t) => s + Math.abs(t.amount), 0);
  });
  const maxMonthly = Math.max(...monthlyExpenses, 1);

  const monthNames = ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun', 'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc'];

  // Top catégories de l'année
  const catTotals = {};
  yearTx.filter(t => t.amount < 0).forEach(t => {
    catTotals[t.categoryId] = (catTotals[t.categoryId] || 0) + Math.abs(t.amount);
  });
  const topCats = Object.entries(catTotals)
    .sort((a, b) => b[1] - a[1])
    .slice(0, 6)
    .map(([id, total]) => ({ cat: CATEGORIES.find(c => c.id === id) || { label: id, emoji: '✦', color: '#9AA0A6' }, total }));

  return (
    <div className="fade-in" style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>

      {/* §01 Résumé annuel */}
      <section>
        <SectionLabel num="01" title={`Résumé ${selectedYear}`} />
        <Card padding={0}>
          <div className="annual-summary" style={{
            display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)',
            padding: '24px 28px', gap: 24,
            borderBottom: '1px solid var(--border)',
          }}>
            {[
              { label: 'Revenus', amount: totalIncome, tone: 'positive' },
              { label: 'Dépenses', amount: -totalExpense, tone: 'negative' },
              { label: "Taux d'investissement", amount: null, extra: savingsRate + '%', tone: savingsRate >= 0 ? 'positive' : 'negative' },
            ].map(({ label, amount, extra, tone }) => (
              <div key={label} style={{ padding: '8px 8px 18px', minWidth: 0 }}>
                <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: 8 }}>{label}</div>
                <div style={{
                  fontFamily: extra ? 'var(--mono)' : 'var(--mono)',
                  fontSize: 'clamp(18px, 1.85vw, 24px)', fontWeight: 600,
                  color: tone === 'positive' ? 'var(--green)' : tone === 'negative' ? 'var(--coral)' : 'var(--ink)',
                  letterSpacing: '-0.01em', lineHeight: 1.05, whiteSpace: 'nowrap',
                }}>
                  {extra || (amount < 0 ? '−' : '') + fmtCHF(Math.abs(amount))}
                  {!extra && <span style={{ fontFamily: 'var(--mono)', fontSize: 11, color: 'var(--muted)', marginLeft: 6, fontWeight: 500 }}>CHF</span>}
                </div>
              </div>
            ))}
          </div>
        </Card>
      </section>

      {/* §02 Évolution mensuelle */}
      <section>
        <SectionLabel num="02" title="Dépenses par mois" />
        <Card padding={24}>
          {yearTx.length === 0 ? (
            <div style={{ textAlign: 'center', color: 'var(--muted)', padding: '32px 0', fontSize: 14 }}>
              Aucune transaction en {selectedYear}.
            </div>
          ) : (
            <div style={{ display: 'flex', alignItems: 'flex-end', gap: 6, height: 140 }}>
              {monthlyExpenses.map((val, i) => (
                <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4 }}>
                  <div style={{ fontSize: 9, fontFamily: 'var(--mono)', color: 'var(--muted)', whiteSpace: 'nowrap' }}>
                    {val > 0 ? fmtCHFnoDec(Math.round(val)) : ''}
                  </div>
                  <div style={{
                    width: '100%', borderRadius: 4,
                    height: val > 0 ? Math.max(4, Math.round((val / maxMonthly) * 100)) + 'px' : '2px',
                    background: val > 0 ? 'var(--coral)' : 'var(--surface-2)',
                    transition: 'height 0.3s',
                  }} />
                  <div style={{ fontSize: 10, color: 'var(--muted)', fontFamily: 'var(--mono)' }}>{monthNames[i]}</div>
                </div>
              ))}
            </div>
          )}
        </Card>
      </section>

      {/* §03 Top catégories */}
      <section>
        <SectionLabel num="03" title="Top catégories" />
        <Card padding={24}>
          {topCats.length === 0 ? (
            <div style={{ textAlign: 'center', color: 'var(--muted)', padding: '16px 0', fontSize: 14 }}>Aucune dépense cette année.</div>
          ) : topCats.map(({ cat, total }, i) => (
            <div key={cat.id || i} style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: i < topCats.length - 1 ? 14 : 0 }}>
              <div style={{
                width: 32, height: 32, borderRadius: 8, background: 'var(--surface-2)',
                display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 15, flexShrink: 0,
              }}>{cat.emoji}</div>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)', marginBottom: 4 }}>{cat.label}</div>
                <div style={{ height: 4, background: 'var(--surface-2)', borderRadius: 999, overflow: 'hidden' }}>
                  <div style={{ width: `${Math.min(100, (total / (topCats[0].total || 1)) * 100)}%`, height: '100%', background: cat.color || 'var(--green)', borderRadius: 999 }} />
                </div>
              </div>
              <div style={{ fontFamily: 'var(--mono)', fontSize: 13, fontWeight: 600, color: 'var(--ink)', whiteSpace: 'nowrap' }}>
                {fmtCHF(total)} <span style={{ fontSize: 10, color: 'var(--muted)' }}>CHF</span>
              </div>
            </div>
          ))}
        </Card>
      </section>
    </div>
  );
}

// ────────────────────────────────────────────────────────────
// ASSURANCES
// ────────────────────────────────────────────────────────────
function InsurancesScreen() {
  const [insurances, setInsurances] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [modalOpen, setModalOpen] = React.useState(false);

  React.useEffect(() => {
    const load = async () => {
      const { data: { user } } = await window.db.auth.getUser();
      if (!user) { setLoading(false); return; }
      const { data } = await window.db
        .from('insurances')
        .select('*, insurance_history(*)')
        .eq('user_id', user.id)
        .order('next_due_date', { ascending: true });
      setInsurances(data || []);
      setLoading(false);
    };
    load();
  }, []);

  const handleDelete = async (id) => {
    const { data: { user } } = await window.db.auth.getUser();
    if (!user) return;
    await window.db.from('insurances').delete().eq('id', id).eq('user_id', user.id);
    setInsurances(prev => prev.filter(i => i.id !== id));
  };

  const annualTotal = insurances.reduce((s, ins) => {
    return s + (ins.frequency === 'mensuel' ? ins.amount * 12 : ins.amount);
  }, 0);

  const daysUntil = (dateStr) => {
    if (!dateStr) return null;
    const diff = Math.ceil((new Date(dateStr) - new Date()) / (1000 * 60 * 60 * 24));
    return diff;
  };

  const dueBadge = (dateStr) => {
    const d = daysUntil(dateStr);
    if (d === null) return null;
    if (d < 0) return { label: 'Passé', color: 'var(--muted)' };
    if (d === 0) return { label: 'Aujourd\'hui', color: 'var(--coral)' };
    if (d <= 7) return { label: `Dans ${d}j`, color: 'var(--coral)' };
    if (d <= 30) return { label: `Dans ${d}j`, color: 'var(--yellow)' };
    return { label: `Dans ${d}j`, color: 'var(--muted)' };
  };

  return (
    <div className="fade-in" style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>

      {/* §01 Résumé */}
      <section>
        <SectionLabel num="01" title="Vue d'ensemble" action={
          <Button size="sm" icon={Icon.plus(14)} onClick={() => setModalOpen(true)}>Ajouter</Button>
        } />
        <Card padding={0}>
          <div style={{ padding: '24px 28px', display: 'flex', gap: 32, flexWrap: 'wrap' }}>
            <div>
              <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: 8 }}>Coût annuel estimé</div>
              <div style={{ fontFamily: 'var(--mono)', fontSize: 28, fontWeight: 600, color: 'var(--ink)' }}>
                {fmtCHF(annualTotal)} <span style={{ fontSize: 12, color: 'var(--muted)' }}>CHF/an</span>
              </div>
            </div>
            <div>
              <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--muted)', textTransform: 'uppercase', letterSpacing: '0.04em', marginBottom: 8 }}>Assurances</div>
              <div style={{ fontFamily: 'var(--mono)', fontSize: 28, fontWeight: 600, color: 'var(--ink)' }}>{insurances.length}</div>
            </div>
          </div>
        </Card>
      </section>

      {/* §02 Liste */}
      <section>
        <SectionLabel num="02" title="Mes assurances" />
        {loading ? (
          <Card padding={24}><div style={{ color: 'var(--muted)', fontSize: 14 }}>Chargement…</div></Card>
        ) : insurances.length === 0 ? (
          <Card padding={48} style={{ textAlign: 'center' }}>
            <div style={{ fontSize: 32, marginBottom: 12 }}>☂️</div>
            <div style={{ fontSize: 15, fontWeight: 600, color: 'var(--ink)', marginBottom: 6 }}>Aucune assurance enregistrée</div>
            <div style={{ fontSize: 13, color: 'var(--muted)', marginBottom: 20 }}>Ajoute tes assurances pour suivre leur évolution de prix.</div>
            <Button onClick={() => setModalOpen(true)} icon={Icon.plus(15)}>Ajouter une assurance</Button>
          </Card>
        ) : (
          <Card padding={0}>
            {insurances.map((ins, i) => {
              const badge = dueBadge(ins.next_due_date);
              const history = (ins.insurance_history || []).sort((a, b) => b.year - a.year);
              const lastTwo = history.slice(0, 2);
              const variation = lastTwo.length === 2 ? ((lastTwo[0].amount - lastTwo[1].amount) / lastTwo[1].amount * 100).toFixed(1) : null;
              return (
                <div key={ins.id} style={{
                  padding: '18px 24px',
                  borderBottom: i < insurances.length - 1 ? '1px solid var(--border)' : 0,
                  display: 'flex', alignItems: 'center', gap: 16,
                }}>
                  <div style={{
                    width: 40, height: 40, borderRadius: 10, background: 'var(--surface-2)',
                    display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
                  }}>{Icon.umbrella(18)}</div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 14, fontWeight: 700, color: 'var(--ink)' }}>{ins.name}</div>
                    <div style={{ fontSize: 12, color: 'var(--muted)', marginTop: 2 }}>
                      {ins.insurer && <span>{ins.insurer} · </span>}
                      {ins.frequency === 'mensuel' ? `${fmtCHF(ins.amount)} CHF/mois` : `${fmtCHF(ins.amount)} CHF/an`}
                      {variation !== null && (
                        <span style={{ marginLeft: 8, color: +variation > 0 ? 'var(--coral)' : 'var(--green)', fontWeight: 600 }}>
                          {+variation > 0 ? '+' : ''}{variation}% vs {lastTwo[1].year}
                        </span>
                      )}
                    </div>
                  </div>
                  {badge && (
                    <div style={{ fontSize: 11, fontWeight: 600, color: badge.color, whiteSpace: 'nowrap', fontFamily: 'var(--mono)' }}>
                      {badge.label}
                    </div>
                  )}
                  <button onClick={() => handleDelete(ins.id)} title="Supprimer" style={{
                    width: 28, height: 28, borderRadius: 6, border: 0, cursor: 'pointer',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    background: 'transparent', color: 'var(--muted)',
                  }}>
                    {Icon.trash(14)}
                  </button>
                </div>
              );
            })}
          </Card>
        )}
      </section>

      {modalOpen && <AddInsuranceModal onClose={() => setModalOpen(false)} onSave={async (data) => {
        const { data: { user } } = await window.db.auth.getUser();
        if (!user) return;
        const { data: saved } = await window.db.from('insurances').insert({ ...data, user_id: user.id }).select('*, insurance_history(*)').single();
        if (saved) setInsurances(prev => [...prev, saved]);
        setModalOpen(false);
      }} />}
    </div>
  );
}

function AddInsuranceModal({ onClose, onSave }) {
  const [name, setName] = React.useState('');
  const [insurer, setInsurer] = React.useState('');
  const [amount, setAmount] = React.useState('');
  const [frequency, setFrequency] = React.useState('annuel');
  const [nextDue, setNextDue] = React.useState('');
  const [saving, setSaving] = React.useState(false);

  const canSave = name.trim() && +amount > 0;

  return (
    <>
      <div onClick={onClose} style={{
        position: 'fixed', inset: 0, background: 'rgba(15,18,15,0.5)',
        backdropFilter: 'blur(2px)', zIndex: 100,
        display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20,
      }}>
        <div onClick={e => e.stopPropagation()} style={{
          width: '100%', maxWidth: 460,
          maxHeight: 'calc(100vh - 40px)',
          display: 'flex', flexDirection: 'column',
          background: 'var(--surface)', borderRadius: 16,
          boxShadow: 'var(--shadow-lg)', border: '1px solid var(--border)',
        }}>
          <div style={{ overflow: 'auto', padding: 28, paddingBottom: 16 }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
              <h2 style={{ margin: 0, fontSize: 20, fontWeight: 700 }}>Nouvelle assurance</h2>
              <button onClick={onClose} style={{ width: 32, height: 32, borderRadius: 999, background: 'var(--surface-2)', border: 0, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--ink)' }}>{Icon.close(16)}</button>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
              <Input label="Nom de l'assurance" value={name} onChange={setName} placeholder="Assurance maladie, RC ménage…" />
              <Input label="Assureur (optionnel)" value={insurer} onChange={setInsurer} placeholder="CSS, Mobilière, Zurich…" />
              <div style={{ display: 'flex', gap: 12 }}>
                <div style={{ flex: 1 }}>
                  <Input label="Montant (CHF)" value={amount} onChange={v => setAmount(v.replace(/[^\d.]/g, ''))} placeholder="0.00" />
                </div>
                <div style={{ flex: 1 }}>
                  <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--muted)', marginBottom: 6 }}>Fréquence</div>
                  <div style={{ display: 'flex', gap: 4 }}>
                    {['mensuel', 'annuel'].map(f => (
                      <button key={f} onClick={() => setFrequency(f)} style={{
                        flex: 1, padding: '10px 8px', borderRadius: 8, border: '1px solid',
                        borderColor: frequency === f ? 'var(--ink)' : 'var(--border)',
                        background: frequency === f ? 'var(--ink)' : 'transparent',
                        color: frequency === f ? 'var(--bg)' : 'var(--ink)',
                        fontSize: 12, fontWeight: 600, cursor: 'pointer',
                      }}>{f.charAt(0).toUpperCase() + f.slice(1)}</button>
                    ))}
                  </div>
                </div>
              </div>
              <div>
                <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--muted)', marginBottom: 6 }}>Prochaine échéance (optionnel)</div>
                <input type="date" value={nextDue} onChange={e => setNextDue(e.target.value)} style={{
                  width: '100%', padding: '10px 14px', borderRadius: 8,
                  border: '1px solid var(--border)', background: 'var(--surface)',
                  color: 'var(--ink)', fontSize: 14, fontFamily: 'var(--mono)',
                  boxSizing: 'border-box',
                }} />
              </div>
            </div>
          </div>
          <div style={{
            padding: '14px 28px 24px', flexShrink: 0,
            borderTop: '1px solid var(--border)',
            display: 'flex', gap: 10, justifyContent: 'flex-end',
            background: 'var(--surface)', borderRadius: '0 0 16px 16px',
          }}>
            <Button variant="ghost" onClick={onClose}>Annuler</Button>
            <Button disabled={!canSave || saving} onClick={async () => {
              setSaving(true);
              try {
                await onSave({ name: name.trim(), insurer: insurer.trim() || null, amount: +amount, frequency, next_due_date: nextDue || null });
              } finally {
                setSaving(false);
              }
            }}>Enregistrer</Button>
          </div>
        </div>
      </div>
    </>
  );
}

Object.assign(window, {
  AuthScreen, OnboardingScreen, DashboardScreen, AppShell,
  TransactionsScreen, SettingsScreen, AddTransactionModal,
  AnnualScreen, InsurancesScreen,
});
