/* Clara v2 — Mockups: Chat & Dashboard (more app-like, richer detail) */

function ChatMockupV2() {
  const ref = React.useRef(null);
  const [stage, setStage] = React.useState(-1);
  const beatRef = useBeatAnchor('beat-5');

  React.useEffect(() => {
    const item = {
      get el() { return ref.current; },
      once: true,
      onEnter: () => { if (stage === -1) setStage(0); }
    };
    ScrollObs.add(item);
    return () => ScrollObs.remove(item);
  }, [stage]);

  const advance = () => setStage((s) => s + 1);

  const userQ1 = '¿Cuánto capital tengo en productos que no se mueven hace 90 días?';
  const claraA1 = 'Tienes $2.3M en inventario sin rotación en los últimos 90 días. El 64% se concentra en 12 referencias y el costo financiero mensual de mantenerlos es $38,000.';
  const userQ2 = '¿Y mi ROAS real incluye el costo de devoluciones?';
  const claraA2 = 'No. El ROAS reportado por tu plataforma de pauta es 3.8x, pero al descontar devoluciones y flete de retorno, tu ROAS real es 2.6x. La diferencia equivale a $1.4M en gasto sin retorno.';

  const [t1] = useTyping(userQ1,  { speed: 22, start: stage >= 0, onDone: () => setTimeout(advance, 350) });
  const [t2] = useTyping(claraA1, { speed: 16, start: stage >= 1, onDone: () => setTimeout(advance, 500) });
  const [t3] = useTyping(userQ2,  { speed: 22, start: stage >= 2, onDone: () => setTimeout(advance, 350) });
  const [t4] = useTyping(claraA2, { speed: 16, start: stage >= 3, onDone: () => setTimeout(advance, 400) });

  return (
    <div className="chat-v2" ref={ref}>
      <div className="titlebar">
        <div className="tlights"><span/><span/><span/></div>
        <div className="crumbs">
          <span className="pip" />
          Workspace · Q1 2025
        </div>
        <div className="right">Sincronizado · hace 2 min</div>
      </div>

      <div className="rail">
        <div className="ico active" title="Chat">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><path d="M3 7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4v6a4 4 0 0 1-4 4H9l-5 4v-4H7"/></svg>
        </div>
        <div className="ico" title="Dashboards">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><rect x="3" y="3" width="8" height="8"/><rect x="13" y="3" width="8" height="8"/><rect x="3" y="13" width="8" height="8"/><rect x="13" y="13" width="8" height="8"/></svg>
        </div>
        <div className="ico" title="Agentes">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><circle cx="12" cy="8" r="4"/><path d="M4 21c0-4 4-7 8-7s8 3 8 7"/></svg>
        </div>
        <div className="ico" title="Fuentes">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><ellipse cx="12" cy="6" rx="8" ry="3"/><path d="M4 6v6c0 1.7 3.6 3 8 3s8-1.3 8-3V6M4 12v6c0 1.7 3.6 3 8 3s8-1.3 8-3v-6"/></svg>
        </div>
        <div className="gap" />
        <div className="ico" title="Ajustes">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 1 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 1 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 1 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9c.66.39 1 1.06 1 1.65a2 2 0 1 1 0 4z"/></svg>
        </div>
      </div>

      <div className="main">
        <div className="convo-head">
          <div className="h"><span className="pin" /> Inventario y rentabilidad · Q1</div>
          <div className="meta">
            <span className="tag">3 fuentes</span>
            <span className="tag">14 turnos</span>
          </div>
        </div>

        {/* USER 1 */}
        {stage >= 0 && (
          <div className="msg">
            <div className="av">tú</div>
            <div>
              <div className="who">tú · 09:42</div>
              <div className="body">{t1}</div>
            </div>
          </div>
        )}

        {/* CLARA 1 */}
        {stage >= 1 && (
          <div className="msg clara">
            <div className="av">C</div>
            <div>
              <div className="who">clara · 09:42</div>
              <div className="body">{t2}</div>
              {stage >= 2 && (
                <React.Fragment>
                  <div className="kpiblock">
                    <div className="k accent">
                      <div className="lbl">Capital dormido</div>
                      <div className="val">$2.3M</div>
                    </div>
                    <div className="k">
                      <div className="lbl">Costo / mes</div>
                      <div className="val">$38K</div>
                    </div>
                    <div className="k">
                      <div className="lbl">SKUs afectados</div>
                      <div className="val">12</div>
                    </div>
                  </div>
                  <div className="sources-inline">
                    <span className="src"><span className="ix">[1]</span> ERP · inventario_activo</span>
                    <span className="src"><span className="ix">[2]</span> Contable · costos_financieros</span>
                    <span className="src"><span className="ix">[3]</span> Reglas · rotación_90d</span>
                  </div>
                </React.Fragment>
              )}
            </div>
          </div>
        )}

        {/* USER 2 */}
        {stage >= 2 && (
          <div className="msg">
            <div className="av">tú</div>
            <div>
              <div className="who">tú · 09:44</div>
              <div className="body">{t3}</div>
            </div>
          </div>
        )}

        {/* CLARA 2 */}
        {stage >= 3 && (
          <div className="msg clara" ref={beatRef}>
            <div className="av">C</div>
            <div>
              <div className="who">clara · 09:44</div>
              <div className="body">{t4}</div>
              {stage >= 4 && (
                <React.Fragment>
                  <div className="kpiblock" style={{ gridTemplateColumns: 'repeat(3, 1fr)' }}>
                    <div className="k">
                      <div className="lbl">ROAS reportado</div>
                      <div className="val">3.8x</div>
                    </div>
                    <div className="k accent">
                      <div className="lbl">ROAS real</div>
                      <div className="val">2.6x</div>
                    </div>
                    <div className="k">
                      <div className="lbl">Gasto sin retorno</div>
                      <div className="val">$1.4M</div>
                    </div>
                  </div>
                  <div className="sources-inline">
                    <span className="src"><span className="ix">[1]</span> Meta Ads · campañas_q1</span>
                    <span className="src"><span className="ix">[2]</span> ERP · devoluciones_q1</span>
                    <span className="src"><span className="ix">[3]</span> ERP · costo_flete</span>
                  </div>
                </React.Fragment>
              )}
            </div>
          </div>
        )}

        <div className="composer">
          <div className="input">
            <span className="caret" />
            <span>Pregúntale algo a Clara…</span>
          </div>
          <div className="send">→</div>
        </div>
      </div>

      <div className="side">
        <h5>Conversaciones</h5>
        <ul>
          <li><span className="lbl">Inventario y rentabilidad</span><span className="meta">hoy</span></li>
          <li><span className="lbl">ROAS real por canal</span><span className="meta">ayer</span></li>
          <li><span className="lbl">Margen Q1 vs Q4</span><span className="meta">3d</span></li>
          <li><span className="lbl">Top SKUs sin rotación</span><span className="meta">5d</span></li>
        </ul>
        <h5>Fuentes activas</h5>
        <ul>
          <li><span className="lbl">Shopify</span><span className="meta">live</span></li>
          <li><span className="lbl">Tu ERP</span><span className="meta">live</span></li>
          <li><span className="lbl">Meta Ads</span><span className="meta">live</span></li>
          <li><span className="lbl">Hojas de cálculo</span><span className="meta">24</span></li>
        </ul>
        <div className="insight-box">
          <div className="head"><span className="p" /> Insight activo</div>
          <div>$2.3M dormidos en 12 SKUs · pausar pauta en 3 liberaría $1.2M en 30 días.</div>
        </div>
      </div>
    </div>
  );
}

