/* global React, GlossaryTooltip, Watermark, Banner, EpisodeHeader, DisclaimerFooter, RubricMeter */
// P06 — Lab variants (S3 slot rendered as standalone screens for the canvas)

const { useState: useL } = React;

// Lab wrapper: episode chrome + central main area only
const LabFrame = ({ breadcrumb, title, bigQuestion, type, duration = 28, total = 30, children }) => (
  <div className="artboard-root">
    <EpisodeHeader
      breadcrumb={breadcrumb}
      title={title}
      bigQuestion={bigQuestion}
      durationDone={duration}
      durationTotal={total}
    />
    <div style={{ maxWidth: 1300, margin: '0 auto', padding: '24px 28px' }}>
      <div className="row" style={{ gap: 8, marginBottom: 18, flexWrap: 'wrap' }}>
        <span className="badge" style={{ borderColor: 'var(--accent)', color: 'var(--accent)' }}>S3 · LAB</span>
        <span className="badge">{type}</span>
        <span className="txt-xs txt-sec">Slot polimórfico del Episode Shell</span>
      </div>
      {children}
    </div>
    <DisclaimerFooter />
  </div>
);

// ============================================================================
// P06a — CASE-X (M00.E00 — Dos empresas, mismo P/E)
// ============================================================================
const P06a_CASEX = () => {
  const decisions = [
    { id: 'D1', label: 'Mirar drivers fundamentales o usar solo P/E aparente', choice: 'drivers' },
    { id: 'D2', label: 'Pagar premium por crecimiento sostenible o por crecimiento aparente', choice: 'sostenible' },
    { id: 'D3', label: 'Cierre del veredicto', choice: null },
  ];

  return (
    <LabFrame
      breadcrumb="C04-A · M00 · E00"
      title="Dos empresas, mismo P/E: ¿cuál pagarías?"
      bigQuestion="P/E 14× en ambas. Una crece al 12%, la otra al 3%. ¿Te cuesta lo mismo el múltiplo?"
      type="CASE-X · bifurcación"
      duration={22} total={30}
    >
      <div style={{ display: 'grid', gridTemplateColumns: '1.5fr 1fr', gap: 24 }}>
        <div>
          {/* Two companies side by side */}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, marginBottom: 20 }}>
            {[
              { ticker: 'NORTE.MC', archetype: 'compounder', pe: '14×', roe: 25, g: 12, ke: 9, gordon: '21,9×', delta: 'descuento -36%', tone: 'pass' },
              { ticker: 'SUR.MC',   archetype: 'mature',     pe: '14×', roe: 8,  g: 3,  ke: 9, gordon: '10,4×', delta: 'premium +35%', tone: 'fail' },
            ].map((c, i) => (
              <div key={c.ticker} className="card" style={{ padding: 16, borderColor: c.tone === 'pass' ? 'rgba(91,198,143,0.4)' : 'rgba(216,92,92,0.4)' }}>
                <div className="row" style={{ justifyContent: 'space-between', marginBottom: 10 }}>
                  <span className="mono bold">{c.ticker}</span>
                  <span className="badge">{c.archetype}</span>
                </div>
                <div className="trio-card" style={{ padding: 10 }}>
                  <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase' }}>P/E observado</div>
                  <div className="trio-value">{c.pe}</div>
                  <div className="row" style={{ gap: 6, flexWrap: 'wrap', marginTop: 4 }}>
                    <span className="chip chip-driver">ROE {c.roe}%</span>
                    <span className="chip chip-driver">g {c.g}%</span>
                    <span className="chip chip-driver">Ke {c.ke}%</span>
                  </div>
                </div>
                <div className="divider" style={{ margin: '12px 0' }}/>
                <div className="row" style={{ justifyContent: 'space-between' }}>
                  <span className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase' }}>P/E teórico Gordon</span>
                  <span className="mono" style={{ color: 'var(--signal-driver)', fontSize: 'var(--size-lg)' }}>{c.gordon}</span>
                </div>
                <div className="row" style={{ justifyContent: 'space-between', marginTop: 6 }}>
                  <span className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase' }}>Δ vs observado</span>
                  <span className={`chip ${c.tone === 'pass' ? 'chip-pass' : 'chip-fail'}`}>{c.delta}</span>
                </div>
              </div>
            ))}
          </div>

          {/* Veredicto editor */}
          <div className="card" style={{ padding: 18 }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 10 }}>Tu veredicto</div>
            <div className="row" style={{ gap: 8, marginBottom: 14 }}>
              <span className="chip chip-active">NORTE merece premium</span>
              <span className="chip">SUR merece descuento</span>
              <span className="chip">No emitir veredicto sin más datos</span>
            </div>
            <input className="input serif" style={{ fontFamily: 'var(--font-serif)' }} defaultValue="NORTE.MC justifica P/E observado por ROE 25% y g 12% sostenibles: el múltiplo aparente subestima los drivers. SUR.MC con ROE 8% y g 3% no sostiene 14×."/>
          </div>
        </div>

        {/* Right: decision tree */}
        <div className="card" style={{ padding: 16 }}>
          <div className="row" style={{ justifyContent: 'space-between', marginBottom: 14 }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase' }}>Árbol de bifurcación</div>
            <span className="chip">2 / 3 decisiones</span>
          </div>
          <svg viewBox="0 0 320 360" style={{ width: '100%', height: 'auto' }}>
            {/* connectors */}
            <line x1="160" y1="40" x2="80" y2="100" stroke="var(--border-strong)" strokeWidth="1"/>
            <line x1="160" y1="40" x2="240" y2="100" stroke="var(--signal-pass)" strokeWidth="2"/>
            <line x1="240" y1="100" x2="180" y2="180" stroke="var(--border-strong)" strokeWidth="1"/>
            <line x1="240" y1="100" x2="280" y2="180" stroke="var(--signal-pass)" strokeWidth="2"/>
            <line x1="280" y1="180" x2="220" y2="260" stroke="var(--border-strong)" strokeWidth="1"/>
            <line x1="280" y1="180" x2="280" y2="260" stroke="var(--accent)" strokeWidth="2"/>

            {/* D1 */}
            <g>
              <rect x="120" y="20" width="80" height="36" rx="6" fill="var(--surface-2)" stroke="var(--border-strong)"/>
              <text x="160" y="42" textAnchor="middle" fill="var(--text-primary)" fontSize="11" fontFamily="var(--font-mono)">D1</text>
            </g>

            {/* D1 children */}
            <g>
              <rect x="20" y="90" width="120" height="36" rx="6" fill="var(--surface-2)" stroke="var(--border-default)" opacity="0.5"/>
              <text x="80" y="106" textAnchor="middle" fill="var(--text-tertiary)" fontSize="10">solo P/E aparente</text>
              <text x="80" y="118" textAnchor="middle" fill="var(--signal-fail)" fontSize="9">↳ trampa</text>
            </g>
            <g>
              <rect x="200" y="90" width="80" height="36" rx="6" fill="rgba(91,198,143,0.15)" stroke="var(--signal-pass)"/>
              <text x="240" y="106" textAnchor="middle" fill="var(--signal-pass)" fontSize="10">drivers</text>
              <text x="240" y="118" textAnchor="middle" fill="var(--signal-pass)" fontSize="9">↳ elegido</text>
            </g>

            {/* D2 */}
            <g>
              <rect x="220" y="170" width="40" height="20" rx="3" fill="var(--surface-2)" stroke="var(--border-default)" opacity="0.5"/>
              <text x="240" y="184" textAnchor="middle" fill="var(--text-tertiary)" fontSize="9">aparente</text>
            </g>
            <g>
              <rect x="240" y="170" width="80" height="20" rx="3" fill="rgba(91,198,143,0.15)" stroke="var(--signal-pass)"/>
              <text x="280" y="184" textAnchor="middle" fill="var(--signal-pass)" fontSize="9">sostenible</text>
            </g>

            {/* D3 in progress */}
            <g>
              <rect x="240" y="250" width="80" height="36" rx="6" fill="rgba(107,163,255,0.12)" stroke="var(--accent)" strokeDasharray="3 3"/>
              <text x="280" y="266" textAnchor="middle" fill="var(--accent)" fontSize="10">D3 · actual</text>
              <text x="280" y="278" textAnchor="middle" fill="var(--accent)" fontSize="9">veredicto</text>
            </g>

            {/* leaf — trampa visible al final */}
            <g>
              <text x="80" y="148" textAnchor="middle" fill="var(--signal-fail)" fontSize="9">veredicto sin drivers</text>
              <text x="80" y="160" textAnchor="middle" fill="var(--text-tertiary)" fontSize="9">→ aprenderías la trampa después</text>
            </g>

            {/* legend */}
            <g transform="translate(20, 320)">
              <circle cx="6" cy="6" r="4" fill="var(--signal-pass)"/>
              <text x="16" y="10" fill="var(--text-tertiary)" fontSize="10">tu ruta</text>
              <circle cx="80" cy="6" r="4" fill="var(--accent)"/>
              <text x="90" y="10" fill="var(--text-tertiary)" fontSize="10">decisión actual</text>
              <circle cx="200" cy="6" r="4" fill="var(--border-strong)"/>
              <text x="210" y="10" fill="var(--text-tertiary)" fontSize="10">descartada</text>
            </g>
          </svg>
          <div className="banner banner-hypothesis" style={{ marginTop: 12 }}>
            <span className="banner-icon">?</span>
            <div>
              <div className="banner-title">Consecuencia visible</div>
              <div className="banner-text">Si eliges veredicto sin invocar al menos 2 drivers cuantitativos, el comité te pedirá rehacer.</div>
            </div>
          </div>
        </div>
      </div>
    </LabFrame>
  );
};

