// Sisyphus — Screen components (screens1)
const { useState, useMemo, useEffect, useRef } = React;
const seed = window.SisyphusSeed;
const S = window.S;
const Icon = window.Icon;

// ─── AnimatedNumber ───────────────────────────────────────────────────────────
// Smoothly animates between numeric values. Accepts a `format` function.
function AnimatedNumber({ value, format, duration = 520, flashColor = true }) {
  const [display, setDisplay] = useState(() => value);
  const [flash,   setFlash]   = useState('');
  const rafRef  = useRef(null);
  const fromRef = useRef(value);

  useEffect(() => {
    if (fromRef.current === value) return;
    const from  = fromRef.current;
    if (flashColor && from !== value) {
      setFlash(value > from ? 'num-flash' : 'num-flash-red');
      setTimeout(() => setFlash(''), 700);
    }
    const start = performance.now();
    cancelAnimationFrame(rafRef.current);
    function step(now) {
      const t      = Math.min((now - start) / duration, 1);
      const eased  = 1 - Math.pow(1 - t, 3); // ease-out cubic
      const cur    = from + (value - from) * eased;
      setDisplay(cur);
      if (t < 1) { rafRef.current = requestAnimationFrame(step); }
      else        { setDisplay(value); fromRef.current = value; }
    }
    rafRef.current = requestAnimationFrame(step);
    return () => cancelAnimationFrame(rafRef.current);
  }, [value, duration]);

  const text = format ? format(display) : String(Math.round(display));
  return React.createElement('span', { className: flash, style: { fontVariantNumeric:'tabular-nums' } }, text);
}
window.AnimatedNumber = AnimatedNumber;


// ─── Primitives ───────────────────────────────────────────────────────────────
// ─── Reusable delete-confirmation modal ───────────────────────────────────────
function DeleteConfirmModal({ entry, onConfirm, onCancel }) {
  if (!entry) return null;
  return (
    <div onClick={onCancel} style={{ position:'fixed', inset:0, zIndex:1200, background:'rgba(5,3,13,0.78)', backdropFilter:'blur(10px)', display:'flex', alignItems:'center', justifyContent:'center', padding:20, animation:'fadeIn 0.15s' }}>
      <div onClick={e => e.stopPropagation()} style={{ width:'100%', maxWidth:340, background:'rgba(14,9,28,0.98)', border:'1px solid rgba(248,113,113,0.3)', borderRadius:18, padding:'24px 22px', boxShadow:'0 40px 80px rgba(0,0,0,0.7)', animation:'popIn 0.2s cubic-bezier(0.2,0.8,0.2,1)' }}>
        <div style={{ width:44, height:44, borderRadius:12, background:'rgba(248,113,113,0.1)', border:'1px solid rgba(248,113,113,0.25)', display:'flex', alignItems:'center', justifyContent:'center', margin:'0 auto 16px' }}>
          <Icon name="archive" size={20} style={{ color:'#f87171' }} />
        </div>
        <div style={{ textAlign:'center', marginBottom:14 }}>
          <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:16, fontWeight:600 }}>¿Eliminar esta entrada?</div>
          <div style={{ fontSize:12.5, color:'var(--text-3)', marginTop:6, lineHeight:1.5 }}>{entry.desc || entry.name || entry.label || 'Esta entrada será eliminada permanentemente.'}</div>
          {entry.amount && <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:18, fontWeight:700, color:'#f87171', marginTop:6 }}>$ {new Intl.NumberFormat('es-AR').format(Math.abs(entry.amount))}</div>}
        </div>
        <div style={{ display:'flex', gap:8 }}>
          <button onClick={onCancel} style={{ flex:1, padding:'11px 0', borderRadius:11, background:'rgba(255,255,255,0.05)', border:'1px solid var(--border)', color:'var(--text-2)', cursor:'pointer', fontFamily:'inherit', fontSize:13.5, fontWeight:600 }}>Cancelar</button>
          <button onClick={onConfirm} style={{ flex:1, padding:'11px 0', borderRadius:11, background:'rgba(248,113,113,0.12)', border:'1px solid rgba(248,113,113,0.3)', color:'#f87171', cursor:'pointer', fontFamily:'inherit', fontSize:13.5, fontWeight:700 }}>Eliminar</button>
        </div>
      </div>
    </div>
  );
}
window.DeleteConfirmModal = DeleteConfirmModal;

// ── EditMovModal ────────────────────────────────────────────────────────────
function EditMovModal({ entry, onSave, onCancel }) {
  if (!entry) return null;
  const seed = window.SisyphusSeed;
  const { useState: useEs, useEffect: useEe } = React;
  const [desc,   setDesc]   = useEs(entry.desc   || '');
  const [amount, setAmount] = useEs(String(Math.abs(entry.amount || 0)));
  const [cat,    setCat]    = useEs(entry.cat     || 'super');
  const [kind,   setKind]   = useEs(entry.kind    || 'variable');
  const [date,   setDate]   = useEs((entry.date   || '').slice(0,10));
  useEe(() => {
    setDesc(entry.desc || '');
    setAmount(String(Math.abs(entry.amount || 0)));
    setCat(entry.cat || 'super');
    setKind(entry.kind || 'variable');
    setDate((entry.date || '').slice(0,10));
  }, [entry?.id]);
  const cats = (seed?.categories || []).filter(c => c.group !== 'ahorro');
  const kinds = [
    { id:'variable', label:'Variable' }, { id:'fijo', label:'Fijo' },
    { id:'ingreso',  label:'Ingreso' }, { id:'ahorro', label:'Ahorro' },
  ];
  const amtNum = parseFloat(amount.replace(/\./g,'').replace(/,/g,'.')) || 0;
  const ready = desc.trim().length > 0 && amtNum > 0;
  function handleSave() {
    if (!ready) return;
    const sign = kind === 'ingreso' ? 1 : -1;
    onSave({ desc: desc.trim(), amount: sign * amtNum, cat, kind, date: date ? date + 'T12:00:00' : entry.date });
  }
  const pill = (active, color) => ({
    padding:'5px 11px', borderRadius:8, fontSize:12, fontWeight:600, cursor:'pointer', fontFamily:'inherit',
    background: active ? (color ? color+'22' : 'var(--accent-dim)') : 'rgba(255,255,255,0.04)',
    color: active ? (color || 'var(--accent-bright)') : 'var(--text-3)',
    border: `1px solid ${active ? (color ? color+'55' : 'var(--border-strong)') : 'var(--border)'}`,
    transition:'all 0.12s',
  });
  return (
    <div onClick={onCancel} style={{ position:'fixed', inset:0, zIndex:1200, background:'rgba(5,3,13,0.78)', backdropFilter:'blur(10px)', display:'flex', alignItems:'center', justifyContent:'center', padding:20, animation:'fadeIn 0.15s' }}>
      <div onClick={e => e.stopPropagation()} style={{ width:'100%', maxWidth:420, background:'rgba(14,9,28,0.98)', border:'1px solid var(--border-strong)', borderRadius:20, padding:'24px 22px 20px', boxShadow:'0 40px 80px rgba(0,0,0,0.7)', animation:'popIn 0.2s cubic-bezier(0.2,0.8,0.2,1)' }}>
        <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:18 }}>
          <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:17, fontWeight:600 }}>Editar movimiento</div>
          <button onClick={onCancel} style={{ background:'none', border:'none', color:'var(--text-3)', cursor:'pointer', padding:4 }}><Icon name="x" size={17} /></button>
        </div>
        {/* Description */}
        <div style={{ marginBottom:12 }}>
          <div style={{ fontSize:10.5, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:600, marginBottom:6 }}>Descripción</div>
          <input value={desc} onChange={e => setDesc(e.target.value)} onKeyDown={e => e.key === 'Enter' && handleSave()}
            style={{ width:'100%', padding:'9px 12px', borderRadius:10, background:'rgba(255,255,255,0.04)', border:'1px solid var(--border-strong)', color:'var(--text)', fontFamily:'inherit', fontSize:13.5, outline:'none', boxSizing:'border-box' }}
            onFocus={e => e.target.style.borderColor='var(--accent)'} onBlur={e => e.target.style.borderColor='var(--border-strong)'} />
        </div>
        {/* Amount + Date */}
        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:10, marginBottom:12 }}>
          <div>
            <div style={{ fontSize:10.5, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:600, marginBottom:6 }}>Monto</div>
            <div style={{ display:'flex', alignItems:'center', gap:4, padding:'8px 12px', borderRadius:10, background:'rgba(255,255,255,0.04)', border:'1px solid var(--border-strong)' }}>
              <span style={{ color:'var(--text-3)', fontSize:14, fontWeight:600 }}>$</span>
              <input type="text" inputMode="numeric" value={amount} onChange={e => setAmount(e.target.value)} onFocus={e => e.target.select()}
                style={{ flex:1, background:'transparent', border:'none', outline:'none', color:'var(--text)', fontFamily:'Space Grotesk, sans-serif', fontSize:16, fontWeight:600, fontVariantNumeric:'tabular-nums' }} />
            </div>
          </div>
          <div>
            <div style={{ fontSize:10.5, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:600, marginBottom:6 }}>Fecha</div>
            <input type="date" value={date} onChange={e => setDate(e.target.value)}
              style={{ width:'100%', padding:'8px 10px', borderRadius:10, background:'rgba(255,255,255,0.04)', border:'1px solid var(--border-strong)', color:'var(--text)', fontFamily:'inherit', fontSize:13, outline:'none', colorScheme:'dark', boxSizing:'border-box' }} />
          </div>
        </div>
        {/* Kind */}
        <div style={{ marginBottom:12 }}>
          <div style={{ fontSize:10.5, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:600, marginBottom:6 }}>Tipo</div>
          <div style={{ display:'flex', gap:5, flexWrap:'wrap' }}>
            {kinds.map(k => <button key={k.id} onClick={() => setKind(k.id)} style={pill(kind===k.id)}>{k.label}</button>)}
          </div>
        </div>
        {/* Category (only for non-ingreso) */}
        {kind !== 'ingreso' && (
          <div style={{ marginBottom:16 }}>
            <div style={{ fontSize:10.5, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:600, marginBottom:6 }}>Categoría</div>
            <div style={{ display:'flex', gap:5, flexWrap:'wrap', maxHeight:90, overflowY:'auto' }}>
              {cats.map(c => <button key={c.id} onClick={() => setCat(c.id)} style={pill(cat===c.id, c.color)}>{c.name}</button>)}
            </div>
          </div>
        )}
        {/* Actions */}
        <div style={{ display:'flex', gap:8 }}>
          <button onClick={onCancel} style={{ flex:1, padding:'11px 0', borderRadius:11, background:'rgba(255,255,255,0.05)', border:'1px solid var(--border)', color:'var(--text-2)', cursor:'pointer', fontFamily:'inherit', fontSize:13.5, fontWeight:600 }}>Cancelar</button>
          <button onClick={handleSave} disabled={!ready} style={{ flex:2, padding:'11px 0', borderRadius:11, background: ready ? 'var(--accent)' : 'var(--accent-dim)', color: ready ? 'var(--on-accent)' : 'var(--text-3)', border:'none', cursor: ready ? 'pointer' : 'default', fontFamily:'inherit', fontSize:13.5, fontWeight:700, transition:'all 0.13s' }}>Guardar cambios</button>
        </div>
      </div>
    </div>
  );
}
window.EditMovModal = EditMovModal;

function Card({ children, style = {}, padding = 18, className = '', onClick, ...rest }) {
  return (
    <div
      className={`card-hov ${className}`}
      onClick={onClick}
      style={{
        background:'var(--card)', border:'1px solid var(--border)',
        borderRadius:18, padding,
        boxShadow:'0 1px 0 rgba(255,255,255,0.03) inset, 0 8px 30px -10px rgba(0,0,0,0.45)',
        transition:'transform 0.18s, box-shadow 0.18s',
        cursor: onClick ? 'pointer' : undefined,
        ...style,
      }}
      {...rest}
    >
      {children}
    </div>
  );
}

function SectionHeader({ title, action, children }) {
  return (
    <div style={{ display:'flex', alignItems:'baseline', justifyContent:'space-between', padding:'0 4px 10px', gap:8 }}>
      <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:16.5, fontWeight:600, letterSpacing:'-0.01em' }}>{title}</div>
      {action
        ? <button onClick={action.onClick} style={{ background:'none', border:'none', color:'var(--accent-bright)', fontSize:12.5, fontWeight:500, cursor:'pointer', fontFamily:'inherit' }}>{action.label}</button>
        : children
      }
    </div>
  );
}

function CatChip({ cat, size = 24 }) {
  if (!cat) return null;
  return (
    <span style={{
      width:size, height:size, borderRadius: size <= 24 ? 7 : 9,
      background: cat.color+'24', border:`1px solid ${cat.color}40`, color:cat.color,
      display:'inline-flex', alignItems:'center', justifyContent:'center', flexShrink:0,
    }}>
      <Icon name={cat.icon} size={size * 0.6} strokeWidth={1.8} />
    </span>
  );
}

// ─── MiniCalendar ─────────────────────────────────────────────────────────────
// Custom date picker matching the app's dark aesthetic — replaces native inputs.
function MiniCalendar({ value, onChange }) {
  const parseDate = (v) => {
    if (!v) return new Date();
    if (v instanceof Date) { const d = new Date(v); d.setHours(0,0,0,0); return d; }
    const p = String(v).split('-').map(Number);
    return new Date(p[0], p[1]-1, p[2]);
  };
  const sel = parseDate(value);
  const [viewY, setViewY] = useState(sel.getFullYear());
  const [viewM, setViewM] = useState(sel.getMonth()); // 0-11
  const today = new Date(); today.setHours(0,0,0,0);
  const mNames = ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];
  const dNames = ['L','M','X','J','V','S','D'];
  const firstDow = (new Date(viewY, viewM, 1).getDay() + 6) % 7; // Mon=0
  const dim = new Date(viewY, viewM + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < firstDow; i++) cells.push(null);
  for (let d = 1; d <= dim; d++) cells.push(d);
  const prevM = () => { if (viewM === 0) { setViewY(y=>y-1); setViewM(11); } else setViewM(m=>m-1); };
  const nextM = () => { if (viewM === 11) { setViewY(y=>y+1); setViewM(0); } else setViewM(m=>m+1); };
  const isSel = (d) => { if (!d || !value) return false; const s=parseDate(value); return s.getFullYear()===viewY && s.getMonth()===viewM && s.getDate()===d; };
  const isTod = (d) => !!(d && today.getFullYear()===viewY && today.getMonth()===viewM && today.getDate()===d);
  const pick = (d) => {
    if (!d) return;
    const str = `${viewY}-${String(viewM+1).padStart(2,'0')}-${String(d).padStart(2,'0')}`;
    onChange(str, new Date(viewY, viewM, d));
  };
  const navBtn = (onClick, icon) => (
    <button onClick={onClick} style={{ width:26, height:26, borderRadius:7, background:'transparent', border:'1px solid var(--border)', color:'var(--text-2)', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', transition:'background 0.12s' }}
      onMouseEnter={e=>e.currentTarget.style.background='var(--accent-dim)'}
      onMouseLeave={e=>e.currentTarget.style.background='transparent'}
    ><Icon name={icon} size={11} strokeWidth={2.5} /></button>
  );
  return (
    <div style={{ userSelect:'none', minWidth:228 }}>
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:10 }}>
        {navBtn(prevM, 'chevLeft')}
        <div style={{ fontSize:12, fontWeight:600, color:'var(--text)' }}>{mNames[viewM]} {viewY}</div>
        {navBtn(nextM, 'chevRight')}
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'repeat(7, 1fr)', gap:3, marginBottom:4 }}>
        {dNames.map(n => <div key={n} style={{ textAlign:'center', fontSize:9, color:'var(--text-3)', fontWeight:700, letterSpacing:'0.06em', padding:'3px 0' }}>{n}</div>)}
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'repeat(7, 1fr)', gap:3 }}>
        {cells.map((d, i) => {
          const s = isSel(d), t = isTod(d);
          return (
            <button key={i} onClick={() => pick(d)} disabled={!d} style={{
              width:'100%', aspectRatio:'1/1', minHeight:30, borderRadius:7, fontSize:12, fontFamily:'inherit',
              background: s ? 'var(--accent)' : t ? 'var(--accent-dim)' : 'transparent',
              border: t && !s ? '1px solid rgba(167,139,250,0.5)' : '1px solid transparent',
              color: s ? 'var(--on-accent)' : d ? (t ? 'var(--accent-bright)' : 'var(--text)') : 'transparent',
              cursor: d ? 'pointer' : 'default', fontWeight: s ? 700 : 400,
              display:'flex', alignItems:'center', justifyContent:'center',
              transition:'background 0.1s',
            }}>{d || ''}</button>
          );
        })}
      </div>
    </div>
  );
}
window.MiniCalendar = MiniCalendar;

