/* global React, ReactDOM, window */
const { useState, useEffect, useRef } = React;
const { Header, Footer, Icon, Eyebrow, SectionHeading, useSharedLang, LangTweak } = window;

const TWEAK_DEFAULS = /*EDITMODE-BEGIN*/{
  "lang": "en",
  "headline": "concrete"
}/*EDITMODE-END*/;

const EMAIL = "hello@cantho2030.com";

// =====================================================================
// Home — Cần Thơ 2030 Innovation Forum (v0.13)
// A Forum landing page, powered by the Challenge Programme. Multi-role
// magnet; sponsor-priority conversion. 9 sections (brief §5):
// Hero+footing · Proof strip · Choose-your-role · Why now · How it works
// · Momentum scoreboard · Forum snapshot · Proof & partners · Final CTA.
// =====================================================================

const F = () => (window.CT_FORUM || { en: {}, vi: {} });
const SP = () => (window.CT_SPEAKERS || { en: {}, vi: {} });
const UNI = () => ((window.CT_PARTNERS && window.CT_PARTNERS.universities) || { en: {}, vi: {} });
const ORG = () => ((window.CT_PARTNERS && window.CT_PARTNERS.organizer) || { en: [], vi: [] });

// vertical → accent
const vAccent = (v = "") => {
  const s = v.toLowerCase();
  if (s.includes("climate") || s.includes("agri") || s.includes("academic") || s.includes("học")) return "green";
  if (s.includes("regtech") || s.includes("aqua")) return "indigo";
  return "gold";
};
const accentChip = {
  indigo: "bg-ct-indigo-50 text-ct-indigo-900 border-ct-indigo-200",
  green: "bg-ct-green-50 text-ct-green-700 border-ct-green-200",
  gold: "bg-ct-gold-50 text-ct-gold-800 border-ct-gold-200",
};
const VChip = ({ v }) => (
  <span className={`inline-flex items-center rounded-md border px-2 py-0.5 text-[10px] font-mono tracking-wide uppercase ${accentChip[vAccent(v)]}`}>{v}</span>
);

const Placeholder = ({ label, className = "", ratio = "aspect-[4/3]" }) => (
  <div className={`relative overflow-hidden rounded-md border border-gray-200 ${ratio} ${className}`}
       style={{ backgroundImage: "repeating-linear-gradient(135deg, oklch(0.95 0.01 250) 0 10px, oklch(0.97 0.008 250) 10px 20px)" }}>
    <span className="absolute inset-0 flex items-center justify-center px-3 text-center text-[10px] font-mono tracking-wide uppercase text-gray-500">{label}</span>
  </div>
);

const LogoRect = ({ name }) => (
  <span className="inline-flex items-center rounded-md border border-gray-200 bg-gray-50 px-2.5 py-1 text-xs font-medium text-ct-indigo-900 whitespace-nowrap">{name}</span>
);

// =====================================================================
// 1 — Hero (rework §2/§3): new H1 + footing proof line + status strip +
//      3 weighted primary CTAs + 4 secondary CTAs + restrained motion.
// =====================================================================
const ForumHero = ({ t, headline }) => {
  const ref = useRef(null);
  useEffect(() => {
    const id = requestAnimationFrame(() => ref.current && ref.current.setAttribute("data-hero-in", ""));
    return () => cancelAnimationFrame(id);
  }, []);
  const h1 = (t.hero.h1Alts && t.hero.h1Alts[headline]) || t.hero.h1;
  let i = 0;
  const rise = () => ({ "--i": i++ });
  return (
    <section ref={ref} data-screen-label="01 Hero" className="relative overflow-hidden bg-ct-indigo-900 text-white">
      <div className="absolute inset-0 opacity-30" aria-hidden="true"
           style={{ background: "radial-gradient(ellipse at 22% 78%, oklch(0.5 0.09 200) 0%, transparent 55%), radial-gradient(ellipse at 88% 12%, oklch(0.55 0.1 80) 0%, transparent 58%), linear-gradient(180deg, oklch(0.22 0.05 250), oklch(0.15 0.045 250))" }}/>
      {/* river-contour motif — abstract, geometric */}
      <svg className="absolute inset-0 h-full w-full opacity-[0.07]" aria-hidden="true" preserveAspectRatio="none" viewBox="0 0 1200 600" fill="none" stroke="white" strokeWidth="1.2">
        {[0,1,2,3,4,5,6].map(n => (
          <path key={n} d={`M-50 ${120 + n*70} C 250 ${60 + n*70}, 450 ${200 + n*70}, 700 ${150 + n*70} S 1100 ${90 + n*70}, 1260 ${170 + n*70}`}/>
        ))}
      </svg>
      <div className="absolute inset-0 opacity-[0.04]" aria-hidden="true"
           style={{ backgroundImage: "linear-gradient(rgba(255,255,255,.6) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.6) 1px, transparent 1px)", backgroundSize: "44px 44px" }}/>

      <div className="relative mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-14 sm:py-16 lg:py-20">
        <p className="hero-rise inline-flex items-center gap-2 rounded-full border border-white/20 bg-white/[0.06] px-3.5 py-1.5 text-[11px] font-mono tracking-[0.18em] text-white/75 uppercase" style={rise()}>
          <span className="size-1.5 rounded-full bg-white/50 pulse-dot"/>{t.hero.eyebrow}
        </p>
        <h1 className="hero-rise mt-6 max-w-4xl text-3xl leading-[1.1] font-semibold tracking-tight text-balance sm:text-4xl lg:text-[3.25rem]" style={rise()}>{h1}</h1>
        <p className="hero-rise mt-5 max-w-2xl text-base sm:text-lg leading-relaxed text-white/85" style={rise()}>{t.hero.sub}</p>

        {/* CTAs — Request Invitation loudest (white); Sponsor stays gold but quieter (outline) */}
        <div className="hero-rise mt-7 flex flex-col gap-3.5" style={rise()}>
          <div className="flex flex-col sm:flex-row flex-wrap gap-3">
            {t.hero.primary.map((c, idx) => {
              const sponsor = c.weight === "sponsor";
              const base = "inline-flex h-12 items-center justify-center gap-2 rounded-md px-5 text-sm transition-all";
              const cls = sponsor
                ? `${base} border border-ct-gold-400/70 text-ct-gold-200 font-medium hover:bg-ct-gold-400/10`
                : idx === 0
                  ? `${base} bg-white text-ct-indigo-900 font-semibold hover:bg-white/90 hover:-translate-y-0.5`
                  : `${base} border border-white/35 text-white font-medium hover:bg-white/10`;
              return (
                <a key={idx} href={c.href || `#${c.scrollTo}`} className={cls}>
                  {c.label}<Icon name="arrow-right" className="size-4"/>
                </a>
              );
            })}
          </div>
          <div className="flex flex-col sm:flex-row flex-wrap gap-2.5">
            {t.hero.secondary.map((c, idx) => (
              <a key={idx} href={c.href || `#${c.scrollTo}`}
                 className="inline-flex h-11 items-center justify-center gap-1.5 rounded-md px-3 text-sm font-medium text-white/70 hover:text-white hover:bg-white/[0.06] transition-colors">
                {c.label}<Icon name="arrow-right" className="size-3.5"/>
              </a>
            ))}
          </div>
        </div>

        {/* Status strip */}
        <dl className="hero-rise mt-8 flex flex-wrap gap-x-10 gap-y-4 border-t border-white/12 pt-6" style={rise()}>
          {t.hero.status.map((s, idx) => (
            <div key={idx}>
              <dt className="text-[10px] font-mono tracking-[0.18em] uppercase text-white/60">{s.label}</dt>
              <dd className="mt-1 text-sm font-medium text-white">{s.value}</dd>
            </div>
          ))}
        </dl>

        {/* Footing proof line — corrected 40-engineer framing, compressed to 2 lines below the CTAs (§3) */}
        <div className="hero-rise mt-7 max-w-2xl border-l-2 border-white/25 pl-4" style={rise()}>
          <p className="text-[10px] font-mono tracking-[0.18em] uppercase text-white/55">{t.hero.footingLabel}</p>
          <p className="mt-1.5 text-sm leading-relaxed text-white/75">{t.hero.footing}</p>
        </div>
      </div>
    </section>
  );
};

