/* global React */
// ============================================================
// CuentasFlow — faithful HTML/CSS recreation of the Meefi web
// app: Dashboard → Cuentas (list) → Detalle de cuenta.
// The whole 1920-wide app is scaled to fit the window; the
// cursor lives OUTSIDE the scaled artboard so it stays normal
// size and clicks land precisely (measured via bounding rects).
// ============================================================
const { useState, useRef, useEffect } = React;
const DES_W = 1840;

const CI = {
  search:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="11" cy="11" r="7"/><path d="m21 21-4.3-4.3"/></svg>),
  home:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 11.5 12 4l9 7.5M5 10v10h14V10"/></svg>),
  bank:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 21h18M4 10h16M5 10V8l7-4 7 4v2M6 10v8M10 10v8M14 10v8M18 10v8"/></svg>),
  grid:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="4" width="18" height="4" rx="1"/><rect x="3" y="12" width="18" height="3" rx="1"/><rect x="3" y="18" width="18" height="2.5" rx="1"/></svg>),
  file:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M6 2h8l4 4v16H6z"/><path d="M14 2v4h4M9 12h6M9 16h6"/></svg>),
  inbox:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="4" width="18" height="16" rx="2.5"/><path d="M3 13h5l2 3h4l2-3h5"/></svg>),
  out:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M4 4h16v16H4z" opacity="0"/><path d="M7 17 17 7M9 7h8v8"/></svg>),
  send:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M22 2 11 13M22 2l-7 20-4-9-9-4 20-7Z"/></svg>),
  stack:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="m12 3 9 5-9 5-9-5 9-5ZM3 13l9 5 9-5M3 17l9 5 9-5"/></svg>),
  plus:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 5v14M5 12h14"/></svg>),
  badge:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="9"/><path d="m8.5 12 2.3 2.3 4.7-4.7"/></svg>),
  shield:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M12 3 5 6v6c0 4 3 6.5 7 9 4-2.5 7-5 7-9V6l-7-3Z"/><path d="m9 12 2 2 4-4"/></svg>),
  swap:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M7 4 3 8l4 4M3 8h14M17 20l4-4-4-4M21 16H7"/></svg>),
  gear:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><circle cx="12" cy="12" r="3.2"/><path d="M19.4 15a1.6 1.6 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.6 1.6 0 0 0-2.7 1.1V21a2 2 0 0 1-4 0v-.1A1.6 1.6 0 0 0 7 19.4a1.6 1.6 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1A1.6 1.6 0 0 0 3 14a2 2 0 0 1 0-4h.1A1.6 1.6 0 0 0 4.6 7a1.6 1.6 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1A1.6 1.6 0 0 0 10 3a2 2 0 0 1 4 0v.1a1.6 1.6 0 0 0 2.7 1.1l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1A1.6 1.6 0 0 0 21 10a2 2 0 0 1 0 4Z"/></svg>),
  bell:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M18 8a6 6 0 1 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13.7 21a2 2 0 0 1-3.4 0"/></svg>),
  chev:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="m6 9 6 6 6-6"/></svg>),
  chevR:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="m9 6 6 6-6 6"/></svg>),
  chevL:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="m15 6-6 6 6 6"/></svg>),
  copy:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="9" y="9" width="11" height="11" rx="2.5"/><path d="M5 15V5a2 2 0 0 1 2-2h8"/></svg>),
  trend:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 17l6-6 4 4 7-8"/></svg>),
  cells:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><rect x="3" y="3" width="8" height="8" rx="1.5"/><rect x="13" y="3" width="8" height="8" rx="1.5"/><rect x="3" y="13" width="8" height="8" rx="1.5"/><rect x="13" y="13" width="8" height="8" rx="1.5"/></svg>),
  arrowR:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M5 12h14M13 6l6 6-6 6"/></svg>),
  arrowUR:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M7 17 17 7M8 7h9v9"/></svg>),
  factory:(p)=>(<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" {...p}><path d="M3 21h18M4 21V9l6 4V9l6 4V5h3v16"/></svg>),
};
const Av = ({ t, size = 38, bg = "#e9edfb", fg = "#3a5bd9" }) => (
  <span className="caf-av-m" style={{ width: size, height: size, background: bg, color: fg, fontSize: size * .42 }}>{t}</span>
);

