/* Loops — small reusable primitives */

const Container = ({ children, className = "" }) =>
<div className={`mx-auto w-full max-w-page px-5 sm:px-6 lg:px-10 ${className}`}>{children}</div>;


const Section = ({ id, children, className = "", as = "section", aria, style }) => {
  const Tag = as;
  return (
    <Tag id={id} aria-label={aria} style={style} className={`relative border-t border-line py-16 sm:py-20 lg:py-28 ${className}`}>
      {children}
    </Tag>);

};

const Kicker = ({ children }) =>
<span className="kicker" style={{ fontWeight: "600" }}>{children}</span>;


const SectionHeading = ({ kicker, title, body, align = "left", titleClassName = "", className = "" }) =>
<div className={`${align === "center" ? "text-center mx-auto" : ""} max-w-3xl ${className}`}>
    {kicker ? <div className="mb-5"><Kicker>{kicker}</Kicker></div> : null}
    <h2 className={`text-balance text-ink font-semibold tracking-tight2 text-[28px] sm:text-[34px] lg:text-[44px] leading-[1.15] ${titleClassName}`}>{title}</h2>
    {body ? <p className="mt-5 text-ink-2 text-[17px] sm:text-[18px] leading-[1.6] text-pretty" style={{ fontSize: "18px" }}>{body}</p> : null}
  </div>;


/* Buttons — primary, secondary, ghost */
const Button = React.forwardRef(({
  as: Tag = "a",
  variant = "primary",
  size = "md",
  children,
  className = "",
  ...props
}, ref) => {
  const base = "inline-flex items-center justify-center gap-2 font-semibold rounded-pill transition-all focus-ring select-none whitespace-nowrap";
  const sizes = {
    sm: "h-10 px-5 text-[14px]",
    md: "h-12 px-6 text-[15px]",
    lg: "h-[52px] px-7 text-[15px]"
  };
  const variants = {
    primary: "bg-brand text-white shadow-cta hover:bg-[#3f45c9] active:bg-[#363bb5]",
    secondary: "bg-soft text-ink border border-line hover:bg-muted/60",
    ghost: "bg-transparent text-brand border-[1.5px] border-brand hover:bg-brand-soft",
    dark: "bg-ink text-white hover:bg-[#2a1f47]",
    white: "bg-white text-ink border border-line hover:bg-soft"
  };
  return (
    <Tag ref={ref} className={`${base} ${sizes[size]} ${variants[variant]} ${className}`} {...props}>
      {children}
    </Tag>);

});

/* Soft pill / chip */
const Chip = ({ children, tone = "indigo", className = "" }) => {
  const tones = {
    indigo: "bg-brand-soft text-brand-deep",
    rose: "bg-rose-soft text-rose",
    amber: "bg-amber-soft text-[#b96e10]",
    neutral: "bg-soft text-ink-2 border border-line"
  };
  return (
    <span className={`inline-flex items-center gap-1.5 rounded-pill px-3 py-1 text-[12.5px] font-semibold tracking-[0.01em] ${tones[tone]} ${className}`}>
      {children}
    </span>);

};

