/* global React, ReactDOM, useTweaks, TweaksPanel, TweakSection, TweakRadio, TweakToggle, TweakSlider */
const { useState, useEffect, useRef, useMemo } = React;

/* ───────────────────────── DATA ───────────────────────── */

const ROSTER_FUSSBALL = [
  { n: "01", name: "Stoff", role: "Tor", note: "Hält alles. Außer das Bier." },
  { n: "07", name: "Hansi", role: "Sturm", note: "Tor pro Halbzeit garantiert*" },
  { n: "10", name: "Maxi", role: "10er", note: "Spielmacher, Vorlagengeber" },
  { n: "04", name: "Toni", role: "IV", note: "Brutal in der Luft" },
  { n: "11", name: "Flo", role: "Flügel", note: "Schnell. Sehr schnell." },
  { n: "06", name: "Lukas", role: "6er", note: "Räumt auf" },
  { n: "09", name: "Beni", role: "Stürmer", note: "Kopfballmonster" },
  { n: "03", name: "Sepp", role: "LV", note: "Kapitän der Reserve" },
];

const ROSTER_RACING = [
  { n: "A1", name: "Maxi", role: "Bergziege", note: "Watt/kg unmenschlich" },
  { n: "A2", name: "Flo", role: "Sprinter", note: "Letzte 200m gehören ihm" },
  { n: "A3", name: "Hansi", role: "Domestique", note: "Zieht den Zug" },
  { n: "A4", name: "Stoff", role: "All-Rounder", note: "Alles. Immer." },
  { n: "A5", name: "Toni", role: "Zeitfahrer", note: "Aero-Position perfekt" },
];

const FIXTURES = [
  { date: "SA 27.06", time: "10:00", opp: "Turnier Vidrol", venue: "Vidrol", kind: "Turnier" },
  { date: "SA 18.07", time: "10:00", opp: "Turnier Leisach", venue: "Sportplatz Leisach", kind: "Turnier" },
];

const SPONSORS = ["LEISACHER BRÄU", "BERGADLER GMBH", "PNEU PUSTERTAL", "DRAU CYCLES", "OSTTIROL ENERGIE", "ALMHÜTTE STIEGERHOF"];

const STATS = [
  { v: "13", l: "Spiele 25/26" },
  { v: "11", l: "Siege" },
  { v: "247", l: "Halbe nach Sieg" },
  { v: "1.247", l: "Höhenmeter Schnitt" },
];

/* ───────────────────────── HELPERS ───────────────────────── */

function useCountdown(target) {
  const [now, setNow] = useState(Date.now());
  useEffect(() => {
    const t = setInterval(() => setNow(Date.now()), 1000);
    return () => clearInterval(t);
  }, []);
  const diff = Math.max(0, target - now);
  const d = Math.floor(diff / 86400000);
  const h = Math.floor((diff % 86400000) / 3600000);
  const m = Math.floor((diff % 3600000) / 60000);
  const s = Math.floor((diff % 60000) / 1000);
  return { d, h, m, s };
}

function useMouse() {
  const [p, setP] = useState({ x: 0.5, y: 0.5 });
  useEffect(() => {
    const onMove = (e) => setP({ x: e.clientX / window.innerWidth, y: e.clientY / window.innerHeight });
    window.addEventListener("mousemove", onMove);
    return () => window.removeEventListener("mousemove", onMove);
  }, []);
  return p;
}

/* ───────────────────────── BRAND ASSETS ───────────────────────── */

function SparteLogo({ sparte, className = "crest-medallion", combined = false }) {
  if (combined) {
    return <img src="assets/leisach-combined.png" alt="Leisach II" className={className} />;
  }
  const src = sparte === "racing" ? "assets/leisach-racing.jpeg" : "assets/leisach-fussball.png";
  const alt = sparte === "racing" ? "Leisach II Racing" : "Leisach II Fußball";
  return <img src={src} alt={alt} className={className} />;
}

function CrestLogo({ size = 56, dark = false }) {
  // Tighter monoline mark: hexagon outline + sharp triple peaks + stamped "II" inside
  const fg = dark ? "#f4ede1" : "#0a1b35";
  const accent = "var(--accent)";
  return (
    <svg
      className="crest-logo"
      viewBox="0 0 200 200"
      width={size}
      height={size}
      xmlns="http://www.w3.org/2000/svg"
      style={{ display: "block" }}
    >
      {/* Outer hexagon — modern, geometric */}
      <path
        d="M 100 12 L 176 56 L 176 144 L 100 188 L 24 144 L 24 56 Z"
        fill="none"
        stroke={fg}
        strokeWidth="2.2"
        strokeLinejoin="miter"
      />
      {/* Inner accent ring (subtle inset) */}
      <path
        d="M 100 28 L 162 64 L 162 136 L 100 172 L 38 136 L 38 64 Z"
        fill="none"
        stroke={fg}
        strokeWidth="0.8"
        strokeLinejoin="miter"
        opacity="0.25"
      />
      {/* Three sharp peaks — clean monoline */}
      <path
        d="M 50 124 L 78 76 L 96 104 L 118 60 L 142 100 L 154 124"
        fill="none"
        stroke={fg}
        strokeWidth="3.4"
        strokeLinecap="square"
        strokeLinejoin="miter"
      />
      {/* Single accent mark — bold gold dot above tallest peak */}
      <circle cx="118" cy="40" r="5" fill={accent} />
      {/* Big italic II — the brand mark, bottom */}
      <text
        x="100" y="166"
        textAnchor="middle"
        fontFamily="Newsreader, Times New Roman, serif"
        fontStyle="italic"
        fontWeight="500"
        fontSize="32"
        fill={accent}
        letterSpacing="-0.02em"
      >II</text>
    </svg>
  );
}

