// Section components - Hero, Profile, Lab, Simulator, Activities, Selected,
// Timeline, Final Reflection, Contact. All read from window.PORTFOLIO_DATA.

const D = window.PORTFOLIO_DATA;
const SIM = window.SIM_DATA;

// Tiny i18n helper: T("english", "dutch", lang) - keeps the JSX compact.
const T = (en, nl, lang) => (lang === "nl" ? nl : en);

// TR(v, lang) - resolves a value that may be a plain string (legacy) or
// a { en, nl } object. Falls back to en if the requested lang is missing.
const TR = (v, lang) =>
  v && typeof v === "object" && !Array.isArray(v) ? (v[lang] || v.en) : v;

// ───── Hero / Helmet visor ─────────────────────────────────────────────────
// Two-stage hero: full-bleed helmet portrait that "zooms into the visor" as
// the user scrolls - by the time they hit the Profile section the camera is
// inside the light-beam tunnel.
window.Hero = function Hero({ lang, accent }) {
  const [progress, setProgress] = React.useState(0);
  const ref = React.useRef(null);

  React.useEffect(() => {
    const onScroll = () => {
      const el = ref.current;
      if (!el) return;
      const rect = el.getBoundingClientRect();
      const vh = window.innerHeight;
      const total = rect.height - vh;
      const scrolled = -rect.top;
      const p = Math.max(0, Math.min(1, scrolled / Math.max(total, 1)));
      setProgress(p);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    window.addEventListener("resize", onScroll);
    return () => {
      window.removeEventListener("scroll", onScroll);
      window.removeEventListener("resize", onScroll);
    };
  }, []);

  const tag = D.taglines.primary[lang] || D.taglines.primary.en;
  const sub = D.taglines.sub[lang] || D.taglines.sub.en;
  const tagParts = tag.split(",");

  const zoom = 1 + progress * 4.0;
  const offsetY = -progress * 6;
  const titleFade = 1 - Math.min(1, progress * 2.4);
  const titleShift = -progress * 60;
  const vignetteFade = Math.min(1, progress * 1.6);
  const beamGlow = Math.min(1, progress * 1.4);

  return (
    <section className="hero hero-helmet" id="top" ref={ref}>
      <div
        className="helmet-bg"
        style={{ transform: `scale(${zoom}) translate3d(0, ${offsetY}%, 0)` }}
      />
      <div
        className="helmet-vignette"
        style={{ opacity: 0.35 + vignetteFade * 0.55 }}
      />
      <div
        className="helmet-beam-glow"
        style={{ opacity: 0.0 + beamGlow * 0.9, transform: `scale(${1 + progress * 0.6})` }}
      />

      <div
        className="hero-helmet-center"
        style={{
          opacity: titleFade,
          transform: `translate3d(0, ${titleShift}px, 0)`,
        }}
      >
        <h1 className="hero-headline">
          {tagParts[0]},
          <br />
          <em>{tagParts[1]?.trim()}</em>,
          <br />
          {tagParts[2]?.trim()}
        </h1>
        <p className="hero-sub">{sub}</p>
        <div className="hero-cta-row">
          <a href="#simulator" className="btn btn-prim">
            {T("Launch Pitstop Simulator", "Start Pitstop Simulator", lang)} <span className="arrow">→</span>
          </a>
          <a href="#about" className="btn">
            {T("Explore Portfolio", "Bekijk portfolio", lang)}
          </a>
        </div>
      </div>

      <div className="hero-scroll-hint" style={{ opacity: 1 - Math.min(1, progress * 3) }}>
        <span>{T("SCROLL · INTO THE VISOR", "SCROLL · DOOR HET VIZIER", lang)}</span>
        <div className="line" />
      </div>
    </section>
  );
};

// ───── Driver Profile ──────────────────────────────────────────────────────
window.Profile = function Profile({ lang }) {
  const [animated, setAnimated] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const obs = new IntersectionObserver(
      (entries) => entries.forEach((e) => { if (e.isIntersecting) setAnimated(true); }),
      { threshold: 0.3 }
    );
    if (ref.current) obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);

  // Skill labels can be either a plain string (legacy) or { en, nl }. Resolve
  // here so EN/NL switching reaches the radar dots and the skill-bar text.
  const resolveLabel = (s) =>
    typeof s.label === "object" ? (s.label[lang] || s.label.en) : s.label;

  const cx = 130, cy = 130, R = 96;
  const N = D.skills.length;
  const points = D.skills.map((s, i) => {
    const a = (Math.PI * 2 * i) / N - Math.PI / 2;
    const r = R * (animated ? s.value : 0);
    return { x: cx + r * Math.cos(a), y: cy + r * Math.sin(a), label: resolveLabel(s), val: s.value, ang: a };
  });
  const polyPts = points.map((p) => `${p.x},${p.y}`).join(" ");

  return (
    <section className="section" id="about">
      <div className="section-head">
        <div>
          <span className="eyebrow">{T("Driver Profile", "Coureur profiel", lang)}</span>
          <h2 className="section-title">Martijn Van Baelen</h2>
          <p className="section-sub">{T(
            "A student wiring motorsport and data into one craft. Here are the numbers behind the profile.",
            "Een student die motorsport en data combineert. Hier de cijfers achter het profiel.",
            lang
          )}</p>
        </div>
      </div>

      <div className="profile-grid" ref={ref}>
        <div className="profile-card">
          <div className="profile-meta">{D.identity.name}</div>
          <h3 className="profile-name">{T("22 years · Student", "22 jaar · Student", lang)}</h3>
          <p className="profile-bio">{D.about[lang] || D.about.en}</p>
          <div style={{ marginTop: 24 }}>
            <div className="profile-section-label">{T("Interests", "Interesses", lang)}</div>
            <div className="profile-tags">{D.interests.map((t) => <span key={t} className={"tag " + (["Formula 1","NASCAR","IndyCar","Sim racing"].includes(t) ? "accent" : "")}>{t}</span>)}</div>
          </div>
          <div style={{ marginTop: 18 }}>
            <div className="profile-section-label">Stack</div>
            <div className="profile-tags">{D.techStack.map((t) => <span key={t} className="tag">{t}</span>)}</div>
          </div>
        </div>

        <div className="skills-stack">
          <h3>{T("TELEMETRY · SKILLS", "TELEMETRIE · SKILLS", lang)}</h3>
          {D.skills.map((s) => (
            <div className="skill-row" key={s.key}>
              <span className="lbl">{resolveLabel(s)}</span>
              <div className="skill-bar"><div className="fill" style={{ width: animated ? `${s.value * 100}%` : 0 }} /><div className="ticks" /></div>
              <span className="val">{Math.round(s.value * 100)}</span>
            </div>
          ))}

          <div className="radar-wrap">
            <svg width="260" height="260" viewBox="0 0 260 260">
              {[0.25, 0.5, 0.75, 1].map((r, i) => (
                <polygon key={i} points={Array.from({ length: N }).map((_, j) => {
                  const a = (Math.PI * 2 * j) / N - Math.PI / 2;
                  return `${cx + R * r * Math.cos(a)},${cy + R * r * Math.sin(a)}`;
                }).join(" ")}
                fill="none" stroke="var(--line)" strokeWidth="0.5" />
              ))}
              {Array.from({ length: N }).map((_, i) => {
                const a = (Math.PI * 2 * i) / N - Math.PI / 2;
                return <line key={i} x1={cx} y1={cy} x2={cx + R * Math.cos(a)} y2={cy + R * Math.sin(a)} stroke="var(--line)" strokeWidth="0.5" />;
              })}
              <polygon points={polyPts} fill="rgba(255,46,62,0.18)" stroke="var(--accent)" strokeWidth="1.5" style={{ transition: "all 1s ease" }} />
              {points.map((p, i) => (
                <g key={i}>
                  <circle cx={p.x} cy={p.y} r="3" fill="var(--accent)" />
                  <text x={cx + (R + 16) * Math.cos(p.ang)} y={cy + (R + 16) * Math.sin(p.ang)} textAnchor="middle" alignmentBaseline="middle"
                        fontFamily="var(--mono)" fontSize="9" fill="var(--fg-3)" letterSpacing="1">{p.label.split(" ")[0].toUpperCase()}</text>
                </g>
              ))}
            </svg>
          </div>
        </div>
      </div>
    </section>
  );
};