// =====================================================================
// 2 — Proof strip (NEW §5#2): thin early credibility band.
// =====================================================================
const ProofStrip = ({ t }) => (
  <section data-screen-label="02 Proof strip" className="bg-white border-b border-gray-200">
    <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-7">
      <div className="flex flex-col gap-6 lg:flex-row lg:items-center lg:gap-8">
        <p className="shrink-0 text-[11px] font-mono tracking-[0.2em] uppercase text-ct-indigo-500">{t.proof.label}</p>
        <div className="grid flex-grow grid-cols-2 gap-x-6 gap-y-5 sm:grid-cols-4">
          {t.proof.items.map((it, i) => (
            <div key={i} className="flex flex-col border-l-2 border-ct-indigo-400/40 pl-3.5">
              <span className="text-lg font-semibold tracking-tight text-ct-indigo-900 tabular-nums leading-none">{it.stat}</span>
              <span className="mt-1.5 text-xs leading-5 text-gray-600 text-pretty">{it.label}</span>
            </div>
          ))}
        </div>
      </div>
      <p className="mt-5 text-[11px] font-mono leading-5 tracking-wide text-gray-500 italic">{t.proof.note}</p>
    </div>
  </section>
);

// =====================================================================
// 3 — Choose your role (NEW §4): six-path router; Sponsor heaviest.
// =====================================================================
const ChooseRole = ({ t }) => (
  <section data-screen-label="03 Choose your role" className="bg-gray-50 border-b border-gray-200 py-16 lg:py-20">
    <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
      <Eyebrow>{t.role.eyebrow}</Eyebrow>
      <SectionHeading className="mt-4">{t.role.h2}</SectionHeading>
      <p className="mt-3 max-w-2xl text-base leading-relaxed text-gray-600 text-pretty">{t.role.intro}</p>
      <div className="mt-9 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
        {t.role.paths.map((p) => {
          const sponsor = p.weight === "sponsor";
          return (
            <a key={p.key} href={p.href || `#${p.scrollTo}`}
               className={`rolecard group flex flex-col rounded-xl border p-6 ${sponsor
                 ? "border-ct-gold-400 bg-ct-gold-400 text-ct-indigo-900 shadow-sm hover:shadow-md sm:row-span-1 lg:col-span-1"
                 : "border-gray-200 bg-white hover:border-ct-indigo-300 hover:shadow-sm"}`}>
              <div className="flex items-center justify-between">
                <span className={`text-[11px] font-mono tracking-[0.16em] uppercase ${sponsor ? "text-ct-indigo-900/70" : "text-ct-indigo-500"}`}>{p.micro}</span>
                {sponsor && <span className="rounded-md bg-ct-indigo-900 px-2 py-0.5 text-[9px] font-mono tracking-[0.16em] uppercase text-ct-gold-300">Priority</span>}
              </div>
              <h3 className={`mt-3 text-xl font-semibold tracking-tight ${sponsor ? "text-ct-indigo-900" : "text-ct-indigo-900"}`}>{p.label}</h3>
              <p className={`mt-2 text-sm leading-6 flex-grow ${sponsor ? "text-ct-indigo-900/80" : "text-gray-600"}`}>{p.desc}</p>
              <span className={`mt-4 inline-flex items-center gap-1.5 text-sm font-medium ${sponsor ? "text-ct-indigo-900" : "text-ct-indigo-900"} group-hover:gap-2.5 transition-all`}>
                {p.label}<Icon name="arrow-right" className="size-4"/>
              </span>
            </a>
          );
        })}
      </div>
    </div>
  </section>
);

