// ESacademy — Variation A, part 2: pillars, timeline, testimonials, final CTA, footer

const {
  ANav, AHero, AResonance, AFit, AJourney, AStart,
  A_PALETTE, AKicker, AButton, ASection, ANumeral,
} = window.EsaVariationA;

const BpContext = window.BpContext;
const C2 = window.ESA_CONTENT;

function ACosmicTunnel() {
  const bp = React.useContext(BpContext);
  const isMobile = bp === 'mobile';
  const isTablet = bp === 'tablet';
  const sectionRef = React.useRef(null);
  const canvasRef = React.useRef(null);
  const textRef = React.useRef(null);
  const scrollProgressRef = React.useRef(0);
  const isInViewRef = React.useRef(false);
  const frameRef = React.useRef(null);
  const timeRef = React.useRef(0);

  React.useEffect(() => {
    const root = document.getElementById('esa-a-root');
    const onScroll = () => {
      const section = sectionRef.current;
      if (!section) return;
      const rect = section.getBoundingClientRect();
      const totalScroll = section.offsetHeight - window.innerHeight;
      const p = Math.max(0, Math.min(1, -rect.top / totalScroll));
      scrollProgressRef.current = p;
      if (textRef.current) {
        let tOp = 0;
        if (p < 0.25) tOp = p / 0.25;
        else if (p < 0.62) tOp = 1;
        else if (p < 0.85) tOp = 1 - (p - 0.62) / 0.23;
        textRef.current.style.opacity = Math.max(0, Math.min(1, tOp));
      }
    };
    const target = root || window;
    target.addEventListener('scroll', onScroll, { passive: true });
    return () => target.removeEventListener('scroll', onScroll);
  }, []);

  React.useEffect(() => {
    const section = sectionRef.current;
    if (!section) return;
    const io = new IntersectionObserver(
      (entries) => { isInViewRef.current = entries[0].isIntersecting; },
      { threshold: 0 }
    );
    io.observe(section);
    return () => io.disconnect();
  }, []);

  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const resize = () => {
      canvas.width = canvas.offsetWidth;
      canvas.height = canvas.offsetHeight;
    };
    resize();
    window.addEventListener('resize', resize);
    return () => window.removeEventListener('resize', resize);
  }, []);

  React.useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');

    const NUM_RINGS = 14;
    const rings = Array.from({ length: NUM_RINGS }, (_, i) => ({
      r: i / NUM_RINGS,
      baseSpeed: 0.002 + (i % 5) * 0.0005,
      isGold: i % 3 === 0,
    }));

    const NUM_PARTICLES = 70;
    const particles = Array.from({ length: NUM_PARTICLES }, () => ({
      angle: Math.random() * Math.PI * 2,
      speed: 0.0018 + Math.random() * 0.0042,
      r: Math.random(),
      size: 0.8 + Math.random() * 2.4,
      isGold: Math.random() < 0.38,
    }));

    const draw = () => {
      if (!isInViewRef.current) {
        frameRef.current = requestAnimationFrame(draw);
        return;
      }
      const W = canvas.width, H = canvas.height;
      if (!W || !H) { frameRef.current = requestAnimationFrame(draw); return; }

      timeRef.current += 0.014;
      const t = timeRef.current;
      const cx = W / 2, cy = H / 2;
      const maxR = Math.sqrt(cx * cx + cy * cy) * 1.15;
      const p = scrollProgressRef.current;
      // Bell curve: 0 at start/end, peak=1 at p=0.5
      const ep = Math.sin(p * Math.PI);

      // Background with subtle motion-blur trail
      ctx.fillStyle = 'rgba(5,9,5,0.92)';
      ctx.fillRect(0, 0, W, H);

      // GOD RAYS — light bursting from center
      if (ep > 0.04) {
        const numRays = 48;
        for (let i = 0; i < numRays; i++) {
          const angle = (i / numRays) * Math.PI * 2 + t * 0.022;
          const cos = Math.cos(angle), sin = Math.sin(angle);
          const isPrimary = i % 6 === 0;
          const rayLen = maxR * (isPrimary ? 1.0 : 0.6) * Math.min(ep * 2, 1);
          const alpha = ep * (isPrimary ? 0.16 : 0.06);
          const grad = ctx.createLinearGradient(cx, cy, cx + cos * rayLen, cy + sin * rayLen);
          grad.addColorStop(0, `rgba(255,248,200,${alpha * 2.5})`);
          grad.addColorStop(0.2, `rgba(215,175,80,${alpha * 1.3})`);
          grad.addColorStop(1, 'rgba(80,55,10,0)');
          ctx.beginPath();
          ctx.moveTo(cx, cy);
          ctx.lineTo(cx + cos * rayLen, cy + sin * rayLen);
          ctx.strokeStyle = grad;
          ctx.globalAlpha = 1;
          ctx.lineWidth = isPrimary ? 6 + ep * 5 : 1.5 + ep;
          ctx.stroke();
        }
      }

      // EXPANDING RINGS
      const speedMult = 1 + ep * 5;
      ctx.globalAlpha = 1;
      for (let i = 0; i < rings.length; i++) {
        const ring = rings[i];
        ring.r += ring.baseSpeed * speedMult;
        if (ring.r > 1.05) ring.r = 0;
        const r = ring.r * maxR;
        const fadeA = Math.max(0, 1 - ring.r);
        ctx.beginPath();
        ctx.arc(cx, cy, r, 0, Math.PI * 2);
        ctx.strokeStyle = ring.isGold ? '#d4b86a' : '#6aaa90';
        ctx.globalAlpha = fadeA * (ring.isGold ? 0.5 + ep * 0.35 : 0.2 + ep * 0.2);
        ctx.lineWidth = ring.isGold ? 1.4 : 0.7;
        ctx.stroke();
      }

      // PARTICLES flying outward
      ctx.globalAlpha = 1;
      for (let i = 0; i < particles.length; i++) {
        const pt = particles[i];
        pt.r += pt.speed * speedMult;
        if (pt.r > 1.05) pt.r = 0;
        const dist = pt.r * maxR;
        const x = cx + Math.cos(pt.angle) * dist;
        const y = cy + Math.sin(pt.angle) * dist;
        ctx.beginPath();
        ctx.arc(x, y, pt.size * (1 + ep * 0.6), 0, Math.PI * 2);
        ctx.fillStyle = pt.isGold ? '#f0d070' : '#70c0b0';
        ctx.globalAlpha = Math.max(0, 1 - pt.r) * (0.3 + ep * 0.6);
        ctx.fill();
      }
      ctx.globalAlpha = 1;

      // CORE GLOW — divine illumination blast
      const coreR = Math.max(1, (100 + ep * 320) * (Math.min(W, H) / 1000));
      const coreA = 0.2 + ep * 0.72;
      const coreGrd = ctx.createRadialGradient(cx, cy, 0, cx, cy, coreR);
      coreGrd.addColorStop(0, `rgba(255,254,240,${coreA})`);
      coreGrd.addColorStop(0.05, `rgba(255,245,170,${coreA * 0.92})`);
      coreGrd.addColorStop(0.15, `rgba(220,178,75,${coreA * 0.65})`);
      coreGrd.addColorStop(0.4, `rgba(50,80,65,${ep * 0.1})`);
      coreGrd.addColorStop(1, 'rgba(0,0,0,0)');
      ctx.fillStyle = coreGrd;
      ctx.fillRect(0, 0, W, H);

      // PULSE FLASH at peak — divine light pulse
      if (ep > 0.6) {
        const pulse = (Math.sin(t * 4) * 0.5 + 0.5) * ((ep - 0.6) / 0.4);
        ctx.fillStyle = `rgba(255,250,220,${pulse * 0.24})`;
        ctx.globalAlpha = 1;
        ctx.fillRect(0, 0, W, H);
      }

      // CENTRAL STAR
      const starR = 3 + ep * 6;
      const starGrd = ctx.createRadialGradient(cx, cy, 0, cx, cy, starR * 4);
      starGrd.addColorStop(0, 'rgba(255,255,245,1)');
      starGrd.addColorStop(0.2, `rgba(255,240,160,${0.7 + ep * 0.3})`);
      starGrd.addColorStop(1, 'rgba(180,140,40,0)');
      ctx.globalAlpha = 1;
      ctx.fillStyle = starGrd;
      ctx.beginPath();
      ctx.arc(cx, cy, starR * 4, 0, Math.PI * 2);
      ctx.fill();

      frameRef.current = requestAnimationFrame(draw);
    };

    frameRef.current = requestAnimationFrame(draw);
    return () => cancelAnimationFrame(frameRef.current);
  }, []);

  const sectionH = isMobile ? '150vh' : isTablet ? '200vh' : '250vh';

  return (
    <section ref={sectionRef} style={{ height: sectionH, position: 'relative' }}>
      <div style={{ position: 'sticky', top: 0, height: '100vh', overflow: 'hidden' }}>
        <canvas ref={canvasRef} style={{ width: '100%', height: '100%', display: 'block' }} />
        <div ref={textRef} style={{
          position: 'absolute', inset: 0,
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          pointerEvents: 'none', opacity: 0,
        }}>
          <div style={{ textAlign: 'center' }}>
            <div style={{
              fontSize: 11, letterSpacing: '0.3em', textTransform: 'uppercase',
              color: 'rgba(244,241,234,0.5)', marginBottom: 22, fontWeight: 500,
            }}>על סף השינוי</div>
            <div style={{
              fontFamily: '"Cormorant Garamond", Georgia, serif',
              fontStyle: 'italic',
              fontSize: isMobile ? 40 : 66,
              color: '#ffe898',
              lineHeight: 1.06,
              letterSpacing: '-0.01em',
              textShadow: '0 0 60px rgba(255,218,80,0.7), 0 0 120px rgba(255,200,60,0.4)',
            }}>המסע מתחיל כאן</div>
          </div>
        </div>
        <div aria-hidden="true" style={{
          position: 'absolute', bottom: 0, left: 0, right: 0, height: '35%',
          background: `linear-gradient(to bottom, transparent 0%, ${A_PALETTE.bg} 100%)`,
          pointerEvents: 'none',
        }} />
      </div>
    </section>
  );
}

