// AI Experiments — 6 logo animation concepts
// Shared aesthetic: thin dark lines on near-white, parametric geometry, 4-8s loops.

const STROKE = '#1a1a1a';
const STROKE_SOFT = '#2a2a2a';

// Shared hook: animation clock
function useClock(speed = 1) {
  const [t, setT] = React.useState(0);
  React.useEffect(() => {
    let raf, start = performance.now();
    const tick = (now) => {
      setT(((now - start) / 1000) * speed);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [speed]);
  return t;
}

// ─────────────────────────────────────────────────────────────
// 1) Orbiting Particles — electrons around a nucleus
//    Three tilted ellipses, dots traveling along them at different speeds
// ─────────────────────────────────────────────────────────────
function OrbitLogo({ size = 200, speed = 1, stroke = STROKE }) {
  const t = useClock(speed);
  const cx = size / 2, cy = size / 2;
  const rings = [
    { rx: 78, ry: 30, rot: 0, speed: 0.6, n: 1, phase: 0 },
    { rx: 78, ry: 30, rot: 60, speed: -0.4, n: 1, phase: 1.2 },
    { rx: 78, ry: 30, rot: -60, speed: 0.5, n: 1, phase: 2.4 },
  ];
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {/* rings */}
      {rings.map((r, i) => (
        <ellipse key={i} cx={cx} cy={cy} rx={r.rx} ry={r.ry}
          fill="none" stroke={stroke} strokeWidth="0.8"
          opacity="0.35"
          transform={`rotate(${r.rot} ${cx} ${cy})`} />
      ))}
      {/* nucleus */}
      <circle cx={cx} cy={cy} r="3.5" fill={stroke} />
      {/* electrons */}
      {rings.map((r, i) => {
        const a = t * r.speed * Math.PI * 2 + r.phase;
        const px = Math.cos(a) * r.rx;
        const py = Math.sin(a) * r.ry;
        const rad = (r.rot * Math.PI) / 180;
        const x = cx + px * Math.cos(rad) - py * Math.sin(rad);
        const y = cy + px * Math.sin(rad) + py * Math.cos(rad);
        return <circle key={i} cx={x} cy={y} r="3" fill={stroke} />;
      })}
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// 2) Neural Mesh — points connected, gentle drift, pulses travel along edges
// ─────────────────────────────────────────────────────────────
function NeuralLogo({ size = 200, speed = 1, stroke = STROKE }) {
  const t = useClock(speed);
  // Fixed node lattice (hex-ish)
  const nodes = React.useMemo(() => {
    const arr = [];
    const rows = 5, cols = 5;
    for (let r = 0; r < rows; r++) {
      for (let c = 0; c < cols; c++) {
        const x = 40 + c * 30 + (r % 2) * 15;
        const y = 40 + r * 30;
        arr.push({ x, y, ox: x, oy: y, seed: Math.random() * 10 });
      }
    }
    return arr;
  }, []);
  const edges = React.useMemo(() => {
    const es = [];
    for (let i = 0; i < nodes.length; i++) {
      for (let j = i + 1; j < nodes.length; j++) {
        const dx = nodes[i].ox - nodes[j].ox;
        const dy = nodes[i].oy - nodes[j].oy;
        if (Math.hypot(dx, dy) < 38) es.push([i, j]);
      }
    }
    return es;
  }, [nodes]);

  // drift
  const drifted = nodes.map(n => ({
    ...n,
    x: n.ox + Math.sin(t * 0.8 + n.seed) * 2.5,
    y: n.oy + Math.cos(t * 0.6 + n.seed * 1.3) * 2.5,
  }));

  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {edges.map(([a, b], i) => (
        <line key={i}
          x1={drifted[a].x} y1={drifted[a].y}
          x2={drifted[b].x} y2={drifted[b].y}
          stroke={stroke} strokeWidth="0.5" opacity="0.4" />
      ))}
      {drifted.map((n, i) => {
        const pulse = (Math.sin(t * 2 + i * 0.8) + 1) / 2;
        return <circle key={i} cx={n.x} cy={n.y} r={1.2 + pulse * 1.2} fill={stroke} />;
      })}
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// 3) Signal Field — vector arrows responding to invisible wave
// ─────────────────────────────────────────────────────────────
function FieldLogo({ size = 200, speed = 1, stroke = STROKE }) {
  const t = useClock(speed);
  const grid = 7;
  const step = size / (grid + 1);
  const arrows = [];
  for (let i = 1; i <= grid; i++) {
    for (let j = 1; j <= grid; j++) {
      const x = i * step, y = j * step;
      const dx = x - size / 2, dy = y - size / 2;
      const d = Math.hypot(dx, dy);
      // angle oscillates based on position + time
      const ang = Math.atan2(dy, dx) + Math.sin(t * 0.8 - d * 0.04) * 1.2;
      const len = 9 + Math.sin(t * 1.2 - d * 0.05) * 3;
      const x2 = x + Math.cos(ang) * len;
      const y2 = y + Math.sin(ang) * len;
      const op = 0.25 + (1 - d / (size / 1.4)) * 0.6;
      arrows.push({ x, y, x2, y2, op });
    }
  }
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {arrows.map((a, i) => (
        <g key={i}>
          <line x1={a.x} y1={a.y} x2={a.x2} y2={a.y2}
            stroke={stroke} strokeWidth="0.6" opacity={a.op} strokeLinecap="round" />
          <circle cx={a.x2} cy={a.y2} r="0.9" fill={stroke} opacity={a.op} />
        </g>
      ))}
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// 4) Phase Rings — concentric rings rotating with dashed stroke
// ─────────────────────────────────────────────────────────────
function PhaseRingsLogo({ size = 200, speed = 1, stroke = STROKE }) {
  const t = useClock(speed);
  const cx = size / 2, cy = size / 2;
  const rings = [
    { r: 30, dash: '4 6', speed: 0.4 },
    { r: 50, dash: '2 8', speed: -0.3 },
    { r: 70, dash: '6 4', speed: 0.2 },
    { r: 88, dash: '1 10', speed: -0.15 },
  ];
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      <circle cx={cx} cy={cy} r="4" fill="none" stroke={stroke} strokeWidth="0.8" />
      <circle cx={cx} cy={cy} r="1.2" fill={stroke} />
      {rings.map((r, i) => {
        const rot = (t * r.speed * 180) % 360;
        // subtle radius breathing
        const rr = r.r + Math.sin(t * 0.5 + i) * 1.5;
        return (
          <circle key={i} cx={cx} cy={cy} r={rr}
            fill="none" stroke={stroke} strokeWidth="0.8"
            strokeDasharray={r.dash}
            transform={`rotate(${rot} ${cx} ${cy})`}
            opacity="0.75" />
        );
      })}
      {/* tick marks */}
      {[0, 60, 120, 180, 240, 300].map((deg, i) => {
        const a = (deg + t * 10) * Math.PI / 180;
        const r1 = 94, r2 = 98;
        return (
          <line key={i}
            x1={cx + Math.cos(a) * r1} y1={cy + Math.sin(a) * r1}
            x2={cx + Math.cos(a) * r2} y2={cy + Math.sin(a) * r2}
            stroke={stroke} strokeWidth="0.8" />
        );
      })}
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// 5) Flow Curve — a single ribbon path morphing
// ─────────────────────────────────────────────────────────────
function FlowLogo({ size = 200, speed = 1, stroke = STROKE }) {
  const t = useClock(speed);
  const cx = size / 2, cy = size / 2;
  // Build 5 parallel sine curves with phase offset
  const curves = [];
  for (let k = 0; k < 7; k++) {
    const pts = [];
    const amp = 22 + k * 1.5;
    const freq = 0.04;
    const phase = t * 0.6 + k * 0.18;
    const samples = 60;
    for (let i = 0; i <= samples; i++) {
      const x = 24 + (i / samples) * (size - 48);
      const y = cy + Math.sin((x - cx) * freq + phase) * amp
                    + Math.sin((x - cx) * freq * 2.7 + phase * 1.4) * 4;
      // add vertical offset per curve
      const offset = (k - 3) * 3.5;
      pts.push([x, y + offset]);
    }
    curves.push(pts);
  }
  const toPath = (pts) => pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${p[0].toFixed(2)} ${p[1].toFixed(2)}`).join(' ');
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {curves.map((pts, i) => (
        <path key={i} d={toPath(pts)} fill="none" stroke={stroke}
          strokeWidth="0.7" opacity={0.3 + (1 - Math.abs(i - 3) / 3) * 0.5} />
      ))}
    </svg>
  );
}

// ─────────────────────────────────────────────────────────────
// 6) Token Cluster — dots arriving from edges, coalescing, dispersing
// ─────────────────────────────────────────────────────────────
function TokenLogo({ size = 200, speed = 1, stroke = STROKE }) {
  const t = useClock(speed);
  const cx = size / 2, cy = size / 2;
  // 24 tokens, each orbits a home position while pulsing toward/away from center
  const tokens = React.useMemo(() => {
    const arr = [];
    for (let i = 0; i < 28; i++) {
      const a = (i / 28) * Math.PI * 2;
      arr.push({ a, seed: i * 0.37 });
    }
    return arr;
  }, []);
  // Cycle phase 0..1
  const phase = (Math.sin(t * 0.5) + 1) / 2; // 0=tight, 1=loose
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {/* central ring */}
      <circle cx={cx} cy={cy} r="8" fill="none" stroke={stroke} strokeWidth="0.8" opacity="0.4" />
      {tokens.map((tk, i) => {
        const r = 12 + phase * 72 + Math.sin(t * 1.1 + tk.seed) * 4;
        const a = tk.a + t * 0.15;
        const x = cx + Math.cos(a) * r;
        const y = cy + Math.sin(a) * r;
        // tail pointing inward
        const tx = cx + Math.cos(a) * (r - 8);
        const ty = cy + Math.sin(a) * (r - 8);
        const op = 0.4 + (1 - phase) * 0.5;
        return (
          <g key={i}>
            <line x1={tx} y1={ty} x2={x} y2={y}
              stroke={stroke} strokeWidth="0.6" opacity={op * 0.7} strokeLinecap="round" />
            <circle cx={x} cy={y} r="1.5" fill={stroke} opacity={op} />
          </g>
        );
      })}
    </svg>
  );
}

Object.assign(window, {
  OrbitLogo, NeuralLogo, FieldLogo, PhaseRingsLogo, FlowLogo, TokenLogo,
});
// AI Products — reworked: tactile, object-like, gestural — less UI chrome
const PRODUCT_STROKE = '#1a1a1a';

function useClockP(speed = 1) {
  const [t, setT] = React.useState(0);
  React.useEffect(() => {
    let raf, start = performance.now();
    const tick = (now) => { setT(((now - start) / 1000) * speed); raf = requestAnimationFrame(tick); };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [speed]);
  return t;
}

// ─────────────────────────────────────────────
// P1) Aperture — iris blades rotate/open like a camera shutter
// ─────────────────────────────────────────────
function CardsLogo({ size = 200, speed = 1, stroke = PRODUCT_STROKE }) {
  const t = useClockP(speed);
  const cx = size / 2, cy = size / 2;
  const blades = 8;
  const R = 62;
  const open = (Math.sin(t * 0.6) + 1) / 2; // 0 closed .. 1 open
  const rot = t * 12;
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      <circle cx={cx} cy={cy} r={R + 6} fill="none" stroke={stroke} strokeWidth="0.8" opacity="0.3"/>
      <circle cx={cx} cy={cy} r={R} fill="none" stroke={stroke} strokeWidth="0.7" opacity="0.5"/>
      {Array.from({length: blades}, (_, i) => {
        const a0 = (i / blades) * Math.PI * 2 + (rot * Math.PI / 180);
        const offset = (1 - open) * 24;
        const tip = [cx + Math.cos(a0) * R, cy + Math.sin(a0) * R];
        const base = [cx + Math.cos(a0 + Math.PI * 0.35) * (R - offset),
                      cy + Math.sin(a0 + Math.PI * 0.35) * (R - offset)];
        const ctrl = [cx + Math.cos(a0 + 0.15) * (R * 0.55 + offset * 0.3),
                      cy + Math.sin(a0 + 0.15) * (R * 0.55 + offset * 0.3)];
        return (
          <path key={i}
            d={`M ${cx} ${cy} L ${tip[0].toFixed(2)} ${tip[1].toFixed(2)} Q ${ctrl[0].toFixed(2)} ${ctrl[1].toFixed(2)} ${base[0].toFixed(2)} ${base[1].toFixed(2)} Z`}
            fill="none" stroke={stroke} strokeWidth="0.8" opacity={0.35 + open * 0.45}/>
        );
      })}
      {/* inner pupil */}
      <circle cx={cx} cy={cy} r={4 + (1 - open) * 10} fill={stroke} opacity={0.15 + (1 - open) * 0.6}/>
    </svg>
  );
}

// ─────────────────────────────────────────────
// P2) Stylus Mark — a single hand-drawn curve traces, fades, retraces
// ─────────────────────────────────────────────
function CursorLogo({ size = 200, speed = 1, stroke = PRODUCT_STROKE }) {
  const t = useClockP(speed);
  const cx = size / 2, cy = size / 2;
  // Parametric curve — a signature-like spiral swoosh
  const curve = (u) => {
    const a = u * Math.PI * 3.2;
    const r = 20 + u * 42;
    return [
      cx + Math.cos(a) * r - 8,
      cy + Math.sin(a) * r * 0.7 + Math.sin(u * Math.PI) * 8,
    ];
  };
  // Cycle: 0..1 draws, 1..1.3 holds, 1.3..1.6 fades, repeat
  const period = (t * 0.35) % 1.6;
  let drawn = 1, fade = 1;
  if (period < 1) drawn = period;
  else if (period < 1.3) { drawn = 1; fade = 1; }
  else { drawn = 1; fade = 1 - (period - 1.3) / 0.3; }
  // Build path up to "drawn"
  const samples = 80;
  const pts = [];
  for (let i = 0; i <= samples; i++) {
    const u = (i / samples) * drawn;
    pts.push(curve(u));
  }
  const d = pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${p[0].toFixed(2)} ${p[1].toFixed(2)}`).join(' ');
  const head = curve(drawn);
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      <path d={d} fill="none" stroke={stroke} strokeWidth="1.6"
        strokeLinecap="round" strokeLinejoin="round" opacity={fade}/>
      {/* tip nib */}
      <circle cx={head[0]} cy={head[1]} r="2.2" fill={stroke} opacity={fade}/>
      <circle cx={head[0]} cy={head[1]} r="5" fill="none" stroke={stroke}
        strokeWidth="0.6" opacity={fade * 0.4}/>
    </svg>
  );
}

// ─────────────────────────────────────────────
// P3) Bloom — a shape unfolds: seed → petals → seed
// ─────────────────────────────────────────────
function PromptLogo({ size = 200, speed = 1, stroke = PRODUCT_STROKE }) {
  const t = useClockP(speed);
  const cx = size / 2, cy = size / 2;
  const petals = 6;
  const phase = (Math.sin(t * 0.45) + 1) / 2; // 0 seed .. 1 full bloom
  const R = 18 + phase * 48;
  const twist = t * 8;
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {/* core */}
      <circle cx={cx} cy={cy} r={4 + (1 - phase) * 8} fill="none" stroke={stroke} strokeWidth="1"/>
      <circle cx={cx} cy={cy} r={1.6} fill={stroke}/>
      {/* petals: teardrops */}
      {Array.from({length: petals}, (_, i) => {
        const a = (i / petals) * Math.PI * 2 + (twist * Math.PI / 180);
        const tip = [cx + Math.cos(a) * R, cy + Math.sin(a) * R];
        // perpendicular for control points
        const perp = a + Math.PI / 2;
        const wide = R * 0.3 * phase;
        const c1 = [cx + Math.cos(a) * R * 0.2 + Math.cos(perp) * wide,
                    cy + Math.sin(a) * R * 0.2 + Math.sin(perp) * wide];
        const c2 = [cx + Math.cos(a) * R * 0.2 - Math.cos(perp) * wide,
                    cy + Math.sin(a) * R * 0.2 - Math.sin(perp) * wide];
        return (
          <path key={i}
            d={`M ${cx} ${cy} Q ${c1[0].toFixed(2)} ${c1[1].toFixed(2)} ${tip[0].toFixed(2)} ${tip[1].toFixed(2)} Q ${c2[0].toFixed(2)} ${c2[1].toFixed(2)} ${cx} ${cy} Z`}
            fill="none" stroke={stroke} strokeWidth="0.9" opacity={0.3 + phase * 0.6}/>
        );
      })}
    </svg>
  );
}

// ─────────────────────────────────────────────
// P4) Cube Fold — an isometric cube unfolds into 6 faces, refolds
// ─────────────────────────────────────────────
function ModulesLogo({ size = 200, speed = 1, stroke = PRODUCT_STROKE }) {
  const t = useClockP(speed);
  const cx = size / 2, cy = size / 2;
  // Single cube with rotating visible faces — simulate with 3 parallelograms
  const phase = (Math.sin(t * 0.55) + 1) / 2; // 0 cube .. 1 expanded
  const s = 34;  // side half
  // isometric vectors
  const ix = [Math.cos(Math.PI / 6), Math.sin(Math.PI / 6)];
  const iy = [-Math.cos(Math.PI / 6), Math.sin(Math.PI / 6)];
  const iz = [0, -1];
  const V = (x, y, z) => [
    cx + x * ix[0] * s + y * iy[0] * s + z * iz[0] * s,
    cy + x * ix[1] * s + y * iy[1] * s + z * iz[1] * s,
  ];
  const exp = phase * 0.9; // explosion amount
  const face = (verts, offset) => {
    const off = [offset[0] * exp * s * 0.9, offset[1] * exp * s * 0.9];
    const d = verts.map((v, i) =>
      `${i === 0 ? 'M' : 'L'}${(v[0] + off[0]).toFixed(2)} ${(v[1] + off[1]).toFixed(2)}`
    ).join(' ') + ' Z';
    return d;
  };
  // top face
  const top = [V(0,0,1), V(1,0,1), V(1,1,1), V(0,1,1)];
  // right face
  const right = [V(1,0,0), V(1,0,1), V(1,1,1), V(1,1,0)];
  // left face
  const left = [V(0,1,0), V(0,1,1), V(1,1,1), V(1,1,0)];
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {/* shadow cube frame (always visible, subtle) */}
      <path d={face(top, iz)} fill="none" stroke={stroke} strokeWidth="0.9" opacity={0.35 + (1-phase)*0.5}/>
      <path d={face(right, ix)} fill="none" stroke={stroke} strokeWidth="0.9" opacity={0.35 + (1-phase)*0.5}/>
      <path d={face(left, iy)} fill="none" stroke={stroke} strokeWidth="0.9" opacity={0.35 + (1-phase)*0.5}/>
      {/* dashed guidelines when expanded */}
      <g opacity={phase * 0.5}>
        {[[V(0,0,1), [0,0]], [V(1,0,0), [0,0]], [V(0,1,0), [0,0]]].map(([p], i) => (
          <line key={i} x1={cx} y1={cy} x2={p[0]} y2={p[1]}
            stroke={stroke} strokeWidth="0.5" strokeDasharray="2 3"/>
        ))}
      </g>
      {/* center dot */}
      <circle cx={cx} cy={cy} r="1.8" fill={stroke}/>
    </svg>
  );
}

// ─────────────────────────────────────────────
// P5) Lathe — a 2D profile curve revolved, rotating 3D form (wireframe)
// ─────────────────────────────────────────────
function WaveformLogo({ size = 200, speed = 1, stroke = PRODUCT_STROKE }) {
  const t = useClockP(speed);
  const cx = size / 2, cy = size / 2;
  // Profile: vase-like silhouette (y: height, returns radius)
  const profile = (y) => {
    // y in [-1, 1]
    return 0.3 + 0.25 * Math.sin(y * Math.PI * 1.2) + 0.15 * Math.cos(y * Math.PI * 2.3);
  };
  const rings = 12;
  const segs = 24;
  const rotY = t * 0.6;
  const H = 62;
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {/* rings (horizontal ellipses at different heights) */}
      {Array.from({length: rings}, (_, i) => {
        const yn = (i / (rings - 1)) * 2 - 1;
        const r = profile(yn) * 70;
        const yp = cy + yn * H;
        // perspective: ellipse ry is small, rx is r
        const ry = r * 0.22;
        return <ellipse key={`r${i}`} cx={cx} cy={yp} rx={r} ry={ry}
          fill="none" stroke={stroke} strokeWidth="0.7" opacity="0.35"/>;
      })}
      {/* vertical meridians — rotated around Y */}
      {Array.from({length: segs}, (_, k) => {
        const ang = (k / segs) * Math.PI * 2 + rotY;
        const pts = [];
        for (let i = 0; i < rings; i++) {
          const yn = (i / (rings - 1)) * 2 - 1;
          const r = profile(yn) * 70;
          const yp = cy + yn * H;
          const xp = cx + Math.cos(ang) * r;
          // z used for opacity only
          const z = Math.sin(ang);
          pts.push({ x: xp, y: yp, z });
        }
        const avgZ = pts.reduce((a, p) => a + p.z, 0) / pts.length;
        const op = avgZ > 0 ? 0.75 : 0.18;
        const d = pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${p.x.toFixed(2)} ${p.y.toFixed(2)}`).join(' ');
        return <path key={`m${k}`} d={d} fill="none" stroke={stroke} strokeWidth="0.7" opacity={op}/>;
      })}
    </svg>
  );
}

// ─────────────────────────────────────────────
// P6) Morph Blob — a squircle that breathes between primitives
// ─────────────────────────────────────────────
function ComposerLogo({ size = 200, speed = 1, stroke = PRODUCT_STROKE }) {
  const t = useClockP(speed);
  const cx = size / 2, cy = size / 2;
  // Superellipse with time-varying exponent n: n=2 circle, n→∞ square, n=1 diamond
  const safeT = Math.max(0, t || 0);
  const phase = (Math.sin(safeT * 0.4) + 1) / 2;
  // Interpolate between diamond (n=1), circle (n=2), square (n=6)
  const cycle = (safeT * 0.25) % 3;
  let n;
  if (cycle < 1) n = 1 + cycle * 1;      // 1 → 2
  else if (cycle < 2) n = 2 + (cycle - 1) * 4; // 2 → 6
  else n = 6 - (cycle - 2) * 5;          // 6 → 1
  const R = 64;
  const samples = 120;
  const pts = [];
  for (let i = 0; i <= samples; i++) {
    const a = (i / samples) * Math.PI * 2;
    const ca = Math.cos(a), sa = Math.sin(a);
    const denom = Math.pow(Math.abs(ca), n) + Math.pow(Math.abs(sa), n);
    const r = R * Math.pow(1 / denom, 1 / n);
    pts.push([cx + ca * r, cy + sa * r]);
  }
  const d = pts.map((p, i) => `${i === 0 ? 'M' : 'L'}${p[0].toFixed(2)} ${p[1].toFixed(2)}`).join(' ') + ' Z';
  // Inner nested shapes for depth
  const rings = [0.72, 0.48, 0.24];
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {rings.map((scale, idx) => {
        const d2 = pts.map((p, i) => {
          const x = cx + (p[0] - cx) * scale;
          const y = cy + (p[1] - cy) * scale;
          return `${i === 0 ? 'M' : 'L'}${x.toFixed(2)} ${y.toFixed(2)}`;
        }).join(' ') + ' Z';
        return <path key={idx} d={d2} fill="none" stroke={stroke} strokeWidth="0.7" opacity={0.25 + idx * 0.1}/>;
      })}
      <path d={d} fill="none" stroke={stroke} strokeWidth="1.1"/>
      <circle cx={cx} cy={cy} r="1.8" fill={stroke}/>
    </svg>
  );
}

Object.assign(window, {
  CardsLogo, CursorLogo, PromptLogo, ModulesLogo, WaveformLogo, ComposerLogo,
});
// AI Infrastructure — non-circular variants
// Shared DNA: thin 1px lines, slow loop, centered, minimal
const INFRA_STROKE = '#1a1a1a';

function useClockI(speed = 1) {
  const [t, setT] = React.useState(0);
  React.useEffect(() => {
    let raf, start = performance.now();
    const tick = (now) => { setT(((now - start) / 1000) * speed); raf = requestAnimationFrame(tick); };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [speed]);
  return t;
}

// ─────────────────────────────────────────────
// A) Isometric Stack — cubes stacking/unstacking (foundation, layers)
// ─────────────────────────────────────────────
function PipelineLogo({ size = 200, speed = 1, stroke = INFRA_STROKE }) {
  const t = useClockI(speed);
  const cx = size / 2, cy = size / 2 + 20;
  const s = 22; // half cube size
  const ix = [Math.cos(Math.PI / 6), Math.sin(Math.PI / 6)];
  const iy = [-Math.cos(Math.PI / 6), Math.sin(Math.PI / 6)];
  const iz = [0, -1];
  const P = (x, y, z) => [
    cx + x * ix[0] * s + y * iy[0] * s + z * iz[0] * s,
    cy + x * ix[1] * s + y * iy[1] * s + z * iz[1] * s,
  ];
  // Cubes at positions [x,y,z]
  const cubes = [
    [0,0,0],[1,0,0],[0,1,0],[1,1,0],
    [0,0,1],[1,0,1],[0,1,1],
    [0,0,2],
  ];
  // Breathing: cubes rise then settle, staggered — stronger lift + slight XY spread from cluster center
  const breathe = (i) => {
    const phase = (t * 0.4 + i * 0.08) % 2;
    if (phase < 1) return Math.sin(phase * Math.PI) * 0.52;
    return 0;
  };
  const drawCube = (x, y, z, rise) => {
    const spread = rise * 0.48;
    const xAdj = x + (x - 1) * spread;
    const yAdj = y + (y - 1) * spread;
    const zz = z + rise;
    const v = [
      P(xAdj, yAdj, zz+1), P(xAdj + 1, yAdj, zz+1), P(xAdj + 1, yAdj + 1, zz+1), P(xAdj, yAdj + 1, zz+1), // top
      P(xAdj, yAdj, zz),   P(xAdj + 1, yAdj, zz),   P(xAdj + 1, yAdj + 1, zz),   P(xAdj, yAdj + 1, zz),   // bot
    ];
    const faces = [
      [0,1,2,3], // top
      [1,5,6,2], // right
      [3,2,6,7], // front
    ];
    return faces.map((f, k) => {
      const d = f.map((idx, i) => `${i===0?'M':'L'}${v[idx][0].toFixed(1)} ${v[idx][1].toFixed(1)}`).join(' ') + ' Z';
      return <path key={k} d={d} fill="none" stroke={stroke} strokeWidth="0.4"/>;
    });
  };
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {/* ground plane */}
      <path d={`M ${P(-0.5, -0.5, 0)[0]} ${P(-0.5, -0.5, 0)[1]} L ${P(2.5, -0.5, 0)[0]} ${P(2.5, -0.5, 0)[1]} L ${P(2.5, 2.5, 0)[0]} ${P(2.5, 2.5, 0)[1]} L ${P(-0.5, 2.5, 0)[0]} ${P(-0.5, 2.5, 0)[1]} Z`}
        fill="none" stroke={stroke} strokeWidth="0.75" opacity="0.25" strokeDasharray="2 3"/>
      {cubes.map(([x, y, z], i) => (
        <g key={i}>{drawCube(x, y, z, breathe(i))}</g>
      ))}
    </svg>
  );
}

// ─────────────────────────────────────────────
// B) Bracket Scaffold — square bracket with nested sub-structure,
//    inner module slides in/out like a drawer
// ─────────────────────────────────────────────
function StackLogo({ size = 200, speed = 1, stroke = INFRA_STROKE }) {
  const t = useClockI(speed);
  const cx = size / 2, cy = size / 2;
  const W = 130, H = 100;
  const slide = (Math.sin(t * 0.5) + 1) / 2; // 0..1
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {/* outer frame — corner brackets only */}
      {(() => {
        const L = 18;
        const x1 = cx - W/2, y1 = cy - H/2, x2 = cx + W/2, y2 = cy + H/2;
        return (
          <g stroke={stroke} strokeWidth="1" fill="none" strokeLinecap="round">
            <polyline points={`${x1+L},${y1} ${x1},${y1} ${x1},${y1+L}`}/>
            <polyline points={`${x2-L},${y1} ${x2},${y1} ${x2},${y1+L}`}/>
            <polyline points={`${x1},${y2-L} ${x1},${y2} ${x1+L},${y2}`}/>
            <polyline points={`${x2},${y2-L} ${x2},${y2} ${x2-L},${y2}`}/>
          </g>
        );
      })()}
      {/* inner modules — 3 stacked, sliding */}
      {[0, 1, 2].map(i => {
        const rowY = cy - 24 + i * 24;
        const offset = (slide - 0.5) * 30 * (i === 1 ? 1 : (i === 0 ? -0.5 : 0.3));
        return (
          <g key={i}>
            <rect x={cx - 44 + offset} y={rowY - 8} width="88" height="16"
              fill="none" stroke={stroke} strokeWidth="0.9" rx="1"/>
            {/* internal dots */}
            {[-32, -16, 0, 16, 32].map((dx, k) => (
              <circle key={k} cx={cx + dx + offset} cy={rowY} r="1"
                fill={stroke} opacity="0.5"/>
            ))}
          </g>
        );
      })}
      {/* tick marks on sides */}
      {[0,1,2,3,4].map(i => {
        const y = cy - 32 + i * 16;
        return (
          <g key={`tk${i}`}>
            <line x1={cx - W/2 - 6} y1={y} x2={cx - W/2 - 2} y2={y} stroke={stroke} strokeWidth="0.7" opacity="0.5"/>
            <line x1={cx + W/2 + 2} y1={y} x2={cx + W/2 + 6} y2={y} stroke={stroke} strokeWidth="0.7" opacity="0.5"/>
          </g>
        );
      })}
    </svg>
  );
}

// ─────────────────────────────────────────────
// C) Topology Tree — a branching node tree, with a signal traveling
//    down root→leaves then back, like compute routing through a cluster
// ─────────────────────────────────────────────
function HexLogo({ size = 200, speed = 1, stroke = INFRA_STROKE }) {
  const t = useClockI(speed);
  const cx = size / 2;
  // Build a 3-level binary-ish tree, centered, growing downward
  const nodes = [
    { id: 0, x: cx, y: 44, parent: null },
    { id: 1, x: cx - 44, y: 92, parent: 0 },
    { id: 2, x: cx + 44, y: 92, parent: 0 },
    { id: 3, x: cx - 66, y: 146, parent: 1 },
    { id: 4, x: cx - 22, y: 146, parent: 1 },
    { id: 5, x: cx + 22, y: 146, parent: 2 },
    { id: 6, x: cx + 66, y: 146, parent: 2 },
  ];
  // Signal: travels root → random leaf → root, loop
  const leaves = [3, 4, 5, 6];
  const cycleDur = 1.4;
  const cycle = (t * 0.6) % (leaves.length * cycleDur);
  const leafIdx = Math.floor(cycle / cycleDur);
  const targetLeaf = leaves[leafIdx];
  const phase = (cycle % cycleDur) / cycleDur; // 0..1 down, back doesn't matter
  // Build path from 0 to target leaf
  const pathFromRoot = (target) => {
    const chain = [];
    let n = target;
    while (n !== null) { chain.unshift(n); n = nodes[n].parent; }
    return chain;
  };
  const chain = pathFromRoot(targetLeaf);
  // Position along path at phase (0..1 goes to leaf, then back)
  const goPhase = phase < 0.5 ? phase * 2 : (1 - phase) * 2;
  const segIdx = Math.min(Math.floor(goPhase * (chain.length - 1)), chain.length - 2);
  const segMix = goPhase * (chain.length - 1) - segIdx;
  const a = nodes[chain[segIdx]], b = nodes[chain[segIdx + 1]];
  const sig = {
    x: a.x + (b.x - a.x) * segMix,
    y: a.y + (b.y - a.y) * segMix,
  };
  const activeSet = new Set(chain.slice(0, segIdx + 1 + (segMix > 0.5 ? 1 : 0)));
  return (
    <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
      {/* edges */}
      {nodes.filter(n => n.parent !== null).map(n => {
        const p = nodes[n.parent];
        const active = activeSet.has(n.id) && activeSet.has(p.id);
        return (
          <line key={n.id} x1={p.x} y1={p.y} x2={n.x} y2={n.y}
            stroke={stroke} strokeWidth={active ? 1 : 0.7}
            opacity={active ? 0.9 : 0.35}/>
        );
      })}
      {/* nodes */}
      {nodes.map(n => {
        const isLeaf = !nodes.some(m => m.parent === n.id);
        const active = activeSet.has(n.id);
        return (
          <g key={n.id}>
            {isLeaf ? (
              <rect x={n.x - 5} y={n.y - 5} width="10" height="10"
                fill={active ? stroke : 'none'} fillOpacity={active ? 0.15 : 0}
                stroke={stroke} strokeWidth={active ? 1.1 : 0.9}/>
            ) : (
              <circle cx={n.x} cy={n.y} r={n.id === 0 ? 6 : 5}
                fill={active ? stroke : 'none'} fillOpacity={active ? 0.15 : 0}
                stroke={stroke} strokeWidth={active ? 1.1 : 0.9}/>
            )}
          </g>
        );
      })}
      {/* traveling signal */}
      <circle cx={sig.x} cy={sig.y} r="2.5" fill={stroke}/>
      <circle cx={sig.x} cy={sig.y} r="5" fill="none" stroke={stroke}
        strokeWidth="0.6" opacity="0.5"/>
      {/* base rail under leaves */}
      <line x1={cx - 86} y1={166} x2={cx + 86} y2={166}
        stroke={stroke} strokeWidth="0.6" opacity="0.3" strokeDasharray="2 3"/>
    </svg>
  );
}

const RackLogo = PipelineLogo;
const GraphLogo = StackLogo;
const ThroughputLogo = HexLogo;

Object.assign(window, {
  PipelineLogo, StackLogo, HexLogo, RackLogo, GraphLogo, ThroughputLogo,
});
// Append to bundle after logos.jsx + products.jsx + infra.jsx (see ai-exploring-bundle.jsx)
// Mount Claude design trio (Orbit · Aperture · Isometric stack) into AI page cards
(function mountAiExploringIcons() {
  const stroke = "rgba(255, 255, 255, 0.88)";
  const reduce =
    typeof window.matchMedia === "function" &&
    window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  const speed = reduce ? 0 : 0.42;
  /* Logo geometry is authored for ~200×200; smaller viewBox clips strokes. Scale via CSS instead. */
  const size = 200;
  const pairs = [
    ["ai-exploring-icon-experiments", typeof OrbitLogo !== "undefined" ? OrbitLogo : null],
    ["ai-exploring-icon-products", typeof CardsLogo !== "undefined" ? CardsLogo : null],
    ["ai-exploring-icon-infra", typeof PipelineLogo !== "undefined" ? PipelineLogo : null],
  ];
  pairs.forEach(([id, Comp]) => {
    const el = document.getElementById(id);
    if (!el || !Comp) return;
    const root = ReactDOM.createRoot(el);
    root.render(<Comp size={size} speed={speed} stroke={stroke} />);
  });
})();