// =====================================================================
// 4 — Why Cần Thơ, why now — compressed to a BAND (keeps the Resolution-59
//      frame; metrics fold into a compact side panel). [Cowork amendment]
// =====================================================================
const WhyNow = ({ t }) => (
  <section data-screen-label="04 Why now" className="bg-white py-14 lg:py-16 border-b border-gray-200">
    <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
      <div className="grid gap-10 lg:grid-cols-[1.5fr_1fr] lg:gap-16 items-start">
        <div>
          <Eyebrow>{t.whyNow.eyebrow}</Eyebrow>
          <SectionHeading className="mt-3">{t.whyNow.h2}</SectionHeading>
          <div className="mt-5 space-y-3 text-base leading-relaxed text-gray-700">
            <p>{t.whyNow.body[0]}</p>
            <p className="font-medium text-ct-indigo-900">{t.whyNow.body[1]}</p>
          </div>
          <ul className="mt-7 grid gap-x-6 gap-y-4 sm:grid-cols-3">
            {t.whyNow.highlights.map((b, i) => (
              <li key={i} className="border-t-2 border-ct-indigo-200 pt-3">
                <span className="font-mono text-[11px] tracking-wide text-ct-indigo-500">{b.n}</span>
                <h3 className="mt-1.5 text-sm font-semibold leading-snug text-ct-indigo-900 text-balance">{b.heading}</h3>
                <p className="mt-1.5 text-xs leading-5 text-gray-600 text-pretty">{b.body}</p>
              </li>
            ))}
          </ul>
        </div>

        {/* Scale metrics — compact side panel */}
        <div className="overflow-hidden rounded-xl border border-gray-200">
          <div className="grid grid-cols-2 gap-px bg-gray-200">
            {t.whyNow.scale.map((m, i) => (
              <div key={i} className="bg-white p-4">
                <p className="text-2xl font-semibold tracking-tight text-ct-indigo-900 tabular-nums">{m.value}</p>
                <p className="mt-1 text-xs font-medium text-ct-indigo-900">{m.label}</p>
                <p className="mt-0.5 text-[10px] font-mono leading-4 tracking-wide text-gray-500">{m.note}</p>
              </div>
            ))}
          </div>
          <p className="bg-gray-50 px-4 py-3 text-[11px] font-mono italic leading-5 text-gray-500">{t.whyNow.disclaimer}</p>
        </div>
      </div>
    </div>
  </section>
);

// =====================================================================
// 5 — How it works (NEW §5#5): the validated pathway, progress-bias.
// =====================================================================
const HowItWorks = ({ t, lang }) => (
  <section data-screen-label="05 How it works" className="bg-gray-50 py-16 lg:py-20 border-y border-gray-200">
    <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
      <Eyebrow>{t.how.eyebrow}</Eyebrow>
      <SectionHeading className="mt-4">{t.how.h2}</SectionHeading>
      <p className="mt-3 max-w-2xl text-base leading-relaxed text-gray-600 text-pretty">{t.how.intro}</p>

      <ol className="mt-12 grid gap-5 sm:grid-cols-2 lg:grid-cols-6 relative">
        {/* connecting line on lg */}
        <span aria-hidden="true" className="pointer-events-none absolute left-0 right-0 top-5 hidden h-px lg:block"
              style={{ background: "linear-gradient(90deg, oklch(0.6 0.105 250) 0%, oklch(0.5 0.105 155) 100%)" }}/>
        {t.how.steps.map((s, i) => (
          <li key={i} className="path-node relative flex flex-col" style={{ "--i": i }}>
            <span className={`relative z-10 inline-flex size-10 items-center justify-center rounded-full text-sm font-semibold tabular-nums ${i === t.how.steps.length - 1 ? "bg-ct-green-500 text-white ring-4 ring-ct-green-100" : "bg-ct-indigo-900 text-white ring-4 ring-gray-50"}`}>{s.n}</span>
            <h3 className="mt-4 text-sm font-semibold text-ct-indigo-900">{s.title}</h3>
            <p className="mt-1.5 text-xs leading-5 text-gray-600 text-pretty">{s.desc}</p>
          </li>
        ))}
      </ol>

      <div className="mt-10 flex flex-col gap-3 rounded-xl border border-ct-indigo-200 bg-ct-indigo-50/50 p-5 sm:flex-row sm:items-center sm:justify-between">
        <p className="text-sm leading-6 text-ct-indigo-900">{t.how.note}</p>
        <a href={t.how.ctaHref} className="shrink-0 inline-flex h-10 items-center justify-center gap-2 rounded-md bg-ct-indigo-900 px-4 text-sm font-medium text-white hover:bg-ct-indigo-800 transition-colors">
          {t.how.cta}<Icon name="arrow-right" className="size-3.5"/>
        </a>
      </div>
    </div>
  </section>
);

// =====================================================================
// 6 — Momentum scoreboard (REWORK + promote §5#6): Speakers + Showcase,
//      four-state counts framed as visibly filling.
// =====================================================================
const StateCount = ({ n, label, tone }) => {
  const map = {
    confirmed: "border-ct-green-200 bg-ct-green-50 text-ct-green-700",
    invited: "border-ct-indigo-200 bg-ct-indigo-50 text-ct-indigo-800",
    discussion: "border-ct-gold-300 bg-ct-gold-50 text-ct-gold-800",
    target: "border-gray-300 bg-gray-100 text-gray-600",
  };
  const dot = { confirmed: "bg-ct-green-600", invited: "bg-ct-indigo-400", discussion: "bg-ct-gold-500", target: "bg-gray-400" };
  return (
    <div className={`flex items-center gap-2.5 rounded-md border px-3.5 py-2.5 ${map[tone]}`}>
      <span className={`size-2 rounded-full ${dot[tone]}`}/>
      <span className="text-xl font-semibold tabular-nums leading-none">{n}</span>
      <span className="text-[10px] font-mono tracking-[0.14em] uppercase">{label}</span>
    </div>
  );
};