// ─── MiniRangeCalendar ────────────────────────────────────────────────────────
// Single-calendar range picker: first click = from, second click = to.
// Props: from (string YYYY-MM-DD | ''), to (string), onFrom, onTo
function MiniRangeCalendar({ from, to, onFrom, onTo }) {
  const parseDate = (v) => {
    if (!v) return null;
    const p = String(v).split('-').map(Number);
    return new Date(p[0], p[1]-1, p[2]);
  };

  const fromD = parseDate(from);
  const toD   = parseDate(to);

  const initView = fromD || new Date();
  const [viewY, setViewY] = useState(initView.getFullYear());
  const [viewM, setViewM] = useState(initView.getMonth());
  // picking: 'from' | 'to'  — cycle: if both set, restart from 'from'
  const [picking, setPicking] = useState('from');

  const today = new Date(); today.setHours(0,0,0,0);
  const mNames = ['Enero','Febrero','Marzo','Abril','Mayo','Junio','Julio','Agosto','Septiembre','Octubre','Noviembre','Diciembre'];
  const dNames = ['L','M','X','J','V','S','D'];
  const firstDow = (new Date(viewY, viewM, 1).getDay() + 6) % 7;
  const dim = new Date(viewY, viewM + 1, 0).getDate();
  const cells = [];
  for (let i = 0; i < firstDow; i++) cells.push(null);
  for (let d = 1; d <= dim; d++) cells.push(d);

  const prevM = () => { if (viewM === 0) { setViewY(y=>y-1); setViewM(11); } else setViewM(m=>m-1); };
  const nextM = () => { if (viewM === 11) { setViewY(y=>y+1); setViewM(0); } else setViewM(m=>m+1); };

  const cellDate = (d) => d ? new Date(viewY, viewM, d) : null;
  const toStr = (dt) => dt ? `${dt.getFullYear()}-${String(dt.getMonth()+1).padStart(2,'0')}-${String(dt.getDate()).padStart(2,'0')}` : '';

  const pick = (d) => {
    if (!d) return;
    const dt = cellDate(d);
    if (picking === 'from') {
      onFrom(toStr(dt));
      // Clear to if it's before the new from
      if (toD && dt > toD) onTo('');
      setPicking('to');
    } else {
      if (fromD && dt < fromD) {
        // Clicked before from: swap — set this as new from
        onFrom(toStr(dt));
        onTo('');
        setPicking('to');
      } else {
        onTo(toStr(dt));
        setPicking('from'); // reset cycle
      }
    }
  };

  const isFrom = (d) => { if (!d || !fromD) return false; const dt = cellDate(d); return dt.getTime() === fromD.getTime(); };
  const isTo   = (d) => { if (!d || !toD)   return false; const dt = cellDate(d); return dt.getTime() === toD.getTime(); };
  const inRange = (d) => {
    if (!d || !fromD || !toD) return false;
    const dt = cellDate(d);
    return dt > fromD && dt < toD;
  };
  const isTod  = (d) => !!(d && today.getFullYear()===viewY && today.getMonth()===viewM && today.getDate()===d);

  const navBtn = (onClick, icon) => (
    <button onClick={onClick} style={{ width:26, height:26, borderRadius:7, background:'transparent', border:'1px solid var(--border)', color:'var(--text-2)', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', transition:'background 0.12s' }}
      onMouseEnter={e=>e.currentTarget.style.background='var(--accent-dim)'}
      onMouseLeave={e=>e.currentTarget.style.background='transparent'}
    ><Icon name={icon} size={11} strokeWidth={2.5} /></button>
  );

  return (
    <div style={{ userSelect:'none' }}>
      {/* Hint row */}
      <div style={{ display:'flex', gap:8, marginBottom:10, fontSize:10.5, color:'var(--text-3)', fontWeight:600, textTransform:'uppercase', letterSpacing:'0.08em' }}>
        <span style={{ flex:1, padding:'4px 8px', borderRadius:7, background: picking==='from' ? 'var(--accent-dim)' : 'rgba(255,255,255,0.04)', border:`1px solid ${picking==='from' ? 'var(--border-strong)' : 'var(--border)'}`, color: picking==='from' ? 'var(--accent-bright)' : 'var(--text-3)', textAlign:'center' }}>
          Desde{from ? `: ${from.slice(8)}.${from.slice(5,7)}` : ' —'}
        </span>
        <span style={{ flex:1, padding:'4px 8px', borderRadius:7, background: picking==='to' ? 'var(--accent-dim)' : 'rgba(255,255,255,0.04)', border:`1px solid ${picking==='to' ? 'var(--border-strong)' : 'var(--border)'}`, color: picking==='to' ? 'var(--accent-bright)' : 'var(--text-3)', textAlign:'center' }}>
          Hasta{to ? `: ${to.slice(8)}.${to.slice(5,7)}` : ' —'}
        </span>
      </div>
      {/* Month nav */}
      <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:10 }}>
        {navBtn(prevM, 'chevLeft')}
        <div style={{ fontSize:12, fontWeight:600, color:'var(--text)' }}>{mNames[viewM]} {viewY}</div>
        {navBtn(nextM, 'chevRight')}
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'repeat(7, 1fr)', gap:2, marginBottom:3 }}>
        {dNames.map(n => <div key={n} style={{ textAlign:'center', fontSize:9, color:'var(--text-3)', fontWeight:700, letterSpacing:'0.06em', padding:'2px 0' }}>{n}</div>)}
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'repeat(7, 1fr)', gap:2 }}>
        {cells.map((d, i) => {
          const sel = isFrom(d) || isTo(d);
          const range = inRange(d);
          const t = isTod(d);
          return (
            <button key={i} onClick={() => pick(d)} disabled={!d} style={{
              width:'100%', aspectRatio:'1/1', borderRadius:6, fontSize:12, fontFamily:'inherit',
              background: sel ? 'var(--accent)' : range ? 'rgba(139,92,246,0.14)' : t ? 'var(--accent-dim)' : 'transparent',
              border: t && !sel ? '1px solid rgba(167,139,250,0.5)' : range ? '1px solid rgba(139,92,246,0.22)' : '1px solid transparent',
              color: sel ? 'var(--on-accent)' : d ? (range ? 'var(--accent-bright)' : t ? 'var(--accent-bright)' : 'var(--text)') : 'transparent',
              cursor: d ? 'pointer' : 'default', fontWeight: sel ? 700 : 400,
              display:'flex', alignItems:'center', justifyContent:'center',
              transition:'background 0.1s',
            }}>{d || ''}</button>
          );
        })}
      </div>
      {/* Reset */}
      {(from || to) && (
        <button onClick={() => { onFrom(''); onTo(''); setPicking('from'); }} style={{ marginTop:8, width:'100%', padding:'5px 0', borderRadius:7, background:'transparent', border:'1px solid var(--border)', color:'var(--text-3)', fontSize:11, fontWeight:600, cursor:'pointer', fontFamily:'inherit', transition:'color 0.12s, border-color 0.12s' }}
          onMouseEnter={e=>{e.currentTarget.style.color='var(--text)';e.currentTarget.style.borderColor='var(--border-strong)';}}
          onMouseLeave={e=>{e.currentTarget.style.color='var(--text-3)';e.currentTarget.style.borderColor='var(--border)';}}
        >Limpiar rango</button>
      )}
    </div>
  );
}
window.MiniRangeCalendar = MiniRangeCalendar;

function StatusBadge({ state, isPaid }) {
  if (isPaid) return (
    <span style={{ display:'inline-flex', alignItems:'center', gap:4, fontSize:10.5, fontWeight:700, color:'#4ade80', textTransform:'uppercase', letterSpacing:'0.08em', animation:'checkPop 0.3s ease' }}>
      <Icon name="check" size={12} strokeWidth={2.5} /> Pagado
    </span>
  );
  const color = state === 'urgent' || state === 'late' ? 'var(--red)' : state === 'warn' ? 'var(--amber)' : 'var(--text-3)';
  return <span style={{ fontSize:10.5, fontWeight:600, color, textTransform:'uppercase', letterSpacing:'0.08em' }}>{S.dueLabel(/* passed as prop below */)}</span>;
}

