// === Escena 03 — «La barra de filtros» ===  [45.4 s · 14 beats del plan] · VALLE
//
// LOCUCIÓN (audio/escena-03.mp3): arriba hay un botón que pone Filtros → nueve atajos en cinco
// grupos, y no se cierra al elegir → Abiertas ya viene puesto → ojo con Todas: no enseña las
// cerradas, te devuelve al arranque → cada filtro deja un chip, y se quita pulsando el chip
// entero → la caja de buscar, con prefijos en español y en inglés → la chuleta sale al pinchar
// dentro → espera medio segundo → y si no pasa ninguna, distingue los dos vacíos.
//
// VALLE DE PROTECCIÓN: ni una cifra grande, un gesto por vez, nada moviéndose con amplitud.
// Todo lo que se mueve aquí mide menos de 20 px.
//
// FIDELIDAD:
//   · Los tres atajos que se combinan son «Mis tareas», «Prioridad alta» y «Esta semana»:
//     coexisten. «Vencidas» quedaría fuera porque se apaga con «Esta semana» (:197-200).
//   · Color SOLO en los atajos. Los chips de usuario y de tipo van con la clase base pelada:
//     los dos, el mismo azul pálido, sin borde (SmartFilterBarU.razor.css:20-34).
//   · La zona de clic del chip es el chip ENTERO, no la equis: por eso al quitarlo se ilumina
//     la píldora completa.
//   · «Todas» NO enseña las cerradas: vuelve al arranque dejando «Abiertas» puesto.
//   · La chuleta y el texto tecleado NO coexisten: al escribir texto libre el modo pasa a Text
//     y el desplegable desaparece (SmartFilterBarU.razor:84, 330-333).
//   · Los dos vacíos son un if/else: van fuera del tablero y rotulados como comparación.
function EscenaTV03({ t }){
  const T = {
    boton:0.7,      // "un botón que pone Filtros" -> el boton, con el cursor encima
    atajos:3.8,     // "nueve atajos en cinco grupos" -> el desplegable entra; cabeceras primero
    nocierra:6.4,   // "No se cierra al elegir" -> el sello de que el panel no se mueve
    tresclics:8.0,  // "combinar tres son tres clics" -> tres clics seguidos, panel quieto
    abiertas:10.6,  // "Abiertas ya viene puesto" -> el chip verde, que ya estaba, se realza
    todas:14.0,     // "el que se llama Todas" -> foco en la ultima opcion
    cerradas:15.2,  // "no enseña las cerradas" -> el aviso de lo que sigue oculto
    arranque:16.6,  // "te devuelve al arranque" -> todo se limpia y «Abiertas» reaparece sola
    chips:19.6,     // "deja un chip arriba" -> los chips vuelven a entrar, en cascada
    chipentero:22.2,// "pulsando el chip entero" -> el chip ENTERO se ilumina y desaparece
    caja:25.2,      // "la caja de buscar" -> el panel se cierra; foco en la caja
    prefijos:27.6,  // "prefijos en español y en inglés" -> la fila de prefijos, en cascada
    chuleta:30.4,   // "La chuleta sale" -> la chuleta baja al pinchar dentro
    medio:33.6,     // "medio segundo" -> se teclea texto libre: la chuleta se retira
    filtrar:34.3,   // "antes de filtrar" -> la barra de espera y el corte de la lista
    ninguna:36.2,   // "Y si no pasa ninguna"
    vacios:38.0,    // "distingue los dos vacíos" -> las dos tarjetas, rotuladas «o esto, o esto»
    buscabas:40.3,  // "Ya tienes delante lo que buscabas" -> vuelve la lista filtrada
    direccion:43.1, // "Ahora mira la dirección" -> la app baja, el navegador sube
    grupoStep:0.13,  // cascada entre cabeceras de grupo del desplegable
    opcStep:0.05,    // cascada entre opciones del desplegable
    prefStep:0.07,   // cascada entre pastillas de prefijo
    filaStep:0.06,   // cascada entre filas de la lista
  };

  const WX=180, WY=150, WW=1560, CHR=76;
  const AY=WY+CHR, SBW=300, MX=WX+SBW, MW=WW-SBW;
  const HDR=AY+92, BAR=HDR+84, CHIPY=BAR;
  const BTN=[504,578,652,726];
  const FILX=828, FILW=148, BOXX=990, BOXW=630;

  const veloVacios = clamp((t-T.vacios+0.9)/0.6,0,1)*clamp((T.buscabas-t+0.2)/0.5,0,1)*0.90;
  const bajaP = Easing.easeInOutCubic(clamp((t-T.direccion)/0.9,0,1));

  const Ico = ({ n, s=24, c='#64748B', sw=2 })=>{
    const Q = {
      lupa:  <><circle cx="11" cy="11" r="6"/><path d="M15.6 15.6 L20 20"/></>,
      filtro:<path d="M3.5 5h17l-6.8 8v5.6l-3.4 1.9V13Z"/>,
      filtroOff:<><path d="M3.5 5h17l-6.8 8v5.6l-3.4 1.9V13Z"/><path d="M3 3 L21 21"/></>,
      help:  <><circle cx="12" cy="12" r="9"/><path d="M9.6 9.6a2.5 2.5 0 1 1 3.1 2.4c-.8.3-1.2.9-1.2 1.7v.4"/><circle cx="11.5" cy="17.2" r="1" fill={c} stroke="none"/></>,
      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"/>,
      folder:<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2Z"/>,
      flecha:<path d="M12 20V5M6 11l6-6 6 6"/>,
    };
    return <svg width={s} height={s} viewBox="0 0 24 24" fill="none" stroke={c} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">{Q[n]}</svg>;
  };

  // ── Los nueve atajos, en sus cinco grupos (SmartFilterBarU.razor:193-203) ─────────────────
  const GRUPOS = [
    { g:'ESTADO',      o:[{n:'Abiertas', on:[0,99]}, {n:'En proceso'}, {n:'Pendientes'}] },
    { g:'ASIGNACIÓN',  o:[{n:'Mis tareas', on:[8.20,16.42], on2:[19.78,24.05]}, {n:'Sin asignar'}] },
    { g:'VENCIMIENTO', o:[{n:'Vencidas'}, {n:'Esta semana', on:[9.70,16.42], on2:[20.42,22.62]}] },
    { g:'PRIORIDAD',   o:[{n:'Prioridad alta', on:[8.95,16.42], on2:[20.10,23.42]}] },
    { g:'OTROS',       o:[{n:'Todas'}] },
  ];
  const enc = (o)=> (o.on && t >= o.on[0] && t < o.on[1]) || (o.on2 && t >= o.on2[0] && t < o.on2[1]);

  // ── Los chips de la barra. Color SOLO en los atajos; usuario y tipo, azul pálido idéntico ──
  const CHIPS = [
    { l:'Abiertas',       bg:'#DCFCE7', fg:'#15803D', iv:[[0,99]] },
    { l:'Mis tareas',     bg:'#DBEAFE', fg:'#1D4ED8', iv:[[8.20,16.42],[19.78,24.05]] },
    { l:'Prioridad alta', bg:'#FEE2E2', fg:'#B91C1C', iv:[[8.95,16.42],[20.10,23.42]] },
    { l:'Esta semana',    bg:'#FFEDD5', fg:'#C2410C', iv:[[9.70,16.42],[20.42,22.62]] },
    { l:'Marta Ruiz',     bg:'#E4F1FF', fg:'#0B4F86', iv:[[31.70,99]] },
    { l:'Error',          bg:'#E4F1FF', fg:'#0B4F86', iv:[[32.55,99]] },
  ];

  const Chip = ({ c })=>{
    let ini = null, fin = null;
    for (let i=0;i<c.iv.length;i++){ if (t >= c.iv[i][0] && t < c.iv[i][1]+0.30){ ini = c.iv[i][0]; fin = c.iv[i][1]; } }
    if (ini === null) return null;
    const p = clamp((t-ini)/0.34,0,1), e = Easing.easeOutBack(p);
    const out = clamp((t-fin)/0.30,0,1);
    const brillo = (fin < 90 && t >= fin-0.42 && t < fin) ? 1 : 0;   // el chip ENTERO reacciona al clic
    const realza = (c.l === 'Abiertas' && t >= T.abiertas && t < T.abiertas+1.5) ? Math.sin((t-T.abiertas)/1.5*Math.PI) : 0;
    return (
      <span style={{display:'inline-flex', alignItems:'center', gap:9, height:40, padding:'0 16px', borderRadius:20,
                    background:c.bg, opacity:p*(1-out),
                    boxShadow:brillo ? '0 0 0 4px rgba(0,133,255,0.35), 0 0 24px rgba(0,133,255,0.5)'
                                     : (realza > 0 ? `0 0 ${realza*26}px rgba(16,185,129,${realza*0.8})` : 'none'),
                    transform:`scale(${lerp(0.7,1,e)*(1-out*0.25)*(1+brillo*0.05)})`}}>
        <span className="f-plex" style={{fontSize:19, fontWeight:600, color:c.fg}}>{c.l}</span>
        <span className="f-plex" style={{fontSize:17, color:c.fg, opacity:0.5}}>✕</span>
      </span>
    );
  };

  // ── La lista. Después de filtrar solo pasan las tres de Marta, tipo Error y con «etiquetas» ─
  const FILAS = [
    { c:'NTO-14', ti:'Revisar etiquetas de producto',        tp:'Error',  tc:'#DC2626', a:'marta',  v:'Hoy',    pasa:true },
    { c:'NTO-21', ti:'Importar catálogo del proveedor',      tp:'Tarea',  tc:'#0085FF', a:'javier', v:'Mañana', pasa:false },
    { c:'NTO-08', ti:'Pasarela de pago en pruebas',          tp:'Tarea',  tc:'#0085FF', a:'nuria',  v:'18 ago', pasa:false },
    { c:'NTO-33', ti:'Etiquetas duplicadas en el buscador',  tp:'Error',  tc:'#DC2626', a:'marta',  v:'Ayer',   pasa:true },
    { c:'NTO-05', ti:'Fotos de la portada',                  tp:'Mejora', tc:'#7C3AED', a:'nuria',  v:'21 ago', pasa:false },
    { c:'NTO-40', ti:'Aviso de cookies',                     tp:'Tarea',  tc:'#0085FF', a:'javier', v:'',       pasa:false },
    { c:'NTO-27', ti:'Etiquetas con acentos rotos',          tp:'Error',  tc:'#DC2626', a:'marta',  v:'Hoy',    pasa:true },
    { c:'NTO-12', ti:'Alta del transportista',               tp:'Tarea',  tc:'#0085FF', a:'nuria',  v:'25 ago', pasa:false },
  ];
  const corte = T.filtrar + 0.55;
  const compacta = Easing.easeInOutCubic(clamp((t-corte)/0.6,0,1));
  let idxPasa = -1;
  const filasY = FILAS.map(f=>{ if (f.pasa){ idxPasa++; return idxPasa; } return -1; });

  const PREFIJOS = ['nat:','n:','nature:','naturaleza:','@usuario','tipo:','t:','type:','estado:','e:','status:','s:','abiertas','open'];
  const CHULETA = [
    { p:'nat:',    d:'naturaleza · Interna, De cliente…' },
    { p:'@',       d:'usuario · Marta Ruiz, Javier Sanz, Ana Costa' },
    { p:'tipo:',   d:'tipo · Tarea, Error, Mejora' },
    { p:'estado:', d:'estado · Backlog, Pendiente, En proceso…' },
  ];

  return (
    <SlideCanvas variant="light">
      <DinaupLogo size={34} style={{position:'absolute', left:56, top:46, opacity:0.45, zIndex:6}}/>
      <div style={{opacity:lerp(1,0.3,bajaP)}}>
        <DemoHeader t={t} eyebrow="LA BARRA DE FILTROS" title={<span>Nueve atajos, y una caja que entiende prefijos</span>}/>
      </div>

      {/* ═════════ LA VENTANA ═════════ */}
      <div style={{position:'absolute', left:WX, top:WY+bajaP*46, 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.28,bajaP), filter:bajaP > 0.1 ? 'saturate(0.5)' : 'none'}}>
        <BrowserChrome url="play.dinaup.com/App/ToDo/8f3c1d92-4b77-4e0a-9a51-2c6de07b1f44/To-Do" title="Tareas — Nueva tienda online"/>

        <div style={{display:'flex', height:784, background:'#F6F8FB'}}>
          {/* Menú lateral: presente, pero callado — el protagonista está a la derecha */}
          <div style={{width:SBW, background:'#fff', borderRight:'1px solid #E8EDF3', padding:'16px 10px', opacity:0.42}}>
            {['Inicio','Mi día','Todas las tareas'].map(x=>(
              <div key={x} style={{display:'flex', alignItems:'center', gap:13, height:46, padding:'0 16px'}}>
                <span style={{width:20, height:20, borderRadius:5, background:'#E2E8F0'}}/>
                <span className="f-plex" style={{fontSize:24, color:'#94A3B8'}}>{x}</span>
              </div>
            ))}
            <div className="f-plex" style={{fontSize:15, fontWeight:700, letterSpacing:'2.4px', color:'#CBD5E1', padding:'20px 16px 8px'}}>PROYECTOS</div>
            {[['Nueva tienda online',true],['Reforma del obrador',false],['Web corporativa',false]].map(([x,act])=>(
              <div key={x} style={{display:'flex', alignItems:'center', gap:13, height:46, padding:'0 16px', borderRadius:10,
                                   background:act ? 'rgba(0,133,255,0.08)' : 'transparent'}}>
                <Ico n="folder" s={20} c={act ? '#0085FF' : '#CBD5E1'}/>
                <span className="f-plex" style={{fontSize:24, color:act ? '#475569' : '#94A3B8', fontWeight:act ? 600 : 400}}>{x}</span>
              </div>
            ))}
          </div>

          <div style={{width:MW, background:'#fff'}}>
            {/* Cabecera del proyecto */}
            <div style={{display:'flex', alignItems:'center', gap:18, height:92, padding:'0 24px', borderBottom:'1px solid #EEF2F6', opacity:0.75}}>
              <span style={{width:44, height:44, borderRadius:12, background:'rgba(0,133,255,0.10)', display:'inline-flex', alignItems:'center', justifyContent:'center'}}>
                <Ico n="folder" s={26} c="#0085FF"/>
              </span>
              <span className="f-plex" style={{fontSize:34, fontWeight:700, color:'#0F172A'}}>Nueva tienda online</span>
              <span className="f-mono" style={{fontSize:20, fontWeight:700, color:'#475569', background:'#EEF2F6', borderRadius:8, padding:'5px 12px'}}>NTO</span>
              <div style={{flex:1}}/>
              <div style={{display:'flex'}}>
                {['marta','javier','nuria'].map((a,i)=>(
                  <img key={a} src={`../_engine/assets/avatares/${a}.jpg`} alt="" style={{width:40, height:40, borderRadius:99, objectFit:'cover', border:'2px solid #fff', marginLeft:i === 0 ? 0 : -10}}/>
                ))}
              </div>
            </div>

            {/* Barra de vistas + Filtros + caja de buscar */}
            <div style={{display:'flex', alignItems:'center', gap:12, height:84, padding:'0 24px', borderBottom:'1px solid #EEF2F6', background:'#FBFCFE'}}>
              {['compacta','kanban','tabla','gantt'].map((v,i)=>(
                <span key={v} style={{width:62, height:62, borderRadius:12, display:'inline-flex', alignItems:'center', justifyContent:'center',
                          background:i === 0 ? 'rgba(0,133,255,0.12)' : '#fff', border:`1px solid ${i === 0 ? 'rgba(0,133,255,0.35)' : '#E2E8F0'}`, opacity:i === 0 ? 1 : 0.55}}>
                  <Ico n={v} s={34} c={i === 0 ? '#0085FF' : '#94A3B8'} sw={1.9}/>
                </span>
              ))}
              <span style={{width:1, height:40, background:'#E2E8F0', margin:'0 8px'}}/>
              <span style={{display:'inline-flex', alignItems:'center', gap:9, width:FILW, height:52, padding:'0 18px', borderRadius:10,
                            border:`1px solid ${t >= T.boton && t < T.caja ? '#0085FF' : '#E2E8F0'}`,
                            background:t >= T.atajos && t < T.caja ? 'rgba(0,133,255,0.08)' : '#fff'}}>
                <Ico n="filtro" s={22} c={t >= T.boton && t < T.caja ? '#0085FF' : '#64748B'}/>
                <span className="f-plex" style={{fontSize:20, fontWeight:600, color:'#334155'}}>Filtros</span>
              </span>
              <span style={{flex:1, display:'inline-flex', alignItems:'center', gap:10, height:52, padding:'0 16px', borderRadius:10,
                            border:`1px solid ${t >= T.caja ? '#0085FF' : '#E2E8F0'}`, background:'#fff',
                            boxShadow:t >= T.caja && t < T.filtrar+1 ? '0 0 0 4px rgba(0,133,255,0.12)' : 'none'}}>
                <Ico n="lupa" s={22} c={t >= T.caja ? '#0085FF' : '#94A3B8'}/>
                {t >= T.medio-0.30
                  ? <span className="f-plex" style={{fontSize:20, color:'#0F172A', fontWeight:600}}>
                      <Typewriter text="etiquetas" start={T.medio-0.30} cps={14} t={t} caret={t < T.filtrar+0.4}/>
                    </span>
                  : <span className="f-plex" style={{fontSize:19, color:'#94A3B8'}}>Buscar… (escribe nat: @ tipo: estado: o abiertas)</span>}
              </span>
              {/* El botón de limpiar solo existe cuando hay algo puesto: aquí siempre lo hay («Abiertas») */}
              <span style={{width:44, height:44, borderRadius:9, display:'inline-flex', alignItems:'center', justifyContent:'center', background:'#F1F5F9'}}>
                <Ico n="filtroOff" s={22} c="#94A3B8"/>
              </span>
              <Ico n="help" s={24} c="#94A3B8"/>
            </div>

            {/* Fila de chips */}
            <div style={{display:'flex', alignItems:'center', gap:10, height:60, padding:'0 24px', borderBottom:'1px solid #F1F5F9'}}>
              {CHIPS.map(c => <Chip key={c.l} c={c}/>)}
            </div>

            {/* La lista */}
            <div style={{position:'relative', height:548}}>
              {FILAS.map((f,i)=>{
                const ent = Easing.easeOutCubic(clamp((t-0.4-i*T.filaStep)/0.45,0,1));
                const fuera = !f.pasa ? compacta : 0;
                const y = f.pasa ? lerp(i*68, filasY[i]*68, compacta) : i*68;
                return (
                  <div key={f.c} style={{position:'absolute', left:0, right:0, top:y, display:'flex', alignItems:'center', gap:16,
                               height:68, padding:'0 24px', borderBottom:'1px solid #EEF2F6',
                               opacity:ent*(1-fuera), transform:`translateX(${fuera*40}px)`}}>
                    <span style={{width:26, height:26, borderRadius:99, border:'3px solid #94A3B8'}}/>
                    <span className="f-plex" style={{flex:1, fontSize:21, color:'#0F172A'}}>{f.ti}</span>
                    <span className="f-plex" style={{fontSize:16, fontWeight:600, color:f.tc, background:`${f.tc}1A`, borderRadius:7, padding:'4px 10px'}}>{f.tp}</span>
                    <span className="f-plex" style={{width:100, textAlign:'right', fontSize:17, color:'#94A3B8'}}>{f.v}</span>
                    <span className="f-mono" style={{width:86, textAlign:'right', fontSize:17, color:'#94A3B8'}}>{f.c}</span>
                    <img src={`../_engine/assets/avatares/${f.a}.jpg`} alt="" style={{width:34, height:34, borderRadius:99, objectFit:'cover'}}/>
                  </div>
                );
              })}
              {/* El remate: lo que queda delante */}
              {t >= T.buscabas && (
                <div style={{position:'absolute', left:24, top:224, display:'inline-flex', alignItems:'center', gap:12,
                             padding:'12px 22px', borderRadius:12, background:'rgba(16,185,129,0.10)',
                             opacity:clamp((t-T.buscabas)/0.45,0,1),
                             transform:`translateY(${(1-Easing.easeOutBack(clamp((t-T.buscabas)/0.55,0,1)))*10}px)`}}>
                  <Ico n="check" s={26} c="#059669" sw={2.6}/>
                  <span className="f-plex" style={{fontSize:24, fontWeight:700, color:'#047857'}}>Tres tareas. Lo que buscabas.</span>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* ═════════ EL DESPLEGABLE DE «FILTROS» · no se cierra al elegir ═════════ */}
      {(()=>{
        const p = clamp((t-T.atajos)/0.42,0,1), out = clamp((t-T.caja)/0.4,0,1);
        if (p <= 0 || out >= 1 || bajaP > 0.2) return null;
        const e = Easing.easeOutBack(p);
        let fila = 0;
        return (
          <div style={{position:'absolute', left:FILX, top:BAR+4, width:430, zIndex:38,
                       opacity:p*(1-out), transform:`translateY(${(1-e)*-14}px) scale(${lerp(0.94,1,e)})`, transformOrigin:'top left'}}>
            <div style={{background:'#fff', borderRadius:14, border:'1px solid #E2E8F0', boxShadow:'0 26px 60px rgba(15,23,42,0.22)', padding:'12px 0 14px'}}>
              {GRUPOS.map((G,gi)=>(
                <div key={G.g}>
                  <div className="f-plex" style={{fontSize:15, fontWeight:700, letterSpacing:'2.2px', color:'#94A3B8',
                               padding:'12px 22px 6px', opacity:clamp((t-T.atajos-gi*T.grupoStep)/0.3,0,1)}}>{G.g}</div>
                  {G.o.map(o=>{
                    const y = fila++; const on = enc(o);
                    const focoTodas = o.n === 'Todas' && t >= T.todas && t < T.arranque+0.4;
                    return (
                      <div key={o.n} style={{display:'flex', alignItems:'center', gap:14, height:44, padding:'0 22px',
                                   background:focoTodas ? 'rgba(239,68,68,0.10)' : (on ? 'rgba(0,133,255,0.07)' : 'transparent'),
                                   opacity:clamp((t-T.atajos-0.30-y*T.opcStep)/0.28,0,1)}}>
                        <span style={{width:22, height:22, borderRadius:6, border:`2px solid ${on ? '#0085FF' : '#CBD5E1'}`,
                                      background:on ? '#0085FF' : '#fff', display:'inline-flex', alignItems:'center', justifyContent:'center'}}>
                          {on && <Ico n="check" s={14} c="#fff" sw={3.2}/>}
                        </span>
                        <span className="f-plex" style={{fontSize:20, fontWeight:on || focoTodas ? 700 : 500,
                                     color:focoTodas ? '#B42318' : (on ? '#0F172A' : '#334155')}}>{o.n}</span>
                      </div>
                    );
                  })}
                </div>
              ))}
            </div>
            {/* «No se cierra al elegir»: el propio panel lo demuestra quedándose quieto */}
            {t >= T.nocierra && t < T.abiertas+0.6 && (
              <div style={{position:'absolute', left:446, top:8, width:280, opacity:clamp((t-T.nocierra)/0.4,0,1)*clamp((T.abiertas+0.6-t)/0.4,0,1)}}>
                <span className="f-plex" style={{fontSize:22, fontWeight:700, color:'#0066CC', lineHeight:1.35}}>
                  No se cierra al elegir:<br/>tres filtros son tres clics.
                </span>
              </div>
            )}
            {/* «no enseña las cerradas» */}
            {t >= T.cerradas && t < T.chips-0.3 && (
              <div style={{position:'absolute', left:446, top:452, width:300,
                           opacity:clamp((t-T.cerradas)/0.4,0,1)*clamp((T.chips-0.3-t)/0.4,0,1)}}>
                <div style={{padding:'14px 18px', borderRadius:12, background:'rgba(239,68,68,0.08)', borderLeft:'4px solid #EF4444'}}>
                  <span className="f-plex" style={{fontSize:21, fontWeight:600, color:'#B42318', lineHeight:1.35}}>
                    Completadas y canceladas siguen ocultas.
                  </span>
                </div>
              </div>
            )}
          </div>
        );
      })()}

      {/* ═════════ Los prefijos, en español y en inglés ═════════ */}
      {(()=>{
        const p = clamp((t-T.prefijos)/0.4,0,1), out = clamp((t-T.chuleta+0.2)/0.4,0,1);
        if (p <= 0 || out >= 1) return null;
        return (
          <div style={{position:'absolute', left:BOXX, top:BAR+10, width:BOXW+70, display:'flex', flexWrap:'wrap', gap:9, zIndex:38,
                       opacity:p*(1-out)}}>
            {PREFIJOS.map((x,i)=>(
              <span key={x} className="f-mono" style={{padding:'8px 14px', borderRadius:9, background:'#0F172A', color:'#8BD5FF',
                        fontSize:19, fontWeight:600, opacity:clamp((t-T.prefijos-i*T.prefStep)/0.25,0,1),
                        transform:`translateY(${(1-Easing.easeOutBack(clamp((t-T.prefijos-i*T.prefStep)/0.35,0,1)))*8}px)`}}>{x}</span>
            ))}
          </div>
        );
      })()}

      {/* ═════════ La chuleta: sale al pinchar dentro, y se retira al teclear texto libre ═════ */}
      {(()=>{
        // Se retira ANTES de que caiga el primer carácter de texto libre: la chuleta y el modo
        // Text no coexisten (SmartFilterBarU.razor:84). El typewriter arranca en T.medio-0.30.
        const p = clamp((t-T.chuleta)/0.4,0,1), out = clamp((t-T.medio+0.58)/0.26,0,1);
        if (p <= 0 || out >= 1) return null;
        const e = Easing.easeOutBack(p);
        return (
          <div style={{position:'absolute', left:BOXX, top:BAR+4, width:600, zIndex:38,
                       opacity:p*(1-out), transform:`translateY(${(1-e)*-12}px) scale(${lerp(0.95,1,e)})`, transformOrigin:'top left'}}>
            <div style={{background:'#fff', borderRadius:14, border:'1px solid #E2E8F0', boxShadow:'0 26px 60px rgba(15,23,42,0.22)', padding:'10px 0'}}>
              {CHULETA.map((c,i)=>{
                const elegida = (i === 1 && t >= 31.55) || (i === 2 && t >= 32.40);
                return (
                  <div key={c.p} style={{display:'flex', alignItems:'center', gap:16, padding:'13px 22px',
                               background:elegida ? 'rgba(0,133,255,0.10)' : 'transparent',
                               opacity:clamp((t-T.chuleta-i*0.09)/0.25,0,1)}}>
                    <span className="f-mono" style={{minWidth:96, fontSize:21, fontWeight:700, color:'#0085FF'}}>{c.p}</span>
                    <span className="f-plex" style={{fontSize:20, color:'#64748B'}}>{c.d}</span>
                  </div>
                );
              })}
            </div>
            <div className="f-plex" style={{fontSize:19, color:'#94A3B8', marginTop:10}}>
              Nunca propone tareas: solo familias de prefijo y sus valores.
            </div>
          </div>
        );
      })()}

      {/* «Espera medio segundo antes de filtrar»: la barra de espera, real, lineal */}
      {t >= T.filtrar-0.35 && t < corte+0.5 && (
        <div style={{position:'absolute', left:BOXX+16, top:BAR-4, width:BOXW-32, height:5, borderRadius:99,
                     background:'#E2E8F0', zIndex:40, opacity:clamp((corte+0.5-t)/0.4,0,1)}}>
          <div style={{height:'100%', borderRadius:99, background:'#0085FF',
                       width:`${clamp((t-(T.filtrar-0.35))/0.5,0,1)*100}%`}}/>
          <span className="f-plex" style={{position:'absolute', left:0, top:14, fontSize:19, fontWeight:600, color:'#0085FF'}}>
            medio segundo
          </span>
        </div>
      )}

      {/* ═════════ LOS DOS VACÍOS · son un if/else: se rotulan como comparación ═════════ */}
      {veloVacios > 0.01 && <div style={{position:'absolute', inset:0, background:'#fff', opacity:veloVacios, zIndex:44}}/>}
      {(()=>{
        const p = clamp((t-T.vacios+0.9)/0.5,0,1), out = clamp((t-T.buscabas+0.2)/0.4,0,1);
        if (p <= 0 || out >= 1) return null;
        const VAC = [
          { t1:'Ninguna tarea pasa el filtro', b:'Quitar los filtros', sub:'hay tareas, pero ninguna cumple lo que has puesto' },
          { t1:'Este proyecto todavía no tiene tareas', b:null, sub:'Escribe la primera en la caja de abajo y pulsa Enter.' },
        ];
        return (
          <div style={{position:'absolute', left:0, right:0, top:236, zIndex:46, opacity:p*(1-out)}}>
            <div className="f-plex" style={{textAlign:'center', fontSize:34, fontWeight:700, color:'#0F172A'}}>
              La lista distingue los dos vacíos
            </div>
            <div className="f-plex" style={{textAlign:'center', fontSize:24, color:'#94A3B8', marginTop:10}}>
              o esto, o esto — nunca las dos: son las dos ramas del mismo <span className="f-mono" style={{color:'#64748B'}}>if</span>
            </div>
            <div style={{display:'flex', justifyContent:'center', gap:60, marginTop:52}}>
              {VAC.map((v,i)=>{
                const e = Easing.easeOutBack(clamp((t-T.vacios+0.9-i*0.22)/0.55,0,1));
                return (
                  <div key={v.t1} style={{width:620, minHeight:330, padding:'46px 42px', borderRadius:20, background:'#fff',
                               border:`2px solid ${i === 0 ? '#BFD9F5' : '#E2E8F0'}`, boxShadow:'0 26px 62px rgba(15,23,42,0.14)',
                               textAlign:'center', transform:`translateY(${(1-e)*18}px) scale(${lerp(0.94,1,e)})`, opacity:e}}>
                    <div style={{width:74, height:74, borderRadius:99, background:i === 0 ? 'rgba(0,133,255,0.10)' : '#F1F5F9',
                                 margin:'0 auto 24px', display:'flex', alignItems:'center', justifyContent:'center'}}>
                      <Ico n={i === 0 ? 'filtroOff' : 'compacta'} s={36} c={i === 0 ? '#0085FF' : '#94A3B8'}/>
                    </div>
                    <div className="f-plex" style={{fontSize:30, fontWeight:700, color:'#0F172A', lineHeight:1.25}}>{v.t1}</div>
                    <div className="f-plex" style={{fontSize:21, color:'#64748B', marginTop:16, lineHeight:1.4}}>{v.sub}</div>
                    {v.b && (
                      <span style={{display:'inline-block', marginTop:26, padding:'13px 26px', borderRadius:10, background:'#0085FF'}}>
                        <span className="f-plex" style={{fontSize:21, fontWeight:700, color:'#fff'}}>{v.b}</span>
                      </span>
                    )}
                    <div className="f-mono" style={{fontSize:17, color:'#94A3B8', marginTop:22}}>{i === 0 ? 'rama 1' : 'rama 2'}</div>
                  </div>
                );
              })}
            </div>
          </div>
        );
      })()}

      {/* «Ahora mira la dirección»: el navegador sube — puente al clímax */}
      {bajaP > 0.02 && (
        <div style={{position:'absolute', left:250, top:lerp(120,158,bajaP), width:1420, zIndex:52,
                     opacity:bajaP, transform:`scale(${lerp(0.94,1,bajaP)})`}}>
          <div style={{display:'flex', alignItems:'center', gap:18, height:104, padding:'0 30px', borderRadius:52,
                       background:'#fff', border:'3px solid #0085FF', boxShadow:'0 22px 60px rgba(0,133,255,0.30)'}}>
            <Ico n="lupa" s={26} c="#0085FF"/>
            <span className="f-mono" style={{flex:1, fontSize:30, color:'#0F172A', whiteSpace:'nowrap', overflow:'hidden'}}>
              play.dinaup.com/App/ToDo/8f3c1d92…/To-Do<span style={{color:'#0085FF'}}>?q=etiquetas&amp;users=…</span>
            </span>
          </div>
          <div className="f-plex" style={{textAlign:'center', fontSize:32, fontWeight:600, color:'#334155', marginTop:26}}>
            Ahora mira la dirección.
          </div>
        </div>
      )}

      <ScriptedCursor t={t}
        clickTimes={[T.boton+0.7, 8.20, 8.95, 9.70, 16.30, 19.78, 20.10, 20.42, T.chipentero, 23.30, 23.95, T.chuleta-0.5, 31.55, 32.40]}
        frames={[
          { t:0,              x:1810, y:1050 },
          { t:T.boton+0.7,    x:FILX+74,  y:360 },
          { t:8.20,           x:FILX+140, y:BAR+186 },   // Mis tareas
          { t:8.95,           x:FILX+140, y:BAR+364 },   // Prioridad alta
          { t:9.70,           x:FILX+140, y:BAR+286 },   // Esta semana
          { t:T.abiertas,     x:FILX+140, y:BAR+86 },    // Abiertas, ya puesto
          { t:16.30,          x:FILX+140, y:BAR+440 },   // Todas
          { t:19.78,          x:FILX+140, y:BAR+186 },
          { t:20.10,          x:FILX+140, y:BAR+364 },
          { t:20.42,          x:FILX+140, y:BAR+286 },
          { t:T.chipentero,   x:MX+520,   y:CHIPY+30 },  // el chip ENTERO
          { t:23.30,          x:MX+360,   y:CHIPY+30 },
          { t:23.95,          x:MX+200,   y:CHIPY+30 },
          { t:T.chuleta-0.5,  x:BOXX+200, y:360 },       // pinchar dentro de la caja
          { t:31.55,          x:BOXX+200, y:BAR+66 },    // @ usuario
          { t:32.40,          x:BOXX+200, y:BAR+120 },   // tipo:
          { t:T.medio,        x:BOXX+200, y:360 },
          { t:T.ninguna,      x:1810, y:1050 },
        ]}/>
    </SlideCanvas>
  );
}
Object.assign(window, { EscenaTV03 });