const SUB = [
  { n: "Principal", b: "$11,136.99" }, { n: "Proveedores", b: "$3,600.01" },
  { n: "Banco BBVA", b: "$0.00" }, { n: "Multi-Procesador Test", b: "$10,000.00" },
  { n: "Nómina STP", b: "$0.00" },
];
const CARD_ACCS = SUB;
const ACCOUNTS = [
  { n: "Principal",             c: "Acct ••0008 · USD", b: "$11,136.99" },
  { n: "Proveedores",           c: "Acct ••0001 · USD", b: "$3,600.01" },
  { n: "Banco BBVA",            c: "Acct ••0014 · USD", b: "$0.00" },
  { n: "Multi-Procesador Test", c: "Acct ••0027 · USD", b: "$10,000.00" },
  { n: "Nómina STP",            c: "Sin cuenta USD",    b: "$0.00" },
  { n: "Nómina ASP",            c: "Acct ••0030 · USD", b: "$0.00" },
  { n: "Prueba",                c: "Acct ••0043 · USD", b: "$0.00" },
  { n: "Gerencia Estatal",      c: "Acct ••0056 · USD", b: "$0.00" },
];
const TX = [
  { d: "May 24", ini: "PR", c1: "#d6ebe0", c2: "#3d7a5e", n: "Prueba", amt: "− $0.01", neg: true, m: "··0015", io: "out" },
  { d: "May 24", ini: "PR", c1: "#d6ebe0", c2: "#3d7a5e", n: "Prueba", amt: "− $0.01", neg: true, m: "··0015", io: "out" },
  { d: "Abr 29", ini: "TE", c1: "#dbe6f5", c2: "#4b6088", n: "Test Business Test Business", amt: "$0.01", neg: false, m: "··0015", io: "in" },
  { d: "Abr 29", ini: "TE", c1: "#dbe6f5", c2: "#4b6088", n: "Test Business Test Business", amt: "$0.01", neg: false, m: "··0015", io: "in" },
  { d: "Abr 29", ini: "TE", c1: "#dbe6f5", c2: "#4b6088", n: "Test Business Test Business", amt: "$0.01", neg: false, m: "··0015", io: "in" },
  { d: "Abr 29", ini: "PR", c1: "#d6ebe0", c2: "#3d7a5e", n: "Prueba", amt: "− $0.01", neg: true, m: "··0015", io: "out" },
  { d: "Abr 29", ini: "m", c1: "#e9edfb", c2: "#3a5bd9", n: "Hacia Multi-procesador Test", amt: "− $10,000.00", neg: true, m: "Transferencia", io: "out", transfer: true },
  { d: "Abr 20", ini: "PR", c1: "#d6ebe0", c2: "#3d7a5e", n: "Prueba Fict 4", amt: "− $0.01", neg: true, m: "··0011", io: "out" },
  { d: "Abr 6", ini: "SO", c1: "#e7e2f3", c2: "#6a5a93", n: "Soluciones Integrales Sa", amt: "− $0.01", neg: true, m: "··0001", io: "out" },
];

function Sidebar({ view, cuentasRef }) {
  const accounts = view !== "dash";
  return (
    <aside className="caf-side">
      <div className="caf-logo">
        <span className="caf-logo-ic"><CI.factory width="20" height="20"/></span>
        <div className="caf-logo-tt">
          <div className="caf-logo-t">Soluciones Integrale…</div>
          <div className="caf-logo-s">Ejecutivo</div>
        </div>
      </div>
      <nav className="caf-nav">
        <div className={`caf-navit ${view === "dash" ? "is-act" : ""}`}><CI.home width="18" height="18"/>Inicio</div>
        <div id="caf-cuentas-nav" ref={cuentasRef} className={`caf-navit ${accounts ? "is-act" : ""}`}><CI.bank width="18" height="18"/>Cuentas</div>
        {accounts && (
          <div className="caf-sub">
            {SUB.map((s, i) => (
              <div key={i} className={`caf-subit ${view === "detail" && i === 0 ? "is-cur" : ""}`}>
                <span className="caf-subit-n">{s.n}</span>
                <span className="caf-subit-b">{s.b}</span>
              </div>
            ))}
          </div>
        )}
        <div className="caf-navit"><CI.grid width="18" height="18"/>Transacciones</div>
        <div className="caf-navsec">Administración</div>
        <div className="caf-navit"><CI.file width="18" height="18"/>Facturas</div>
        <div className="caf-navit"><CI.inbox width="18" height="18"/>Cuentas por cobrar</div>
        <div className="caf-navit"><CI.out width="18" height="18"/>Cuentas por pagar</div>
      </nav>
    </aside>
  );
}