const Momentum = ({ t, lang }) => {
  const sp = SP()[lang] || SP().en || {};
  const booths = (window.CT_BOOTHS && (window.CT_BOOTHS[lang] || window.CT_BOOTHS.en)) || null;
  const sl = t.speakers.stateLabels;
  const ms = t.momentum.stateLabels;
  const strip = [
    ...(sp.invited || []).map(r => ({ ...r, state: "invited" })),
    ...(sp.target || []).map(r => ({ ...r, state: "target" })),
  ];
  const stateBadge = {
    invited: "border-ct-indigo-200 bg-ct-indigo-50 text-ct-indigo-800",
    target: "border-gray-300 bg-gray-100 text-gray-500",
  };
  const reserved = booths && booths.tba && booths.tba[0] ? booths.tba[0].count : 0;

  return (
    <section id="momentum" data-screen-label="06 Momentum scoreboard" className="bg-white py-16 lg:py-20 scroll-mt-20">
      <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
        <div className="flex flex-wrap items-end justify-between gap-4">
          <div className="max-w-2xl">
            <Eyebrow><span className="inline-flex items-center gap-1.5"><span className="size-1.5 rounded-full bg-ct-green-500 pulse-dot"/>{t.momentum.eyebrow}</span></Eyebrow>
            <SectionHeading className="mt-4">{t.momentum.h2}</SectionHeading>
            <p className="mt-3 text-base leading-relaxed text-gray-600 text-pretty">{t.momentum.intro}</p>
          </div>
        </div>

        {/* Lead counters — three big numbers + one progress bar toward the 25-booth cap */}
        {(() => {
          const spConf = (sp.confirmed || []).length, spInv = (sp.invited || []).length;
          const bConf = booths ? booths.confirmed.length : 0;
          const bInv = booths ? booths.invited.length : 0;
          const bTgt = booths ? booths.target.length : 0;
          const confirmedTotal = spConf + bConf;
          const invitedTotal = spInv + bInv;
          const spokenFor = bConf + bInv + bTgt;
          const pct = Math.min(100, Math.round((spokenFor / 25) * 100));
          const vi = lang === "vi";
          return (
            <div className="mt-10 grid gap-4 sm:grid-cols-3">
              <div className="rounded-xl border-2 border-ct-green-300 bg-ct-green-50/60 p-6">
                <div className="flex items-center gap-2"><span className="size-2 rounded-full bg-ct-green-600"/><span className="text-[11px] font-mono tracking-[0.16em] uppercase text-ct-green-700">{ms.confirmed}</span></div>
                <p className="mt-3 text-5xl font-semibold tracking-tight text-ct-green-700 tabular-nums leading-none">{confirmedTotal}</p>
                <p className="mt-2.5 text-sm leading-5 text-gray-600">{vi ? "di\u1ec5n gi\u1ea3 + \u0111\u1ed1i t\u00e1c tr\u01b0ng b\u00e0y \u0111\u00e3 ch\u1ed1t" : "speakers + showcase partners locked in"}</p>
              </div>
              <div className="rounded-xl border border-ct-indigo-200 bg-ct-indigo-50/50 p-6">
                <div className="flex items-center gap-2"><span className="size-2 rounded-full bg-ct-indigo-400"/><span className="text-[11px] font-mono tracking-[0.16em] uppercase text-ct-indigo-700">{ms.invited}</span></div>
                <p className="mt-3 text-5xl font-semibold tracking-tight text-ct-indigo-800 tabular-nums leading-none">{invitedTotal}</p>
                <p className="mt-2.5 text-sm leading-5 text-gray-600">{vi ? "l\u1eddi m\u1eddi \u0111\u00e3 g\u1eedi, \u0111ang trao \u0111\u1ed5i" : "invitations out, in active discussion"}</p>
              </div>
              <div className="rounded-xl border border-gray-200 bg-white p-6">
                <div className="flex items-center gap-2"><span className="size-2 rounded-full bg-gray-400"/><span className="text-[11px] font-mono tracking-[0.16em] uppercase text-gray-600">{vi ? "gian \u0111\u00e3 \u0111\u01b0\u1ee3c gi\u1eef ch\u1ed7" : "booths spoken for"}</span></div>
                <p className="mt-3 text-5xl font-semibold tracking-tight text-ct-indigo-900 tabular-nums leading-none">{spokenFor}<span className="text-2xl text-gray-400"> / 25</span></p>
                <div className="mt-3.5 h-2.5 w-full overflow-hidden rounded-full bg-gray-100">
                  <div className="h-full rounded-full bg-gradient-to-r from-ct-green-500 to-ct-indigo-400" style={{ width: pct + "%" }}/>
                </div>
                <p className="mt-2 text-[11px] font-mono tracking-wide text-gray-500">{vi ? `${pct}% ti\u1ebfn t\u1edbi m\u1ee9c tr\u1ea7n 25 gian` : `${pct}% toward the 25-booth cap`}</p>
              </div>
            </div>
          );
        })()}

        {/* --- Speakers --- */}
        <div className="mt-12">
          <div className="flex flex-wrap items-center justify-between gap-3">
            <h3 className="text-lg font-semibold tracking-tight text-ct-indigo-900">{t.momentum.speakersTitle}</h3>
            <div className="flex flex-wrap gap-2.5">
              <StateCount n={(sp.confirmed || []).length} label={ms.confirmed} tone="confirmed"/>
              <StateCount n={(sp.invited || []).length} label={ms.invited} tone="invited"/>
              <StateCount n={(sp.target || []).length} label={ms.target} tone="target"/>
            </div>
          </div>

          <p className="mt-7 text-[11px] font-mono tracking-[0.18em] uppercase text-gray-500">{t.momentum.speakersConfirmed}</p>
          <div className="mt-4 grid gap-5 md:grid-cols-3">
            {(sp.confirmed || []).map((s, i) => (
              <article key={i} className="flex flex-col rounded-xl border border-gray-200 bg-white overflow-hidden">
                <div className="h-1.5 w-full bg-ct-indigo-900"/>
                <div className="flex flex-col flex-grow p-5">
                  <h4 className="text-base font-semibold leading-tight text-ct-indigo-900">{s.name}</h4>
                  {s.nameNote && <p className="text-xs font-mono tracking-wide text-gray-500">{s.nameNote}</p>}
                  <p className="mt-1 text-sm font-medium text-ct-indigo-500">{s.org}</p>
                  <div className="mt-2.5"><VChip v={s.vertical}/></div>
                  <p className="mt-2 text-[11px] font-mono tracking-wide uppercase text-gray-500">{s.day}</p>
                  <p className="mt-2.5 text-sm font-medium text-ct-indigo-900 leading-snug">{s.topic}</p>
                </div>
              </article>
            ))}
          </div>

          {strip.length > 0 && (
            <ul className="mt-5 divide-y divide-gray-100 rounded-xl border border-gray-200 overflow-hidden">
              {strip.map((r, i) => (
                <li key={i} className="flex flex-col gap-2 bg-white p-4 sm:flex-row sm:items-center sm:gap-4">
                  <span className={`inline-flex w-fit shrink-0 items-center rounded-md border px-2 py-0.5 text-[10px] font-mono tracking-wide uppercase ${stateBadge[r.state]}`}>{sl[r.state]}</span>
                  <div className="flex flex-wrap items-center gap-x-3 gap-y-1.5 flex-grow">
                    <VChip v={r.vertical}/>
                    <span className="text-sm font-medium text-ct-indigo-900">{r.topic}</span>
                    <span className="text-xs font-mono text-gray-500">· {r.day} · {t.speakers.slotLabel}: {r.slot}</span>
                  </div>
                </li>
              ))}
            </ul>
          )}

          {/* Nominate-a-speaker CTA (anchor preserved) */}
          <div id="nominate-speaker" className="mt-6 flex flex-col gap-4 rounded-xl border border-ct-indigo-200 bg-ct-indigo-50/50 p-5 sm:flex-row sm:items-center sm:justify-between scroll-mt-20">
            <p className="max-w-2xl text-sm leading-relaxed text-ct-indigo-900">{t.momentum.nomQ}</p>
            <a href={`mailto:${EMAIL}?subject=${encodeURIComponent("[CT2030 Innovation Forum — Speaker nomination]")}`}
               className="shrink-0 inline-flex h-10 items-center justify-center gap-2 rounded-md bg-ct-indigo-900 px-4 text-sm font-medium text-white hover:bg-ct-indigo-800 transition-colors">
              {t.momentum.nomCta}<Icon name="arrow-right" className="size-3.5"/>
            </a>
          </div>
        </div>

        {/* --- Showcase --- */}
        {booths && (
          <div className="mt-14 border-t border-gray-200 pt-12">
            <div className="flex flex-wrap items-center justify-between gap-3">
              <div>
                <h3 className="text-lg font-semibold tracking-tight text-ct-indigo-900">{t.momentum.boothsTitle}</h3>
                <p className="mt-1 text-[11px] font-mono tracking-[0.16em] uppercase text-ct-indigo-500">{t.momentum.boothCap}</p>
              </div>
              <div className="flex flex-wrap gap-2.5">
                <StateCount n={booths.confirmed.length} label={ms.confirmed} tone="confirmed"/>
                <StateCount n={booths.invited.length} label={ms.invited} tone="invited"/>
                <StateCount n={booths.target.length} label={ms.target} tone="target"/>
              </div>
            </div>

            <p className="mt-4 text-[11px] font-mono tracking-wide text-gray-500">{reserved} {lang === "vi" ? "gian giữ cho các đơn đăng ký giai đoạn sau" : "of the 25 booths held in reserve for late-stage applications"}</p>

            <p className="mt-8 text-[11px] font-mono tracking-[0.18em] uppercase text-gray-500">{t.momentum.boothsConfirmed}</p>
            <div className="mt-4 grid gap-4 sm:grid-cols-2 lg:grid-cols-5">
              {booths.confirmed.map((p, i) => (
                <div key={i} className="flex flex-col rounded-xl border border-gray-200 bg-white p-5">
                  <div className="flex h-12 items-center">
                    {p.logo ? (
                      <img src={p.logo} alt={p.name} className="max-h-9 max-w-full object-contain object-left"
                           onError={(e) => { e.currentTarget.style.display = "none"; e.currentTarget.nextSibling.style.display = "flex"; }}/>
                    ) : null}
                    <span className="hidden h-9 w-full items-center rounded-md bg-[repeating-linear-gradient(135deg,#eceef1_0_8px,#f6f7f9_8px_16px)] px-2 font-mono text-[10px] tracking-wide text-gray-500"
                          style={{ display: p.logo ? "none" : "flex" }}>logo pending</span>
                  </div>
                  <p className="mt-3 text-sm font-semibold leading-snug text-ct-indigo-900">{p.name}</p>
                  <p className="mt-1 text-xs leading-5 text-gray-600 flex-grow">{p.role}</p>
                  <span className="mt-3 inline-flex w-fit items-center rounded-md border border-gray-200 bg-gray-50 px-2 py-0.5 text-[10px] font-mono tracking-wide uppercase text-gray-500">{p.track}</span>
                </div>
              ))}
            </div>

            <a href={t.momentum.boothsHref} className="mt-8 inline-flex h-11 items-center gap-2 rounded-md bg-ct-indigo-900 px-5 text-sm font-medium text-white hover:bg-ct-indigo-800 transition-colors">
              {t.momentum.boothsCta}<Icon name="arrow-right" className="size-4"/>
            </a>
          </div>
        )}
      </div>
    </section>
  );
};

