// ============================================================
// SHARED UI — icons, primitives, chart bg
// ============================================================

const Icon = ({ name, size = 18, stroke = 2, ...rest }) => {
  const paths = {
    arrow: <><line x1="5" y1="12" x2="19" y2="12" /><polyline points="13 5 19 12 13 19" /></>,
    arrowUR: <><line x1="7" y1="17" x2="17" y2="7" /><polyline points="8 7 17 7 17 16" /></>,
    arrowDown: <><line x1="12" y1="5" x2="12" y2="19" /><polyline points="6 13 12 19 18 13" /></>,
    check: <><polyline points="20 6 9 17 4 12" /></>,
    x: <><line x1="18" y1="6" x2="6" y2="18" /><line x1="6" y1="6" x2="18" y2="18" /></>,
    plus: <><line x1="12" y1="5" x2="12" y2="19" /><line x1="5" y1="12" x2="19" y2="12" /></>,
    chevDown: <><polyline points="6 9 12 15 18 9" /></>,
    chevRight: <><polyline points="9 6 15 12 9 18" /></>,
    chevLeft: <><polyline points="15 6 9 12 15 18" /></>,
    search: <><circle cx="11" cy="11" r="7" /><line x1="20" y1="20" x2="16.65" y2="16.65" /></>,
    menu: <><line x1="4" y1="7" x2="20" y2="7" /><line x1="4" y1="13" x2="20" y2="13" /><line x1="4" y1="19" x2="20" y2="19" /></>,
    play: <><polygon points="6 4 20 12 6 20 6 4" fill="currentColor" stroke="none" /></>,
    pause: <><rect x="6" y="4" width="4" height="16" fill="currentColor" stroke="none" /><rect x="14" y="4" width="4" height="16" fill="currentColor" stroke="none" /></>,
    lock: <><rect x="4" y="11" width="16" height="10" rx="2" /><path d="M7 11V8a5 5 0 0 1 10 0v3" /></>,
    unlock: <><rect x="4" y="11" width="16" height="10" rx="2" /><path d="M7 11V8a5 5 0 0 1 9.6-2" /></>,
    shield: <><path d="M12 3 4 6v6c0 5 4 8 8 9 4-1 8-4 8-9V6l-8-3z" /></>,
    chart: <><line x1="4" y1="20" x2="20" y2="20" /><polyline points="4 16 9 11 13 14 20 6" /></>,
    candle: <><line x1="7" y1="3" x2="7" y2="21" /><rect x="5" y="7" width="4" height="9" /><line x1="17" y1="3" x2="17" y2="21" /><rect x="15" y="10" width="4" height="7" /></>,
    target: <><circle cx="12" cy="12" r="9" /><circle cx="12" cy="12" r="5" /><circle cx="12" cy="12" r="1.4" fill="currentColor" /></>,
    brain: <><path d="M9 4a3 3 0 0 0-3 3v.5a3 3 0 0 0-2 2.83V12a3 3 0 0 0 2 2.83V17a3 3 0 0 0 3 3" /><path d="M15 4a3 3 0 0 1 3 3v.5a3 3 0 0 1 2 2.83V12a3 3 0 0 1-2 2.83V17a3 3 0 0 1-3 3" /><line x1="12" y1="4" x2="12" y2="20" /></>,
    book: <><path d="M4 4h11a4 4 0 0 1 4 4v12H8a4 4 0 0 1-4-4V4z" /><line x1="4" y1="16" x2="19" y2="16" /></>,
    bolt: <><polygon points="13 2 4 14 11 14 10 22 20 9 13 9 13 2" fill="currentColor" stroke="none" /></>,
    star: <><polygon points="12 2 15 9 22 10 17 15 18 22 12 19 6 22 7 15 2 10 9 9 12 2" fill="currentColor" stroke="none" /></>,
    users: <><circle cx="9" cy="8" r="3.5" /><path d="M3 20c1-3.5 3.5-5 6-5s5 1.5 6 5" /><circle cx="17" cy="9" r="2.5" /><path d="M15 14.5c2 0 4 1 5 4" /></>,
    user: <><circle cx="12" cy="8" r="4" /><path d="M4 21c1-4 4-6 8-6s7 2 8 6" /></>,
    discord: <><path d="M19 5a16 16 0 0 0-4-1l-.2.4A11 11 0 0 1 18 6c-2-1-4-1.5-6-1.5S8 5 6 6a11 11 0 0 1 3.2-1.6L9 4a16 16 0 0 0-4 1c-2 3-2.5 6-2.5 9 1.5 1.5 3 2 4.5 2l1-1.5c-1-.2-1.8-.6-2.5-1.2.2.2 4 1.7 6.5 1.7s6.3-1.5 6.5-1.7c-.7.6-1.5 1-2.5 1.2l1 1.5c1.5 0 3-.5 4.5-2 0-3-.5-6-2.5-9zM9 13c-.8 0-1.5-.8-1.5-1.7s.7-1.7 1.5-1.7 1.5.8 1.5 1.7S9.8 13 9 13zm6 0c-.8 0-1.5-.8-1.5-1.7s.7-1.7 1.5-1.7 1.5.8 1.5 1.7S15.8 13 15 13z" fill="currentColor" stroke="none" /></>,
    youtube: <><rect x="2" y="6" width="20" height="12" rx="3" /><polygon points="10 9 16 12 10 15" fill="currentColor" stroke="none" /></>,
    whatsapp: <><path d="M3 21l1.4-4.4a8 8 0 1 1 3 3L3 21z" /><path d="M9 10c.5 1.5 1.5 2.5 3 3l1.2-.8 2 .8c0 1.4-1 2-2.5 1.5C10.5 14 9 12.5 8 10.5 7.5 9 8 8 9.4 8L10 10z" fill="currentColor" stroke="none" /></>,
    phone: <><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6A19.79 19.79 0 0 1 2.12 4.18 2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7a2 2 0 0 1 1.72 2.03z" /></>,
    mail: <><rect x="3" y="5" width="18" height="14" rx="2" /><polyline points="3 7 12 13 21 7" /></>,
    calendar: <><rect x="3" y="5" width="18" height="16" rx="2" /><line x1="3" y1="10" x2="21" y2="10" /><line x1="8" y1="3" x2="8" y2="7" /><line x1="16" y1="3" x2="16" y2="7" /></>,
    clock: <><circle cx="12" cy="12" r="9" /><polyline points="12 7 12 12 16 14" /></>,
    download: <><path d="M12 3v12" /><polyline points="7 10 12 15 17 10" /><line x1="4" y1="20" x2="20" y2="20" /></>,
    file: <><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z" /><polyline points="14 3 14 9 20 9" /></>,
    video: <><rect x="3" y="6" width="14" height="12" rx="2" /><polygon points="17 10 22 7 22 17 17 14" fill="currentColor" stroke="none" /></>,
    settings: <><circle cx="12" cy="12" r="3" /><path d="M19.4 15a1.7 1.7 0 0 0 .4 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.4 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1-1.5 1.7 1.7 0 0 0-1.8.4l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .4-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1 1.7 1.7 0 0 0-.4-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.4h.1a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.4l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.4 1.8v.1a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z" /></>,
    layout: <><rect x="3" y="3" width="18" height="18" rx="2" /><line x1="3" y1="9" x2="21" y2="9" /><line x1="9" y1="21" x2="9" y2="9" /></>,
    flame: <><path d="M12 22c5 0 7-3 7-6.5 0-2.5-1.5-4-3-5 0 2-2 3-2 3s-1-2 0-5c-3 1-7 4.5-7 9 0 3 2 4.5 5 4.5z" fill="currentColor" stroke="none" /></>,
    coin: <><circle cx="12" cy="12" r="9" /><path d="M9 9h5a2 2 0 0 1 0 4H9m0 0h6" /><line x1="12" y1="6" x2="12" y2="18" /></>,
    diamond: <><polygon points="6 3 18 3 22 9 12 22 2 9" /><line x1="6" y1="3" x2="10" y2="9" /><line x1="18" y1="3" x2="14" y2="9" /><line x1="2" y1="9" x2="22" y2="9" /></>,
    crown: <><path d="M3 7l4 4 5-6 5 6 4-4-2 11H5L3 7z" /></>,
    eye: <><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z" /><circle cx="12" cy="12" r="3" /></>,
    eyeOff: <><path d="M2 12s4-7 10-7c2 0 4 .5 5.5 1.5M22 12s-4 7-10 7c-2 0-4-.5-5.5-1.5" /><line x1="4" y1="4" x2="20" y2="20" /></>,
    heart: <><path d="M12 21s-7-4.5-9-9c-1.5-4 2-7 5-7 1.5 0 3 .8 4 2 1-1.2 2.5-2 4-2 3 0 6.5 3 5 7-2 4.5-9 9-9 9z" fill="currentColor" stroke="none" /></>,
    globe: <><circle cx="12" cy="12" r="9" /><line x1="3" y1="12" x2="21" y2="12" /><path d="M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18" /></>,
    refresh: <><polyline points="21 4 21 10 15 10" /><path d="M20 14a8 8 0 1 1-2.5-9.2L21 8" /></>,
    sparkle: <><path d="M12 3l1.5 5 5 1.5-5 1.5L12 16l-1.5-5-5-1.5 5-1.5L12 3z" fill="currentColor" stroke="none" /><path d="M19 14l.7 2 2 .7-2 .7-.7 2-.7-2-2-.7 2-.7L19 14z" fill="currentColor" stroke="none" /></>,
    arrowUp: <><line x1="12" y1="19" x2="12" y2="5" /><polyline points="6 11 12 5 18 11" /></>,
    info: <><circle cx="12" cy="12" r="9" /><line x1="12" y1="11" x2="12" y2="16" /><circle cx="12" cy="8" r="0.5" fill="currentColor" /></>,
    warn: <><path d="M12 3 2 20h20L12 3z" /><line x1="12" y1="10" x2="12" y2="14" /><circle cx="12" cy="17" r="0.5" fill="currentColor" /></>
  };
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round" {...rest} style={{ stroke: "rgb(255, 255, 255)" }}>
      {paths[name] || null}
    </svg>);

};

