const { useState, useEffect, useRef } = React;

// Resource resolver: prefers a blob URL injected by the offline bundler,
// falls back to the relative path so the live (non-bundled) version still works.
const R = (id, fallback) => (window.__resources && window.__resources[id]) || fallback;
const ASSETS = {
  logo:     R("logo",     "assets/only-moles-logo.png"),
  molrat1:  R("molrat1",  "assets/molrat-1.png"),
  molrat2:  R("molrat2",  "assets/molrat-2.png"),
  molrat3:  R("molrat3",  "assets/molrat-3.png"),
  molratFluweel: R("molratFluweel", "assets/molrat-fluweel.png"),
  teamLogo: R("teamLogo", "assets/team-logo.jpg"),
  caveoirCover: R("caveoirCover", "assets/caveoir-cover.png"),
};

// ---------- Auth card ----------
// Flip to true once the Facebook provider is configured in the Firebase
// console (Authentication → Sign-in method → Facebook).
const SHOW_FACEBOOK = false;

function AuthCard({ accent, defaultTab = "signup", t, tHtml }) {
  const [tab, setTab] = useState(defaultTab);
  const [email, setEmail] = useState("");
  const [pw, setPw] = useState("");
  const [tier, setTier] = useState("colony");
  const [agreed, setAgreed] = useState(true);
  const [submitted, setSubmitted] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);        // i18n key, or null
  const [resetSent, setResetSent] = useState(false);

  useEffect(() => { setTab(defaultTab); }, [defaultTab]);

  const tiers = [
    { id: "burrow", price: 5 },
    { id: "colony", price: 12 },
    { id: "queen",  price: 25 },
  ];

  // Clear transient feedback whenever the user edits the form.
  const clearFeedback = () => { setError(null); setResetSent(false); };

  const switchTab = (next) => { setTab(next); clearFeedback(); };

  const submit = async (e) => {
    e.preventDefault();
    if (!email || !pw || loading) return;
    clearFeedback();
    setLoading(true);
    try {
      const auth = firebase.auth();
      if (tab === "signup") {
        const cred = await auth.createUserWithEmailAndPassword(email.trim(), pw);
        // No database — stash the chosen tier on the profile so the members
        // nav can show it. Best-effort; account creation already succeeded.
        try { await cred.user.updateProfile({ displayName: tier }); } catch (_) {}
        setSubmitted("signup");           // keep the existing welcome card
      } else {
        await auth.signInWithEmailAndPassword(email.trim(), pw);
        window.location.assign("/Members"); // redirect into the members area
        return;                             // leave the spinner up during nav
      }
    } catch (err) {
      setError(window.firebaseAuthErrorKey(err && err.code));
    } finally {
      setLoading(false);
    }
  };

  const onForgot = async () => {
    clearFeedback();
    if (!email) { setError("auth_err_need_email"); return; }
    if (loading) return;
    setLoading(true);
    try {
      await firebase.auth().sendPasswordResetEmail(email.trim());
      setResetSent(true);
    } catch (err) {
      setError(window.firebaseAuthErrorKey(err && err.code));
    } finally {
      setLoading(false);
    }
  };

  // Google / Facebook sign-in. Works for both new and returning users
  // (signInWithPopup creates the account on first use).
  const socialSignIn = async (which) => {
    if (loading) return;
    clearFeedback();
    setLoading(true);
    try {
      const provider = which === "google"
        ? new firebase.auth.GoogleAuthProvider()
        : new firebase.auth.FacebookAuthProvider();
      await firebase.auth().signInWithPopup(provider);
      window.location.assign("/Members");   // leave the spinner up during nav
      return;
    } catch (err) {
      const code = err && err.code;
      // The visitor just closed/cancelled the popup — not a real error.
      if (code === "auth/popup-closed-by-user" || code === "auth/cancelled-popup-request") {
        setLoading(false);
        return;
      }
      setError(window.firebaseAuthErrorKey(code));
    } finally {
      setLoading(false);
    }
  };

  if (submitted) {
    return (
      <div className="auth-card auth-card--done">
        <div className="auth-done-icon" style={{ background: accent }}>
          <svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="white" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
            <path d="M4 12.5l5 5L20 7" />
          </svg>
        </div>
        <h3>{submitted === "signup" ? t("auth_welcome_signup") : t("auth_welcome_login")}</h3>
        <p className="auth-done-copy">
          {submitted === "signup" ? t("auth_welcome_signup_copy") : t("auth_welcome_login_copy")}
        </p>
        <button
          className="auth-link"
          onClick={() => { setSubmitted(null); setEmail(""); setPw(""); clearFeedback(); }}
        >
          {t("auth_back")}
        </button>
      </div>
    );
  }

  const currentPrice = tiers.find((tt) => tt.id === tier).price;

  return (
    <div className="auth-card" id="auth">
      <div className="auth-tabs" role="tablist">
        <button
          role="tab"
          aria-selected={tab === "signup"}
          className={`auth-tab ${tab === "signup" ? "is-active" : ""}`}
          onClick={() => switchTab("signup")}
        >
          {t("auth_tab_signup")}
        </button>
        <button
          role="tab"
          aria-selected={tab === "login"}
          className={`auth-tab ${tab === "login" ? "is-active" : ""}`}
          onClick={() => switchTab("login")}
        >
          {t("auth_tab_login")}
        </button>
      </div>

      <form className="auth-form" onSubmit={submit}>
        {tab === "signup" && (
          <div className="tiers" role="radiogroup">
            {tiers.map((tt) => (
              <label
                key={tt.id}
                className={`tier ${tier === tt.id ? "is-active" : ""}`}
                style={tier === tt.id ? { borderColor: accent, background: `color-mix(in oklab, ${accent} 8%, white)` } : {}}
              >
                <input
                  type="radio"
                  name="tier"
                  checked={tier === tt.id}
                  onChange={() => setTier(tt.id)}
                />
                <div className="tier-head">
                  <span className="tier-label">{t(`auth_tier_${tt.id}`)}</span>
                  <span className="tier-price">€{tt.price}<span>/mo</span></span>
                </div>
                <div className="tier-sub">{t(`auth_tier_${tt.id}_sub`)}</div>
              </label>
            ))}
          </div>
        )}

        <label className="field">
          <span>{t("auth_email")}</span>
          <input
            type="email"
            value={email}
            onChange={(e) => { setEmail(e.target.value); clearFeedback(); }}
            placeholder="you@example.com"
            required
          />
        </label>
        <label className="field">
          <span>{t("auth_password")}</span>
          <input
            type="password"
            value={pw}
            onChange={(e) => { setPw(e.target.value); clearFeedback(); }}
            placeholder="••••••••"
            required
          />
        </label>

        {tab === "signup" && (
          <label className="consent">
            <input type="checkbox" checked={agreed} onChange={(e) => setAgreed(e.target.checked)} />
            <span {...tHtml("auth_consent")} />
          </label>
        )}

        <button
          type="submit"
          className="auth-submit"
          disabled={loading || (tab === "signup" && !agreed)}
          style={{ background: accent }}
        >
          {loading
            ? t("auth_loading")
            : tab === "signup"
              ? t("auth_submit_signup_tmpl", { price: currentPrice })
              : t("auth_submit_login")}
        </button>

        {error && <p className="auth-error" role="alert">{t(error)}</p>}
        {resetSent && <p className="auth-note" role="status">{t("auth_reset_sent")}</p>}

        {tab === "login" && (
          <button
            type="button"
            className="auth-link auth-link--center"
            onClick={onForgot}
            disabled={loading}
          >
            {t("auth_forgot")}
          </button>
        )}

        <div className="auth-divider"><span>{t("auth_or")}</span></div>

        <div className="auth-social">
          <button
            type="button"
            className="auth-social-btn"
            onClick={() => socialSignIn("google")}
            disabled={loading}
          >
            <svg className="auth-social-icon" viewBox="0 0 18 18" width="18" height="18" aria-hidden="true">
              <path fill="#4285F4" d="M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844a4.14 4.14 0 0 1-1.796 2.716v2.259h2.908c1.702-1.567 2.684-3.875 2.684-6.615z"/>
              <path fill="#34A853" d="M9 18c2.43 0 4.467-.806 5.956-2.18l-2.908-2.259c-.806.54-1.837.86-3.048.86-2.344 0-4.328-1.584-5.036-3.711H.957v2.332A8.997 8.997 0 0 0 9 18z"/>
              <path fill="#FBBC05" d="M3.964 10.71A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.957A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.957 4.042l3.007-2.332z"/>
              <path fill="#EA4335" d="M9 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.463.891 11.426 0 9 0A8.997 8.997 0 0 0 .957 4.958L3.964 7.29C4.672 5.163 6.656 3.58 9 3.58z"/>
            </svg>
            {t("auth_google")}
          </button>
          {SHOW_FACEBOOK && (
            <button
              type="button"
              className="auth-social-btn"
              onClick={() => socialSignIn("facebook")}
              disabled={loading}
            >
              <svg className="auth-social-icon" viewBox="0 0 24 24" width="18" height="18" fill="#1877F2" aria-hidden="true">
                <path d="M13.5 21v-7.5h2.5l.5-3h-3V8.5c0-.9.3-1.5 1.6-1.5H17V4.25C16.6 4.2 15.65 4 14.55 4 12.25 4 10.7 5.35 10.7 7.95V10.5H8v3h2.7V21h2.8z"/>
              </svg>
              {t("auth_facebook")}
            </button>
          )}
        </div>
      </form>
    </div>
  );
}