// ─── HOME ─────────────────────────────────────────────────────────────────────
function HomeScreen({ ccy, onNav, onOpenAdd, onCcy, isDesktop, paidPagos, onTogglePaid, spentState, budgets, extraIngresos = 0, userName, selectedMonthIdx, onSelectMonth, cuotasGrupos = [], movimientos = [], confirmedIngs = {}, onConfirmIngreso, metas = [], onAddMeta, onUpdateMeta, onDeleteMeta }) {
  const [monthDropOpen, setMonthDropOpen] = useState(false);
  const [dropPos,       setDropPos]       = useState({ top: 60, left: 0 });
  const [hideSaldo,     setHideSaldo]     = useState(() => localStorage.getItem('sis_hide_saldo') === 'true');
  const toggleHide = () => setHideSaldo(v => { localStorage.setItem('sis_hide_saldo', !v); return !v; });
  const monthBtnRef = useRef(null);

  // Month-close confirmation modal states
  const [closeModal,     setCloseModal]     = useState(false);
  const [closeStats,     setCloseStats]     = useState(null);
  const [closeSending,   setCloseSending]   = useState(false);
  const [closeDone,      setCloseDone]      = useState(false);

  // Month archive from localStorage
  const [historyKey, setHistoryKey] = useState(0); // bump to re-read after close
  const history = useMemo(() => {
    try { return window.MonthClose?.getHistory() || []; } catch { return []; }
  }, [historyKey]);

  // Are we viewing a past archived month?
  const isArchived = selectedMonthIdx !== null && selectedMonthIdx !== undefined && history[selectedMonthIdx];
  const arch       = isArchived ? history[selectedMonthIdx] : null;

  // Open dropdown — compute fixed position from button rect
  function openDrop() {
    if (monthBtnRef.current) {
      const r = monthBtnRef.current.getBoundingClientRect();
      setDropPos({ top: r.bottom + 6, left: r.left });
    }
    setMonthDropOpen(o => !o);
  }

  // Close dropdown on outside click (listen on fixed panel div id)
  useEffect(() => {
    if (!monthDropOpen) return;
    const fn = e => {
      const panel = document.getElementById('month-drop-panel');
      if (!panel?.contains(e.target) && !monthBtnRef.current?.contains(e.target)) setMonthDropOpen(false);
    };
    document.addEventListener('mousedown', fn);
    return () => document.removeEventListener('mousedown', fn);
  }, [monthDropOpen]);

  // Open close-month confirmation modal
  function openCloseModal() {
    setMonthDropOpen(false);
    const stats = window.MonthClose?.buildStats?.() || null;
    setCloseStats(stats);
    setCloseDone(false);
    setCloseModal(true);
  }

  // Execute month close
  async function confirmClose() {
    setCloseSending(true);
    try {
      await window.MonthClose?.cerrarMes(() => {});
    } catch(e) { console.warn('[MonthClose]', e); }
    setCloseSending(false);
    setCloseDone(true);
    setHistoryKey(k => k + 1); // refresh history list
  }

  // ── Data: use archive snapshot or live state ─────────────────────
  const todayD = new Date();
  const conv   = n => ccy === 'USD' ? n / seed.fxBlue : n;
  const fmt    = n => S.fmtMoney(conv(n), ccy);

  // Live totals (current month)
  const tLive = S.monthlyTotals(spentState, budgets, extraIngresos);
  const rLive = S.runway(spentState, budgets, extraIngresos);

  // Archived / current values
  const ingTotal    = arch ? arch.ingTotal  : tLive.ingTotal;
  const egrTotal    = arch ? arch.egrTotal  : tLive.egrTotal;
  const ahoTotal    = arch ? arch.ahoTotal  : tLive.ahoTotal;
  const neto        = arch ? arch.neto      : (tLive.ingTotal - tLive.egrTotal - tLive.ahoTotal);
  const budgetTotal = tLive.budgetTotal; // always from live settings
  const restante    = arch ? arch.neto : rLive.restante;

  const monthName   = arch
    ? (arch.monthName || '').replace(/^\w/, c => c.toUpperCase())
    : todayD.toLocaleDateString('es-AR', { month:'long', year:'numeric' }).replace(' de ', ' · ').replace(/^\w/, c => c.toUpperCase());

  const monthPct       = arch ? 1 : todayD.getDate() / rLive.daysInMonth;
  const forecastPositive = arch ? neto >= 0 : rLive.forecastNeto >= 0;
  const forecastNeto   = arch ? neto : rLive.forecastNeto;

  // Distribution: archived catSpent or live
  const dist = useMemo(() => {
    if (arch) {
      return seed.categories.map(c => {
        const spent  = (arch.catSpent?.[c.id] || 0);
        const budget = c.budget;
        return { ...c, spent, budget, pct: budget > 0 ? spent / budget : 0 };
      }).sort((a,b) => b.spent - a.spent);
    }
    return S.distribucion(spentState, budgets).sort((a,b) => b.spent - a.spent);
  }, [arch, spentState, budgets]);

  const budgetUsedPct = budgetTotal > 0 ? Math.round(egrTotal / budgetTotal * 100) : 0;
  const kpis = [
    { l:'Ingresos',     v: ingTotal,    delta: arch ? arch.monthName : '+5%',               icon:'arrowDown', color:'var(--accent-bright)' },
    { l:'Egresos',      v: egrTotal,    delta:`${budgetUsedPct}% del presup`,               icon:'arrowUp',   color:'var(--red)'           },
    { l:'Ahorro',       v: ahoTotal,    delta: arch ? (neto >= 0 ? '✓ Positivo' : '⚠ Negativo') : '+18%', icon:'shield', color:'var(--accent)' },
    { l:'Presupuesto',  v: budgetTotal, delta:`Quedan ${fmt(budgetTotal - egrTotal)}`,       icon:'sliders', color:'var(--text-3)' },
  ];

  // ── Month selector button (dropdown rendered as fixed portal below) ──
  const monthSelector = (
    <button ref={monthBtnRef} onClick={openDrop} style={{
      display:'inline-flex', alignItems:'center', gap:5,
      fontSize:11.5, fontWeight:700, letterSpacing:'0.12em', textTransform:'uppercase',
      color: isArchived ? 'var(--accent-bright)' : 'var(--text-3)',
      background: isArchived ? 'var(--accent-dim)' : 'transparent',
      border: `1px solid ${isArchived ? 'var(--border-strong)' : 'transparent'}`,
      borderRadius:8, padding:'3px 9px 3px 6px', cursor:'pointer',
      fontFamily:'inherit',
      transition:'background 0.14s, color 0.14s, border-color 0.14s',
    }}>
      <Icon name="chevDown" size={11} strokeWidth={2.5} />
      {isArchived ? arch.monthName : monthName}
    </button>
  );

  // ── Archive banner ───────────────────────────────────────────────
  const archiveBanner = isArchived ? (
    <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', gap:12, padding:'10px 14px', borderRadius:12, background:'rgba(167,139,250,0.08)', border:'1px solid rgba(167,139,250,0.22)' }}>
      <div style={{ display:'flex', alignItems:'center', gap:8 }}>
        <Icon name="calendar" size={14} style={{ color:'var(--accent-bright)', flexShrink:0 }} />
        <div style={{ fontSize:12.5, color:'var(--text-2)' }}>
          Estás viendo el resumen de <strong style={{ color:'var(--accent-bright)', textTransform:'capitalize' }}>{arch.monthName}</strong> — mes archivado.
        </div>
      </div>
      <button onClick={() => onSelectMonth && onSelectMonth(null)} style={{ padding:'5px 11px', borderRadius:8, background:'var(--accent-dim)', border:'1px solid var(--border-strong)', color:'var(--accent-bright)', fontSize:11.5, fontWeight:600, cursor:'pointer', fontFamily:'inherit', whiteSpace:'nowrap', flexShrink:0 }}>
        Volver al actual
      </button>
    </div>
  ) : null;

  const upcoming = seed.pagos;

  // ── Fixed-position dropdown panel (above everything) ─────────────
  const monthDropPanel = monthDropOpen ? (
    <div id="month-drop-panel" style={{
      position:'fixed', top: dropPos.top, left: dropPos.left, zIndex:8000,
      minWidth:230, background:'#0c0818',
      border:'1px solid var(--border-strong)', borderRadius:14,
      padding:'4px', boxShadow:'0 24px 64px rgba(0,0,0,0.85)',
      animation:'fadeSlide 0.12s ease',
    }}>
      {/* Current month */}
      <button onClick={() => { onSelectMonth && onSelectMonth(null); setMonthDropOpen(false); }} style={{
        width:'100%', textAlign:'left', padding:'9px 12px', borderRadius:10,
        background: !isArchived ? 'var(--accent-dim)' : 'transparent',
        color: !isArchived ? 'var(--accent-bright)' : 'var(--text)',
        border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:13, fontWeight: !isArchived ? 600 : 400,
        display:'flex', alignItems:'center', justifyContent:'space-between',
      }}
        onMouseEnter={e => { if(isArchived) e.currentTarget.style.background='rgba(255,255,255,0.05)'; }}
        onMouseLeave={e => { if(isArchived) e.currentTarget.style.background='transparent'; }}
      >
        <span>Mes actual</span>
        <span style={{ fontSize:10, padding:'2px 7px', borderRadius:999, background: !isArchived ? 'var(--accent)' : 'rgba(167,139,250,0.15)', color: !isArchived ? 'var(--on-accent)' : 'var(--text-3)', fontWeight:700 }}>LIVE</span>
      </button>

      {/* Archived months */}
      {history.length > 0 && <div style={{ height:1, background:'var(--border)', margin:'2px 8px' }} />}
      {history.length === 0 && (
        <div style={{ padding:'10px 12px', fontSize:12, color:'var(--text-3)', textAlign:'center', lineHeight:1.5 }}>
          Sin meses archivados.<br/>Cerrá el mes desde aquí ↓
        </div>
      )}
      {history.slice().reverse().map((m, ri) => {
        const realIdx = history.length - 1 - ri;
        const active  = selectedMonthIdx === realIdx;
        return (
          <button key={realIdx} onClick={() => { onSelectMonth && onSelectMonth(realIdx); setMonthDropOpen(false); }} style={{
            width:'100%', textAlign:'left', padding:'9px 12px', borderRadius:10,
            background: active ? 'var(--accent-dim)' : 'transparent',
            color: active ? 'var(--accent-bright)' : 'var(--text-2)',
            border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:13, fontWeight: active ? 600 : 400,
            display:'flex', alignItems:'center', justifyContent:'space-between',
          }}
            onMouseEnter={e => { if(!active) e.currentTarget.style.background='rgba(255,255,255,0.05)'; }}
            onMouseLeave={e => { if(!active) e.currentTarget.style.background='transparent'; }}
          >
            <span style={{ textTransform:'capitalize' }}>{m.monthName}</span>
            <span style={{ fontSize:12, color: m.neto >= 0 ? 'var(--accent-bright)' : 'var(--red)', fontWeight:600 }}>{S.fmtMoney(conv(m.neto), ccy)}</span>
          </button>
        );
      })}

      {/* Divider + close month action */}
      <div style={{ height:1, background:'var(--border)', margin:'2px 8px' }} />
      <button onClick={openCloseModal} style={{
        width:'100%', textAlign:'left', padding:'10px 12px', borderRadius:10,
        background:'rgba(248,113,113,0.07)', color:'var(--red)',
        border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:13, fontWeight:600,
        display:'flex', alignItems:'center', gap:8,
        transition:'background 0.12s',
      }}
        onMouseEnter={e => e.currentTarget.style.background='rgba(248,113,113,0.14)'}
        onMouseLeave={e => e.currentTarget.style.background='rgba(248,113,113,0.07)'}
      >
        <Icon name="check" size={13} strokeWidth={2.5} />
        Cerrar el mes actual
      </button>
    </div>
  ) : null;

  // ── Month-close confirmation modal ───────────────────────────────
  const closeMonthModal = closeModal ? (() => {
    const st = closeStats;
    const fmtN = n => S.fmtMoney(n, 'ARS');
    const netoPos = st ? st.neto >= 0 : true;
    const topCats = st ? st.cats.slice().sort((a,b) => b.spent - a.spent).slice(0,3) : [];

    // Simple inline tips
    const tips = [];
    if (st) {
      const savPct = st.ingTotal > 0 ? Math.round((st.ahoTotal / st.ingTotal) * 100) : 0;
      if (savPct >= 20) tips.push('💜 Tasa de ahorro del ' + savPct + '% — encima del objetivo del 20%. Excelente.');
      else tips.push('📈 Tasa de ahorro del ' + savPct + '%. El objetivo ideal es ≥ 20%.');
      if (st.overBudget?.length > 0)
        tips.push('⚠️ Excediste el presupuesto en ' + st.overBudget.map(c => c.name).join(', ') + '.');
      else
        tips.push('✅ No excediste ningún presupuesto este mes. Disciplina financiera real.');
      if (st.neto < 0)
        tips.push('🔴 Neto negativo: gastaste más de lo que ingresó. Revisá gastos fijos para el próximo mes.');
    }

    return (
      <div style={{ position:'fixed', inset:0, zIndex:9000, display:'flex', alignItems:'flex-end', justifyContent:'center', padding: isDesktop ? '0' : '0' }}
        onClick={e => { if(e.target === e.currentTarget && !closeSending) setCloseModal(false); }}
      >
        <div style={{ position:'fixed', inset:0, background:'rgba(5,3,13,0.72)', backdropFilter:'blur(8px)' }} />
        <div style={{
          position:'relative', zIndex:1,
          width: isDesktop ? 540 : '100%', maxWidth:540,
          maxHeight:'90dvh', overflowY:'auto',
          background:'#0f0b18', border:'1px solid var(--border-strong)',
          borderRadius: isDesktop ? 24 : '24px 24px 0 0',
          padding:'28px 24px 32px',
          boxShadow:'0 -8px 64px rgba(0,0,0,0.7)',
          animation: isDesktop ? 'slideUp 0.25s ease' : 'slideUp 0.25s ease',
          margin: isDesktop ? 'auto' : '0',
          alignSelf: isDesktop ? 'center' : 'flex-end',
        }}>
          {closeDone ? (
            /* ── Success state ── */
            <div style={{ textAlign:'center', padding:'16px 0' }}>
              <div style={{ width:64, height:64, borderRadius:20, background:'rgba(52,211,153,0.12)', border:'1px solid rgba(52,211,153,0.3)', display:'flex', alignItems:'center', justifyContent:'center', margin:'0 auto 16px', color:'#34d399' }}>
                <Icon name="check" size={28} strokeWidth={2} />
              </div>
              <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:22, fontWeight:600, marginBottom:8 }}>¡Mes cerrado!</div>
              <div style={{ fontSize:14, color:'var(--text-2)', lineHeight:1.55, marginBottom:24 }}>
                El resumen de <strong style={{ textTransform:'capitalize' }}>{st?.monthName}</strong> fue archivado.
                {window.GmailAPI?.isConnected() && <><br/>Se envió un resumen a tu correo.</>}
              </div>
              <div style={{ display:'flex', gap:10 }}>
                <button onClick={() => { setCloseModal(false); onSelectMonth && onSelectMonth(history.length - 1); }} style={{ flex:1, padding:'11px 0', borderRadius:12, background:'var(--accent-dim)', border:'1px solid var(--border-strong)', color:'var(--accent-bright)', fontFamily:'inherit', fontSize:13, fontWeight:600, cursor:'pointer' }}>
                  Ver mes cerrado
                </button>
                <button onClick={() => setCloseModal(false)} style={{ flex:1, padding:'11px 0', borderRadius:12, background:'transparent', border:'1px solid var(--border)', color:'var(--text-2)', fontFamily:'inherit', fontSize:13, cursor:'pointer' }}>
                  Cerrar
                </button>
              </div>
            </div>
          ) : (
            /* ── Confirmation state ── */
            <>
              <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:20 }}>
                <div>
                  <div style={{ fontSize:11, color:'var(--red)', textTransform:'uppercase', letterSpacing:'0.12em', fontWeight:700, marginBottom:4 }}>⚠ Confirmar cierre</div>
                  <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:20, fontWeight:600 }}>
                    Cerrar {st ? <span style={{ textTransform:'capitalize' }}>{st.monthName}</span> : 'el mes actual'}
                  </div>
                </div>
                <button onClick={() => setCloseModal(false)} style={{ width:32, height:32, borderRadius:9, background:'rgba(255,255,255,0.07)', border:'none', color:'var(--text-3)', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                  <Icon name="x" size={14} />
                </button>
              </div>

              {/* KPI summary */}
              {st && (
                <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:8, marginBottom:16 }}>
                  {[
                    { l:'Ingresos', v: st.ingTotal, c:'var(--accent-bright)' },
                    { l:'Egresos',  v: st.egrTotal, c:'var(--red)'           },
                    { l:'Ahorro',   v: st.ahoTotal, c:'var(--accent)'        },
                    { l:'Neto',     v: st.neto,     c: netoPos ? '#34d399' : 'var(--red)' },
                  ].map(k => (
                    <div key={k.l} style={{ padding:'12px 14px', borderRadius:12, background:'rgba(255,255,255,0.03)', border:'1px solid var(--border)' }}>
                      <div style={{ fontSize:10, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:600, marginBottom:4 }}>{k.l}</div>
                      <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:16, fontWeight:700, color:k.c, fontVariantNumeric:'tabular-nums' }}>{fmtN(k.v)}</div>
                    </div>
                  ))}
                </div>
              )}

              {/* Top 3 categories */}
              {topCats.length > 0 && (
                <div style={{ marginBottom:16 }}>
                  <div style={{ fontSize:10.5, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:600, marginBottom:8 }}>Top categorías del mes</div>
                  <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
                    {topCats.map(c => (
                      <div key={c.id} style={{ display:'flex', alignItems:'center', justifyContent:'space-between', padding:'8px 12px', borderRadius:10, background:'rgba(255,255,255,0.03)', border:'1px solid var(--border)' }}>
                        <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                          <div style={{ width:8, height:8, borderRadius:'50%', background: c.color || 'var(--accent)', flexShrink:0 }} />
                          <span style={{ fontSize:13, color:'var(--text-2)' }}>{c.name}</span>
                        </div>
                        <div style={{ display:'flex', alignItems:'center', gap:10 }}>
                          <div style={{ width:60, height:4, borderRadius:999, background:'rgba(255,255,255,0.06)', overflow:'hidden' }}>
                            <div style={{ height:'100%', width: Math.min(100, c.pct) + '%', background: c.over ? 'var(--red)' : (c.color || 'var(--accent)'), borderRadius:999 }} />
                          </div>
                          <span style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:13, fontWeight:600, color: c.over ? 'var(--red)' : 'var(--text)', minWidth:80, textAlign:'right', fontVariantNumeric:'tabular-nums' }}>{fmtN(c.spent)}</span>
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* Tips */}
              {tips.length > 0 && (
                <div style={{ padding:'14px 16px', borderRadius:12, background:'rgba(167,139,250,0.06)', border:'1px solid rgba(167,139,250,0.15)', marginBottom:20 }}>
                  <div style={{ fontSize:10.5, color:'var(--accent-bright)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700, marginBottom:10 }}>Tips para el próximo mes</div>
                  {tips.map((t, i) => (
                    <div key={i} style={{ fontSize:13, color:'var(--text-2)', lineHeight:1.6, marginBottom: i < tips.length-1 ? 6 : 0 }}>{t}</div>
                  ))}
                </div>
              )}

              <div style={{ padding:'12px 16px', borderRadius:12, background:'rgba(248,113,113,0.06)', border:'1px solid rgba(248,113,113,0.2)', marginBottom:20, fontSize:13, color:'rgba(248,113,113,0.8)', lineHeight:1.5 }}>
                Esta acción archivará los datos del mes. No podrás deshacer esto.
              </div>

              <div style={{ display:'flex', gap:10 }}>
                <button onClick={confirmClose} disabled={closeSending} style={{
                  flex:1, padding:'13px 0', borderRadius:12,
                  background: closeSending ? 'var(--accent-dim)' : 'var(--accent)',
                  color: closeSending ? 'var(--accent-bright)' : 'var(--on-accent)',
                  border: closeSending ? '1px solid var(--border-strong)' : 'none',
                  fontFamily:'inherit', fontSize:14, fontWeight:600, cursor: closeSending ? 'default' : 'pointer',
                  display:'flex', alignItems:'center', justifyContent:'center', gap:8,
                  transition:'all 0.15s',
                }}>
                  {closeSending
                    ? <><span style={{ display:'inline-block', width:14, height:14, border:'2px solid currentColor', borderTopColor:'transparent', borderRadius:'50%', animation:'spin 0.8s linear infinite' }} /> Cerrando...</>
                    : <><Icon name="check" size={15} strokeWidth={2.5} /> Confirmar y cerrar el mes</>
                  }
                </button>
                <button onClick={() => setCloseModal(false)} disabled={closeSending} style={{ padding:'13px 18px', borderRadius:12, background:'transparent', border:'1px solid var(--border)', color:'var(--text-2)', fontFamily:'inherit', fontSize:14, cursor:'pointer' }}>
                  Cancelar
                </button>
              </div>
            </>
          )}
        </div>
      </div>
    );
  })() : null;

  // ── Hero card (shared between mobile + desktop) ──────────────────
  const heroCard = (
    <Card padding={0} style={{ overflow:'hidden', position:'relative' }}>
      <div style={{ position:'absolute', inset:0, background:'radial-gradient(120% 80% at 0% 0%, rgba(167,139,250,0.22), transparent 55%), radial-gradient(120% 80% at 100% 100%, rgba(99,102,241,0.18), transparent 55%)', pointerEvents:'none' }} />
      <div style={{ position:'relative', padding:'20px 20px 18px' }}>
        <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:12 }}>
          <div style={{ display:'flex', alignItems:'center', gap:8 }}>
            <div style={{ width:6, height:6, borderRadius:'50%', background: isArchived ? 'var(--text-3)' : 'var(--accent)', boxShadow: isArchived ? 'none' : '0 0 10px var(--accent-glow)' }} />
            <div style={{ fontSize:11.5, color:'var(--text-2)', textTransform:'uppercase', letterSpacing:'0.14em', fontWeight:600 }}>{isArchived ? 'Quedó ese mes' : 'Te queda este mes'}</div>
          </div>
          <button onClick={toggleHide} style={{ background:'none', border:'none', cursor:'pointer', color:'var(--text-3)', padding:4, display:'flex', alignItems:'center', opacity:0.7 }}>
            <Icon name={hideSaldo ? 'eyeOff' : 'eye'} size={16} strokeWidth={1.8} />
          </button>
        </div>
        <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:48, fontWeight:600, letterSpacing:'-0.035em', lineHeight:1, color: restante >= 0 ? 'var(--text)' : 'var(--red)' }}>
          {hideSaldo ? <span style={{ letterSpacing:'0.05em' }}>$ ***</span> : <AnimatedNumber value={restante} format={fmt} />}
        </div>
        <div style={{ marginTop:8, fontSize:13, color:'var(--text-2)', lineHeight:1.45 }}>
          de <strong style={{ color:'var(--text)', fontWeight:600 }}>{hideSaldo ? '$ ***' : fmt(ingTotal)}</strong> ingresados.{' '}
          {isArchived
            ? <span style={{ color:'var(--text-3)' }}>Mes cerrado.</span>
            : <span>Quedan <strong style={{ color:'var(--text)', fontWeight:600 }}>{rLive.remainingDays} dias</strong>.</span>
          }
        </div>
        <div style={{ marginTop:16 }}>
          <div style={{ height:6, background:'rgba(255,255,255,0.06)', borderRadius:999, overflow:'hidden' }}>
            <div style={{ height:'100%', width:`${monthPct*100}%`, background: isArchived ? 'rgba(167,139,250,0.4)' : 'linear-gradient(90deg, var(--accent-deep), var(--accent-bright))', borderRadius:999, transition:'width 0.8s' }} />
          </div>
          <div style={{ display:'flex', justifyContent:'space-between', marginTop:6, fontSize:10.5, color:'var(--text-3)', letterSpacing:'0.06em', textTransform:'uppercase', fontWeight:600 }}>
            <span>{isArchived ? 'Mes completo' : `Dia ${todayD.getDate()}/${rLive.daysInMonth}`}</span>
            <span>{Math.round(monthPct*100)}% del mes</span>
          </div>
        </div>
        {!isArchived && (
          <div style={{ marginTop:16, padding:'12px 14px', borderRadius:12, background: forecastPositive ? 'rgba(139,92,246,0.10)' : 'rgba(248,113,113,0.10)', border:`1px solid ${forecastPositive ? 'rgba(139,92,246,0.25)' : 'rgba(248,113,113,0.25)'}`, display:'flex', alignItems:'center', gap:12 }}>
            <div style={{ width:36, height:36, borderRadius:10, flexShrink:0, background: forecastPositive ? 'var(--accent-dim)' : 'rgba(248,113,113,0.15)', color: forecastPositive ? 'var(--accent-bright)' : 'var(--red)', display:'flex', alignItems:'center', justifyContent:'center' }}>
              <Icon name={forecastPositive ? 'trend' : 'arrowDown'} size={18} />
            </div>
            <div style={{ flex:1, minWidth:0 }}>
              <div style={{ fontSize:11, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:600, marginBottom:2 }}>Pronostico fin de mes</div>
              <div style={{ fontSize:13.5, color:'var(--text)', lineHeight:1.35 }}>
                A este ritmo terminas con <strong style={{ color: forecastPositive ? 'var(--accent-bright)' : 'var(--red)' }}>{fmt(forecastNeto)}</strong>
              </div>
            </div>
          </div>
        )}
        {isArchived && (
          <div style={{ marginTop:16, padding:'12px 14px', borderRadius:12, background:'rgba(167,139,250,0.07)', border:'1px solid rgba(167,139,250,0.18)', display:'flex', alignItems:'center', gap:12 }}>
            <div style={{ width:36, height:36, borderRadius:10, flexShrink:0, background:'rgba(167,139,250,0.12)', color:'var(--accent-bright)', display:'flex', alignItems:'center', justifyContent:'center' }}>
              <Icon name="shield" size={18} />
            </div>
            <div>
              <div style={{ fontSize:11, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:600, marginBottom:2 }}>Ahorro del mes</div>
              <div style={{ fontSize:13.5, color:'var(--text)', lineHeight:1.35 }}>
                Ahorraste <strong style={{ color:'var(--accent-bright)' }}>{fmt(ahoTotal)}</strong> ese mes.
              </div>
            </div>
          </div>
        )}
      </div>
    </Card>
  );

  // ── KPI grid ─────────────────────────────────────────────────────
  const kpiGrid = (cols) => (
    <div style={{ display:'grid', gridTemplateColumns:`repeat(${cols}, 1fr)`, gap:10 }}>
      {kpis.map((k,i) => (
        <Card key={i} padding={14} style={{ display:'flex', flexDirection:'column', gap:8 }}>
          <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between' }}>
            <div style={{ fontSize:10.5, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.12em', fontWeight:600 }}>{k.l}</div>
            <div style={{ color: k.color, opacity:0.85 }}>
              <Icon name={k.icon} size={13} strokeWidth={2} />
            </div>
          </div>
          <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:15, fontWeight:700, letterSpacing:'-0.01em', lineHeight:1.2, fontVariantNumeric:'tabular-nums' }}>
            <AnimatedNumber value={k.v} format={fmt} />
          </div>
          <div style={{ fontSize:11.5, color:'var(--text-3)' }}>{k.delta}</div>
        </Card>
      ))}
    </div>
  );

  // ── Top categorias ────────────────────────────────────────────────
  const categoriasSection = (
    <div>
      <SectionHeader title="Donde se va la plata" action={{ label:'Ver distribución →', onClick: () => onNav('movimientos') }} />
      <Card padding={4}>
        {dist.slice(0,5).map((c,i) => {
          const pct = Math.min(c.pct, 1.2);
          const over = c.pct > 1;
          return (
            <div key={c.id} style={{ display:'grid', gridTemplateColumns:'auto 1fr auto', alignItems:'center', gap:12, padding:'12px 14px', borderTop: i===0 ? 'none' : '1px solid var(--border)' }}>
              <CatChip cat={c} size={32} />
              <div style={{ minWidth:0 }}>
                <div style={{ display:'flex', justifyContent:'space-between', alignItems:'baseline', gap:8, marginBottom:6 }}>
                  <div style={{ fontSize:13.5, fontWeight:500, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{c.name}</div>
                  <div style={{ fontSize:12.5, fontVariantNumeric:'tabular-nums', fontWeight:600, color: over ? 'var(--red)' : 'var(--text)', display:'flex', alignItems:'baseline', gap:4, whiteSpace:'nowrap' }}>
                    {fmt(c.spent)}
                    <span style={{ fontSize:10, color:'var(--text-3)', fontWeight:400 }}>/ {fmt(c.budget)}</span>
                  </div>
                </div>
                <div style={{ height:4, background:'rgba(255,255,255,0.05)', borderRadius:999, overflow:'hidden' }}>
                  <div style={{ height:'100%', width:`${pct*100}%`, background: over ? 'var(--red)' : c.color, borderRadius:999, transition:'width 0.6s' }} />
                </div>
              </div>
              <div style={{ fontSize:11.5, color: over ? 'var(--red)' : 'var(--text-3)', fontVariantNumeric:'tabular-nums', minWidth:36, textAlign:'right' }}>
                {Math.round(c.pct*100)}%
              </div>
            </div>
          );
        })}
      </Card>
    </div>
  );

  // ── Compact pago row (for desktop right panel) ────────────────────
  const PagoRow = ({ p }) => {
    const cat = seed.catPorId[p.cat];
    const state = S.dueState(p.due);
    const isPaid = paidPagos && paidPagos.has(p.id);
    const stateColor = state === 'urgent' || state === 'late' ? 'var(--red)' : state === 'warn' ? 'var(--amber)' : 'var(--text-3)';
    return (
      <div className={isPaid ? 'paid-card' : ''} style={{
        display:'grid', gridTemplateColumns:'auto 1fr auto', alignItems:'center', gap:12,
        padding:'12px 14px',
        background:'var(--card)', borderRadius:12,
        border:`1px solid ${isPaid ? 'var(--border)' : state === 'urgent' ? 'rgba(248,113,113,0.35)' : state === 'warn' ? 'rgba(251,191,36,0.25)' : 'var(--border)'}`,
        transition:'border-color 0.2s',
      }}>
        <CatChip cat={cat} size={30} />
        <div style={{ minWidth:0 }}>
          <div style={{ fontSize:13, fontWeight:500, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', textDecoration: isPaid ? 'line-through' : 'none', color: isPaid ? 'var(--text-3)' : 'var(--text)' }}>{p.name}</div>
          <div style={{ fontSize:10.5, fontWeight:600, marginTop:2, color: isPaid ? '#4ade80' : stateColor, textTransform:'uppercase', letterSpacing:'0.07em', display:'flex', alignItems:'center', gap:4 }}>
            {isPaid ? <><Icon name="check" size={10} strokeWidth={2.5} /> Pagado</> : S.dueLabel(p.due)}
          </div>
        </div>
        <div style={{ textAlign:'right' }}>
          <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:14, fontWeight:600, fontVariantNumeric:'tabular-nums', color: isPaid ? 'var(--text-3)' : 'var(--text)', textDecoration: isPaid ? 'line-through' : 'none' }}>{fmt(p.amount)}</div>
          {onTogglePaid && (
            <button onClick={() => onTogglePaid(p.id)} style={{ marginTop:4, fontSize:10, fontWeight:600, color: isPaid ? 'var(--text-3)' : 'var(--accent-bright)', background:'none', border:'none', cursor:'pointer', fontFamily:'inherit', padding:0 }}>
              {isPaid ? 'Deshacer' : 'Marcar pagado'}
            </button>
          )}
        </div>
      </div>
    );
  };

  // ── Ingresos panel ────────────────────────────────────────────────
  const ingresosPanel = (
    <div>
      <SectionHeader title="Ingresos del mes" />
      <Card padding={0}>
        {seed.ingresos.map((ing, i) => {
          const confirmed = !!(confirmedIngs && confirmedIngs[ing.id]);
          return (
            <div key={ing.id} style={{ display:'flex', alignItems:'center', gap:12, padding:'11px 14px', borderTop: i===0 ? 'none' : '1px solid var(--border)', background: confirmed ? 'rgba(74,222,128,0.03)' : 'transparent', transition:'background 0.2s' }}>
              <div style={{ width:32, height:32, borderRadius:9, background: confirmed ? 'rgba(74,222,128,0.12)' : 'var(--accent-dim)', color: confirmed ? '#4ade80' : 'var(--accent-bright)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0, transition:'all 0.2s' }}>
                <Icon name={confirmed ? 'check' : 'dollar'} size={14} strokeWidth={2} />
              </div>
              <div style={{ flex:1, minWidth:0 }}>
                <div style={{ fontSize:13, fontWeight:500 }}>{ing.name}</div>
                <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:14, fontWeight:700, fontVariantNumeric:'tabular-nums', marginTop:1 }}>{fmt(ing.amount)}</div>
              </div>
              <button
                onClick={() => !confirmed && onConfirmIngreso && onConfirmIngreso(ing.id)}
                style={{ padding:'5px 12px', borderRadius:999, border:'none', cursor: confirmed ? 'default' : 'pointer', fontFamily:'inherit', fontSize:11, fontWeight:700, flexShrink:0, background: confirmed ? 'rgba(74,222,128,0.12)' : 'var(--accent-dim)', color: confirmed ? '#4ade80' : 'var(--accent-bright)', transition:'all 0.15s' }}
              >{confirmed ? '✓ Recibido' : 'Confirmar'}</button>
            </div>
          );
        })}
      </Card>
    </div>
  );

  // ── Accesos rapidos ───────────────────────────────────────────────
  // ── Cuotas activas widget ──────────────────────────────────────────────────
  const cuotasWidget = (() => {
    if (!cuotasGrupos || cuotasGrupos.length === 0) return null;
    const fmt2 = n => S.fmtMoney(ccy === 'USD' ? n / seed.fxBlue : n, ccy);
    const hoy = new Date();
    const activeCuotas = cuotasGrupos.map(g => {
      const paid = (movimientos || []).filter(m => m.cuotaGrupoId === g.id && new Date(m.date) <= hoy).length;
      const remaining = g.totalCuotas - paid;
      const montoCuota = g.montoTotal / g.totalCuotas;
      return { ...g, paid, remaining, montoCuota };
    }).filter(g => g.remaining > 0);
    if (activeCuotas.length === 0) return null;
    const totalMensual = activeCuotas.reduce((a, g) => a + g.montoCuota, 0);
    return (
      <div>
        <SectionHeader title="Cuotas activas" action={{ label:'Ver todas →', onClick: () => onNav('movimientos') }} />
        <Card style={{ padding:0, overflow:'hidden' }}>
          <div style={{ padding:'14px 16px 10px', display:'flex', alignItems:'center', justifyContent:'space-between', borderBottom:'1px solid var(--border)' }}>
            <div style={{ fontSize:12, color:'var(--text-3)' }}>{activeCuotas.length} plan{activeCuotas.length !== 1 ? 'es' : ''} activo{activeCuotas.length !== 1 ? 's' : ''}</div>
            <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:15, fontWeight:700, color:'#818cf8' }}>
              {fmt2(totalMensual)}<span style={{ fontSize:11, fontWeight:400, color:'var(--text-3)', marginLeft:4 }}>/mes</span>
            </div>
          </div>
          {activeCuotas.slice(0,3).map((g, i) => {
            const pct = g.paid / g.totalCuotas;
            return (
              <div key={g.id} style={{ padding:'11px 16px', borderBottom: i < Math.min(activeCuotas.length,3)-1 ? '1px solid var(--border)' : 'none', display:'flex', alignItems:'center', gap:12 }}>
                <div style={{ flex:1, minWidth:0 }}>
                  <div style={{ fontSize:13, fontWeight:500, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{g.descripcion || 'Cuota'}</div>
                  <div style={{ display:'flex', alignItems:'center', gap:8, marginTop:6 }}>
                    <div style={{ flex:1, height:4, background:'rgba(255,255,255,0.06)', borderRadius:999, overflow:'hidden' }}>
                      <div style={{ height:'100%', width:`${pct*100}%`, background:'linear-gradient(90deg, #6366f1, #818cf8)', borderRadius:999, transition:'width 0.6s' }} />
                    </div>
                    <span style={{ fontSize:10.5, color:'var(--text-3)', whiteSpace:'nowrap' }}>{g.paid}/{g.totalCuotas}</span>
                  </div>
                </div>
                <div style={{ textAlign:'right', flexShrink:0 }}>
                  <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:13.5, fontWeight:600, fontVariantNumeric:'tabular-nums' }}>{fmt2(g.montoCuota)}</div>
                  <div style={{ fontSize:10.5, color:'var(--text-3)', marginTop:2 }}>{g.remaining} cuota{g.remaining !== 1 ? 's' : ''} más</div>
                </div>
              </div>
            );
          })}
        </Card>
      </div>
    );
  })();

  // ── Accesos rápidos
    const accesosRapidos = (
    <div>
      <SectionHeader title="Accesos rápidos" />
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap: isDesktop ? 12 : 10 }}>
        <QuickAction large={isDesktop} icon="cart"     label="Bandeja banco"      sub={`${seed.bandeja.length} sin confirmar`}  onClick={() => onNav('pagos')} highlight />
        <QuickAction large={isDesktop} icon="user"     label="Cobrar a deudores"  sub={`${seed.deudores.length} pendientes`}    onClick={() => onNav('pagos')} />
        <QuickAction large={isDesktop} icon="pie"      label="Análisis"           sub="Distribución · histórico"               onClick={() => onNav('movimientos')} />
        <QuickAction large={isDesktop} icon="sliders"  label="Configuración"      sub="Presupuestos · perfil"                  onClick={() => onNav('config')} />
      </div>
    </div>
  );

  // ── DESKTOP LAYOUT ────────────────────────────────────────────────
  if (isDesktop) {
    return (
      <React.Fragment>
        <div style={{ display:'flex', flexDirection:'column', gap:22, padding:'20px 28px 44px', maxWidth:760, margin:'0 auto', width:'100%' }}>
          {/* LEFT COLUMN */}
          <div style={{ display:'flex', flexDirection:'column', gap:22 }}>
            <div className="s0">
              {monthSelector}
              <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:26, fontWeight:600, letterSpacing:'-0.02em', marginTop:4 }}>Hola, {userName || 'Adolfo'}</div>
            </div>
            {archiveBanner && <div className="s1">{archiveBanner}</div>}
            <div className={archiveBanner ? 's2' : 's1'}>{heroCard}</div>
            <div className={archiveBanner ? 's3' : 's2'}>{kpiGrid(4)}</div>
            <div className={archiveBanner ? 's4' : 's3'}>{categoriasSection}</div>
            <div className={archiveBanner ? 's5' : 's4'}>{accesosRapidos}</div>
          </div>

        </div>
        {monthDropPanel}
        {closeMonthModal}
      </React.Fragment>
    );
  }

  // ── MOBILE LAYOUT ─────────────────────────────────────────────────
  return (
    <div style={{ display:'flex', flexDirection:'column', gap:22, padding:'var(--sp) var(--sp) var(--sp-bottom)' }}>
      <div className="s0" style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginTop:4 }}>
        <div>
          {monthSelector}
          <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:22, fontWeight:600, letterSpacing:'-0.02em', marginTop:4 }}>Hola, {userName || 'Adolfo'}</div>
        </div>
        <button onClick={onCcy} style={{ height:36, padding:'0 14px', borderRadius:999, background:'var(--surface)', border:'1px solid var(--border)', color:'var(--text-2)', fontSize:12.5, fontWeight:600, cursor:'pointer', fontFamily:'inherit', display:'flex', alignItems:'center', gap:6 }}>
          <Icon name="exchange" size={13} /> {ccy}
        </button>
      </div>
      {archiveBanner && <div className="s1">{archiveBanner}</div>}
      <div className={archiveBanner ? 's2' : 's1'}>{heroCard}</div>
      {/* Empty state: no income configured yet */}
      {!isArchived && ingTotal === 0 && movimientos.length === 0 && (
        <div className="s2" style={{ padding:'18px 20px', borderRadius:16, background:'rgba(167,139,250,0.08)', border:'1px solid rgba(167,139,250,0.2)', display:'flex', gap:14, alignItems:'flex-start' }}>
          <div style={{ width:40, height:40, borderRadius:11, background:'var(--accent-dim)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0, color:'var(--accent-bright)' }}>
            <Icon name="spark" size={18} strokeWidth={1.8} />
          </div>
          <div>
            <div style={{ fontSize:14, fontWeight:600, marginBottom:4 }}>¡Bienvenido a Sisyphus!</div>
            <div style={{ fontSize:12.5, color:'var(--text-3)', lineHeight:1.55 }}>
              Configurá tu sueldo en <strong style={{ color:'var(--accent-bright)' }}>Config → Presupuestos</strong> para ver tu runway mensual, y usá el botón <strong style={{ color:'var(--accent-bright)' }}>+</strong> para registrar tu primer gasto.
            </div>
            <button onClick={onOpenAdd} style={{ marginTop:10, padding:'7px 16px', borderRadius:9, background:'var(--accent)', color:'var(--on-accent)', border:'none', fontFamily:'inherit', fontSize:12.5, fontWeight:600, cursor:'pointer' }}>
              + Registrar primer gasto
            </button>
          </div>
        </div>
      )}
      <div className={archiveBanner ? 's3' : 's2'}>{kpiGrid(2)}</div>
      {cuotasWidget && <div className="s3b" style={{ animation:'sectionUp 0.38s cubic-bezier(0.16,1,0.3,1) 0.18s both' }}>{cuotasWidget}</div>}
      <div className="s4">{accesosRapidos}</div>
      {metas && metas.length > 0 && (
        <div className="s5">
          <SectionHeader title="Metas de ahorro" action={{ label:'Gestionar →', onClick: () => onNav('config') }} />
          <div style={{ display:'flex', flexDirection:'column', gap:8 }}>
            {metas.slice(0,3).map(m => {
              const pct = m.objetivo > 0 ? Math.min((m.actual||0) / m.objetivo, 1) : 0;
              return (
                <Card key={m.id} padding={12}>
                  <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:8 }}>
                    <div style={{ width:32, height:32, borderRadius:9, background:(m.color||'#8b5cf6')+'22', color:m.color||'#8b5cf6', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
                      <Icon name={m.icono||'star'} size={15} strokeWidth={1.8} />
                    </div>
                    <div style={{ flex:1, minWidth:0 }}>
                      <div style={{ fontSize:13, fontWeight:500 }}>{m.nombre}</div>
                      <div style={{ fontSize:11, color:'var(--text-3)', marginTop:1 }}>
                        {S.fmtMoney(m.actual||0)} de {S.fmtMoney(m.objetivo)} · {Math.round(pct*100)}%
                      </div>
                    </div>
                    {pct >= 1 && <span style={{ fontSize:10, fontWeight:700, color:'#4ade80', letterSpacing:'0.06em' }}>✓ LISTO</span>}
                  </div>
                  <div style={{ height:5, background:'rgba(255,255,255,0.06)', borderRadius:999, overflow:'hidden' }}>
                    <div style={{ height:'100%', width:`${pct*100}%`, background: pct>=1 ? '#4ade80' : (m.color||'var(--accent-bright)'), borderRadius:999, transition:'width 0.5s' }} />
                  </div>
                </Card>
              );
            })}
          </div>
        </div>
      )}
      <div className={metas?.length > 0 ? 's5' : 's5'}>{categoriasSection}</div>
      {monthDropPanel}
      {closeMonthModal}
    </div>
  );
}