function Topbar() {
  return (
    <div className="caf-top">
      <div className="caf-search"><CI.search width="16" height="16"/><span>Busca lo que quieras</span></div>
      <span className="caf-kbd">⌘ k</span>
      <div className="caf-topr">
        <span className="caf-move"><CI.swap width="18" height="18"/>Mover dinero</span>
        <span className="caf-ic"><CI.gear width="19" height="19"/></span>
        <span className="caf-ic"><CI.bell width="19" height="19"/></span>
        <span className="caf-prof">R</span>
      </div>
    </div>
  );
}

function DashScreen() {
  return (
    <div className="caf-page">
      <h1 className="caf-h1">Bienvenido, Roberto</h1>
      <div className="caf-actions">
        <button className="caf-act caf-act-blue"><CI.send width="16" height="16"/>Enviar</button>
        <button className="caf-act"><CI.stack width="16" height="16"/>Masivo</button>
        <button className="caf-act"><CI.plus width="16" height="16"/>Nueva factura</button>
        <button className="caf-act"><CI.badge width="16" height="16"/>Aplicar pagos</button>
      </div>
      <div className="caf-grid2">
        <div className="caf-card caf-bal">
          <div className="caf-bal-top">
            <span className="caf-bal-title">Balance en Meefi <CI.shield width="15" height="15"/></span>
            <span className="caf-bal-tg"><span className="caf-tg-on"><CI.trend width="15" height="15"/></span><span className="caf-tg-off"><CI.cells width="15" height="15"/></span></span>
          </div>
          <div className="caf-bal-amt">$24,737.00<span className="caf-cur-tag">USD</span></div>
          <div className="caf-bal-range">Últimos 7 días <CI.chev width="13" height="13"/></div>
          <div className="caf-chart">
            <svg viewBox="0 0 820 190" preserveAspectRatio="none">
              <defs><linearGradient id="cafg" x1="0" y1="0" x2="0" y2="1"><stop offset="0%" stopColor="rgba(90,116,236,.22)"/><stop offset="100%" stopColor="rgba(90,116,236,0)"/></linearGradient></defs>
              <path d="M0,120 L360,120 C420,120 445,72 520,70 L820,70 L820,190 L0,190 Z" fill="url(#cafg)"/>
              <path d="M0,120 L360,120 C420,120 445,72 520,70 L820,70" fill="none" stroke="#5a74ec" strokeWidth="2.4"/>
            </svg>
          </div>
          <div className="caf-chart-x">{["May 22","May 23","May 24","May 25","May 26","May 27"].map((d,i)=><span key={i}>{d}</span>)}</div>
        </div>
        <div className="caf-card caf-cuentas">
          <div className="caf-cuentas-top"><span>Cuentas</span><span className="caf-dots">⋮</span></div>
          {CARD_ACCS.map((a, i) => (
            <div key={i} className="caf-crow"><Av t="m" size={30}/><span className="caf-crow-n">{a.n}</span><span className="caf-crow-b">{a.b}</span></div>
          ))}
          <div className="caf-verall"><span className="caf-plus6">+6</span> Ver todas las cuentas</div>
        </div>
      </div>
      <div className="caf-mov-head"><h2 className="caf-h2">Movimientos</h2><span className="caf-month"><CI.chevL width="15" height="15"/> May 2026 <CI.chevR width="15" height="15"/></span></div>
      <div className="caf-grid2">
        <div className="caf-card caf-mov">
          <div className="caf-mov-k">Entradas</div>
          <div className="caf-mov-v caf-green">$3,500.00<span className="caf-cur-tag">USD</span></div>
          <div className="caf-mov-sub">Mayores fuentes</div>
          <div className="caf-crow caf-crow-b2"><Av t="T" size={30} bg="#dbe6f5" fg="#4b6088"/><span className="caf-crow-n">TEST BUSINESS TEST BUSINESS</span><span className="caf-crow-b">$3,500.00</span></div>
          <div className="caf-crow caf-verrow"><span className="caf-verall-ic"><CI.arrowUR width="14" height="14"/></span><span className="caf-crow-n">Ver todas</span><CI.chevR width="14" height="14"/></div>
        </div>
        <div className="caf-card caf-mov">
          <div className="caf-mov-k">Salidas</div>
          <div className="caf-mov-v caf-olive">$0.02<span className="caf-cur-tag">USD</span></div>
          <div className="caf-mov-sub">Mayores destinos</div>
          <div className="caf-crow caf-crow-b2"><Av t="P" size={30} bg="#d6ebe0" fg="#3d7a5e"/><span className="caf-crow-n">PRUEBA</span><span className="caf-crow-b">$0.01</span></div>
          <div className="caf-crow caf-crow-b2"><Av t="P" size={30} bg="#d6ebe0" fg="#3d7a5e"/><span className="caf-crow-n">PRUEBA</span><span className="caf-crow-b">$0.01</span></div>
        </div>
      </div>
    </div>
  );
}