function AFloatingCompanion() {
  const bp = React.useContext(BpContext);
  const wrapperRef = React.useRef(null);
  const size = bp === 'desktop' ? 130 : bp === 'tablet' ? 95 : 72;

  React.useEffect(() => {
    const root = document.getElementById('esa-a-root');
    const half = size / 2;

    const update = () => {
      if (!wrapperRef.current) return;
      const st = root ? root.scrollTop : window.scrollY;
      const total = root
        ? root.scrollHeight - root.clientHeight
        : document.body.scrollHeight - window.innerHeight;

      const heroH = window.innerHeight;

      if (st < heroH * 0.5) {
        wrapperRef.current.style.opacity = '0';
        return;
      }

      const journeyEl = document.getElementById('esa-journey');
      if (journeyEl) {
        const jr = journeyEl.getBoundingClientRect();
        if (jr.top < window.innerHeight && jr.bottom > 0) {
          wrapperRef.current.style.opacity = '0';
          return;
        }
      }

      const fadeIn = Math.min(1, (st - heroH * 0.5) / (heroH * 0.4));
      wrapperRef.current.style.opacity = String(fadeIn);

      const companionP = Math.min(1, Math.max(0, (st - heroH * 0.5) / (total - heroH * 0.5)));

      const xVw = 50 + Math.cos(companionP * Math.PI * 5) * 30;
      const yVh = 80 - companionP * 72;

      const xPx = window.innerWidth * xVw / 100 - half;
      const yPx = window.innerHeight * yVh / 100 - half;
      wrapperRef.current.style.transform = `translate(${xPx}px, ${yPx}px)`;
    };

    update();

    const target = root || window;
    target.addEventListener('scroll', update, { passive: true });
    return () => target.removeEventListener('scroll', update);
  }, [bp, size]);

  return (
    <div ref={wrapperRef} style={{
      position: 'fixed',
      left: 0,
      top: 0,
      width: size,
      height: size,
      pointerEvents: 'none',
      zIndex: 8,
      opacity: 0,
      transition: 'transform 0.55s cubic-bezier(0.25, 0.46, 0.45, 0.94), opacity 0.6s ease',
    }}>
      <div style={{ width: '100%', height: '100%', animation: 'esa-float 8s ease-in-out infinite' }}>
        <img
          src="hero-visual.png?v=4"
          alt="" aria-hidden="true"
          style={{
            width: '100%', height: '100%',
            objectFit: 'cover', objectPosition: 'center 28%',
            borderRadius: '50%',
            mixBlendMode: 'multiply',
            opacity: 0.58,
            WebkitMaskImage: 'radial-gradient(circle at center, #000 45%, rgba(0,0,0,0.5) 72%, transparent 100%)',
            maskImage: 'radial-gradient(circle at center, #000 45%, rgba(0,0,0,0.5) 72%, transparent 100%)',
            filter: 'contrast(1.08) saturate(1.15)',
            userSelect: 'none', pointerEvents: 'none',
          }}
        />
      </div>
    </div>
  );
}