function QuickAction({ icon, label, sub, onClick, highlight, large }) {
  const p = large ? 18 : 14;
  const r = large ? 16 : 14;
  const ic = large ? 44 : 32;
  const ir = large ? 12 : 9;
  const is = large ? 20 : 16;
  return (
    <button onClick={onClick} className="card-hov ripple-btn" style={{
      textAlign:'left', padding:p, borderRadius:r,
      background: highlight ? 'var(--accent-dim)' : 'var(--card)',
      border:`1px solid ${highlight ? 'var(--border-strong)' : 'var(--border)'}`,
      cursor:'pointer', fontFamily:'inherit', color:'inherit',
      display:'flex', flexDirection:'column', gap: large ? 14 : 10,
      transition:'transform 0.18s, box-shadow 0.18s',
    }}>
      <div style={{ width:ic, height:ic, borderRadius:ir, background: highlight ? 'var(--accent)' : 'rgba(167,139,250,0.12)', color: highlight ? 'var(--on-accent)' : 'var(--accent-bright)', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0 }}>
        <Icon name={icon} size={is} strokeWidth={2} />
      </div>
      <div>
        <div style={{ fontSize: large ? 14 : 13, fontWeight:600, lineHeight:1.2 }}>{label}</div>
        <div style={{ fontSize: large ? 12.5 : 11.5, color:'var(--text-3)', marginTop:3 }}>{sub}</div>
      </div>
    </button>
  );
}

