// Shared primitives for dub2.ai site

const Mark = ({ size = 32, animated = false }) => {
  if (animated) return <AnimatedMark size={size} />;
  return (
    <img src="assets/mark.svg" width={size} height={size} alt="dub2.ai mark" style={{ display: 'block' }} />
  );
};

// Animated version of the dot-matrix — pulses inside-out
const AnimatedMark = ({ size = 200, speed = 1 }) => {
  const dots = [
    [-9, -38, 3.5, '#C21500', 2],  [9, -38, 3.5, '#C21500', 2],
    [-26, -26, 5, '#C21500', 2], [-9, -26, 5, '#EA4A35', 1], [9, -26, 5, '#EA4A35', 1], [26, -26, 5, '#C21500', 2],
    [-38, -9, 3.5, '#C21500', 2], [-26, -9, 5, '#EA4A35', 1], [-9, -9, 6, '#FF604C', 0], [9, -9, 6, '#FF604C', 0], [26, -9, 5, '#EA4A35', 1], [38, -9, 3.5, '#C21500', 2],
    [-38, 9, 3.5, '#C21500', 2], [-26, 9, 5, '#EA4A35', 1], [-9, 9, 6, '#FF604C', 0], [9, 9, 6, '#FF604C', 0], [26, 9, 5, '#EA4A35', 1], [38, 9, 3.5, '#C21500', 2],
    [-26, 26, 5, '#C21500', 2], [-9, 26, 5, '#EA4A35', 1], [9, 26, 5, '#EA4A35', 1], [26, 26, 5, '#C21500', 2],
    [-9, 38, 3.5, '#C21500', 2],  [9, 38, 3.5, '#C21500', 2],
  ];
  return (
    <svg viewBox="-60 -60 120 120" width={size} height={size} style={{ display: 'block' }}>
      <style>{`
        @keyframes d2-pulse {
          0%, 100% { transform: scale(1); opacity: 1; }
          50%      { transform: scale(1.18); opacity: 0.85; }
        }
        .d2-dot { transform-origin: center; transform-box: fill-box; }
      `}</style>
      {dots.map(([cx, cy, r, fill, ring], i) => (
        <circle key={i} cx={cx} cy={cy} r={r} fill={fill}
          className="d2-dot"
          style={{ animation: `d2-pulse ${2.4 / speed}s ${ring * 0.22}s var(--ease-out, ease-out) infinite` }}
        />
      ))}
    </svg>
  );
};

const Logo = ({ height = 28, variant = 'color', animated = false }) => (
  <a href="index.html" style={{ display: 'inline-flex', alignItems: 'center', gap: 10, textDecoration: 'none' }}>
    <Mark size={height} animated={animated} />
    <span style={{
      fontFamily: 'var(--font-display)', fontWeight: 400, fontSize: height * 0.85,
      letterSpacing: '-0.03em', color: variant === 'light' ? '#fff' : 'var(--brand-ember)',
      lineHeight: 1,
    }}>dub2.ai</span>
  </a>
);

const Button = ({ variant = 'primary', size = 'md', children, onClick, href, style, type, disabled }) => {
  const sizes = {
    sm: { padding: '6px 14px', fontSize: 13 },
    md: { padding: '10px 20px', fontSize: 14 },
    lg: { padding: '14px 28px', fontSize: 16 },
  };
  const variants = {
    primary: { background: 'var(--brand-ember)', color: '#fff', border: '1.5px solid transparent' },
    secondary: { background: '#fff', color: 'var(--fg-1)', border: '1.5px solid var(--border-2)' },
    ghost: { background: 'transparent', color: 'var(--fg-1)', border: '1.5px solid transparent' },
    onDark: { background: '#fff', color: 'var(--brand-ember)', border: '1.5px solid transparent' },
    onDarkGhost: { background: 'transparent', color: '#fff', border: '1.5px solid rgba(255,255,255,0.2)' },
  };
  const base = {
    display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 8,
    borderRadius: 'var(--radius-md)', fontFamily: 'var(--font-body)', fontWeight: 600,
    cursor: disabled ? 'not-allowed' : 'pointer', transition: 'all .16s var(--ease-standard)',
    textDecoration: 'none', whiteSpace: 'nowrap', opacity: disabled ? 0.6 : 1,
    ...sizes[size], ...variants[variant], ...style,
  };
  const className = `d2-btn d2-btn-${variant}`;
  if (href) return <a className={className} href={href} onClick={onClick} style={base}>{children}</a>;
  return <button className={className} type={type || 'button'} onClick={onClick} style={base} disabled={disabled}>{children}</button>;
};