function APillars() {
  const bp = React.useContext(BpContext);
  const isMobile = bp === 'mobile';
  const isTablet = bp === 'tablet';

  return (
    <>
      {C2.pillars.map((p, idx) => {
        const dark = idx % 2 === 1;
        const reversed = !isMobile && !isTablet && idx % 2 === 1;

        const imageCol = (
          <Reveal>
            <div>
              <AKicker>סקשן 0{6 + idx} · {p.sub}</AKicker>
              <div style={{
                display: 'inline-block', padding: '6px 14px',
                background: A_PALETTE.gold, color: A_PALETTE.paper,
                fontSize: 12, letterSpacing: '0.1em', textTransform: 'uppercase',
                marginBottom: 28, fontWeight: 500,
              }}>{p.tag}</div>
              <h2 style={{
                fontSize: isMobile ? 40 : isTablet ? 52 : 64, fontWeight: 500, color: A_PALETTE.ink,
                margin: 0, letterSpacing: '-0.025em', lineHeight: 1.02,
              }}>{p.name}</h2>
              {p.subtitle && (
                <div style={{
                  marginTop: 18, fontSize: isMobile ? 18 : 22, fontWeight: 500,
                  color: A_PALETTE.accent, letterSpacing: '-0.005em', lineHeight: 1.3,
                }}>{p.subtitle}</div>
              )}
              {p.id === 'adam' ? (
                <div style={{ marginTop: 40, animation: 'esa-float 5s ease-in-out infinite' }}>
                  <img src="book-cover.png?v=4" alt="האדם - גרסה 2.0"
                    style={{ display: 'block', width: '100%', maxWidth: isMobile ? 260 : 380, height: 'auto', ...(isMobile && { marginLeft: 'auto', marginRight: 'auto' }) }} />
                </div>
              ) : p.id === '369' ? (
                <div style={{ marginTop: 40 }}>
                  <img src="369-journey.png?v=3" alt="מסע של 369 יום"
                    style={{ display: 'block', width: '100%', maxWidth: isMobile ? 300 : 540, height: 'auto', ...(isMobile && { marginLeft: 'auto', marginRight: 'auto' }) }} />
                </div>
              ) : p.id === 'compass' ? (
                <div style={{
                  marginTop: 44,
                  width: isMobile ? 200 : 280, height: isMobile ? 200 : 280,
                  display: 'grid', placeItems: 'center', position: 'relative',
                  ...(isMobile && { marginLeft: 'auto', marginRight: 'auto' }),
                }}>
                  <div style={{
                    position: 'absolute', inset: 0, borderRadius: '50%',
                    background: `radial-gradient(circle at center, ${A_PALETTE.accent}1f 0%, ${A_PALETTE.accent}10 45%, transparent 72%)`,
                    pointerEvents: 'none',
                  }} />
                  <div style={{ width: isMobile ? 164 : 244, height: isMobile ? 164 : 244, position: 'relative' }}>
                    <PillarGlyph id={p.id} />
                  </div>
                </div>
              ) : (
                <div style={{ marginTop: 48, width: isMobile ? 160 : 220, height: isMobile ? 160 : 220, ...(isMobile && { marginLeft: 'auto', marginRight: 'auto' }) }}>
                  <PillarGlyph id={p.id} />
                </div>
              )}
            </div>
          </Reveal>
        );

        const textCol = (
          <Reveal delay={0.15} style={{ paddingTop: isMobile ? 0 : 60 }}>
            <h3 style={{
              fontSize: isMobile ? 22 : 32, fontWeight: 500, color: A_PALETTE.ink,
              margin: '0 0 24px', lineHeight: 1.25, letterSpacing: '-0.015em',
            }}>{p.title}</h3>
            <p style={{
              fontSize: isMobile ? 16 : 19, lineHeight: 1.7, color: A_PALETTE.inkSoft,
              margin: '0 0 36px', maxWidth: 600, whiteSpace: 'pre-line',
            }}>{p.body}</p>
            <a href={p.id === 'adam' ? '/adam-2.0.html' : p.id === '369' ? '/369' : '#'} style={{textDecoration:'none'}}><AButton primary>{p.cta}</AButton></a>
          </Reveal>
        );

        return (
          <ASection key={p.id} bg={dark
            ? `radial-gradient(ellipse at 80% 10%, rgba(122,106,58,0.06) 0%, ${A_PALETTE.bgAlt} 65%)`
            : `radial-gradient(ellipse at 20% 10%, rgba(122,106,58,0.05) 0%, ${A_PALETTE.bg} 65%)`
          } id={p.id}>
            <div style={{
              display: 'grid',
              gridTemplateColumns: isMobile || isTablet ? '1fr' : reversed ? '7fr 5fr' : '5fr 7fr',
              gap: isMobile ? 40 : isTablet ? 48 : 80,
              alignItems: 'center',
            }}>
              {reversed ? <>{textCol}{imageCol}</> : <>{imageCol}{textCol}</>}
            </div>
          </ASection>
        );
      })}
    </>
  );
}