function MountainDraw() {
  // Hand-drawn mountain silhouette spanning whole hero — peaks rise tall.
  return (
    <svg
      className="mtn-draw"
      viewBox="0 0 1600 900"
      preserveAspectRatio="none"
      xmlns="http://www.w3.org/2000/svg"
      aria-hidden
    >
      {/* Far range — soft, peaks lower */}
      <path
        className="mtn-far"
        d="M -20 720 L 120 580 L 220 660 L 360 460 L 480 600 L 600 520 L 760 620 L 900 480 L 1060 640 L 1220 540 L 1360 620 L 1500 560 L 1620 640 L 1620 900 L -20 900 Z"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.4"
        strokeLinejoin="round"
      />
      {/* Mid range — taller peaks */}
      <path
        className="mtn-mid"
        d="M -20 800 L 100 640 L 200 740 L 340 460 L 460 680 L 560 540 L 700 700 L 820 360 L 960 660 L 1080 520 L 1240 720 L 1380 540 L 1500 700 L 1620 620 L 1620 900 L -20 900 Z"
        fill="none"
        stroke="currentColor"
        strokeWidth="1.8"
        strokeLinejoin="round"
      />
      {/* Near range with detail */}
      <path
        className="mtn-near"
        d="M -20 900 L -20 820 L 80 720 L 180 800 L 280 600 L 360 760 L 460 580 L 540 740 L 640 540 L 720 740 L 820 480 L 920 720 L 1020 600 L 1120 760 L 1240 620 L 1340 760 L 1440 640 L 1540 760 L 1620 700 L 1620 900 Z"
        fill="none"
        stroke="currentColor"
        strokeWidth="2.2"
        strokeLinejoin="round"
      />
      {/* Snow caps */}
      <g className="mtn-caps" stroke="currentColor" strokeWidth="2" fill="none" opacity="0.6">
        <path d="M 350 472 L 360 460 L 372 478" />
        <path d="M 810 372 L 820 360 L 834 376" />
        <path d="M 815 494 L 820 480 L 830 492" />
        <path d="M 635 552 L 640 540 L 648 552" />
      </g>
      {/* Tree dots */}
      <g className="mtn-trees" fill="currentColor" opacity="0.55">
        <circle cx="120" cy="830" r="3" />
        <circle cx="240" cy="850" r="3" />
        <circle cx="380" cy="830" r="3" />
        <circle cx="600" cy="830" r="3" />
        <circle cx="780" cy="838" r="3" />
        <circle cx="990" cy="820" r="3" />
        <circle cx="1180" cy="838" r="3" />
        <circle cx="1380" cy="838" r="3" />
      </g>
      {/* Single bird */}
      <path className="mtn-bird" d="M 1180 280 q 6 -8 12 0 q 6 -8 12 0" fill="none" stroke="currentColor" strokeWidth="1.5" opacity="0.5" />
      <path className="mtn-bird" d="M 1230 320 q 5 -6 10 0 q 5 -6 10 0" fill="none" stroke="currentColor" strokeWidth="1.5" opacity="0.4" />
    </svg>
  );
}

function MorphingPill() {
  const messages = [
    "SAISON 25/26 · LANDING IN PROGRESS",
    "BIERORDNUNG §1 — §47 · IM ENTWURF",
    "247 HALBE NACH SIEG · KALKULIERT",
    "OSTTIROL · 46.82°N 12.74°E",
    "BUILT IN OSTTIROL · POWERED BY MALZ",
    "TRIKOT 25/26 · IN PRODUKTION",
  ];
  const [i, setI] = useState(0);
  useEffect(() => {
    const t = setInterval(() => setI(v => (v + 1) % messages.length), 3200);
    return () => clearInterval(t);
  }, []);
  return (
    <span className="ed-nav-soon">
      <span className="ed-nav-dot" />
      <span className="ed-nav-roll" key={i}>{messages[i]}</span>
    </span>
  );
}

/* Rubber stamp — looks pressed-on at angle */
function RubberStamp({ text = "GENEHMIGT", sub = "MMXXVI", angle = -8, top, left, right, bottom }) {
  const style = { top, left, right, bottom, transform: `rotate(${angle}deg)` };
  return (
    <div className="rubber-stamp" style={style} aria-hidden>
      <div className="rs-ring">
        <div className="rs-inner">
          <div className="rs-text">{text}</div>
          <div className="rs-divider">★</div>
          <div className="rs-sub">{sub}</div>
        </div>
      </div>
    </div>
  );
}

/* Hand-drawn annotation arrow + scribble */
function HandAnnotation({ x, y, label, dir = "left" }) {
  // dir = "left" arrow points right (label on left)
  const isLeft = dir === "left";
  return (
    <div className="hand-annot" style={{ left: x, top: y }} aria-hidden>
      <svg width="200" height="120" viewBox="0 0 200 120" className="hand-annot-svg">
        {isLeft ? (
          <>
            <path d="M 8 80 Q 60 30, 120 50 T 188 70" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
            <path d="M 178 60 L 192 72 L 175 78" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
          </>
        ) : (
          <>
            <path d="M 192 80 Q 140 30, 80 50 T 12 70" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
            <path d="M 22 60 L 8 72 L 25 78" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
          </>
        )}
      </svg>
      <span className="hand-annot-label" style={isLeft ? {} : { right: 0, left: "auto" }}>{label}</span>
    </div>
  );
}

/* Flying bird silhouette — crosses sky every ~28s */
function FlyingBird() {
  return (
    <div className="bird-stage" aria-hidden>
      <svg viewBox="0 0 60 30" className="bird-svg">
        <path d="M 4 18 Q 12 4, 22 14 Q 30 4, 38 14 Q 48 4, 56 18" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
      </svg>
    </div>
  );
}