// ───── AI / Data Lab ───────────────────────────────────────────────────────
window.Lab = function Lab({ lang }) {
  return (
    <section className="section" id="lab">
      <div className="section-head">
        <div>
          <span className="eyebrow">{T("Motorsport AI & Data Lab", "Motorsport AI & Data Lab", lang)}</span>
          <h2 className="section-title">{T("The lab - AI & data in motorsport", "Het lab - AI & data in motorsport", lang)}</h2>
          <p className="section-sub">{T(
            "How I think about AI and data analysis in motorsport - especially pitstops, where hundredths decide who exits ahead.",
            "Hoe ik kijk naar AI en data-analyse in motorsport - vooral in pitstops, waar honderdsten beslissen wie er voor staat.",
            lang
          )}</p>
        </div>
      </div>
      <div className="lab-grid">
        {D.lab.map((c) => {
          const title = typeof c.title === "object" ? (c.title[lang] || c.title.en) : c.title;
          const desc  = typeof c.desc  === "object" ? (c.desc[lang]  || c.desc.en)  : c.desc;
          return (
            <div className="lab-card" key={title}>
              <h4>{title}</h4>
              <p>{desc}</p>
            </div>
          );
        })}
      </div>
    </section>
  );
};

// ───── Simulator section ───────────────────────────────────────────────────
window.SimulatorSection = function SimulatorSection({ accent, lang }) {
  const N_STOPS = 10000;
  const [crewKey, setCrewKey] = React.useState(SIM.defaultCrewKey);
  const [result, setResult] = React.useState(null);
  const [animKey, setAnimKey] = React.useState(0);

  // Re-run the Monte Carlo whenever the user picks a different crew.
  React.useEffect(() => {
    const crew = SIM.crews[crewKey];
    setResult(null);
    const id = setTimeout(() => {
      const r = window.MonteCarlo.runMany(N_STOPS, crew.edges);
      setResult(r);
      setAnimKey((k) => k + 1);
    }, 30);
    return () => clearTimeout(id);
  }, [crewKey]);

  const crew = SIM.crews[crewKey];
  const crewKeys = Object.keys(SIM.crews);

  return (
    <section className="section sim-section" id="simulator">
      <div className="section-head">
        <div>
          <span className="eyebrow">{T("Featured Project", "Uitgelicht project", lang)}</span>
          <h2 className="section-title">IndyCar Pitstop Monte Carlo</h2>
          <p className="section-sub">{T(
            "Live, in your browser. Pick a pit crew and watch the median pitstop play out.",
            "Live, in je browser. Kies een pitcrew en bekijk de mediane stop.",
            lang
          )}</p>
        </div>
      </div>

      <div className="sim-frame">
        <div className="sim-headerbar">
          <div className="left">
            <span className="pill">PIT-WALL DASHBOARD</span>
          </div>
          <div className="left" style={{ color: "var(--fg-3)" }}>
            {T("INTERNSHIP · ASPHALT ANALYTICS · HUNTERSVILLE NC", "STAGE · ASPHALT ANALYTICS · HUNTERSVILLE NC", lang)}
          </div>
        </div>
        <div className="sim-body">
          <aside className="sim-side">
            <h4>{T("Pit crew · select", "Pitcrew · kies", lang)}</h4>
            <div className="crew-selector">
              {crewKeys.map((k) => {
                const c = SIM.crews[k];
                const tag = typeof c.tagline === "object" ? (c.tagline[lang] || c.tagline.en) : c.tagline;
                return (
                  <button
                    key={k}
                    className={"crew-chip" + (crewKey === k ? " on" : "")}
                    onClick={() => setCrewKey(k)}
                  >
                    <span className="crew-chip-name">{c.name}</span>
                    <span className="crew-chip-tag">{tag}</span>
                  </button>
                );
              })}
            </div>

            <h4 style={{ marginTop: 18 }}>{T("Lineup", "Opstelling", lang)}</h4>
            {crew.athletes.map((a) => (
              <div className="crew-row" key={a.role}>
                <span className="swatch" style={{ background: a.color }} />
                <div>
                  <label>{a.role}</label>
                  <div className="crew-name">{a.name}</div>
                </div>
              </div>
            ))}

          </aside>

          <div className="sim-stage">
            <div className="sim-canvas-wrap">
              {result && <window.PitstopCanvas key={animKey} animationData={result.animation_data} accentColor={accent} />}
            </div>
            {result && (
              <div className="sim-median-banner">
                <span className="lbl">
                  {T("Median pitstop time", "Mediaan pitstoptijd", lang)} · {crew.name}
                </span>
                <span className="val">{result.animation_data.total_time.toFixed(2)}<span className="unit">s</span></span>
              </div>
            )}
          </div>
        </div>
      </div>
    </section>
  );
};