// ============================================================================
// P06c — CASE (M01.E04 — Mismo P/E, tres calidades)
// ============================================================================
const P06c_CASE = () => {
  const [ranking, setRanking] = useL(['ALFA', 'BETA', 'GAMM']);

  const companies = {
    ALFA: { name: 'ALFA.MC', cash_conv: 96, recurrence: 88, transparency: 92, verdict: 'pass', tag: 'stalwart sólida' },
    BETA: { name: 'BETA.MC', cash_conv: 78, recurrence: 62, transparency: 71, verdict: 'hypothesis', tag: 'mixto · revisar' },
    GAMM: { name: 'GAMM.MC', cash_conv: 58, recurrence: 35, transparency: 48, verdict: 'warning', tag: 'cíclica en pico, SBC alto' },
  };

  const move = (idx, dir) => {
    setRanking(prev => {
      const n = [...prev];
      const t = n[idx];
      n[idx] = n[idx + dir];
      n[idx + dir] = t;
      return n;
    });
  };

  return (
    <LabFrame
      breadcrumb="C04-A · M01 · E04"
      title="Mismo P/E, tres calidades: ordenar sin mirar precio"
      bigQuestion="Tres empresas, P/E 18×. ¿Cuál merece premium, cuál descuento y por qué?"
      type="CASE · drag-and-drop ranking"
      duration={26} total={35}
    >
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 320px', gap: 24 }}>
        <div>
          <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 10 }}>Tu ranking · arrastra o usa botones</div>
          <div className="col" style={{ gap: 10 }}>
            {ranking.map((id, idx) => {
              const c = companies[id];
              const verdictTone = c.verdict === 'pass' ? 'chip-pass' : c.verdict === 'hypothesis' ? 'chip-hypothesis' : 'chip-warning';
              return (
                <div key={id} className="card" style={{ padding: 14, display: 'grid', gridTemplateColumns: '40px 1fr auto auto', gap: 14, alignItems: 'center' }}>
                  <div className="mono" style={{ fontSize: 'var(--size-2xl)', color: 'var(--text-tertiary)', textAlign: 'center' }}>#{idx+1}</div>
                  <div>
                    <div className="row" style={{ gap: 8, marginBottom: 6 }}>
                      <span className="mono bold">{c.name}</span>
                      <span className="badge">P/E 18×</span>
                      <span className="txt-xs txt-sec">{c.tag}</span>
                    </div>
                    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 10 }}>
                      {[
                        { label: 'Cash conv.', val: c.cash_conv, target: 95 },
                        { label: 'Recurrencia', val: c.recurrence, target: 80 },
                        { label: 'Transparencia', val: c.transparency, target: 80 },
                      ].map(k => {
                        const tone = k.val >= k.target ? 'pass' : k.val >= k.target - 15 ? 'warn' : 'fail';
                        return (
                          <div key={k.label} className="col" style={{ gap: 3 }}>
                            <div className="row" style={{ justifyContent: 'space-between' }}>
                              <span className="txt-xs txt-ter">{k.label}</span>
                              <span className="mono txt-xs">{k.val}%</span>
                            </div>
                            <div className="rubric-bar"><div className={`rubric-fill ${tone}`} style={{ width: `${k.val}%` }}/></div>
                          </div>
                        );
                      })}
                    </div>
                  </div>
                  <span className={`chip ${verdictTone}`}>
                    {c.verdict === 'pass' && '● verde'}
                    {c.verdict === 'hypothesis' && '● ámbar'}
                    {c.verdict === 'warning' && '● rojo'}
                  </span>
                  <div className="col" style={{ gap: 4 }}>
                    <button className="btn btn-ghost" style={{ padding: '2px 8px' }} disabled={idx === 0} onClick={() => move(idx, -1)}>↑</button>
                    <button className="btn btn-ghost" style={{ padding: '2px 8px' }} disabled={idx === ranking.length - 1} onClick={() => move(idx, 1)}>↓</button>
                  </div>
                </div>
              );
            })}
          </div>

          <Banner
            tone="driver"
            icon="✓"
            title="feedback_bank.excellent"
            text="Tu orden coincide con la convergencia de las 3 dimensiones de quality framework. La palabra fraude no aparece pese a ratios bajos: lenguaje prudente."
          />
        </div>

        <div className="col" style={{ gap: 14 }}>
          <div className="card" style={{ padding: 16 }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 8 }}>Quality framework Finaz</div>
            <ul className="col" style={{ gap: 8, fontSize: 'var(--size-sm)' }}>
              <li className="row" style={{ gap: 8 }}><span className="i-icon">i</span>Cash conversion = CFO / NI &gt; 95%</li>
              <li className="row" style={{ gap: 8 }}><span className="i-icon">i</span>Recurrencia revenue &gt; 80%</li>
              <li className="row" style={{ gap: 8 }}><span className="i-icon">i</span>Transparencia · restate, SBC, auditor</li>
            </ul>
          </div>
          <div className="card" style={{ padding: 16 }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 10 }}>Veredicto agregado</div>
            <ul className="col" style={{ gap: 4, fontSize: 'var(--size-sm)' }}>
              <li><span style={{ color: 'var(--signal-pass)' }}>● verde</span>: 3 dimensiones altas</li>
              <li><span style={{ color: 'var(--signal-hypothesis)' }}>● ámbar</span>: 1 dimensión media</li>
              <li><span style={{ color: 'var(--signal-warning)' }}>● rojo</span>: 2+ bajas</li>
            </ul>
          </div>
        </div>
      </div>
    </LabFrame>
  );
};