function AccountsScreen({ rowRef, rowHover }) {
  return (
    <div className="caf-page">
      <div className="caf-head-row">
        <h1 className="caf-h1">Cuentas</h1>
        <div className="caf-head-actions"><span className="caf-headlink"><CI.swap width="16" height="16"/>Transferir</span><button className="caf-act caf-act-out">Crear cuenta</button></div>
      </div>
      <div className="caf-totals">
        <div className="caf-tot-big"><div className="caf-tot-k">Disponible ⓘ</div><div className="caf-tot-bigv">$24,737.00<span className="caf-cur-tag">USD</span><span className="caf-shield"><CI.shield width="16" height="16"/></span></div></div>
        <div><div className="caf-tot-k">Reservado</div><div className="caf-tot-sv">$0.04</div></div>
        <div><div className="caf-tot-k">Total</div><div className="caf-tot-sv">$24,737.04</div></div>
      </div>
      <div className="caf-tbl">
        <div className="caf-tbl-head"><span>Cuenta</span><span>Balance</span></div>
        {ACCOUNTS.map((a, i) => (
          <div key={i} ref={i === 0 ? rowRef : null} className={`caf-trow ${i === 0 && rowHover ? "is-hover" : ""}`}>
            <span className="caf-trow-l"><Av t="m" size={40}/><span className="caf-trow-meta"><span className="caf-trow-n">{a.n}</span><span className="caf-trow-c">{a.c}</span></span></span>
            <span className="caf-trow-b">{a.b}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function DetailScreen({ verRef }) {
  return (
    <div className="caf-page">
      <h1 className="caf-h1">Principal</h1>
      <div className="caf-grid2 caf-grid-det">
        <div className="caf-card caf-detbal">
          <div className="caf-det-top">
            <div><div className="caf-tot-k">Disponible ⓘ</div><div className="caf-det-amt">$11,136.99<span className="caf-cur-tag">USD</span></div></div>
            <div className="caf-det-btns"><button className="caf-act"><CI.plus width="15" height="15"/>Individual</button><button className="caf-act">Transferir</button></div>
          </div>
          <div className="caf-det-stats">
            <div><div className="caf-tot-k">Tipo</div><div className="caf-det-sv">Cheques</div></div>
            <div><div className="caf-tot-k">Total</div><div className="caf-det-sv">$11,137.03</div></div>
            <div><div className="caf-tot-k">Reservado</div><div className="caf-det-sv">$0.04</div></div>
          </div>
          <div className="caf-det-sep"/>
          <span ref={verRef} className="caf-link">Ver todas las transacciones <CI.chevR width="14" height="14"/></span>
        </div>
        <div className="caf-card caf-clabe">
          <div className="caf-clabe-row"><span className="caf-tot-k">SWIFT</span><span className="caf-clabe-v">MEEFMXMMXXX <CI.copy width="14" height="14"/></span></div>
          <div className="caf-clabe-row"><span className="caf-tot-k">Banco ⓘ</span><span className="caf-clabe-v">ASP Integra Opciones <CI.copy width="14" height="14"/></span></div>
          <div className="caf-clabe-row"><span className="caf-tot-k">Account</span><span className="caf-clabe-v">6596 4404 0008 <CI.copy width="14" height="14"/></span></div>
          <div className="caf-clabe-sep"/>
          <div className="caf-clabe-docs">Documentos <CI.chev width="14" height="14"/></div>
        </div>
      </div>
      <div className="caf-mov-head"><h2 className="caf-h2">Transferencias recientes <span className="caf-link2">Ver todas <CI.chevR width="13" height="13"/></span></h2></div>
      <div className="caf-txtbl">
        <div className="caf-txhead"><span>Fecha</span><span>Contraparte</span><span className="caf-r">Monto</span><span>Método</span></div>
        {TX.map((t, i) => (
          <div key={i} className="caf-txrow">
            <span className="caf-tx-d">{t.d}</span>
            <span className="caf-tx-c"><Av t={t.ini} size={30} bg={t.c1} fg={t.c2}/>{t.n}</span>
            <span className={`caf-tx-amt ${t.neg ? "" : "caf-green"}`}>{t.amt}</span>
            <span className="caf-tx-m">{t.io === "in" ? "←" : "→"} {t.transfer ? "" : <CI.bank width="13" height="13"/>} {t.m}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

function CuentasFlow() {
  const [view, setView]   = useState("dash");
  const [navHover, setNav]= useState(false);
  const [rowHover, setRow]= useState(false);
  const [cur, setCur]     = useState({ x: 360, y: 230, show: false });
  const [press, setPress] = useState(false);
  const [click, setClick] = useState(null);
  const [box, setBox]     = useState({ s: 0.5, h: 1600 });

  const stageRef = useRef(null);
  const cuentasRef = useRef(null);
  const principalRef = useRef(null);
  const verRef = useRef(null);
  const last = useRef({ x: 360, y: 230 });

  useEffect(() => {
    const st = stageRef.current;
    const measure = () => {
      if (!st) return;
      const w = st.clientWidth, h = st.clientHeight;
      const s = w / DES_W;
      setBox({ s, h: Math.max(956, Math.ceil(h / s)) });
    };
    measure();
    window.addEventListener("resize", measure);

    const timers = [];
    const at = (ms, fn) => timers.push(setTimeout(fn, ms));
    let k = 0;
    const moveTo = (ref, dx = 0, dy = 0) => {
      const el = ref.current; if (!st || !el) return;
      const a = st.getBoundingClientRect();
      const r = el.getBoundingClientRect();
      const x = r.left - a.left + r.width / 2 + dx;
      const y = r.top - a.top + r.height / 2 + dy;
      last.current = { x, y };
      setCur({ x, y, show: true });
    };
    const pulse = () => {
      const { x, y } = last.current;
      setPress(true); setClick({ x, y, k: ++k });
      timers.push(setTimeout(() => setPress(false), 200));
    };
    const startCursor = () => {
      if (!st) return;
      const a = st.getBoundingClientRect();
      const x = a.width * 0.58, y = a.height * 0.4;
      last.current = { x, y };
      setCur({ x, y, show: true });
    };

    // STEP 0 — Dashboard → click "Cuentas" in sidebar
    setView("dash"); setCur((c) => ({ ...c, show: false }));
    at(200,  () => startCursor());            // cursor visible on the dashboard from the start
    at(1050, () => moveTo(cuentasRef, 28, 0)); // travel left to the "Cuentas" sidebar item
    at(1150, () => setNav(true));
    at(2400, () => pulse());
    at(3050, () => { setNav(false); setView("accounts"); });

    // STEP 1 — Cuentas list → click "Principal" row
    at(3500, () => moveTo(principalRef, -260, 0));
    at(3600, () => setRow(true));
    at(4850, () => pulse());
    at(5550, () => { setRow(false); setView("detail"); });

    // STEP 2 — Detalle de cuenta → settle on "Ver todas las transacciones"
    at(6150, () => moveTo(verRef));
    // hold until the feature rotates away

    return () => { timers.forEach(clearTimeout); window.removeEventListener("resize", measure); };
  }, []);

  return (
    <div className="caf-stage" ref={stageRef}>
      <div className="caf-art" style={{ width: DES_W, height: box.h, transform: `scale(${box.s})` }}>
        <Sidebar view={view} cuentasRef={cuentasRef}/>
        <div className="caf-mainwrap">
          <Topbar/>
          <div className="caf-main">
            <div className={`caf-screen ${view === "dash" ? "is-on" : ""}`}>{view === "dash" && <DashScreen/>}</div>
            <div className={`caf-screen ${view === "accounts" ? "is-on" : ""}`}>{view === "accounts" && <AccountsScreen rowRef={principalRef} rowHover={rowHover}/>}</div>
            <div className={`caf-screen ${view === "detail" ? "is-on" : ""}`}>{view === "detail" && <DetailScreen verRef={verRef}/>}</div>
          </div>
        </div>
      </div>

      {cur.show && (
        <span className={`caf-cursor ${press ? "is-press" : ""}`} style={{ left: cur.x, top: cur.y }}>
          <svg width="21" height="21" viewBox="0 0 24 24" fill="#1b1f26" stroke="#fff" strokeWidth="1.5" strokeLinejoin="round"><path d="M5.5 2.6 L5.5 19.4 L9.7 15.4 L12.5 21.2 L14.9 20 L12.1 14.3 L17.6 14.3 Z"/></svg>
        </span>
      )}
      {click && <span key={click.k} className="caf-click" style={{ left: click.x, top: click.y }}/>}
      <style>{CAF_CSS}</style>
    </div>
  );
}

const CAF_CSS = `
.caf-stage,.caf-stage *{font-family:'Montserrat',sans-serif !important;box-sizing:border-box;}
.caf-stage{position:absolute;inset:0;background:#fff;overflow:hidden;-webkit-font-smoothing:antialiased;}
.caf-art{position:absolute;top:0;left:0;transform-origin:0 0;display:flex;background:#fff;color:#2b3240;}

/* sidebar */
.caf-side{width:232px;flex:none;border-right:1px solid #eef0f3;display:flex;flex-direction:column;padding:0 14px;}
.caf-logo{display:flex;align-items:center;gap:11px;padding:20px 8px 22px;}
.caf-logo-ic{width:34px;height:34px;border-radius:9px;background:#0b1b4d;color:#fff;display:flex;align-items:center;justify-content:center;flex:none;}
.caf-logo-t{font-size:14px;font-weight:600;color:#222a37;line-height:1.1;}
.caf-logo-s{font-size:12px;color:#9aa2b1;margin-top:2px;}
.caf-nav{display:flex;flex-direction:column;gap:3px;}
.caf-navit{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:9px;font-size:14.5px;font-weight:500;color:#5b6475;cursor:default;transition:background .2s,color .2s;}
.caf-navit svg{color:#8893a6;}
.caf-navit.is-act{background:#f3f5f8;color:#222a37;}
.caf-navit.is-act svg{color:#2b3240;}
.caf-navit.is-hover:not(.is-act){background:#f7f8fa;}
.caf-sub{display:flex;flex-direction:column;margin:2px 0 6px 0;padding-left:14px;}
.caf-subit{display:flex;flex-direction:column;gap:1px;padding:7px 12px;border-left:2px solid transparent;}
.caf-subit.is-cur{border-left-color:#1f3cd6;}
.caf-subit-n{font-size:13.5px;color:#3a4250;font-weight:500;}
.caf-subit-b{font-size:12px;color:#9aa2b1;}
.caf-navsec{font-size:11.5px;font-weight:600;letter-spacing:.06em;color:#aab2c2;padding:18px 12px 8px;}

/* topbar */
.caf-mainwrap{flex:1;min-width:0;display:flex;flex-direction:column;}
.caf-top{height:64px;flex:none;display:flex;align-items:center;gap:16px;padding:0 30px;border-bottom:1px solid #eef0f3;position:relative;}
.caf-search{display:flex;align-items:center;gap:9px;color:#aeb4c0;font-size:14.5px;}
.caf-search svg{color:#aeb4c0;}
.caf-kbd{position:absolute;left:50%;transform:translateX(-50%);font-size:12px;color:#aab2c2;background:#f4f5f8;border:1px solid #eceef2;border-radius:6px;padding:3px 8px;}
.caf-topr{margin-left:auto;display:flex;align-items:center;gap:20px;}
.caf-move{display:flex;align-items:center;gap:8px;font-size:14.5px;color:#3a4250;font-weight:500;}
.caf-move svg{color:#5b6475;}
.caf-ic{color:#7c8698;display:flex;}
.caf-prof{width:32px;height:32px;border-radius:999px;background:#f0e7df;color:#9a6b46;display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:600;}

/* main */
.caf-main{flex:1;position:relative;overflow:hidden;}
.caf-screen{position:absolute;inset:0;opacity:0;pointer-events:none;transition:opacity .5s cubic-bezier(.22,.61,.36,1);overflow:hidden;}
.caf-screen.is-on{opacity:1;}
.caf-page{position:absolute;inset:0;padding:40px 0 0;display:flex;flex-direction:column;align-items:center;animation:cafIn .55s cubic-bezier(.22,.61,.36,1) both;}
@keyframes cafIn{from{opacity:0;transform:translateY(14px);}to{opacity:1;transform:none;}}
.caf-page>*{width:100%;max-width:1280px;}
.caf-h1{font-size:30px;font-weight:400;color:#222a37;letter-spacing:-.01em;margin:0 0 26px;}
.caf-h2{font-size:22px;font-weight:400;color:#222a37;margin:0;}

/* dashboard action buttons */
.caf-actions{display:flex;gap:12px;margin-bottom:26px;}
.caf-act{display:inline-flex;align-items:center;gap:8px;border-radius:999px;font-size:14px;font-weight:500;
  padding:9px 18px;border:1px solid #e6e8ee;background:#fff;color:#3a4250;cursor:default;}
.caf-act svg{color:#69728a;}
.caf-act-blue{background:#1f3cd6;color:#fff;border-color:#1f3cd6;}
.caf-act-blue svg{color:#fff;}
.caf-act-out{color:#aab2c2;border-color:#e6e8ee;}

.caf-grid2{display:grid;grid-template-columns:1.32fr 1fr;gap:26px;}
.caf-grid-det{grid-template-columns:1.32fr 1fr;}
.caf-card{border:1px solid #ebedf1;border-radius:16px;padding:24px;background:#fff;}

/* balance card */
.caf-bal-top{display:flex;align-items:center;justify-content:space-between;}
.caf-bal-title{display:inline-flex;align-items:center;gap:8px;font-size:15px;color:#5b6475;}
.caf-bal-title svg{color:#3a5bd9;}
.caf-bal-tg{display:inline-flex;gap:0;border:1px solid #e6e8ee;border-radius:9px;overflow:hidden;}
.caf-tg-on{padding:6px 9px;background:#f3f5f8;color:#2b3240;display:flex;}
.caf-tg-off{padding:6px 9px;color:#9aa2b1;display:flex;}
.caf-bal-amt{font-size:34px;font-weight:400;color:#222a37;letter-spacing:-.01em;margin:14px 0 4px;display:flex;align-items:baseline;gap:9px;}
.caf-cur-tag{font-size:13px;font-weight:600;letter-spacing:.04em;color:#9aa2b1;}
.caf-bal-range{display:inline-flex;align-items:center;gap:6px;font-size:13px;color:#8a93a3;margin-bottom:8px;}
.caf-chart{height:150px;}
.caf-chart svg{width:100%;height:100%;display:block;}
.caf-chart-x{display:flex;justify-content:space-between;font-size:11.5px;color:#aab2c2;margin-top:6px;}

/* cuentas card */
.caf-cuentas-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:6px;}
.caf-cuentas-top>span:first-child{font-size:18px;color:#222a37;}
.caf-dots{color:#aab2c2;font-size:18px;}
.caf-crow{display:flex;align-items:center;gap:12px;padding:9px 0;}
.caf-crow-n{font-size:14px;color:#2b3240;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.caf-crow-b{font-size:14px;color:#2b3240;font-weight:500;}
.caf-av-m{display:inline-flex;align-items:center;justify-content:center;flex:none;border-radius:999px;font-weight:700;line-height:1;}
.caf-verall{display:flex;align-items:center;gap:11px;padding-top:10px;font-size:14px;color:#5b6475;}
.caf-plus6{width:30px;height:30px;border-radius:999px;background:#f3f5f8;color:#8a93a3;display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;}
.caf-verall-ic{width:30px;height:30px;border-radius:999px;background:#f3f5f8;color:#8a93a3;display:inline-flex;align-items:center;justify-content:center;}

/* movimientos */
.caf-mov-head{display:flex;align-items:center;justify-content:space-between;margin:36px auto 18px;}
.caf-month{display:inline-flex;align-items:center;gap:14px;font-size:15px;color:#3a4250;}
.caf-month svg{color:#9aa2b1;}
.caf-mov-k{font-size:14px;color:#8a93a3;}
.caf-mov-v{font-size:26px;font-weight:400;margin:4px 0 18px;letter-spacing:-.01em;display:flex;align-items:baseline;gap:8px;}
.caf-green{color:#1f9d63;}
.caf-olive{color:#8a8a3c;}
.caf-mov-sub{font-size:13px;color:#9aa2b1;margin-bottom:6px;}
.caf-crow-b2{border-top:1px solid #f1f3f6;}
.caf-verrow{border-top:1px solid #f1f3f6;color:#5b6475;}
.caf-verrow .caf-crow-n{font-size:14px;color:#3a4250;}

/* accounts list */
.caf-head-row{display:flex;align-items:flex-start;justify-content:space-between;}
.caf-head-actions{display:flex;align-items:center;gap:18px;}
.caf-headlink{display:inline-flex;align-items:center;gap:8px;font-size:14.5px;color:#3a4250;font-weight:500;}
.caf-headlink svg{color:#5b6475;}
.caf-totals{display:flex;align-items:flex-start;gap:64px;margin:6px 0 30px;}
.caf-tot-k{font-size:14px;color:#9099a8;margin-bottom:6px;}
.caf-tot-bigv{font-size:34px;font-weight:400;color:#222a37;letter-spacing:-.01em;display:flex;align-items:center;gap:8px;}
.caf-shield{color:#3a5bd9;display:flex;}
.caf-tot-sv{font-size:15px;color:#3a4250;}
.caf-tbl{border-top:1px solid #eef0f3;}
.caf-tbl-head{display:flex;justify-content:space-between;padding:14px 4px;font-size:13px;color:#9aa2b1;border-bottom:1px solid #eef0f3;}
.caf-trow{display:flex;align-items:center;justify-content:space-between;padding:16px 8px;border-bottom:1px solid #f1f3f6;border-radius:10px;transition:background .2s ease;}
.caf-trow.is-hover{background:#f7f8fa;}
.caf-trow-l{display:flex;align-items:center;gap:14px;}
.caf-trow-meta{display:flex;flex-direction:column;gap:3px;}
.caf-trow-n{font-size:15px;color:#222a37;}
.caf-trow-c{font-size:13px;color:#9aa2b1;}
.caf-trow-b{font-size:15px;color:#2b3240;font-weight:500;}

/* detail */
.caf-det-top{display:flex;align-items:flex-start;justify-content:space-between;}
.caf-det-amt{font-size:34px;font-weight:400;color:#222a37;letter-spacing:-.01em;margin-top:4px;display:flex;align-items:baseline;gap:9px;}
.caf-det-btns{display:flex;gap:10px;}
.caf-det-stats{display:flex;gap:60px;margin-top:24px;}
.caf-det-sv{font-size:15px;color:#2b3240;margin-top:5px;}
.caf-det-sep{height:1px;background:#eef0f3;margin:22px 0 16px;}
.caf-link{display:inline-flex;align-items:center;gap:5px;color:#2a4bd0;font-size:14.5px;font-weight:500;}
.caf-link svg{color:#2a4bd0;}
.caf-clabe{display:flex;flex-direction:column;}
.caf-clabe-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;}
.caf-clabe-v{display:inline-flex;align-items:center;gap:8px;font-size:15px;color:#2b3240;}
.caf-clabe-v svg{color:#9aa2b1;}
.caf-clabe-addr{display:flex;align-items:flex-start;gap:8px;justify-content:flex-end;text-align:right;font-size:14px;color:#3a4250;line-height:1.5;}
.caf-clabe-addr svg{color:#9aa2b1;flex:none;margin-top:2px;}
.caf-clabe-sep{height:1px;background:#eef0f3;margin:18px 0 14px;}
.caf-clabe-docs{display:flex;align-items:center;justify-content:flex-end;gap:6px;font-size:14.5px;color:#3a4250;}
.caf-clabe-docs svg{color:#9aa2b1;}
.caf-link2{display:inline-flex;align-items:center;gap:4px;font-size:14px;color:#2a4bd0;font-weight:500;margin-left:14px;}
.caf-txtbl{margin-top:14px;}
.caf-txhead{display:grid;grid-template-columns:108px 1fr 200px 168px;gap:16px;padding:0 0 13px;font-size:13px;color:#9aa2b1;}
.caf-r{text-align:right;}
.caf-txrow{display:grid;grid-template-columns:108px 1fr 200px 168px;gap:16px;align-items:center;padding:15px 0;border-top:1px solid #f1f3f6;font-size:14px;}
.caf-tx-d{color:#8a93a3;}
.caf-tx-c{display:flex;align-items:center;gap:11px;color:#2b3240;}
.caf-tx-amt{text-align:right;color:#2b3240;font-weight:500;}
.caf-tx-m{display:flex;align-items:center;gap:7px;color:#8a93a3;font-size:13.5px;}
.caf-tx-m svg{color:#aab2c2;}

/* cursor */
.caf-cursor{position:absolute;width:21px;height:21px;margin:0 0 0 -1px;z-index:40;pointer-events:none;
  transition:left 1s cubic-bezier(.33,0,.2,1),top 1s cubic-bezier(.33,0,.2,1),transform .18s ease;}
.caf-cursor svg{display:block;filter:drop-shadow(0 1px 2px rgba(0,0,0,.3));}
.caf-cursor.is-press{transform:scale(.82);}
.caf-click{position:absolute;width:34px;height:34px;margin:-17px 0 0 -17px;z-index:35;pointer-events:none;
  border-radius:50%;border:2px solid rgba(31,60,214,.5);animation:cafClick .6s cubic-bezier(.2,.7,.2,1) forwards;}
@keyframes cafClick{0%{opacity:.85;transform:scale(.3);}100%{opacity:0;transform:scale(1.5);}}

/* Tablet / phone: the artboard is stretched to fill the stage height, but the
   dashboard content flows from the top — leaving a big empty band at the
   bottom. Center the content column vertically so the demo sits in the middle
   of the window instead of being top-loaded. Desktop (≥1025px) is untouched. */
@media (max-width:1024px){
  .caf-page{ justify-content:center; padding-top:0; padding-bottom:0; }
}
`;

window.CuentasFlow = CuentasFlow;