/* App store buttons — illustrative, never real Apple/Google trade dress */
const AppStoreBadge = ({ store = "apple", className = "" }) => {
  const apple =
  <a href="#" aria-label="Download Loops on iOS"
  className={`focus-ring inline-flex items-center gap-3 rounded-[14px] bg-ink text-white pl-3.5 pr-4 h-[52px] hover:bg-[#2a1f47] transition-colors ${className}`}>
      <svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
        <path d="M16.365 1.43c0 1.14-.46 2.23-1.21 3.01-.79.83-2.09 1.47-3.15 1.39-.13-1.1.42-2.26 1.16-3.01.83-.85 2.23-1.46 3.2-1.39ZM20.5 17.4c-.55 1.27-.82 1.83-1.53 2.95-1 1.56-2.4 3.51-4.14 3.52-1.55.01-1.95-1.01-4.05-1-2.1.01-2.54 1.02-4.09 1-1.74-.01-3.07-1.78-4.06-3.34-2.78-4.36-3.07-9.48-1.36-12.2 1.22-1.94 3.14-3.07 4.95-3.07 1.84 0 3 1.01 4.51 1.01 1.47 0 2.37-1.02 4.5-1.02 1.61 0 3.32.88 4.54 2.4-3.98 2.18-3.34 7.87.73 9.76Z" />
      </svg>
      <span className="flex flex-col items-start leading-tight">
        <span className="text-[10.5px] opacity-80 font-normal">Download on</span>
        <span className="text-[15px] font-semibold tracking-tight">App Store</span>
      </span>
    </a>;

  const google =
  <a href="#" aria-label="Get Loops on Android"
  className={`focus-ring inline-flex items-center gap-3 rounded-[14px] bg-ink text-white pl-3.5 pr-4 h-[52px] hover:bg-[#2a1f47] transition-colors ${className}`}>
      <svg width="22" height="22" viewBox="0 0 24 24" aria-hidden="true">
        <defs>
          <linearGradient id="ga" x1="0" x2="1" y1="0" y2="1">
            <stop offset="0" stopColor="#4c52dd" /><stop offset="1" stopColor="#5b39c5" />
          </linearGradient>
          <linearGradient id="gb" x1="0" x2="1" y1="1" y2="0">
            <stop offset="0" stopColor="#fb9526" /><stop offset="1" stopColor="#f53864" />
          </linearGradient>
        </defs>
        <path d="M3.6 2.3c-.3.3-.4.7-.4 1.3v17c0 .6.1 1 .4 1.3l9.4-9.4-9.4-10.2Z" fill="url(#ga)" />
        <path d="M16.5 8.6 13 12l3.5 3.4 4-2.3c1-.6 1-1.6 0-2.2l-4-2.3Z" fill="url(#gb)" />
        <path d="M3.6 22c.3.3.8.3 1.4 0l11.5-6.6L13 12 3.6 22Z" fill="#4c52dd" />
        <path d="M3.6 2.3 13 12l3.5-3.4L5 2c-.6-.3-1.1-.3-1.4.3Z" fill="#5b39c5" />
      </svg>
      <span className="flex flex-col items-start leading-tight">
        <span className="text-[10.5px] opacity-80 font-normal">Get it on</span>
        <span className="text-[15px] font-semibold tracking-tight">Google Play</span>
      </span>
    </a>;

  return store === "apple" ? apple : google;
};

/* Animated brand keyline — subtle, just a thin moving line */
const Keyline = ({ className = "" }) =>
<div className={`keyline-gradient h-[1.5px] w-full rounded-pill opacity-80 ${className}`} aria-hidden="true" />;


/* A simple visual "season glyph" — abstract calm circle motif */
const SeasonGlyph = ({ variant = 0, className = "" }) => {
  const variants = [
  // career — concentric rising arc
  <g key="0">
      <circle cx="24" cy="24" r="18" stroke="#4c52dd" strokeWidth="1.5" fill="none" opacity="0.35" />
      <path d="M10 30 Q 24 12 38 22" stroke="#4c52dd" strokeWidth="2" strokeLinecap="round" fill="none" />
      <circle cx="38" cy="22" r="3" fill="#4c52dd" />
    </g>,
  // money — soft coin stack
  <g key="1">
      <ellipse cx="24" cy="32" rx="14" ry="3.5" fill="#fb9526" opacity="0.2" />
      <ellipse cx="24" cy="26" rx="14" ry="3.5" fill="#fb9526" opacity="0.4" />
      <ellipse cx="24" cy="20" rx="14" ry="3.5" fill="#fb9526" opacity="0.9" />
    </g>,
  // exercise — pulse
  <g key="2">
      <path d="M6 24 L 16 24 L 20 14 L 26 34 L 30 20 L 36 24 L 42 24" stroke="#4c52dd" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" fill="none" />
    </g>,
  // mood — gentle waves
  <g key="3">
      <path d="M6 28 Q 14 20 22 28 T 42 28" stroke="#f53864" strokeWidth="1.8" fill="none" strokeLinecap="round" opacity="0.9" />
      <path d="M6 22 Q 14 14 22 22 T 42 22" stroke="#4c52dd" strokeWidth="1.8" fill="none" strokeLinecap="round" opacity="0.5" />
    </g>,
  // relationships — two overlapping circles
  <g key="4">
      <circle cx="18" cy="24" r="11" stroke="#4c52dd" strokeWidth="1.8" fill="#4c52dd" fillOpacity="0.05" />
      <circle cx="30" cy="24" r="11" stroke="#f53864" strokeWidth="1.8" fill="#f53864" fillOpacity="0.05" />
    </g>,
  // exams — three rising bars
  <g key="5">
      <rect x="10" y="28" width="6" height="10" rx="2" fill="#4c52dd" opacity="0.35" />
      <rect x="21" y="22" width="6" height="16" rx="2" fill="#4c52dd" opacity="0.65" />
      <rect x="32" y="14" width="6" height="24" rx="2" fill="#4c52dd" />
    </g>,
  // parenting — small + big circle
  <g key="6">
      <circle cx="20" cy="22" r="10" stroke="#4c52dd" strokeWidth="1.8" fill="none" />
      <circle cx="34" cy="30" r="5" fill="#fb9526" />
    </g>,
  // big questions — single dot with halo
  <g key="7">
      <circle cx="24" cy="24" r="18" stroke="#5b39c5" strokeWidth="1" fill="none" opacity="0.25" />
      <circle cx="24" cy="24" r="12" stroke="#5b39c5" strokeWidth="1" fill="none" opacity="0.4" />
      <circle cx="24" cy="24" r="4" fill="#5b39c5" />
    </g>];

  return (
    <div className={`inline-flex h-12 w-12 items-center justify-center rounded-tile bg-soft border border-line ${className}`}>
      <svg viewBox="0 0 48 48" width="32" height="32" aria-hidden="true">{variants[variant % variants.length]}</svg>
    </div>);

};