// ============================================================
// ICON CHIP — premium animated electric chip
// ============================================================
const IconChip = ({ icon, color = 'acid', size = 'md', className = '' }) =>
<div className={`icon-chip ${color} ${size === 'lg' ? 'lg' : ''} ${className}`}>
    <Icon name={icon} size={size === 'lg' ? 28 : 24} stroke={1.8} />
  </div>;


// ============================================================
// BUTTONS
// ============================================================
const Button = ({ children, variant = 'acid', size = 'md', icon = 'arrow', iconOnly = false, onClick, href, type, className = '', ...rest }) => {
  const btnRef = React.useRef(null);
  const lastAddedRef = React.useRef(0);
  const [isListening, setIsListening] = React.useState(false);
  const [circles, setCircles] = React.useState([]);

  const createCircle = (x, y) => {
    const w = (btnRef.current && btnRef.current.offsetWidth) || 0;
    const xPos = w ? x / w : 0;
    const color = `linear-gradient(to right, var(--circle-start) ${xPos * 100}%, var(--circle-end) ${xPos * 100}%)`;
    setCircles(prev => [...prev, { id: Date.now() + Math.random(), x, y, color, fadeState: null }]);
  };

  const handlePointerMove = (e) => {
    if (!isListening) return;
    const now = Date.now();
    if (now - lastAddedRef.current > 100) {
      lastAddedRef.current = now;
      const r = e.currentTarget.getBoundingClientRect();
      createCircle(e.clientX - r.left, e.clientY - r.top);
    }
  };

  React.useEffect(() => {
    const pending = circles.filter(c => !c.fadeState);
    if (pending.length === 0) return;
    const timers = [];
    pending.forEach((c) => {
      timers.push(setTimeout(() => setCircles(p => p.map(x => x.id === c.id ? { ...x, fadeState: 'in' } : x)), 0));
      timers.push(setTimeout(() => setCircles(p => p.map(x => x.id === c.id ? { ...x, fadeState: 'out' } : x)), 1000));
      timers.push(setTimeout(() => setCircles(p => p.filter(x => x.id !== c.id)), 2200));
    });
    return () => timers.forEach(clearTimeout);
  }, [circles]);

  const cls = `btn btn-glass btn-${variant} ${size === 'sm' ? 'btn-sm' : ''} ${size === 'lg' ? 'btn-lg' : ''} ${className}`;
  const inner = (
    <>
      <span className="btn-content">
        {children}
        {icon &&
          <span className="btn-arrow">
            <Icon name={icon} size={12} stroke={2.5} />
          </span>
        }
      </span>
      {circles.map(({ id, x, y, color, fadeState }) =>
        <span
          key={id}
          className={`btn-spark ${fadeState === 'in' ? 'btn-spark-in' : ''} ${fadeState === 'out' ? 'btn-spark-out' : ''}`}
          style={{ left: x, top: y, background: color }} />
      )}
    </>
  );

  const shared = {
    ref: btnRef,
    className: cls,
    onClick,
    onPointerMove: handlePointerMove,
    onPointerEnter: () => setIsListening(true),
    onPointerLeave: () => { setIsListening(false); },
  };

  if (href) {
    return <a {...shared} href={href} {...rest}>{inner}</a>;
  }
  return <button {...shared} type={type || 'button'} {...rest}>{inner}</button>;
};

