/* Nexpersona - Why us + Selected Work */

const { useState: useStateP, useEffect: useEffectP, useRef: useRefP, useMemo: useMemoP } = React;

function useInView(threshold = 0.3) {
  const ref = useRefP(null);
  const [seen, setSeen] = useStateP(false);
  useEffectP(() => {
    if (!ref.current || seen) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) {
        setSeen(true);
        io.disconnect();
      }
    }, { threshold });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [seen, threshold]);
  return [ref, seen];
}

function AnimatedNumber({ value, format, duration = 1600, prefix = '', suffix = '' }) {
  const [ref, seen] = useInView(0.4);
  const [n, setN] = useStateP(0);
  useEffectP(() => {
    if (!seen) return;
    const start = performance.now();
    let raf;
    const tick = (t) => {
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setN(value * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [seen, value, duration]);
  return <span ref={ref}>{prefix}{format(n)}{suffix}</span>;
}

function MiniBars({ bars, highlightLast = true }) {
  const [ref, seen] = useInView(0.3);
  const max = Math.max(...bars);
  return (
    <div className="mini-bars" ref={ref}>
      {bars.map((b, i) => (
        <span key={i}
          className={`mini-bar ${highlightLast && i === bars.length - 1 ? 'hi' : ''}`}
          style={{
            height: seen ? `${(b / max) * 100}%` : '6%',
            transition: `height .8s cubic-bezier(0.16,1,0.3,1) ${0.15 + i * 0.04}s`,
          }}/>
      ))}
    </div>
  );
}

function RadialGauge({ value, label }) {
  const [ref, seen] = useInView(0.3);
  const R = 28;
  const C = 2 * Math.PI * R;
  const arc = seen ? C * value : 0;
  const ticks = Array.from({ length: 24 }, (_, i) => i);
  return (
    <div className="gauge-wrap" ref={ref}>
      <svg viewBox="0 0 80 80" className="gauge">
        {ticks.map((i) => {
          const a = (i / ticks.length) * Math.PI * 2 - Math.PI / 2;
          const r1 = 35, r2 = 38;
          const x1 = 40 + Math.cos(a) * r1, y1 = 40 + Math.sin(a) * r1;
          const x2 = 40 + Math.cos(a) * r2, y2 = 40 + Math.sin(a) * r2;
          const highlit = seen && i / ticks.length < value;
          return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2}
                       stroke={highlit ? 'var(--accent-alt)' : 'currentColor'}
                       strokeOpacity={highlit ? 1 : 0.18}
                       strokeWidth="1"
                       style={{ transition: `stroke-opacity .3s ease ${0.6 + i * 0.04}s, stroke .3s ease ${0.6 + i * 0.04}s` }}/>;
        })}
        <circle cx="40" cy="40" r={R} fill="none" stroke="currentColor" strokeOpacity="0.10" strokeWidth="2"/>
        <circle cx="40" cy="40" r={R} fill="none"
                stroke="var(--accent-alt)" strokeWidth="2.5"
                strokeLinecap="round"
                strokeDasharray={`${arc} ${C}`}
                transform="rotate(-90 40 40)"
                style={{ transition: 'stroke-dasharray 1.6s cubic-bezier(0.16,1,0.3,1) .2s' }}/>
        <circle cx="40" cy="40" r="2" fill="var(--accent-alt)"/>
      </svg>
      <span className="gauge-label">{label}</span>
    </div>
  );
}

function DotGrid({ filled, cols = 18, rows = 4 }) {
  const [ref, seen] = useInView(0.3);
  const total = cols * rows;
  const n = Math.min(filled, total);
  return (
    <div className="dot-grid" ref={ref}
         style={{ gridTemplateColumns: `repeat(${cols}, 1fr)` }}>
      {Array.from({ length: total }).map((_, i) => {
        const isFilled = i < n;
        return <span key={i} className={`dg-cell ${isFilled ? 'fill' : ''}`}
                     style={{
                       opacity: seen ? (isFilled ? 1 : 0.14) : 0,
                       transform: seen ? 'scale(1)' : 'scale(0)',
                       transition: `opacity .25s ease ${i * 8}ms, transform .35s cubic-bezier(0.16,1,0.3,1) ${i * 8}ms`,
                     }}/>;
      })}
    </div>
  );
}

function TestimonialCarousel() {
  const { t, tR } = window.useT();
  const TESTIMONIALS = [
    { quote: tR('t.1.quote'), name: 'M. Halden', role: t('t.1.role'), org: 'Halden Goods', initial: 'M.H' },
    { quote: tR('t.2.quote'), name: 'A. Reinholt', role: t('t.2.role'), org: 'Reinholt Studio', initial: 'A.R' },
    { quote: tR('t.3.quote'), name: 'L. Sava', role: t('t.3.role'), org: 'North & Quill', initial: 'L.S' },
    { quote: tR('t.4.quote'), name: 'J. Auzina', role: t('t.4.role'), org: 'Verge Health', initial: 'J.A' },
  ];

  const [i, setI] = useStateP(0);
  const [paused, setPaused] = useStateP(false);
  const cardRef = useRefP(null);

  useEffectP(() => {
    if (paused) return;
    const tid = setInterval(() => setI((x) => (x + 1) % TESTIMONIALS.length), 6500);
    return () => clearInterval(tid);
  }, [paused, TESTIMONIALS.length]);

  const onMove = (e) => {
    const r = cardRef.current.getBoundingClientRect();
    cardRef.current.style.setProperty('--mx', `${e.clientX - r.left}px`);
    cardRef.current.style.setProperty('--my', `${e.clientY - r.top}px`);
  };
  const go = (d) => setI((x) => (x + d + TESTIMONIALS.length) % TESTIMONIALS.length);

  return (
    <article
      ref={cardRef}
      className="proof-card pc-carousel"
      onMouseMove={onMove}
      onMouseEnter={() => setPaused(true)}
      onMouseLeave={() => setPaused(false)}
      aria-roledescription="carousel"
    >
      <div className="pc-top">
        <span className="pc-meta">{t('pc.meta.testimonials')}</span>
        <div className="pc-arrows">
          <button className="pc-arrow" onClick={() => go(-1)} aria-label={t('pc.aria.prev')}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M19 12H5M12 19l-7-7 7-7"/></svg>
          </button>
          <button className="pc-arrow" onClick={() => go(1)} aria-label={t('pc.aria.next')}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
          </button>
        </div>
      </div>

      <div className="pc-carousel-stage">
        {TESTIMONIALS.map((tm, idx) => (
          <div key={idx} className={`pc-slide ${idx === i ? 'is-current' : (idx === (i - 1 + TESTIMONIALS.length) % TESTIMONIALS.length ? 'is-prev' : 'is-next')}`}>
            <span className="pc-mark serif">“</span>
            <blockquote className="pc-quote-text serif">{tm.quote}</blockquote>
            <div className="pc-cite-row">
              <span className="pc-initial mono">{tm.initial}</span>
              <div className="pc-cite-block">
                <div className="pc-cite-name">{tm.name}</div>
                <div className="pc-cite-role">{tm.role} · {tm.org}</div>
              </div>
            </div>
          </div>
        ))}
      </div>

      <div className="pc-dots" role="tablist">
        {TESTIMONIALS.map((_, idx) => (
          <button
            key={idx}
            className={`pc-dot ${idx === i ? 'active' : ''}`}
            onClick={() => setI(idx)}
            aria-label={`Show testimonial ${idx + 1}`}
            aria-selected={idx === i}
          >
            <span className="pc-dot-fill" style={{
              animationDuration: paused ? '0s' : '6.5s',
              animationPlayState: idx === i && !paused ? 'running' : 'paused',
              animationName: idx === i ? 'pc-dot-fill' : 'none',
            }}/>
          </button>
        ))}
      </div>

      <span className="pc-counter mono">{String(i + 1).padStart(2, '0')} / {String(TESTIMONIALS.length).padStart(2, '0')}</span>
    </article>
  );
}

function FounderVision() {
  const { t, tR } = window.useT();
  const cardRef = useRefP(null);
  const onMove = (e) => {
    const r = cardRef.current.getBoundingClientRect();
    cardRef.current.style.setProperty('--mx', `${e.clientX - r.left}px`);
    cardRef.current.style.setProperty('--my', `${e.clientY - r.top}px`);
  };

  return (
    <article ref={cardRef} className="proof-card pc-vision" onMouseMove={onMove}>
      <div className="pc-top">
        <span className="pc-meta">{t('vision.meta')}</span>
        <span className="pc-tag">{t('vision.tag')}</span>
      </div>
      <div className="pc-vision-body">
        <p className="pc-vision-text serif">{tR('vision.text')}</p>
        <div className="pc-cite-row">
          <span className="pc-initial mono">R.K</span>
          <div className="pc-cite-block">
            <div className="pc-cite-name">Reinis K.</div>
            <div className="pc-cite-role">{t('vision.role')}</div>
          </div>
        </div>
      </div>
    </article>
  );
}

function ProofCard({ meta, tag, number, name, desc, chart, delay = 0 }) {
  const cardRef = useRefP(null);
  const onMove = (e) => {
    const r = cardRef.current.getBoundingClientRect();
    cardRef.current.style.setProperty('--mx', `${e.clientX - r.left}px`);
    cardRef.current.style.setProperty('--my', `${e.clientY - r.top}px`);
  };

  return (
    <article
      ref={cardRef}
      className="proof-card"
      style={{ '--float-delay': `${-delay * 1.3}s` }}
      onMouseMove={onMove}
    >
      <div className="pc-top">
        <span className="pc-meta">{meta}</span>
        <span className="pc-tag">{tag}</span>
      </div>
      <div className="pc-number serif">
        {number}
      </div>
      <h3 className="pc-name serif">{name}</h3>
      <p className="pc-desc">{desc}</p>
      <div className="pc-chart">{chart}</div>
    </article>
  );
}

function Work() {
  const { t, tR } = window.useT();
  return (
    <section className="section shell" id="work">
      <div className="eyebrow-row reveal">
        <span className="dot"></span>
        <span className="mono">{t('work.eyebrow')}</span>
        <span className="line"></span>
      </div>
      <div className="work-head reveal">
        <h2 className="serif work-h">{tR('work.title')}</h2>
        <p style={{maxWidth: 380, color: 'var(--text-2)', fontSize: 15, lineHeight: 1.5}}>{t('work.sub')}</p>
      </div>

      {/* Desktop grid (CSS hides this on mobile) */}
      <div className="proof-grid">
        <ProofCard
          meta={t('work.1.meta')}
          tag={t('work.1.tag')}
          number={<AnimatedNumber value={4.2} format={(n) => n.toFixed(1) + '×'} />}
          name={t('work.1.name')}
          desc={t('work.1.desc')}
          chart={<MiniBars bars={[14, 22, 18, 32, 38, 48, 64, 72, 86, 98, 116, 132]} />}
          delay={0}
        />
        <TestimonialCarousel />
        <FounderVision />
        <ProofCard
          meta={t('work.2.meta')}
          tag={t('work.2.tag')}
          number={<AnimatedNumber value={2.4} format={(n) => '€' + n.toFixed(1) + 'M'} />}
          name={t('work.2.name')}
          desc={t('work.2.desc')}
          chart={<RadialGauge value={0.78} label={t('work.2.gauge')} />}
          delay={2}
        />
        <ProofCard
          meta={t('work.3.meta')}
          tag={t('work.3.tag')}
          number={<AnimatedNumber value={680} format={(n) => '+' + Math.round(n) + 'k'} />}
          name={t('work.3.name')}
          desc={t('work.3.desc')}
          chart={<DotGrid filled={56} cols={18} rows={4} />}
          delay={3}
        />
      </div>

      {/* Mobile: two auto-marquee rows (testimonials + main cards) */}
      <MobileWork />
    </section>
  );
}

// ---------- Mobile-only Selected Work renderer

function MobileWork() {
  const { t, tR } = window.useT();

  const testimonials = [
    { quote: tR('t.1.quote'), name: 'M. Halden', role: t('t.1.role'), org: 'Halden Goods', initial: 'M.H' },
    { quote: tR('t.2.quote'), name: 'A. Reinholt', role: t('t.2.role'), org: 'Reinholt Studio', initial: 'A.R' },
    { quote: tR('t.3.quote'), name: 'L. Sava', role: t('t.3.role'), org: 'North & Quill', initial: 'L.S' },
    { quote: tR('t.4.quote'), name: 'J. Auzina', role: t('t.4.role'), org: 'Verge Health', initial: 'J.A' },
  ];

  const mainCards = [
    {
      kind: 'stat',
      meta: t('work.1.meta'), tag: t('work.1.tag'),
      number: '4.2×',
      name: t('work.1.name'), desc: t('work.1.desc'),
    },
    {
      kind: 'vision',
      meta: t('vision.meta'), tag: t('vision.tag'),
      visionText: tR('vision.text'),
      name: 'Reinis K.', role: t('vision.role'), initial: 'R.K',
    },
    {
      kind: 'stat',
      meta: t('work.2.meta'), tag: t('work.2.tag'),
      number: '€2.4M',
      name: t('work.2.name'), desc: t('work.2.desc'),
    },
    {
      kind: 'stat',
      meta: t('work.3.meta'), tag: t('work.3.tag'),
      number: '+680k',
      name: t('work.3.name'), desc: t('work.3.desc'),
    },
  ];

  // Duplicate for seamless loop
  const tDouble = [...testimonials, ...testimonials];
  const mDouble = [...mainCards, ...mainCards];

  return (
    <div className="proof-mobile">
      <MarqueeRow modifier="top" pauseLabel="testimonials">
        {tDouble.map((tm, i) => (
          <article className="pm-card pm-card-testimonial" key={`t-${i}`}>
            <blockquote className="pm-quote">{tm.quote}</blockquote>
            <div className="pm-cite">
              <span className="pm-initial">{tm.initial}</span>
              <div>
                <div className="pm-cite-name">{tm.name}</div>
                <div className="pm-cite-role">{tm.role} · {tm.org}</div>
              </div>
            </div>
          </article>
        ))}
      </MarqueeRow>

      <MarqueeRow modifier="bottom" pauseLabel="main">
        {mDouble.map((c, i) => {
          if (c.kind === 'vision') {
            return (
              <article className="pm-card pm-card-main pm-card-vision" key={`m-${i}`}>
                <div className="pm-top">
                  <span>{c.meta}</span>
                  <span className="pm-tag">{c.tag}</span>
                </div>
                <p className="pm-vision-text">{c.visionText}</p>
                <div className="pm-cite">
                  <span className="pm-initial">{c.initial}</span>
                  <div>
                    <div className="pm-cite-name">{c.name}</div>
                    <div className="pm-cite-role">{c.role}</div>
                  </div>
                </div>
              </article>
            );
          }
          return (
            <article className="pm-card pm-card-main" key={`m-${i}`}>
              <div className="pm-top">
                <span>{c.meta}</span>
                <span className="pm-tag">{c.tag}</span>
              </div>
              <div className="pm-number">{c.number}</div>
              <h3 className="pm-name">{c.name}</h3>
              <p className="pm-desc">{c.desc}</p>
            </article>
          );
        })}
      </MarqueeRow>
    </div>
  );
}

/* Infinite marquee with native swipe.
 *
 * The track is a native overflow-x: auto element so the browser
 * handles touch panning + momentum for free. JS auto-advances
 * scrollLeft each frame; when scrollLeft crosses the half-mark
 * of the duplicated content, we warp back by half - the warp is
 * invisible because the content is duplicated 2x.
 *
 * Pause triggers (both desktop hover and mobile touch) stop the
 * auto-advance; release resumes after a short grace period.
 */
function MarqueeRow({ children, modifier }) {
  const trackRef = useRefP(null);
  const [hoverPaused, setHoverPaused] = useStateP(false);
  const touchingRef = useRefP(false);
  const resumeTimerRef = useRefP(null);

  // Initial centering: start halfway into the first duplicate so the
  // user can swipe both ways without immediately hitting an edge.
  useEffectP(() => {
    const el = trackRef.current;
    if (!el) return;
    const id = setTimeout(() => {
      if (el.scrollWidth > el.clientWidth * 2) {
        el.scrollLeft = Math.floor(el.scrollWidth / 4);
      }
    }, 60);
    return () => clearTimeout(id);
  }, []);

  // Auto-advance loop with wrap-around. Skip when paused or touching.
  useEffectP(() => {
    const el = trackRef.current;
    if (!el) return;
    const prefersReduce = window.matchMedia?.('(prefers-reduced-motion: reduce)').matches;
    if (prefersReduce) return;

    // Top row drifts right (+), bottom row drifts left (-).
    const speed = modifier === 'bottom' ? -0.55 : 0.75;

    let raf;
    const tick = () => {
      if (!hoverPaused && !touchingRef.current) {
        el.scrollLeft += speed;
      }
      // Wrap so the carousel is effectively infinite.
      const half = el.scrollWidth / 2;
      if (half > 0) {
        if (el.scrollLeft >= half) el.scrollLeft -= half;
        else if (el.scrollLeft < 0) el.scrollLeft += half;
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [hoverPaused, modifier]);

  const onTouchStart = () => {
    touchingRef.current = true;
    if (resumeTimerRef.current) {
      clearTimeout(resumeTimerRef.current);
      resumeTimerRef.current = null;
    }
  };
  const onTouchEnd = () => {
    // Short grace so auto-advance picks back up shortly after lift-off.
    resumeTimerRef.current = setTimeout(() => {
      touchingRef.current = false;
      resumeTimerRef.current = null;
    }, 350);
  };

  return (
    <div
      className={`pm-marquee pm-marquee-${modifier}`}
      onMouseEnter={() => setHoverPaused(true)}
      onMouseLeave={() => setHoverPaused(false)}
      onTouchStart={onTouchStart}
      onTouchEnd={onTouchEnd}
      onTouchCancel={onTouchEnd}
    >
      <div ref={trackRef} className="pm-track">{children}</div>
    </div>
  );
}

// ---------- 06 Why us - bloom

function buildBloom(channels, offers) {
  const W = 1100, H = 520, cx = W / 2, cy = H / 2;
  const ringNamed = (radius, names, offset = 0) =>
    names.map((name, i) => {
      const a = ((i + offset) / names.length) * Math.PI * 2 - Math.PI / 2;
      return {
        x: cx + Math.cos(a) * radius,
        y: cy + Math.sin(a) * radius,
        a, i, name, radius,
      };
    });
  const ring3 = Array.from({ length: 14 }, (_, i) => {
    const a = (i / 14) * Math.PI * 2 - Math.PI / 2 + 0.12;
    const r = 244 + (i % 2) * 6;
    return { x: cx + Math.cos(a) * r, y: cy + Math.sin(a) * r, a, i, radius: r };
  });
  return {
    W, H, cx, cy,
    r1: ringNamed(100, channels),
    r2: ringNamed(176, offers, 0.5),
    r3: ring3,
  };
}

function labelOffset(B, dot, distance = 18) {
  const lx = B.cx + Math.cos(dot.a) * (dot.radius + distance);
  const ly = B.cy + Math.sin(dot.a) * (dot.radius + distance);
  const cos = Math.cos(dot.a);
  const sin = Math.sin(dot.a);
  let anchor = 'middle';
  if (cos > 0.3) anchor = 'start';
  else if (cos < -0.3) anchor = 'end';
  let dy = 4;
  if (sin > 0.5) dy = 11;
  else if (sin < -0.5) dy = -3;
  return { x: lx, y: ly + dy, anchor };
}

function CompoundingBloom() {
  const { t } = window.useT();
  const [ref, seen] = useInView(0.18);
  const isMobile = window.useMobileNX ? window.useMobileNX(720) : false;

  const channels = [1,2,3,4,5,6].map(i => t(`bloom.channel.${i}`));
  const offers = [1,2,3,4,5,6].map(i => t(`bloom.offer.${i}`));
  const B = buildBloom(channels, offers);
  const { W, H, cx, cy, r1, r2, r3 } = B;

  const ring1to2 = r1.flatMap((a, i) => {
    const start = i;
    return [r2[start % r2.length], r2[(start + 1) % r2.length]].map((b) => [a, b]);
  });
  const ring2to3 = r2.flatMap((a, i) => {
    const startIdx = Math.round((i / r2.length) * r3.length);
    return [r3[startIdx % r3.length], r3[(startIdx + 1) % r3.length]].map((b) => [a, b]);
  });

  return (
    <div className={`bloom ${seen ? 'in' : ''}`} ref={ref}>
      <svg
        viewBox={isMobile ? "270 -20 560 560" : `0 0 ${W} ${H}`}
        preserveAspectRatio="xMidYMid meet"
        width="100%"
        height="100%"
      >
        <defs>
          <radialGradient id="originGrad">
            <stop offset="0" stopColor="var(--accent-alt)" stopOpacity="0.4"/>
            <stop offset="1" stopColor="var(--accent-alt)" stopOpacity="0"/>
          </radialGradient>
          <radialGradient id="bgGlow">
            <stop offset="0" stopColor="var(--accent-alt)" stopOpacity="0.12"/>
            <stop offset="1" stopColor="var(--accent-alt)" stopOpacity="0"/>
          </radialGradient>
        </defs>

        <circle cx={cx} cy={cy} r="320" fill="url(#bgGlow)"/>
        <circle cx={cx} cy={cy} r="100" fill="none" stroke="currentColor" strokeOpacity="0.10" strokeDasharray="2 4"/>
        <circle cx={cx} cy={cy} r="176" fill="none" stroke="currentColor" strokeOpacity="0.08" strokeDasharray="2 4"/>
        <circle cx={cx} cy={cy} r="248" fill="none" stroke="currentColor" strokeOpacity="0.06" strokeDasharray="2 4"/>

        <circle className="bloom-pulse p1" cx={cx} cy={cy} fill="none" stroke="var(--accent-alt)" strokeWidth="1"/>
        <circle className="bloom-pulse p2" cx={cx} cy={cy} fill="none" stroke="var(--accent-alt)" strokeWidth="1"/>
        <circle className="bloom-pulse p3" cx={cx} cy={cy} fill="none" stroke="var(--accent-alt)" strokeWidth="1"/>

        {r1.map((p, i) => (
          <line key={`o1-${i}`} className="bloom-line l1"
                x1={cx} y1={cy} x2={p.x} y2={p.y}
                stroke="currentColor" strokeOpacity="0.32" strokeWidth="0.8"
                style={{ animationDelay: `${0.2 + i * 0.06}s` }}/>
        ))}
        {ring1to2.map(([a, b], i) => (
          <line key={`12-${i}`} className="bloom-line l2"
                x1={a.x} y1={a.y} x2={b.x} y2={b.y}
                stroke="currentColor" strokeOpacity="0.22" strokeWidth="0.7"
                style={{ animationDelay: `${0.6 + i * 0.04}s` }}/>
        ))}
        {ring2to3.map(([a, b], i) => (
          <line key={`23-${i}`} className="bloom-line l3"
                x1={a.x} y1={a.y} x2={b.x} y2={b.y}
                stroke="currentColor" strokeOpacity="0.14" strokeWidth="0.6"
                style={{ animationDelay: `${1.0 + i * 0.03}s` }}/>
        ))}

        {r3.map((p, i) => (
          <circle key={`d3-${i}`} className="bloom-dot d3"
                  cx={p.x} cy={p.y} r="2.6" fill="currentColor"
                  style={{ animationDelay: `${1.3 + i * 0.04}s` }}/>
        ))}

        {r2.map((p, i) => {
          const lp = labelOffset(B, p);
          return (
            <g key={`d2-${i}`} className="bloom-node n2">
              <circle className="bloom-dot d2"
                      cx={p.x} cy={p.y} r="4" fill="currentColor"
                      style={{ animationDelay: `${0.8 + i * 0.05}s` }}/>
              <text className="bloom-lbl bloom-lbl-2"
                    x={lp.x} y={lp.y} textAnchor={lp.anchor}
                    style={{ animationDelay: `${1.0 + i * 0.05}s` }}>
                {p.name}
              </text>
            </g>
          );
        })}

        {r1.map((p, i) => {
          const lp = labelOffset(B, p, 22);
          return (
            <g key={`d1-${i}`} className="bloom-node n1">
              <circle className="bloom-dot d1"
                      cx={p.x} cy={p.y} r="6" fill="var(--accent-alt)"
                      style={{ animationDelay: `${0.4 + i * 0.06}s` }}/>
              <text className="bloom-lbl bloom-lbl-1"
                    x={lp.x} y={lp.y} textAnchor={lp.anchor}
                    style={{ animationDelay: `${0.6 + i * 0.06}s` }}>
                {p.name}
              </text>
            </g>
          );
        })}

        <circle cx={cx} cy={cy} r="40" fill="url(#originGrad)" className="bloom-origin-glow"/>
        <circle cx={cx} cy={cy} r="14" fill="var(--accent-alt)" className="bloom-origin"/>
        <circle cx={cx} cy={cy} r="6" fill="var(--bg)"/>
        <text x={cx} y={cy + 38} textAnchor="middle" className="bloom-lbl bloom-lbl-brand">
          {t('bloom.brand')}
        </text>
      </svg>

      <span className="bloom-anno tl">{window.NXparse(t('why.anno'))}</span>
    </div>
  );
}

function Why() {
  const { t, tR } = window.useT();
  return (
    <section className="section why-section" id="about">
      <div className="why-bg" aria-hidden="true"></div>
      <div className="shell">
        <div className="eyebrow-row reveal">
          <span className="dot"></span>
          <span className="mono">{t('why.eyebrow')}</span>
          <span className="line"></span>
        </div>
        <CompoundingBloom />
        <div className="why-legend reveal">
          <div className="why-legend-intro">
            <h3 className="serif why-legend-title">{tR('why.legend.title')}</h3>
            <p className="why-legend-body">{t('why.legend.body')}</p>
          </div>
          <ol className="why-legend-rings">
            {[1, 2, 3].map((i) => (
              <li className="wlr" key={i}>
                <span className={`wlr-swatch wlr-${i}`} aria-hidden="true"></span>
                <div className="wlr-text">
                  <span className="wlr-label">{t(`why.ring.${i}.label`)}</span>
                  <span className="wlr-detail">{t(`why.ring.${i}.detail`)}</span>
                </div>
              </li>
            ))}
          </ol>
        </div>
      </div>
    </section>
  );
}

window.NXWork = Work;
window.NXWhy = Why;