/* ─── DASHBOARD V2 — fully interactive ─── */

const DASH_VIEWS = {
  ejecutivo: {
    label: 'Vista ejecutiva',
    kpis: [
      { lbl: 'Ventas reales',       val: '$14.2M', delta: '↓ 8.3%',          neg: true,  spark: [40,55,42,60,48,52,58,50,45,40,52,48], hotIdx: i => i===11 },
      { lbl: 'Margen operativo real',val: '17.4%', delta: 'vs 42% reportado', neg: true,  spark: [50,52,48,46,44,42,40,38,36,34,32,30], hotIdx: i => i>9  },
      { lbl: 'Capital dormido',      val: '$2.3M',  delta: '12 SKUs',          neg: true,  spark: [20,28,32,36,38,42,44,48,52,58,62,68], hotIdx: i => i>8  },
      { lbl: 'Clientes activos',     val: '284',    delta: '↑ 6%',             neg: false, spark: [30,35,38,40,44,48,50,52,54,58,60,62], hotIdx: () => false },
    ],
    chartTitle: 'Ventas reportadas vs reales · 2024',
    chartLegend: [['reported','Reportado'],['real','Real'],['alert','Q1 Δ']],
    reported: [62,70,88,54,60,72,66,58,64,70,76,82],
    real:     [52,58,70,44,50,58,54,48,52,56,62,64],
    hotCol: 2,
    tableTitle: 'Ventas por categoría · Q1',
    tableCols: ['Categoría','Distribución','Valor','YoY'],
    rows: [
      { name:'Categoría A — Decoración', val:'$4.80M', pct:'-22%', neg:true,  meter:100 },
      { name:'Categoría B — Iluminación',val:'$3.60M', pct:'+4%',  neg:false, meter:75  },
      { name:'Categoría C — Textiles',   val:'$3.20M', pct:'-5%',  neg:true,  meter:67  },
      { name:'Categoría D — Cocina',     val:'$2.60M', pct:'+11%', neg:false, meter:54  },
    ],
    insight: <>Tu margen reportado es 42%, pero tu margen <b>operativo real</b> es 17.4%. La brecha viene de devoluciones (Cat A) y costo de flete inversa.</>,
    insightCta: 'Ver desglose →',
  },
  margen: {
    label: 'Margen real',
    kpis: [
      { lbl: 'Margen bruto',    val: '42.1%', delta: '↓ 1.2pp',  neg: true,  spark: [60,62,58,56,58,55,52,50,48,46,44,42], hotIdx: i => i>9  },
      { lbl: 'Margen neto',     val: '9.8%',  delta: '↓ 3.1pp',  neg: true,  spark: [28,30,26,24,22,20,18,16,14,12,11,10], hotIdx: i => i>8  },
      { lbl: 'Margen operativo',val: '17.4%', delta: 'vs 42% rep.',neg: true, spark: [50,48,46,44,42,40,38,36,34,32,30,28], hotIdx: i => i>7  },
      { lbl: 'EBITDA',          val: '$2.9M', delta: '↓ 22%',    neg: true,  spark: [55,52,50,48,46,44,42,40,38,36,35,34], hotIdx: () => false },
    ],
    chartTitle: 'Evolución de márgenes · 12 meses',
    chartLegend: [['reported','Bruto'],['real','Neto'],['alert','Gap']],
    reported: [60,62,58,56,58,55,52,50,48,46,44,42],
    real:     [28,30,26,24,22,20,18,16,14,12,11,10],
    hotCol: 11,
    tableTitle: 'Margen por categoría · Q1',
    tableCols: ['Categoría','Margen bruto','Margen real','Gap'],
    rows: [
      { name:'Decoración',  val:'41.2%', pct:'18.1%', neg:true,  meter:82  },
      { name:'Iluminación', val:'44.8%', pct:'22.3%', neg:false, meter:90  },
      { name:'Textiles',    val:'38.5%', pct:'14.9%', neg:true,  meter:77  },
      { name:'Cocina',      val:'46.1%', pct:'24.7%', neg:false, meter:92  },
    ],
    insight: <>El gap entre margen bruto y real se amplió <b>+8pp este trimestre</b>. Principal causa: devoluciones en Decoración (Cat A) sin reposición de costo logístico.</>,
    insightCta: 'Ver por SKU →',
  },
  canales: {
    label: 'Ventas por canal',
    kpis: [
      { lbl: 'Shopify',   val: '$8.4M',  delta: '↓ 5.1%', neg: true,  spark: [55,60,58,62,56,58,60,54,52,50,48,46], hotIdx: i => i>9  },
      { lbl: 'Meta Ads',  val: '$3.1M',  delta: '↑ 12%',  neg: false, spark: [30,32,35,38,40,42,44,46,48,50,52,54], hotIdx: () => false },
      { lbl: 'B2B directo',val: '$2.2M', delta: '↓ 2.4%', neg: true,  spark: [40,38,36,34,32,30,28,26,24,22,20,18], hotIdx: i => i>8  },
      { lbl: 'Otros',     val: '$0.5M',  delta: '+nuevos', neg: false, spark: [5,6,7,8,9,10,12,14,16,18,20,22],      hotIdx: () => false },
    ],
    chartTitle: 'Ventas por canal · mensual',
    chartLegend: [['reported','Shopify'],['real','Meta'],['alert','B2B']],
    reported: [55,60,58,62,56,58,60,54,52,50,48,46],
    real:     [30,32,35,38,40,42,44,46,48,50,52,54],
    hotCol: 5,
    tableTitle: 'Performance por canal · Q1',
    tableCols: ['Canal','Participación','Ventas','YoY'],
    rows: [
      { name:'Shopify',    val:'$8.40M', pct:'-5%',  neg:true,  meter:100 },
      { name:'Meta Ads',   val:'$3.10M', pct:'+12%', neg:false, meter:37  },
      { name:'B2B directo',val:'$2.20M', pct:'-2%',  neg:true,  meter:26  },
      { name:'Otros',      val:'$0.50M', pct:'+41%', neg:false, meter:6   },
    ],
    insight: <>Shopify sigue siendo el canal principal pero <b>Meta Ads creció +12%</b>. El ROAS real descontando devoluciones baja de 3.8x a 2.6x.</>,
    insightCta: 'Ver ROAS real →',
  },
  inventario: {
    label: 'Inventario zombie',
    kpis: [
      { lbl: 'Capital dormido',   val: '$2.3M', delta: '↑ desde $1.8M', neg: true,  spark: [20,24,28,32,36,40,44,48,54,58,64,68], hotIdx: i => i>7  },
      { lbl: 'SKUs en riesgo',    val: '12',    delta: '>90 días',       neg: true,  spark: [4,5,5,6,7,7,8,9,10,11,12,12],        hotIdx: i => i>8  },
      { lbl: 'Costo mensual',     val: '$38K',  delta: 'almacén + fin.', neg: true,  spark: [18,20,22,24,26,28,30,32,34,36,38,38], hotIdx: i => i>9  },
      { lbl: 'Días prom. parado', val: '118d',  delta: '+22d vs Q4',    neg: true,  spark: [60,65,70,75,80,85,88,92,96,100,108,118],hotIdx: i => i>8 },
    ],
    chartTitle: 'Inventario sin rotación · acumulado',
    chartLegend: [['reported','Valor ($M)'],['real','SKUs'],['alert','Críticos']],
    reported: [20,24,28,32,36,40,44,48,54,58,64,68],
    real:     [4,5,5,6,7,7,8,9,10,11,12,12],
    hotCol: 10,
    tableTitle: 'Top SKUs zombie · Q1',
    tableCols: ['Referencia','Días parado','Valor','Acción'],
    rows: [
      { name:'REF-2241 Tela lino 60"',  val:'$420K', pct:'142d', neg:true,  meter:100 },
      { name:'REF-1892 Denim oscuro',   val:'$380K', pct:'128d', neg:true,  meter:90  },
      { name:'REF-3301 Punto grueso',   val:'$310K', pct:'115d', neg:true,  meter:81  },
      { name:'REF-0847 Forro satinado', val:'$290K', pct:'96d',  neg:true,  meter:68  },
    ],
    insight: <><b>$2.3M dormidos en 12 SKUs</b>. Pausar pauta en las 3 referencias con mayor costo de oportunidad liberaría $1.2M en 30 días.</>,
    insightCta: 'Ver plan de liquidación →',
  },
  cobranza: {
    label: 'Cobranza',
    kpis: [
      { lbl: 'Cartera total',  val: '$6.8M', delta: '+4.2% vs Q4',  neg: false, spark: [50,52,54,56,58,60,62,64,66,65,67,68], hotIdx: () => false },
      { lbl: 'Cartera vencida',val: '$1.2M', delta: '17.6% del total',neg: true, spark: [10,11,12,13,14,15,16,15,16,17,17,18], hotIdx: i => i>8  },
      { lbl: 'Por vencer 30d', val: '$2.1M', delta: 'en riesgo',    neg: true,  spark: [28,30,32,30,28,30,32,28,30,32,30,32], hotIdx: () => false },
      { lbl: 'Recuperada Q1',  val: '$3.5M', delta: '↑ 8% vs Q4',   neg: false, spark: [30,32,34,36,38,40,40,42,44,44,46,48], hotIdx: () => false },
    ],
    chartTitle: 'Aging de cartera · Q1',
    chartLegend: [['reported','Al día'],['real','Vencida'],['alert','Crítica']],
    reported: [70,68,66,64,62,60,58,56,54,52,50,48],
    real:     [18,19,20,21,22,23,24,25,26,27,28,30],
    hotCol: 9,
    tableTitle: 'Top deudores · Q1',
    tableCols: ['Cliente','Días vencido','Saldo','Riesgo'],
    rows: [
      { name:'Distribuidora Norte S.A.', val:'$380K', pct:'62d', neg:true,  meter:100 },
      { name:'Textiles del Pacífico',    val:'$290K', pct:'45d', neg:true,  meter:76  },
      { name:'Moda Express Ltda.',       val:'$210K', pct:'38d', neg:false, meter:55  },
      { name:'Almacenes Centrales',      val:'$180K', pct:'31d', neg:false, meter:47  },
    ],
    insight: <><b>$1.2M en cartera vencida</b>. Distribuidora Norte supera 60 días — activar protocolo de cobranza prioritaria puede recuperar $380K esta semana.</>,
    insightCta: 'Ver gestión →',
  },
};

