// ============================================
// Pages
// ============================================

// ---------- Home ----------
function FilterDropdown({ value, onChange, options }) {
  const [open, setOpen] = useState(false);
  const rootRef = useRef(null);
  const current = options.find((o) => o.key === value) || options[0];

  useEffect(() => {
    if (!open) return;
    const onDown = (e) => {
      if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(false);
    };
    const onKey = (e) => { if (e.key === "Escape") setOpen(false); };
    document.addEventListener("pointerdown", onDown);
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("pointerdown", onDown);
      document.removeEventListener("keydown", onKey);
    };
  }, [open]);

  return (
    <div ref={rootRef} className={"filter-dd " + (open ? "open" : "")}>
      <button
        type="button"
        className="filter-dd-current"
        onClick={() => setOpen((v) => !v)}
        aria-haspopup="listbox"
        aria-expanded={open}
      >
        <span>{current.label}</span>
        <svg viewBox="0 0 12 8" width="10" height="7" aria-hidden="true">
          <path d="M1 2 L6 7 L11 2" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </button>
      {open && (
        <ul className="filter-dd-list" role="listbox">
          {options.map((o) => (
            <li key={o.key}>
              <button
                type="button"
                role="option"
                aria-selected={o.key === value}
                className={"filter-dd-opt " + (o.key === value ? "active" : "")}
                onClick={() => { onChange(o.key); setOpen(false); }}
              >
                {o.label}
              </button>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

function HomePage({ onOpen, onNavigate }) {
  const { t } = useLang();
  const [heroTrailer, setHeroTrailer] = useState(null);
  const [filter, setFilter] = useState("all"); // all | feature | documentary

  const matches = (f, key) => {
    const g = (f.genre || []).map((x) => String(x).toLowerCase());
    if (key === "feature") return g.includes("feature");
    if (key === "documentary") return g.includes("documentary");
    return true;
  };
  const shown = FILMS_ORDERED.filter((f) => matches(f, filter));

  return (
    <>
      <HeroCarousel onOpen={onOpen} onTrailer={(f) => setHeroTrailer(f)} />
      {heroTrailer && (
        <TrailerLightbox film={heroTrailer} onClose={() => setHeroTrailer(null)} />
      )}

      <div className="shell">
        <div className="toolbar toolbar-filter">
          <span className="toolbar-meta">{t("films.count", { n: shown.length })}</span>
          <FilterDropdown
            value={filter}
            onChange={setFilter}
            options={[
              { key: "all",         label: t("filter.all") },
              { key: "feature",     label: t("filter.feature") },
              { key: "documentary", label: t("filter.documentary") },
            ]}
          />
        </div>
        <div className="grid">
          {shown.map((f) => (
            <FilmCard key={f.id} film={f} onClick={() => onOpen(f.id)} />
          ))}
        </div>
      </div>
    </>
  );
}

function HeroCarousel({ onOpen, onTrailer }) {
  const { t } = useLang();
  const films = FILMS_ORDERED;
  const [idx, setIdx] = useState(0);
  const [dragX, setDragX] = useState(0);
  const [isDragging, setIsDragging] = useState(false);
  const [paused, setPaused] = useState(false);
  const startX = useRef(0);
  const wrapRef = useRef(null);
  const didDragRef = useRef(false);
  const videoRefs = useRef({});
  const AUTO_MS = 7000;

  // Auto-advance
  useEffect(() => {
    if (paused || isDragging) return;
    const t = setTimeout(() => setIdx((i) => (i + 1) % films.length), AUTO_MS);
    return () => clearTimeout(t);
  }, [idx, paused, isDragging, films.length]);

  // Drive <video> playback per idx — konservative Strategie nach iOS-Safari-Bug:
  //   - Aktiver Slide: play() (kein vid.load() — das resettet currentTime und
  //     kann unter iOS den Autoplay-Token verbrennen). preload="auto" reicht.
  //   - Alle anderen: pause(), aber nicht vid.load() — iOS Safari ist da heikel.
  // (Vorherige Versionen hatten Nachbarn-Preload + globalen no-cors-fetch — beides
  // raus, weil Range-Request-Konflikte und Autoplay-Token-Verbrauch vermutet.)
  useEffect(() => {
    if (!films.length) return;
    const activeId = films[idx]?.id;

    Object.entries(videoRefs.current).forEach(([id, vid]) => {
      if (!vid) return;
      if (id === activeId) {
        const p = vid.play();
        if (p && typeof p.catch === "function") p.catch(() => {});
      } else {
        try { vid.pause(); } catch (_) {}
      }
    });
  }, [idx, films]);

  const go = (delta) => {
    setIdx((i) => (i + delta + films.length) % films.length);
  };

  useEffect(() => {
    const onKey = (e) => {
      if (e.target && (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA" || e.target.isContentEditable)) return;
      if (e.key === "ArrowRight") { e.preventDefault(); go(1); }
      else if (e.key === "ArrowLeft") { e.preventDefault(); go(-1); }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [films.length]);

  const onPointerDown = (e) => {
    startX.current = e.clientX;
    setIsDragging(true);
    setDragX(0);
    didDragRef.current = false;
    wrapRef.current?.setPointerCapture?.(e.pointerId);
  };
  const onPointerMove = (e) => {
    if (!isDragging) return;
    const dx = e.clientX - startX.current;
    setDragX(dx);
    if (Math.abs(dx) > 6) didDragRef.current = true;
  };
  const onPointerUp = () => {
    if (!isDragging) return;
    const w = wrapRef.current?.offsetWidth || 1;
    const ratio = dragX / w;
    if (ratio < -0.12) go(1);
    else if (ratio > 0.12) go(-1);
    setIsDragging(false);
    setDragX(0);
  };
  const onCarouselClick = (e) => {
    if (didDragRef.current) { didDragRef.current = false; return; }
    go(1);
  };

  const film = films[idx];
  const accent = film.accent || "#f4f1ec";
  const progress = isDragging ? dragX / (wrapRef.current?.offsetWidth || 1) : 0;

  return (
    <section
      className="hero-carousel"
      ref={wrapRef}
      onClick={onCarouselClick}
      onPointerDown={onPointerDown}
      onPointerMove={onPointerMove}
      onPointerUp={onPointerUp}
      onPointerCancel={onPointerUp}
      style={{ "--film-accent": accent }}
    >
      {films.map((f, i) => {
        const active = i === idx;
        return (
          <div
            key={f.id}
            className={"hero-slide " + (active ? "active" : "")}
            style={{
              transform: active ? `translateX(${dragX * 0.4}px)` : "none",
              opacity: active ? 1 : 0,
            }}
            aria-hidden={!active}
          >
            {f.heroVideo ? (
              <video
                ref={(el) => {
                  if (el) videoRefs.current[f.id] = el;
                  else delete videoRefs.current[f.id];
                }}
                className="hero-video"
                src={f.heroVideo}
                poster={f.heroStill || f.poster || undefined}
                autoPlay={active}
                muted
                loop
                playsInline
                preload={active ? "auto" : "metadata"}
              />
            ) : (
              <div className="hero-fallback">
                <Slot
                  label=""
                  src={f.heroStill || f.poster || ""}
                  alt={f.title}
                  aspect="auto"
                  className="hero-still"
                />
              </div>
            )}
            <div className="hero-vignette" />
          </div>
        );
      })}

      <div
        className="hero-title-wrap"
        onMouseEnter={() => setPaused(true)}
        onMouseLeave={() => setPaused(false)}
        style={{
          transform: `translate(${dragX * 1.6}px, -54%)`,
          opacity: 1 - Math.min(0.5, Math.abs(progress) * 1.2),
        }}
      >
        <h1
          key={film.id}
          className={"hero-title " + (film.heroTitleLines ? "hero-title-stacked" : "")}
          onPointerDown={(e) => e.stopPropagation()}
          onPointerUp={(e) => e.stopPropagation()}
          onClick={(e) => {
            e.stopPropagation();
            if (didDragRef.current) { didDragRef.current = false; return; }
            try { sessionStorage.setItem("cin:compactHero", film.id); } catch (_) {}
            onOpen(film.id);
          }}
          style={{
            pointerEvents: "auto",
            cursor: "pointer",
            color: film.accent || film.heroTitleColor || "#fff",
          }}
        >
          {film.heroTitleLines ? (
            film.heroTitleLines.map((line, i) => (
              <span key={i} className="hero-title-line">{line}</span>
            ))
          ) : (
            film.title
          )}
        </h1>
        {film.status === "coming-soon" ? (
          <div key={film.id + "-sub"} className="hero-title-sub">{t("misc.comingSoonShort")}</div>
        ) : (
          <div key={film.id + "-sub"} className="hero-title-sub">
            {[film.director, film.year, film.runtime].filter(Boolean).join(" · ")}
          </div>
        )}
      </div>

      <div className="hero-rail" style={{ color: accent }} aria-hidden="false">
        <div className="hero-rail-bar">
          <span
            key={idx + "-" + paused + "-" + isDragging}
            className="hero-rail-fill"
            style={{
              animationDuration: `${AUTO_MS}ms`,
              animationPlayState: (!paused && !isDragging) ? "running" : "paused",
            }}
          />
        </div>
        <div className="hero-rail-meta">
          <span className="hero-rail-idx">
            <strong>{String(idx + 1).padStart(2, "0")}</strong>
            <span style={{ opacity: 0.55 }}>/ {String(films.length).padStart(2, "0")}</span>
          </span>
          <span className="hero-rail-dots">
            {films.map((_, i) => (
              <button
                key={i}
                type="button"
                className={"hero-rail-dot " + (i === idx ? "active" : "")}
                onClick={(e) => { e.stopPropagation(); setIdx(i); }}
                aria-label={`Go to slide ${i + 1}`}
              />
            ))}
          </span>
          <span className="hero-rail-title">{film.title}</span>
        </div>
      </div>
    </section>
  );
}

// ---------- Films index (2-column tiles — toolbar matches home) ----------
function FilmsPage({ onOpen }) {
  const { t } = useLang();
  const [filter, setFilter] = useState("all");
  const [trailer, setTrailer] = useState(null);

  const matches = (f, key) => {
    const g = (f.genre || []).map((x) => String(x).toLowerCase());
    if (key === "feature") return g.includes("feature");
    if (key === "documentary") return g.includes("documentary");
    return true;
  };
  const items = FILMS_ORDERED.filter((f) => matches(f, filter));

  return (
    <>
      <div className="shell">
        <div className="toolbar toolbar-filter">
          <span className="toolbar-meta">{t("films.count", { n: items.length })}</span>
          <FilterDropdown
            value={filter}
            onChange={setFilter}
            options={[
              { key: "all",         label: t("filter.all") },
              { key: "feature",     label: t("filter.feature") },
              { key: "documentary", label: t("filter.documentary") },
            ]}
          />
        </div>

        <div className="films-list">
          {items.map((f) => (
            <FilmTile
              key={f.id}
              film={f}
              onOpen={onOpen}
              onTrailer={(film) => setTrailer(film)}
            />
          ))}
        </div>
      </div>

      {trailer && (
        <TrailerLightbox film={trailer} onClose={() => setTrailer(null)} />
      )}
    </>
  );
}

function FilmTile({ film, onOpen, onTrailer }) {
  const { t, lang } = useLang();
  const accent = film.accent || "#f4f1ec";
  const lede = resolveLocalized(film.lede, lang);
  const synopsis = resolveLocalized(film.synopsis, lang);
  const hasTrailer = film.trailer && film.trailer !== "#" && film.trailer.length > 0;
  const isComingSoon = film.status === "coming-soon";

  return (
    <article
      className={"film-tile " + (isComingSoon ? "film-tile-soon-state" : "")}
      style={{ "--film-accent": accent }}
    >
      <div className="film-tile-poster" onClick={() => onOpen(film.id)}>
        <PosterSlot film={film} />
        {isComingSoon && (
          <div className="film-tile-soon">{t("misc.comingSoonShort")}</div>
        )}
      </div>

      <div className="film-tile-body">
        <h2 className="film-tile-title" onClick={() => onOpen(film.id)}>
          {film.title}
        </h2>
        <div className="film-tile-meta">
          {[
            film.year,
            translateGenres(film.genre, t),
            film.runtime,
          ].filter(Boolean).map((m, i, arr) => (
            <React.Fragment key={i}>
              <span>{m}</span>
              {i < arr.length - 1 && <span className="film-tile-meta-sep">·</span>}
            </React.Fragment>
          ))}
        </div>

        {(synopsis || lede) && (
          <p className="film-tile-lede">{synopsis || lede}</p>
        )}

        <dl className="film-tile-credits">
          {film.director && (
            <div>
              <dt>{t("meta.director")}</dt>
              <dd>{film.director}</dd>
            </div>
          )}
          {film.cast?.length > 0 && (
            <div>
              <dt>{t("meta.cast") || "Cast"}</dt>
              <dd>{film.cast.slice(0, 3).join(", ")}{film.cast.length > 3 ? " …" : ""}</dd>
            </div>
          )}
        </dl>

        {hasTrailer && (
          <div className="film-tile-actions">
            <button
              type="button"
              className="film-tile-btn film-tile-btn-play"
              onClick={() => onTrailer(film)}
            >
              <svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" width="12" height="12">
                <path d="M7 4.5v15l13-7.5-13-7.5z" />
              </svg>
              <span>{t("btn.watchTrailer")}</span>
            </button>
          </div>
        )}
      </div>
    </article>
  );
}

function FilmRow({ film, index, flip, onClick }) {
  const { t, lang } = useLang();
  const rowRef = useReveal({ threshold: 0.2 });
  const mediaRef = usePointerParallax(6);
  const isComingSoon = film.status === "coming-soon";
  const accent = film.accent || "#f4f1ec";
  const lede = resolveLocalized(film.lede, lang);
  return (
    <article
      ref={rowRef}
      className={"film-row reveal " + (flip ? "film-row-flip " : "") + (isComingSoon ? "film-row-soon" : "")}
      style={{ "--film-accent": accent }}
      onClick={onClick}
    >
      <div className="film-row-media">
        <div ref={mediaRef} className="parallax-media">
          <PosterSlot film={film} />
        </div>
      </div>
      <div className="film-row-body">
        <h2 className="film-row-title">{film.title}</h2>
        <div className="film-row-sub">
          {[
            film.year || null,
            translateGenres(film.genre, t),
            film.runtime || null,
            film.country || null,
          ].filter(Boolean).join(" · ")}
        </div>
        {lede && <p className="film-row-lede">{lede}</p>}
        <div className="film-row-tags">
          {film.director && (
            <span className="film-row-tag">
              <span className="film-row-tag-k">{t("meta.director")}</span>
              <span className="film-row-tag-v">{film.director}</span>
            </span>
          )}
          {film.awards?.length > 0 && (
            <span className="film-row-tag">
              <span className="film-row-tag-k">{t("section.awards")}</span>
              <span className="film-row-tag-v">
                {film.awards.length} {film.awards.length === 1 ? "·" : "·"}{" "}
                {film.awards.slice(0, 2).map((a) => a.festival).join(", ")}
                {film.awards.length > 2 ? ` +${film.awards.length - 2}` : ""}
              </span>
            </span>
          )}
          {film.festivals?.length > 0 && (
            <span className="film-row-tag">
              <span className="film-row-tag-k">{t("section.festivals")}</span>
              <span className="film-row-tag-v">{film.festivals.length}</span>
            </span>
          )}
        </div>
        <div className="film-row-cta">
          <span className="film-row-cta-line" />
          <span className="film-row-cta-text">
            {isComingSoon ? t("misc.comingSoon") : t("btn.viewFilm")}
          </span>
        </div>
      </div>
    </article>
  );
}

function FilmCard({ film, onClick }) {
  const { lang, t } = useLang();
  const isComingSoon = film.status === "coming-soon";
  const hasVideo = typeof film.heroVideo === "string" && film.heroVideo.trim().length > 0;
  const videoRef = useRef(null);
  const [hovering, setHovering] = useState(false);

  const onEnter = () => {
    if (!hasVideo) return;
    setHovering(true);
    const v = videoRef.current;
    if (v) {
      try { v.currentTime = 0; } catch (_) {}
      const p = v.play();
      if (p && p.catch) p.catch(() => {});
    }
  };
  const onLeave = () => {
    setHovering(false);
    const v = videoRef.current;
    if (v) v.pause();
  };

  return (
    <div
      className={"film-card " + (isComingSoon ? "film-card-soon" : "")}
      onClick={onClick}
      onMouseEnter={onEnter}
      onMouseLeave={onLeave}
      style={{ "--film-accent": film.accent || "#f4f1ec" }}
    >
      <div className={"film-card-media " + (hovering && hasVideo ? "is-hover" : "")}>
        <PosterSlot film={film} />
        {hasVideo && (
          <>
            <video
              ref={videoRef}
              className="poster-hover-video"
              src={film.heroVideo}
              muted
              loop
              playsInline
              preload="none"
              aria-hidden="true"
            />
            <div className="poster-hover-tint" aria-hidden="true" />
            <div className="poster-hover-overlay">
              <span className="poster-hover-title">{film.title}</span>
              <span className="poster-hover-cta">
                <span className="poster-hover-cta-label">{t("btn.toFilm")}</span>
                <span className="poster-hover-cta-arrow" aria-hidden="true">→</span>
              </span>
              <span className="poster-hover-sub">
                {[
                  film.year || null,
                  translateGenres(film.genre, t),
                  film.runtime || null,
                ].filter(Boolean).join(" · ")}
              </span>
            </div>
          </>
        )}
      </div>
      <div className="film-meta">
        <div className="film-title">
          {film.title}
          {isComingSoon && <span className="soon-badge">{t("misc.comingSoonShort")}</span>}
        </div>
        <div className="film-sub">
          {[
            film.year || null,
            translateGenres(film.genre, t),
            film.runtime || null,
          ].filter(Boolean).join(" · ")}
        </div>
      </div>
    </div>
  );
}

// ---------- Detail (unified template) ----------
function DetailPage({ id, onBack }) {
  const { t, lang } = useLang();
  const film = FILMS.find((f) => f.id === id);
  const [trailerOpen, setTrailerOpen] = useState(false);
  const [heroProgress, setHeroProgress] = useState(0);
  const [pageProgress, setPageProgress] = useState(0);
  const [compactHero] = useState(() => {
    try {
      const flag = sessionStorage.getItem("cin:compactHero");
      if (flag === id) {
        sessionStorage.removeItem("cin:compactHero");
        return true;
      }
    } catch (_) {}
    return false;
  });

  useEffect(() => {
    if (!trailerOpen) return;
    const onKey = (e) => { if (e.key === "Escape") setTrailerOpen(false); };
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = "";
    };
  }, [trailerOpen]);

  useEffect(() => {
    const onScroll = () => {
      const vh = window.innerHeight || 1;
      const p = Math.min(1, Math.max(0, window.scrollY / (vh * 0.5)));
      setHeroProgress(p);
      const doc = document.documentElement;
      const max = (doc.scrollHeight - window.innerHeight) || 1;
      setPageProgress(Math.min(1, Math.max(0, window.scrollY / max)));
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, [id]);

  if (!film) return null;

  const isComingSoon = film.status === "coming-soon";
  const accent = film.accent || "#f4f1ec";

  return (
    <div className={"film-page" + (compactHero ? " compact-hero" : "")} style={{ "--film-accent": accent }}>
      <div className="film-progress" aria-hidden="true">
        <div className="film-progress-bar" style={{ transform: `scaleX(${pageProgress})` }} />
      </div>
      {compactHero ? (
        <section className="film-hero-compact" aria-hidden="true">
          {film.heroVideo ? (
            <video
              className="film-hero-video"
              src={film.heroVideo}
              autoPlay
              muted
              loop
              playsInline
              preload="auto"
            />
          ) : (
            <HeroStillSlot film={film} />
          )}
          <div className="film-hero-compact-vignette" />
        </section>
      ) : (
        <section className="film-hero">
          <div className="film-hero-media">
            {film.heroVideo ? (
              <video
                className="film-hero-video"
                src={film.heroVideo}
                autoPlay
                muted
                loop
                playsInline
                preload="auto"
              />
            ) : (
              <HeroStillSlot film={film} />
            )}
            <div className="film-hero-vignette" />
          </div>
          <div
            className="film-hero-overlay"
            style={{
              opacity: 1 - heroProgress,
              transform: `translateY(${heroProgress * -40}px)`,
            }}
          >
            <div className="film-hero-meta">
              {isComingSoon && (
                <div className="film-hero-num">{t("misc.comingSoonShort")}</div>
              )}
              <h1 className="film-hero-title">{film.title}</h1>
              <div className="film-hero-sub">
                {[film.director, film.year, film.runtime].filter(Boolean).join(" · ")}
              </div>
            </div>
            {!isComingSoon && (
              <div className="film-hero-scroll" aria-hidden="true">
                <span>{t("misc.scroll")}</span>
                <span className="film-hero-scroll-line" />
              </div>
            )}
          </div>
        </section>
      )}

      {isComingSoon ? (
        <ComingSoonBody film={film} />
      ) : (
        <DetailBody film={film} onTrailer={() => setTrailerOpen(true)} />
      )}

      {trailerOpen && <TrailerLightbox film={film} onClose={() => setTrailerOpen(false)} />}
    </div>
  );
}

function ComingSoonBody({ film }) {
  const { t } = useLang();
  return (
    <div className="shell">
      <div className="detail">
        <div className="coming-soon-block">
          <div className="eyebrow">{translateGenres(film.genre, t) || t("misc.inDev")}</div>
          <h2 className="h-display" style={{ marginTop: 12 }}>{t("misc.comingSoon")}</h2>
        </div>
      </div>
    </div>
  );
}

function DetailBody({ film, onTrailer }) {
  const { t, lang } = useLang();
  const hasTrailer = film.trailer && film.trailer !== "#" && film.trailer.length > 0;
  const synopsis = resolveLocalized(film.synopsis, lang);
  const notes = resolveLocalized(film.notes, lang);
  const lede = resolveLocalized(film.lede, lang);
  const hasStills = (film.stills || []).some((s) => typeof s === "string" && s.trim().length > 0);
  const hasLaurels = (film.laurels || []).length > 0;
  const genreText = translateGenres(film.genre, t);
  const [stillIdx, setStillIdx] = useState(null);
  return (
    <div className="shell">
      <div className="detail">
        <div className="film-split">
          {/* LEFT - Sticky sidebar: laurels + poster + facts + actions */}
          <aside className="film-split-side">
            {hasLaurels && (
              <div className="film-split-laurels">
                <LaurelsStrip film={film} />
              </div>
            )}
            <div className="film-split-poster">
              <PosterSlot film={film} />
            </div>
            <dl className="film-split-facts">
              {film.director && (
                <div className="film-split-fact"><dt>{t("meta.director")}</dt><dd>{film.director}</dd></div>
              )}
              {film.year && (
                <div className="film-split-fact"><dt>{t("th.year")}</dt><dd>{film.year}</dd></div>
              )}
              {film.runtime && (
                <div className="film-split-fact"><dt>{t("meta.runtime")}</dt><dd>{film.runtime}</dd></div>
              )}
              {film.country && (
                <div className="film-split-fact"><dt>{t("meta.country")}</dt><dd>{film.country}</dd></div>
              )}
              {film.language && (
                <div className="film-split-fact"><dt>{t("meta.language")}</dt><dd>{film.language}</dd></div>
              )}
              {film.released && (
                <div className="film-split-fact"><dt>{t("meta.premiere")}</dt><dd>{film.released}</dd></div>
              )}
              {genreText && (
                <div className="film-split-fact"><dt>Genre</dt><dd>{genreText}</dd></div>
              )}
            </dl>
            <div className="film-split-actions">
              {hasTrailer ? (
                <button className="link-btn primary block" onClick={onTrailer}>{t("btn.watchTrailer")}</button>
              ) : (
                <span className="link-btn disabled block" aria-disabled="true">{t("btn.trailerEmpty")}</span>
              )}
              {film.imdb && film.imdb !== "#" && (
                <a className="link-btn block" href={film.imdb}>IMDB ↗</a>
              )}
              {film.pressKit && (
                <a className="link-btn block" href={film.pressKit}>Press Kit (PDF)</a>
              )}
            </div>
          </aside>

          {/* RIGHT - Synopsis + Notes + Stills */}
          <div className="film-split-main">
            {(synopsis || lede) && (
              <section className="film-split-section">
                <h3>{t("section.synopsis")}</h3>
                {lede && <p className="film-split-lede">{lede}</p>}
                {synopsis && synopsis.split("\n\n").map((p, i) => <p key={i}>{p}</p>)}
              </section>
            )}
            {notes && (
              <section className="film-split-section">
                <h3>{t("section.notes")}</h3>
                {notes.split("\n\n").map((p, i) => <p key={i}>{p}</p>)}
              </section>
            )}
            {hasStills && (
              <section className="film-split-section">
                <h3>{t("section.stills")}</h3>
                <StillsGrid film={film} onOpen={(i) => setStillIdx(i)} />
              </section>
            )}
          </div>
        </div>

        {stillIdx !== null && (
          <StillsLightbox
            film={film}
            index={stillIdx}
            onClose={() => setStillIdx(null)}
            onChange={(i) => setStillIdx(i)}
          />
        )}

        {film.press?.length > 0 && (
          <section className="film-section">
            <h3>{t("section.press")}</h3>
            <ul className="press-list">
              {film.press.map((q, i) => {
                const quote = resolveLocalized(q.quote, lang);
                const source = resolveLocalized(q.source, lang);
                return (
                  <li key={i} className="press-item">
                    <blockquote className="press-quote">“{quote}”</blockquote>
                    <cite className="press-source">— {source}</cite>
                  </li>
                );
              })}
            </ul>
          </section>
        )}

        {film.crew?.length > 0 && (
          <section className="film-section two-col">
            <div>
              <h3>{t("section.crew")}</h3>
              <div className="kv-list kv-tight">
                {film.crew.map((c, i) => (
                  <div key={i} className="kv-row">
                    <div className="k">{resolveLocalized(c.role, lang)}</div>
                    <div className="v">{c.name}</div>
                  </div>
                ))}
              </div>
            </div>
            {film.castDetailed?.length > 0 && (
              <div>
                <h3>{t("section.castHdr")}</h3>
                <div className="kv-list kv-tight">
                  {film.castDetailed.map((c, i) => (
                    <div key={i} className="kv-row">
                      <div className="k">{resolveLocalized(c.role, lang)}</div>
                      <div className="v">{c.name}</div>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </section>
        )}

        {(film.awards?.length > 0 || film.festivals?.length > 0) && (
          <section className="film-section awards-festivals-grid">
            {film.awards?.length > 0 && (
              <div className="awards-panel">
                <div className="awards-head">
                  <div className="awards-kicker">{t("section.awards")}</div>
                </div>
                <ol className="awards-list">
                  {film.awards.map((a, i) => (
                    <li key={i} className="awards-row">
                      <span className="awards-name">{a.name}</span>
                      <span className="awards-fest">{a.festival}</span>
                    </li>
                  ))}
                </ol>
              </div>
            )}

            {film.festivals?.length > 0 && (
              <div className="festivals-panel">
                <div className="awards-head">
                  <div className="awards-kicker">{t("section.festivals")}</div>
                </div>
                <ul className="festivals-list">
                  {film.festivals.map((f, i) => (
                    <li key={i} className="festivals-row">
                      <span className="festivals-name">{f.name}</span>
                      <span className="festivals-year">{f.year}</span>
                    </li>
                  ))}
                </ul>
              </div>
            )}
          </section>
        )}

      </div>
    </div>
  );
}

function MetaCell({ k, v, wide }) {
  return (
    <div className={"meta-cell " + (wide ? "meta-cell-wide" : "")}>
      <div className="meta-key">{k}</div>
      <div className="meta-val">{v}</div>
    </div>
  );
}

function StillsLightbox({ film, index, onChange, onClose }) {
  const stills = (film.stills || []).filter(Boolean);
  const safeIdx = Math.max(0, Math.min(index, stills.length - 1));
  const src = stills[safeIdx];
  const go = (delta) => {
    if (stills.length < 2) return;
    onChange((safeIdx + delta + stills.length) % stills.length);
  };
  useEffect(() => {
    const onKey = (e) => {
      if (e.key === "Escape") onClose();
      else if (e.key === "ArrowRight") go(1);
      else if (e.key === "ArrowLeft") go(-1);
    };
    window.addEventListener("keydown", onKey);
    const prev = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      window.removeEventListener("keydown", onKey);
      document.body.style.overflow = prev;
    };
  }, [safeIdx, stills.length]);
  if (!src) return null;
  return ReactDOM.createPortal(
    <div className="slb-overlay" onClick={onClose}>
      <button className="slb-close" onClick={onClose} aria-label="Close">✕</button>
      {stills.length > 1 && (
        <>
          <button
            className="slb-nav slb-prev"
            onClick={(e) => { e.stopPropagation(); go(-1); }}
            aria-label="Previous"
          >‹</button>
          <button
            className="slb-nav slb-next"
            onClick={(e) => { e.stopPropagation(); go(1); }}
            aria-label="Next"
          >›</button>
        </>
      )}
      <figure className="slb-figure" onClick={(e) => e.stopPropagation()}>
        <img src={src} alt={`${film.title} still ${safeIdx + 1}`} />
        <figcaption className="slb-caption">
          <span className="slb-caption-title">{film.title}</span>
          <a
            className="slb-dl"
            href={src}
            download={`${film.slug}-still-${String(safeIdx + 1).padStart(2, "0")}.jpg`}
            onClick={(e) => e.stopPropagation()}
            aria-label="Download still"
            title="Download"
          >
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
              <path d="M12 4v12" />
              <path d="M6 12l6 6 6-6" />
              <path d="M5 20h14" />
            </svg>
            <span>Download</span>
          </a>
          <span className="slb-caption-sub">{safeIdx + 1} / {stills.length}</span>
        </figcaption>
      </figure>
    </div>,
    document.body
  );
}

function TrailerLightbox({ film, onClose }) {
  const { t, lang } = useLang();
  const u = legalUrls(lang);
  const [consented, setConsented] = useState(false);
  const tr = film.trailer || "";
  const vimeo = tr.match(/vimeo\.com\/(\d+)(?:\/([a-zA-Z0-9]+))?/);
  const yt = tr.match(/(?:youtu\.be\/|youtube\.com\/watch\?v=)([\w-]+)/);
  const provider = vimeo ? "Vimeo" : yt ? "YouTube" : null;
  return (
    <div className="lb-overlay" onClick={onClose}>
      <button className="lb-close" onClick={onClose} aria-label="Close">✕</button>
      <div className="lb-box" onClick={(e) => e.stopPropagation()}>
        <div className="lb-video">
          {!provider ? (
            <div className="lb-video-ph">
              <div className="lb-play">▶</div>
              <div className="lb-video-label">{t("btn.trailerEmpty")}</div>
            </div>
          ) : !consented ? (
            <div className="lb-consent">
              <h3 className="lb-consent-title">{t("trailer.consent.title")}</h3>
              <p className="lb-consent-body">
                {t("trailer.consent.body").replace("{provider}", provider)}
              </p>
              <div className="lb-consent-actions">
                <button className="lb-consent-primary" onClick={() => setConsented(true)}>
                  {t("trailer.consent.button")}
                </button>
                <button className="lb-consent-ghost" onClick={onClose}>
                  {t("trailer.consent.cancel")}
                </button>
              </div>
              <p className="lb-consent-link">
                <a href={u.privacy} target="_blank" rel="noopener">{t("trailer.consent.privacy")}</a>
              </p>
            </div>
          ) : vimeo ? (
            <iframe
              src={`https://player.vimeo.com/video/${vimeo[1]}${vimeo[2] ? `?h=${vimeo[2]}&autoplay=1` : `?autoplay=1`}`}
              style={{ width: "100%", height: "100%", border: 0 }}
              allow="autoplay; fullscreen; picture-in-picture"
              allowFullScreen
              title={`${film.title} trailer`}
            />
          ) : (
            <iframe
              src={`https://www.youtube-nocookie.com/embed/${yt[1]}?autoplay=1&rel=0`}
              style={{ width: "100%", height: "100%", border: 0 }}
              allow="autoplay; fullscreen"
              allowFullScreen
              title={`${film.title} trailer`}
            />
          )}
        </div>
        <div className="lb-caption">
          <span className="lb-caption-title">{film.title}</span>
          <span className="lb-caption-sub">{t("misc.trailerLabel")} · {film.runtime || "—"} · {film.year || "—"}</span>
        </div>
      </div>
    </div>
  );
}

// ---------- Festivals & Awards (aggregate) ----------
function FestivalsPage({ onOpen }) {
  const { t } = useLang();
  const festivals = [];
  const awards = [];
  for (const f of FILMS) {
    (f.festivals || []).forEach((x) =>
      festivals.push({ ...x, filmId: f.id, filmTitle: f.title })
    );
    (f.awards || []).forEach((x) =>
      awards.push({ ...x, filmId: f.id, filmTitle: f.title })
    );
  }
  festivals.sort((a, b) => (b.year || 0) - (a.year || 0));

  return (
    <>
      <section className="page-head">
        <div className="shell">
          <div className="eyebrow">{t("section.fa")}</div>
          <h1 className="h-display">{t("fa.title")}</h1>
        </div>
      </section>
      <div className="shell">
        <div className="fa-wrap">
          <section className="fa-block">
            <div className="fa-head">
              <div className="fa-kicker">01 — {t("section.awards")}</div>
            </div>
            <div className="fa-table fa-table-awards" role="table">
              <div className="fa-thead" role="row">
                <span role="columnheader">#</span>
                <span role="columnheader">{t("th.award") || "Auszeichnung"}</span>
                <span role="columnheader">{t("th.festival") || "Festival"}</span>
                <span role="columnheader">{t("th.film") || "Film"}</span>
              </div>
              <ul className="fa-tbody">
                {awards.map((a, i) => (
                  <li key={i} className="fa-trow" onClick={() => onOpen(a.filmId)} role="row">
                    <span className="fa-idx" role="cell">{String(i + 1).padStart(2, "0")}</span>
                    <span className="fa-award" role="cell">{a.name}</span>
                    <span className="fa-fest" role="cell">{a.festival}</span>
                    <span className="fa-film-cell" role="cell">{a.filmTitle}</span>
                  </li>
                ))}
              </ul>
            </div>
          </section>

          <section className="fa-block">
            <div className="fa-head">
              <div className="fa-kicker">02 — {t("section.festivals")}</div>
            </div>
            <div className="fa-table fa-table-festivals" role="table">
              <div className="fa-thead" role="row">
                <span role="columnheader">#</span>
                <span role="columnheader">{t("th.festival") || "Festival"}</span>
                <span role="columnheader">{t("th.film") || "Film"}</span>
                <span role="columnheader">{t("th.year") || "Jahr"}</span>
              </div>
              <ul className="fa-tbody">
                {festivals.map((f, i) => (
                  <li key={i} className="fa-trow" onClick={() => onOpen(f.filmId)} role="row">
                    <span className="fa-idx" role="cell">{String(i + 1).padStart(2, "0")}</span>
                    <span className="fa-fest" role="cell">{f.name}</span>
                    <span className="fa-film-cell" role="cell">{f.filmTitle}</span>
                    <span className="fa-year" role="cell">{f.year}</span>
                  </li>
                ))}
              </ul>
            </div>
          </section>
        </div>
      </div>
    </>
  );
}

// ---------- About Us ----------
function AboutPage() {
  const { t, lang } = useLang();
  const u = legalUrls(lang);
  return (
    <>
      <section className="page-head">
        <div className="shell">
          <div className="eyebrow">{t("about.kicker")}</div>
          <h1 className="h-display">{t("about.title")}</h1>
        </div>
      </section>
      <div className="shell">
        <div className="about-grid">
          <div className="about-portraits">
            <figure className="about-portrait">
              <img src="uploads/about-studio.jpg" alt="Cinephiles Films collective" loading="lazy" />
            </figure>
            <figure className="about-portrait">
              <img src="uploads/about-team.jpg" alt="Cinephiles Films team" loading="lazy" />
            </figure>
          </div>
          <div className="prose">
            <div className="prose-body">
              <p className="lead">{t("about.lead")}</p>
              <p>{t("about.body")}</p>
              <p>{t("about.body2")}</p>
              <p>{t("about.body3")}</p>
              <div className="kv-list">
                <div className="kv-row">
                  <div className="k">{t("about.contact")}</div>
                  <div className="v"><a href="mailto:info@cinephiles.de" className="inline-link">info@cinephiles.de</a></div>
                </div>
                <div className="kv-row">
                  <div className="k">{t("about.legal")}</div>
                  <div className="v">
                    <a href={u.imprint} className="inline-link">{t("footer.imprint")}</a>
                    <span style={{ margin: "0 10px", color: "var(--fg-dim)" }}>·</span>
                    <a href={u.privacy} className="inline-link">{t("footer.privacy")}</a>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

Object.assign(window, {
  HomePage,
  FilmsPage,
  DetailPage,
  AboutPage,
  FestivalsPage,
});