/* Live versus card — Fußball ⨯ Racing duality with rotating stats */
function VersusCard() {
  const stats = [
    { eyebrow: "ZWEI SPARTEN · EIN VEREIN", lA: "Mann", nA: "11", labelA: "Fussball", lB: "Räder", nB: "02", labelB: "Racing", foot: "Rasen trifft Asphalt" },
    { eyebrow: "DIE ROHDATEN · 25/26", lA: "Tore", nA: "47", labelA: "Saison", lB: "Podest", nB: "06", labelB: "Saison", foot: "Bilanz auf Kurs" },
    { eyebrow: "ALTER · DURCHSCHNITT", lA: "Jahre", nA: "24", labelA: "Mannschaft", lB: "PS", nB: "118", labelB: "Maschine", foot: "Jung & laut" },
    { eyebrow: "BIER NACH HEIMSPIEL", lA: "Halbe", nA: "247", labelA: "Statistisch", lB: "Min", nB: "12", labelB: "Bis Schaum weg", foot: "Bierordnung §3" },
  ];
  const [idx, setIdx] = useState(0);
  useEffect(() => {
    const t = setInterval(() => setIdx(v => (v + 1) % stats.length), 4500);
    return () => clearInterval(t);
  }, []);
  const s = stats[idx];
  return (
    <div className="versus-card" aria-hidden>
      <div className="vs-eyebrow">
        <span className="vs-dot" />
        <span className="vs-eyebrow-text" key={"e" + idx}>{s.eyebrow}</span>
        <span className="vs-page">{String(idx + 1).padStart(2, "0")}/{String(stats.length).padStart(2, "0")}</span>
      </div>
      <div className="vs-row" key={"r" + idx}>
        <div className="vs-side">
          <div className="vs-num">{s.nA}</div>
          <div className="vs-label">{s.lA}</div>
          <div className="vs-name">{s.labelA}</div>
        </div>
        <div className="vs-x">×</div>
        <div className="vs-side">
          <div className="vs-num">{s.nB}</div>
          <div className="vs-label">{s.lB}</div>
          <div className="vs-name">{s.labelB}</div>
        </div>
      </div>
      <div className="vs-divider" />
      <div className="vs-foot">
        <span className="vs-foot-text" key={"f" + idx}>{s.foot}</span>
        <span className="vs-foot-r">{idx === 3 ? "🍺" : "→"}</span>
      </div>
      {/* Tape strip — fake "barcode" of pages */}
      <div className="vs-tape">
        {stats.map((_, i) => (
          <span key={i} className={"vs-tape-bar" + (i === idx ? " vs-tape-bar-active" : "")} />
        ))}
      </div>
    </div>
  );
}

/* Cursor trail — ephemeral dots */
function CursorTrail() {
  const [pts, setPts] = useState([]);
  useEffect(() => {
    let id = 0;
    const onMove = (e) => {
      setPts(p => {
        const next = [...p, { id: id++, x: e.clientX, y: e.clientY, t: Date.now() }];
        return next.slice(-10);
      });
    };
    window.addEventListener("mousemove", onMove);
    const cleanup = setInterval(() => {
      const now = Date.now();
      setPts(p => p.filter(pt => now - pt.t < 800));
    }, 100);
    return () => {
      window.removeEventListener("mousemove", onMove);
      clearInterval(cleanup);
    };
  }, []);
  return (
    <div className="cursor-trail" aria-hidden>
      {pts.map((pt, i) => (
        <span
          key={pt.id}
          className="ct-dot"
          style={{
            left: pt.x,
            top: pt.y,
            opacity: (i / pts.length) * 0.4,
            transform: `scale(${0.3 + (i / pts.length) * 0.7})`,
          }}
        />
      ))}
    </div>
  );
}

function SnowDrift() {
  const flakes = useMemo(() =>
    Array.from({ length: 24 }).map(() => ({
      l: Math.random() * 100,
      d: 8 + Math.random() * 16,
      delay: -Math.random() * 16,
      o: 0.15 + Math.random() * 0.35,
      s: 1 + Math.random() * 2,
      drift: (Math.random() - 0.5) * 60,
    })), []);
  return (
    <div className="snow-stage" aria-hidden>
      {flakes.map((f, i) => (
        <span
          key={i}
          className="snow-flake"
          style={{
            left: f.l + "%",
            animationDuration: f.d + "s",
            animationDelay: f.delay + "s",
            opacity: f.o,
            width: f.s + "px",
            height: f.s + "px",
            "--drift": f.drift + "px",
          }}
        />
      ))}
    </div>
  );
}

function SunArc() {
  return (
    <div className="sun-arc" aria-hidden>
      <svg viewBox="0 0 1600 900" preserveAspectRatio="xMidYMid slice">
        {/* Sun disc — concentric rings */}
        <circle cx="800" cy="780" r="320" fill="none" stroke="var(--accent)" strokeWidth="1.4" opacity="0.55" />
        <circle cx="800" cy="780" r="240" fill="none" stroke="var(--accent)" strokeWidth="1.2" opacity="0.45" />
        <circle cx="800" cy="780" r="170" fill="none" stroke="var(--accent)" strokeWidth="1" opacity="0.35" />
        <circle cx="800" cy="780" r="105" fill="none" stroke="var(--accent)" strokeWidth="0.8" opacity="0.25" />
        {/* Sun rays */}
        <g className="sun-rays" stroke="var(--accent)" strokeWidth="1.2" strokeLinecap="round">
          {Array.from({ length: 16 }).map((_, i) => {
            const a = (i * Math.PI * 2) / 16 - Math.PI / 2;
            const x1 = 800 + Math.cos(a) * 340;
            const y1 = 780 + Math.sin(a) * 340;
            const x2 = 800 + Math.cos(a) * (i % 2 === 0 ? 460 : 410);
            const y2 = 780 + Math.sin(a) * (i % 2 === 0 ? 460 : 410);
            return <line key={i} x1={x1} y1={y1} x2={x2} y2={y2} opacity={0.5} />;
          })}
        </g>
        {/* tiny center sun */}
        <circle cx="800" cy="780" r="6" fill="var(--accent)" opacity="0.7" />
      </svg>
    </div>
  );
}