// ============================================================
// BACKGROUND — candlestick chart
// ============================================================
const CandleChart = () => null;
const _CandleChartArchived = ({ density = 'normal', opacity = 0.42 }) => {
  // Deterministic candles trending upward, diagonal bottom-left → top-right
  const candles = React.useMemo(() => {
    const N = density === 'dense' ? 70 : density === 'sparse' ? 30 : 48;
    const arr = [];
    let price = 80;
    for (let i = 0; i < N; i++) {
      const drift = i / N * 55;
      const noise = (Math.sin(i * 1.7) + Math.cos(i * 0.9) + Math.sin(i * 0.4)) * 4;
      const open = price + noise * 0.4;
      const close = open + Math.sin(i * 2.1) * 4 + (Math.random() > 0.5 ? 1.2 : -1.2);
      const high = Math.max(open, close) + 1 + Math.abs(Math.sin(i)) * 2;
      const low = Math.min(open, close) - 1 - Math.abs(Math.cos(i * 1.3)) * 2;
      arr.push({ x: 30 + i / (N - 1) * 1140, open, close, high, low, up: close > open });
      price = close + drift / N;
    }
    // Invert Y for visual; use y = 360 - val * 2
    return arr.map((c) => ({
      x: c.x,
      up: c.up,
      bodyTop: 380 - Math.max(c.open, c.close) * 2.4,
      bodyBottom: 380 - Math.min(c.open, c.close) * 2.4,
      wickTop: 380 - c.high * 2.4,
      wickBottom: 380 - c.low * 2.4
    }));
  }, [density]);

  const linePath = candles.map((c, i) =>
  `${i === 0 ? 'M' : 'L'} ${c.x} ${(c.bodyTop + c.bodyBottom) / 2}`
  ).join(' ');

  return (
    <svg className="bg-chart" viewBox="0 0 1200 480" preserveAspectRatio="xMidYMid slice" style={{ opacity }}>
      <defs>
        <linearGradient id="grid-fade" x1="0" x2="1" y1="0" y2="0">
          <stop offset="0" stopColor="#1a1a1a" stopOpacity="0" />
          <stop offset="0.5" stopColor="#1a1a1a" stopOpacity="1" />
          <stop offset="1" stopColor="#1a1a1a" stopOpacity="0" />
        </linearGradient>
        <linearGradient id="trend-grad" x1="0" x2="1" y1="1" y2="0">
          <stop offset="0" stopColor="#B7FF1A" stopOpacity="0.05" />
          <stop offset="1" stopColor="#B7FF1A" stopOpacity="0.7" />
        </linearGradient>
        <radialGradient id="vignette" cx="0.5" cy="0.5" r="0.7">
          <stop offset="0.5" stopColor="#050505" stopOpacity="0" />
          <stop offset="1" stopColor="#050505" stopOpacity="1" />
        </radialGradient>
        <filter id="glow"><feGaussianBlur stdDeviation="3" /></filter>
      </defs>

      {/* Grid lines */}
      {[60, 120, 180, 240, 300, 360].map((y) =>
      <line key={y} x1="0" x2="1200" y1={y} y2={y} stroke="url(#grid-fade)" strokeWidth="1" opacity="0.5" />
      )}

      {/* Trend area fill */}
      <path
        d={`${linePath} L 1170 480 L 30 480 Z`}
        fill="url(#trend-grad)"
        opacity="0.15" />
      

      {/* Candles */}
      {candles.map((c, i) => {
        const stroke = c.up ? '#B7FF1A' : '#3a3a3a';
        const fill = c.up ? '#B7FF1A' : '#1f1f1f';
        return (
          <g key={i}>
            <line x1={c.x} x2={c.x} y1={c.wickTop} y2={c.wickBottom} stroke={stroke} strokeWidth="1.2" opacity={c.up ? 0.55 : 0.35} />
            <rect
              x={c.x - 4} width={8}
              y={c.bodyTop} height={Math.max(2, c.bodyBottom - c.bodyTop)}
              fill={fill}
              stroke={stroke}
              strokeWidth="1"
              opacity={c.up ? 0.85 : 0.45} />
            
          </g>);

      })}

      {/* Trend line glow */}
      <path d={linePath} fill="none" stroke="#B7FF1A" strokeWidth="2" opacity="0.85" filter="url(#glow)" />
      <path d={linePath} fill="none" stroke="#DCFF7A" strokeWidth="1" opacity="0.9" />

      {/* Vignette */}
      <rect width="1200" height="480" fill="url(#vignette)" />
    </svg>);

};

