/* @jsxRuntime classic */
/* global React */
const { useState, useEffect, useRef } = React;

/* ────────── Eyebrow — tracked small-caps in brass ────────── */
const Eyebrow = ({ children, color = 'var(--vg-brass)', style }) => (
  <div style={{
    fontFamily: "'Inter Tight', sans-serif",
    fontSize: 11,
    fontWeight: 600,
    textTransform: 'uppercase',
    letterSpacing: '0.22em',
    color,
    ...style,
  }}>{children}</div>
);

/* ────────── Signature divider: rule · lozenge · rule ────────── */
const Ornament = ({ color = 'var(--vg-rule-brass)', dot = 'var(--vg-brass)', style }) => (
  <div style={{ display: 'flex', alignItems: 'center', gap: 14, ...style }}>
    <span style={{ flex: 1, height: 1, background: color }} />
    <span style={{ width: 8, height: 8, background: dot, transform: 'rotate(45deg)' }} />
    <span style={{ flex: 1, height: 1, background: color }} />
  </div>
);

/* ────────── Ampersand as ornament ────────── */
const Amp = ({ color = 'var(--vg-brass)' }) => (
  <em translate="no" className="notranslate" style={{ color, fontStyle: 'italic', fontFamily: "'Cormorant Garamond', serif" }}>&amp;</em>
);

/* ────────── Button ────────── */
const Button = ({ children, variant = 'primary', onClick, type, style, href }) => {
  const base = {
    fontFamily: "'Inter Tight', sans-serif",
    fontSize: 11.5,
    fontWeight: 600,
    textTransform: 'uppercase',
    letterSpacing: '0.2em',
    padding: '14px 22px',
    borderRadius: 2,
    cursor: 'pointer',
    transition: 'all 240ms cubic-bezier(.25,.1,.25,1)',
    border: '1px solid currentColor',
    display: 'inline-block',
    textDecoration: 'none',
    lineHeight: 1,
  };
  const variants = {
    primary:   { background: 'var(--vg-midnight)', color: 'var(--vg-paper)', borderColor: 'var(--vg-midnight)' },
    brass:     { background: 'var(--vg-brass)',    color: 'var(--vg-midnight)', borderColor: 'var(--vg-brass)' },
    ghost:     { background: 'transparent',        color: 'var(--vg-ink)',   borderColor: 'var(--vg-ink)' },
    ghostDark: { background: 'transparent',        color: 'var(--vg-paper)', borderColor: 'rgba(244,239,230,0.55)' },
  };
  const s = { ...base, ...variants[variant], ...style };
  const hover = (e, on) => {
    if (variant === 'brass') {
      e.currentTarget.style.background = on ? 'var(--vg-brass-dim)' : 'var(--vg-brass)';
      e.currentTarget.style.borderColor = on ? 'var(--vg-brass-dim)' : 'var(--vg-brass)';
    } else if (variant === 'ghost') {
      e.currentTarget.style.background = on ? 'var(--vg-ink)' : 'transparent';
      e.currentTarget.style.color      = on ? 'var(--vg-paper)' : 'var(--vg-ink)';
    } else if (variant === 'ghostDark') {
      e.currentTarget.style.background = on ? 'rgba(244,239,230,0.06)' : 'transparent';
      e.currentTarget.style.borderColor = on ? 'var(--vg-brass)' : 'rgba(244,239,230,0.55)';
      e.currentTarget.style.color = on ? 'var(--vg-brass-bright)' : 'var(--vg-paper)';
    } else {
      e.currentTarget.style.opacity = on ? 0.88 : 1;
    }
  };
  const Tag = href ? 'a' : 'button';
  return (
    <Tag
      href={href}
      type={type}
      onClick={onClick}
      style={s}
      onMouseEnter={e => hover(e, true)}
      onMouseLeave={e => hover(e, false)}
    >{children}</Tag>
  );
};

/* ────────── Logotype — typographic recreation in brand fonts ──────────
   Mirrors the brand horizontal lockup: VAL & GAL | CAPITAL.
   "VAL" + "GAL" in Cormorant Garamond display, ampersand in italic brass,
   a thin vertical rule, then "CAPITAL" in tracked Inter Tight small caps.
   Sized via `height` so it reads at any scale. */
const Logotype = ({ height = 32, variant = 'light' }) => {
  const ink   = variant === 'dark' ? 'var(--vg-paper)' : 'var(--vg-ink)';
  const sub   = variant === 'dark' ? 'rgba(244,239,230,0.75)' : 'var(--vg-stone-700)';
  const rule  = variant === 'dark' ? 'rgba(244,239,230,0.45)'  : 'rgba(10,15,25,0.32)';
  const brass = 'var(--vg-brass)';
  const fsMain = height * 0.95;
  const fsSub  = height * 0.36;
  const ruleH  = height * 0.78;
  return (
    <div translate="no" className="notranslate" style={{
      display:'inline-flex', alignItems:'center', gap: height * 0.42,
      lineHeight: 1, height,
    }}>
      <span style={{
        fontFamily: "'Cormorant Garamond', serif",
        fontWeight: 500,
        fontSize: fsMain,
        letterSpacing: '0.02em',
        color: ink,
        whiteSpace: 'nowrap',
      }}>
        VAL
        <em style={{
          color: brass, fontStyle:'italic', fontWeight: 400,
          padding: `0 ${height * 0.18}px`,
        }}>&amp;</em>
        GAL
      </span>
      <span style={{
        display:'inline-block', width: 1, height: ruleH, background: rule,
      }}/>
      <span style={{
        fontFamily: "'Inter Tight', sans-serif",
        fontWeight: 400,
        fontSize: fsSub,
        letterSpacing: '0.32em',
        textTransform: 'uppercase',
        color: sub,
        paddingLeft: height * 0.04,
      }}>
        Capital
      </span>
    </div>
  );
};

/* ────────── Intersection observer hook (for reveals + counters) ────────── */
const useInView = (options = { threshold: 0.2 }) => {
  const ref = useRef(null);
  const [inView, setInView] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const obs = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setInView(true); obs.disconnect(); }
    }, options);
    obs.observe(el);
    return () => obs.disconnect();
  }, []);
  return [ref, inView];
};

/* ────────── Animated counter — counts up once in-view ────────── */
const Counter = ({ to, suffix = '', prefix = '', duration = 1400, format = (n) => n }) => {
  const [ref, inView] = useInView();
  const [val, setVal] = useState(0);
  useEffect(() => {
    if (!inView) return;
    const t0 = performance.now();
    const ease = (t) => 1 - Math.pow(1 - t, 3);
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - t0) / duration);
      setVal(Math.round(ease(p) * to));
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [inView, to, duration]);
  return <span ref={ref}>{prefix}{format(val)}{suffix}</span>;
};

/* ────────── Reveal wrapper — fades + slight rise when in-view ────────── */
const Reveal = ({ children, delay = 0, y = 14, style }) => {
  const [ref, inView] = useInView({ threshold: 0.15 });
  return (
    <div
      ref={ref}
      style={{
        opacity: inView ? 1 : 0,
        transform: `translateY(${inView ? 0 : y}px)`,
        transition: `opacity 620ms cubic-bezier(.25,.1,.25,1) ${delay}ms, transform 620ms cubic-bezier(.25,.1,.25,1) ${delay}ms`,
        ...style,
      }}
    >{children}</div>
  );
};

Object.assign(window, { Eyebrow, Ornament, Amp, Button, Logotype, useInView, Counter, Reveal });