// ============================================================================
// P06d — MAP (concept map · M03.E01)
// ============================================================================
const P06d_MAP = () => {
  // 8 companies around a central sector node
  const sector = { x: 280, y: 200, label: 'Sector retail apparel premium' };
  const nodes = [
    { id: 'A', x: 80,  y: 100, label: 'LUXEAR', sub: 'lujo puro · margen 32%',     match: 'no' },
    { id: 'B', x: 100, y: 220, label: 'PREMM',  sub: 'premium · 18%',              match: 'maybe' },
    { id: 'C', x: 130, y: 340, label: 'CASHM',  sub: 'mass · 9%',                  match: 'no' },
    { id: 'D', x: 280, y: 60,  label: 'BOUTQ',  sub: 'boutique nicho · DTC',       match: 'maybe' },
    { id: 'E', x: 460, y: 100, label: 'STREET', sub: 'streetwear premium',         match: 'yes' },
    { id: 'F', x: 480, y: 220, label: 'ATHLE',  sub: 'athleisure premium',         match: 'yes' },
    { id: 'G', x: 440, y: 340, label: 'OUTLT',  sub: 'outlet · descuento',         match: 'no' },
    { id: 'H', x: 280, y: 360, label: 'DEPTM',  sub: 'department store',           match: 'no' },
  ];
  const colorFor = m => m === 'yes' ? 'var(--signal-pass)' : m === 'maybe' ? 'var(--signal-hypothesis)' : 'var(--signal-warning)';

  return (
    <LabFrame
      breadcrumb="C04-A · M03 · E01"
      title="Cuándo 8 empresas no son sector"
      bigQuestion="El listado del proveedor de datos dice sector. ¿Pero son comparables?"
      type="MAP · concept graph"
      duration={20} total={35}
    >
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 280px', gap: 24 }}>
        <div className="card" style={{ padding: 0, overflow: 'hidden', position: 'relative' }}>
          <div style={{ padding: 14, borderBottom: '1px solid var(--border-subtle)', display: 'flex', justifyContent: 'space-between' }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase' }}>Mapa sectorial · arrastra aristas</div>
            <div className="row" style={{ gap: 8 }}>
              <span className="chip chip-pass">3 comparables</span>
              <span className="chip chip-hypothesis">2 pendientes</span>
              <span className="chip chip-warning">3 fuera</span>
            </div>
          </div>
          <svg viewBox="0 0 580 420" style={{ width: '100%', height: 'auto', background: 'var(--surface-1)' }}>
            <defs>
              <pattern id="grid" width="20" height="20" patternUnits="userSpaceOnUse">
                <path d="M 20 0 L 0 0 0 20" fill="none" stroke="var(--border-subtle)" strokeWidth="0.5"/>
              </pattern>
            </defs>
            <rect width="580" height="420" fill="url(#grid)"/>

            {/* edges */}
            {nodes.map(n => (
              <line
                key={`e-${n.id}`}
                x1={sector.x} y1={sector.y} x2={n.x} y2={n.y}
                stroke={colorFor(n.match)}
                strokeWidth={n.match === 'yes' ? 2 : 1}
                strokeDasharray={n.match === 'no' ? '4 4' : n.match === 'maybe' ? '6 3' : '0'}
                opacity={n.match === 'no' ? 0.4 : 1}
              />
            ))}

            {/* central node */}
            <g>
              <circle cx={sector.x} cy={sector.y} r="56" fill="var(--accent-muted)" stroke="var(--accent)" strokeWidth="2"/>
              <text x={sector.x} y={sector.y - 4} textAnchor="middle" fill="var(--text-primary)" fontSize="11" fontWeight="600">SECTOR</text>
              <text x={sector.x} y={sector.y + 12} textAnchor="middle" fill="var(--accent)" fontSize="10">retail apparel</text>
              <text x={sector.x} y={sector.y + 24} textAnchor="middle" fill="var(--accent)" fontSize="10">premium</text>
            </g>

            {/* peripheral nodes */}
            {nodes.map(n => (
              <g key={n.id}>
                <circle cx={n.x} cy={n.y} r="28" fill="var(--surface-2)" stroke={colorFor(n.match)} strokeWidth="1.5"/>
                <text x={n.x} y={n.y + 3} textAnchor="middle" fill="var(--text-primary)" fontSize="10" fontWeight="600">{n.label}</text>
                <text x={n.x} y={n.y + 44} textAnchor="middle" fill="var(--text-tertiary)" fontSize="9">{n.sub}</text>
              </g>
            ))}
          </svg>
        </div>

        <div className="col" style={{ gap: 14 }}>
          <div className="card" style={{ padding: 14 }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 10 }}>Leyenda de aristas</div>
            <div className="col" style={{ gap: 8, fontSize: 'var(--size-sm)' }}>
              <div className="row" style={{ gap: 10 }}>
                <svg width="40" height="6"><line x1="0" y1="3" x2="40" y2="3" stroke="var(--signal-pass)" strokeWidth="2"/></svg>
                <span>Comparable</span>
              </div>
              <div className="row" style={{ gap: 10 }}>
                <svg width="40" height="6"><line x1="0" y1="3" x2="40" y2="3" stroke="var(--signal-hypothesis)" strokeWidth="1" strokeDasharray="6 3"/></svg>
                <span>Maybe (verificar)</span>
              </div>
              <div className="row" style={{ gap: 10 }}>
                <svg width="40" height="6"><line x1="0" y1="3" x2="40" y2="3" stroke="var(--signal-warning)" strokeWidth="1" strokeDasharray="4 4"/></svg>
                <span>Fuera (sub-sector mismatch)</span>
              </div>
            </div>
          </div>

          <div className="card" style={{ padding: 14 }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 8 }}>Justificaciones</div>
            <div className="col" style={{ gap: 8, fontSize: 'var(--size-sm)' }}>
              <div>
                <div className="bold">LUXEAR — fuera</div>
                <div className="txt-sec txt-xs">Margen 32% vs sector ~18%. Lujo puro tiene economía distinta.</div>
              </div>
              <div>
                <div className="bold">CASHM — fuera</div>
                <div className="txt-sec txt-xs">Mass-market con margen 9%; comparables sería retail mass, no premium.</div>
              </div>
              <div style={{ color: 'var(--signal-hypothesis)' }}>
                <div className="bold">BOUTQ — pendiente</div>
                <div className="txt-sec txt-xs">DTC: ¿comparable o canal aparte?</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </LabFrame>
  );
};