// ───── Activities ──────────────────────────────────────────────────────────
window.Activities = function Activities({ lang }) {
  const [filter, setFilter] = React.useState("all");
  const [flashId, setFlashId] = React.useState(null);

  // Cross-section jump: the Timeline dispatches a "scrollToActivity" event
  // when one of its dots is clicked. Reset the filter to "all" so the target
  // card is in the DOM, then smooth-scroll to it on the next frame.
  React.useEffect(() => {
    const handler = (e) => {
      const id = e.detail;
      if (!id) return;
      setFilter("all");
      requestAnimationFrame(() => {
        const target = document.getElementById("activity-" + id);
        if (!target) return;
        target.scrollIntoView({ behavior: "smooth", block: "center" });
        setFlashId(id);
        setTimeout(() => setFlashId((cur) => (cur === id ? null : cur)), 1600);
      });
    };
    window.addEventListener("scrollToActivity", handler);
    return () => window.removeEventListener("scrollToActivity", handler);
  }, []);

  const items = filter === "all" ? D.activities : D.activities.filter((a) => a.domain === filter);
  const counts = D.activities.reduce((acc, a) => ({ ...acc, [a.domain]: (acc[a.domain] || 0) + 1 }), {});
  const dateLocale = lang === "nl" ? "nl-BE" : "en-GB";

  const filters = [
    { k: "all",           l: T("All", "Alle", lang) },
    { k: "seminar",       l: T("Seminars", "Seminaries", lang) },
    { k: "innovation",    l: T("Innovation", "Innovatie", lang) },
    { k: "personal",      l: T("Personal Dev", "Persoonlijke ontwikkeling", lang) },
    { k: "international", l: T("International", "Internationaal", lang) },
  ];

  return (
    <section className="section" id="activities">
      <div className="section-head">
        <div>
          <span className="eyebrow">{T("Activities Overview", "Overzicht activiteiten", lang)}</span>
          <h2 className="section-title">{T("Activities · by domain", "Activiteiten · per domein", lang)}</h2>
          <p className="section-sub">{T(
            "Every activity with a short description, location and time.",
            "Elke activiteit met een korte beschrijving, locatie en tijd.",
            lang
          )}</p>
        </div>
      </div>

      <div className="filters">
        {filters.map((f) => (
          <button key={f.k} className={"filter-chip " + (filter === f.k ? "on" : "")} onClick={() => setFilter(f.k)}>
            {f.l} <span className="count">{f.k === "all" ? D.activities.length : counts[f.k] || 0}</span>
          </button>
        ))}
      </div>

      <div className="activity-grid">
        {items.map((a) => (
          <div
            key={a.id}
            id={"activity-" + a.id}
            className={"activity-card dom-" + a.domain + (flashId === a.id ? " flash" : "")}
          >
            <div className="top">
              <span>{new Date(a.date).toLocaleDateString(dateLocale, { day: "2-digit", month: "short", year: "numeric" })}</span>
              <span className="domain">{a.domain}</span>
            </div>
            <h4>{TR(a.title, lang)}</h4>
            <p>{TR(a.desc, lang)}</p>
            <dl className="meta-rows">
              <div className="meta-row">
                <dt>{T("Location", "Locatie", lang)}</dt>
                <dd>{TR(a.location, lang)}</dd>
              </div>
              <div className="meta-row">
                <dt>{T("Time", "Tijd", lang)}</dt>
                <dd>{a.duration}</dd>
              </div>
            </dl>
          </div>
        ))}
      </div>
    </section>
  );
};