function Constellation() {
  const m = useMouse();
  // 5 anchor stars whose hairlines connect through the cursor
  const stars = [
    { x: 12, y: 22 }, { x: 78, y: 18 }, { x: 88, y: 64 },
    { x: 18, y: 72 }, { x: 50, y: 50 },
  ];
  const cx = m.x * 100, cy = m.y * 100;
  return (
    <svg className="constellation" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden>
      {stars.map((s, i) => (
        <line
          key={i}
          x1={s.x} y1={s.y} x2={cx} y2={cy}
          stroke="var(--accent)"
          strokeWidth="0.05"
          opacity={0.18}
        />
      ))}
      {stars.map((s, i) => (
        <circle key={"s" + i} cx={s.x} cy={s.y} r="0.25" fill="var(--accent)" opacity="0.5" />
      ))}
    </svg>
  );
}

/* ───────────────────────── HERO VARIANTS ───────────────────────── */

function HeroEditorial({ sparte }) {
  const m = useMouse();
  const [scroll, setScroll] = useState(0);
  const [time, setTime] = useState(new Date());

  useEffect(() => {
    const onScroll = () => setScroll(window.scrollY);
    window.addEventListener("scroll", onScroll, { passive: true });
    const t = setInterval(() => setTime(new Date()), 1000);
    return () => { window.removeEventListener("scroll", onScroll); clearInterval(t); };
  }, []);

  const tx = (m.x - 0.5) * 24;
  const ty = (m.y - 0.5) * 24;

  return (
    <section className="hero hero-editorial">
      {/* Drifting LEISACH parallax band — kept, iconic */}
      <div
        className="ed-drift-name ed-anim"
        aria-hidden
        style={{ transform: `translate3d(${-scroll * 0.5 - 40}px, 0, 0)` }}
      >
        LEISACH&nbsp;·&nbsp;LEISACH&nbsp;·&nbsp;LEISACH&nbsp;·&nbsp;LEISACH
      </div>

      <SunArc />

      <div className="ed-mtn-stage" aria-hidden>
        <MountainDraw />
      </div>

      {/* THE II — sculptural centerpiece */}
      <div
        className="ed-ii-stage ed-anim"
        aria-hidden
        style={{ transform: `translate3d(${tx * 0.3}px, ${ty * 0.3 - scroll * 0.1}px, 0)` }}
      >
        <div className="ed-ii-glyph">II</div>
        <div className="ed-ii-shadow">II</div>
        <div className="ed-ii-stripe">II</div>
      </div>

      {/* Two minimal gold accents */}
      <div className="ed-stars" aria-hidden>
        <span className="ed-star ed-star-1">✦</span>
        <span className="ed-star ed-star-4">✦</span>
      </div>

      <header className="ed-topbar ed-topbar-min ed-anim">
        <div className="ed-mark">
          <SparteLogo combined className="crest-medallion ed-crest-img" />
          <div className="ed-mark-text">
            <div className="ed-mark-1">LEISACH&nbsp;<em>II</em></div>
          </div>
        </div>
        <div className="ed-topbar-rail">
          <span className="ed-rail-kicker">Built in <em>Osttirol</em>·Powered by <em>Malz</em></span>
          <span className="ed-rail-divider" />
          <span className="ed-rail-coord">46.82°N&nbsp;·&nbsp;12.74°E</span>
          <span className="ed-rail-divider" />
          <span className="ed-rail-time">{time.toLocaleTimeString("de-AT", { hour: "2-digit", minute: "2-digit", second: "2-digit" })}</span>
          <button className="ed-cta" data-trikot-trigger type="button">
            <span>Radtrikot 25/26</span>
            <span className="ed-cta-arrow">↗</span>
          </button>
        </div>
      </header>

      <div className="ed-edge-l ed-anim" aria-hidden>
        <span>VOL.</span>
        <span className="ed-edge-num">II</span>
        <span>MMXXVI</span>
      </div>
      <div className="ed-edge-r ed-anim" aria-hidden>
        <span>BUILT IN</span>
        <span className="ed-edge-num">·</span>
        <span>OSTTIROL</span>
      </div>

      <div className="ed-bottom-bar ed-anim">
        <div className="ed-claim ed-claim-display">
          <div className="ed-claim-line-1">Die <em>Zweite.</em></div>
          <div className="ed-claim-line-2">Durstiger als die <span className="ed-claim-mark-w">Erste</span>.</div>
        </div>
        <div className="ed-scroll">
          <span>SCROLL</span>
          <div className="ed-scroll-line"><span /></div>
        </div>
      </div>

      <div className="ed-marquee ed-anim">
        <div className="ed-marquee-track">
          {Array.from({ length: 6 }).map((_, i) => (
            <span key={i}>
              ✦ LEISACH&nbsp;II ✦ MMXXVI ✦ BUILT IN OSTTIROL · POWERED BY MALZ ✦ BERG · BIER · BALL ✦ OSTTIROL ✦ SPORTCLUB · MMXIX ✦&nbsp;
            </span>
          ))}
        </div>
      </div>
    </section>
  );
}