// =====================================================================
// 7 — Forum snapshot (KEEP §5#7): Day 1/2/3 cards.
// =====================================================================
const DayCard = ({ d, accent }) => (
  <div className={`flex flex-col rounded-xl border bg-white ${accent}`}>
    <div className="border-b border-gray-200 p-6">
      <p className="text-xs font-mono tracking-[0.16em] uppercase text-ct-indigo-500">{d.tag}</p>
      <h3 className="mt-1.5 text-xl font-semibold tracking-tight text-ct-indigo-900 text-balance">{d.theme}</h3>
      <p className="mt-2 text-sm text-gray-600">{d.purpose}</p>
    </div>
    {d.rows && (
      <ul className="divide-y divide-gray-100 p-2">
        {d.rows.map((r, i) => (
          <li key={i} className="flex flex-col gap-1 p-3 sm:flex-row sm:items-start sm:gap-3">
            <span className="shrink-0 w-24 text-[11px] font-mono tracking-wide uppercase text-gray-500 pt-0.5">{r.block}</span>
            <div className="flex-grow">
              <p className="text-sm leading-6 text-gray-800">{r.activity}</p>
              <span className="mt-1 inline-block text-[10px] font-mono tracking-wide uppercase text-ct-indigo-400">{r.vertical}</span>
            </div>
          </li>
        ))}
      </ul>
    )}
  </div>
);

