// reel-shared.jsx — Horus Hub REELS (9:16 · 1080×1920) — vertical caption system
// Reuses brand tokens + helpers from vsl-shared.jsx (HORUS, GRAD, HL, envelope,
// PhaseBg, Atmosphere, Scene). Loaded after animations.jsx + vsl-shared.jsx.

const { HORUS: R, GRAD: RG, GRAD_PB: RGPB, HL: RHL, envelope: rEnv, PhaseBg: RBg,
        Scene: RScene, GridLines: RGrid, Easing: RE, clamp: rcl, interpolate: ritp,
        useSprite: rSpr } = window;

// Vertical canvas constants
const CW = 1080, CH = 1920, CX = 540;

// ── Caption (headline) ───────────────────────────────────────────────────────
// Big kinetic line, centred. cy default sits in the mobile-safe middle band.
function RCap({ at, until, children, cx = CX, cy = 980, size = 88, weight = 700,
  color = R.white, font = R.display, maxWidth = 900, align = 'center',
  letterSpacing = '-0.025em', lh = 1.1, shadow = true }) {
  const { localTime } = rSpr();
  const { o, ty } = rEnv(localTime, at, until, 0.5, 0.45);
  if (o <= 0.001) return null;
  return (
    <div style={{
      position: 'absolute', left: cx, top: cy,
      transform: `translate(-50%, calc(-50% + ${ty}px))`,
      width: maxWidth, textAlign: align,
      fontFamily: font, fontSize: size, fontWeight: weight, color,
      letterSpacing, lineHeight: lh, opacity: o,
      textWrap: 'balance', willChange: 'transform, opacity',
      textShadow: shadow ? '0 3px 36px rgba(0,0,0,0.7)' : 'none',
    }}>
      {children}
    </div>
  );
}

// ── Sub / supporting line ─────────────────────────────────────────────────────
function RSub({ at, until, children, cx = CX, cy = 980, size = 48, weight = 500,
  color = R.dim, maxWidth = 860, font = R.display, align = 'center' }) {
  return (
    <RCap at={at} until={until} cx={cx} cy={cy} size={size} weight={weight}
      color={color} maxWidth={maxWidth} font={font} align={align} letterSpacing="-0.01em" lh={1.22}>
      {children}
    </RCap>
  );
}

// ── Eyebrow / kicker ──────────────────────────────────────────────────────────
function REyebrow({ at, until, children, cx = CX, cy = 820, color = R.purpleLight }) {
  const { localTime } = rSpr();
  const { o, ty } = rEnv(localTime, at, until, 0.45, 0.4);
  if (o <= 0.001) return null;
  return (
    <div style={{
      position: 'absolute', left: cx, top: cy,
      transform: `translate(-50%, calc(-50% + ${ty}px))`,
      opacity: o, fontFamily: R.display, fontSize: 26, fontWeight: 600,
      letterSpacing: '0.36em', textTransform: 'uppercase', color, whiteSpace: 'nowrap',
    }}>{children}</div>
  );
}

// ── Phase progress (top-safe) ─────────────────────────────────────────────────
function RPhase({ idx, label }) {
  return (
    <div style={{
      position: 'absolute', left: '50%', top: 150, transform: 'translateX(-50%)',
      display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16, zIndex: 40,
    }}>
      <div style={{ display: 'flex', gap: 9 }}>
        {[0,1,2,3].map(i => (
          <div key={i} style={{
            width: i === idx ? 44 : 11, height: 5, borderRadius: 3,
            background: i === idx ? RG : 'rgba(255,255,255,0.18)', transition: 'width .4s',
          }} />
        ))}
      </div>
      <span style={{ fontFamily: R.display, fontSize: 18, letterSpacing: '0.34em',
        textTransform: 'uppercase', color: R.faint }}>{label}</span>
    </div>
  );
}

// ── Emblem (brand mark) with glow ─────────────────────────────────────────────
function REmblem({ x = CX, y = 760, size = 360, scale = 1, rot = 0, glow = 1, op = 1 }) {
  return (
    <div style={{ position: 'absolute', left: x, top: y, opacity: op,
      transform: `translate(-50%,-50%) scale(${scale}) rotate(${rot}deg)` }}>
      <img src="assets/emblema.png" alt="" style={{ width: size, height: size, objectFit: 'contain',
        filter: `drop-shadow(0 0 ${40 + glow * 70}px hsl(263 75% 55% / ${0.35 + glow * 0.4}))` }} />
    </div>
  );
}

// ── Bottom scrim — seats captions over busy visuals ───────────────────────────
function RScrim({ from = 0.5, op = 1 }) {
  return (
    <div style={{ position: 'absolute', inset: 0, pointerEvents: 'none', opacity: op,
      background: `linear-gradient(180deg, transparent 0%, transparent ${from*100}%, rgba(7,7,12,0.82) 100%)` }} />
  );
}

// window helper for staged visuals
const rwin = (lt, a, b, f = 0.5) => rcl(Math.min((lt - a) / f, (b - lt) / f, 1), 0, 1);

Object.assign(window, {
  CW, CH, CX, RCap, RSub, REyebrow, RPhase, REmblem, RScrim, rwin,
});