function HeroBroadcast({ sparte }) {
  const isFB = sparte === "fussball";
  const cd = useCountdown(useMemo(() => Date.now() + 1000 * 60 * 60 * 78 + 47000, []));

  return (
    <section className="hero hero-broadcast">
      <div className="bc-grid-bg" aria-hidden />
      <div className="bc-scanline" aria-hidden />

      <header className="bc-topbar">
        <div className="bc-channel">
          <div className="bc-ch-logo"><SparteLogo combined className="crest-medallion bc-ch-img" /></div>
          <div>
            <div className="bc-ch-1">LEISACH II · SPORTNETWORK</div>
            <div className="bc-ch-2">CH 02 · 24/7 BERG · BIER · BALL</div>
          </div>
        </div>
        <div className="bc-clock"><span className="dot live" /> LIVE · {new Date().toLocaleTimeString("de-AT", { hour: "2-digit", minute: "2-digit" })}</div>
      </header>

      <div className="bc-stage">
        <div className="bc-tag">{isFB ? "MATCHDAY -3" : "RACE WEEK"}</div>
        <h1 className="bc-headline">
          {isFB ? "MATCH" : "STAGE"}<br />
          <span className="bc-headline-italic">PREVIEW.</span>
        </h1>

        <div className="bc-stats">
          {STATS.map((s, i) => (
            <div className="bc-stat" key={i}>
              <div className="bc-stat-v">{s.v}</div>
              <div className="bc-stat-l">{s.l}</div>
            </div>
          ))}
        </div>
      </div>

      <div className="bc-lower-third">
        <div className="bc-lt-left">
          <div className="bc-lt-tag">NEXT FIXTURE</div>
          <div className="bc-lt-main">LEISACH II <span>·</span> TURNIER VIDROL</div>
          <div className="bc-lt-sub">SA 27.06.2026 · VIDROL</div>
        </div>
        <div className="bc-lt-right">
          <div className="bc-cd">
            {[
              ["TG", cd.d], ["STD", cd.h], ["MIN", cd.m], ["SEK", cd.s]
            ].map(([l, v], i) => (
              <div key={i}>
                <b>{String(v).padStart(2, "0")}</b>
                <span>{l}</span>
              </div>
            ))}
          </div>
        </div>
      </div>

      <div className="bc-ticker">
        <div className="bc-ticker-label">BREAKING</div>
        <div className="bc-ticker-track">
          <span>★ Hansi trifft im Aufwärmen 14× in Folge — Trainer "leicht beunruhigt"</span>
          <span>★ Maxi sichtet sich neuen Sattel — gesamte Saison gefährdet</span>
          <span>★ Leisacher Bräu erhöht Halbe-Limit auf 4 nach Sieg</span>
          <span>★ Toni weiterhin ungeschlagen im Bierdiscus</span>
          <span>★ Wetter Samstag: warm, mild, optimal für Niederlagen des Gegners</span>
        </div>
      </div>
    </section>
  );
}

function HeroExperimental({ sparte }) {
  const isFB = sparte === "fussball";
  const m = useMouse();
  const cd = useCountdown(useMemo(() => Date.now() + 1000 * 60 * 60 * 78 + 47000, []));

  const tx = (m.x - 0.5) * 40;
  const ty = (m.y - 0.5) * 40;

  return (
    <section className="hero hero-exp">
      {/* layered mountains */}
      <div className="ex-mountains" aria-hidden>
        <svg viewBox="0 0 1600 600" preserveAspectRatio="none">
          <defs>
            <linearGradient id="m1" x1="0" x2="0" y1="0" y2="1">
              <stop offset="0" stopColor="#0b1d3a" />
              <stop offset="1" stopColor="#04060c" />
            </linearGradient>
          </defs>
          <path d="M0 600 L0 380 L180 200 L320 320 L460 180 L640 360 L820 220 L1000 380 L1200 240 L1400 360 L1600 280 L1600 600 Z" fill="#0b1d3a" />
          <path d="M0 600 L0 460 L160 320 L320 420 L500 300 L700 440 L900 340 L1100 460 L1300 360 L1600 440 L1600 600 Z" fill="#08152a" />
          <path d="M0 600 L0 520 L200 460 L420 520 L640 460 L880 540 L1100 480 L1320 540 L1600 500 L1600 600 Z" fill="#040912" />
        </svg>
      </div>

      <div className="ex-orb" style={{ transform: `translate(${tx * 2}px, ${ty * 2}px)` }} aria-hidden />
      <div className="ex-orb ex-orb-2" style={{ transform: `translate(${-tx * 1.5}px, ${-ty * 1.5}px)` }} aria-hidden />
      <div className="ex-grid" aria-hidden />

      <header className="ex-topbar">
        <div className="ex-mark">
          <SparteLogo combined className="crest-medallion ex-mark-img" />
          <span>LEISACH II</span>
        </div>
        <nav>
          <a>TEAM</a><a>FIXTURES</a><a>RACING</a><a>SHOP*</a>
        </nav>
      </header>

      <div className="ex-stage">
        <div className="ex-eyebrow">
          <span className="dot live" /> SAISON 25/26 · {isFB ? "FUSSBALL" : "RACING"} DIVISION
        </div>

        <h1 className="ex-headline" style={{ transform: `translate3d(${tx * 0.3}px, ${ty * 0.3}px, 0)` }}>
          <span className="ex-h-1">BERG.</span>
          <span className="ex-h-2">BIER.</span>
          <span className="ex-h-3">BALL.</span>
          <span className="ex-h-4">{isFB ? "BUDE." : "BREAKAWAY."}</span>
        </h1>

        <div className="ex-glass">
          <div className="ex-glass-row">
            <div>
              <div className="ex-g-l">NÄCHSTER START</div>
              <div className="ex-g-v">FR · 02.05 · 19:30</div>
            </div>
            <div>
              <div className="ex-g-l">GEGNER</div>
              <div className="ex-g-v">PUSTERTAL-SCHLUCK</div>
            </div>
            <div>
              <div className="ex-g-l">COUNTDOWN</div>
              <div className="ex-g-v ex-mono">
                {String(cd.d).padStart(2, "0")}:{String(cd.h).padStart(2, "0")}:{String(cd.m).padStart(2, "0")}:{String(cd.s).padStart(2, "0")}
              </div>
            </div>
          </div>
          <button className="ex-cta">
            <span>SAISONHEFT ÖFFNEN</span>
            <span className="ex-cta-arrow">↗</span>
          </button>
        </div>
      </div>
    </section>
  );
}

/* ───────────────────────── REVEAL ON SCROLL ───────────────────────── */

function useRevealOnScroll(selector, threshold = 0.35) {
  useEffect(() => {
    const els = document.querySelectorAll(selector);
    if (!els.length) return;
    const obs = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add("in-view");
          obs.unobserve(e.target);
        }
      });
    }, { threshold });
    els.forEach(el => obs.observe(el));
    return () => obs.disconnect();
  }, [selector, threshold]);
}