// ─── Shared payment-method dropdown (phone + desktop identical) ──────────────
function MovPmDropdown({ tarjetaFilter, onSelect }) {
  const [open, setOpen] = useState(false);
  const pmOptions = [
    { id:'', label:'Método de pago' },
    { id:'efectivo', label:'Efectivo' },
    { id:'debito',   label:'Débito' },
    ...((window._tarjetasForFilter||[]).filter(t=>t.active).map(t=>({ id:t.id, label:t.name }))),
  ];
  const active = pmOptions.find(p => p.id === tarjetaFilter);
  return (
    <div style={{ position:'relative', display:'inline-block' }}>
      <button onClick={() => setOpen(o => !o)} style={{
        padding:'6px 12px', borderRadius:999, display:'flex', alignItems:'center', gap:6,
        background: tarjetaFilter ? 'rgba(99,102,241,0.18)' : 'rgba(255,255,255,0.04)',
        color: tarjetaFilter ? '#818cf8' : 'var(--text-2)',
        border:`1px solid ${tarjetaFilter ? 'rgba(99,102,241,0.4)' : 'var(--border)'}`,
        fontSize:12.5, fontWeight:600, cursor:'pointer', fontFamily:'inherit', transition:'all 0.13s',
      }}>
        <Icon name="cards" size={13} />
        {tarjetaFilter && active ? active.label : 'Método de pago'}
        <Icon name="chevDown" size={11} />
      </button>
      {open && (
        <div style={{ position:'absolute', top:'calc(100% + 6px)', left:0, background:'rgba(14,9,28,0.98)', border:'1px solid var(--border-strong)', borderRadius:12, padding:6, zIndex:50, minWidth:170, boxShadow:'0 20px 40px rgba(0,0,0,0.6)', animation:'fadeSlide 0.15s ease' }}>
          {pmOptions.map(pm => (
            <button key={pm.id} onClick={() => { onSelect(pm.id); setOpen(false); }} style={{
              width:'100%', textAlign:'left', padding:'8px 12px', borderRadius:8,
              background: tarjetaFilter===pm.id ? 'var(--accent-dim)' : 'transparent',
              color: tarjetaFilter===pm.id ? 'var(--accent-bright)' : 'var(--text-2)',
              border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:13, fontWeight: tarjetaFilter===pm.id?600:400,
            }}>{pm.label}</button>
          ))}
        </div>
      )}
      {open && <div onClick={() => setOpen(false)} style={{ position:'fixed', inset:0, zIndex:49 }} />}
    </div>
  );
}