function PillarGlyph({ id }) {
  const [glyphRef, glyphVisible] = useScrollReveal({ threshold: 0.2 });
  const [needleAngle, setNeedleAngle] = React.useState(0);
  const stroke = A_PALETTE.accent;
  const common = { fill: 'none', stroke, strokeWidth: 1 };

  React.useEffect(() => {
    if (id !== 'compass') return;
    const onMove = (e) => {
      const el = glyphRef.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      const cx = rect.left + rect.width / 2;
      const cy = rect.top + rect.height / 2;
      setNeedleAngle(Math.atan2(e.clientY - cy, e.clientX - cx) * 180 / Math.PI + 90);
    };
    window.addEventListener('mousemove', onMove, { passive: true });
    return () => window.removeEventListener('mousemove', onMove);
  }, [id]);

  const svgStyle = {
    width: '100%', height: '100%',
    opacity: glyphVisible ? 1 : 0,
    transform: glyphVisible ? 'scale(1)' : 'scale(0.88)',
    transition: 'opacity 0.9s ease, transform 0.9s cubic-bezier(0.22,0.61,0.36,1)',
  };

  if (id === 'adam') {
    return (
      <svg ref={glyphRef} viewBox="0 0 220 220" style={svgStyle}>
        {[0, 20, 40, 60, 80].map((o, i) => (
          <rect key={o} x={30 + o} y={30 + o} width={160 - o * 2} height={160 - o * 2}
            {...common} strokeOpacity={0.7 - o / 150}
            style={{ transition: `opacity 0.6s ease ${i * 0.12}s` }}
          />
        ))}
        <circle cx="110" cy="110" r="4" fill={stroke} />
      </svg>
    );
  }
  if (id === '369') {
    return (
      <svg ref={glyphRef} viewBox="0 0 220 220" style={svgStyle}>
        {[0, 1, 2, 3, 4, 5].map(i => (
          <g key={i}>
            <line x1={30} y1={40 + i * 28} x2={190} y2={40 + i * 28} {...common} strokeOpacity={0.3 + i * 0.1} />
            <circle cx={i % 2 === 0 ? 60 + i * 14 : 140 - i * 8} cy={40 + i * 28}
              r={i === 5 ? 6 : 3} fill={stroke} />
          </g>
        ))}
      </svg>
    );
  }
  if (id === 'compass') {
    return (
      <svg ref={glyphRef} viewBox="0 0 220 220" style={svgStyle}>
        <circle cx="110" cy="110" r="80" {...common} strokeOpacity={0.5} />
        <circle cx="110" cy="110" r="60" {...common} strokeOpacity={0.3} strokeDasharray="2 4" />
        <circle cx="110" cy="110" r="40" {...common} strokeOpacity={0.4} />
        {[0, 45, 90, 135, 180, 225, 270, 315].map(deg => (
          <line key={deg} x1="110" y1="110" x2="110" y2="30" {...common}
            strokeOpacity={deg % 90 === 0 ? 0.9 : 0.3}
            transform={`rotate(${deg} 110 110)`} />
        ))}
        <g transform={`rotate(${needleAngle} 110 110)`} style={{ transition: 'transform 0.18s ease' }}>
          <polygon points="110,30 104,70 116,70" fill={stroke} />
          <polygon points="110,190 104,150 116,150" fill={stroke} fillOpacity={0.3} />
        </g>
        <circle cx="110" cy="110" r="5" fill={stroke} />
      </svg>
    );
  }
  return (
    <svg ref={glyphRef} viewBox="0 0 220 220" style={svgStyle}>
      <line x1="110" y1="14" x2="110" y2="206" {...common} strokeOpacity={0.65} />
      <line x1="36" y1="110" x2="184" y2="110" {...common} strokeOpacity={0.18} strokeDasharray="2 4" />
      {[
        { y: 130, len: 30, drop: 22 },
        { y: 152, len: 46, drop: 26 },
        { y: 174, len: 60, drop: 22 },
        { y: 192, len: 38, drop: 12 },
      ].map((r, i) => (
        <g key={'r' + i} strokeOpacity={0.55 - i * 0.05}>
          <path d={`M110 ${r.y} Q ${110 - r.len * 0.5} ${r.y + r.drop * 0.5} ${110 - r.len} ${r.y + r.drop}`} {...common} />
          <path d={`M110 ${r.y} Q ${110 + r.len * 0.5} ${r.y + r.drop * 0.5} ${110 + r.len} ${r.y + r.drop}`} {...common} />
        </g>
      ))}
      <circle cx="110" cy="206" r="2.5" fill={stroke} fillOpacity={0.6} />
      {[
        { y: 90, len: 30, rise: 20 },
        { y: 68, len: 50, rise: 26 },
        { y: 44, len: 68, rise: 24 },
        { y: 22, len: 46, rise: 12 },
      ].map((w, i) => (
        <g key={'w' + i} strokeOpacity={0.6 - i * 0.05}>
          <path d={`M110 ${w.y} Q ${110 - w.len * 0.5} ${w.y - w.rise * 0.5} ${110 - w.len} ${w.y - w.rise}`} {...common} />
          <path d={`M110 ${w.y} Q ${110 + w.len * 0.5} ${w.y - w.rise * 0.5} ${110 + w.len} ${w.y - w.rise}`} {...common} />
        </g>
      ))}
      <circle cx="110" cy="110" r="6" fill="none" stroke={stroke} strokeWidth="1" strokeOpacity={0.5} />
      <circle cx="110" cy="110" r="3" fill={stroke} />
      <circle cx="110" cy="14" r="2" fill={stroke} fillOpacity={0.7} />
    </svg>
  );
}