// ───── Selected highlights ─────────────────────────────────────────────────
window.Selected = function Selected({ lang }) {
  const stage = D.selected["stage-usa"];
  const hack = D.selected["hack-future"];
  const pw = D.selected["projectweek"];

  const labels = {
    goal: T("Goal of the activity", "Doel van de activiteit", lang),
    personal: T("My personal goals", "Mijn persoonlijke doelen", lang),
    did: T("What I did", "Wat ik deed", lang),
    learned: T("What I learned", "Wat ik geleerd heb", lang),
    reflection: T("Reflection", "Reflectie", lang),
  };

  return (
    <section className="section" id="selected">
      <div className="section-head">
        <div>
          <span className="eyebrow">{T("Race Highlights", "Race-hoogtepunten", lang)}</span>
          <h2 className="section-title">{T("Selected activities", "Geselecteerde activiteiten", lang)}</h2>
        </div>
      </div>

      <div className="selected-stack">
        <article className="selected-card headline">
          <div className="stage-headline-hero">
            <div>
              <span className="stamp">★ {T("RACE OF THE SEASON", "RACE VAN HET SEIZOEN", lang)}</span>
              <h3>{T("Internship USA · Asphalt Analytics", "Stage USA · Asphalt Analytics", lang)}</h3>
              <div className="stage-headline-meta">
                {T(
                  "HUNTERSVILLE · NORTH CAROLINA · 12 WEEKS · 09 MAR – 29 MAY 2026",
                  "HUNTERSVILLE · NORTH CAROLINA · 12 WEKEN · 09 MRT – 29 MEI 2026",
                  lang
                )}
              </div>
              <p className="stage-headline-desc">{TR(stage.description, lang)}</p>
            </div>
            <div className="map">
              <svg viewBox="-50 -10 500 220" preserveAspectRatio="xMidYMid meet">
                <defs>
                  <linearGradient id="route" x1="0" x2="1" y1="0" y2="0">
                    <stop offset="0%" stopColor="var(--accent-2)" />
                    <stop offset="100%" stopColor="var(--accent)" />
                  </linearGradient>
                </defs>
                <path d="M40,100 Q140,40 200,90 T380,80" fill="none" stroke="url(#route)" strokeWidth="2.5" strokeDasharray="4 3" />
                <circle cx="40" cy="100" r="6" fill="var(--accent-2)" />
                <text x="40" y="124" textAnchor="middle" fontFamily="var(--mono)" fontSize="9" fill="var(--fg-2)" letterSpacing="2">HASSELT · BE</text>
                <circle cx="380" cy="80" r="9" fill="var(--accent)" />
                <circle cx="380" cy="80" r="13" fill="none" stroke="var(--accent)" strokeWidth="1" opacity="0.5">
                  <animate attributeName="r" from="9" to="22" dur="2s" repeatCount="indefinite" />
                  <animate attributeName="opacity" from="0.7" to="0" dur="2s" repeatCount="indefinite" />
                </circle>
                <text x="380" y="62" textAnchor="middle" fontFamily="var(--mono)" fontSize="9" fill="var(--fg)" letterSpacing="2">HUNTERSVILLE · NC</text>
                <text x="200" y="160" textAnchor="middle" fontFamily="var(--mono)" fontSize="10" fill="var(--accent)" letterSpacing="2">≈ 7,000 KM · BRU → CLT</text>
              </svg>
            </div>
          </div>
          <figure className="stage-photo">
            <figcaption>
              <span className="lbl">{T("DARLINGTON · TRACKSIDE", "DARLINGTON · LANGS DE BAAN", lang)}</span>
              <p className="line">
                {T(
                  "With the trophy after Tyler Reddick (#45 · 23XI Racing) took the Goodyear 400 at Darlington Raceway.",
                  "Met de trofee na de overwinning van Tyler Reddick (#45 · 23XI Racing) in de Goodyear 400 op Darlington Raceway.",
                  lang
                )}
              </p>
              <p className="sub">
                {T(
                  "Trackside in the team garage, right after the win - one of the moments the internship turned from a study placement into something I'll carry with me.",
                  "Langs de baan in de garage, vlak na de overwinning - één van die momenten waarop de stage van schoolopdracht naar iets blijvends omsloeg.",
                  lang
                )}
              </p>
            </figcaption>
            <img
              src="assets/darlington_win.jpeg"
              alt="Martijn with the Darlington trophy after Tyler Reddick's #45 (23XI Racing) win"
              loading="lazy"
            />
          </figure>
          <div className="body">
            <section><h4>{labels.goal}</h4><p>{TR(stage.goal, lang)}</p></section>
            <section><h4>{labels.personal}</h4><p>{TR(stage.personalGoal, lang)}</p></section>
            <section><h4>{labels.did}</h4><p>{TR(stage.did, lang)}</p></section>
            <section><h4>{labels.learned}</h4><p>{TR(stage.learned, lang)}</p></section>
            <section className="span-2"><h4>{labels.reflection}</h4><p>{TR(stage.reflection, lang)}</p></section>
          </div>
        </article>

        <article className="selected-card">
          <div className="meta">
            <h3>{TR(hack.title, lang)}</h3>
            <span className="sub">{TR(hack.subtitle, lang)}</span>
            <p className="meta-desc">{TR(hack.description, lang)}</p>
            <div className="meta-tags">
              <span className="tag accent">SCORE 67%</span>
              <span className="tag">{T("RANK 9 / 11", "PLAATS 9 / 11", lang)}</span>
              <span className="tag">PYTHON · ML</span>
            </div>
          </div>
          <div className="body">
            <section><h4>{labels.goal}</h4><p>{TR(hack.goal, lang)}</p></section>
            <section><h4>{labels.personal}</h4><p>{TR(hack.personalGoal, lang)}</p></section>
            <section><h4>{labels.did}</h4><p>{TR(hack.did, lang)}</p></section>
            <section><h4>{labels.learned}</h4><p>{TR(hack.learned, lang)}</p></section>
            <section className="span-2"><h4>{labels.reflection}</h4><p>{TR(hack.reflection, lang)}</p></section>
          </div>
        </article>

        <article className="selected-card">
          <div className="meta">
            <h3>{TR(pw.title, lang)}</h3>
            <span className="sub">{TR(pw.subtitle, lang)}</span>
            <p className="meta-desc">{TR(pw.description, lang)}</p>
            <div className="meta-tags">
              <span className="tag">{T("TEAM KICK-OFF", "TEAM KICK-OFF", lang)}</span>
              <span className="tag">{T("JOB EVENT", "JOB EVENT", lang)}</span>
              <span className="tag">{T("RESEARCH PROJECT", "RESEARCH PROJECT", lang)}</span>
            </div>
          </div>
          <div className="body">
            <section><h4>{labels.goal}</h4><p>{TR(pw.goal, lang)}</p></section>
            <section><h4>{labels.personal}</h4><p>{TR(pw.personalGoal, lang)}</p></section>
            <section><h4>{labels.did}</h4><p>{TR(pw.did, lang)}</p></section>
            <section><h4>{labels.learned}</h4><p>{TR(pw.learned, lang)}</p></section>
            <section className="span-2"><h4>{labels.reflection}</h4><p>{TR(pw.reflection, lang)}</p></section>
          </div>
        </article>
      </div>
    </section>
  );
};

