/* burp.agency — shared atoms, hooks, routes */

/* ─── SEO routes (public URLs at site root) ─ */
const ROUTES = {
  home:   '/',
  words:  '/offerings/content-marketing',
  shape:  '/offerings/design',
  motion: '/offerings/growth-marketing',
  offerings: '/offerings',
  blog:   '/blog',
  work:   '/work',
  audit:  '/audit',
  contact: '/contact',
};

/* ─── File-relative paths (so mockups link correctly) ─────────── */
/* `depth` is how many `../` to prepend (0 = at site root). */
const fileRoutes = (depth = 0) => {
  const p = '../'.repeat(depth);
  return {
    home:      p + 'index.html',
    offerings: p + 'offerings.html',
    words:     p + 'offerings/content-marketing.html',
    shape:     p + 'offerings/design.html',
    motion:    p + 'offerings/growth-marketing.html',
    blog:      p + 'blog.html',
    work:      p + 'work.html',
    audit:     p + 'audit.html',
    contact:   p + 'contact.html',
  };
};

/* ─── useReveal: simple, CSS-based fade-in
   Uses CSS @keyframes (declared globally) with a delay. No IntersectionObserver
   plumbing — content is visible by default, animation just fades it in nicely.
   This trades scroll-driven reveal for reliability across iframe contexts. */
function useReveal(opts = {}) {
  const { delay = 0 } = opts;
  const ref = React.useRef(null);
  const style = {
    animation: `burp-fade-in .6s cubic-bezier(.22,1,.36,1) ${delay}ms both`,
  };
  return [ref, style, true];
}

/* ─── useScrollProgress: 0..1 across whole page ───────────────── */
function useScrollProgress() {
  const [p, setP] = React.useState(0);
  React.useEffect(() => {
    const onScroll = () => {
      const h = document.documentElement;
      const max = (h.scrollHeight - h.clientHeight) || 1;
      setP(Math.min(1, Math.max(0, h.scrollTop / max)));
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return p;
}

/* ─── Reveal wrapper component ────────────────────────────────── */
const Reveal = ({ children, delay = 0, as = 'div', style, ...rest }) => {
  const [ref, rstyle] = useReveal({ delay });
  const Tag = as;
  return <Tag ref={ref} style={{ ...rstyle, ...style }} {...rest}>{children}</Tag>;
};

/* ─── Btn ─────────────────────────────────────────────────────── */
const Btn = ({ children, variant = 'default', size = 'md', href, onClick, style, ...rest }) => {
  const cls = `btn${variant === 'accent' ? ' btn--accent' : ''}${variant === 'ghost' ? ' btn--ghost' : ''}`;
  const sized = size === 'sm' ? { height: 40, padding: '0 18px', fontSize: 13 } : null;
  const Tag = href ? 'a' : 'button';
  return (
    <Tag href={href} onClick={onClick} className={cls}
         style={{ ...sized, ...style }} {...rest}>
      {children}
    </Tag>
  );
};

const Label = ({ children, ink, style }) => (
  <span style={{
    fontFamily: 'Inter, sans-serif',
    fontSize: 11, fontWeight: 600,
    letterSpacing: '0.10em', textTransform: 'uppercase',
    color: ink ? 'var(--color-ink)' : 'var(--color-orange)',
    display: 'inline-block',
    ...style,
  }}>{children}</span>
);

const Caption = ({ children, style }) => (
  <span style={{
    fontFamily: 'Inter, sans-serif',
    fontSize: 13, fontWeight: 600,
    letterSpacing: '0.08em', textTransform: 'uppercase',
    color: 'var(--color-mid-gray)',
    ...style,
  }}>{children}</span>
);

const Container = ({ children, narrow, style }) => (
  <div style={{
    maxWidth: narrow ? 800 : 1200,
    margin: '0 auto',
    padding: '0 32px',
    ...style,
  }}>{children}</div>
);

const Section = ({ children, bg = 'cream', id, label, style }) => {
  const bgs = {
    cream:    'var(--color-cream)',
    white:    '#ffffff',
    charcoal: 'var(--color-charcoal)',
    ink:      'var(--color-ink)',
    tint:     'var(--color-pale-orange)',
  };
  const dark = bg === 'charcoal' || bg === 'ink';
  return (
    <section id={id} data-screen-label={label} style={{
      background: bgs[bg],
      color: dark ? '#fff' : 'var(--color-ink)',
      paddingTop: 120, paddingBottom: 120,
      ...style,
    }}>{children}</section>
  );
};

/* ─── Scroll progress bar (top-of-page indicator) ─────────────── */
const ScrollProgress = () => {
  const p = useScrollProgress();
  return (
    <div style={{
      position: 'fixed', top: 0, left: 0, right: 0,
      height: 2, background: 'transparent',
      zIndex: 1000, pointerEvents: 'none',
    }}>
      <div style={{
        width: `${p * 100}%`, height: '100%',
        background: 'var(--color-orange)',
        transition: 'width .08s linear',
      }}/>
    </div>
  );
};

Object.assign(window, {
  ROUTES, fileRoutes,
  useReveal, useScrollProgress, Reveal,
  Btn, Label, Caption, Container, Section, ScrollProgress,
});