// ---------- Teaser tile ----------
function TeaserTile({ caption, sub, src, position, blur, membersOnly, sneakPreview, revealSrc, revealPosition, onOpen }) {
  const [hovered, setHovered] = useState(false);
  const showReveal = hovered && revealSrc;
  return (
    <article
      className={`tile ${showReveal ? "is-revealed" : ""}`}
      onMouseEnter={() => setHovered(true)}
      onMouseLeave={() => setHovered(false)}
    >
      <button
        type="button"
        className="tile-media"
        onClick={onOpen}
        aria-label={caption}
      >
        <div
          className="tile-img"
          style={{
            backgroundImage: `url(${showReveal ? revealSrc : src})`,
            backgroundPosition: showReveal ? (revealPosition || "center") : (position || "center"),
            filter: showReveal ? "blur(0px) saturate(1.05)" : `blur(${blur}px) saturate(1.05)`,
            transform: hovered ? "scale(1.04)" : "scale(1.02)",
          }}
        />
        <div className="tile-veil" />
        <div className="tile-lock">
          <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            {showReveal ? (
              <>
                <rect x="4" y="11" width="16" height="10" rx="2" />
                <path d="M8 11V7a4 4 0 0 1 8 0" />
              </>
            ) : (
              <>
                <rect x="4" y="11" width="16" height="10" rx="2" />
                <path d="M8 11V7a4 4 0 0 1 8 0v4" />
              </>
            )}
          </svg>
          <span>{showReveal ? sneakPreview : membersOnly}</span>
        </div>
      </button>
      <div className="tile-meta">
        <div className="tile-cap">{caption}</div>
        <div className="tile-sub">{sub}</div>
      </div>
    </article>
  );
}

