/* Primitives — Logo, Button, Eyebrow, Section, Container, Reveal, hooks. */
const { useState, useEffect, useRef } = React;

function Container({ children, style }) {
  return <div style={{ width:'100%', maxWidth:'var(--maxw)', margin:'0 auto', padding:'0 24px', ...style }}>{children}</div>;
}

/* Wordmark: orbital mark + "Brand New Edge" */
function Logo({ size = 30, variant, href = 'index.html' }) {
  return (
    <a href={href} aria-label="Brand New Edge home" style={{ display:'inline-flex', alignItems:'center', gap:10, textDecoration:'none' }}>
      <Mark size={size} variant={variant} />
      <span style={{ fontFamily:'var(--font-display)', fontWeight:800, fontSize:size*.62, letterSpacing:'-.02em', color:'var(--text-1)', whiteSpace:'nowrap' }}>
        Brand New Edge
      </span>
    </a>
  );
}

function Eyebrow({ children, style }) {
  return <div className="t-eyebrow" style={{ display:'inline-flex', alignItems:'center', ...style }}>
    {children}
  </div>;
}

function Button({ children, variant = 'solid', href = '#contact', onClick, style }) {
  const [h, setH] = useState(false);
  const base = {
    display:'inline-flex', alignItems:'center', gap:8, cursor:'pointer',
    fontFamily:'var(--font-body)', fontWeight:600, fontSize:15.5, lineHeight:1,
    padding:'14px 22px', borderRadius:'var(--r-btn)', textDecoration:'none',
    transition:'all var(--dur) var(--ease-out)', border:'1px solid transparent', whiteSpace:'nowrap',
  };
  const variants = {
    solid: { background:'linear-gradient(100deg, #9B55D6 0%, #7B2FBE 38%, #5B3FD6 70%, #3D4FC9 100%)', color:'#fff', boxShadow: h ? 'var(--glow)' : 'var(--shadow-sm)', transform: h ? 'translateY(-1px)' : 'none' },
    accent:{ background:'linear-gradient(100deg, #9B55D6 0%, #7B2FBE 38%, #5B3FD6 70%, #3D4FC9 100%)', color:'#fff', boxShadow: h ? 'var(--glow)' : 'none', transform: h ? 'translateY(-1px)' : 'none' },
    ghost: { background: h ? 'rgba(155,85,214,.10)' : 'transparent', color:'var(--text-1)', borderColor:'var(--border-2)' },
  };
  return (
    <a href={href} onClick={onClick} onMouseEnter={()=>setH(true)} onMouseLeave={()=>setH(false)}
      style={{ ...base, ...variants[variant], ...style }}>{children}</a>
  );
}

/* Section wrapper. bg: app | alt | deep (theme-aware light/dark) | navy (always dark feature) */
function Section({ id, bg = 'app', children, style, label }) {
  const bgMap = { app:'var(--app-bg)', alt:'var(--section-alt)', deep:'var(--section-deep)', navy:'var(--navy-feature)' };
  // deep = theme-aware surface (light-gray in bright mode, navy in dark); navy = always-dark feature band
  const deepForce = { '--text-1':'var(--on-deep-1)', '--text-2':'var(--on-deep-2)', '--text-3':'var(--on-deep-3)', '--border-1':'var(--deep-border)', '--border-2':'var(--deep-border)', '--eyebrow':'var(--deep-eyebrow)', '--card-bg':'var(--deep-card)', '--client-filter':'var(--deep-client-filter)' };
  const navyForce = { '--text-1':'#fff', '--text-2':'rgba(255,255,255,.74)', '--text-3':'rgba(255,255,255,.54)', '--border-1':'rgba(255,255,255,.12)', '--border-2':'rgba(255,255,255,.22)', '--eyebrow':'#A98BD6', '--accent':'#9B55D6', '--accent-strong':'#7B2FBE', '--card-bg':'rgba(255,255,255,.05)', '--client-filter':'none', '--on-deep-1':'#fff', '--on-deep-2':'rgba(255,255,255,.74)', '--on-deep-3':'rgba(255,255,255,.54)', '--deep-card':'rgba(255,255,255,.05)', '--deep-border':'rgba(255,255,255,.12)', '--deep-chip':'rgba(255,255,255,.08)', '--deep-input':'rgba(255,255,255,.06)' };
  const force = bg === 'deep' ? deepForce : bg === 'navy' ? navyForce : {};
  return (
    <section id={id} data-screen-label={label} style={{ background:bgMap[bg], color:'var(--text-1)', position:'relative', ...force, ...style }}>
      {children}
    </section>
  );
}

/* Reveal — visible-by-default safe entrance via CSS transition + forced fallback. */
function Reveal({ children, delay = 0, as = 'div', style, ...rest }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el) return;
    const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (reduce || !('IntersectionObserver' in window)) { setShown(true); return; }
    const io = new IntersectionObserver((es) => {
      es.forEach(e => { if (e.isIntersecting) { setShown(true); io.disconnect(); } });
    }, { threshold:.12, rootMargin:'0px 0px -8% 0px' });
    io.observe(el);
    const t = setTimeout(() => setShown(true), 1400); // safety: never stay hidden
    return () => { io.disconnect(); clearTimeout(t); };
  }, []);
  const Tag = as;
  // Opacity stays 1 (never strands invisible in captures); only transform animates.
  return (
    <Tag ref={ref} style={{
      transform: shown ? 'none' : 'translateY(16px)',
      opacity: 1,
      transition:`transform .6s var(--ease-out) ${delay}ms`,
      willChange:'transform',
      ...style,
    }} {...rest}>{children}</Tag>
  );
}

/* Count-up on view. Pass numeric string; non-numeric (EST) renders as-is. */
function CountUp({ value, suffix = '', dur = 1400, style }) {
  const ref = useRef(null);
  const numeric = /^\d/.test(value);
  const target = numeric ? parseInt(value, 10) : null;
  const [n, setN] = useState(numeric ? 0 : value);
  useEffect(() => {
    if (!numeric) return;
    const el = ref.current; if (!el) return;
    let raf, started = false;
    const run = () => {
      const t0 = performance.now();
      const tick = (t) => {
        const p = Math.min(1, (t - t0) / dur);
        const e = 1 - Math.pow(1 - p, 3);
        setN(Math.round(e * target));
        if (p < 1) raf = requestAnimationFrame(tick);
      };
      raf = requestAnimationFrame(tick);
    };
    const io = new IntersectionObserver((es) => {
      es.forEach(e => { if (e.isIntersecting && !started) { started = true; run(); io.disconnect(); } });
    }, { threshold:.4 });
    io.observe(el);
    const safety = setTimeout(() => { if (!started) { started = true; setN(target); } }, 1600);
    return () => { io.disconnect(); cancelAnimationFrame(raf); clearTimeout(safety); };
  }, []);
  const display = numeric ? `${n}${suffix}` : `${value}${suffix}`;
  return <span ref={ref} style={style}>{display}</span>;
}

function ClientLogo({ name, h = 22 }) {
  const src = (window.__resources && window.__resources['client-' + name]) || `assets/clients/${name}.svg`;
  return <img src={src} alt={name} style={{ height:h, width:'auto', filter:'var(--client-filter)', opacity:.85 }} />;
}

Object.assign(window, { Container, Logo, Eyebrow, Button, Section, Reveal, CountUp, ClientLogo });