const PERIODS = ['Q1 2025','Q4 2024','YoY'];
const PERIOD_MULT = { 'Q1 2025': 1, 'Q4 2024': 0.91, 'YoY': 1.08 };
const MONTHS = ['ENE','FEB','MAR','ABR','MAY','JUN','JUL','AGO','SEP','OCT','NOV','DIC'];

function DashMiniBar({ data, animate, hotIdx }) {
  const max = Math.max(...data);
  return (
    <div className="spark">
      {data.map((h, i) => (
        <div
          key={i}
          className={`s ${hotIdx(i) ? 'hot' : ''}`}
          style={{
            height: animate ? Math.round((h / max) * 100) + '%' : '0%',
            transitionDelay: (i * 30) + 'ms',
            transition: 'height 0.9s cubic-bezier(0.16,1,0.3,1)',
          }}
        />
      ))}
    </div>
  );
}

function DashboardMockupV2() {
  const ref = React.useRef(null);
  const [animate, setAnimate] = React.useState(false);
  const [view, setView] = React.useState('ejecutivo');
  const [period, setPeriod] = React.useState('Q1 2025');
  const [hovBar, setHovBar] = React.useState(null);
  const [activeRow, setActiveRow] = React.useState(null);
  const [expandInsight, setExpandInsight] = React.useState(false);
  const [activeKpi, setActiveKpi] = React.useState(null);

  React.useEffect(() => {
    const item = {
      get el() { return ref.current; },
      once: true,
      onEnter: () => setAnimate(true),
    };
    ScrollObs.add(item);
    return () => ScrollObs.remove(item);
  }, []);

  // Reset row/bar selection on view change
  React.useEffect(() => {
    setActiveRow(null);
    setHovBar(null);
    setExpandInsight(false);
    setActiveKpi(null);
  }, [view, period]);

  const d = DASH_VIEWS[view];
  const mult = PERIOD_MULT[period];

  const scaleVal = (raw) => {
    if (!raw) return raw;
    const m = raw.match(/^\$?([\d.]+)([MK]?)$/);
    if (!m) return raw;
    const n = parseFloat(m[1]) * mult;
    return (m[2] ? '$' : '') + n.toFixed(1) + m[2];
  };

  const sideItems = [
    { key: 'ejecutivo',  label: 'Ejecutivo'         },
    { key: 'margen',     label: 'Margen real'        },
    { key: 'canales',    label: 'Ventas por canal'   },
    { key: 'inventario', label: 'Inventario zombie'  },
    { key: 'cobranza',   label: 'Cobranza'           },
  ];

  const tooltipStyle = {
    position: 'absolute', bottom: 'calc(100% + 6px)', left: '50%',
    transform: 'translateX(-50%)',
    background: '#1C1C1C', color: '#F5F0E8',
    fontSize: 10, padding: '4px 7px', borderRadius: 4,
    whiteSpace: 'nowrap', pointerEvents: 'none', zIndex: 10,
    fontFamily: "'DM Sans', sans-serif",
  };

  return (
    <div className="dash-v2" ref={ref}>

      {/* ── topbar ── */}
      <div className="topbar">
        <div className="brand"><span className="pip" /> CLARA</div>
        <div className="tabs">
          {['Inicio','Dashboard ejecutivo','Inventario','Clientes'].map((t, i) => (
            <span
              key={t}
              className={`t ${i === 1 ? 'active' : ''}`}
              style={{ cursor: 'pointer' }}
            >{t}</span>
          ))}
        </div>
        <div className="right">
          <span className="badge"><span className="p" /> Sincronizado · 09:48</span>
        </div>
      </div>

      <div className="layout">

        {/* ── sidebar ── */}
        <aside className="sidebar">
          <h6>Vistas</h6>
          <ul>
            {sideItems.map(s => (
              <li
                key={s.key}
                className={view === s.key ? 'active' : ''}
                style={{ cursor: 'pointer', transition: 'background 120ms' }}
                onClick={() => setView(s.key)}
              >
                <span className="ico" /> {s.label}
              </li>
            ))}
          </ul>
          <h6>Equipo</h6>
          <ul>
            {['Asesor financiero','Estratega de ventas','Analista de inventario'].map(l => (
              <li key={l} style={{ cursor: 'pointer' }}><span className="ico" /> {l}</li>
            ))}
          </ul>
          <h6>Atajos</h6>
          <ul>
            {['Q1 vs Q4','Top SKUs'].map(l => (
              <li key={l} style={{ cursor: 'pointer' }}><span className="ico" /> {l}</li>
            ))}
          </ul>
        </aside>

        {/* ── main content ── */}
        <div className="content">
          <div className="crumb">Workspace / <b>{d.label}</b></div>

          <div className="pagehead">
            <div className="h1">{period} · {d.label}</div>
            <div className="filters">
              {PERIODS.map(p => (
                <span
                  key={p}
                  className={`chip ${period === p ? 'active' : ''}`}
                  style={{ cursor: 'pointer', transition: 'all 120ms' }}
                  onClick={() => setPeriod(p)}
                >{p}</span>
              ))}
            </div>
          </div>

          {/* KPIs */}
          <div className="kpis">
            {d.kpis.map((k, i) => (
              <div
                key={i}
                className={`k ${activeKpi === i ? 'kpi-active' : ''}`}
                style={{
                  cursor: 'pointer',
                  outline: activeKpi === i ? '2px solid #E8006F' : '2px solid transparent',
                  outlineOffset: -2,
                  borderRadius: 8,
                  transition: 'outline-color 150ms',
                }}
                onClick={() => setActiveKpi(activeKpi === i ? null : i)}
              >
                <div className="lbl">{k.lbl}</div>
                <div className="row">
                  <div className="val">{scaleVal(k.val)}</div>
                  <div className={`delta ${k.neg ? 'neg' : 'pos'}`}>{k.delta}</div>
                </div>
                <DashMiniBar data={k.spark} animate={animate} hotIdx={k.hotIdx} />
              </div>
            ))}
          </div>

          {/* Chart + Table */}
          <div className="panels">

            {/* Chart */}
            <div className="panel">
              <div className="ph">
                <div className="t">{d.chartTitle}</div>
                <div className="leg">
                  {d.chartLegend.map(([cls, lbl]) => (
                    <span key={cls} className="it"><span className={`d ${cls}`} /> {lbl}</span>
                  ))}
                </div>
              </div>
              <div className="chart">
                <div className="yax">
                  <span>$100M</span><span>$75M</span><span>$50M</span><span>$25M</span><span>$0</span>
                </div>
                <div className="bars">
                  {MONTHS.map((m, i) => {
                    const isHot = i === d.hotCol;
                    const isHov = hovBar === i;
                    return (
                      <div
                        key={m}
                        className={`col ${isHot ? 'hot' : ''}`}
                        style={{ position: 'relative', cursor: 'pointer' }}
                        onMouseEnter={() => setHovBar(i)}
                        onMouseLeave={() => setHovBar(null)}
                      >
                        {isHov && (
                          <div style={tooltipStyle}>
                            {m}: rep {d.reported[i]} / real {d.real[i]}
                          </div>
                        )}
                        <div
                          className="b reported"
                          style={{
                            height: animate ? Math.round(d.reported[i] * mult) + '%' : '0%',
                            transitionDelay: (i * 40) + 'ms',
                            transition: 'height 1.0s cubic-bezier(0.16,1,0.3,1)',
                            opacity: hovBar !== null && !isHov ? 0.45 : 1,
                          }}
                        />
                        <div
                          className="b real"
                          style={{
                            height: animate ? Math.round(d.real[i] * mult) + '%' : '0%',
                            transitionDelay: (200 + i * 40) + 'ms',
                            transition: 'height 1.0s cubic-bezier(0.16,1,0.3,1)',
                            opacity: hovBar !== null && !isHov ? 0.45 : 1,
                          }}
                        />
                        <span className="lbl">{m}</span>
                      </div>
                    );
                  })}
                </div>
              </div>
            </div>

            {/* Table */}
            <div className="panel">
              <div className="ph">
                <div className="t">{d.tableTitle}</div>
                <div className="leg">
                  <span className="it"><span className="d alert" /> Caída &gt; 10%</span>
                </div>
              </div>
              <div className="table">
                <div className="thead">
                  {d.tableCols.map((c, i) => (
                    <span key={c} style={i > 1 ? { textAlign: 'right' } : {}}>{c}</span>
                  ))}
                </div>
                {d.rows.map((r, i) => (
                  <div
                    key={i}
                    className={`trow ${r.neg && i === 0 ? 'alert' : ''} ${activeRow === i ? 'trow-sel' : ''}`}
                    style={{
                      cursor: 'pointer',
                      background: activeRow === i ? 'rgba(232,0,111,0.06)' : '',
                      transition: 'background 120ms',
                    }}
                    onClick={() => setActiveRow(activeRow === i ? null : i)}
                  >
                    <span className="name">{r.name}</span>
                    <span className="meter">
                      <span style={{
                        width: animate ? r.meter + '%' : '0%',
                        transition: `width 1.1s cubic-bezier(0.16,1,0.3,1) ${200 + i * 80}ms`,
                        background: activeRow === i ? '#E8006F' : undefined,
                      }} />
                    </span>
                    <span className="val">{scaleVal(r.val)}</span>
                    <span className={`pct ${r.neg ? 'neg' : 'pos'}`}>{r.pct}</span>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* Insight bar */}
          <div
            className="insightbar"
            style={{ cursor: 'pointer' }}
            onClick={() => setExpandInsight(e => !e)}
          >
            <div className="head"><span className="p" /> Clara dice</div>
            <div className="body">{d.insight}</div>
            {expandInsight && (
              <div style={{
                marginTop: 10, padding: '10px 12px',
                background: 'rgba(255,255,255,0.08)', borderRadius: 6,
                fontSize: 12, lineHeight: 1.6, color: 'inherit',
                fontFamily: "'DM Sans', sans-serif",
              }}>
                Fuentes: ERP SAP · Shopify · Meta Ads · Google Sheets — Última sync hace 4 min.
              </div>
            )}
            <div className="cta">{expandInsight ? 'Cerrar ↑' : d.insightCta}</div>
          </div>

        </div>
      </div>
    </div>
  );
}

window.ChatMockupV2 = ChatMockupV2;
window.DashboardMockupV2 = DashboardMockupV2;