const Eyebrow = ({ children, light }) => (
  <div style={{
    fontSize: 12, fontWeight: 700, letterSpacing: '0.14em', textTransform: 'uppercase',
    color: light ? 'rgba(255,255,255,.75)' : 'var(--brand-ember)',
    fontFamily: 'var(--font-body)',
  }}>{children}</div>
);

const Pill = ({ children, tone = 'soft' }) => {
  const tones = {
    soft: { background: 'var(--brand-blush)', color: 'var(--brand-ember)' },
    solid: { background: 'var(--brand-ember)', color: '#fff' },
    outline: { background: '#fff', border: '1.5px solid var(--brand-ember)', color: 'var(--brand-ember)' },
    neutral: { background: 'var(--neutral-100)', color: 'var(--fg-1)' },
    onDark: { background: 'rgba(255,255,255,0.08)', color: '#fff', border: '1px solid rgba(255,255,255,0.14)' },
  };
  return <span style={{
    display: 'inline-flex', alignItems: 'center', gap: 6, padding: '4px 12px',
    borderRadius: 999, fontSize: 12, fontWeight: 600, fontFamily: 'var(--font-body)', ...tones[tone],
  }}>{children}</span>;
};

// Static dot-grid (for decorative placement)
const DotGrid = ({ w = 200, h = 200, opacity = 1, style }) => {
  const dots = [
    [-9, -38, 3.5, '#C21500'], [9, -38, 3.5, '#C21500'],
    [-26, -26, 5, '#C21500'], [-9, -26, 5, '#EA4A35'], [9, -26, 5, '#EA4A35'], [26, -26, 5, '#C21500'],
    [-38, -9, 3.5, '#C21500'], [-26, -9, 5, '#EA4A35'], [-9, -9, 6, '#FF604C'], [9, -9, 6, '#FF604C'], [26, -9, 5, '#EA4A35'], [38, -9, 3.5, '#C21500'],
    [-38, 9, 3.5, '#C21500'], [-26, 9, 5, '#EA4A35'], [-9, 9, 6, '#FF604C'], [9, 9, 6, '#FF604C'], [26, 9, 5, '#EA4A35'], [38, 9, 3.5, '#C21500'],
    [-26, 26, 5, '#C21500'], [-9, 26, 5, '#EA4A35'], [9, 26, 5, '#EA4A35'], [26, 26, 5, '#C21500'],
    [-9, 38, 3.5, '#C21500'], [9, 38, 3.5, '#C21500'],
  ];
  return (
    <svg viewBox="-60 -60 120 120" width={w} height={h} style={{ opacity, display: 'block', ...style }}>
      {dots.map(([cx, cy, r, fill], i) => <circle key={i} cx={cx} cy={cy} r={r} fill={fill} />)}
    </svg>
  );
};

// Repeating dot-grid pattern (for backgrounds). Uses ember dots at low opacity.
const DotPattern = ({ size = 24, dotSize = 1.6, color = 'currentColor', opacity = 0.12, style }) => (
  <svg width="100%" height="100%" style={{ position: 'absolute', inset: 0, color, opacity, ...style }}>
    <defs>
      <pattern id={`dp-${size}-${dotSize}`} x="0" y="0" width={size} height={size} patternUnits="userSpaceOnUse">
        <circle cx={size / 2} cy={size / 2} r={dotSize} fill="currentColor" />
      </pattern>
    </defs>
    <rect width="100%" height="100%" fill={`url(#dp-${size}-${dotSize})`} />
  </svg>
);

// Scroll reveal — respects reduced motion
const Reveal = ({ children, delay = 0, as: Tag = 'div', style, ...rest }) => {
  const ref = React.useRef(null);
  const [visible, setVisible] = React.useState(false);
  React.useEffect(() => {
    if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { setVisible(true); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => { if (e.isIntersecting) { setVisible(true); io.disconnect(); } });
    }, { threshold: 0.15 });
    if (ref.current) io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  return (
    <Tag ref={ref} style={{
      opacity: visible ? 1 : 0,
      transform: visible ? 'none' : 'translateY(14px)',
      transition: `opacity .55s var(--ease-out) ${delay}ms, transform .55s var(--ease-out) ${delay}ms`,
      ...style,
    }} {...rest}>{children}</Tag>
  );
};