// ───── Timeline ────────────────────────────────────────────────────────────
window.Timeline = function Timeline({ lang }) {
  const yr2 = D.timeline.year2;
  const yr3 = D.timeline.year3;

  const renderRow = (events, yearKey, yearLabel, yearDesc) => (
    <div className="timeline-year-row">
      <div className="timeline-year-label">
        <span className="badge">{yearKey}</span>
        <span>{yearLabel}</span>
        <span className="desc">· {yearDesc}</span>
      </div>
      <div className="timeline-track">
        <div className="axis" />
        {events.map((e, i) => {
          const left = events.length === 1 ? 50 : (i / (events.length - 1)) * 100;
          const above = i % 2 === 0;
          const clickable = !!e.activityId;
          const onJump = clickable
            ? () => window.dispatchEvent(new CustomEvent("scrollToActivity", { detail: e.activityId }))
            : undefined;
          const onKey = clickable
            ? (ev) => { if (ev.key === "Enter" || ev.key === " ") { ev.preventDefault(); onJump(); } }
            : undefined;
          return (
            <div
              key={e.id}
              className={"timeline-event t-" + e.type + (e.marquee ? " marquee" : "") + (above ? " above" : " below") + (clickable ? " clickable" : "")}
              style={{ left: `calc(64px + ${left}% - ${left * 1.28}px - 46px)`, top: above ? 18 : 134 }}
              onClick={onJump}
              onKeyDown={onKey}
              role={clickable ? "button" : undefined}
              tabIndex={clickable ? 0 : undefined}
              aria-label={clickable ? `Jump to activity: ${e.label}` : undefined}
            >
              {!above && <div className="stem" />}
              <div className="dot" />
              {above && <div className="stem" />}
              <span className="label" style={{ marginTop: above ? 14 : 8 }}>{e.label}</span>
              <span className="date">{e.date}</span>
              <span className="desc">{e.desc}</span>
            </div>
          );
        })}
      </div>
    </div>
  );

  return (
    <section className="section" id="timeline">
      <div className="section-head">
        <div>
          <span className="eyebrow">{T("Race Season", "Race-seizoen", lang)}</span>
          <h2 className="section-title">{T("The season calendar", "De seizoenskalender", lang)}</h2>
          <p className="section-sub">{T(
            "Two consecutive seasons - 2TIN (year 2) and 3TIN (year 3, starting at the Innovation Route). Every round a milestone.",
            "Twee seizoenen achter elkaar - 2TIN (jaar 2) en 3TIN (jaar 3, vanaf de Innovation Route). Elke ronde een mijlpaal.",
            lang
          )}</p>
        </div>
      </div>

      <div className="timeline-frame">
        <div className="timeline-legend">
          <span><i style={{ background: "var(--accent-2)" }} /> {T("Seminar", "Seminar", lang)}</span>
          <span><i style={{ background: "var(--accent)" }} /> {T("Innovation", "Innovatie", lang)}</span>
          <span><i style={{ background: "var(--warn)" }} /> {T("Personal dev", "Persoonlijk", lang)}</span>
          <span><i style={{ background: "var(--good)" }} /> {T("International", "Internationaal", lang)}</span>
          <span><i style={{ background: "var(--silver)" }} /> {T("Future", "Toekomst", lang)}</span>
        </div>
        <div className="timeline-scroll">
          {renderRow(yr2, "Y2",
            T("2TIN · Year 2", "2TIN · Jaar 2", lang),
            T("Projectweek → seminars", "Projectweek → seminaries", lang)
          )}
          {renderRow(yr3, "Y3",
            T("3TIN · Year 3", "3TIN · Jaar 3", lang),
            T("Innovation route → US Internship → future", "Innovation route → Stage USA → toekomst", lang)
          )}
        </div>
      </div>
    </section>
  );
};

