// Nivk.com Insights — the living mark. A breathing emerald core with three satellites
// orbiting on tilted rings (Posts · Queries · Topics), a slow radar sweep, and
// occasional discovery pings that fire a brief beam back to the core. Pure canvas,
// DPR-aware, self-cleaning, honors reduced-motion. Adapted from the SQSEO BrandOrb.
(function init(){
if(!window.React){return setTimeout(init,30);}
const React = window.React;

const RGB = { accent: "14,138,95", cyan: "33,184,205", amber: "245,166,35" };

function BrandOrb({ size = 120, className, style }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    const canvas = ref.current; if (!canvas) return;
    const ctx = canvas.getContext("2d"); if (!ctx) return;
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    const dpr = Math.min(2, window.devicePixelRatio || 1);
    canvas.width = Math.round(size * dpr); canvas.height = Math.round(size * dpr);
    ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
    const cx = size / 2, cy = size / 2, R = size / 2 - 6, start = performance.now();

    const sats = [
      { hue: "accent", radius: 0.92, speed: 0.55, phase: 0.3, tilt: 0.42, size: 3.6, nextPing: 1400 },
      { hue: "cyan", radius: 0.66, speed: -0.8, phase: 2.1, tilt: 0.7, size: 3.0, nextPing: 2600 },
      { hue: "amber", radius: 0.44, speed: 1.15, phase: 4.0, tilt: 0.3, size: 2.6, nextPing: 3800 },
    ];
    const pings = [];
    const satPos = (s, t) => { const ang = s.phase + t * s.speed; return { x: cx + Math.cos(ang) * R * s.radius, y: cy + Math.sin(ang) * R * s.radius * s.tilt, ang }; };

    const draw = (now) => {
      const t = (now - start) / 1000;
      ctx.clearRect(0, 0, size, size);
      const halo = ctx.createRadialGradient(cx, cy, 0, cx, cy, R);
      halo.addColorStop(0, "rgba(14,138,95,0.10)"); halo.addColorStop(1, "rgba(14,138,95,0)");
      ctx.fillStyle = halo; ctx.beginPath(); ctx.arc(cx, cy, R, 0, Math.PI * 2); ctx.fill();

      for (const s of sats) {
        ctx.beginPath(); ctx.ellipse(cx, cy, R * s.radius, R * s.radius * s.tilt, 0, 0, Math.PI * 2);
        ctx.strokeStyle = "rgba(" + RGB[s.hue] + ",0.10)"; ctx.lineWidth = 1; ctx.stroke();
      }
      if (!reduce) {
        const sweep = t * 0.6; ctx.save(); ctx.translate(cx, cy); ctx.rotate(sweep);
        const g = ctx.createLinearGradient(0, 0, R, 0);
        g.addColorStop(0, "rgba(14,138,95,0.12)"); g.addColorStop(1, "rgba(14,138,95,0)");
        ctx.fillStyle = g; ctx.beginPath(); ctx.moveTo(0, 0); ctx.arc(0, 0, R, -0.5, 0); ctx.closePath(); ctx.fill(); ctx.restore();
      }
      for (let i = pings.length - 1; i >= 0; i--) {
        const p = pings[i]; const age = (now - p.born) / 900;
        if (age >= 1) { pings.splice(i, 1); continue; }
        const rr = 2 + age * 13;
        ctx.beginPath(); ctx.arc(p.x, p.y, rr, 0, Math.PI * 2);
        ctx.strokeStyle = "rgba(" + RGB[p.hue] + "," + ((1 - age) * 0.6) + ")"; ctx.lineWidth = 1.4; ctx.stroke();
        ctx.beginPath(); ctx.moveTo(p.x, p.y); ctx.lineTo(cx, cy);
        ctx.strokeStyle = "rgba(" + RGB[p.hue] + "," + ((1 - age) * 0.22) + ")"; ctx.lineWidth = 1; ctx.stroke();
      }
      const drawn = sats.map((s) => ({ s, pos: satPos(s, reduce ? s.phase / s.speed : t) })).sort((a, b) => a.pos.y - b.pos.y);
      for (const d of drawn) {
        const s = d.s, pos = d.pos, rgb = RGB[s.hue];
        const glow = ctx.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, s.size * 4);
        glow.addColorStop(0, "rgba(" + rgb + ",0.30)"); glow.addColorStop(1, "rgba(" + rgb + ",0)");
        ctx.fillStyle = glow; ctx.beginPath(); ctx.arc(pos.x, pos.y, s.size * 4, 0, Math.PI * 2); ctx.fill();
        ctx.fillStyle = "rgb(" + rgb + ")"; ctx.beginPath(); ctx.arc(pos.x, pos.y, s.size, 0, Math.PI * 2); ctx.fill();
        if (!reduce && now >= s.nextPing + start) { pings.push({ x: pos.x, y: pos.y, hue: s.hue, born: now }); s.nextPing = now - start + 2600 + Math.random() * 2600; }
      }
      const breathe = reduce ? 0 : Math.sin(t * 1.6) * 1.1;
      const coreR = size * 0.085 + breathe;
      const coreGlow = ctx.createRadialGradient(cx, cy, 0, cx, cy, coreR * 3.2);
      coreGlow.addColorStop(0, "rgba(14,138,95,0.45)"); coreGlow.addColorStop(1, "rgba(14,138,95,0)");
      ctx.fillStyle = coreGlow; ctx.beginPath(); ctx.arc(cx, cy, coreR * 3.2, 0, Math.PI * 2); ctx.fill();
      const core = ctx.createRadialGradient(cx - coreR * 0.3, cy - coreR * 0.3, 0, cx, cy, coreR);
      core.addColorStop(0, "rgba(60,190,140,1)"); core.addColorStop(1, "rgba(10,113,80,1)");
      ctx.fillStyle = core; ctx.beginPath(); ctx.arc(cx, cy, coreR, 0, Math.PI * 2); ctx.fill();
    };

    if (reduce) { draw(start); return; }
    let raf = 0;
    const loop = (now) => { draw(now); raf = requestAnimationFrame(loop); };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, [size]);

  return <canvas ref={ref} aria-hidden className={className} style={{ width: size, height: size, display: "block", ...(style || {}) }} />;
}

window.LTQ = window.LTQ || {};
window.LTQ.BrandOrb = BrandOrb;
})();