// ---------- Tile lightbox modal ----------
function TileModal({ tile, blur, accent, onClose, t }) {
  const isOpen = !!tile;
  // Lock body scroll + close on Esc — only while open
  useEffect(() => {
    if (!isOpen) return;
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    return () => {
      document.body.style.overflow = prev;
      window.removeEventListener("keydown", onKey);
    };
  }, [isOpen, onClose]);

  if (!tile) return null;
  const hasReveal = !!tile.revealSrc;

  return (
    <div className="tm-overlay" onClick={onClose} role="dialog" aria-modal="true" aria-label={tile.caption}>
      <button className="tm-close" onClick={onClose} aria-label={t("modal_close")}>
        <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M6 6l12 12M18 6l-12 12" />
        </svg>
      </button>
      <figure className="tm-card" onClick={(e) => e.stopPropagation()}>
        <div className="tm-media">
          <div
            className="tm-img"
            style={{
              backgroundImage: `url(${hasReveal ? tile.revealSrc : tile.src})`,
              backgroundPosition: hasReveal ? (tile.revealPosition || "center") : (tile.position || "center"),
              filter: hasReveal ? "saturate(1.05)" : `blur(${Math.max(blur, 22)}px) saturate(1.05)`,
            }}
          />
          {!hasReveal && (
            <div className="tm-locked">
              <div className="tm-locked-pill">
                <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                  <rect x="4" y="11" width="16" height="10" rx="2" />
                  <path d="M8 11V7a4 4 0 0 1 8 0v4" />
                </svg>
                <span>{t("members_only")}</span>
              </div>
              <p className="tm-locked-msg">{t("modal_locked_msg")}</p>
              <a className="btn btn--primary btn--lg" href="#auth" onClick={onClose} style={{ background: accent }}>
                {t("modal_locked_cta")}
              </a>
            </div>
          )}
        </div>
        <figcaption className="tm-cap">
          <div>
            <div className="tm-cap-title">{tile.caption}</div>
            <div className="tm-cap-sub">{tile.sub}</div>
          </div>
          {hasReveal && (
            <span className="tm-cap-tag" style={{ background: `color-mix(in oklab, ${accent} 14%, white)`, color: accent }}>
              {t("sneak_preview")}
            </span>
          )}
        </figcaption>
      </figure>
    </div>
  );
}