/* ----------------------------------------------------------------
   Hover micro-interaction helper.
   Plays a looping WAAPI animation while `card` is hovered/focused.
   On hover-in: eases playback up to full speed.
   On hover-out: instead of freezing mid-motion, it smoothly carries
   the animation FORWARD to its next resting frame (an iteration
   boundary, where the element sits at its default state) and only
   then pauses — so every hover animation resets cleanly.
   Respects prefers-reduced-motion (stays at the resting frame).
   Returns a cleanup function.
------------------------------------------------------------------- */
function attachHoverLoop(el, card, keyframes, timing) {
  if (!el) return () => {};
  const reduce = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  const D = timing.duration;
  const anim = el.animate(keyframes, { ...timing, iterations: Infinity, easing: "linear" });
  anim.pause();
  if (reduce || !card) return () => anim.cancel();

  let raf = null,last = null;
  let mode = "idle"; // 'in' | 'out' | 'idle'
  let settleFrom = 0,settleTarget = 0,settleElapsed = 0,settleDur = 1;
  const easeOut = (p) => 1 - Math.pow(1 - p, 3);

  const loop = (t) => {
    if (last == null) last = t;
    const dt = (t - last) / 1000;
    last = t;

    if (mode === "in") {
      let r = anim.playbackRate;
      r += (1 - r) * Math.min(1, dt * 4.5); // ease up to speed
      if (1 - r < 0.012) r = 1;
      anim.playbackRate = r;
      if (anim.playState !== "running") anim.play();
      raf = requestAnimationFrame(loop);
    } else if (mode === "out") {
      // drive currentTime manually toward the next resting frame
      settleElapsed += dt * 1000;
      const p = Math.min(1, settleElapsed / settleDur);
      anim.currentTime = settleFrom + (settleTarget - settleFrom) * easeOut(p);
      if (p >= 1) {anim.currentTime = settleTarget;anim.pause();mode = "idle";raf = null;last = null;return;}
      raf = requestAnimationFrame(loop);
    } else {
      raf = null;last = null;
    }
  };
  const kick = () => {if (!raf) {last = null;raf = requestAnimationFrame(loop);}};

  const start = () => {mode = "in";if (anim.playState !== "running") anim.play();kick();};
  const stop = () => {
    const c = anim.currentTime || 0;
    settleFrom = c;
    settleTarget = Math.ceil((c + 0.001) / D) * D; // next iteration boundary = resting frame
    settleElapsed = 0;
    settleDur = Math.min(650, settleTarget - c + 120); // proportional, capped, snappy
    anim.pause(); // we drive currentTime ourselves now
    anim.playbackRate = 1;
    mode = "out";
    kick();
  };

  card.addEventListener("mouseenter", start);
  card.addEventListener("mouseleave", stop);
  card.addEventListener("focusin", start);
  card.addEventListener("focusout", stop);
  return () => {
    card.removeEventListener("mouseenter", start);
    card.removeEventListener("mouseleave", stop);
    card.removeEventListener("focusin", start);
    card.removeEventListener("focusout", stop);
    if (raf) cancelAnimationFrame(raf);
    anim.cancel();
  };
}

Object.assign(window, { Container, Section, SectionHeading, Kicker, Button, Chip, AppStoreBadge, Keyline, SeasonGlyph, attachHoverLoop });