// ─── MOVIMIENTOS ──────────────────────────────────────────────────────────────
function MovScreen({ ccy, isDesktop, movimientos, spentState, budgets, onSendAnalisis, extraIngresos, onDeleteMov, onEditMov }) {
  const [movTab, setMovTab] = useState('movs');
  const [deleteEntry, setDeleteEntry] = useState(null);
  const [editEntry,   setEditEntry]   = useState(null);
  const [filter, setFilter] = useState('todos');
  const [tarjetaFilter, setTarjetaFilter] = useState('');  // '' = todas, id = specific card
  const [dateFilter, setDateFilter] = useState('mes');
  const [customFrom, setCustomFrom] = useState('');
  const [customTo, setCustomTo] = useState('');
  const [showCustom, setShowCustom] = useState(false);
  const [q, setQ] = useState('');
  const [analisisOpen, setAnalisisOpen] = useState(false);
  const [analisisData, setAnalisisData] = useState(null);
  const [sendingEmail, setSendingEmail] = useState(false);
  const conv = n => ccy === 'USD' ? n / seed.fxBlue : n;
  const fmt  = n => S.fmtMoney(conv(n), ccy);


  function openAnalisis() {
    const stats = window.MonthClose?.buildStats();
    setAnalisisData(stats || null);
    setAnalisisOpen(true);
  }

  async function handleSendEmail() {
    setSendingEmail(true);
    if (onSendAnalisis) await onSendAnalisis();
    setSendingEmail(false);
  }

  const analisisModal = analisisOpen && (
    <div onClick={() => setAnalisisOpen(false)} style={{ position:'fixed', inset:0, zIndex:900, background:'rgba(5,3,13,0.7)', backdropFilter:'blur(10px)', display:'flex', alignItems:'center', justifyContent:'center', padding:20, animation:'fadeIn 0.18s' }}>
      <div onClick={e => e.stopPropagation()} style={{ width:'100%', maxWidth:520, background:'rgba(14,9,28,0.98)', border:'1px solid var(--border-strong)', borderRadius:20, padding:'24px 24px 20px', maxHeight:'80dvh', overflowY:'auto', boxShadow:'0 40px 80px rgba(0,0,0,0.6)', animation:'slideUp 0.22s cubic-bezier(0.2,0.8,0.2,1)' }}>
        {/* Header */}
        <div style={{ display:'flex', alignItems:'center', justifyContent:'space-between', marginBottom:20 }}>
          <div>
            <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:17, fontWeight:600, letterSpacing:'-0.01em' }}>Análisis rápido</div>
            <div style={{ fontSize:11.5, color:'var(--text-3)', marginTop:2 }}>{analisisData?.monthName || 'Mes actual'}</div>
          </div>
          <button onClick={() => setAnalisisOpen(false)} style={{ width:28, height:28, borderRadius:8, background:'rgba(255,255,255,0.06)', border:'none', color:'var(--text-3)', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center' }}>
            <Icon name="x" size={12} />
          </button>
        </div>

        {analisisData ? (
          <>
            {/* KPI strip */}
            <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:8, marginBottom:16 }}>
              {[
                { l:'Ingresos',  v: analisisData.ingTotal, color:'#4ade80' },
                { l:'Egresos',   v: analisisData.egrTotal, color:'#f87171' },
                { l:'Ahorro',    v: analisisData.ahoTotal, color:'#818cf8' },
                { l:'Neto',      v: analisisData.neto,     color: analisisData.neto >= 0 ? '#4ade80' : '#f87171' },
              ].map(({ l, v, color }) => (
                <div key={l} style={{ padding:'10px 12px', borderRadius:10, background:'rgba(255,255,255,0.03)', border:'1px solid var(--border)' }}>
                  <div style={{ fontSize:10, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700 }}>{l}</div>
                  <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:16, fontWeight:700, marginTop:4, color, fontVariantNumeric:'tabular-nums' }}>$ {new Intl.NumberFormat('es-AR').format(Math.round(v))}</div>
                </div>
              ))}
            </div>

            {/* Top categories */}
            {analisisData.cats && (
              <div style={{ marginBottom:16 }}>
                <div style={{ fontSize:11, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700, marginBottom:8 }}>Top categorías</div>
                <div style={{ display:'flex', flexDirection:'column', gap:5 }}>
                  {[...analisisData.cats].sort((a,b) => b.spent - a.spent).slice(0,5).map(cat => (
                    <div key={cat.id} style={{ display:'flex', alignItems:'center', gap:8 }}>
                      <div style={{ fontSize:12, flex:1, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap', color:'var(--text-2)' }}>{cat.name}</div>
                      <div style={{ height:4, width:80, borderRadius:999, background:'rgba(255,255,255,0.06)', overflow:'hidden', flexShrink:0 }}>
                        <div style={{ height:'100%', width:`${Math.min((cat.spent/analisisData.egrTotal)*100,100)}%`, background: cat.over ? '#f87171' : 'var(--accent)', borderRadius:999 }} />
                      </div>
                      <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:11.5, fontWeight:600, fontVariantNumeric:'tabular-nums', color: cat.over ? '#f87171' : 'var(--text-2)', width:80, textAlign:'right', flexShrink:0 }}>$ {new Intl.NumberFormat('es-AR').format(Math.round(cat.spent))}</div>
                    </div>
                  ))}
                </div>
              </div>
            )}

            {/* Over-budget alerts */}
            {analisisData.overBudget && analisisData.overBudget.length > 0 && (
              <div style={{ marginBottom:16, padding:'10px 12px', borderRadius:10, background:'rgba(248,113,113,0.06)', border:'1px solid rgba(248,113,113,0.2)' }}>
                <div style={{ fontSize:11, color:'#f87171', fontWeight:700, marginBottom:6 }}>⚠ Sobre presupuesto</div>
                {analisisData.overBudget.map(c => (
                  <div key={c.id} style={{ fontSize:11.5, color:'var(--text-2)', marginTop:3 }}>
                    {c.name}: <span style={{ color:'#f87171', fontWeight:600 }}>$ {new Intl.NumberFormat('es-AR').format(Math.round(c.spent))}</span> / {new Intl.NumberFormat('es-AR').format(c.budget)} ({c.pct}%)
                  </div>
                ))}
              </div>
            )}

            {/* Send email button */}
            <button
              onClick={handleSendEmail}
              disabled={sendingEmail}
              style={{ width:'100%', padding:'11px 0', borderRadius:11, background: sendingEmail ? 'var(--card)' : 'linear-gradient(145deg, var(--accent-bright), var(--accent-deep))', color: sendingEmail ? 'var(--text-3)' : 'var(--on-accent)', border:'none', cursor: sendingEmail ? 'not-allowed' : 'pointer', fontFamily:'inherit', fontSize:13.5, fontWeight:600, display:'flex', alignItems:'center', justifyContent:'center', gap:8, transition:'all 0.15s' }}
            >
              {sendingEmail
                ? <><span style={{ width:13, height:13, borderRadius:'50%', border:'2px solid var(--text-3)', borderTopColor:'transparent', animation:'spin 0.7s linear infinite', display:'inline-block' }} /> Enviando...</>
                : <><Icon name="bell" size={14} strokeWidth={2} /> Enviar a mi correo</>
              }
            </button>
          </>
        ) : (
          <div style={{ textAlign:'center', padding:'20px 0', color:'var(--text-3)', fontSize:13 }}>No se pudieron calcular las estadísticas</div>
        )}
      </div>
    </div>
  );

  const movs = movimientos || [];

  const filters = [
    { id:'todos', label:'Todos' }, { id:'ingreso', label:'Ingresos' },
    { id:'fijo', label:'Fijos' }, { id:'variable', label:'Variables' }, { id:'ahorro', label:'Ahorro' },
    { id:'cuotas', label:'Cuotas' },
  ];

  // ── Date range helpers ────────────────────────────────────────────────────
  function startOfDay(d) { if (!d) return new Date(0); const x = new Date(d); x.setHours(0,0,0,0); return x; }
  const today = startOfDay(new Date());
  const yesterday = new Date(today); yesterday.setDate(today.getDate() - 1);
  const weekStart = new Date(today); weekStart.setDate(today.getDate() - today.getDay() + (today.getDay() === 0 ? -6 : 1));
  const monthStart = new Date(today.getFullYear(), today.getMonth(), 1);

  function inDateRange(m) {
    const d = startOfDay(m.date);
    switch (dateFilter) {
      case 'hoy':    return d.getTime() === today.getTime();
      case 'ayer':   return d.getTime() === yesterday.getTime();
      case 'semana': return d >= weekStart && d <= today;
      case 'mes':    return d >= monthStart && d <= today;
      case 'otro': {
        const from = customFrom ? startOfDay(new Date(customFrom)) : null;
        const to   = customTo   ? startOfDay(new Date(customTo))   : null;
        if (from && d < from) return false;
        if (to   && d > to)   return false;
        return true;
      }
      default: return true;
    }
  }

  const filtered = movs.filter(m => {
    if (!inDateRange(m)) return false;
    if (filter !== 'todos') {
      if (filter === 'ingreso' && m.kind !== 'ingreso') return false;
      if (filter === 'cuotas' && !m.cuotaGrupoId) return false;
      if (filter !== 'ingreso' && filter !== 'cuotas' && m.kind !== filter) return false;
    }
    if (q) {
      const cat = seed.catPorId[m.cat];
      const hay = (m.desc + ' ' + (cat?.name||'')).toLowerCase();
      if (!hay.includes(q.toLowerCase())) return false;
    }
    if (tarjetaFilter) {
      if (m.tarjetaId !== tarjetaFilter) return false;
    }
    return true;
  });

  const groups = useMemo(() => {
    const map = new Map();
    for (const m of filtered) {
      // Use local date key to avoid UTC timezone shifts (e.g. Argentina = UTC-3)
      const d = m.date instanceof Date ? m.date : new Date(m.date || Date.now());
      const key = `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;
      if (!map.has(key)) map.set(key, { date:m.date, items:[] });
      map.get(key).items.push(m);
    }
    return Array.from(map.values());
  }, [filtered]);

  const datePills = [
    { id:'hoy',    label:'Hoy' },
    { id:'ayer',   label:'Ayer' },
    { id:'semana', label:'Esta semana' },
    { id:'mes',    label:'Este mes' },
    { id:'otro',   label:'Otro' },
  ];

  const searchAndFilters = (
    <>
      <div style={{ display:'flex', alignItems:'center', gap:8, padding:'10px 14px', background:'var(--card)', border:'1px solid var(--border)', borderRadius:12 }}>
        <Icon name="search" size={16} style={{ color:'var(--text-3)', flexShrink:0 }} />
        <input value={q} onChange={e=>setQ(e.target.value)} placeholder="Buscar comercio o categoría" style={{ flex:1, background:'transparent', border:'none', outline:'none', color:'var(--text)', fontFamily:'inherit', fontSize:14 }}/>
        {q && <button onClick={()=>setQ('')} style={{ background:'none', border:'none', color:'var(--text-3)', cursor:'pointer' }}><Icon name="x" size={14}/></button>}
      </div>
      {/* Category filters */}
      <div style={{ display:'flex', gap:6, overflowX:'auto', scrollbarWidth:'none', flexWrap: isDesktop ? 'wrap' : 'nowrap' }}>
        {filters.map(f => (
          <button key={f.id} onClick={()=>setFilter(f.id)} style={{
            flexShrink:0, padding:'7px 14px', borderRadius:999,
            background: filter===f.id ? 'var(--accent)' : 'var(--card)',
            color: filter===f.id ? 'var(--on-accent)' : 'var(--text-2)',
            border:`1px solid ${filter===f.id ? 'var(--accent)' : 'var(--border)'}`,
            fontSize:12.5, fontWeight:600, cursor:'pointer', fontFamily:'inherit',
            transition:'background 0.15s, color 0.15s, border-color 0.15s',
          }}>{f.label}</button>
        ))}
      </div>
      {/* Payment method — same dropdown as desktop */}
      <MovPmDropdown tarjetaFilter={tarjetaFilter} onSelect={setTarjetaFilter} />
    </>
  );

  const groupsList = (
    <div style={{ display:'flex', flexDirection:'column', gap:18 }}>
      {groups.length === 0 && (
        <div style={{ textAlign:'center', padding:'40px 20px', color:'var(--text-3)', fontSize:13 }}>Sin movimientos para este filtro.</div>
      )}
      {groups.map((g, gi) => (
        <div key={gi} className={`si-${Math.min(gi,5)}`}>
          <div style={{ fontSize:11, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.14em', fontWeight:600, padding:'0 4px 8px' }}>
            {new Date(g.date).toLocaleDateString('es-AR', { weekday:'long', day:'numeric', month:'short' })}
          </div>
          <Card padding={0}>
            {g.items.map((m, mi) => {
              const cat = m.kind === 'ingreso' ? null : seed.catPorId[m.cat];
              const isIng = m.kind === 'ingreso';
              return (
                <div key={m.id} style={{ display:'grid', gridTemplateColumns:'auto 1fr auto', alignItems:'center', gap:12, padding:'14px 16px', borderTop: mi===0 ? 'none' : '1px solid var(--border)' }}>
                  {isIng ? (
                    <div style={{ width:36, height:36, borderRadius:10, background:'rgba(139,92,246,0.16)', color:'var(--accent-bright)', display:'flex', alignItems:'center', justifyContent:'center' }}>
                      <Icon name="arrowDown" size={16} strokeWidth={2.2} />
                    </div>
                  ) : <CatChip cat={cat} size={36} />}
                  <div style={{ minWidth:0 }}>
                    <div style={{ fontSize:14, fontWeight:500, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{m.desc}</div>
                    <div style={{ fontSize:11.5, color:'var(--text-3)', marginTop:2, display:'flex', alignItems:'center', gap:6 }}>
                      <span>{isIng ? 'Ingreso' : cat?.name}</span>
                      {m.tarjetaId && m.tarjetaId !== 'efectivo' && m.tarjetaId !== 'debito' && (
                        <span style={{ fontSize:9, fontWeight:800, padding:'1px 5px', borderRadius:999, background:'rgba(99,102,241,0.12)', color:'#818cf8', letterSpacing:'0.04em' }}>
                          {(window._tarjetasForFilter||[]).find(t=>t.id===m.tarjetaId)?.name?.replace(' ','·') || 'CC'}
                        </span>
                      )}
                      {m.tarjetaId === 'efectivo' && <span style={{ fontSize:9, fontWeight:700, padding:'1px 5px', borderRadius:999, background:'rgba(74,222,128,0.1)', color:'#4ade80' }}>EFECTIVO</span>}
                      {m.tarjetaId === 'debito' && <span style={{ fontSize:9, fontWeight:700, padding:'1px 5px', borderRadius:999, background:'rgba(139,92,246,0.1)', color:'var(--accent-bright)' }}>DÉBITO</span>}
                    </div>
                  </div>
                  <div style={{ display:'flex', alignItems:'center', gap:8 }}>
                    <div style={{ fontSize:14, fontWeight:600, fontVariantNumeric:'tabular-nums', textAlign:'right', color: isIng ? 'var(--accent-bright)' : 'var(--text)' }}>
                      {isIng ? '+' : ''}{fmt(m.amount)}
                    </div>
                    {onEditMov && (
                      <button onClick={e => { e.stopPropagation(); setEditEntry(m); }} style={{ width:24, height:24, borderRadius:7, background:'transparent', border:'none', color:'var(--text-3)', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', opacity:0.4, transition:'opacity 0.15s' }}
                        onTouchStart={e=>e.currentTarget.style.opacity='1'} onTouchEnd={e=>e.currentTarget.style.opacity='0.4'}
                        onMouseEnter={e=>e.currentTarget.style.opacity='1'} onMouseLeave={e=>e.currentTarget.style.opacity='0.4'}>
                        <Icon name="settings" size={11} strokeWidth={2} />
                      </button>
                    )}
                    {onDeleteMov && (
                      <button onClick={e => { e.stopPropagation(); setDeleteEntry(m); }} style={{ width:24, height:24, borderRadius:7, background:'transparent', border:'none', color:'var(--text-3)', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', opacity:0.5, transition:'opacity 0.15s' }}
                        onMouseEnter={e=>e.currentTarget.style.opacity='1'} onMouseLeave={e=>e.currentTarget.style.opacity='0.5'}>
                        <Icon name="x" size={12} strokeWidth={2} />
                      </button>
                    )}
                  </div>
                </div>
              );
            })}
          </Card>
        </div>
      ))}
    </div>
  );

  // Mobile: Análisis sub-tab (DonutPane directly)
  const mobileMovTabBar = (
    <div style={{ display:'flex', padding:4, background:'var(--card)', border:'1px solid var(--border)', borderRadius:12, gap:2 }}>
      {[{ id:'movs', label:'Movimientos' }, { id:'analisis', label:'Distribución' }].map(t => (
        <button key={t.id} onClick={() => setMovTab(t.id)} style={{
          flex:1, padding:'9px 0', borderRadius:9,
          background: movTab===t.id ? 'var(--accent-dim)' : 'transparent',
          color: movTab===t.id ? 'var(--accent-bright)' : 'var(--text-2)',
          border:'none', cursor:'pointer', fontFamily:'inherit',
          fontSize:13, fontWeight:600,
          transition:'background 0.14s, color 0.14s',
        }}>{t.label}</button>
      ))}
    </div>
  );

  if (isDesktop) {
    // Build DonutPane data
    const dist2 = (window.S && S.distribucion) ? S.distribucion(spentState, budgets) : [];
    const totalEgr2 = dist2.filter(d => !['ahorroUSD','inversion','emergencia'].includes(d.id)).reduce((a,b) => a+b.spent, 0);
    const DonutPaneDyn = window.DonutPane;

    return (
      <>
      <div style={{ display:'flex', flexDirection:'column', padding:'20px 28px 44px', maxWidth:1200, margin:'0 auto', width:'100%', gap:16 }}>
        {/* 3-column: filters | list | donut */}
        <div style={{ display:'grid', gridTemplateColumns:'180px 1fr 300px', gap:22, alignItems:'start' }}>
          {/* LEFT: filters */}
          <div style={{ display:'flex', flexDirection:'column', gap:10, position:'sticky', top:24 }}>
            <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:15, fontWeight:600, letterSpacing:'-0.01em', paddingBottom:6 }}>Filtros</div>
            {/* Search */}
            <div style={{ display:'flex', alignItems:'center', gap:7, padding:'9px 12px', background:'var(--card)', border:'1px solid var(--border)', borderRadius:11 }}>
              <Icon name="search" size={14} style={{ color:'var(--text-3)', flexShrink:0 }} />
              <input value={q} onChange={e=>setQ(e.target.value)} placeholder="Buscar..." style={{ flex:1, background:'transparent', border:'none', outline:'none', color:'var(--text)', fontFamily:'inherit', fontSize:12.5, minWidth:0 }}/>
              {q && <button onClick={()=>setQ('')} style={{ background:'none', border:'none', color:'var(--text-3)', cursor:'pointer' }}><Icon name="x" size={12}/></button>}
            </div>
            {/* Date section */}
            <div style={{ fontSize:10, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.12em', fontWeight:700, padding:'4px 4px 2px' }}>Período</div>
            <div style={{ display:'flex', flexDirection:'column', gap:2 }}>
              {datePills.map(d => (
                <button key={d.id} onClick={() => { setDateFilter(d.id); setShowCustom(d.id==='otro'); }} style={{
                  padding:'8px 12px', borderRadius:9, textAlign:'left',
                  background: dateFilter===d.id ? 'var(--accent-dim)' : 'transparent',
                  color: dateFilter===d.id ? 'var(--accent-bright)' : 'var(--text-2)',
                  border:`1px solid ${dateFilter===d.id ? 'var(--border-strong)' : 'transparent'}`,
                  fontSize:12.5, fontWeight: dateFilter===d.id ? 600 : 500, cursor:'pointer', fontFamily:'inherit',
                  transition:'background 0.13s, color 0.13s',
                }}>{d.label}</button>
              ))}
            </div>
            {showCustom && (
              <div style={{ animation:'fadeSlide 0.15s ease', padding:'10px 12px', background:'var(--card)', border:'1px solid var(--border)', borderRadius:10 }}>
                {window.MiniRangeCalendar
                  ? React.createElement(window.MiniRangeCalendar, { from:customFrom, to:customTo, onFrom:setCustomFrom, onTo:setCustomTo })
                  : <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
                      <input type="date" value={customFrom} onChange={e=>setCustomFrom(e.target.value)} style={{ padding:'7px 10px', borderRadius:8, background:'var(--surface)', border:'1px solid var(--border)', color:'var(--text)', fontFamily:'inherit', fontSize:12.5 }} />
                      <input type="date" value={customTo}   onChange={e=>setCustomTo(e.target.value)}   style={{ padding:'7px 10px', borderRadius:8, background:'var(--surface)', border:'1px solid var(--border)', color:'var(--text)', fontFamily:'inherit', fontSize:12.5 }} />
                    </div>
                }
              </div>
            )}
            {/* Category section */}
            <div style={{ fontSize:10, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.12em', fontWeight:700, padding:'6px 4px 2px' }}>Tipo</div>
            <div style={{ display:'flex', flexDirection:'column', gap:2 }}>
              {filters.map(f => (
                <button key={f.id} onClick={()=>setFilter(f.id)} style={{
                  padding:'8px 12px', borderRadius:9, textAlign:'left',
                  background: filter===f.id ? 'var(--accent-dim)' : 'transparent',
                  color: filter===f.id ? 'var(--accent-bright)' : 'var(--text-2)',
                  border:`1px solid ${filter===f.id ? 'var(--border-strong)' : 'transparent'}`,
                  fontSize:12.5, fontWeight: filter===f.id ? 600 : 500, cursor:'pointer', fontFamily:'inherit',
                  transition:'background 0.13s, color 0.13s',
                }}>{f.label}</button>
              ))}
            </div>
            {/* Payment method section */}
            <div style={{ fontSize:10, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.12em', fontWeight:700, padding:'6px 4px 2px' }}>Medio de pago</div>
            <div style={{ display:'flex', flexDirection:'column', gap:2 }}>
              {[
                { id:'', label:'Todos' },
                { id:'efectivo', label:'Efectivo' },
                { id:'debito',   label:'Débito' },
                ...((window._tarjetasForFilter||[]).filter(t=>t.active).map(t=>({ id:t.id, label:t.name }))),
              ].map(pm => (
                <button key={pm.id} onClick={()=>setTarjetaFilter(pm.id)} style={{
                  padding:'8px 12px', borderRadius:9, textAlign:'left',
                  background: tarjetaFilter===pm.id ? 'rgba(99,102,241,0.15)' : 'transparent',
                  color: tarjetaFilter===pm.id ? '#818cf8' : 'var(--text-2)',
                  border:`1px solid ${tarjetaFilter===pm.id ? 'rgba(99,102,241,0.35)' : 'transparent'}`,
                  fontSize:12.5, fontWeight: tarjetaFilter===pm.id ? 600 : 500, cursor:'pointer', fontFamily:'inherit',
                  transition:'all 0.13s',
                }}>{pm.label}</button>
              ))}
            </div>
          </div>

          {/* CENTER: list */}
          <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
            <div style={{ display:'flex', alignItems:'baseline', justifyContent:'space-between' }}>
              <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:22, fontWeight:600, letterSpacing:'-0.02em' }}>Movimientos</div>
              <div style={{ fontSize:12.5, color:'var(--text-3)' }}>{filtered.length} resultados</div>
            </div>
            {groupsList}
          </div>

          {/* RIGHT: DonutPane */}
          <div style={{ position:'sticky', top:24 }}>
            {DonutPaneDyn ? (
              <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
                <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:15, fontWeight:600, letterSpacing:'-0.01em', padding:'0 4px 4px' }}>Distribución</div>
                <DonutPaneDyn dist={dist2} totalEgr={totalEgr2} ccy={ccy} isDesktop={false} />
              </div>
            ) : null}
          </div>
        </div>
      </div>
      <DeleteConfirmModal
        entry={deleteEntry}
        onConfirm={() => { onDeleteMov && onDeleteMov(deleteEntry.id); setDeleteEntry(null); }}
        onCancel={() => setDeleteEntry(null)}
      />
      {window.EditMovModal && React.createElement(window.EditMovModal, {
        entry: editEntry,
        onSave: (changes) => { onEditMov && onEditMov(editEntry.id, changes); setEditEntry(null); },
        onCancel: () => setEditEntry(null),
      })}
      </>
    );
  }

  // ── Mobile ────────────────────────────────────────────────────────
  if (movTab === 'analisis') {
    const dist2 = S.distribucion(spentState, budgets);
    const totalEgr2 = dist2.filter(d => !['ahorroUSD','inversion','emergencia'].includes(d.id)).reduce((a,b) => a+b.spent, 0);
    const DonutPaneDyn = window.DonutPane;
    return (
      <div style={{ display:'flex', flexDirection:'column', gap:14, padding:'var(--sp) var(--sp) var(--sp-bottom)' }}>
        <div>
          <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:26, fontWeight:600, letterSpacing:'-0.02em', marginBottom:4 }}>Movimientos</div>
        </div>
        {mobileMovTabBar}
        {DonutPaneDyn
          ? <DonutPaneDyn dist={dist2} totalEgr={totalEgr2} ccy={ccy} isDesktop={false} />
          : <div style={{ textAlign:'center', padding:32, color:'var(--text-3)' }}>Cargando…</div>
        }
      </div>
    );
  }

  return (
    <div style={{ display:'flex', flexDirection:'column', gap:14, padding:'var(--sp) var(--sp) var(--sp-bottom)' }}>
      <div>
        <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:26, fontWeight:600, letterSpacing:'-0.02em', marginBottom:4 }}>Movimientos</div>
        <div style={{ fontSize:12.5, color:'var(--text-3)' }}>{filtered.length} resultados</div>
      </div>
      {mobileMovTabBar}
      {searchAndFilters}
      {groupsList}
      <DeleteConfirmModal
        entry={deleteEntry}
        onConfirm={() => { onDeleteMov && onDeleteMov(deleteEntry.id); setDeleteEntry(null); }}
        onCancel={() => setDeleteEntry(null)}
      />
      {window.EditMovModal && React.createElement(window.EditMovModal, {
        entry: editEntry,
        onSave: (changes) => { onEditMov && onEditMov(editEntry.id, changes); setEditEntry(null); },
        onCancel: () => setEditEntry(null),
      })}
    </div>
  );
}

// ─── PAGOS ────────────────────────────────────────────────────────────────────
// PagoCard — lightweight row design
function PagoCard({ p, isPaid, onTogglePaid, ccy, tarjetasState, onDelete }) {
  const conv = n => ccy === 'USD' ? n / seed.fxBlue : n;
  const fmt  = n => S.fmtMoney(conv(n), ccy);
  const dueStr   = p.due || p.fecha || '';
  const dueState = dueStr ? S.dueState(dueStr) : 'normal';
  const dueLabel = dueStr ? S.dueLabel(dueStr) : '—';
  const isCC     = p.tipoPago === 'cierre_cc';
  const tarjeta  = isCC && tarjetasState ? tarjetasState.find(t => t.id === p.tarjetaId) : null;
  const network  = tarjeta?.network || '';
  const isUrgent = dueState === 'urgent' || dueState === 'late';
  const dotColor = isPaid ? '#4ade80' : isUrgent ? 'var(--red)' : dueState === 'warn' ? 'var(--amber)' : 'rgba(255,255,255,0.18)';

  const cat = seed.catPorId[p.cat];

  return (
    <div className={isUrgent && !isPaid ? 'urgent-pulse' : ''} style={{
      display:'flex', alignItems:'center', gap:12, padding:'11px 14px', borderRadius:12,
      background: 'rgba(255,255,255,0.02)',
      border:`1px solid ${isUrgent && !isPaid ? 'rgba(248,113,113,0.2)' : 'var(--border)'}`,
      transition:'all 0.25s',
      opacity: isPaid ? 0.55 : 1,
    }}>
      {/* Category icon instead of dot */}
      {CatChip
        ? <CatChip cat={cat} size={36} style={{ filter: isPaid ? 'grayscale(0.7)' : 'none', transition:'filter 0.25s' }} />
        : <div style={{ width:8, height:8, borderRadius:'50%', background: dotColor, flexShrink:0 }} />}
      {/* Name + due */}
      <div style={{ flex:1, minWidth:0 }}>
        <div style={{ fontSize:13.5, fontWeight:500, textDecoration: isPaid ? 'line-through' : 'none', color: isPaid ? 'var(--text-3)' : 'var(--text)', overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>
          {p.name || p.label}
          {network && <span style={{ marginLeft:6, fontSize:9, fontWeight:800, padding:'1px 5px', borderRadius:999, background:'rgba(99,102,241,0.15)', color:'#818cf8', verticalAlign:'middle' }}>{network}</span>}
        </div>
        <div style={{ fontSize:11, marginTop:1, color: isPaid ? '#4ade80' : isUrgent ? 'var(--red)' : dueState === 'warn' ? 'var(--amber)' : 'var(--text-3)', fontWeight: isUrgent ? 600 : 400 }}>
          {isPaid ? '✓ Pagado' : dueLabel}
        </div>
      </div>
      {/* Amount */}
      <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:14, fontWeight:600, fontVariantNumeric:'tabular-nums', color: isPaid ? 'var(--text-3)' : isCC ? '#818cf8' : 'var(--text)', textDecoration: isPaid ? 'line-through' : 'none', flexShrink:0 }}>
        {fmt(p.amount)}
      </div>
      {/* Action */}
      {onTogglePaid && (
        <button onClick={() => onTogglePaid(p.id)} className="ripple-btn" style={{
          width:32, height:32, borderRadius:9, flexShrink:0,
          background: isPaid ? 'rgba(74,222,128,0.12)' : 'var(--accent-dim)',
          border:`1px solid ${isPaid ? 'rgba(74,222,128,0.25)' : 'var(--border-strong)'}`,
          color: isPaid ? '#4ade80' : 'var(--accent-bright)',
          cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center',
          transition:'background 0.15s, border-color 0.15s, transform 0.08s',
        }}>
          <Icon name={isPaid ? 'x' : 'check'} size={13} strokeWidth={2.5} />
        </button>
      )}
      {/* Delete — only for dynamic pagos (not seed) */}
      {onDelete && (
        <button onClick={() => onDelete(p)} style={{ width:26, height:26, borderRadius:7, background:'transparent', border:'none', color:'var(--text-3)', cursor:'pointer', display:'flex', alignItems:'center', justifyContent:'center', flexShrink:0, opacity:0.45, transition:'opacity 0.15s' }}
          onMouseEnter={e=>e.currentTarget.style.opacity='1'} onMouseLeave={e=>e.currentTarget.style.opacity='0.45'}>
          <Icon name="archive" size={11} />
        </button>
      )}
    </div>
  );
}

// DeudorCard — standalone
function DeudorCard({ d, isCollected, onMarkCollected, ccy, onDelete }) {
  const conv = n => ccy === 'USD' ? n / seed.fxBlue : n;
  const fmt  = n => S.fmtMoney(conv(n), ccy);
  const dueState   = d.due ? S.dueState(d.due) : 'normal';
  const dueLabel   = d.due ? S.dueLabel(d.due)  : '—';
  const stateColor = dueState === 'late' ? 'var(--red)' : dueState === 'urgent' ? 'var(--amber)' : 'var(--text-3)';
  const isSplit    = d.isSplit;

  return (
    <Card padding={16} className={isCollected ? 'paid-card' : ''} style={{
      borderColor: isCollected ? 'rgba(74,222,128,0.2)' : isSplit ? 'rgba(74,222,128,0.18)' : dueState==='late' ? 'rgba(248,113,113,0.35)' : 'var(--border)',
      background: isSplit && !isCollected ? 'rgba(74,222,128,0.03)' : undefined,
      transition:'border-color 0.2s'
    }}>
      <div style={{ display:'flex', alignItems:'center', gap:14 }}>
        {/* Avatar */}
        <div style={{ width:40, height:40, borderRadius:'50%', flexShrink:0,
          background: isSplit ? 'rgba(74,222,128,0.15)' : 'linear-gradient(145deg, var(--accent-bright), var(--accent-deep))',
          color: isSplit ? '#4ade80' : 'var(--on-accent)',
          fontWeight:700, fontSize:16, display:'flex', alignItems:'center', justifyContent:'center' }}>
          {isSplit
            ? <Icon name="swap" size={18} strokeWidth={2} />
            : (d.name||'?').charAt(0).toUpperCase()
          }
        </div>
        <div style={{ flex:1, minWidth:0 }}>
          <div style={{ display:'flex', alignItems:'center', gap:6 }}>
            <div style={{ fontSize:14.5, fontWeight:600, textDecoration: isCollected ? 'line-through' : 'none', color: isCollected ? 'var(--text-3)' : 'var(--text)' }}>{d.name}</div>
            {isSplit && !isCollected && (
              <span style={{ fontSize:9, fontWeight:800, padding:'2px 6px', borderRadius:999, background:'rgba(74,222,128,0.15)', color:'#4ade80', letterSpacing:'0.05em' }}>SPLIT</span>
            )}
          </div>
          {d.splitOf && !isCollected && (
            <div style={{ fontSize:11, color:'rgba(74,222,128,0.7)', marginTop:2, fontStyle:'italic' }}>↳ {d.splitOf}</div>
          )}
          <div style={{ fontSize:11.5, marginTop: d.splitOf ? 2 : 3, color:'var(--text-3)' }}>
            {isCollected ? d.note : dueLabel}
            {isCollected && <span style={{ color:'#4ade80', fontWeight:600, marginLeft:6 }}>· Cobrado ✓</span>}
          </div>
        </div>
        <div style={{ textAlign:'right', flexShrink:0 }}>
          <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:18, fontWeight:600, fontVariantNumeric:'tabular-nums', color: isCollected ? 'var(--text-3)' : 'var(--text)' }}>
            {!isCollected && <span style={{ color:'#4ade80', marginRight:2 }}>$</span>}
            {isCollected ? fmt(d.amount) : new Intl.NumberFormat('es-AR').format(Math.round(Math.abs(d.amount)))}
          </div>
          <div style={{ display:'flex', flexDirection:'column', gap:6, alignItems:'flex-end' }}>
            {!isCollected && onMarkCollected && (
              <button onClick={() => onMarkCollected(d.id)} style={{
                fontSize:11, fontWeight:700, padding:'4px 10px', borderRadius:999,
                background:'rgba(74,222,128,0.12)', color:'#4ade80',
                border:'1px solid rgba(74,222,128,0.25)', cursor:'pointer', fontFamily:'inherit',
                transition:'background 0.14s',
              }}>✓ Cobrado</button>
            )}
            {onDelete && (
              <button onClick={() => onDelete(d)} style={{ fontSize:10, fontWeight:600, padding:'3px 8px', borderRadius:999, background:'transparent', border:'none', color:'var(--text-3)', cursor:'pointer', fontFamily:'inherit', opacity:0.5, transition:'opacity 0.15s' }}
                onMouseEnter={e=>e.currentTarget.style.opacity='1'} onMouseLeave={e=>e.currentTarget.style.opacity='0.5'}>
                Eliminar
              </button>
            )}
          </div>
        </div>
      </div>
    </Card>
  );
}

// BandejaCard — standalone
function BandejaCard({ b, onConfirm, onDiscard, ccy }) {
  const conv = n => ccy === 'USD' ? n / seed.fxBlue : n;
  const fmt  = n => S.fmtMoney(conv(n), ccy);
  return (
    <Card padding={14}>
      <div style={{ display:'flex', alignItems:'center', gap:12 }}>
        <div style={{ width:38, height:38, borderRadius:10, flexShrink:0, background:'rgba(251,191,36,0.1)', color:'var(--amber)', display:'flex', alignItems:'center', justifyContent:'center' }}>
          <Icon name="bell" size={17} strokeWidth={1.8} />
        </div>
        <div style={{ flex:1, minWidth:0 }}>
          <div style={{ fontSize:13.5, fontWeight:500, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{b.merchant || b.desc || 'Movimiento'}</div>
          <div style={{ fontSize:11.5, color:'var(--text-3)', marginTop:2 }}>{b.source || 'Gmail'} · {b.date ? new Date(b.date).toLocaleDateString('es-AR') : ''}</div>
        </div>
        <div style={{ textAlign:'right', flexShrink:0 }}>
          <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:15, fontWeight:600, color:'var(--amber)', fontVariantNumeric:'tabular-nums' }}>{fmt(Math.abs(b.amount || 0))}</div>
          <div style={{ display:'flex', gap:6, marginTop:4, justifyContent:'flex-end' }}>
            <button onClick={() => onConfirm && onConfirm(b.id, b.suggested)} style={{ fontSize:10.5, fontWeight:600, color:'var(--accent-bright)', background:'none', border:'none', cursor:'pointer', fontFamily:'inherit', padding:0 }}>Confirmar</button>
            <span style={{ color:'var(--text-3)', fontSize:10 }}>·</span>
            <button onClick={() => onDiscard && onDiscard(b.id)} style={{ fontSize:10.5, fontWeight:600, color:'var(--text-3)', background:'none', border:'none', cursor:'pointer', fontFamily:'inherit', padding:0 }}>Ignorar</button>
          </div>
        </div>
      </div>
    </Card>
  );
}

function PagosScreen({ ccy, isDesktop, paidPagos, onTogglePaid, collectedDeudores, onMarkCollected, extraPagos = [], extraDeudores = [], pendingBandeja = [], onConfirmBandeja, onDiscardBandeja, tarjetasState = [], onDeletePago, onDeleteDeudor }) {
  const conv = n => ccy === 'USD' ? n / seed.fxBlue : n;
  const fmt  = n => S.fmtMoney(conv(n), ccy);
  const [tab, setTab] = useState('pagos');
  const [deleteEntry, setDeleteEntry] = useState(null);

  const allPagos  = [...(seed.pagos || []), ...(extraPagos || [])];
  const ccPagos   = allPagos.filter(p => p.tipoPago === 'cierre_cc');
  const pagos     = allPagos.filter(p => p.tipoPago !== 'cierre_cc');
  const deudores  = [...(seed.deudores || []), ...(extraDeudores || [])];

  const paid      = paidPagos   || new Set();
  const collected = collectedDeudores || new Set();

  // For cuota pagos: only show the FIRST unpaid installment per group
  // (next one becomes visible after paying the current)
  const cuotaGroupSeen = new Set();
  const visiblePagos = pagos.filter(p => {
    if (p.tipoPago !== 'cuota') return true; // non-cuota always show
    const gid = p.cuotaGrupoId;
    if (!gid) return true;
    if (paid.has(p.id)) return true; // already paid — show in "ya pagados"
    if (cuotaGroupSeen.has(gid)) return false; // another pending cuota of same group already shown
    cuotaGroupSeen.add(gid);
    return true;
  });

  const pendingPagos  = visiblePagos.filter(p => !paid.has(p.id)).sort((a,b) => new Date(a.due||'9999') - new Date(b.due||'9999'));
  const donePagos     = visiblePagos.filter(p => paid.has(p.id));
  const pendingDeu    = deudores.filter(d => !collected.has(d.id));
  const doneDeu       = deudores.filter(d =>  collected.has(d.id));
  const pendingCC     = ccPagos.filter(p => !paid.has(p.id));
  const doneCC        = ccPagos.filter(p =>  paid.has(p.id));

  const totalPorPagar  = pendingPagos.reduce((a,p) => a + p.amount, 0) + pendingCC.reduce((a,p) => a + p.amount, 0);
  const totalACobrar   = pendingDeu.reduce((a,d) => a + d.amount, 0);
  const neto           = totalACobrar - totalPorPagar;

  const tabs = [
    { id:'pagos',   label:'Por pagar', count: pendingPagos.length + pendingCC.length },
    { id:'deben',   label:'Te deben',  count: pendingDeu.length },
    ...(pendingBandeja.length > 0 ? [{ id:'bandeja', label:'Bandeja', count: pendingBandeja.length }] : []),
  ];

  const heroCard = (
    <div style={{ display:'flex', gap:10 }}>
      <div style={{ flex:1, padding:'14px 16px', borderRadius:14, background:'var(--card)', border:'1px solid var(--border)' }}>
        <div style={{ fontSize:10, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700, marginBottom:6 }}>Por pagar</div>
        <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:22, fontWeight:700, color:'var(--text)' }}>
          <span style={{ color:'#f87171', marginRight:2 }}>$</span>
          {AnimatedNumber ? <AnimatedNumber value={totalPorPagar} format={n => new Intl.NumberFormat('es-AR').format(Math.round(n))} duration={500} /> : new Intl.NumberFormat('es-AR').format(Math.round(totalPorPagar))}
        </div>
        <div style={{ fontSize:10.5, color:'var(--text-3)', marginTop:3 }}>{pendingPagos.length + pendingCC.length} pendientes</div>
      </div>
      <div style={{ flex:1, padding:'14px 16px', borderRadius:14, background:'var(--card)', border:'1px solid var(--border)' }}>
        <div style={{ fontSize:10, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700, marginBottom:6 }}>A cobrar</div>
        <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:22, fontWeight:700, color:'var(--text)' }}>
          <span style={{ color:'#4ade80', marginRight:2 }}>$</span>
          {AnimatedNumber ? <AnimatedNumber value={totalACobrar} format={n => new Intl.NumberFormat('es-AR').format(Math.round(n))} duration={500} /> : new Intl.NumberFormat('es-AR').format(Math.round(totalACobrar))}
        </div>
        <div style={{ fontSize:10.5, color:'var(--text-3)', marginTop:3 }}>{pendingDeu.length} pendientes</div>
      </div>
    </div>
  );

  const pagosContent = (
    <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
      {ccPagos.length > 0 && (
        <div>
          <div style={{ fontSize:11, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700, padding:'4px 2px 8px' }}>Resumenes de tarjeta</div>
          {ccPagos.map((p,i) => <div key={p.id} className={`si-${Math.min(i,5)}`}><PagoCard p={p} isPaid={paid.has(p.id)} onTogglePaid={onTogglePaid} ccy={ccy} tarjetasState={tarjetasState} /></div>)}
        </div>
      )}
      {pendingPagos.length === 0 && ccPagos.length === 0 ? (
        <div style={{ textAlign:'center', padding:'40px 0', color:'var(--text-3)', fontSize:13 }}>
          <div style={{ width:44, height:44, borderRadius:14, background:'var(--accent-dim)', display:'flex', alignItems:'center', justifyContent:'center', margin:'0 auto 12px', color:'var(--accent-bright)' }}><Icon name="check" size={20} strokeWidth={1.8} /></div>
          Sin pagos pendientes
        </div>
      ) : (
        <>
          {pendingPagos.map((p,i) => <div key={p.id} className={`si-${Math.min(i,5)}`}><PagoCard p={p} isPaid={paid.has(p.id)} onTogglePaid={onTogglePaid} ccy={ccy} tarjetasState={tarjetasState} onDelete={onDeletePago ? (p) => setDeleteEntry({...p, _type:'pago'}) : null} /></div>)}
          {donePagos.length > 0 && (
            <div style={{ fontSize:11, color:'var(--text-3)', textTransform:'uppercase', letterSpacing:'0.1em', fontWeight:700, padding:'8px 2px 4px', borderTop:'1px solid var(--border)', marginTop:4 }}>Ya pagados</div>
          )}
          {donePagos.map((p,i) => <div key={p.id} className={`si-${Math.min(i,5)}`}><PagoCard p={p} isPaid={true} onTogglePaid={onTogglePaid} ccy={ccy} tarjetasState={tarjetasState} onDelete={onDeletePago ? (p) => setDeleteEntry({...p, _type:'pago'}) : null} /></div>)}
          {doneCC.map((p,i) => <div key={p.id} className={`si-${Math.min(i,5)}`}><PagoCard p={p} isPaid={true} onTogglePaid={onTogglePaid} ccy={ccy} tarjetasState={tarjetasState} /></div>)}
        </>
      )}
    </div>
  );

  const debenContent = (
    <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
      {deudores.length === 0 ? (
        <div style={{ textAlign:'center', padding:'40px 0', color:'var(--text-3)', fontSize:13 }}>Sin deudores registrados</div>
      ) : (
        <>
          {pendingDeu.map(d => <DeudorCard key={d.id} d={d} isCollected={false} onMarkCollected={onMarkCollected} ccy={ccy} onDelete={onDeleteDeudor ? (d) => setDeleteEntry({...d, _type:'deudor'}) : null} />)}
          {doneDeu.length > 0 && <div style={{ height:1, background:'var(--border)', margin:'4px 0' }} />}
          {doneDeu.map(d    => <DeudorCard key={d.id} d={d} isCollected={true}  onMarkCollected={onMarkCollected} ccy={ccy} onDelete={onDeleteDeudor ? (d) => setDeleteEntry({...d, _type:'deudor'}) : null} />)}
        </>
      )}
    </div>
  );

  const bandejaContent = (
    <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
      {(pendingBandeja || []).map(b => (
        <BandejaCard key={b.id} b={b} onConfirm={onConfirmBandeja} onDiscard={onDiscardBandeja} ccy={ccy} />
      ))}
    </div>
  );

  if (isDesktop) {
    const cols = pendingBandeja.length > 0 ? '1fr 1fr 1fr' : '1fr 1fr';
    return (
      <div style={{ padding:'20px 28px 44px', maxWidth:1100, margin:'0 auto', width:'100%' }}>
        <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:22, fontWeight:600, letterSpacing:'-0.02em', marginBottom:20 }}>Pagos</div>
        {heroCard}
        <div style={{ display:'grid', gridTemplateColumns: cols, gap:22, alignItems:'start', marginTop:20 }}>
          <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
            <SectionHeader title="Por pagar" />
            {pagosContent}
          </div>
          <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
            <SectionHeader title="Te deben" />
            {debenContent}
          </div>
          {pendingBandeja.length > 0 && (
            <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
              <SectionHeader title="Bandeja" />
              {bandejaContent}
            </div>
          )}
        </div>
      </div>
    );
  }

  return (
    <div style={{ padding:'var(--sp) var(--sp) var(--sp-bottom)' }}>
      <div style={{ fontFamily:'Space Grotesk, sans-serif', fontSize:26, fontWeight:600, letterSpacing:'-0.02em', marginBottom:14 }}>Pagos</div>
      {heroCard}
      <div style={{ display:'flex', padding:4, background:'var(--card)', border:'1px solid var(--border)', borderRadius:12, gap:2, margin:'14px 0' }}>
        {tabs.map(t => (
          <button key={t.id} onClick={() => setTab(t.id)} style={{
            flex:1, padding:'9px 0', borderRadius:9, position:'relative',
            background: tab===t.id ? 'var(--accent-dim)' : 'transparent',
            color: tab===t.id ? 'var(--accent-bright)' : 'var(--text-2)',
            border:'none', cursor:'pointer', fontFamily:'inherit', fontSize:12.5, fontWeight:600,
            transition:'background 0.14s, color 0.14s',
          }}>
            {t.label}
            {t.count > 0 && (
              <span style={{ marginLeft:5, fontSize:10, fontWeight:700, background: tab===t.id ? 'var(--accent)' : 'rgba(255,255,255,0.12)', color: tab===t.id ? 'var(--on-accent)' : 'var(--text-3)', padding:'1px 5px', borderRadius:999 }}>{t.count}</span>
            )}
          </button>
        ))}
      </div>
      {tab === 'pagos'   && pagosContent}
      {tab === 'deben'   && debenContent}
      {tab === 'bandeja' && bandejaContent}
    </div>
  );
}

window.Card          = Card;
window.SectionHeader = SectionHeader;
window.CatChip       = CatChip;
window.HomeScreen    = HomeScreen;
window.MovScreen     = MovScreen;
window.MovPmDropdown = MovPmDropdown;
window.PagosScreen   = PagosScreen;