const Day3Card = ({ d }) => (
  <div className="flex flex-col rounded-xl border-2 border-dashed border-ct-indigo-300 bg-ct-indigo-50/40">
    <div className="border-b border-ct-indigo-200/70 p-6">
      <p className="mb-2 inline-flex items-center gap-1.5 rounded-md border border-ct-indigo-300 bg-white px-2 py-0.5 text-[10px] font-mono tracking-wide uppercase text-ct-indigo-800">{d.optionalTag}</p>
      <p className="text-xs font-mono tracking-[0.16em] uppercase text-ct-indigo-500">{d.tag}</p>
      <h3 className="mt-1.5 text-xl font-semibold tracking-tight text-ct-indigo-900 text-balance">{d.theme}</h3>
      <p className="mt-2 text-sm italic text-gray-600">{d.intro}</p>
    </div>
    <div className="flex flex-col flex-grow p-6">
      <p className="text-[11px] font-mono tracking-[0.16em] uppercase text-ct-indigo-800">{d.eligibilityLabel}</p>
      <ul className="mt-3 space-y-2">
        {d.eligibility.map((e, i) => (
          <li key={i} className="flex gap-2.5 items-start text-sm leading-6 text-gray-700"><Icon name="check" className="size-4 shrink-0 text-ct-indigo-600 mt-0.5"/>{e}</li>
        ))}
      </ul>
      <p className="mt-5 text-[11px] font-mono tracking-[0.16em] uppercase text-ct-indigo-800">{d.shapeLabel}</p>
      <ul className="mt-3 space-y-2 flex-grow">
        {d.shape.map((e, i) => (
          <li key={i} className="flex gap-2.5 items-start text-sm leading-6 text-gray-700"><span className="mt-2 size-1.5 shrink-0 rounded-full bg-ct-indigo-500"/>{e}</li>
        ))}
      </ul>
      <a href="#request-invitation" className="mt-6 inline-flex h-11 items-center justify-center gap-2 rounded-md bg-ct-indigo-900 px-5 text-sm font-semibold text-white hover:bg-ct-indigo-800 transition-colors">{d.cta}<Icon name="arrow-right" className="size-4"/></a>
    </div>
  </div>
);

const ForumSnapshot = ({ t }) => (
  <section id="days" data-screen-label="07 Forum snapshot" className="bg-gray-50 py-16 lg:py-20 border-y border-gray-200 scroll-mt-20">
    <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
      <Eyebrow>{t.days.eyebrow}</Eyebrow>
      <SectionHeading className="mt-4">{t.days.h2}</SectionHeading>
      <div className="mt-10 grid gap-6 lg:grid-cols-3 items-start">
        <DayCard d={t.days.day1} accent="border-ct-indigo-200"/>
        <DayCard d={t.days.day2} accent="border-ct-green-200"/>
        <Day3Card d={t.days.day3}/>
      </div>
      {t.days.venue && (
        <p className="mt-6 flex items-start gap-2.5 max-w-3xl text-sm leading-6 text-gray-600">
          <Icon name="pin" className="size-4 shrink-0 mt-0.5 text-ct-indigo-600"/>{t.days.venue}
        </p>
      )}
    </div>
  </section>
);

// =====================================================================
// 8 — Proof & partners, full (KEEP §5#8): organizer stack + CICT anchor
//      + education network. The considered trust spine, low on the page.
// =====================================================================
const ProofPartners = ({ t, lang }) => {
  const rows = ORG()[lang] || ORG().en || [];
  const u = UNI()[lang] || UNI().en;
  const a = u.anchor;
  return (
    <section data-screen-label="08 Proof & partners" className="bg-white py-16 lg:py-20 border-b border-gray-200">
      <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
        <Eyebrow>{t.cict.eyebrow}</Eyebrow>
        <SectionHeading className="mt-4">{lang === "vi" ? "Ai đứng sau Cần Thơ 2030" : "Who stands behind Cần Thơ 2030"}</SectionHeading>

        {/* Organizer stack */}
        <dl className="mt-10 divide-y divide-gray-100 border-y border-gray-100">
          {rows.map((r, i) => (
            <div key={i} className="grid gap-2 py-4 sm:grid-cols-[14rem_1fr] sm:gap-6 sm:items-baseline">
              <dt className="text-[11px] font-mono tracking-[0.18em] uppercase text-ct-indigo-500">{r.label}</dt>
              <dd className="flex flex-wrap gap-2">
                {r.names.map((n, j) => <LogoRect key={j} name={n}/>)}
              </dd>
            </div>
          ))}
        </dl>
        <p className="mt-5 text-[11px] font-mono tracking-wide text-gray-500 italic">{t.logoPlaceholder} — {lang === "vi" ? "logo thật chờ ký duyệt theo từng đơn vị" : "real logos appear once signed off per entity"}.</p>

        {/* CICT anchor — full row */}
        <div className="mt-12 grid gap-8 rounded-xl border-2 border-ct-indigo-300 bg-ct-indigo-50/40 p-7 lg:grid-cols-[16rem_1fr] lg:gap-12 lg:p-10 items-start">
          <div>
            <Placeholder label="CICT logo · pending sign-off" ratio="aspect-[3/2]"/>
            <p className="mt-3 text-[11px] font-mono tracking-wide uppercase text-ct-indigo-500">{t.cict.hostedLabel}</p>
          </div>
          <div>
            <div className="flex flex-wrap items-center gap-3">
              <span className="text-xl font-semibold tracking-tight text-ct-indigo-900">{a.name}</span>
              <span className="rounded-md bg-ct-indigo-900 px-2 py-0.5 text-[11px] font-mono tracking-wide uppercase text-white whitespace-nowrap">{a.role}</span>
            </div>
            <p className="mt-1.5 text-[11px] font-mono tracking-[0.16em] uppercase text-gray-500">{a.full}</p>
            <p className="mt-4 text-base leading-relaxed text-gray-800">{a.body}</p>
            <blockquote className="mt-6 border-l-2 border-ct-indigo-300 pl-4 text-base italic leading-relaxed text-gray-500">{a.quote}</blockquote>
            <a href={a.url} target="_blank" rel="noopener" className="mt-6 inline-flex items-center gap-1.5 text-sm font-medium text-ct-indigo-900 hover:gap-2.5 transition-all">{t.cict.link}<Icon name="external" className="size-3.5"/></a>
          </div>
        </div>

        <p className="mt-8 max-w-3xl border-l-2 border-ct-indigo-300 pl-4 text-sm italic leading-relaxed text-gray-600">{u.safeguard}</p>

        {/* Education network */}
        <p className="mt-10 text-[11px] font-mono tracking-[0.18em] uppercase text-ct-indigo-500">{t.eduNet.eyebrow}</p>
        <div className="mt-4 grid gap-5 md:grid-cols-3">
          {u.network.map((c, i) => (
            <article key={i} className="flex flex-col rounded-xl border border-gray-200 bg-white p-6">
              <Placeholder label={`${c.name} logo`} ratio="aspect-[3/1]" className="mb-4"/>
              <h3 className="text-base font-semibold text-ct-indigo-900">{c.name}</h3>
              <p className="mt-1 text-[11px] font-mono tracking-wide uppercase text-ct-indigo-500">{c.role}</p>
              <p className="mt-3 text-sm leading-6 text-gray-700">{c.body}</p>
            </article>
          ))}
        </div>
        <p className="mt-6 max-w-3xl text-sm italic leading-relaxed text-gray-500">{t.gate}</p>
      </div>
    </section>
  );
};