// ============================================================================
// P06f — CALC+CASE (M02.E03 — EV/EBITDA por sector)
// ============================================================================
const P06f_CALCCASE = () => {
  const rows = [
    { ticker: 'INDU.MC', sector: 'Industrial', ev: 4820, ebitda: 580, ev_ebitda: 8.3, sector_med: 9.1, primario: 'EV/EBITDA', verdict: 'driver' },
    { ticker: 'SAAS.MC', sector: 'Software',   ev: 12480, ebitda: 1090, ev_ebitda: 11.5, sector_med: 18.4, primario: 'EV/Sales',   verdict: 'hypothesis' },
    { ticker: 'OILG.MC', sector: 'Energy',     ev: 23900, ebitda: 5210, ev_ebitda: 4.6,  sector_med: 5.2, primario: 'normalized cycle', verdict: 'warning' },
    { ticker: 'RTLB.MC', sector: 'Retail apparel', ev: 1860, ebitda: 215, ev_ebitda: 8.7, sector_med: 9.8, primario: 'EV/EBITDA', verdict: 'driver' },
  ];

  return (
    <LabFrame
      breadcrumb="C04-A · M02 · E03"
      title="EV/EBITDA por sector: cuándo es primario y cuándo es ruido"
      bigQuestion="¿Cuándo el sector exige EV/Sales o normalized, no EV/EBITDA?"
      type="CALC+CASE · calculadora + decisión"
      duration={24} total={35}
    >
      <div style={{ display: 'grid', gridTemplateColumns: '7fr 5fr', gap: 20 }}>
        {/* Left: CALC */}
        <div className="card" style={{ padding: 0, overflow: 'hidden', position: 'relative' }}>
          <div style={{ padding: 14, borderBottom: '1px solid var(--border-subtle)' }}>
            <div className="row" style={{ justifyContent: 'space-between' }}>
              <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase' }}>Calculadora · EV/EBITDA por empresa</div>
              <span className="chip chip-active">4 / 4 filas</span>
            </div>
          </div>
          <table className="table">
            <thead>
              <tr>
                <th>Ticker</th>
                <th>Sector</th>
                <th className="num">EV</th>
                <th className="num">EBITDA</th>
                <th className="num">EV/EBITDA</th>
                <th className="num">sector mediano</th>
                <th>Δ</th>
              </tr>
            </thead>
            <tbody>
              {rows.map(r => {
                const delta = ((r.ev_ebitda / r.sector_med - 1) * 100).toFixed(0);
                return (
                  <tr key={r.ticker}>
                    <td className="mono bold">{r.ticker}</td>
                    <td className="txt-sec">{r.sector}</td>
                    <td className="num">{r.ev.toLocaleString()}</td>
                    <td className="num">{r.ebitda.toLocaleString()}</td>
                    <td className="num" style={{ color: 'var(--signal-driver)', fontSize: 'var(--size-md)' }}>{r.ev_ebitda.toFixed(1)}×</td>
                    <td className="num">{r.sector_med.toFixed(1)}×</td>
                    <td><span className={`chip ${delta < 0 ? 'chip-pass' : 'chip-warning'}`}>{delta > 0 ? '+' : ''}{delta}%</span></td>
                  </tr>
                );
              })}
            </tbody>
          </table>
          <Watermark/>
          <div style={{ height: 16 }}/>
        </div>

        {/* Right: CASE decision panel */}
        <div className="card" style={{ padding: 16 }}>
          <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 12 }}>Decisión · múltiplo primario por sector</div>
          <div className="col" style={{ gap: 10 }}>
            {rows.map(r => {
              const verdictTone = r.verdict === 'driver' ? 'chip-pass' : r.verdict === 'hypothesis' ? 'chip-hypothesis' : 'chip-warning';
              return (
                <div key={r.ticker} style={{ padding: 12, background: 'var(--surface-2)', borderRadius: 'var(--r-md)', border: '1px solid var(--border-subtle)' }}>
                  <div className="row" style={{ justifyContent: 'space-between', marginBottom: 6 }}>
                    <span className="mono bold">{r.ticker}</span>
                    <span className={`chip ${verdictTone}`}>{r.primario}</span>
                  </div>
                  <div className="txt-xs txt-sec" style={{ lineHeight: 1.4 }}>
                    {r.ticker === 'SAAS.MC' && 'EV/Sales primario: SaaS pre-rentable con margen objetivo implícito 30%; EBITDA aún ruidoso.'}
                    {r.ticker === 'OILG.MC' && 'EV/EBITDA en pico cíclico engaña. Normalize a EBITDA mid-cycle (5y avg).'}
                    {r.ticker === 'INDU.MC' && 'Industrial maduro: EV/EBITDA primario. Empresa en descuento -9% sobre sector con drivers neutros.'}
                    {r.ticker === 'RTLB.MC' && 'Retail apparel: EV/EBITDA primario, complementar con EV/Sales por estacionalidad.'}
                  </div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    </LabFrame>
  );
};

// ============================================================================
// P06g — VIDEO+Q-MAP (M01.E01)
// ============================================================================
const P06g_VIDEO = () => {
  const [t, setT] = useL(0.46);
  const questions = [
    { ts: 0.12, label: '01:48', q: '¿Qué diferencia hay entre EPS reportado y EPS_clean?', answered: true },
    { ts: 0.31, label: '04:42', q: 'Identifica un add-back legítimo y uno abusivo en el listado', answered: true },
    { ts: 0.46, label: '07:00', q: 'Empresa con SBC 22% sostenido 3 años: ¿qué haces con el EPS?', answered: false, active: true },
    { ts: 0.62, label: '09:24', q: 'Restructuring presente cada año desde 2018: ¿one-off?', answered: false },
    { ts: 0.84, label: '12:48', q: 'Cierra el memo: 3 adjustments y por qué', answered: false },
  ];

  return (
    <LabFrame
      breadcrumb="C04-A · M01 · E01"
      title="P/E como cociente de un cuento"
      bigQuestion="¿Qué le pides al beneficio antes de meterlo en el denominador de un P/E?"
      type="VIDEO+Q-MAP · video interactivo"
      duration={14} total={30}
    >
      <div style={{ display: 'grid', gridTemplateColumns: '1.7fr 1fr', gap: 20 }}>
        <div>
          {/* Video player */}
          <div className="placeholder-img" style={{ aspectRatio: '16/9', position: 'relative', marginBottom: 12 }}>
            <div className="col" style={{ alignItems: 'center', gap: 12 }}>
              <button className="audio-play-btn" style={{ width: 56, height: 56 }}>
                <svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor"><path d="M4 3l9 5-9 5V3z"/></svg>
              </button>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text-tertiary)' }}>video · earnings depurados · 12 ajustes</span>
              <span style={{ fontFamily: 'var(--font-mono)', fontSize: 10, color: 'var(--text-tertiary)' }}>captions ON · 1×</span>
            </div>
            {/* paused overlay question */}
            <div style={{ position: 'absolute', inset: 0, background: 'linear-gradient(to bottom, transparent 60%, rgba(10,12,16,0.95))', display: 'flex', alignItems: 'flex-end', padding: 20 }}>
              <div className="card" style={{ padding: 16, background: 'rgba(17,20,26,0.95)', backdropFilter: 'blur(8px)', borderColor: 'var(--accent)' }}>
                <div className="row" style={{ marginBottom: 8, gap: 8 }}>
                  <span className="chip chip-active">⏸ Q-MAP · 07:00</span>
                  <span className="badge">aplicación</span>
                </div>
                <div className="serif" style={{ fontSize: 'var(--size-md)' }}>
                  Empresa tech con SBC del 22% del revenue sostenido 3 años: ¿cómo ajustas EPS para hacer P/E comparable con cash-comp peers?
                </div>
                <div className="row" style={{ gap: 8, marginTop: 12 }}>
                  <button className="btn btn-primary">Responder y continuar</button>
                  <button className="btn btn-ghost">Pista del Tutor</button>
                </div>
              </div>
            </div>
          </div>

          {/* Timeline */}
          <div className="card" style={{ padding: 14 }}>
            <div className="row" style={{ justifyContent: 'space-between', marginBottom: 10 }}>
              <span className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase' }}>Timeline · Q-MAP</span>
              <span className="mono txt-xs txt-sec">07:00 / 15:18</span>
            </div>
            <div style={{ position: 'relative', height: 30 }}>
              <div style={{ position: 'absolute', left: 0, right: 0, top: 14, height: 2, background: 'var(--surface-3)' }}/>
              <div style={{ position: 'absolute', left: 0, top: 14, height: 2, width: `${t*100}%`, background: 'var(--accent)' }}/>
              {questions.map(q => (
                <div
                  key={q.label}
                  style={{
                    position: 'absolute', left: `calc(${q.ts*100}% - 8px)`, top: 7,
                    width: 16, height: 16, borderRadius: '50%',
                    background: q.active ? 'var(--accent)' : q.answered ? 'var(--signal-pass)' : 'var(--surface-3)',
                    border: `2px solid ${q.active ? 'var(--accent)' : q.answered ? 'var(--signal-pass)' : 'var(--border-strong)'}`,
                    cursor: 'pointer',
                  }}
                  title={q.q}
                />
              ))}
            </div>
            <div className="row" style={{ gap: 14, fontSize: 11, color: 'var(--text-tertiary)', justifyContent: 'space-between', marginTop: 8 }}>
              {questions.map(q => <span key={q.label} className="mono">{q.label}</span>)}
            </div>
          </div>
        </div>

        {/* Right: questions list */}
        <div className="card" style={{ padding: 14 }}>
          <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 12 }}>Preguntas del Q-MAP · 2 / 5</div>
          <div className="col" style={{ gap: 8 }}>
            {questions.map(q => (
              <div key={q.label} className={`card ${q.active ? '' : ''}`} style={{
                padding: 12,
                background: q.active ? 'var(--accent-muted)' : 'var(--surface-2)',
                borderColor: q.active ? 'var(--accent)' : 'var(--border-subtle)',
              }}>
                <div className="row" style={{ justifyContent: 'space-between', marginBottom: 4 }}>
                  <span className="mono txt-xs txt-ter">{q.label}</span>
                  {q.answered && <span className="chip chip-pass" style={{ fontSize: 10 }}>✓ respondida</span>}
                  {q.active && <span className="chip chip-active" style={{ fontSize: 10 }}>actual</span>}
                </div>
                <div className="txt-sm" style={{ color: q.answered ? 'var(--text-tertiary)' : 'var(--text-primary)' }}>{q.q}</div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </LabFrame>
  );
};

// ============================================================================
// P06h — GATE (M01.E06 — Gate del módulo)
// ============================================================================
const P06h_GATE = () => {
  const companies = [
    { ticker: 'COMP-A.MC', pe_clean: 16.2, peg: 0.8, sector_pos: -0.12, recurrence: 92, verdict: 'pass' },
    { ticker: 'COMP-B.MC', pe_clean: 22.4, peg: 1.4, sector_pos:  0.18, recurrence: 68, verdict: 'hypothesis' },
    { ticker: 'COMP-C.MC', pe_clean: 9.8,  peg: 0.6, sector_pos: -0.35, recurrence: 41, verdict: 'warning' },
  ];

  return (
    <LabFrame
      breadcrumb="C04-A · M01 · E06"
      title="Gate M01: veredicto sobre múltiplos beneficio"
      bigQuestion="¿Puedes emitir veredicto sobre 3 empresas sin caer en barata/cara?"
      type="GATE · plantilla de comité"
      duration={26} total={30}
    >
      <div className="card" style={{ padding: 18, marginBottom: 18 }}>
        <div className="row" style={{ justifyContent: 'space-between', marginBottom: 14 }}>
          <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase' }}>Plantilla del comité · 3 empresas × 4 dimensiones</div>
          <div className="row" style={{ gap: 14 }}>
            <span className="txt-xs txt-sec mono">Mastery threshold</span>
            <div style={{ width: 200, position: 'relative' }}>
              <div className="rubric-bar"><div className="rubric-fill pass" style={{ width: '88%' }}/></div>
              <div className="rubric-threshold" style={{ left: '75%', position: 'absolute', top: -2, bottom: -2 }}/>
            </div>
            <span className="mono txt-sm" style={{ color: 'var(--signal-pass)' }}>88 / 75</span>
          </div>
        </div>

        <table className="table">
          <thead>
            <tr>
              <th>Empresa</th>
              <th>(1) P/E clean</th>
              <th>(2) PEG</th>
              <th>(3) Sectorial</th>
              <th>(4) Recurrencia</th>
              <th>Veredicto</th>
              <th>Memo</th>
            </tr>
          </thead>
          <tbody>
            {companies.map(c => (
              <tr key={c.ticker}>
                <td className="mono bold">{c.ticker}</td>
                <td className="num">{c.pe_clean.toFixed(1)}×</td>
                <td className="num" style={{ color: c.peg < 1 ? 'var(--signal-pass)' : c.peg < 1.5 ? 'var(--signal-hypothesis)' : 'var(--signal-warning)' }}>{c.peg.toFixed(2)}</td>
                <td className="num" style={{ color: c.sector_pos < 0 ? 'var(--signal-driver)' : 'var(--signal-warning)' }}>
                  {c.sector_pos > 0 ? '+' : ''}{(c.sector_pos*100).toFixed(0)}%
                </td>
                <td className="num">{c.recurrence}%</td>
                <td>
                  <span className={`chip ${c.verdict === 'pass' ? 'chip-pass' : c.verdict === 'hypothesis' ? 'chip-hypothesis' : 'chip-warning'}`}>
                    ● {c.verdict === 'pass' ? 'verde' : c.verdict === 'hypothesis' ? 'ámbar' : 'rojo'}
                  </span>
                </td>
                <td><button className="btn btn-ghost txt-xs">✎ editar</button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
        {companies.map(c => (
          <div key={c.ticker} className="card" style={{ padding: 14 }}>
            <div className="row" style={{ justifyContent: 'space-between', marginBottom: 10 }}>
              <span className="mono bold">{c.ticker}</span>
              <span className={`chip ${c.verdict === 'pass' ? 'chip-pass' : c.verdict === 'hypothesis' ? 'chip-hypothesis' : 'chip-warning'}`}>
                ● {c.verdict === 'pass' ? 'verde' : c.verdict === 'hypothesis' ? 'ámbar' : 'rojo'}
              </span>
            </div>
            <div className="serif txt-sm" style={{ lineHeight: 1.5, color: 'var(--text-secondary)' }}>
              {c.ticker === 'COMP-A.MC' && 'Convergencia positiva en 4 dimensiones: P/E clean por debajo de mediana sectorial, PEG defendible con g sostenible, recurrencia >90%.'}
              {c.ticker === 'COMP-B.MC' && 'Mixto: PEG 1,4× exige g superior al techo sectorial. Recurrencia 68% señal de proyectos one-off. Evidencia pendiente sobre backlog 24m.'}
              {c.ticker === 'COMP-C.MC' && 'Múltiplo aparente bajo no compensa recurrencia 41% ni dispersión -35% vs sector. Investigar earnings cyclicality antes de tesis.'}
            </div>
          </div>
        ))}
      </div>
    </LabFrame>
  );
};

// ============================================================================
// P06e — MAP+CASE (M01.E05 — sectorial mediano)
// ============================================================================
const P06e_MAPCASE = () => {
  return (
    <LabFrame
      breadcrumb="C04-A · M01 · E05"
      title="P/E sectorial mediano: cuándo es útil y cuándo distrae"
      bigQuestion="¿El P/E mediano sectorial es benchmark o ruido?"
      type="MAP+CASE · mapa + decisión"
      duration={22} total={30}
    >
      <div style={{ display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 20 }}>
        {/* Boxplot-style visualization */}
        <div className="card" style={{ padding: 18 }}>
          <div className="row" style={{ justifyContent: 'space-between', marginBottom: 14 }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase' }}>Dispersión P/E por sector · IQR + outliers</div>
            <span className="chip chip-hypothesis">2 outliers detectados</span>
          </div>
          <svg viewBox="0 0 540 340" style={{ width: '100%', height: 'auto' }}>
            {/* axis */}
            <line x1="80" y1="20" x2="80" y2="300" stroke="var(--border-default)"/>
            <line x1="80" y1="300" x2="520" y2="300" stroke="var(--border-default)"/>
            {/* y labels */}
            {[5, 10, 15, 20, 25, 30, 35].map((v, i) => (
              <g key={v}>
                <text x="70" y={300 - (v/40)*280} textAnchor="end" fill="var(--text-tertiary)" fontSize="10" fontFamily="var(--font-mono)">{v}×</text>
                <line x1="78" x2="82" y1={300 - (v/40)*280} y2={300 - (v/40)*280} stroke="var(--border-strong)"/>
              </g>
            ))}

            {/* Boxplots */}
            {[
              { x: 160, label: 'Software',   q1: 22, q3: 36, med: 28, min: 12, max: 48, iqr_ratio: 0.50, outlier: { v: 48, label: 'Outlier P95' } },
              { x: 300, label: 'Industrial', q1: 11, q3: 17, med: 14, min: 7,  max: 22, iqr_ratio: 0.43, outlier: null },
              { x: 440, label: 'Semis',      q1: 14, q3: 38, med: 22, min: 9,  max: 52, iqr_ratio: 1.09, outlier: { v: 52, label: 'fabless vs IDM mix' } },
            ].map(b => {
              const yScale = v => 300 - (v/40)*280;
              const w = 60;
              return (
                <g key={b.label}>
                  <line x1={b.x} y1={yScale(b.min)} x2={b.x} y2={yScale(b.q1)} stroke="var(--text-tertiary)"/>
                  <line x1={b.x} y1={yScale(b.q3)} x2={b.x} y2={yScale(b.max)} stroke="var(--text-tertiary)"/>
                  <rect x={b.x - w/2} y={yScale(b.q3)} width={w} height={yScale(b.q1) - yScale(b.q3)} fill="var(--accent-muted)" stroke="var(--accent)"/>
                  <line x1={b.x - w/2} y1={yScale(b.med)} x2={b.x + w/2} y2={yScale(b.med)} stroke="var(--signal-driver)" strokeWidth="2"/>
                  <text x={b.x} y={yScale(b.med) - 6} textAnchor="middle" fill="var(--signal-driver)" fontSize="10" fontFamily="var(--font-mono)">{b.med}×</text>

                  {/* min/max ticks */}
                  <line x1={b.x - 8} y1={yScale(b.min)} x2={b.x + 8} y2={yScale(b.min)} stroke="var(--text-tertiary)"/>
                  <line x1={b.x - 8} y1={yScale(b.max)} x2={b.x + 8} y2={yScale(b.max)} stroke="var(--text-tertiary)"/>

                  {b.outlier && (
                    <g>
                      <circle cx={b.x} cy={yScale(b.outlier.v)} r="4" fill="var(--signal-hypothesis)"/>
                      <line x1={b.x + 8} y1={yScale(b.outlier.v)} x2={b.x + 30} y2={yScale(b.outlier.v) - 18} stroke="var(--signal-hypothesis)" strokeDasharray="2 2"/>
                      <text x={b.x + 32} y={yScale(b.outlier.v) - 20} fill="var(--signal-hypothesis)" fontSize="10">{b.outlier.label}</text>
                    </g>
                  )}

                  <text x={b.x} y={320} textAnchor="middle" fill="var(--text-primary)" fontSize="11" fontWeight="500">{b.label}</text>
                  <text x={b.x} y={334} textAnchor="middle" fill="var(--text-tertiary)" fontSize="10">IQR/med: {b.iqr_ratio.toFixed(2)}</text>
                </g>
              );
            })}
          </svg>
        </div>

        <div className="col" style={{ gap: 12 }}>
          <div className="card" style={{ padding: 14 }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 10 }}>Decisión por sector</div>
            <div className="col" style={{ gap: 10, fontSize: 'var(--size-sm)' }}>
              <div>
                <div className="row" style={{ marginBottom: 4 }}>
                  <span className="bold">Software</span>
                  <span className="chip chip-pass" style={{ marginLeft: 'auto' }}>benchmark útil</span>
                </div>
                <span className="txt-xs txt-sec">IQR/med 0,50 → relativamente homogéneo. Mediana 28× es ancla razonable.</span>
              </div>
              <div>
                <div className="row" style={{ marginBottom: 4 }}>
                  <span className="bold">Industrial</span>
                  <span className="chip chip-pass" style={{ marginLeft: 'auto' }}>benchmark útil</span>
                </div>
                <span className="txt-xs txt-sec">IQR/med 0,43. Mediana 14× con dispersión moderada.</span>
              </div>
              <div>
                <div className="row" style={{ marginBottom: 4 }}>
                  <span className="bold">Semis</span>
                  <span className="chip chip-warning" style={{ marginLeft: 'auto' }}>ruido — sub-sector</span>
                </div>
                <span className="txt-xs txt-sec">IQR/med 1,09 → demasiada dispersión. Mezcla fabless (multiples altos) e IDM (capital-intensivos). Usar sub-sectorial.</span>
              </div>
            </div>
          </div>

          <div className="card" style={{ padding: 14 }}>
            <div className="txt-xs txt-ter mono" style={{ textTransform: 'uppercase', marginBottom: 8 }}>Outliers · tesis o trampa</div>
            <div className="col" style={{ gap: 8, fontSize: 'var(--size-sm)' }}>
              <div>
                <div className="row" style={{ gap: 6 }}><span className="chip chip-hypothesis">P95 software</span></div>
                <div className="txt-xs txt-sec" style={{ marginTop: 4 }}>SaaS premium con moat verticalizado y g 35% sostenible 4 años. <em>Tesis estructural</em>.</div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </LabFrame>
  );
};

Object.assign(window, { P06a_CASEX, P06c_CASE, P06d_MAP, P06e_MAPCASE, P06f_CALCCASE, P06g_VIDEO, P06h_GATE, LabFrame });