// ---------- Live pill ----------
function LivePill({ label }) {
  return (
    <div className="live-pill">
      <span className="live-dot" />
      {label}
    </div>
  );
}

// ---------- App ----------
function App() {
  const { lang, setLang, t, tHtml } = useLang();
  const [tweak, setTweak] = useTweaks(/*EDITMODE-BEGIN*/{
    "accent": "#E5638A",
    "blur": 16,
    "heroTilt": 1,
    "showRaisedBar": true,
    "faqMark": "card"
  }/*EDITMODE-END*/);
  const [openTile, setOpenTile] = useState(null);

  const tilePositions = [
    { src: ASSETS.molrat1, position: "center 30%", revealSrc: ASSETS.molratFluweel, revealPosition: "center 30%" },
    { src: ASSETS.molrat2, position: "center 20%" },
    { src: ASSETS.molrat1, position: "right 40%" },
    { src: ASSETS.molrat2, position: "left center" },
    { src: ASSETS.molrat1, position: "center 70%" },
    { src: ASSETS.molrat2, position: "center 60%" },
  ];

  return (
    <div className="page">
      {/* ---------- Nav ---------- */}
      <nav className="nav">
        <a className="nav-brand" href="#top" aria-label="Only Moles">
          <img src={ASSETS.logo} alt="Only Moles" />
        </a>
        <div className="nav-right">
          <a className="nav-link" href="#peek">{t("nav_peek")}</a>
          <a className="nav-link" href="#charity">{t("nav_cause")}</a>
          <a className="nav-link" href="#faq">{t("nav_faq")}</a>
          <LanguageSwitcher lang={lang} setLang={setLang} />
          <a className="nav-link nav-link--cta" href="#auth">{t("nav_login")}</a>
        </div>
      </nav>

      {/* ---------- Hero ---------- */}
      <header className="hero" id="top">
        <div className="hero-left">
          <h1 className="headline" {...tHtml("hero_headline")} />

          <p className="lede" {...tHtml("hero_lede")} />

          <div className="hero-cta">
            <a className="btn btn--primary btn--lg" href="#auth" style={{ background: tweak.accent }}>
              {t("hero_cta_subscribe")}
              <svg viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" style={{ marginLeft: 8 }}>
                <path d="M5 12h14M13 5l7 7-7 7" />
              </svg>
            </a>
            <a className="btn btn--ghost btn--lg" href="#auth">{t("hero_cta_member")}</a>
          </div>

          <div className="hero-meta">
            <div className="hero-meta-item">
              <div className="meta-num">1,284</div>
              <div className="meta-lbl">{t("stat_members")}</div>
            </div>
            <div className="hero-meta-divider" />
            <div className="hero-meta-item">
              <div className="meta-num">312</div>
              <div className="meta-lbl">{t("stat_posts")}</div>
            </div>
            <div className="hero-meta-divider" />
            <div className="hero-meta-item">
              <div className="meta-num" style={{ color: tweak.accent }}>€8,420</div>
              <div className="meta-lbl">{t("stat_raised")}</div>
            </div>
          </div>
        </div>

        <div className="hero-right">
          <div className="photo-stack" style={{ "--tilt": tweak.heroTilt }}>
            <figure className="photo photo--side">
              <img src={ASSETS.molrat3} alt="A naked mole rat in a cream lingerie set, posing power-stance" />
              <figcaption>
                <span className="photo-handle">@noradiva</span>
                <span className="photo-time">5m</span>
              </figcaption>
            </figure>
            <figure className="photo photo--back">
              <img src={ASSETS.molrat2} alt="A naked mole rat posing in a polka-dot bikini" />
              <figcaption>
                <span className="photo-handle">@queenhilde</span>
                <span className="photo-time">2h</span>
              </figcaption>
            </figure>
            <figure className="photo photo--front">
              <img src={ASSETS.molrat1} alt="A naked mole rat in a pink polka-dot bikini, looking at camera" />
              <figcaption>
                <span className="photo-handle">@bertthemole</span>
                <span className="photo-time">just now</span>
              </figcaption>
              <LivePill label={t("live_pill")} />
            </figure>
            <div className="photo-sticker" style={{ borderColor: tweak.accent, color: tweak.accent }}>
              <span>18+</span>
            </div>
          </div>
        </div>
      </header>

      {/* ---------- Teaser grid ---------- */}
      <section className="section" id="peek">
        <div className="section-head">
          <div>
            <div className="section-eyebrow">{t("peek_eyebrow")}</div>
            <h2 className="section-title" {...tHtml("peek_title")} />
          </div>
          <p className="section-note"><a href="#auth">{t("peek_note")}</a></p>
        </div>

        <div className="grid">
          {tilePositions.map((p, i) => {
            const tile = {
              ...p,
              caption: t(`tile_${i}_caption`),
              sub: t(`tile_${i}_sub`),
            };
            return (
              <TeaserTile
                key={i}
                caption={tile.caption}
                sub={tile.sub}
                src={p.src}
                position={p.position}
                revealSrc={p.revealSrc}
                revealPosition={p.revealPosition}
                blur={tweak.blur}
                membersOnly={t("members_only")}
                sneakPreview={t("sneak_preview")}
                onOpen={() => setOpenTile(tile)}
              />
            );
          })}
        </div>
      </section>

      {/* ---------- Press ---------- */}
      <section className="press">
        <div className="press-cover-wrap">
          <a
            className="press-cover"
            href={ASSETS.caveoirCover}
            target="_blank"
            rel="noopener"
            aria-label={t("press_cover_alt")}
          >
            <img src={ASSETS.caveoirCover} alt={t("press_cover_alt")} />
          </a>
          <span className="press-tape" aria-hidden="true" />
          <span className="press-medal" style={{ borderColor: tweak.accent, color: tweak.accent }} aria-hidden="true">
            <span>Best<br/>Website<br/>2026</span>
          </span>
        </div>
        <div className="press-body">
          <div className="press-eyebrow">{t("press_eyebrow")}</div>
          <div className="press-stars" aria-label="5 out of 5 stars">
            {[0,1,2,3,4].map((i) => (
              <svg key={i} viewBox="0 0 24 24" width="22" height="22" fill={tweak.accent} aria-hidden="true">
                <path d="M12 2.5l2.9 6.4 6.95.6-5.27 4.59 1.6 6.81L12 17.3l-6.18 3.6 1.6-6.81L2.15 9.5l6.95-.6L12 2.5z" />
              </svg>
            ))}
          </div>
          <blockquote className="press-quote">{t("press_quote")}</blockquote>
          <div className="press-attribution">{t("press_attribution")}</div>
        </div>
      </section>

      {/* ---------- Subscribe + Auth ---------- */}
      <section className="subscribe">
        <div className="sub-left">
          <div className="section-eyebrow">{t("sub_eyebrow")}</div>
          <h2 className="section-title" {...tHtml("sub_title")} />
          <p className="sub-body" {...tHtml("sub_body")} />
          <ul className="perks">
            {["perk_1", "perk_2", "perk_3", "perk_4"].map((key) => (
              <li key={key}>
                <span
                  className="perk-check"
                  style={{
                    background: `color-mix(in oklab, ${tweak.accent} 14%, white)`,
                    color: tweak.accent,
                  }}
                >
                  <svg viewBox="0 0 14 14" width="11" height="11" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round">
                    <path d="M3 7.3 5.7 10 11 4.5" />
                  </svg>
                </span>
                <span>{t(key)}</span>
              </li>
            ))}
          </ul>
        </div>
        <div className="sub-right">
          <AuthCard accent={tweak.accent} t={t} tHtml={tHtml} />
        </div>
      </section>

      {/* ---------- FAQ ---------- */}
      <Faq t={t} tHtml={tHtml} accent={tweak.accent} markStyle={tweak.faqMark} />

      {/* ---------- Charity ---------- */}
      <section className="charity" id="charity">
        <div className="charity-card">
          <div className="charity-left">
            <div className="charity-eyebrow" style={{ color: tweak.accent }}>{t("charity_eyebrow")}</div>
            <h2 className="charity-title" {...tHtml("charity_title")} />
            <p className="charity-body" {...tHtml("charity_body")} />

            {tweak.showRaisedBar && (
              <div className="raised">
                <div className="raised-row">
                  <span>{t("charity_raised_tmpl", { amount: "8.420" })}</span>
                  <span className="raised-goal">{t("charity_goal_tmpl", { amount: "12.500" })}</span>
                </div>
                <div className="raised-bar">
                  <div className="raised-fill" style={{ width: "67%", background: tweak.accent }} />
                </div>
              </div>
            )}

            <div className="charity-actions">
              <a className="btn btn--primary" href="#auth" style={{ background: tweak.accent }}>
                {t("charity_cta_primary")}
              </a>
              <a className="btn btn--ghost" href="https://www.samenlooprosmalen.nl/donate-0mqdar" target="_blank" rel="noopener">
                {t("charity_cta_secondary")}
              </a>
            </div>
          </div>

          <div className="charity-right">
            <img
              className="team-logo"
              src={ASSETS.teamLogo}
              alt="De Naakte Molratten — Graven voor Kankeronderzoek!"
            />
          </div>
        </div>
      </section>

      {/* ---------- Share ---------- */}
      <Share t={t} tHtml={tHtml} accent={tweak.accent} />

      {/* ---------- Footer ---------- */}
      <footer className="foot">
        <div className="foot-left">
          <img src={ASSETS.logo} alt="" />
          <span>{t("foot_copy")}</span>
        </div>
        <div className="foot-right">
          <a href="#">{t("foot_privacy")}</a>
          <a href="#">{t("foot_contact")}</a>
          <a href="https://www.samenlooprosmalen.nl/" target="_blank" rel="noopener">{t("foot_samenloop")}</a>
        </div>
      </footer>

      {/* ---------- Tile lightbox ---------- */}
      <TileModal tile={openTile} blur={tweak.blur} accent={tweak.accent} onClose={() => setOpenTile(null)} t={t} />

      {/* ---------- Tweaks ---------- */}
      <TweaksPanel title="Tweaks">
        <TweakSection label="Look" />
        <TweakColor
          label="Accent"
          value={tweak.accent}
          options={["#E5638A", "#D14B7A", "#C2185B", "#B8336A", "#7A2952"]}
          onChange={(v) => setTweak("accent", v)}
        />
        <TweakSlider
          label="Teaser blur"
          value={tweak.blur}
          min={4}
          max={30}
          step={1}
          unit="px"
          onChange={(v) => setTweak("blur", v)}
        />
        <TweakSlider
          label="Hero photo tilt"
          value={tweak.heroTilt}
          min={0}
          max={3}
          step={0.1}
          onChange={(v) => setTweak("heroTilt", v)}
        />
        <TweakSection label="Charity" />
        <TweakToggle
          label="Show progress bar"
          value={tweak.showRaisedBar}
          onChange={(v) => setTweak("showRaisedBar", v)}
        />
        <TweakSection label="FAQ" />
        <TweakRadio
          label="Header mark"
          value={tweak.faqMark}
          options={[
            { value: "card",   label: "Card" },
            { value: "stamp",  label: "Stamp" },
            { value: "bubble", label: "Bubble" },
            { value: "ring",   label: "Ring" },
          ]}
          onChange={(v) => setTweak("faqMark", v)}
        />
      </TweaksPanel>
    </div>
  );
}

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