/* AI Edge v2 — cinematic FX. Requires React, window.AE, window.I, window.useInView, window.HeroCanvas, THREE (optional). */
(function(){
const { useState, useEffect, useRef } = React;
const AE = window.AE, I = window.I, useInView = window.useInView;
const motionOff = ()=> document.documentElement.dataset.motion==="off";

/* oklch(L C H) -> [r,g,b]; deterministic, no reliance on browser color serialization */
function oklchToRgb(L,C,H){
  const hr=H*Math.PI/180, a=C*Math.cos(hr), b=C*Math.sin(hr);
  const l_=L+0.3963377774*a+0.2158037573*b, m_=L-0.1055613458*a-0.0638541728*b, s_=L-0.0894841775*a-1.2914855480*b;
  const l=l_*l_*l_, m=m_*m_*m_, s=s_*s_*s_;
  const r=4.0767416621*l-3.3077115913*m+0.2309699292*s;
  const g=-1.2684380046*l+2.6097574011*m-0.3413193965*s;
  const bb=-0.0041960863*l-0.7034186147*m+1.7076147010*s;
  const gam=(x)=>{ x=Math.max(0,Math.min(1,x)); return x<=0.0031308?12.92*x:1.055*Math.pow(x,1/2.4)-0.055; };
  return [Math.round(gam(r)*255),Math.round(gam(g)*255),Math.round(gam(bb)*255)];
}
function parseColor(s,fb){
  s=(s||"").trim();
  const ok=s.match(/oklch\(\s*([\d.]+)\s+([\d.]+)\s+([\d.]+)/i);
  if(ok){ const c=oklchToRgb(+ok[1],+ok[2],+ok[3]); return c[0]+","+c[1]+","+c[2]; }
  const m=s.match(/[\d.]+/g); return (m&&m.length>=3)?m.slice(0,3).map(n=>Math.round(+n)).join(","):fb;
}
function accentRGB(){
  const s=parseColor(getComputedStyle(document.documentElement).getPropertyValue("--accent"),"78,227,154").split(",");
  return { r:(+s[0])/255, g:(+s[1])/255, b:(+s[2])/255 };
}

/* ---------------- CharReveal ---------------- */
function CharReveal({ text, trigger, stagger=42, base=0, className="" }){
  const [ref,seen]=useInView({ threshold:0.4 });
  const mo=motionOff();
  const on = (trigger!==undefined ? trigger : seen) || mo;
  const chars=[...text];
  return (
    <span ref={ref} className={`cr ${className}`}>
      {chars.map((c,i)=>(
        <span key={i} className="ch" style={{
          display:"inline-block",
          opacity:on?1:0,
          transform:on?"none":"translateY(0.35em)"
        }}>{c===" " ? " " : c}</span>
      ))}
    </span>
  );
}

/* ---------------- CursorGlow ---------------- */
function CursorGlow(){
  const ref=useRef(null);
  useEffect(()=>{
    const el=ref.current; let x=innerWidth/2,y=innerHeight/2,tx=x,ty=y,raf;
    const move=(e)=>{ tx=e.clientX; ty=e.clientY; el.classList.add("on"); };
    const loop=()=>{ x+=(tx-x)*0.16; y+=(ty-y)*0.16; el.style.transform=`translate(${x}px,${y}px)`; raf=requestAnimationFrame(loop); };
    window.addEventListener("pointermove",move,{passive:true}); loop();
    return ()=>{ window.removeEventListener("pointermove",move); cancelAnimationFrame(raf); };
  },[]);
  return <div ref={ref} className="cursor-glow"></div>;
}

/* ---------------- TopProgress ---------------- */
function TopProgress(){
  const ref=useRef(null);
  useEffect(()=>{
    let raf;
    const upd=()=>{ const h=document.documentElement.scrollHeight-innerHeight;
      const p=h>0?Math.min(1,scrollY/h):0; if(ref.current) ref.current.style.width=(p*100)+"%"; };
    const on=()=>{ cancelAnimationFrame(raf); raf=requestAnimationFrame(upd); };
    upd(); addEventListener("scroll",on,{passive:true}); addEventListener("resize",on);
    return ()=>{ removeEventListener("scroll",on); removeEventListener("resize",on); cancelAnimationFrame(raf); };
  },[]);
  return <div ref={ref} className="pbar"></div>;
}

/* ---------------- BootSequence ---------------- */
function BootSequence({ onDone }){
  const B=AE.boot;
  const [n,setN]=useState(0);     // lines shown
  const [pct,setPct]=useState(0);
  const [out,setOut]=useState(false);
  useEffect(()=>{
    let alive=true; const tos=[];
    let acc=0;
    B.lines.forEach((ln,i)=>{ acc+=ln.ms;
      tos.push(setTimeout(()=>{ if(!alive)return; setN(i+1); setPct(Math.round((i+1)/B.lines.length*100)); }, acc));
    });
    tos.push(setTimeout(()=>{ if(!alive)return; setOut(true); }, acc+560));
    tos.push(setTimeout(()=>{ if(!alive)return; onDone(); }, acc+1180));
    return ()=>{ alive=false; tos.forEach(clearTimeout); };
  },[]);
  const skip=()=>{ setOut(true); setTimeout(onDone,260); };
  return (
    <div className={`boot ${out?"out":""}`}>
      <div className="boot-box">
        <div className="boot-top">
          <span className="glyph"><I.glyph/></span>
          <span style={{whiteSpace:"nowrap"}}>{B.title}</span>
          <button className="skip" onClick={skip}>skip →</button>
        </div>
        <div className="boot-log">
          {B.lines.map((ln,i)=>(
            <div key={i} className={`boot-line ${i<n?"show":""} ${ln.last?"last":""}`}>
              <span className="mk">{ln.last?"":"[ok]"}</span>
              <span className="tx">{ln.txt}{i===n-1 && !ln.last && <span className="boot-cursor"></span>}</span>
              {ln.v && <span className="vv">{ln.v}</span>}
            </div>
          ))}
        </div>
        <div className="boot-bar"><i style={{ width:pct+"%" }}></i></div>
      </div>
    </div>
  );
}

/* ---------------- Particle field (Three.js) ---------------- */
function useParticles(canvasRef, booted, active){
  useEffect(()=>{
    if(!active) return;
    const THREE = window.THREE;
    const canvas = canvasRef.current;
    if(!THREE || !canvas){ return; }
    const host = canvas.parentElement;
    let w=host.clientWidth, h=host.clientHeight;
    const renderer = new THREE.WebGLRenderer({ canvas, alpha:true, antialias:true });
    renderer.setPixelRatio(Math.min(2, window.devicePixelRatio||1));
    renderer.setSize(w,h);
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(58, w/h, 0.1, 100);
    camera.position.z = 26;

    const isMobile = w<700;
    const N = isMobile? 1300 : 2800;
    const pos = new Float32Array(N*3), scl = new Float32Array(N), mix = new Float32Array(N);
    // gaussian-ish blob, flattened on z for depth-of-field feel
    function gauss(){ return (Math.random()+Math.random()+Math.random()-1.5)/1.5; }
    for(let i=0;i<N;i++){
      const r = 3.6 + Math.random()*4.2;
      const a = Math.random()*Math.PI*2, b = Math.acos(2*Math.random()-1);
      pos[i*3]   = Math.sin(b)*Math.cos(a)*r;
      pos[i*3+1] = Math.sin(b)*Math.sin(a)*r;
      pos[i*3+2] = Math.cos(b)*r*0.7;
      scl[i] = 0.45 + Math.random()*Math.random()*1.8;
      mix[i] = Math.pow(Math.random(),3);
    }
    const geo = new THREE.BufferGeometry();
    geo.setAttribute("position", new THREE.BufferAttribute(pos,3));
    geo.setAttribute("aScale", new THREE.BufferAttribute(scl,1));
    geo.setAttribute("aMix", new THREE.BufferAttribute(mix,1));

    const ac = accentRGB();
    const uniforms = {
      uTime:{value:0}, uOpacity:{value:0}, uSize:{value: isMobile?70:96 },
      uColor:{value:new THREE.Color(ac.r,ac.g,ac.b)},
      uColor2:{value:new THREE.Color(ac.r,ac.g,ac.b).lerp(new THREE.Color(1,1,1),0.4)},
    };
    const mat = new THREE.ShaderMaterial({
      uniforms, transparent:true, depthWrite:false, blending:THREE.AdditiveBlending,
      vertexShader:`
        attribute float aScale; attribute float aMix;
        varying float vMix; varying float vTw;
        uniform float uTime; uniform float uSize;
        void main(){
          vMix=aMix;
          vec3 p = position;
          float t = uTime*0.18;
          p.x += sin(p.y*0.55 + t) * 0.45 + cos(p.z*0.5 - t*0.7) * 0.30;
          p.y += cos(p.x*0.5 + t*0.9) * 0.45 + sin(p.z*0.6 + t) * 0.25;
          p.z += sin(p.x*0.4 + p.y*0.4 + t) * 0.40;
          vec4 mv = modelViewMatrix * vec4(p,1.0);
          float tw = 0.55 + 0.45*sin(uTime*1.4 + aScale*28.0 + position.x*0.6);
          vTw = tw;
          gl_PointSize = uSize * aScale * (0.6+0.6*tw) * (1.0 / -mv.z);
          gl_Position = projectionMatrix * mv;
        }`,
      fragmentShader:`
        varying float vMix; varying float vTw;
        uniform vec3 uColor; uniform vec3 uColor2; uniform float uOpacity;
        void main(){
          float d = length(gl_PointCoord - vec2(0.5));
          if(d>0.5) discard;
          float a = smoothstep(0.5, 0.04, d);
          vec3 c = mix(uColor, uColor2, vMix);
          gl_FragColor = vec4(c, a * uOpacity * (0.35 + 0.65*vTw));
        }`,
    });
    const points = new THREE.Points(geo, mat);

    // graph lines between near neighbours (subset, static)
    const LN = isMobile? 260 : 620;
    const lp = [];
    for(let i=0;i<LN;i++){
      const a = (Math.random()*N)|0;
      let best=-1, bd=1e9;
      for(let k=0;k<6;k++){ const b=(Math.random()*N)|0; if(b===a)continue;
        const dx=pos[a*3]-pos[b*3], dy=pos[a*3+1]-pos[b*3+1], dz=pos[a*3+2]-pos[b*3+2];
        const dd=dx*dx+dy*dy+dz*dz; if(dd<bd){bd=dd;best=b;} }
      if(best>=0 && bd<10){ lp.push(pos[a*3],pos[a*3+1],pos[a*3+2], pos[best*3],pos[best*3+1],pos[best*3+2]); }
    }
    const lgeo=new THREE.BufferGeometry();
    lgeo.setAttribute("position", new THREE.BufferAttribute(new Float32Array(lp),3));
    const lmat=new THREE.LineBasicMaterial({ color:new THREE.Color(ac.r,ac.g,ac.b), transparent:true, opacity:0, blending:THREE.AdditiveBlending, depthWrite:false });
    const lines=new THREE.LineSegments(lgeo, lmat);

    const group=new THREE.Group(); group.add(points); group.add(lines); scene.add(group);

    let mx=0,my=0, r2x=0,r2y=0, raf, t0=performance.now(), accFrame=0;
    const onMove=(e)=>{ mx=(e.clientX/innerWidth-0.5); my=(e.clientY/innerHeight-0.5); };
    addEventListener("pointermove",onMove,{passive:true});

    function resize(){ w=host.clientWidth; h=host.clientHeight; camera.aspect=w/h; camera.updateProjectionMatrix(); renderer.setSize(w,h); }
    const ro=new ResizeObserver(resize); ro.observe(host);

    function loop(now){
      raf=requestAnimationFrame(loop);
      const dt=(now-t0)/1000; t0=now; accFrame++;
      const mot = !motionOff();
      if(mot){ uniforms.uTime.value = now/1000; }
      // entrance
      const tgtOpacity = booted.current? 1:0;
      uniforms.uOpacity.value += (tgtOpacity-uniforms.uOpacity.value)*0.05;
      lmat.opacity += ((booted.current? (isMobile?0.09:0.16):0)-lmat.opacity)*0.05;
      const tgtZ = booted.current? 16:26;
      camera.position.z += (tgtZ-camera.position.z)*0.04;
      // rotation toward pointer + idle spin
      if(mot){ group.rotation.y += dt*0.06; }
      r2x += ((my*0.5)-r2x)*0.05; r2y += ((mx*0.6)-r2y)*0.05;
      group.rotation.x = r2x; group.rotation.y += (r2y-(group.rotation._py||0)); group.rotation._py=r2y;
      camera.position.x += ((mx*3)-camera.position.x)*0.04;
      camera.position.y += ((-my*2)-camera.position.y)*0.04;
      camera.lookAt(0,0,0);
      // re-read accent occasionally for live tweak
      if(accFrame%45===0){ const a=accentRGB(); uniforms.uColor.value.setRGB(a.r,a.g,a.b); uniforms.uColor2.value.setRGB(a.r,a.g,a.b); uniforms.uColor2.value.lerp(new THREE.Color(1,1,1),0.4); lmat.color.setRGB(a.r,a.g,a.b); }
      renderer.render(scene,camera);
    }
    raf=requestAnimationFrame(loop);
    return ()=>{ cancelAnimationFrame(raf); removeEventListener("pointermove",onMove); ro.disconnect();
      geo.dispose(); mat.dispose(); lgeo.dispose(); lmat.dispose(); renderer.dispose(); };
  },[active]);
}

function FlowFieldCanvas(){
  const cv=useRef(null);
  useEffect(()=>{
    const canvas=cv.current, ctx=canvas.getContext("2d");
    const host=canvas.parentElement, root=document.documentElement;
    let w,h,dpr,raf,parts=[],frame=0,accent="78,227,154",bg="14,17,22";
    const readColors=()=>{ accent=parseColor(getComputedStyle(root).getPropertyValue("--accent"),"78,227,154");
      bg=parseColor(getComputedStyle(root).getPropertyValue("--bg"),"14,17,22"); };
    const count=()=> Math.min(1100, Math.round(w*h/2000));
    const spawn=(p)=>{ p.x=Math.random()*w; p.y=Math.random()*h; p.life=60+Math.random()*200; };
    const field=(x,y,t)=> (Math.sin(y*0.0042+t*0.25)+Math.cos(x*0.0042-t*0.2))*Math.PI + Math.sin((x+y)*0.0016+t*0.1)*0.8;
    let mx=-1,my=-1;
    const onMove=(e)=>{ const r=host.getBoundingClientRect(); mx=e.clientX-r.left; my=e.clientY-r.top; };
    const size=()=>{ dpr=Math.min(2,devicePixelRatio||1); const r=host.getBoundingClientRect();
      w=r.width;h=r.height;canvas.width=w*dpr;canvas.height=h*dpr;ctx.setTransform(dpr,0,0,dpr,0,0);
      ctx.fillStyle=`rgb(${bg})`; ctx.fillRect(0,0,w,h);
      parts=Array.from({length:count()},()=>{const p={};spawn(p);return p;});
      ctx.lineWidth=1.1;
      for(const p of parts){ const a=field(p.x,p.y,0); ctx.strokeStyle=`rgba(${accent},0.16)`;
        ctx.beginPath(); ctx.moveTo(p.x,p.y); ctx.lineTo(p.x+Math.cos(a)*6,p.y+Math.sin(a)*6); ctx.stroke(); } };
    const step=()=>{ frame++; if(frame%50===0) readColors();
      if(root.dataset.motion==="off"){ return; }
      ctx.fillStyle=`rgba(${bg},0.05)`; ctx.fillRect(0,0,w,h);
      const t=frame*0.01; ctx.lineWidth=1.2;
      for(const p of parts){
        let a=field(p.x,p.y,t), near=0;
        if(mx>=0){ const dx=p.x-mx,dy=p.y-my,dist=Math.hypot(dx,dy); near=Math.max(0,1-dist/200); a+=near*1.3; }
        const nx=p.x+Math.cos(a)*1.3, ny=p.y+Math.sin(a)*1.3;
        ctx.strokeStyle=`rgba(${accent},${0.09+near*0.55})`;
        ctx.beginPath(); ctx.moveTo(p.x,p.y); ctx.lineTo(nx,ny); ctx.stroke();
        p.x=nx; p.y=ny; p.life--;
        if(p.x<-2||p.x>w+2||p.y<-2||p.y>h+2||p.life<0) spawn(p);
      } };
    const loop=()=>{ step(); raf=requestAnimationFrame(loop); };
    readColors(); size(); loop();
    const ro=new ResizeObserver(size); ro.observe(host);
    addEventListener("pointermove",onMove,{passive:true});
    return ()=>{ cancelAnimationFrame(raf); ro.disconnect(); removeEventListener("pointermove",onMove); };
  },[]);
  return <canvas ref={cv} className="phero-canvas"></canvas>;
}

function ParticleHero({ booted, fx }){
  const canvasRef=useRef(null);
  const bootedRef=useRef(booted);
  useEffect(()=>{ bootedRef.current=booted; },[booted]);
  const useThree = fx==="particles" && !!window.THREE;
  useParticles(canvasRef, bootedRef, useThree);
  const [copied,setCopied]=useState(false);
  const cmd="npm i "+AE.npm;
  const copy=()=>{ navigator.clipboard?.writeText(cmd); setCopied(true); setTimeout(()=>setCopied(false),1400); };
  const mo = motionOff();
  const rvStyle=(d)=>({ opacity:(booted||mo)?1:0, transform:(booted||mo)?"none":"translateY(16px)" });

  return (
    <header className={`phero ${booted?"live":""}`} id="top">
      {useThree && <canvas ref={canvasRef} className="phero-canvas"></canvas>}
      {fx==="flow" && <FlowFieldCanvas/>}
      {fx==="grid" && <div className="phero-canvas">{React.createElement(window.HeroCanvas)}</div>}
      <div className="phero-veil"></div>
      <div className="wrap phero-inner">
        <div className="eyebrow" style={rvStyle(40)}>{AE.hero.eyebrow}</div>
        <h1>
          <CharReveal text="AI " trigger={booted} stagger={70}/>
          <span className="mk"><CharReveal text="Edge" trigger={booted} stagger={70} base={210}/></span>
        </h1>
        <p className="hero-tag" style={rvStyle(120)}>
          <b>{AE.hero.tag[0]}</b><br/>
          <span style={{color:"var(--muted)"}}>{AE.hero.tag[1]}</span>
        </p>
        <div className="hero-cta" style={rvStyle(200)}>
          <a href="#video" className="btn btn-primary"><I.play/>{AE.ui.ctaWatch}</a>
          <div className="term">
            <span className="prompt">$</span><code>{cmd}</code>
            <button className="copy" onClick={copy} aria-label="复制">{copied? <I.check/> : <I.copy/>}</button>
          </div>
        </div>
        <div className="hero-meta" style={rvStyle(280)}>
          <span className="chip"><span className="dot"></span>Hit Rate@5 ≥ 90%</span>
          <span className="chip">{AE.ui.chipMit}</span>
          <span className="chip">P95 ~412ms</span>
          <span className="chip">{AE.ui.chipCn}</span>
        </div>
      </div>
      <div className="phero-scroll" style={rvStyle(420)}><span>SCROLL</span><span className="ln"></span></div>
    </header>
  );
}

/* ---------------- Magnetic + Tilt ---------------- */
function Magnetic({ children, strength=0.4 }){
  const ref=useRef(null);
  useEffect(()=>{
    const el=ref.current; if(!el) return;
    if(matchMedia("(pointer:coarse)").matches) return;
    const move=(e)=>{ if(motionOff())return; const r=el.getBoundingClientRect();
      const x=e.clientX-(r.left+r.width/2), y=e.clientY-(r.top+r.height/2);
      el.style.transform=`translate(${x*strength}px,${y*strength}px)`; };
    const leave=()=>{ el.style.transform="translate(0,0)"; };
    el.addEventListener("pointermove",move); el.addEventListener("pointerleave",leave);
    return ()=>{ el.removeEventListener("pointermove",move); el.removeEventListener("pointerleave",leave); };
  },[]);
  return <span ref={ref} className="mag">{children}</span>;
}
function Tilt({ children, className="", max=9 }){
  const ref=useRef(null);
  useEffect(()=>{
    const el=ref.current; if(!el) return;
    if(matchMedia("(pointer:coarse)").matches) return;
    const move=(e)=>{ if(motionOff())return; const r=el.getBoundingClientRect();
      const px=(e.clientX-r.left)/r.width-0.5, py=(e.clientY-r.top)/r.height-0.5;
      el.style.transform=`perspective(800px) rotateY(${px*max}deg) rotateX(${-py*max}deg) translateY(-2px)`; };
    const leave=()=>{ el.style.transform="perspective(800px) rotateY(0) rotateX(0)"; };
    el.addEventListener("pointermove",move); el.addEventListener("pointerleave",leave);
    return ()=>{ el.removeEventListener("pointermove",move); el.removeEventListener("pointerleave",leave); };
  },[]);
  return <div ref={ref} className={`tilt ${className}`}>{children}</div>;
}

/* ---------------- Capabilities v2 (tilt) ---------------- */
const capIcon = { retrieval:I.retrieval, agent:I.agent, sql:I.sql, eval:I.eval };
function CapabilitiesV2(){
  const [ref,seen]=useInView();
  return (
    <section className="section-pad" id="caps">
      <div className="wrap">
        <div className="section-head" ref={ref}>
          <div className="eyebrow">{AE.ui.capEyebrow}</div>
          <h2><CharReveal text={AE.ui.capTitle} trigger={seen} stagger={28}/></h2>
          <p style={{opacity:seen?1:0, transition:"opacity .8s .3s"}}>{AE.ui.capLead}</p>
        </div>
        <div className="cap-grid">
          {AE.caps.map((c,i)=>{ const Ico=capIcon[c.k]; return (
            <Tilt key={c.k} className="cap-tilt">
              <div className="cap" style={{ transitionDelay:(i*60)+"ms", opacity:seen?1:0, transform:seen?"none":"translateY(20px)", transition:"opacity .6s, transform .6s, border-color .2s" }}>
                <span className="num mono">0{i+1}</span>
                <span className="cap-ico tilt-z"><Ico/></span>
                <div className="tilt-z"><h3>{c.t}</h3><p>{c.d}</p></div>
              </div>
            </Tilt>
          );})}
        </div>
      </div>
    </section>
  );
}

/* ---------------- Retrieval Trace (redesigned pipeline) ---------------- */
function ScrollFlow(){
  const [mode,setMode]=useState("success");
  const [shown,setShown]=useState(0);
  const secRef=useRef(null);
  const startedRef=useRef(false);
  const timerRef=useRef(null);
  const data=AE.trace.cases[mode];
  const N=data.spans.length;

  const play=()=>{
    clearInterval(timerRef.current);
    if(document.documentElement.dataset.motion==="off"){ setShown(N+1); return; }
    setShown(0); let i=0;
    timerRef.current=setInterval(()=>{ i++; setShown(i); if(i>=N+1) clearInterval(timerRef.current); }, 230);
  };
  useEffect(()=>{
    const el=secRef.current;
    const check=()=>{ if(startedRef.current||!el) return;
      const r=el.getBoundingClientRect();
      if(r.top<innerHeight*0.72 && r.bottom>innerHeight*0.28){ startedRef.current=true; play(); } };
    check(); addEventListener("scroll",check,{passive:true}); addEventListener("resize",check);
    return ()=>{ removeEventListener("scroll",check); removeEventListener("resize",check); clearInterval(timerRef.current); };
  },[]);
  useEffect(()=>{ if(startedRef.current) play(); },[mode]);

  return (
    <section className="flow section-pad" id="flow" ref={secRef}>
      <div className="wrap">
        <div className="section-head" style={{marginBottom:26}}>
          <div className="eyebrow">{AE.trace.eyebrow}</div>
          <h2 style={{marginTop:12}}>{AE.trace.title}</h2>
          <p style={{marginTop:14}}>{AE.trace.sub}</p>
        </div>
        <div className="tabs" style={{marginBottom:18}}>
          {["success","fallback"].map(m=>(
            <button key={m} className={`tab ${mode===m?"on":""}`} onClick={()=>setMode(m)}>
              <span className="tg">{AE.trace.cases[m].tag}</span>{AE.trace.cases[m].label}
            </button>
          ))}
        </div>
        <div className="trace">
          <div className="trace-head">
            <span className="trace-q"><b>{AE.ui.traceQuery}</b><span className="arr">›</span>{data.q}</span>
            <span className="trace-total">{AE.ui.traceTotalA}{data.total}{AE.ui.traceTotalB}</span>
          </div>
          <div className="trace-body">
            {data.spans.map((s,i)=>{
              const left=(s.a/data.total*100), w=(s.d/data.total*100);
              return (
                <div key={i} className={`trace-row ${i<shown?"in":""}`}>
                  <div className="trace-label"><span className="k">{s.k}</span><span className="n">{s.n}</span></div>
                  <div className="trace-track">
                    <div className={`trace-bar ${s.warn?"warn":""}`} style={{ left:left+"%", "--w":w+"%" }}></div>
                  </div>
                  <div className={`trace-res ${s.warn?"warn":""}`}><span>{s.r}</span><span className="d">{s.d}ms</span></div>
                </div>
              );
            })}
          </div>
          <div className={`trace-verdict ${data.verdict.ok?"ok":"warn"} ${shown>N?"in":""}`}>
            {data.verdict.ok? <I.check style={{width:16,height:16}}/> : <I.warn style={{width:16,height:16}}/>}
            <span>{data.verdict.t}</span>
          </div>
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { CharReveal, CursorGlow, TopProgress, BootSequence, ParticleHero, Magnetic, Tilt, CapabilitiesV2, ScrollFlow });
})();