// =====================================================================
// 9 — Final CTA (§5#9): Request Invitation primary; Sponsor heaviest.
// =====================================================================
const SponsorBand = ({ t, lang }) => {
  const s = t.sponsorCta;
  return (
    <section data-screen-label="09a Sponsor (heaviest weight)" className="bg-ct-indigo-900 text-white pt-16 lg:pt-20 pb-4">
      <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
        <div className="rounded-xl border border-ct-gold-400/30 bg-gradient-to-br from-ct-gold-400/[0.10] to-transparent p-7 lg:p-10">
          <Eyebrow className="text-ct-gold-300">{s.eyebrow}</Eyebrow>
          <h2 className="mt-4 max-w-3xl text-3xl font-semibold tracking-tight sm:text-4xl text-balance">{s.h2}</h2>
          <p className="mt-4 max-w-3xl text-base leading-relaxed text-white/85">{s.body}</p>

          <div className="mt-9 grid gap-5 lg:grid-cols-[1.3fr_1fr]">
            <div className="grid gap-3 sm:grid-cols-3">
              {s.highlights.map((h, i) => (
                <div key={i} className="rounded-xl border border-white/15 bg-white/[0.04] p-5">
                  <p className="text-sm font-semibold text-ct-gold-300">{h.tier}</p>
                  <p className="mt-2 text-sm leading-6 text-white/85">{h.line}</p>
                </div>
              ))}
            </div>
            <div className="rounded-xl border border-white/15 bg-white/[0.04] p-5">
              <p className="text-[11px] font-mono tracking-[0.16em] uppercase text-ct-gold-300">{s.outcomesLabel}</p>
              <ul className="mt-3 space-y-2.5">
                {s.outcomes.map((o, i) => (
                  <li key={i} className="flex gap-2.5 items-start text-sm leading-6 text-white/85"><Icon name="check" className="size-4 shrink-0 text-ct-gold-400 mt-0.5"/>{o}</li>
                ))}
              </ul>
            </div>
          </div>

          <div className="mt-8 flex flex-col sm:flex-row flex-wrap gap-3">
            <a href={`mailto:${EMAIL}?subject=${encodeURIComponent("[CT2030 Sponsor] Prospectus request — Forum")}`} className="inline-flex h-12 items-center justify-center gap-2 rounded-md bg-ct-gold-400 px-5 text-sm font-semibold text-ct-indigo-900 ring-2 ring-ct-gold-300/40 hover:bg-ct-gold-300 transition-all hover:-translate-y-0.5">{s.ctaProspectus}<Icon name="arrow-right" className="size-4"/></a>
            <a href={`mailto:${EMAIL}?subject=${encodeURIComponent("[CT2030 Sponsor] 15-min scoping call — Forum")}`} className="inline-flex h-12 items-center justify-center gap-2 rounded-md border border-white/30 px-5 text-sm font-medium text-white hover:bg-white/10 transition-colors">{s.ctaCall}</a>
            <a href="Sponsor.html#forum-sponsor" className="inline-flex h-12 items-center justify-center gap-2 rounded-md border border-white/30 px-5 text-sm font-medium text-white hover:bg-white/10 transition-colors">{s.ctaTiers}<Icon name="arrow-right" className="size-3.5"/></a>
          </div>
        </div>
      </div>
    </section>
  );
};