/* ───────────────────────── MEDIA — video + cut-out player ───────────────────────── */

function MediaSection() {
  useRevealOnScroll(".media-reveal");
  const [muted, setMuted] = useState(true);
  const iframeRef = useRef(null);
  const userMutedRef = useRef(false); // user explicitly muted via button → don't auto-unmute

  const sendCmd = (func, args = "") => {
    const w = iframeRef.current && iframeRef.current.contentWindow;
    if (!w) return;
    w.postMessage(JSON.stringify({ event: "command", func, args }), "*");
  };

  const toggleSound = () => {
    if (muted) {
      sendCmd("unMute");
      sendCmd("setVolume", [70]);
      userMutedRef.current = false;
      setMuted(false);
    } else {
      sendCmd("mute");
      userMutedRef.current = true;
      setMuted(true);
    }
  };

  // Keep the video playing (muted autoplay). Sound only via the unmute button.
  useEffect(() => {
    const armTimer = setTimeout(() => {
      sendCmd("playVideo");
    }, 2500);

    const keepAlive = setInterval(() => {
      sendCmd("playVideo");
    }, 5000);

    return () => {
      clearTimeout(armTimer);
      clearInterval(keepAlive);
    };
  }, []);

  return (
    <section className="media-sec">
      <div className="media-grain" aria-hidden />
      <div className="media-eyebrow media-reveal">
        <span className="media-eyebrow-line" />
        <span>¶ DORFLEGENDEN · SOUNDTRACK 25/26</span>
        <span className="media-eyebrow-line" />
      </div>

      <div className="media-stage">
        {/* Big background headline */}
        <div className="media-bg-text" aria-hidden>
          <span>BERG</span>
          <span>BIER</span>
          <span>BALL</span>
        </div>

        {/* Autoplay video — tilted card */}
        <div className="media-video-card media-reveal">
          <div className="media-video-frame">
            <iframe
              ref={iframeRef}
              className="media-video"
              src="https://www.youtube.com/embed/P1XOLNZgg6Q?autoplay=1&mute=1&loop=1&playlist=P1XOLNZgg6Q&controls=0&modestbranding=1&rel=0&playsinline=1&iv_load_policy=3&showinfo=0&disablekb=1&enablejsapi=1"
              title="Florian Andreas — Dorflegenden"
              frameBorder="0"
              allow="autoplay; encrypted-media; picture-in-picture"
              allowFullScreen
            />
            {/* subtle scanline overlay for character */}
            <div className="media-video-scan" aria-hidden />
            {/* Sound toggle */}
            <button
              type="button"
              className={"media-video-sound" + (muted ? " is-muted" : " is-on")}
              onClick={toggleSound}
              aria-label={muted ? "Ton einschalten" : "Ton ausschalten"}
            >
              <span className="media-video-sound-ico">{muted ? "🔇" : "🔊"}</span>
              <span className="media-video-sound-l">{muted ? "TON AN" : "TON AUS"}</span>
            </button>
          </div>
          <div className="media-video-meta">
            <span className="dot live" />
            <span className="media-video-title"><em>Florian Andreas</em> — Dorflegenden</span>
            <span className={"media-video-pill" + (muted ? " is-muted-pill" : "")}>
              {muted ? "TON AN — BUTTON DRÜCKEN" : "TON LÄUFT"}
            </span>
          </div>
        </div>

        {/* Cut-out player — masked into transparency */}
        <div className="media-player-stage media-reveal" aria-hidden>
          <img src="assets/player-cutout.png" alt="" className="media-player" />
          <div className="media-player-glow" />
        </div>

        {/* Sticker / N°99 badge */}
        <div className="media-sticker media-reveal">
          <span className="media-sticker-l">NUMMER</span>
          <span className="media-sticker-num">99</span>
          <span className="media-sticker-r">LEISACH&nbsp;II</span>
        </div>

        {/* Three-truths spine — wordplay on "Halbzeit" */}
        <div className="media-truths media-reveal">
          <div>Manche spielen auf <em>Sieg.</em></div>
          <div>Manche fahren auf <em>Zeit.</em></div>
          <div>Wir spielen auf die <em>Dritte&nbsp;Halbzeit.</em></div>
        </div>
      </div>

      <div className="media-foot">— BUILT IN OSTTIROL · POWERED BY MALZ —</div>
    </section>
  );
}


/* ───────────────────────── SHARED SECTIONS ───────────────────────── */

function SectionLabel({ n, t, k }) {
  return (
    <div className="sec-label">
      <span className="sec-n">{n}</span>
      <span className="sec-t">{t}</span>
      {k && <span className="sec-k">/ {k}</span>}
    </div>
  );
}

function Fixtures() {
  useRevealOnScroll(".fix-reveal");
  return (
    <section className="fix-sec">
      <div className="fix-eyebrow fix-reveal">
        <span className="fix-eyebrow-line" />
        <span>¶ TERMINE · SAISON 25/26</span>
        <span className="fix-eyebrow-line" />
      </div>

      <h2 className="fix-h fix-reveal">
        Wann <em>treffen</em> wir uns?
      </h2>

      <div className="fix-grid">
        {FIXTURES.map((f, i) => {
          const [day, dm] = f.date.split(" ");
          return (
            <article className="fix-card fix-reveal" key={i}>
              <div className="fix-card-tag">{f.kind}</div>
              <div className="fix-card-date">
                <span className="fix-card-day">{day}</span>
                <span className="fix-card-num">{dm}</span>
              </div>
              <div className="fix-card-title">{f.opp}</div>
              <div className="fix-card-meta">
                <span>{f.venue}</span>
              </div>
            </article>
          );
        })}
      </div>

      <div className="fix-foot">— ZWEI TERMINE · MEHR BRAUCHT'S NICHT —</div>
    </section>
  );
}