// ──────────────────── TIMELINE ────────────────────
function ATimeline() {
  const bp = React.useContext(BpContext);
  const isMobile = bp === 'mobile';
  const isTablet = bp === 'tablet';
  const t = C2.timeline;
  const [lineRef, lineProgress] = useScrollProgress();
  const gridCols = isMobile ? '1fr' : isTablet ? 'repeat(2, 1fr)' : 'repeat(4, 1fr)';
  const hPad = isMobile ? 20 : isTablet ? 32 : 64;

  return (
    <section id="timeline" style={{
      background: A_PALETTE.bgWarm,
      padding: `${isMobile ? 80 : 200}px ${hPad}px ${isMobile ? 64 : 160}px`,
      position: 'relative',
    }}>
      <div style={{
        position: 'absolute', top: 0, left: '50%', transform: 'translateX(-50%)',
        width: 'min(1240px, calc(100% - 40px))',
        height: 1, background: A_PALETTE.rule, opacity: 0.35,
      }} />
      <div style={{ maxWidth: 1240, margin: '0 auto' }}>
        <Reveal style={{ textAlign: 'center', marginBottom: isMobile ? 56 : 100 }}>
          <AKicker>{t.kicker}</AKicker>
          <h2 style={{
            fontSize: isMobile ? 36 : 64, fontWeight: 500, color: A_PALETTE.ink,
            margin: 0, letterSpacing: '-0.025em', lineHeight: 1.05,
          }}>
            זה לא ריצה.{' '}
            <span style={{
              fontFamily: '"Cormorant Garamond", Georgia, serif',
              fontStyle: 'italic', color: A_PALETTE.accent,
            }}>זה מסע.</span>
          </h2>
        </Reveal>

        <div ref={lineRef} style={{ position: 'relative', padding: '40px 0 20px' }}>
          {!isMobile && !isTablet && (
            <>
              <div style={{
                position: 'absolute', top: 79, right: '6%', left: '6%',
                height: 2, background: A_PALETTE.rule, opacity: 0.4,
              }} />
              <div style={{
                position: 'absolute', top: 79, right: '6%',
                width: `${lineProgress * 88}%`,
                height: 2,
                background: A_PALETTE.accent,
                opacity: 0.85,
                transition: 'width 0.8s cubic-bezier(0.22,0.61,0.36,1)',
              }} />
            </>
          )}
          {isMobile && (
            <>
              <div style={{
                position: 'absolute', top: 40, bottom: 20, right: 11,
                width: 1.5, background: A_PALETTE.rule, opacity: 0.4, zIndex: 0,
              }} />
              <div style={{
                position: 'absolute', top: 40, right: 11,
                width: 1.5,
                height: `calc((100% - 60px) * ${lineProgress})`,
                background: A_PALETTE.accent, opacity: 0.85,
                transition: 'height 0.8s cubic-bezier(0.22,0.61,0.36,1)',
                zIndex: 0,
              }} />
            </>
          )}

          <div style={{ display: 'grid', gridTemplateColumns: gridCols, gap: isMobile ? 40 : 24 }}>
            {t.stations.map((st, i) => (
              <Reveal key={st.n} delay={i * 0.1}>
                <div style={{
                  display: 'flex',
                  flexDirection: isMobile ? 'row' : 'column',
                  alignItems: isMobile ? 'flex-start' : 'center',
                  textAlign: isMobile ? 'right' : 'center',
                  gap: isMobile ? 20 : 0,
                }}>
                  <div style={{
                    width: 24, height: 24, borderRadius: '50%',
                    background: A_PALETTE.bgWarm,
                    border: `1.5px solid ${A_PALETTE.accent}`,
                    position: 'relative', zIndex: 2,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    marginBottom: isMobile ? 0 : 40,
                    flexShrink: 0,
                    position: 'relative', zIndex: 2,
                    transform: lineProgress > i / 4 ? 'scale(1.25)' : 'scale(1)',
                    transition: 'transform 0.4s cubic-bezier(0.22,0.61,0.36,1)',
                  }}>
                    <div style={{ width: 8, height: 8, borderRadius: '50%', background: A_PALETTE.accent }} />
                  </div>
                  <div>
                    <div style={{
                      fontFamily: '"Cormorant Garamond", Georgia, serif',
                      fontStyle: 'italic', fontSize: 20, color: A_PALETTE.muted, marginBottom: 10,
                    }}>תחנה {st.n}</div>
                    <div style={{
                      fontSize: isMobile ? 22 : 28, fontWeight: 500, color: A_PALETTE.ink,
                      marginBottom: 10, letterSpacing: '-0.015em',
                    }}>{st.state}</div>
                    <div style={{
                      fontSize: 15, color: A_PALETTE.inkSoft, lineHeight: 1.6, maxWidth: isMobile ? '100%' : 220,
                    }}>{st.body}</div>
                  </div>
                </div>
              </Reveal>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

// ──────────────────── TESTIMONIALS ────────────────────
function ATestimonials() {
  const bp = React.useContext(BpContext);
  const isMobile = bp === 'mobile';
  const isTablet = bp === 'tablet';
  const t = C2.testimonials;
  const trackRef = React.useRef(null);
  const posRef = React.useRef(0);
  const pausedRef = React.useRef(false);
  const cardWidth = isMobile ? 280 : isTablet ? 320 : 400;
  const gap = 16;
  const items = [...t.items, ...t.items];
  const oneSetWidth = t.items.length * (cardWidth + gap);

  React.useEffect(() => {
    let raf;
    const step = () => {
      if (!pausedRef.current) {
        posRef.current += 0.5;
        if (posRef.current >= oneSetWidth) posRef.current -= oneSetWidth;
        if (trackRef.current) {
          trackRef.current.style.transform = `translateX(${-posRef.current}px)`;
        }
      }
      raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [oneSetWidth]);

  return (
    <div style={{ overflow: 'hidden' }}>
    <ASection>
      <Reveal style={{ marginBottom: 64 }}>
        <div style={{ textAlign: 'center' }}>
          <AKicker>{t.kicker}</AKicker>
          <h2 style={{
            fontSize: isMobile ? 36 : 56, fontWeight: 500, color: A_PALETTE.ink,
            margin: 0, letterSpacing: '-0.025em', lineHeight: 1.05,
          }}>{t.title}</h2>
        </div>
      </Reveal>

      <div
        style={{ overflow: 'hidden', margin: `0 ${isMobile ? -20 : isTablet ? -32 : -64}px` }}
        onMouseEnter={() => { pausedRef.current = true; }}
        onMouseLeave={() => { pausedRef.current = false; }}
      >
        <div
          ref={trackRef}
          style={{ display: 'flex', gap, willChange: 'transform' }}
        >
          {items.map((item, i) => (
            <div key={i} style={{
              flexShrink: 0,
              width: cardWidth,
              padding: isMobile ? '28px 24px 24px' : '40px 36px 36px',
              background: i % 2 === 0 ? A_PALETTE.paper : A_PALETTE.bgAlt,
              border: `1px solid ${A_PALETTE.rule}`,
              boxShadow: '0 2px 20px rgba(31,42,36,0.07)',
              display: 'flex', flexDirection: 'column', gap: 16,
            }}>
              <div style={{
                fontFamily: '"Cormorant Garamond", Georgia, serif',
                fontSize: isMobile ? 60 : 80, color: A_PALETTE.gold,
                lineHeight: 0.7, marginBottom: 4, opacity: 0.85,
              }}>"</div>
              <p style={{
                fontSize: isMobile ? 15 : 17, lineHeight: 1.65, color: A_PALETTE.ink,
                margin: 0, flex: 1,
              }}>{item.quote}</p>
              <div style={{
                display: 'flex', alignItems: 'center', gap: 12,
                paddingTop: 16, borderTop: `1px solid ${A_PALETTE.rule}`,
              }}>
                <span style={{ width: 20, height: 1, background: A_PALETTE.accent, flexShrink: 0 }} />
                <span style={{ fontSize: 14, fontWeight: 500, color: A_PALETTE.ink }}>{item.name}</span>
                <span style={{
                  fontFamily: '"Cormorant Garamond", Georgia, serif',
                  fontStyle: 'italic', fontSize: 14, color: A_PALETTE.muted,
                }}>· גיל {item.age} · {item.city}</span>
              </div>
            </div>
          ))}
        </div>
      </div>
    </ASection>
    </div>
  );
}

// ──────────────────── FINAL CTA ────────────────────
function AFinalCta() {
  const bp = React.useContext(BpContext);
  const isMobile = bp === 'mobile';
  const f = C2.finalCta;
  const [auraRef, auraPos] = useCursorAura();

  return (
    <div style={{ overflow: 'hidden' }}>
    <ASection bg={A_PALETTE.ink} tall>
      <div ref={auraRef} style={{ position: 'relative', textAlign: 'center', maxWidth: 820, margin: '0 auto' }}>
        <div aria-hidden="true" style={{
          position: 'absolute', inset: -80, pointerEvents: 'none', zIndex: 0,
          background: `radial-gradient(circle 260px at ${auraPos.x}px ${auraPos.y}px, rgba(91,122,106,0.18) 0%, transparent 70%)`,
          opacity: auraPos.on ? 1 : 0,
          transition: 'opacity 0.4s ease',
        }} />

        <div style={{ position: 'relative', zIndex: 1 }}>
          <Reveal>
            <div style={{
              fontSize: 13, letterSpacing: '0.22em', color: 'rgba(244,241,234,0.5)',
              textTransform: 'uppercase', marginBottom: 24,
            }}>{f.kicker}</div>
            <h2 style={{
              fontSize: isMobile ? 'clamp(32px, 8vw, 48px)' : 'clamp(48px, 5.5vw, 76px)',
              fontWeight: 500,
              color: A_PALETTE.bg, margin: '0 0 32px',
              letterSpacing: '-0.025em', lineHeight: 1.08,
            }}>
              אתה לא צריך לפתור את כל החיים שלך{' '}
              <span style={{
                fontFamily: '"Cormorant Garamond", Georgia, serif',
                fontStyle: 'italic', color: A_PALETTE.accentSoft,
              }}>היום.</span>
              <br />
              אתה רק צריך להתחיל{' '}
              <span style={{
                fontFamily: '"Cormorant Garamond", Georgia, serif',
                fontStyle: 'italic', color: A_PALETTE.accentSoft,
              }}>נכון.</span>
            </h2>
          </Reveal>

          <Reveal delay={0.12}>
            <p style={{
              fontSize: isMobile ? 17 : 20, lineHeight: 1.65,
              color: 'rgba(244,241,234,0.75)',
              margin: '0 0 48px', maxWidth: 640, marginInline: 'auto',
            }}>{f.body}</p>
            <div style={{
              display: 'flex', gap: 16,
              justifyContent: 'center',
              flexWrap: 'wrap',
              flexDirection: isMobile ? 'column' : 'row',
              alignItems: 'center',
            }}>
              <button onClick={() => document.getElementById('start')?.scrollIntoView({behavior:'smooth'})} style={{
                padding: isMobile ? '16px 28px' : '20px 38px',
                background: A_PALETTE.bg, color: A_PALETTE.ink,
                border: 'none', fontSize: isMobile ? 15 : 16, fontWeight: 500, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 14, fontFamily: 'inherit',
                width: isMobile ? '100%' : 'auto', justifyContent: 'center',
              }}>{f.primary} <span>←</span></button>
              <button onClick={() => document.getElementById('start')?.scrollIntoView({behavior:'smooth'})} style={{
                padding: isMobile ? '16px 28px' : '20px 38px',
                background: 'transparent', color: A_PALETTE.bg,
                border: `1px solid rgba(244,241,234,0.3)`,
                fontSize: isMobile ? 15 : 16, fontWeight: 500, cursor: 'pointer',
                display: 'inline-flex', alignItems: 'center', gap: 14, fontFamily: 'inherit',
                width: isMobile ? '100%' : 'auto', justifyContent: 'center',
              }}>{f.secondary} <span>←</span></button>
            </div>
          </Reveal>
        </div>
      </div>
    </ASection>
    </div>
  );
}

// ──────────────────── FOOTER ────────────────────
function AFooter() {
  const bp = React.useContext(BpContext);
  const isMobile = bp === 'mobile';
  const isTablet = bp === 'tablet';
  const f = C2.footer;
  const hPad = isMobile ? 20 : isTablet ? 32 : 64;

  return (
    <footer style={{
      background: A_PALETTE.bg,
      padding: `${isMobile ? 48 : 80}px ${hPad}px 40px`,
      borderTop: `1px solid ${A_PALETTE.rule}`
    }}>
      <div style={{ maxWidth: 1240, margin: '0 auto' }}>
        <Reveal>
          <div style={{
            display: 'grid',
            gridTemplateColumns: isMobile || isTablet ? '1fr' : '2fr 3fr',
            gap: isMobile ? 40 : 80, marginBottom: 48
          }}>
            <div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 20 }}>
                <div style={{
                  width: 28, height: 28, borderRadius: '50%',
                  border: `1.5px solid ${A_PALETTE.ink}`, position: 'relative',
                }}>
                  <div style={{ position: 'absolute', inset: 6, borderRadius: '50%', background: A_PALETTE.accent }} />
                </div>
                <div style={{ fontSize: 20, fontWeight: 600, color: A_PALETTE.ink, letterSpacing: '0.04em' }}>ESacademy</div>
              </div>
              <p style={{
                fontSize: 18, lineHeight: 1.55, color: A_PALETTE.inkSoft,
                maxWidth: 420, margin: 0,
                fontFamily: '"Cormorant Garamond", Georgia, serif',
                fontStyle: 'italic', fontWeight: 400,
              }}>{f.tagline}</p>
            </div>
            <div style={{
              display: 'grid',
              gridTemplateColumns: isMobile ? 'repeat(2, 1fr)' : 'repeat(3, 1fr)',
              gap: 16, fontSize: 14, color: A_PALETTE.inkSoft,
            }}>
              {f.nav.map((n, i) => (
                <a key={i} style={{ color: 'inherit', textDecoration: 'none', cursor: 'pointer', padding: '4px 0' }}>{n}</a>
              ))}
            </div>
          </div>
        </Reveal>
        <div style={{
          paddingTop: 24, borderTop: `1px solid ${A_PALETTE.rule}`,
          display: 'flex',
          flexDirection: isMobile ? 'column' : 'row',
          justifyContent: 'space-between',
          gap: isMobile ? 8 : 0,
          fontSize: 12, color: A_PALETTE.muted,
          letterSpacing: '0.08em', textTransform: 'uppercase',
        }}>
          <span>© 2025 ESacademy · כל הזכויות שמורות</span>
          <span>נבנה עם כוונה</span>
        </div>
      </div>
    </footer>
  );
}

// Main exported page component
function AScrollTop() {
  const btnRef = React.useRef(null);

  React.useEffect(() => {
    const root = document.getElementById('esa-a-root');
    const target = root || window;
    const onScroll = () => {
      const st = root ? root.scrollTop : window.scrollY;
      if (!btnRef.current) return;
      const visible = st > 400;
      btnRef.current.style.opacity = visible ? '1' : '0';
      btnRef.current.style.pointerEvents = visible ? 'auto' : 'none';
      btnRef.current.style.transform = visible ? 'translateY(0)' : 'translateY(12px)';
    };
    target.addEventListener('scroll', onScroll, { passive: true });
    return () => target.removeEventListener('scroll', onScroll);
  }, []);

  const handleClick = () => {
    const root = document.getElementById('esa-a-root');
    (root || window).scrollTo({ top: 0, behavior: 'smooth' });
  };

  return (
    <button
      ref={btnRef}
      onClick={handleClick}
      aria-label="חזרה לראש הדף"
      style={{
        position: 'fixed', bottom: 28, right: 28,
        width: 50, height: 50,
        borderRadius: '50%',
        border: '2px solid rgba(244,241,234,0.18)',
        background: A_PALETTE.accent,
        color: A_PALETTE.bg,
        cursor: 'pointer',
        zIndex: 90,
        opacity: 0,
        pointerEvents: 'none',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        boxShadow: '0 4px 20px rgba(45,74,62,0.4)',
        transition: 'opacity 0.4s ease, transform 0.4s ease, background 0.2s ease',
      }}
      onMouseEnter={e => { e.currentTarget.style.background = '#3d6454'; e.currentTarget.style.transform = 'translateY(-3px)'; }}
      onMouseLeave={e => { e.currentTarget.style.background = A_PALETTE.accent; e.currentTarget.style.transform = 'translateY(0)'; }}
    >
      <svg width="18" height="18" viewBox="0 0 18 18" fill="none" aria-hidden="true">
        <path d="M9 14V4M4.5 8.5L9 4L13.5 8.5" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
    </button>
  );
}

function AAccessibility() {
  const [open, setOpen] = React.useState(false);
  const [textLevel, setTextLevel] = React.useState(0);
  const [hiContrast, setHiContrast] = React.useState(false);
  const wrapRef = React.useRef(null);

  React.useEffect(() => {
    const root = document.getElementById('esa-a-root');
    if (!root) return;
    const sizes = { '-1': '87%', '0': '', '1': '112%', '2': '125%' };
    root.style.fontSize = sizes[String(textLevel)] || '';
  }, [textLevel]);

  React.useEffect(() => {
    document.body.style.filter = hiContrast ? 'contrast(1.5) saturate(0.6)' : '';
    return () => { document.body.style.filter = ''; };
  }, [hiContrast]);

  React.useEffect(() => {
    if (!open) return;
    const handler = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false);
    };
    const t = setTimeout(() => document.addEventListener('click', handler), 0);
    return () => { clearTimeout(t); document.removeEventListener('click', handler); };
  }, [open]);

  const btnSt = {
    padding: '7px 12px', borderRadius: 8,
    border: `1px solid ${A_PALETTE.rule}`,
    background: A_PALETTE.paper, color: A_PALETTE.ink,
    cursor: 'pointer', fontSize: 13,
    fontFamily: 'Heebo, sans-serif',
    transition: 'background 0.15s',
  };

  return (
    <div ref={wrapRef} style={{ position: 'fixed', bottom: 28, left: 28, zIndex: 90 }}>
      {open && (
        <div style={{
          position: 'absolute', bottom: 62, left: 0,
          background: '#fff', borderRadius: 16,
          padding: '20px 22px',
          boxShadow: '0 8px 40px rgba(31,42,36,0.18)',
          minWidth: 230, direction: 'rtl',
          fontFamily: 'Heebo, sans-serif', color: A_PALETTE.ink,
        }}>
          <div style={{ fontWeight: 600, fontSize: 15, marginBottom: 18 }}>הגדרות נגישות</div>

          <div style={{ marginBottom: 16 }}>
            <div style={{ fontSize: 12, color: A_PALETTE.muted, marginBottom: 8 }}>גודל טקסט</div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button onClick={() => setTextLevel(l => Math.max(-1, l - 1))} style={btnSt}>א−</button>
              <button onClick={() => setTextLevel(0)} style={{ ...btnSt, flex: 1 }}>איפוס</button>
              <button onClick={() => setTextLevel(l => Math.min(2, l + 1))} style={btnSt}>א+</button>
            </div>
          </div>

          <div style={{ marginBottom: 16 }}>
            <button
              onClick={() => setHiContrast(v => !v)}
              style={{
                ...btnSt, width: '100%',
                background: hiContrast ? A_PALETTE.accent : A_PALETTE.paper,
                color: hiContrast ? A_PALETTE.bg : A_PALETTE.ink,
                border: `1px solid ${hiContrast ? A_PALETTE.accent : A_PALETTE.rule}`,
              }}
            >
              {hiContrast ? '✓ ' : ''}ניגודיות גבוהה
            </button>
          </div>

          <div style={{ borderTop: `1px solid ${A_PALETTE.rule}`, paddingTop: 12, fontSize: 12 }}>
            <a href="/accessibility" style={{ color: A_PALETTE.accentSoft, textDecoration: 'none' }}>
              הצהרת נגישות ←
            </a>
          </div>
        </div>
      )}

      <button
        onClick={() => setOpen(v => !v)}
        aria-label="תפריט נגישות"
        title="נגישות"
        style={{
          width: 50, height: 50, borderRadius: '50%',
          border: 'none',
          background: open ? '#3d6454' : A_PALETTE.accent,
          color: A_PALETTE.bg, cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          boxShadow: '0 4px 20px rgba(45,74,62,0.4)',
          transition: 'background 0.2s ease, transform 0.2s ease',
        }}
        onMouseEnter={e => { e.currentTarget.style.background = '#3d6454'; e.currentTarget.style.transform = 'translateY(-3px)'; }}
        onMouseLeave={e => { e.currentTarget.style.background = open ? '#3d6454' : A_PALETTE.accent; e.currentTarget.style.transform = 'translateY(0)'; }}
      >
        <svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
          <circle cx="12" cy="4.5" r="2.2"/>
          <path d="M6.5 9.3C8 8.2 10 7.7 12 7.7s4 .5 5.5 1.6l-1 1.4C15.2 9.8 13.6 9.4 12 9.4s-3.2.4-4.5 1.3L6.5 9.3z"/>
          <path d="M9.8 11.5l-2.3 9h1.9l1.6-5.2 1.6 5.2h1.9l-2.3-9H9.8z"/>
        </svg>
      </button>
    </div>
  );
}

function VariationA() {
  const bp = useBreakpoint();
  return (
    <BpContext.Provider value={bp}>
      <div style={{
        background: A_PALETTE.bg, color: A_PALETTE.ink,
        fontFamily: 'Heebo, system-ui, sans-serif',
        minHeight: '100%', direction: 'rtl',
      }}>
        <CustomCursor />
        <AFloatingCompanion />
        <AScrollTop />
        <AAccessibility />
        <ANav />
        <AHero />
        <AResonance />
        <ACosmicTunnel />
        <AFit />
        <AJourney />
        <AStart />
        <APillars />
        <ATimeline />
        <ATestimonials />
        <AFinalCta />
        <AFooter />
      </div>
    </BpContext.Provider>
  );
}

window.VariationA = VariationA;