// 20×20 stroked icons — matches design system (1.75 stroke, round caps)
const Icon = ({ name, size = 20, color = 'currentColor', strokeWidth = 1.75 }) => {
  const common = { width: size, height: size, viewBox: '0 0 24 24', fill: 'none', stroke: color, strokeWidth, strokeLinecap: 'round', strokeLinejoin: 'round' };
  const paths = {
    check: <polyline points="20 6 9 17 4 12" />,
    arrow: <g><line x1="5" y1="12" x2="19" y2="12" /><polyline points="13 6 19 12 13 18" /></g>,
    arrowUpRight: <g><line x1="7" y1="17" x2="17" y2="7"/><polyline points="7 7 17 7 17 17"/></g>,
    sparkle: <g><path d="M12 3v4M12 17v4M3 12h4M17 12h4M5.6 5.6l2.8 2.8M15.6 15.6l2.8 2.8M18.4 5.6l-2.8 2.8M8.4 15.6l-2.8 2.8"/></g>,
    shield: <path d="M12 2 4 5v6c0 5 3.4 9 8 11 4.6-2 8-6 8-11V5l-8-3z"/>,
    code: <g><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></g>,
    zap: <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />,
    chat: <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>,
    menu: <g><line x1="3" y1="6" x2="21" y2="6"/><line x1="3" y1="12" x2="21" y2="12"/><line x1="3" y1="18" x2="21" y2="18"/></g>,
    close: <g><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></g>,
    plus: <g><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></g>,
    voice: <g><rect x="9" y="3" width="6" height="12" rx="3"/><path d="M5 11a7 7 0 0 0 14 0"/><line x1="12" y1="18" x2="12" y2="22"/></g>,
    workflow: <g><rect x="3" y="3" width="6" height="6" rx="1"/><rect x="15" y="15" width="6" height="6" rx="1"/><path d="M9 6h6a3 3 0 0 1 3 3v6"/></g>,
    doc: <g><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="13" y2="17"/></g>,
    box: <g><path d="m21 16-9 5-9-5V8l9-5 9 5z"/><polyline points="3 8 12 13 21 8"/><line x1="12" y1="13" x2="12" y2="21"/></g>,
    cpu: <g><rect x="4" y="4" width="16" height="16" rx="2"/><rect x="9" y="9" width="6" height="6"/><line x1="9" y1="1" x2="9" y2="4"/><line x1="15" y1="1" x2="15" y2="4"/><line x1="9" y1="20" x2="9" y2="23"/><line x1="15" y1="20" x2="15" y2="23"/><line x1="20" y1="9" x2="23" y2="9"/><line x1="20" y1="14" x2="23" y2="14"/><line x1="1" y1="9" x2="4" y2="9"/><line x1="1" y1="14" x2="4" y2="14"/></g>,
    palette: <g><circle cx="13.5" cy="6.5" r=".5" fill="currentColor"/><circle cx="17.5" cy="10.5" r=".5" fill="currentColor"/><circle cx="8.5" cy="7.5" r=".5" fill="currentColor"/><circle cx="6.5" cy="12.5" r=".5" fill="currentColor"/><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.9 0 1.5-.8 1.5-1.7 0-.4-.2-.8-.5-1.1-.3-.3-.5-.7-.5-1.1 0-.9.7-1.6 1.6-1.6H16c3.3 0 6-2.7 6-6 0-4.9-4.5-8.5-10-8.5z"/></g>,
    map: <g><polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"/><line x1="8" y1="2" x2="8" y2="18"/><line x1="16" y1="6" x2="16" y2="22"/></g>,
    mail: <g><rect x="3" y="5" width="18" height="14" rx="2"/><polyline points="3 7 12 13 21 7"/></g>,
    linkedin: <g><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-4 0v7h-4v-7a6 6 0 0 1 6-6z"/><rect x="2" y="9" width="4" height="12"/><circle cx="4" cy="4" r="2"/></g>,
    users: <g><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></g>,
    flag: <g><path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/><line x1="4" y1="22" x2="4" y2="15"/></g>,
    clock: <g><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></g>,
    trending: <g><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/></g>,
    lock: <g><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></g>,
  };
  return <svg {...common}>{paths[name] || paths.plus}</svg>;
};

Object.assign(window, { Mark, AnimatedMark, Logo, Button, Eyebrow, Pill, DotGrid, DotPattern, Reveal, Icon });