// ============================================================
// STAT CARD
// ============================================================
const Stat = ({ value, label, suffix = '', color = 'acid', icon }) =>
<div className="card" style={{ padding: '24px 24px 22px' }}>
    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 14 }}>
      {icon && <IconChip icon={icon} color={color} />}
      <div className="tag" style={{ marginLeft: 'auto' }}>
        <span className="dot" style={{ background: `var(--${color})`, boxShadow: `0 0 8px var(--${color}-glow)` }} />
        Live
      </div>
    </div>
    <div style={{ fontSize: 42, fontWeight: 800, letterSpacing: '-0.04em', lineHeight: 1, fontFamily: 'Inter' }}>
      <span style={{ color: `var(--${color})` }}>{value}</span><span style={{ color: 'var(--text-mute)' }}>{suffix}</span>
    </div>
    <div style={{ marginTop: 10, color: 'var(--text-dim)', fontSize: 14 }}>{label}</div>
  </div>;


// ============================================================
// FLOAT CHIP — proof chip you scatter in sections (right/left)
// ============================================================
const FloatChip = ({ brand, color = 'acid', line, val, valExtra, top, bottom, left, right, size = 'md', center = false, delay = 0, duration = 8, rotate, boost = 1 }) => {
  const ref = React.useRef(null);
  const [revealed, setRevealed] = React.useState(false);
  // Per-chip rotation seed (between -15 and 15) derived from delay if not specified
  const seedRotate = rotate !== undefined ? rotate : (((delay * 47) % 30) - 15);

  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;

    // Trigger entry animation when chip enters viewport
    const io = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting) {
        setRevealed(true);
        io.disconnect();
      }
    }, { threshold: 0.1 });
    io.observe(el);

    // Scroll-driven scale (chips grow as they travel through viewport)
    let frame = null;
    const update = () => {
      const rect = el.getBoundingClientRect();
      const vh = window.innerHeight;
      const centerY = rect.top + rect.height / 2;
      // t: 0 when chip-center is at viewport-bottom, 1 when at top
      const t = Math.max(0, Math.min(1, 1 - (centerY / vh)));
      // Scale from 0.82 (entering bottom) to 1.18 (about to exit top)
      const scale = 0.82 + t * 0.36;
      el.style.setProperty('--scroll-scale', scale.toFixed(3));
      frame = null;
    };
    const onScroll = () => {
      if (frame === null) frame = requestAnimationFrame(update);
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    update();

    return () => {
      io.disconnect();
      window.removeEventListener('scroll', onScroll);
      if (frame) cancelAnimationFrame(frame);
    };
  }, []);

  const pos = { top, bottom, left, right };
  Object.keys(pos).forEach((k) => pos[k] === undefined && delete pos[k]);
  const CHIP_COLORS = {
    acid:   { cls: 'hf-acid',   icon: 'rgba(183,255,26,0.18)' },
    cyan:   { cls: 'hf-cyan',   icon: 'rgba(79,231,213,0.18)' },
    blue:   { cls: 'hf-blue',   icon: 'rgba(90,200,255,0.18)' },
    gold:   { cls: 'hf-gold',   icon: 'rgba(255,203,82,0.18)' },
    indigo: { cls: 'hf-indigo', icon: 'rgba(99,102,241,0.20)' },
    rose:   { cls: 'hf-rose',   icon: 'rgba(244,63,94,0.20)'  },
    violet: { cls: 'hf-violet', icon: 'rgba(139,92,246,0.20)' },
    amber:  { cls: 'hf-amber',  icon: 'rgba(245,158,11,0.20)' },
  };
  const cInfo = CHIP_COLORS[color] || CHIP_COLORS.acid;
  const sizeCls = size === 'sm' ? 'scatter-chip-sm' : size === 'lg' ? 'scatter-chip-lg' : '';
  const chipCls = `hero-float scatter-chip ${cInfo.cls} ${sizeCls}`;
  const brandData = brand === 'apex' ?
    { src: 'assets/logo-apex-fit.png', bg: '#000', bd: 'rgba(255,255,255,0.18)' } :
    brand === 'tradeify' ?
    { src: 'assets/logo-tradeify-icon.png', bg: '#000', bd: 'rgba(255,255,255,0.18)' } :
    brand === 'fundednext' ?
    { src: 'assets/logo-fundednext-fit.png', bg: '#000', bd: 'rgba(255,255,255,0.18)' } :
    null;

  const inner = (
    <div className="float-chip-scale">
      <div className={chipCls} style={{ animationDelay: `-${delay}s`, animationDuration: `${duration}s` }}>
        {brandData ?
          <div className={`hf-brand hf-brand-${brand}`} style={{ background: brandData.bg, borderColor: brandData.bd }}>
            <img src={brandData.src} alt={brand} />
          </div> :
          <div className="hf-icon" style={{ background: cInfo.icon, color: `var(--${color})` }}>
            <Icon name="chart" size={size === 'sm' ? 13 : 14} />
          </div>
        }
        <div className="hf-text">
          <div className="hf-line">{line}</div>
          <div className="hf-val">{val}{valExtra && <> <span style={{ color: `var(--${color})` }}>·</span> {valExtra}</>}</div>
        </div>
      </div>
    </div>
  );

  if (center) {
    return (
      <div style={{ position: 'absolute', top: pos.top || 0, left: 0, right: 0, display: 'flex', justifyContent: 'center', pointerEvents: 'none' }}>
        <div ref={ref}
          className={`float-chip-wrap float-chip-wrap-rel ${revealed ? 'chip-revealed' : ''}`}
          style={{ '--chip-rotate': `${seedRotate}deg` }}>
          {inner}
        </div>
      </div>
    );
  }

  return (
    <div ref={ref}
      className={`float-chip-wrap ${revealed ? 'chip-revealed' : ''}`}
      style={{ ...pos, '--chip-rotate': `${seedRotate}deg`, '--chip-boost': boost }}>
      {inner}
    </div>
  );
};

