// === Escena 05 — «Kanban y Gantt con el mismo filtro» ===  [37.8 s · 9 beats del plan]
//
// LOCUCIÓN (audio/escena-05.mp3): el tablero dibuja una columna por cada estado de tu flujo, con
// su cuenta → arrastras una tarjeta y se guarda solo, salvo que tu flujo no permita ese salto →
// entonces sale un aviso y la tarjeta se queda donde estaba → al lado, la línea de tiempo:
// barras, flechas y cadena crítica → sin fechas no hay barras, y te dice lo que falta → y el
// filtro manda aquí también: si deja fuera una punta, la flecha se va con ella.
//
// Venimos de la ventana del compañero: los chips siguen arriba, intactos, en las dos vistas.
//
// FIDELIDAD:
//   · Lo que rechaza el arrastre es el FLUJO, no el rol: se piden los estados disponibles de esa
//     tarea y si el destino no está, sale el aviso (KanbanViewU.razor:116-121). Nada mira el rol.
//   · El aviso es literal: «No permitido» / «Esta transición de estado no es válida.» Y la tarea
//     no se escribe, así que la tarjeta vuelve a su columna.
//   · Sin carriles: `KanbanViewU` pinta columnas y nada más.
//   · La tarjeta lleva título, clave, prioridad solo si no es Normal, fecha en palabras y UN
//     avatar. No hay icono de comentarios.
//   · La columna «25%» lleva barra debajo porque su nombre es un porcentaje válido.
//   · El aviso de la Gantt vacía solo sale cuando NINGUNA tarea tiene fecha: por eso se enseña
//     el cuadro entero vacío, no una Gantt a medias.
//   · Nada de zoom por días, semanas o meses: `GanttViewU` no configura ninguno.
function EscenaTV05({ t }){
  const T = {
    columnas:1.1,   // "una columna por cada estado" -> las columnas entran en cascada
    cuenta:3.2,     // "con su cuenta" -> los contadores de cabecera
    arrastra:4.9,   // "Arrastras una tarjeta" -> el cursor arrastra a la columna siguiente
    guarda:6.1,     // "y se guarda solo" -> sello verde
    salvo:7.2,      // "salvo que tu flujo no permita" -> arranca el segundo arrastre, el malo
    aviso:10.9,     // "sale un aviso" -> el aviso literal, con su titulo y su texto
    vuelve:12.3,    // "se queda donde estaba" -> la tarjeta vuelve con fade, sin brusquedad
    gantt:15.2,     // "la línea de tiempo" -> corte a la Gantt; los chips siguen arriba
    barras:17.1,    // "Barras por fechas" -> las barras se dibujan
    flechas:18.4,   // "flechas entre tareas" -> las flechas se trazan
    critica:19.6,   // "la cadena crítica encendida" -> la cadena se enciende recorriendo las barras
    sinfechas:22.0, // "Sin fechas no hay barras" -> el cuadro entero vacio
    falta:24.4,     // "Te dice lo que falta" -> el aviso literal de la Gantt vacia
    filtro:28.0,    // "Y el filtro manda aquí también" -> vuelve la Gantt con sus barras
    punta:29.8,     // "si deja fuera una punta" -> una tarea sale y su flecha se va con ella
    cuarta:33.5,    // "Queda la cuarta vista" -> los cuatro botones; el cuarto se enciende
    avisar:36.0,    // "hay que avisar" -> anticipacion de la escena 6
    colStep:0.12,    // cascada entre columnas del tablero
    cardStep:0.08,   // cascada entre tarjetas de una columna
    filaStep:0.10,   // cascada entre filas de la Gantt
    dragDur:1.05,    // lo que tarda una tarjeta en cruzar de columna
  };

  const WX=180, WY=150, WW=1560, CHR=76;
  const AY=WY+CHR;                 // 226
  const BOARD=AY+60;               // 286 · debajo de la fila de chips
  // Seis columnas, una por cada estado del flujo de este inquilino, en el orden del código.
  // A 240 px caben las seis dentro de los 1520 útiles de la ventana.
  const COLW=240, COLGAP=14, COLX0=WX+20;
  const colX = (i)=> COLX0 + i*(COLW+COLGAP);

  const enGantt = t >= T.gantt;
  const vacia = t >= T.sinfechas && t < T.filtro;

  const Ico = ({ n, s=24, c='#64748B', sw=2 })=>{
    const Q = {
      compacta:<path d="M4 7h16M4 12h16M4 17h16"/>,
      kanban:<><rect x="3.5" y="4" width="4.6" height="16" rx="1.2"/><rect x="9.7" y="4" width="4.6" height="11" rx="1.2"/><rect x="15.9" y="4" width="4.6" height="14" rx="1.2"/></>,
      tabla: <><rect x="3" y="4.5" width="18" height="15" rx="2"/><path d="M3 9.5h18M3 14.5h18M9 4.5v15"/></>,
      gantt: <><path d="M3.5 3.5v17"/><path d="M6.5 7h8M9 12h10M6.5 17h6"/></>,
      check: <path d="M5 12.5 L10 17 L19 7"/>,
      alerta:<><path d="M12 3.5 21.5 20.5H2.5Z"/><path d="M12 10v4.4"/><circle cx="12" cy="17.6" r="1" fill={c} stroke="none"/></>,
      cal:   <><rect x="3" y="5.5" width="18" height="15" rx="2"/><path d="M3 10.5h18M8 3v5M16 3v5"/></>,
      prio:  <path d="M5 21V4h13l-3 4 3 4H5"/>,
    };
    return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">{Q[n]}</svg>;
  };

  // ── Kanban: una columna por estado del flujo, en el orden del código ──────────────────────
  const COLS = [
    { n:'Backlog',    col:'#94A3B8', c:1, pct:null },
    { n:'Pendiente',  col:'#0EA5E9', c:3, pct:null },
    { n:'En proceso', col:'#0085FF', c:2, pct:null },
    { n:'Pausado',    col:'#F59E0B', c:1, pct:null },
    { n:'25%',        col:'#10B981', c:1, pct:25 },
    { n:'Completado', col:'#059669', c:0, pct:null },
  ];
  const CARDS = [
    { col:0, ti:'Etiquetas del blog',            cl:'NTO-58', v:'2 sep',  prio:null },
    { col:1, ti:'Revisar etiquetas de producto', cl:'NTO-14', v:'Hoy',    prio:'Alta' },
    { col:1, ti:'Etiquetas con acentos rotos',   cl:'NTO-27', v:'Hoy',    prio:null },
    { col:1, ti:'Etiquetas del buscador',        cl:'NTO-44', v:'26 ago', prio:null },
    { col:2, ti:'Etiquetas duplicadas',          cl:'NTO-33', v:'Ayer',   prio:'Urgente' },
    { col:2, ti:'Acentos en el catálogo',        cl:'NTO-36', v:'Mañana', prio:null },
    { col:3, ti:'Etiquetas del pie',             cl:'NTO-62', v:'4 sep',  prio:null },
    { col:4, ti:'Etiquetas de envío',            cl:'NTO-19', v:'28 ago', prio:null },
  ];
  const CARDH=100, CARDGAP=12, CARDY0=BOARD+72;

  // Los dos arrastres. El primero vale; el segundo lo rechaza el flujo y la tarjeta vuelve.
  const dragOK  = { idx:2, de:1, a:2, t0:T.arrastra, t1:T.arrastra+T.dragDur };
  const dragNO  = { idx:1, de:1, a:5, t0:T.salvo,    t1:T.salvo+1.7 };

  const posCard = (i)=>{
    const c = CARDS[i];
    let base = { x:colX(c.col)+12, y:CARDY0 + CARDS.filter((o,j)=> j < i && o.col === c.col).length*(CARDH+CARDGAP) };
    if (i === dragOK.idx && t >= dragOK.t0){
      const p = Easing.easeInOutCubic(clamp((t-dragOK.t0)/T.dragDur,0,1));
      return { x:lerp(base.x, colX(dragOK.a)+12, p), y:lerp(base.y, CARDY0+2*(CARDH+CARDGAP), p), drag:p > 0 && p < 1, ok:t >= dragOK.t1 };
    }
    if (i === dragNO.idx && t >= dragNO.t0){
      const ida = Easing.easeInOutCubic(clamp((t-dragNO.t0)/1.1,0,1));
      const vue = Easing.easeInOutCubic(clamp((t-T.vuelve)/0.8,0,1));
      const p = ida*(1-vue);
      return { x:lerp(base.x, colX(dragNO.a)+12, p), y:lerp(base.y, CARDY0, p), drag:p > 0.02, no:t >= T.aviso && t < T.vuelve+0.8 };
    }
    return base;
  };

  // ── Gantt: cinco tareas con fechas; la cadena crítica es 1-2-3-4 ──────────────────────────
  const TAREAS = [
    { cl:'NTO-14', n:'Revisar etiquetas de producto',       ini:'12 ago', fin:'14 ago', est:'Pendiente',  d0:0, dl:3, crit:true },
    { cl:'NTO-33', n:'Etiquetas duplicadas en el buscador', ini:'14 ago', fin:'17 ago', est:'En proceso', d0:2, dl:4, crit:true },
    { cl:'NTO-27', n:'Etiquetas con acentos rotos',         ini:'17 ago', fin:'19 ago', est:'Pendiente',  d0:5, dl:3, crit:true, fuera:true },
    { cl:'NTO-52', n:'Revisión final de etiquetas',         ini:'19 ago', fin:'23 ago', est:'Backlog',    d0:7, dl:5, crit:true },
    { cl:'NTO-19', n:'Etiquetas de envío',                  ini:'21 ago', fin:'24 ago', est:'25%',        d0:9, dl:4, crit:false },
  ];
  // La rejilla de la Gantt: 640 px de columnas fijas («Tarea», «Inicio», «Fin», «Estado») y el
  // resto para la línea de tiempo. Dieciséis días a 55 px. Sin zoom: el componente no lo tiene.
  const GX=WX+20, GW=1520, LBL=640, TLW=GW-LBL, DIA=TLW/16;
  const GY=BOARD+16, GHDR=56, GROW=76;
  const fuera = (i)=> TAREAS[i].fuera ? clamp((t-T.punta)/0.6,0,1) : 0;

  const criticaP = clamp((t-T.critica)/1.5,0,1);
  const cuartaE = Easing.easeOutBack(clamp((t-T.cuarta)/0.55,0,1));

  return (
    <SlideCanvas variant="light">
      <DinaupLogo size={34} style={{position:'absolute', left:56, top:46, opacity:0.45, zIndex:6}}/>
      <DemoHeader t={t} eyebrow={enGantt ? 'LA VISTA GANTT' : 'LA VISTA KANBAN'}
                  title={<span>{enGantt ? 'La misma lista, en el tiempo' : 'Una columna por cada estado de tu flujo'}</span>}/>

      {/* ═════════ LA VENTANA ═════════ */}
      <div style={{position:'absolute', left:WX, top:WY, width:WW, height:860, borderRadius:16, overflow:'hidden',
                   background:'#fff', border:'1px solid #E2E8F0', boxShadow:'0 34px 82px rgba(15,23,42,0.14)',
                   opacity:lerp(1, 0.30, clamp((t-T.cuarta)/0.7,0,1))}}>
        <BrowserChrome url={`play.dinaup.com/App/ToDo/8f3c1d92…/${enGantt ? 'Gantt' : 'Kanban'}?q=etiquetas&users=…&types=…`} title="Tareas — Nueva tienda online"/>
        {/* Los chips siguen arriba, intactos, en las dos vistas */}
        <div style={{display:'flex', alignItems:'center', gap:10, height:60, padding:'0 20px', borderBottom:'1px solid #F1F5F9'}}>
          {[['Abiertas','#DCFCE7','#15803D'],['Marta Ruiz','#E4F1FF','#0B4F86'],['Error','#E4F1FF','#0B4F86']].map(c=>(
            <span key={c[0]} style={{display:'inline-flex', alignItems:'center', gap:9, height:40, padding:'0 16px', borderRadius:20, background:c[1]}}>
              <span className="f-plex" style={{fontSize:19, fontWeight:600, color:c[2]}}>{c[0]}</span>
              <span className="f-plex" style={{fontSize:17, color:c[2], opacity:0.5}}>✕</span>
            </span>
          ))}
        </div>
        <div style={{height:724, background:'#F6F8FB'}}/>
      </div>

      {/* ═════════ EL TABLERO · columnas y tarjetas ═════════ */}
      {!enGantt && COLS.map((C,i)=>{
        const e = Easing.easeOutBack(clamp((t-T.columnas-i*T.colStep)/0.5,0,1));
        const n = useCountUp(0, C.c, T.cuenta+i*0.07, 0.7, t);
        return (
          <div key={C.n} style={{position:'absolute', left:colX(i), top:BOARD+14, width:COLW, height:690, borderRadius:14,
                       background:'#fff', border:'1px solid #E8EDF3', zIndex:16,
                       opacity:clamp((t-T.columnas-i*T.colStep)/0.4,0,1),
                       transform:`translateY(${(1-e)*16}px)`}}>
            <div style={{display:'flex', alignItems:'center', gap:10, padding:'16px 16px 12px'}}>
              <span style={{width:12, height:12, borderRadius:99, background:C.col}}/>
              <span className="f-plex" style={{flex:1, fontSize:22, fontWeight:700, color:'#0F172A'}}>{C.n}</span>
              <span className="f-mono" style={{fontSize:20, fontWeight:700, color:'#94A3B8'}}>{n}</span>
            </div>
            {C.pct !== null && (
              <div style={{height:6, margin:'0 16px 8px', borderRadius:99, background:'#EEF2F6'}}>
                <div style={{height:'100%', width:`${C.pct}%`, borderRadius:99, background:C.col}}/>
              </div>
            )}
            {/* hueco de destino del arrastre válido (la columna arranca en BOARD+14) */}
            {i === 2 && t >= T.arrastra && t < T.arrastra+T.dragDur && (
              <div style={{position:'absolute', left:12, top:CARDY0-(BOARD+14)+2*(CARDH+CARDGAP), width:COLW-24, height:CARDH,
                           borderRadius:10, border:'2px dashed #0085FF', background:'rgba(0,133,255,0.06)'}}/>
            )}
          </div>
        );
      })}

      {!enGantt && CARDS.map((c,i)=>{
        const pos = posCard(i);
        const e = Easing.easeOutCubic(clamp((t-T.columnas-c.col*T.colStep-0.25-i*T.cardStep)/0.4,0,1));
        const rechazada = pos.no;
        const aceptada = pos.ok && t < T.salvo;
        return (
          <div key={c.cl} style={{position:'absolute', left:pos.x, top:pos.y, width:COLW-24, height:CARDH, borderRadius:10,
                       background:'#fff', border:`1px solid ${rechazada ? '#FCA5A5' : (aceptada ? '#6EE7B7' : '#E8EDF3')}`,
                       boxShadow:pos.drag ? '0 18px 40px rgba(15,23,42,0.24)' : '0 1px 4px rgba(15,23,42,0.07)',
                       transform:`rotate(${pos.drag ? -2 : 0}deg) scale(${pos.drag ? 1.03 : 1})`,
                       padding:'12px 14px', zIndex:pos.drag ? 30 : 20,
                       opacity:e}}>
            <div className="f-plex" style={{fontSize:18, fontWeight:600, color:'#0F172A', lineHeight:1.25}}>{c.ti}</div>
            <div style={{display:'flex', alignItems:'center', gap:9, marginTop:12}}>
              <span className="f-mono" style={{fontSize:15, color:'#94A3B8'}}>{c.cl}</span>
              {c.prio && <span style={{display:'inline-flex'}}><Ico n="prio" s={17} c="#B42318" sw={2.2}/></span>}
              <span className="f-plex" style={{fontSize:15, color:c.v === 'Hoy' || c.v === 'Ayer' ? '#B45309' : '#94A3B8'}}>{c.v}</span>
              <div style={{flex:1}}/>
              <img src="../_engine/assets/avatares/marta.jpg" alt="" style={{width:26, height:26, borderRadius:99, objectFit:'cover'}}/>
            </div>
            {aceptada && (
              <span style={{position:'absolute', right:-12, top:-12, width:32, height:32, borderRadius:99, background:'#10B981',
                            display:'flex', alignItems:'center', justifyContent:'center',
                            transform:`scale(${lerp(0.3,1,Easing.easeOutBack(clamp((t-dragOK.t1)/0.4,0,1)))})`}}>
                <Ico n="check" s={18} c="#fff" sw={3.2}/>
              </span>
            )}
          </div>
        );
      })}

      {/* «sale un aviso»: literal, con su título y su texto */}
      {t >= T.aviso && t < T.gantt-0.4 && (
        <div style={{position:'absolute', left:1230, top:BOARD+118, width:470, zIndex:40,
                     opacity:clamp((t-T.aviso)/0.35,0,1)*clamp((T.gantt-0.4-t)/0.4,0,1),
                     transform:`translateX(${(1-Easing.easeOutBack(clamp((t-T.aviso)/0.45,0,1)))*40}px)`}}>
          <div style={{display:'flex', gap:16, padding:'22px 24px', borderRadius:14, background:'#fff',
                       borderLeft:'6px solid #EF4444', boxShadow:'0 24px 56px rgba(15,23,42,0.22)'}}>
            <Ico n="alerta" s={32} c="#EF4444" sw={2}/>
            <div>
              <div className="f-plex" style={{fontSize:26, fontWeight:800, color:'#B42318'}}>No permitido</div>
              <div className="f-plex" style={{fontSize:21, color:'#475569', marginTop:8, lineHeight:1.35}}>
                Esta transición de estado no es válida.
              </div>
            </div>
          </div>
          {t >= T.vuelve && (
            <div className="f-plex" style={{fontSize:21, fontWeight:600, color:'#64748B', marginTop:16, textAlign:'right',
                         opacity:clamp((t-T.vuelve)/0.4,0,1)}}>
              No lo decide el rol: lo decide tu flujo.
            </div>
          )}
        </div>
      )}

      {/* ═════════ LA GANTT ═════════ */}
      {enGantt && !vacia && (
        <div style={{position:'absolute', left:GX, top:GY, width:GW, height:520, zIndex:16,
                     opacity:clamp((t-T.gantt)/0.5,0,1) * (t >= T.filtro ? clamp((t-T.filtro)/0.45,0,1) : 1),
                     transform:`translateY(${(1-Easing.easeOutCubic(clamp((t-T.gantt)/0.5,0,1)))*12}px)`}}>
          <div style={{position:'relative', height:520, background:'#fff', borderRadius:14, border:'1px solid #E8EDF3', overflow:'hidden'}}>
            {/* cabecera de las cuatro columnas; la primera va congelada */}
            <div style={{display:'flex', alignItems:'center', height:GHDR, borderBottom:'1px solid #EEF2F6', background:'#FBFCFE'}}>
              <span className="f-plex" style={{width:300, padding:'0 18px', fontSize:18, fontWeight:700, color:'#475569'}}>Tarea</span>
              <span className="f-plex" style={{width:110, fontSize:18, fontWeight:700, color:'#475569'}}>Inicio</span>
              <span className="f-plex" style={{width:110, fontSize:18, fontWeight:700, color:'#475569'}}>Fin</span>
              <span className="f-plex" style={{width:120, fontSize:18, fontWeight:700, color:'#475569'}}>Estado</span>
              <div style={{flex:1, display:'flex'}}>
                {['12','14','16','18','20','22','24','26'].map(d=>(
                  <span key={d} className="f-mono" style={{width:DIA*2, fontSize:15, color:'#94A3B8'}}>{d} ago</span>
                ))}
              </div>
            </div>
            {TAREAS.map((k,i)=>{
              const e = Easing.easeOutCubic(clamp((t-T.gantt-0.2-i*T.filaStep)/0.4,0,1));
              const f = fuera(i);
              const bw = Easing.easeOutCubic(clamp((t-T.barras-i*0.09)/0.5,0,1));
              const critOn = k.crit && criticaP > (i+0.4)/5;
              return (
                <div key={k.cl} style={{position:'absolute', left:0, right:0, top:GHDR+i*GROW, height:GROW,
                             display:'flex', alignItems:'center', borderBottom:'1px solid #F4F7FA',
                             opacity:e*(1-f), transform:`translateX(${f*-40}px)`}}>
                  <span className="f-plex" style={{width:300, padding:'0 18px', fontSize:18, color:'#0F172A',
                               whiteSpace:'nowrap', overflow:'hidden', textOverflow:'ellipsis'}}>{k.cl} - {k.n}</span>
                  <span className="f-plex" style={{width:110, fontSize:17, color:'#64748B'}}>{k.ini}</span>
                  <span className="f-plex" style={{width:110, fontSize:17, color:'#64748B'}}>{k.fin}</span>
                  <span className="f-plex" style={{width:120, fontSize:17, color:'#64748B'}}>{k.est}</span>
                  <div style={{flex:1, position:'relative', height:GROW}}>
                    <div style={{position:'absolute', left:14+k.d0*DIA, top:(GROW-34)/2, height:34, borderRadius:8,
                                 width:k.dl*DIA*bw,
                                 background:critOn ? 'linear-gradient(90deg,#FB7185,#EF4444)' : 'linear-gradient(90deg,#38BDF8,#0085FF)',
                                 boxShadow:critOn ? '0 0 18px rgba(239,68,68,0.45)' : 'none'}}/>
                  </div>
                </div>
              );
            })}
            {/* el encendido de la cadena crítica */}
            {criticaP > 0 && criticaP < 1 && (
              <ScanLine y={GHDR} height={5*GROW} progress={criticaP} width={GW} color="#EF4444"/>
            )}
          </div>

          {/* las flechas entre tareas: se DIBUJAN, no aparecen */}
          <svg style={{position:'absolute', left:0, top:0, width:GW, height:520, pointerEvents:'none'}} width={GW} height="520">
            {[[0,1],[1,2],[2,3]].map((pr,j)=>{
              const [a,b] = pr;
              const p = Easing.easeInOutCubic(clamp((t-T.flechas-j*0.16)/0.5,0,1));
              const vivo = 1 - Math.max(fuera(a), fuera(b));
              const x1 = LBL+14+(TAREAS[a].d0+TAREAS[a].dl)*DIA, y1 = GHDR+a*GROW+GROW/2;
              const x2 = LBL+14+TAREAS[b].d0*DIA,                y2 = GHDR+b*GROW+GROW/2;
              const d = `M${x1} ${y1} H${x1+14} V${y2} H${x2}`;
              return (
                <g key={j} opacity={p*vivo}>
                  <path d={d} stroke="#64748B" strokeWidth="2.4" fill="none" strokeDasharray="220" strokeDashoffset={220*(1-p)}/>
                  <path d={`M${x2-9} ${y2-6} L${x2} ${y2} L${x2-9} ${y2+6}`} stroke="#64748B" strokeWidth="2.4" fill="none" opacity={clamp((p-0.78)/0.22,0,1)}/>
                </g>
              );
            })}
          </svg>
        </div>
      )}

      {/* «Sin fechas no hay barras»: el cuadro ENTERO vacío, que es el caso que la voz describe */}
      {vacia && (()=>{
        const p = clamp((t-T.sinfechas)/0.5,0,1), out = clamp((t-T.filtro+0.4)/0.4,0,1);
        const e = Easing.easeOutBack(p);
        return (
          <div style={{position:'absolute', left:GX, top:GY, width:GW, height:520, zIndex:18,
                       opacity:p*(1-out), transform:`scale(${lerp(0.96,1,e)})`}}>
            <div style={{height:520, borderRadius:14, background:'#fff', border:'1px solid #E8EDF3',
                         display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:26, padding:'0 120px'}}>
              <Ico n="cal" s={64} c="#94A3B8" sw={1.6}/>
              <div className="f-plex" style={{fontSize:32, fontWeight:600, color:'#334155', textAlign:'center', lineHeight:1.4,
                           opacity:clamp((t-T.falta)/0.5,0,1)}}>
                Para ver el diagrama Gantt, las tareas necesitan tener{' '}
                <b style={{color:'#0F172A'}}>Fecha de inicio planificada</b> y/o <b style={{color:'#0F172A'}}>Vencimiento</b>.
              </div>
              <div className="f-plex" style={{fontSize:22, color:'#94A3B8', opacity:clamp((t-T.falta-0.4)/0.5,0,1)}}>
                te dice lo que falta, en vez de quedarse en blanco
              </div>
            </div>
            <div className="f-plex" style={{position:'absolute', left:0, top:-38, fontSize:20, fontWeight:700, letterSpacing:'2.2px', color:'#94A3B8'}}>
              CUANDO NINGUNA TIENE FECHA
            </div>
          </div>
        );
      })()}

      {/* «si deja fuera una punta, la flecha se va con ella» */}
      {t >= T.punta && t < T.cuarta && (
        <div style={{position:'absolute', left:GX, top:GY+540, width:GW, textAlign:'center', zIndex:24,
                     opacity:clamp((t-T.punta)/0.45,0,1)*clamp((T.cuarta-t)/0.4,0,1)}}>
          <span style={{display:'inline-flex', alignItems:'center', gap:14, padding:'14px 28px', borderRadius:14,
                        background:'rgba(245,158,11,0.12)'}}>
            <Ico n="alerta" s={26} c="#D97706" sw={2.2}/>
            <span className="f-plex" style={{fontSize:26, fontWeight:700, color:'#B45309'}}>
              El filtro deja fuera una punta · la flecha se va con ella
            </span>
          </span>
        </div>
      )}

      {/* «Queda la cuarta vista. Y ahí hay que avisar.» — puente a la escena 6 */}
      {t >= T.cuarta && (
        <div style={{position:'absolute', left:0, right:0, top:392, textAlign:'center', zIndex:48,
                     opacity:clamp((t-T.cuarta)/0.5,0,1)}}>
          <div style={{display:'inline-flex', gap:16}}>
            {['compacta','kanban','tabla','gantt'].map((v,i)=>{
              const on = i === 2;
              const e = Easing.easeOutBack(clamp((t-T.cuarta-i*0.09)/0.5,0,1));
              return (
                <span key={v} style={{width:110, height:110, borderRadius:22, display:'inline-flex', alignItems:'center', justifyContent:'center',
                          background:on ? '#fff' : '#F4F6F9',
                          border:`3px solid ${on ? '#F59E0B' : '#E6EAF0'}`,
                          boxShadow:on ? '0 0 44px rgba(245,158,11,0.40)' : 'none',
                          opacity:on ? 1 : 0.5, transform:`scale(${lerp(0.7,1,e)*(on ? lerp(1,1.10,cuartaE) : 1)})`}}>
                  <Ico n={v} s={56} c={on ? '#D97706' : '#94A3B8'} sw={1.7}/>
                </span>
              );
            })}
          </div>
          <div className="f-plex" style={{fontSize:40, fontWeight:700, color:'#0F172A', marginTop:44,
                       opacity:clamp((t-T.cuarta-0.5)/0.5,0,1)}}>
            Queda la cuarta vista.
          </div>
          {t >= T.avisar && (
            <div className="f-plex" style={{fontSize:34, fontWeight:600, color:'#B45309', marginTop:18,
                         opacity:clamp((t-T.avisar)/0.45,0,1),
                         transform:`translateY(${(1-Easing.easeOutCubic(clamp((t-T.avisar)/0.5,0,1)))*12}px)`}}>
              Y ahí hay que avisar.
            </div>
          )}
        </div>
      )}

      <ScriptedCursor t={t} clickTimes={[]} frames={[
        { t:0,                    x:1830, y:1050 },
        { t:T.arrastra-0.35,      x:colX(1)+120, y:CARDY0+CARDH+CARDGAP+50 },
        { t:T.arrastra+T.dragDur, x:colX(2)+120, y:CARDY0+2*(CARDH+CARDGAP)+50 },
        { t:T.salvo-0.35,         x:colX(1)+120, y:CARDY0+50 },
        { t:T.salvo+1.1,          x:colX(5)+120, y:CARDY0+50 },
        { t:T.vuelve,             x:colX(5)+120, y:CARDY0+50 },
        { t:T.vuelve+0.9,         x:1830, y:1050 },
      ]}/>
    </SlideCanvas>
  );
}
Object.assign(window, { EscenaTV05 });