// ───── PXL X-Factor block ──────────────────────────────────────────────────
function XFactor({ lang }) {
  const xf = D.xFactor;
  return (
    <div className="xfactor-card">
      <div className="xfactor-head">
        <div>
          <p className="lbl">{T("PXL framework", "PXL-kader", lang)}</p>
          <h3>{T("The PXL X-Factor - my four axes", "De PXL X-Factor - mijn vier assen", lang)}</h3>
        </div>
        <span className="stamp">{T("PERSONAL REFLECTION", "EIGEN REFLECTIE", lang)}</span>
      </div>

      <div className="xfactor-x-stage">
        <svg
          className="xfactor-x-svg"
          viewBox="0 0 800 550"
          preserveAspectRatio="none"
          aria-hidden="true"
        >
          <defs>
            <linearGradient id="xfArmA" x1="0" y1="0" x2="1" y2="1">
              <stop offset="0%" stopColor="var(--accent)" />
              <stop offset="100%" stopColor="var(--accent-2)" />
            </linearGradient>
            <linearGradient id="xfArmB" x1="1" y1="0" x2="0" y2="1">
              <stop offset="0%" stopColor="var(--accent-2)" />
              <stop offset="100%" stopColor="var(--accent)" />
            </linearGradient>
            <radialGradient id="xfHalo" cx="0.5" cy="0.5" r="0.5">
              <stop offset="0%" stopColor="rgba(255,46,62,0.22)" />
              <stop offset="100%" stopColor="rgba(255,46,62,0)" />
            </radialGradient>
          </defs>
          <rect x="220" y="120" width="360" height="310" fill="url(#xfHalo)" />
          <line x1="290" y1="170" x2="510" y2="380" stroke="url(#xfArmA)" strokeWidth="3" strokeLinecap="round" />
          <line x1="510" y1="170" x2="290" y2="380" stroke="url(#xfArmB)" strokeWidth="3" strokeLinecap="round" />
          <circle cx="400" cy="275" r="22" fill="var(--bg)" stroke="var(--accent)" strokeWidth="2" />
          <text
            x="400" y="282"
            textAnchor="middle"
            fontFamily="var(--display)"
            fontSize="22"
            fontWeight="700"
            fill="var(--accent)"
          >X</text>
        </svg>
        {xf.axes.map((a, i) => {
          const corner = ["tl", "tr", "bl", "br"][i] || "tl";
          return (
            <div key={a.id} className={"xfactor-x-cell " + corner}>
              <div className="lbl">{TR(a.label, lang)}</div>
              <div className="note">{TR(a.note, lang)}</div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

// ───── Final reflection ────────────────────────────────────────────────────
window.Final = function Final({ lang }) {
  const r = D.finalReflection;
  return (
    <section className="section" id="reflection">
      <div className="section-head">
        <div>
          <span className="eyebrow">{T("Finish Line", "Eindstreep", lang)}</span>
          <h2 className="section-title">{T("The post-race debrief", "De post-race debrief", lang)}</h2>
          <p className="section-sub">{T(
            "Goals reached? Who have I become? Next steps?",
            "Doelen behaald? Wie ben ik geworden? Volgende stappen?",
            lang
          )}</p>
        </div>
      </div>

      <div className="final-grid">
        <div className="final-card"><span className="lbl">{T("Goals reached", "Doelen behaald", lang)}</span><p>{TR(r.goalsReached, lang)}</p></div>
        <div className="final-card"><span className="lbl">{T("Who I am now", "Wie ik nu ben", lang)}</span><p>{TR(r.whoIAm, lang)}</p></div>
        <div className="final-card span2"><span className="lbl">{T("What I learned", "Wat ik geleerd heb", lang)}</span><p>{TR(r.learned, lang)}</p></div>
        <div className="final-card"><span className="lbl">{T("Strengths", "Sterktes", lang)}</span><p>{TR(r.strengths, lang)}</p></div>
        <div className="final-card"><span className="lbl">{T("Growth points", "Groeipunten", lang)}</span><p>{TR(r.growth, lang)}</p></div>
        <div className="final-card span2"><span className="lbl">{T("Next steps", "Volgende stappen", lang)}</span><p>{TR(r.nextSteps, lang)}</p></div>
      </div>

      <XFactor lang={lang} />

      <div className="final-grid" style={{ marginTop: 16 }}>
        <div className="final-card span2 future"><span className="lbl">{T("THE FUTURE", "DE TOEKOMST", lang)}</span><p className="future-text">{TR(r.future, lang)}</p></div>
      </div>
    </section>
  );
};

// ───── Contact ─────────────────────────────────────────────────────────────
window.Contact = function Contact({ lang }) {
  return (
    <section className="section" id="contact">
      <div className="contact-frame">
        <div className="contact-eyebrow">{T("Next race", "Volgende race", lang)}</div>
        <h2>{T("Ready for the next round.", "Klaar voor de volgende ronde.", lang)}</h2>
        <p className="sub">{T(
          "Looking for data / AI roles in motorsport, race engineering or pitstop analytics. Open to junior roles and conversations.",
          "Op zoek naar een data- of AI-rol in motorsport, race-engineering of pitstop-analytics. Open voor junior rollen en gesprekken.",
          lang
        )}</p>
        <div className="contact-row">
          <a className="btn btn-prim" href={`mailto:${D.identity.email}`}>{D.identity.email}</a>
          <a className="btn btn-secondary" href={D.identity.linkedin} target="_blank" rel="noopener noreferrer">LinkedIn →</a>
        </div>
      </div>
    </section>
  );
};