function Gallery() {
  useRevealOnScroll(".gal-reveal");
  return (
    <section className="gal-sec">
      <div className="gal-eyebrow gal-reveal">
        <span className="gal-eyebrow-line" />
        <span>¶ EINBLICKE · BERG · BIER · BALL</span>
        <span className="gal-eyebrow-line" />
      </div>

      <h2 className="gal-h gal-reveal">
        Aus dem <em>Maschinenraum.</em>
      </h2>

      <div className="gal-grid">
        <figure className="gal-tile gal-tile-wide gal-reveal">
          <img src="assets/photos/team-1.jpeg" alt="Mannschaftsfoto Leisach II" />
          <figcaption className="gal-cap">
            <span className="gal-cap-n">№ 01</span>
            <span className="gal-cap-t">Die Mannschaft · Sommer 2026</span>
          </figcaption>
        </figure>

        <figure className="gal-tile gal-tile-strike gal-reveal">
          <img src="assets/photos/coach-1.jpeg" alt="Ex-Trainer Leisach II" />
          <span className="gal-tile-strike-x" aria-hidden />
          <figcaption className="gal-cap">
            <span className="gal-cap-n">№ 02</span>
            <span className="gal-cap-t">Der Ex-Trainer am Spielfeldrand</span>
          </figcaption>
        </figure>

        <figure className="gal-tile gal-reveal">
          <img src="assets/photos/coaches.jpeg" alt="Trainerteam Leisach II" />
          <figcaption className="gal-cap">
            <span className="gal-cap-n">№ 03</span>
            <span className="gal-cap-t">Das Trainerteam</span>
          </figcaption>
        </figure>

        <figure className="gal-tile gal-tile-wide gal-reveal">
          <img src="assets/photos/action-1.jpeg" alt="Einwurf · Nummer 28" />
          <figcaption className="gal-cap">
            <span className="gal-cap-n">№ 04</span>
            <span className="gal-cap-t">Einwurf · Nr. 28 in Aktion</span>
          </figcaption>
        </figure>

        <figure className="gal-tile gal-reveal">
          <img src="assets/photos/action-2.jpeg" alt="Kopfball-Duell" />
          <figcaption className="gal-cap">
            <span className="gal-cap-n">№ 05</span>
            <span className="gal-cap-t">Kopfball-Duell</span>
          </figcaption>
        </figure>
      </div>
    </section>
  );
}