// ============================================================
// SECTION HEADER
// ============================================================
const SectionHeader = ({ eyebrow, title, subtitle, align = 'left', accentWord }) => {
  const renderTitle = () => {
    if (!accentWord) return title;
    const parts = title.split(accentWord);
    return <>{parts[0]}<span className="acid">{accentWord}</span>{parts[1]}</>;
  };
  return (
    <div style={{ textAlign: align, maxWidth: 720, margin: align === 'center' ? '0 auto 56px' : '0 0 56px' }}>
      {eyebrow && <div className="eyebrow" style={{ marginBottom: 18 }}><span className="dot" />{eyebrow}</div>}
      <h2>{renderTitle()}</h2>
      {subtitle && <p className="lead" style={{ marginTop: 18 }}>{subtitle}</p>}
    </div>);

};

// ============================================================
// REVEAL ON SCROLL — IntersectionObserver
// ============================================================
const Reveal = ({ children, delay = 0, as: As = 'div', className = '', style = {}, ...rest }) =>
<As className={`reveal ${className}`} style={{ '--reveal-delay': `${delay}ms`, ...style }} {...rest}>
    {children}
  </As>;


// Helper used across pages to hide "Apply for Elite" CTAs from
// users that already have Elite (or admin) — single source of truth.
const isEliteUser = (user) => user?.role === 'elite' || user?.role === 'admin';

// Export to window
Object.assign(window, { Icon, IconChip, Button, CandleChart, Stat, FloatChip, SectionHeader, Reveal, isEliteUser });