const RequestInvitation = ({ t, lang }) => {
  const R = t.invite;
  const [v, setV] = useState({ name: "", org: "", role: "", email: "", reason: "", day3: R.dayOptions[0] });
  const set = (k) => (e) => setV(s => ({ ...s, [k]: e.target.value }));
  const submit = (e) => {
    e.preventDefault();
    if (!v.name || !v.org || !v.email) { alert(R.required); return; }
    const L = R.fields;
    const body = `${L.name}: ${v.name}\n${L.org}: ${v.org}\n${L.role}: ${v.role}\n${L.email}: ${v.email}\n${R.dayQuestion} ${v.day3}\n\n${L.reason}:\n${v.reason}`;
    window.location.href = `mailto:${EMAIL}?subject=${encodeURIComponent(R.subject)}&body=${encodeURIComponent(body)}`;
  };
  const input = "w-full rounded-md border border-white/20 bg-white/[0.06] px-3.5 py-2.5 text-sm text-white placeholder-white/40 focus:border-ct-indigo-300 focus:ring-1 focus:ring-ct-indigo-300 outline-none transition";
  const label = "block text-[11px] font-mono tracking-[0.14em] uppercase text-white/60 mb-1.5";
  const L = R.fields;
  return (
    <section id="request-invitation" data-screen-label="09b Request an Invitation" className="bg-ct-indigo-900 text-white pb-16 lg:pb-20 pt-12 scroll-mt-16">
      <div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 grid gap-10 lg:grid-cols-2 lg:gap-16 items-start">
        <div>
          <Eyebrow className="text-white/70">{R.eyebrow}</Eyebrow>
          <h2 className="mt-4 text-3xl font-semibold tracking-tight sm:text-4xl text-balance">{R.h2}</h2>
          <p className="mt-4 text-base leading-relaxed text-white/85">{R.lede}</p>
          <div className="mt-7 rounded-xl border border-white/15 bg-white/[0.04] p-6">
            <p className="text-[11px] font-mono tracking-[0.16em] uppercase text-white/60">{R.workflowLabel}</p>
            <p className="mt-3 text-sm leading-7 text-white/85">{R.workflow}</p>
            <div className="mt-5 pt-5 border-t border-white/12">
              <p className="text-[11px] font-mono tracking-[0.16em] uppercase text-white/60">{R.briefingLabel}</p>
              <a href={R.briefingHref} target="_blank" rel="noopener" className="mt-3 inline-flex items-center gap-2 rounded-md border border-white/25 px-4 py-2.5 text-sm font-medium text-white hover:bg-white/10 transition-colors"><Icon name="doc" className="size-4"/>{R.briefingText}<Icon name="arrow-right" className="size-3.5"/></a>
              <p className="mt-2 text-[11px] font-mono tracking-wide text-white/50">{R.briefingMeta}</p>
            </div>
          </div>
        </div>
        <form onSubmit={submit} className="rounded-xl border border-white/15 bg-white/[0.04] p-6 sm:p-8">
          <div className="grid gap-5 sm:grid-cols-2">
            <div><label className={label}>{L.name} *</label><input className={input} value={v.name} onChange={set("name")} required/></div>
            <div><label className={label}>{L.org} *</label><input className={input} value={v.org} onChange={set("org")} required/></div>
            <div><label className={label}>{L.role}</label><input className={input} value={v.role} onChange={set("role")}/></div>
            <div><label className={label}>{L.email} *</label><input type="email" className={input} value={v.email} onChange={set("email")} required/></div>
            <div className="sm:col-span-2"><label className={label}>{L.reason}</label><textarea rows={3} className={input} value={v.reason} onChange={set("reason")}/></div>
            <div className="sm:col-span-2"><label className={label}>{R.dayQuestion}</label><select className={`${input} [&>option]:text-gray-900`} value={v.day3} onChange={set("day3")}>{R.dayOptions.map(o => <option key={o} value={o}>{o}</option>)}</select></div>
          </div>
          <button type="submit" className="mt-7 inline-flex h-12 items-center gap-2 rounded-md bg-white px-5 text-sm font-semibold text-ct-indigo-900 hover:bg-white/90 transition-all hover:-translate-y-0.5">{R.submit}<Icon name="arrow-right" className="size-4"/></button>
          <p className="mt-4 text-xs font-mono tracking-wide text-white/55">{R.note}</p>
        </form>
      </div>
    </section>
  );
};

// -------------------- Tweaks --------------------
const HeadlineTweak = ({ value, setHeadline, lang }) => {
  if (!window.TweaksPanel) return null;
  const { TweakSection, TweakRadio } = window;
  const opts = lang === "vi"
    ? [{ value: "lead", label: "Chủ đạo" }, { value: "energy", label: "Năng lượng" }, { value: "concrete", label: "Cụ thể" }]
    : [{ value: "lead", label: "Lead" }, { value: "energy", label: "Energy" }, { value: "concrete", label: "Concrete" }];
  return (
    <TweakSection label={lang === "vi" ? "Tiêu đề hero (Oz chọn)" : "Hero headline (Oz to pick)"}>
      <TweakRadio label={lang === "vi" ? "Phương án" : "Variant"} value={value} options={opts} onChange={setHeadline}/>
    </TweakSection>
  );
};

const TweaksMount = ({ tweaks, setLang, setHeadline }) => {
  if (!window.TweaksPanel) return null;
  const { TweaksPanel } = window;
  return (
    <TweaksPanel title="Tweaks">
      <HeadlineTweak value={tweaks.headline} setHeadline={setHeadline} lang={tweaks.lang}/>
      <LangTweak lang={tweaks.lang} setLang={setLang}/>
    </TweaksPanel>
  );
};

const App = () => {
  const [tweaks, setTweak] = (window.useTweaks || ((d) => [d, () => {}]))(TWEAK_DEFAULS);
  const lang = tweaks.lang;
  const t = F()[lang] || F().en;
  const setLang = useSharedLang(tweaks, setTweak);
  const setHeadline = (h) => setTweak("headline", h);
  return (
    <>
      <Header lang={lang} setLang={setLang} current="Home.html"/>
      <ForumHero t={t} headline={tweaks.headline}/>
      <ProofStrip t={t}/>
      <ChooseRole t={t}/>
      <WhyNow t={t}/>
      <HowItWorks t={t} lang={lang}/>
      <Momentum t={t} lang={lang}/>
      <ForumSnapshot t={t}/>
      <ProofPartners t={t} lang={lang}/>
      <SponsorBand t={t} lang={lang}/>
      <RequestInvitation t={t} lang={lang}/>
      <Footer lang={lang}/>
      <TweaksMount tweaks={tweaks} setLang={setLang} setHeadline={setHeadline}/>
    </>
  );
};

ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
