// hf-motion.jsx — bulletproof, pure-CSS entrance motion.
//
// Lesson learned: JS-driven hide→reveal (IntersectionObserver toggling classes,
// per-component timers) was fragile in this runtime — content could stick hidden.
// This version uses a CSS @keyframes animation that ALWAYS ends visible
// (animation-fill-mode: both). If animation is unsupported or reduced-motion is
// on, the element is simply visible. There is no hidden resting state that can
// strand content. `delay` staggers entrances via animation-delay.
//
//   • Reveal  — fade + rise once, on mount. Always ends visible.
//   • CountUp — kept for compatibility; renders the final value immediately
//               (no scroll dependency), so it can never read as 0.

function Reveal({ children, delay = 0, as = 'div', style = {}, className = '' }) {
  const Tag = as;
  const cls = ('k-reveal ' + (className || '')).trim();
  const merged = delay ? { animationDelay: `${delay}ms`, ...style } : style;
  return <Tag className={cls} style={merged}>{children}</Tag>;
}

// Static, reliable number — no observer, no animation-to-zero risk.
function CountUp({ to, decimals = 0, prefix = '', suffix = '', style = {} }) {
  const shown = decimals > 0 ? Number(to).toFixed(decimals) : Math.round(to).toString();
  return <span style={style}>{prefix}{shown}{suffix}</span>;
}

Object.assign(window, { Reveal, CountUp });