function BreakingNews() {
  useRevealOnScroll(".bn-reveal");
  return (
    <section className="bn-sec">
      <div className="bn-strip">
        <div className="bn-strip-track">
          {Array.from({ length: 2 }).map((_, k) => (
            <div className="bn-strip-track-half" key={k}>
              {Array.from({ length: 8 }).map((_, i) => (
                <React.Fragment key={i}>
                  <span className="bn-strip-dot" />
                  <span className="bn-strip-label">EILMELDUNG</span>
                </React.Fragment>
              ))}
            </div>
          ))}
        </div>
      </div>

      <div className="bn-inner">
        <div className="bn-grid">
          <div className="bn-text">
            <div className="bn-meta bn-reveal">
              <span className="bn-meta-tag">PRESSEMITTEILUNG</span>
              <span className="bn-meta-sep" />
              <span className="bn-meta-date">LEISACH · MMXXVI</span>
            </div>

            <h2 className="bn-headline bn-reveal">
              Cheftrainer <em>entlassen.</em>
            </h2>

            <p className="bn-lead bn-reveal">
              Nach internen Problemen und Unstimmigkeiten wurde unser
              Cheftrainer von seiner Rolle entbunden und übernimmt ab sofort
              wieder die volle Verantwortung für die <em>Torwart-Position</em>.
            </p>
          </div>

          <figure className="bn-photo bn-reveal">
            <img src="assets/photos/coach-1.jpeg" alt="Ehemaliger Cheftrainer am Spielfeldrand" />
            <span className="bn-photo-strike" aria-hidden />
            <figcaption className="bn-photo-cap">
              <span className="bn-photo-tag">EX-TRAINER</span>
              <span className="bn-photo-t">Der Ex-Cheftrainer · letzte Anweisungen am Spielfeldrand</span>
            </figcaption>
          </figure>
        </div>

        <div className="bn-divider bn-reveal" />

        <div className="bn-cta-row bn-reveal">
          <div className="bn-cta-text">
            <div className="bn-cta-tag">STELLENAUSSCHREIBUNG</div>
            <div className="bn-cta-h">Cheftrainer-Position offen.</div>
            <div className="bn-cta-sub">Bewerbungen bitte per WhatsApp.</div>
          </div>
        </div>
      </div>

      <div className="bn-strip bn-strip-end">
        <div className="bn-strip-track">
          {Array.from({ length: 2 }).map((_, k) => (
            <div className="bn-strip-track-half" key={k}>
              {Array.from({ length: 8 }).map((_, i) => (
                <React.Fragment key={i}>
                  <span className="bn-strip-dot" />
                  <span className="bn-strip-label">ENDE DER EILMELDUNG</span>
                </React.Fragment>
              ))}
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

function SparteSelect({ sparte, setSparte }) {
  return (
    <section className="ss">
      <div className="ss-eyebrow">
        <span className="ss-eyebrow-line" />
        <span className="ss-eyebrow-text">¶ WÄHLE DEINE DISZIPLIN</span>
        <span className="ss-eyebrow-line" />
      </div>

      <div className="ss-hint">
        <span className="ss-hint-icon" aria-hidden>👇</span>
        Klick auf eine Disziplin · eigene Unterseite
      </div>

      <div className="ss-grid">
        <a
          href="/fussball/"
          className={`ss-card ss-card-fussball ss-card-link ${sparte === "fussball" ? "active" : ""}`}
          onMouseEnter={() => setSparte("fussball")}
        >
          <div className="ss-card-bg" aria-hidden>
            <span className="ss-bg-num">I</span>
          </div>
          <span className="ss-card-badge">LIVE</span>
          <img src="assets/leisach-fussball.png" alt="" className="ss-card-logo" aria-hidden />
          <div className="ss-card-inner">
            <div className="ss-card-tag">DISZIPLIN · I · MMXIX → ∞</div>
            <div className="ss-card-title">Fußball</div>
            <div className="ss-card-cta">
              <span>Rein in die Kabine</span>
              <span className="ss-card-cta-arrow" aria-hidden>→</span>
            </div>
          </div>
        </a>

        <div className="ss-divider" aria-hidden>
          <span>×</span>
        </div>

        <div
          className={`ss-card ss-card-racing ss-card-disabled ${sparte === "racing" ? "active" : ""}`}
          onMouseEnter={() => setSparte("racing")}
        >
          <div className="ss-card-bg" aria-hidden>
            <span className="ss-bg-num">II</span>
          </div>
          <span className="ss-card-badge ss-card-badge-soon">BALD</span>
          <img src="assets/leisach-racing.jpeg" alt="" className="ss-card-logo ss-card-logo-racing" aria-hidden />
          <div className="ss-card-inner">
            <div className="ss-card-tag">DISZIPLIN · II</div>
            <div className="ss-card-title">Racing</div>
            <div className="ss-card-cta ss-card-cta-disabled">
              <span>Coming Soon</span>
              <span className="ss-card-cta-arrow" aria-hidden>·</span>
            </div>
          </div>
        </div>
      </div>

      <div className="ss-foot">
        <span>BUILT IN OSTTIROL</span>
        <span className="ss-foot-mid">— EST. MMXIX —</span>
        <span>POWERED BY MALZ</span>
      </div>
    </section>
  );
}

function Footer({ sparte }) {
  return (
    <footer className="ft">
      <div className="ft-top">
        <div className="ft-mark">
          <SparteLogo combined className="crest-medallion ft-crest-img" />
          <div>
            <div className="ft-1">LEISACH II</div>
            <div className="ft-2">SPORTCLUB · OSTTIROL</div>
          </div>
        </div>
        <div className="ft-cols">
          <div>
            <div className="ft-h">KONTAKT</div>
            <div>Sportplatz Leisach</div>
            <div>9909 Leisach, Osttirol</div>
            <div>servus@leisach2.at</div>
          </div>
          <div>
            <div className="ft-h">SOCIAL</div>
            <div>@leisach.zwei</div>
            <div>STRAVA · Leisach II</div>
            <div>WhatsApp Gruppe</div>
          </div>
          <div>
            <div className="ft-h">RECHTLICHES</div>
            <div>Impressum</div>
            <div>Vereinsstatut</div>
            <div>Bierordnung §1–§47</div>
          </div>
        </div>
      </div>
      <div className="ft-big">LEISACH<span>II</span></div>
      <div className="ft-bot">
        <span>© 2026 LEISACH II · ALLE FOULS VORBEHALTEN</span>
        <span>BUILT IN OSTTIROL · POWERED BY MALZ</span>
      </div>
    </footer>
  );
}

/* ───────────────────────── APP ───────────────────────── */

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "vibe": "editorial",
  "sparte": "fussball",
  "accent": "gold",
  "motion": true
}/*EDITMODE-END*/;

function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const sparte = tweaks.sparte;

  // Global trigger — any element with [data-trikot-trigger] führt direkt zur Radtrikot-Seite
  useEffect(() => {
    const onClick = (e) => {
      const trigger = e.target.closest("[data-trikot-trigger]");
      if (trigger) {
        e.preventDefault();
        window.location.href = "/trikot/";
      }
    };
    document.addEventListener("click", onClick);
    return () => document.removeEventListener("click", onClick);
  }, []);

  // accent color override
  useEffect(() => {
    const map = {
      gold: "#e9bf5e",
      hellblau: "#3e8edf",
      weiss: "#ffffff",
      red: "#e63946",
    };
    document.documentElement.style.setProperty("--accent", map[tweaks.accent] || "#e9bf5e");
    document.documentElement.dataset.vibe = tweaks.vibe;
    document.documentElement.dataset.motion = tweaks.motion ? "on" : "off";
  }, [tweaks.accent, tweaks.vibe, tweaks.motion]);

  const setSparte = (s) => setTweak("sparte", s);

  let Hero;
  if (tweaks.vibe === "broadcast") Hero = HeroBroadcast;
  else if (tweaks.vibe === "experimental") Hero = HeroExperimental;
  else Hero = HeroEditorial;

  return (
    <div className="app" data-screen-label="01 Leisach II Homepage">
      <Hero sparte={sparte} />
      <MediaSection />
      <SparteSelect sparte={sparte} setSparte={setSparte} />
      <Fixtures />
      <Gallery />
      <BreakingNews />
      <Footer sparte={sparte} />

      <TweaksPanel title="Tweaks">
        <TweakSection title="Vibe">
          <TweakRadio
            value={tweaks.vibe}
            onChange={(v) => setTweak("vibe", v)}
            options={[
              { value: "editorial", label: "Editorial" },
              { value: "broadcast", label: "Broadcast" },
              { value: "experimental", label: "Experimental" },
            ]}
          />
        </TweakSection>
        <TweakSection title="Sparte">
          <TweakRadio
            value={tweaks.sparte}
            onChange={(v) => setTweak("sparte", v)}
            options={[
              { value: "fussball", label: "Fußball" },
              { value: "racing", label: "Racing" },
            ]}
          />
        </TweakSection>
        <TweakSection title="Akzentfarbe">
          <TweakRadio
            value={tweaks.accent}
            onChange={(v) => setTweak("accent", v)}
            options={[
              { value: "gold", label: "Gold" },
              { value: "hellblau", label: "Hellblau" },
              { value: "weiss", label: "Weiß" },
              { value: "red", label: "Rot" },
            ]}
          />
        </TweakSection>
        <TweakSection title="Bewegung">
          <TweakToggle
            value={tweaks.motion}
            onChange={(v) => setTweak("motion", v)}
            label="Marquee / Scanlines / Float"
          />
        </TweakSection>
      </TweaksPanel>
    </div>
  );
}

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