// Sjednocený design — STREETWEAR-INSPIRED v romantické paletě
// Hero: editorial typo + pink countdown box (z varianty A)
// Karty: 9:16 streetwear-styl, 5 vedle sebe, tag v rohu, name+job pod kartou
// Discord live, Opat04 = pořadatel

const { useState, useEffect, useRef, useMemo } = React;

// ===== Storm lightning path generator (deterministic jagged polyline) =====
const lightningPath = (sx, sy, ex, ey, seed) => {
  const segs = 9;
  const rng = (n) => {
    const v = Math.sin((seed + 1) * 12.9898 + n * 78.233) * 43758.5453;
    return v - Math.floor(v);
  };
  let d = `M${sx},${sy}`;
  for (let i = 1; i < segs; i++) {
    const t = i / segs;
    const bx = sx + (ex - sx) * t;
    const by = sy + (ey - sy) * t;
    const ox = (rng(i * 3.1) - 0.5) * 56;
    const oy = (rng(i * 2.7 + 5) - 0.5) * 18;
    d += ` L${(bx + ox).toFixed(1)},${(by + oy).toFixed(1)}`;
  }
  return d + ` L${ex},${ey}`;
};

// ===== Scroll-driven parallax — víc-vrstvý depth feel na hero =====
// Body se hýbou různými rychlostmi → wow effect, pro-level
function useScrollParallax() {
  useEffect(() => {
    let raf = null;
    const apply = () => {
      const vh = window.innerHeight || 800;
      // Cap na 1× viewport — parallax aktivní jen když je hero v okně
      const y = Math.max(0, Math.min(window.scrollY, vh));
      const root = document.documentElement;
      root.style.setProperty("--py-video", `${y * 0.32}px`);
      root.style.setProperty("--py-display", `${y * -0.14}px`);
      root.style.setProperty("--py-opatova", `${y * 0.08}px`);
      root.style.setProperty("--py-stats", `${y * -0.06}px`);
      raf = null;
    };
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(apply);
    };
    window.addEventListener("scroll", onScroll, { passive: true });
    apply();
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
}

// ===== Scroll progress bar (fixed top, fills as you scroll the page) =====
function ScrollProgress() {
  const [progress, setProgress] = useState(0);
  useEffect(() => {
    const onScroll = () => {
      const h = document.documentElement;
      const max = h.scrollHeight - h.clientHeight;
      setProgress(max > 0 ? (h.scrollTop / max) * 100 : 0);
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);
  return <div className="ds-progress" style={{ "--p": `${progress}%` }} />;
}

// ===== Vertical corner stamp (editorial-poster style) =====
function CornerStamp() {
  return (
    <div className="ds-stamp" aria-hidden="true">
      <span className="ds-stamp-rule" />
      <div className="ds-stamp-text">
        <span>EST·2026</span>
        <span className="ds-stamp-dot">●</span>
        <span>SOBOTA·20:00</span>
        <span className="ds-stamp-dot">●</span>
        <span>DISCORD·LIVE</span>
      </div>
      <span className="ds-stamp-rule" />
    </div>
  );
}

// ===== Countdown helper =====
function useNextSaturday2000() {
  const [now, setNow] = useState(new Date());
  useEffect(() => {
    const t = setInterval(() => setNow(new Date()), 1000);
    return () => clearInterval(t);
  }, []);
  const target = useMemo(() => {
    const d = new Date(now);
    const day = d.getDay();
    let diff = (6 - day + 7) % 7;
    d.setHours(20, 0, 0, 0);
    if (diff === 0 && now.getHours() >= 20) diff = 7;
    d.setDate(d.getDate() + diff);
    return d;
  }, [now]);
  const ms = Math.max(0, target - now);
  const days = Math.floor(ms / 86400000);
  const hours = Math.floor(ms % 86400000 / 3600000);
  const mins = Math.floor(ms % 3600000 / 60000);
  const secs = Math.floor(ms % 60000 / 1000);

  // Brand world: time-aware status / label
  const day = now.getDay();
  const hour = now.getHours();
  const minute = now.getMinutes();
  const isSaturday = day === 6;
  const isLive = isSaturday && hour >= 20 && hour < 23; // Sobota 20:00-23:00 = LIVE
  const isStartingSoon = isSaturday && hour === 19 && minute >= 30; // 30 min před
  const isToday = isSaturday && hour < 20; // Je sobota, ale ještě před show
  const isTomorrow = day === 5 && hour >= 18; // Pátek večer
  let label = "Další epizoda za";
  let mood = "default";
  if (isLive) { label = "Právě teče LIVE"; mood = "live"; }
  else if (isStartingSoon) { label = "Začínáme za chvíli!"; mood = "soon"; }
  else if (isToday) { label = "Dnes večer LIVE za"; mood = "today"; }
  else if (isTomorrow) { label = "Zítra večer LIVE za"; mood = "tomorrow"; }

  return { days, hours, mins, secs, target, label, mood, isLive };
}

// ===== Silhouette placeholder =====
function Silhouette({ gender, seed = 0, idx = 0 }) {
  const isGirl = gender === "girl";
  const variants = [
  { hair: "long", neck: 28, hat: false },
  { hair: "bun", neck: 30, hat: false },
  { hair: "short", neck: 30, hat: false },
  { hair: "wavy", neck: 28, hat: true },
  { hair: "ponytail", neck: 30, hat: false }];

  const v = variants[(seed + idx) % variants.length];
  const palette = isGirl ?
  ["#ff8fc4", "#c026d3"] :
  ["#a78bfa", "#5b21b6"];
  const id = `${gender}-${seed}-${idx}`;

  return (
    <svg viewBox="0 0 200 280" preserveAspectRatio="xMidYMid slice" style={{ display: "block", width: "300px", height: "380px" }}>
      <defs>
        <linearGradient id={`bg-${id}`} x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor={palette[0]} />
          <stop offset="100%" stopColor={palette[1]} />
        </linearGradient>
        <radialGradient id={`spot-${id}`} cx="0.5" cy="0.25" r="0.6">
          <stop offset="0%" stopColor="rgba(255,255,255,0.35)" />
          <stop offset="100%" stopColor="rgba(255,255,255,0)" />
        </radialGradient>
      </defs>
      <rect width="200" height="280" fill={`url(#bg-${id})`} style={{ width: "300px", height: "324px" }} />
      <rect width="200" height="280" fill={`url(#spot-${id})`} style={{ width: "126px", height: "314px" }} />
      {/* tělo / ramena */}
      <path d={`M 10 280 Q 100 ${200 - (isGirl ? 10 : 0)} 190 280 Z`} fill="rgba(0,0,0,0.32)" />
      {/* krk */}
      <rect x={100 - v.neck / 2} y="180" width={v.neck} height="40" fill="rgba(0,0,0,0.25)" />
      {/* hlava */}
      <ellipse cx="100" cy="135" rx="42" ry="50" fill="rgba(0,0,0,0.32)" />
      {/* vlasy podle varianty */}
      {v.hair === "long" &&
      <path d="M 56 195 Q 100 75 144 195 L 152 220 Q 100 240 48 220 Z" fill="rgba(0,0,0,0.45)" />
      }
      {v.hair === "bun" &&
      <>
          <path d="M 60 100 Q 100 75 140 100 L 140 90 L 60 90 Z" fill="rgba(0,0,0,0.45)" />
          <circle cx="100" cy="78" r="14" fill="rgba(0,0,0,0.45)" />
        </>
      }
      {v.hair === "short" &&
      <path d="M 60 110 Q 100 75 140 110 L 140 95 L 60 95 Z" fill="rgba(0,0,0,0.45)" />
      }
      {v.hair === "wavy" &&
      <path d="M 56 180 Q 70 110 100 90 Q 130 110 144 180 L 144 100 L 56 100 Z" fill="rgba(0,0,0,0.45)" />
      }
      {v.hair === "ponytail" &&
      <>
          <path d="M 60 110 Q 100 78 140 110 L 140 95 L 60 95 Z" fill="rgba(0,0,0,0.45)" />
          <path d="M 138 100 Q 160 130 152 175 L 144 175 Q 142 130 130 110 Z" fill="rgba(0,0,0,0.45)" />
        </>
      }
      {v.hat &&
      <rect x="55" y="80" width="90" height="20" fill="rgba(0,0,0,0.5)" rx="4" />
      }
    </svg>);

}

// ===== Arcade Love Game — intro (game1.png) → match screen (game2.png) =====
function ArcadeGame({ matchedGirl, matchedBoy }) {
  const [phase, setPhase] = useState("intro");
  const triggered = useRef(false);
  const ref = useRef(null);

  useEffect(() => {
    if (!ref.current) return;
    const obs = new IntersectionObserver(([entry]) => {
      if (entry.isIntersecting && !triggered.current) {
        triggered.current = true;
        setTimeout(() => setPhase("match"), 2800);
      }
    }, { threshold: 0.35 });
    obs.observe(ref.current);
    return () => obs.disconnect();
  }, []);

  const skipIntro = () => {
    triggered.current = true;
    setPhase("match");
  };

  return (
    <div ref={ref} className="arc-game-wrap">
      {/* Intro frame — game1.png */}
      <div
        className={`arc-game-frame ${phase === "intro" ? "is-active" : "is-gone"}`}
        onClick={skipIntro}
      >
        <img src="game1.png" alt="Love Game intro" className="arc-game-img" />
        <div className="arc-game-press">START</div>
      </div>

      {/* Match frame — game2.png with overlay slots */}
      <div className={`arc-game-frame ${phase === "match" ? "is-active" : ""}`}>
        <img src="game2.png" alt="Love Match" className="arc-game-img" />
        <div className="arc-game-overlay">
          <div className={`arc-game-slot ${matchedGirl ? "filled" : ""}`}>
            <div className="arc-game-slot-tag">P1</div>
            {matchedGirl ?
              (matchedGirl.photo ?
                <img src={matchedGirl.photo} alt={matchedGirl.name} className="arc-game-slot-img" /> :
                <Silhouette gender="girl" seed={matchedGirl.id.charCodeAt(1)} idx={0} />
              ) :
              <div className="arc-game-empty">VYBER<br />HRÁČE</div>}
            <div className="arc-game-slot-name">{matchedGirl ? matchedGirl.name.toUpperCase() : "?????"}</div>
          </div>

          <div className="arc-game-vs">
            <PixelHeart filled={!!(matchedGirl && matchedBoy)} size={70} />
            <div className={`arc-game-status ${matchedGirl && matchedBoy ? "won" : ""}`}>
              {matchedGirl && matchedBoy ? "MATCH!" : "VS"}
            </div>
          </div>

          <div className={`arc-game-slot ${matchedBoy ? "filled" : ""}`}>
            <div className="arc-game-slot-tag">P2</div>
            {matchedBoy ?
              (matchedBoy.photo ?
                <img src={matchedBoy.photo} alt={matchedBoy.name} className="arc-game-slot-img" /> :
                <Silhouette gender="boy" seed={matchedBoy.id.charCodeAt(1)} idx={0} />
              ) :
              <div className="arc-game-empty">VYBER<br />HRÁČE</div>}
            <div className="arc-game-slot-name">{matchedBoy ? matchedBoy.name.toUpperCase() : "?????"}</div>
          </div>
        </div>
      </div>
    </div>
  );
}

// ===== Pixel Heart (8-bit arcade style) =====
function PixelHeart({ filled = true, size = 110 }) {
  const pattern = [
    [0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0],
    [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
    [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
    [0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0],
    [0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0],
    [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
  ];
  const cols = pattern[0].length;
  const rows = pattern.length;
  const cell = Math.max(4, Math.floor(size / cols));
  const w = cell * cols;
  const h = cell * rows;
  const fill = filled ? "var(--pink)" : "rgba(255,77,143,0.25)";
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}
      style={{ filter: filled ? "drop-shadow(0 0 14px var(--pink)) drop-shadow(0 0 30px rgba(255,77,143,0.6))" : "none", display: "block" }}>
      {pattern.map((row, y) => row.map((p, x) =>
        p ? <rect key={`${x}-${y}`} x={x * cell} y={y * cell} width={cell} height={cell} fill={fill} /> : null
      ))}
    </svg>);
}

// ===== Heart =====
function Heart({ filled, size = 18, color = "currentColor" }) {
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill={filled ? color : "none"} stroke={color} strokeWidth="2.2" aria-hidden="true" style={{ display: "inline-block", verticalAlign: "middle" }}>
      <path d="M12 21s-7.5-4.6-9.5-9.4C1 7.5 4 4 7.5 4c2 0 3.4 1 4.5 2.6C13.1 5 14.5 4 16.5 4 20 4 23 7.5 21.5 11.6 19.5 16.4 12 21 12 21z" strokeLinejoin="round" />
    </svg>);
}

// ===== Sparkle (4-point star, designerská hvězdička) =====
function Sparkle({ size = 14, color = "currentColor" }) {
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill={color} aria-hidden="true" style={{ display: "inline-block", verticalAlign: "middle" }}>
      <path d="M12 1 C12 8 12 8 23 12 C12 16 12 16 12 23 C12 16 12 16 1 12 C12 8 12 8 12 1 Z" />
    </svg>);
}

// ===== ArrowRight =====
function ArrowRight({ size = 16, color = "currentColor", strokeWidth = 2 }) {
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" style={{ display: "inline-block", verticalAlign: "middle" }}>
      <path d="M5 12h14M13 6l6 6-6 6" />
    </svg>);
}

// ===== ArrowUpRight (pro archive) =====
function ArrowUpRight({ size = 18, color = "currentColor", strokeWidth = 2 }) {
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke={color} strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" style={{ display: "inline-block", verticalAlign: "middle" }}>
      <path d="M7 17L17 7M9 7h8v8" />
    </svg>);
}

// ===== Play (triangle pro live indikátory) =====
function PlayTriangle({ size = 14, color = "currentColor" }) {
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill={color} aria-hidden="true" style={{ display: "inline-block", verticalAlign: "middle" }}>
      <path d="M7 4 L20 12 L7 20 Z" />
    </svg>);
}

// ===== ShowIcon (klapka — pro "Nx v show" badge) =====
function ShowIcon({ size = 12, color = "currentColor" }) {
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" style={{ display: "inline-block", verticalAlign: "middle" }}>
      <path d="M3.41 9 7 3.59 9.41 9" />
      <path d="m9.41 9 3-5.41 2.41 5.41" />
      <path d="m15 9 2.59-4.41L20.41 9" />
      <rect x="3" y="9" width="18" height="12" rx="1" />
    </svg>);
}

// ===== Instagram icon =====
function IGIcon({ size = 14, color = "currentColor" }) {
  return (
    <svg viewBox="0 0 24 24" width={size} height={size} fill="none" stroke={color} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" style={{ display: "inline-block", verticalAlign: "middle" }}>
      <rect x="3" y="3" width="18" height="18" rx="5" ry="5" />
      <path d="M16 11.4A4 4 0 1 1 12.6 8 4 4 0 0 1 16 11.4z" />
      <line x1="17.5" y1="6.5" x2="17.5" y2="6.5" strokeWidth="2.5" />
    </svg>);
}

// ===== Best Energy card — info + IG na přední straně, flip = druhá fotka =====
function BestEnergyCard({ p, rank, voted, count, onVote }) {
  const [flipped, setFlipped] = useState(false);
  // count = aktuální DB counter (po toggle override). Když není dodán, fallback na p.votes
  // (voter's vote už je v DB count zahrnut, takže žádné +1 nepotřebujeme)
  const totalVotes = count != null ? count : (p.votes || 0);
  const igHandle = p.ig ? (p.ig.startsWith("@") ? p.ig : `@${p.ig}`) : null;
  const igUrl = igHandle ? `https://instagram.com/${igHandle.replace("@", "")}` : null;
  // Fallback IG (každá karta má decentní IG odkaz — bez handle vede na show)
  const fallbackIgUrl = "https://instagram.com/opat04x";
  const cardIgUrl = igUrl || fallbackIgUrl;
  const igTitle = igHandle ? `Instagram ${igHandle}` : "Instagram show";

  return (
    <div className="pc-wrap be-wrap">
      <div
        className={`pc-card be-card ${flipped ? "flipped" : ""} ${p.gender}`}
        onClick={(e) => {
          // Když uživatel klikne na link/button uvnitř, neflipovat (IG, vote)
          if (e.target.closest && e.target.closest('button, a')) return;
          setFlipped(f => !f);
        }}
        role="button"
        tabIndex={0}
        onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setFlipped(f => !f); } }}>

        {/* FRONT — fotka + bohatý overlay (jméno, IG, info) */}
        <div className="pc-face pc-front pc-front-full">
          <div className="pc-photo pc-photo-full">
            {p.photo ?
              <img src={p.photo} alt={p.name} className="pc-photo-img" loading="lazy" decoding="async" style={p.photo_position ? { objectPosition: p.photo_position } : undefined} /> :
              <Silhouette gender={p.gender} seed={p.id.charCodeAt(p.id.length - 1)} idx={(rank || 0) % 5} />
            }
            <span className="be-rank-pill">#{rank}</span>
            <span className="be-votes-pill">
              <Heart filled size={11} color="#fff" />
              <span>{totalVotes}</span>
            </span>
            {p.appearances > 1 && (
              <span className="be-appearances-pill" title={`${p.appearances}× v show`}>
                <em>{p.appearances}</em>×
              </span>
            )}

            {/* Decentní IG ikona — každá karta. Když má p.ig, vede tam, jinak na show. */}
            <a className={`be-ig-icon ${igHandle ? "has-handle" : ""}`}
              href={cardIgUrl}
              target="_blank"
              rel="noreferrer noopener"
              onClick={(e) => e.stopPropagation()}
              title={igTitle}
              aria-label={igTitle}>
              <IGIcon size={14} />
            </a>

            <div className={`be-front-overlay ${p.info ? "has-info" : ""}`}>
              <div className="be-front-name-row">
                <h3 className="be-front-name">{p.name}{p.winner && <span className="be-winner-mark" title="Vítěz epizody">★</span>}</h3>
                {p.age && <span className="be-front-age">{p.age}</span>}
              </div>
              {/* IG handle se zobrazuje jen jako ikona vpravo dole (be-ig-icon) — ne jako text v popisu */}
              {p.info && (
                <ul className="be-front-bullets">
                  {p.info.slice(0, 4).map((line, i) => <li key={i}>{line}</li>)}
                </ul>
              )}
            </div>
          </div>
        </div>

        {/* BACK — druhá fotka (typicky z IG), nebo fallback vote-box */}
        {p.photo2 ?
          <div className="pc-face pc-back be-back-photo">
            <div className="pc-photo pc-photo-full">
              <img src={p.photo2} alt={`${p.name} — IG`} className="pc-photo-img" loading="lazy" decoding="async" />
              <div className="be-back-photo-overlay">
                <div className="be-back-photo-meta">
                  <span className="be-back-photo-tag">EP {String(p.episode).padStart(2, "0")} · {p.appearances || 1}×</span>
                  <h3 className="be-back-photo-name">{p.name}{p.age && <span> · {p.age}</span>}</h3>
                  {igHandle &&
                    <a className="be-back-photo-ig"
                      href={igUrl}
                      target="_blank"
                      rel="noreferrer noopener"
                      onClick={(e) => e.stopPropagation()}>
                      <IGIcon size={13} />
                      <span>{igHandle}</span>
                    </a>
                  }
                </div>
                <button
                  type="button"
                  className={`be-back-vote-btn ${voted ? "voted" : ""}`}
                  onClick={(e) => { e.preventDefault(); e.stopPropagation(); onVote(p.id); }}>
                  <Heart filled={voted} size={14} />
                  <span>{voted ? "Zrušit hlas" : `Hlasovat · ${totalVotes}`}</span>
                </button>
              </div>
            </div>
          </div> :
          <div className="pc-face pc-back be-back">
            <div className="be-back-tag">ENERGY ↘</div>
            <h3 className="be-back-name">{p.name}{p.age && <span> · {p.age}</span>}</h3>
            <div className="be-back-meta">EP {String(p.episode).padStart(2, "0")} · {p.appearances || 1}×</div>
            <div className="be-back-vote-stat">
              <em>{totalVotes}</em>
              <span>HLASŮ</span>
            </div>
            <button
              type="button"
              className={`be-back-vote-btn ${voted ? "voted" : ""}`}
              onClick={(e) => { e.preventDefault(); e.stopPropagation(); onVote(p.id); }}>
              <Heart filled={voted} size={14} />
              <span>{voted ? "Zrušit hlas" : "Hlasovat"}</span>
            </button>
            <p className="be-back-note">Klikni pro hlasování</p>
          </div>
        }
      </div>
    </div>);
}

// ===== Profile-card style (Sophie Bennett inspired) =====
function PersonCard({ p, gender, idx, votes, count, onVote, onSelectMatch, matched, className = "", style }) {
  const [flipped, setFlipped] = useState(false);

  // === TBD slot — nevybraný účastník (otazník + silueta, žádný flip) ===
  if (p.tbd) {
    return (
      <div className={`pc-wrap pc-wrap-tbd ${className}`.trim()} style={style}>
        <div className={`pc-card pc-card-tbd ${gender}`}>
          <div className="pc-photo pc-photo-full">
            <Silhouette gender={gender} seed={idx * 7 + 13} idx={idx} />
            <div className="pc-tbd-overlay">
              <span className="pc-tbd-mark">?</span>
              <span className="pc-tbd-label">Nevybráno</span>
            </div>
          </div>
        </div>
      </div>);
  }

  const posts = 12 + p.id.charCodeAt(1) * 7 % 80;
  const isLiked = votes.includes(p.id);
  // Real DB vote count (count override po toggle, jinak p.votes)
  const likeCount = count != null ? count : (p.votes || 0);
  return (
    <div className={`pc-wrap ${className}`.trim()} style={style}>
      <div
        className={`pc-card ${flipped ? "flipped" : ""} ${gender} ${p.unconfirmed ? "is-unconfirmed" : ""}`}
        onClick={(e) => {
          // Pokud uživatel klikl na button/link uvnitř, neflipovat (vote/IG)
          if (e.target.closest && e.target.closest('button, a')) return;
          setFlipped(f => !f);
        }}
        role="button"
        tabIndex={0}
        onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setFlipped(f => !f); } }}>
        {/* Always-visible overlay (above flipping faces) — like button + appearances/NEW badge */}
        <button
          type="button"
          className={`pc-overlay-like ${isLiked ? "is-liked" : ""}`}
          onClick={(e) => { e.preventDefault(); e.stopPropagation(); onVote(p.id); }}
          onMouseDown={(e) => e.stopPropagation()}
          aria-label={isLiked ? "Odlajknout" : "Lajknout"}
          title="Lajknout">
          <Heart filled={isLiked} size={16} />
          <span className="pc-overlay-like-count">{likeCount}</span>
        </button>

        {(() => {
          if (p.unconfirmed) {
            return <span className="pc-overlay-badge pc-overlay-unconfirmed" title="Účast ještě nepotvrzená">NEPOTVRZENO</span>;
          }
          // Jen "NEW" badge pro první-časáky, žádný appearances counter
          if ((p.appearances || 1) === 1) {
            return <span className="pc-overlay-badge pc-overlay-tier pc-tier-new" title="Nový/Nová účinkující — první díl">NEW</span>;
          }
          return null;
        })()}

        <div className="pc-face pc-front pc-front-full">
          <div className="pc-photo pc-photo-full">
            {p.photo ?
              <img src={p.photo} alt={p.name} className="pc-photo-img" loading="lazy" decoding="async" style={p.photo_position ? { objectPosition: p.photo_position } : undefined} /> :
              <Silhouette gender={gender} seed={p.id.charCodeAt(1)} idx={idx} />
            }
            <div className="pc-photo-overlay">
              <h3 className="pc-name-overlay">{p.name}</h3>
              <span className="pc-age-overlay">{p.age}</span>
            </div>
          </div>
        </div>
        <div className="pc-face pc-back">
          <div className="pc-back-name">{p.name} <span>· {p.age}</span></div>
          <div className="pc-back-job">{p.job} · {p.height} cm · {p.appearances || 1}×</div>
          <p className="pc-back-bio">{p.bio}</p>
          <div className="pc-back-block">
            <div className="pc-back-label">FUN FACT</div>
            <p>{p.fact}</p>
          </div>
          <div className="pc-back-foot">
            <button
              type="button"
              className={`pc-vote-btn ${votes.includes(p.id) ? "active" : ""}`}
              onMouseDown={(e) => e.stopPropagation()}
              onClick={(e) => { e.preventDefault(); e.stopPropagation(); onVote(p.id); }}
              title="Hlasovat pro favorita">
              <Heart filled={votes.includes(p.id)} size={18} />
              <span className="pc-vote-count">{likeCount}</span>
              <span className="pc-vote-label">{votes.includes(p.id) ? "Hlasováno" : "Hlasovat"}</span>
            </button>
            <span className="pc-back-ig-mini">{p.ig}</span>
          </div>
        </div>
      </div>
    </div>);
}

// ===== Main =====
// ===== ApplyForm — přihláška do show s upload foto/video =====
function ApplyForm() {
  const [name, setName] = useState("");
  const [age, setAge] = useState("");
  const [instagram, setInstagram] = useState("");
  const [discord, setDiscord] = useState("");
  const [bio, setBio] = useState("");
  const [file, setFile] = useState(null);
  const [externalUrl, setExternalUrl] = useState("");
  const [submitting, setSubmitting] = useState(false);
  const [done, setDone] = useState(false);
  const [error, setError] = useState("");

  // Max velikost: 50 MB pro video, 10 MB pro foto (rozhoduje se podle file.type)
  const MAX_VIDEO = 50 * 1024 * 1024;
  const MAX_PHOTO = 10 * 1024 * 1024;

  function pickFile(e) {
    const f = e.target.files && e.target.files[0];
    if (!f) { setFile(null); return; }
    const isVideo = (f.type || "").startsWith("video/");
    const limit = isVideo ? MAX_VIDEO : MAX_PHOTO;
    if (f.size > limit) {
      setError(`Soubor je moc velký (max ${isVideo ? "50 MB pro video" : "10 MB pro foto"}). Nahraj menší nebo dej odkaz na Drive/Discord.`);
      return;
    }
    setError("");
    setFile(f);
  }

  async function submit(e) {
    e.preventDefault();
    if (submitting) return;
    if (!name.trim()) { setError("Vyplň prosím jméno."); return; }
    if (!window.dsAPI || !window.dsAPI.submitApplication) {
      setError("Připojení k databázi selhalo. Zkuste obnovit stránku.");
      return;
    }
    setSubmitting(true); setError("");
    try {
      await window.dsAPI.submitApplication({ name, age, instagram, discord, bio, file, externalUrl });
      setDone(true);
    } catch (err) {
      setError("Nepodařilo se odeslat: " + (err.message || String(err)));
    } finally {
      setSubmitting(false);
    }
  }

  if (done) {
    return (
      <div className="ds-apply-success">
        <div className="ds-apply-success-heart"><Heart filled size={56} color="var(--pink)" /></div>
        <h3>Hotovo, díky!</h3>
        <p>Tvoji přihlášku jsme přijali. Pokud se hodíš do nadcházejícího dílu, ozveme se.</p>
      </div>
    );
  }

  const fileLabel = file
    ? `✓ ${file.name} (${(file.size / 1024 / 1024).toFixed(1)} MB)`
    : "Vybrat foto / video";

  return (
    <form className="ds-apply-form" onSubmit={submit}>
      <label>Jméno *<input type="text" placeholder="Tereza N." value={name} onChange={(e) => setName(e.target.value)} maxLength={200} required /></label>
      <label>Věk<input type="number" placeholder="23" min={16} max={99} value={age} onChange={(e) => setAge(e.target.value)} /></label>
      <label>Instagram<input type="text" placeholder="@tvoje.handle" value={instagram} onChange={(e) => setInstagram(e.target.value)} maxLength={100} /></label>
      <label>Discord handle<input type="text" placeholder="username#0000" value={discord} onChange={(e) => setDiscord(e.target.value)} maxLength={100} /></label>
      <label>Pár vět o tobě<textarea placeholder="Co tě baví, co hledáš…" value={bio} onChange={(e) => setBio(e.target.value)} maxLength={2000} rows={3} /></label>

      <div className="ds-apply-media">
        <label className="ds-apply-file">
          <input type="file" accept="image/*,video/*" onChange={pickFile} style={{ display: "none" }} />
          <span className={file ? "is-loaded" : ""}>{fileLabel}</span>
          <em>📷 / 🎬</em>
        </label>
        <div className="ds-apply-or">— nebo —</div>
        <label>Odkaz na video/fotku (Drive, Disk, Discord, …)
          <input type="url" placeholder="https://drive.google.com/..." value={externalUrl} onChange={(e) => setExternalUrl(e.target.value)} maxLength={500} />
        </label>
      </div>

      {error && <div className="ds-apply-error">{error}</div>}

      <button type="submit" className="ds-apply-btn" disabled={submitting}>
        <span>{submitting ? "Odesílám…" : "PŘIHLÁSIT SE"}</span>
        <Heart filled size={16} color="#fff" />
      </button>
      <p className="ds-apply-disclaimer">
        Odesláním souhlasíš se zpracováním údajů jen pro účely výběru účinkujících. Žádný spam.
      </p>
    </form>
  );
}

function VariantMain({ tweaks }) {
  const D = window.DATESHOW_DATA;
  const { days, hours, mins, secs, label: countdownLabel, mood: countdownMood, isLive } = useNextSaturday2000();

  // ── Voting (DB-backed) ─────────────────────────────────────────
  // myVotes = pole IDs účastníků pro které tento voter hlasoval (1 hlas / device / účastník)
  // voteCountOverride = server-vrácené nové countery po toggle (override pro p.votes)
  const [myVotes, setMyVotes] = useState([]);
  const [voteCountOverride, setVoteCountOverride] = useState({});
  const [votingId, setVotingId] = useState(null); // ID právě odbavovaného kliknutí (loading state)

  // Načti existující hlasy tohoto voter_id (z localStorage UUID) při mountu
  useEffect(() => {
    if (window.dsAPI && window.dsAPI.loadMyVotes) {
      window.dsAPI.loadMyVotes()
        .then(set => setMyVotes([...set]))
        .catch(err => console.warn("[ds] loadMyVotes failed:", err));
    }
  }, []);

  const toggleVote = async (id) => {
    if (votingId) return; // prevent double-click race condition
    if (!window.dsAPI || !window.dsAPI.toggleVote) {
      // Fallback (lokální only) — kdyby Supabase nedoběhl
      setMyVotes(v => v.includes(id) ? v.filter(x => x !== id) : [...v, id]);
      return;
    }
    // Ulož scroll pozici — pokud se po re-renderu změní, vrátíme uživatele zpátky
    const savedScrollY = window.scrollY;

    setVotingId(id);
    // Optimistic update
    const wasVoted = myVotes.includes(id);
    const optimistic = wasVoted ? myVotes.filter(x => x !== id) : [...myVotes, id];
    setMyVotes(optimistic);
    try {
      const { newCount } = await window.dsAPI.toggleVote(id);
      setVoteCountOverride(c => ({ ...c, [id]: newCount }));
      // Po re-renderu (2× rAF = po next paint) zkontroluj zda nedošlo ke skoku
      requestAnimationFrame(() => requestAnimationFrame(() => {
        if (Math.abs(window.scrollY - savedScrollY) > 8) {
          window.scrollTo({ top: savedScrollY, behavior: "instant" });
        }
      }));
    } catch (err) {
      console.warn("[ds] vote failed, rolling back:", err);
      setMyVotes(myVotes); // rollback
      alert("Hlasování selhalo: " + (err && err.message ? err.message : String(err)));
    } finally {
      setVotingId(null);
    }
  };

  // Aktuální counter pro účastníka (override po hlasování přebije p.votes)
  const adjustedVotes = (p) => {
    const c = voteCountOverride[p.id];
    return c != null ? c : (p.votes || 0);
  };

  const [match, setMatch] = useState({ girl: null, boy: null });
  const selectMatch = (id, gender) => setMatch((m) => ({ ...m, [gender]: m[gender] === id ? null : id }));

  const matchedGirl = D.girls.find((g) => g.id === match.girl);
  const matchedBoy = D.boys.find((b) => b.id === match.boy);

  const palette = tweaks.palette || "mix";
  const dark = tweaks.dark !== false;
  const [navOpen, setNavOpen] = useState(false);
  useEffect(() => {
    document.body.classList.toggle("ds-nav-locked", navOpen);
    return () => document.body.classList.remove("ds-nav-locked");
  }, [navOpen]);

  // Legacy aliasy aby nemusela být upravená každá child komponenta
  const votes = myVotes;
  const bestVotes = myVotes.reduce((acc, id) => { acc[id] = true; return acc; }, {});
  const toggleBestVote = toggleVote;

  // Tab routing přes URL hash — #best-energy / main
  const TABS = ["best-energy"];
  const hashToTab = (h) => TABS.includes((h || "").replace("#", "")) ? h.replace("#", "") : "main";
  const [activeTab, setActiveTab] = useState(() =>
    typeof window !== "undefined" ? hashToTab(window.location.hash) : "main"
  );
  const goHome = (e) => {
    if (e) e.preventDefault();
    if (window.location.hash) {
      history.replaceState(null, "", window.location.pathname + window.location.search);
    }
    setActiveTab("main");
    setNavOpen(false);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };
  useEffect(() => {
    const onHash = () => {
      const hash = window.location.hash;
      const tab = hashToTab(hash);
      if (tab !== "main") {
        setActiveTab(tab);
        window.scrollTo({ top: 0, behavior: "instant" });
      } else {
        setActiveTab("main");
        requestAnimationFrame(() => {
          if (hash && hash !== "#") {
            const el = document.querySelector(hash);
            if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
          }
        });
      }
    };
    window.addEventListener("hashchange", onHash);
    return () => window.removeEventListener("hashchange", onHash);
  }, []);

  // useScrollParallax(); — DISABLED: video parallax způsoboval scroll lag.

  // Scroll progress 0→1 přes první viewport (pro fading top banneru)
  useEffect(() => {
    const onScroll = () => {
      const trigger = window.innerHeight * 0.6;
      const progress = Math.min(1, Math.max(0, window.scrollY / trigger));
      document.documentElement.style.setProperty("--scroll-progress", progress.toFixed(3));
    };
    onScroll();
    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, []);

  return (
    <div className={`ds-app palette-${palette} ${dark ? "theme-dark" : "theme-light"}`} data-tab={activeTab}>
      <ScrollProgress />
      {/* TOP BAR — editorial styl */}
      <header className="ds-top">
        <div className="ds-top-left">
          <a href="#" className="ds-mast" onClick={goHome} aria-label="Domů">DATESHOW</a>
        </div>
        <nav className={`ds-nav ${navOpen ? "open" : ""}`}>
          <a href="#" onClick={goHome} className={activeTab === "main" ? "is-active" : ""}>Domů</a>
          <a href="#cast" onClick={() => setNavOpen(false)}>Účastníci</a>
          <a href="#best-energy" onClick={() => setNavOpen(false)} className={`ds-nav-best ${activeTab === "best-energy" ? "is-active" : ""}`}>Best Energy</a>
          <a href="#archive" onClick={() => setNavOpen(false)}>Archiv</a>
          <a href="#apply" onClick={() => setNavOpen(false)}>Přihláška</a>
        </nav>
        <button
          className="ds-burger"
          aria-label="Menu"
          aria-expanded={navOpen}
          onClick={() => setNavOpen((o) => !o)}
        >
          <span /><span /><span />
        </button>
      </header>

      {/* HERO */}
      <section className="ds-hero">
        {/* Dual video crossfade — eliminuje flicker při loopu.
            Oba videos hrají kontinuálně s offsetem (B je v půlce, když A startuje).
            Když jeden je blízko konce/seamu, fadne se na druhý (který je v middle). */}
        <video
          className="ds-hero-video ds-hero-video-a"
          src="interletlove-web.mp4"
          autoPlay muted loop playsInline preload="auto"
          ref={(el) => {
            if (!el || el.dataset.dualFix === "1") return;
            el.dataset.dualFix = "1";
            const FADE_WINDOW = 0.6;
            // Reveal AS SOON AS video can play — nečekáme na preloader timer.
            // Když je video ready dřív než preloader zmizí, fade-in proběhne POD
            // preloaderem a uživatel hned uvidí video v moment kdy preloader zmizí.
            // Pokud video nestihlo (slow net), preloader se schová a video se odhalí
            // jakmile dostatečně buffuje.
            const reveal = () => el.classList.add("is-revealed");
            if (el.readyState >= 3) {
              reveal();
            } else {
              el.addEventListener("canplay", reveal, { once: true });
              el.addEventListener("loadeddata", reveal, { once: true });
              setTimeout(reveal, 10000); // absolute safety fallback (10s)
            }
            // Dual crossfade jen na desktopu — na mobile dvě videa = 2× CPU pro decoder.
            // Mobile dostane single video s mírným seam flickerem (přijatelný kompromis).
            const isMobile = window.matchMedia && window.matchMedia('(max-width: 700px)').matches;
            if (!isMobile) {
              el.addEventListener("loadedmetadata", () => {
                const b = document.querySelector(".ds-hero-video-b");
                if (!b) return;
                const start = () => {
                  b.currentTime = el.duration / 2;
                  b.play().catch(() => {});
                };
                if (b.readyState >= 1) start();
                else b.addEventListener("loadedmetadata", start, { once: true });
              });
              el.addEventListener("timeupdate", () => {
                const b = document.querySelector(".ds-hero-video-b");
                if (!b || !el.duration) return;
                const aRemaining = el.duration - el.currentTime;
                if (aRemaining < FADE_WINDOW || el.currentTime < FADE_WINDOW) {
                  el.style.opacity = "0";
                  b.style.opacity = "1";
                }
              });
            }
          }}
        />
        <video
          className="ds-hero-video ds-hero-video-b"
          src="interletlove-web.mp4"
          muted loop playsInline preload="metadata"
          ref={(el) => {
            if (!el || el.dataset.dualFix === "1") return;
            el.dataset.dualFix = "1";
            const FADE_WINDOW = 0.6;
            el.addEventListener("timeupdate", () => {
              const a = document.querySelector(".ds-hero-video-a");
              if (!a || !el.duration) return;
              const bRemaining = el.duration - el.currentTime;
              if (bRemaining < FADE_WINDOW || el.currentTime < FADE_WINDOW) {
                el.style.opacity = "0";
                a.style.opacity = "1";
              }
            });
          }}
        />
        <div className="ds-hero-tint" />
        <div className="ds-hero-grid">
          <div className="ds-hero-left">
            <Reveal as="div" className="ds-hero-opatova" delay={0} y={0} aria-label="Opatova">
              <span className="opa-l opa-l-1">O</span>
              <span className="opa-l opa-l-2">P</span>
              <span className="opa-l opa-l-3">A</span>
              <span className="opa-l opa-l-4">T</span>
              <span className="opa-l opa-l-5">O</span>
              <span className="opa-l opa-l-6">V</span>
              <span className="opa-l opa-l-7">A</span>
            </Reveal>
            <h1 className="ds-display">
              <BlurText text="DATE" stagger={140} />
              <br />
              <BlurText text="SHOW" stagger={140} delay={300} />
              <Reveal as="span" delay={900} y={0} className="ds-hero-live-wrap">
                <img src="live.png" alt="LIVE" className="ds-hero-live-sticker" />
              </Reveal>
            </h1>
            <Reveal delay={750} y={16}>
              <p className="ds-hero-tagline">Největší online dating show ve <strong>střední Evropě</strong>.<br />Živě každou sobotu na <strong>Discordu</strong>.</p>
            </Reveal>
            <Reveal delay={900} y={16}>
              <div className="ds-hero-cta">
                <a className="ds-btn-primary" href="#apply">
                  <span>PŘIHLÁSIT SE</span>
                  <Heart filled size={15} />
                </a>
              </div>
            </Reveal>
          </div>

          <Reveal className="ds-hero-right" delay={1100} y={30}>
            <div className={`ds-cd-card ds-cd-mood-${countdownMood} ${isLive ? "is-live" : ""}`}>
              <div className="ds-cd-label">{countdownLabel}</div>
              <div className="ds-cd-grid">
                <div className="ds-cd-cell"><div className="ds-cd-num">{String(days).padStart(2, "0")}</div><div className="ds-cd-unit">DNŮ</div></div>
                <div className="ds-cd-cell"><div className="ds-cd-num">{String(hours).padStart(2, "0")}</div><div className="ds-cd-unit">HOD</div></div>
                <div className="ds-cd-cell"><div className="ds-cd-num">{String(mins).padStart(2, "0")}</div><div className="ds-cd-unit">MIN</div></div>
                <div className="ds-cd-cell"><div className="ds-cd-num">{String(secs).padStart(2, "0")}</div><div className="ds-cd-unit">SEC</div></div>
              </div>
              <div className="ds-cd-foot">
                <a className="ds-discord-btn" href="#archive">
                  <span>Předchozí epizody</span>
                  <ArrowRight size={12} />
                </a>
              </div>
            </div>
          </Reveal>
        </div>

        <div className="ds-strip">
          <div className="ds-strip-track">
            {Array.from({ length: 4 }).map((_, k) => <React.Fragment key={k}>
                <span>#1 LIVE DATE SHOW NA CZ/SK</span>
                <span className="ds-strip-icon"><Heart filled size={14} /></span>
                <span>200K+ VIEWS</span>
                <span className="ds-strip-icon"><Sparkle size={12} /></span>
                <span>DISCORD LIVE</span>
                <span className="ds-strip-icon"><Heart filled size={14} /></span>
                <span>SOBOTA 20:00</span>
                <span className="ds-strip-icon"><Sparkle size={12} /></span>
                <span>18+</span>
                <span className="ds-strip-icon"><Heart filled size={14} /></span>
                <span>BIZAR</span>
                <span className="ds-strip-icon"><Sparkle size={12} /></span>
                <span>ÚSPĚŠNOST 67%</span>
                <span className="ds-strip-icon"><Heart filled size={14} /></span>
                <span>10+ EPIZOD</span>
                <span className="ds-strip-icon"><Sparkle size={12} /></span>
                <span>BEZ CENZURY</span>
                <span className="ds-strip-icon"><Heart filled size={14} /></span>
                <span>NEZMEŠKEJ</span>
                <span className="ds-strip-icon"><Sparkle size={12} /></span>
              </React.Fragment>
            )}
          </div>
        </div>

        {/* Stoupající srdíčka — emise z bottom edge hero, rise + fade upward */}
        <div className="ds-hearts-rising" aria-hidden="true">
          {Array.from({ length: 14 }).map((_, i) => (
            <svg key={i} className={`ds-heart-rise ds-heart-rise-${i + 1}`} viewBox="0 0 24 24" fill="currentColor">
              <path d="M12 21s-7.5-4.6-9.5-9.4C1 7.5 4 4 7.5 4c2 0 3.4 1 4.5 2.6C13.1 5 14.5 4 16.5 4 20 4 23 7.5 21.5 11.6 19.5 16.4 12 21 12 21z" />
            </svg>
          ))}
        </div>

        {/* Floating scroll indicator — premium glass button, jump na cast */}
        <a className="ds-hero-scroll-indicator" href="#cast" aria-label="Scroll to cast" onClick={(e) => {
          e.preventDefault();
          const t = document.getElementById("cast");
          if (t) t.scrollIntoView({ behavior: "smooth", block: "start" });
        }}>
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round" width="32" height="32">
            <polyline points="6 9 12 15 18 9" />
          </svg>
        </a>
      </section>

      {/* PROČ DATESHOW? */}
      <Reveal as="section" className="ds-why" y={30}>
        <div className="ds-why-head">
          <h2 className="ds-h2 ds-why-title">PROČ <em>DATESHOW?</em></h2>
        </div>

        <div className="ds-why-grid">
          <RevealSlide className="ds-why-item" delay={100} dir="up" distance={80} rotate={-3}>
            <span className="ds-why-num">01</span>
            <h3 className="ds-why-q">Seznámit se naživo už <em>neumíme</em>.</h3>
            <p className="ds-why-p">Po covidu je IRL seznámení těžší než kdy dřív. Na ulici se k nikomu nepřipojíš, v baru každý kouká do telefonu. Skutečná setkání jsou vzácnost.</p>
          </RevealSlide>

          <RevealSlide className="ds-why-item" delay={280} dir="up" distance={100} rotate={2}>
            <span className="ds-why-num">02</span>
            <h3 className="ds-why-q">Internet je plný <em>falešných</em> tváří.</h3>
            <p className="ds-why-p">AI generované profily, upravené fotky, scammeři. Ten, kdo s tebou píše, nemusí být ten, koho ukazuje obrazovka.</p>
          </RevealSlide>

          <RevealSlide className="ds-why-item" delay={460} dir="up" distance={120} rotate={-2}>
            <span className="ds-why-num">03</span>
            <h3 className="ds-why-q">Píšou jí <em>desítky</em> kluků!</h3>
            <p className="ds-why-p">Žádná holka nedostává 2-3 zprávy. Denně jí chodí <strong>30+</strong> šablonových DM, kopírovaných hlášek, slizkých flirtů. Pokud nejsi výjimečný, ztratíš se ve frontě. Tady ji vidíš naživo, bez algoritmu, bez konkurence.</p>
          </RevealSlide>
        </div>

        <RevealSlide className="ds-why-solution" delay={300} dir="left" distance={140}>
          {/* Subtle floating hearts (jen 5, jemnější) */}
          <div className="ds-why-hearts" aria-hidden="true">
            {Array.from({ length: 5 }).map((_, i) => {
              const left = (i * 19 + 10) % 100;
              const delay = i * 1.6;
              const dur = 9 + (i % 2) * 2;
              return (
                <span
                  key={i}
                  className="ds-why-heart"
                  style={{
                    left: `${left}%`,
                    animationDelay: `${delay}s`,
                    animationDuration: `${dur}s`
                  }}
                >
                  <Heart filled size={10 + (i % 2) * 4} />
                </span>
              );
            })}
          </div>

          <div className="ds-why-arrow" aria-hidden="true">↓</div>
          <p className="ds-why-callout">
            <span className="ds-why-callout-pre">A přesně tohle řeší</span>
            <strong>Opatova DateShow.</strong>
          </p>
          <p className="ds-why-supporting">
            <strong>Skuteční lidé. Živá kamera. Lehký scénář, jinak freestyle.</strong>
            <br />
            A nejlepší na tom je, že to <strong>opravdu funguje</strong>. Dali jsme dohromady už <strong>desítky reálných párů</strong>.
          </p>
        </RevealSlide>
      </Reveal>

      {/* HOST */}
      <section className="ds-team">
        <Reveal as="div" className="ds-team-grid ds-team-sync" y={0}>
          {/* Pořadatel */}
          <div className="ds-team-col team-col-host">
            <div className="ds-team-label host-label">
              <h3 className="ds-team-label-title">POŘADATEL</h3>
            </div>
            <article className="ds-team-card host-card">
              <div className="ds-team-photo">
                {D.host.photo ?
                  <img src={D.host.photo} alt={D.host.name} className="ds-team-photo-img" loading="lazy" decoding="async" style={D.host.photo_position ? { objectPosition: D.host.photo_position } : undefined} /> :
                  <Silhouette gender="boy" seed={1} idx={2} />
                }
                <span className="ds-team-badge">
                  <svg width="22" height="22" viewBox="0 0 24 24" fill="none">
                    <path d="M12 2l2.4 2.1 3.2-.4.8 3.1 3 1.5-1.4 2.9 1 3-2.7 1.7-.5 3.2-3.2 0L12 22l-2.6-2.9-3.2 0-.5-3.2L3 14.2l1-3-1.4-2.9 3-1.5.8-3.1 3.2.4z" fill="var(--pink)" />
                    <path d="M9 12.5l2 2 4-4.5" stroke="#fff" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
                  </svg>
                </span>
              </div>
              <div className="ds-team-body">
                <h4 className="ds-team-name"><BlurText text={D.host.name} stagger={120} /></h4>
                <div className="ds-team-role">{D.host.role}</div>
                <p className="ds-team-bio">{D.host.bio}</p>
                <div className="ds-team-stats">
                  <div><em>12</em><span>epizod</span></div>
                  <div><em>500k+</em><span>fanoušků</span></div>
                  <div><em>{D.host.age}</em><span>let</span></div>
                  <div><em>{D.host.instagram}</em><span>instagram</span></div>
                </div>
              </div>
            </article>
          </div>

          {/* Moderátor — rotující */}
          <div className="ds-team-col team-col-mod">
            <div className="ds-team-label mod-label">
              <h3 className="ds-team-label-title">MODERÁTOR</h3>
            </div>
            <article className="ds-team-card mod-card">
              <div className="ds-team-photo">
                {D.moderator.photo ?
                  <img src={D.moderator.photo} alt={D.moderator.name} className="ds-team-photo-img" loading="lazy" decoding="async" style={D.moderator.photo_position ? { objectPosition: D.moderator.photo_position } : undefined} /> :
                  <Silhouette gender="girl" seed={3} idx={1} />
                }
                <span className="ds-team-rotate">NOVÝ</span>
              </div>
              <div className="ds-team-body">
                <h4 className="ds-team-name"><BlurText text={D.moderator.name} stagger={120} delay={200} /></h4>
                <div className="ds-team-role">{D.moderator.role}</div>
                <p className="ds-team-bio">{D.moderator.bio}</p>
                <div className="ds-team-stats">
                  {D.moderator.episodes && D.moderator.episodes.length > 0 ? (
                    <div><em>EP {D.moderator.episodes.join(", ")}</em><span>{D.moderator.episodes.length === 1 ? "byl pouze v" : `${D.moderator.episodes.length}× moderátor`}</span></div>
                  ) : (
                    <div><em>EP {D.episode}</em><span>jen tento díl</span></div>
                  )}
                  <div><em>{D.moderator.age}</em><span>let</span></div>
                  <div><em>{D.moderator.instagram}</em><span>instagram</span></div>
                </div>
              </div>
            </article>
          </div>
        </Reveal>
      </section>

      {/* CAST — 5 + 5 streetwear karet */}
      <section id="cast" className="ds-cast">
        <Reveal className="ds-cast-head" y={20}>
          <div>
            <h2 className="ds-h2 ds-h2-center">TENTO TÝDEN SE ZÚČASTNÍ</h2>
          </div>
        </Reveal>

        <RevealSlide className="ds-cast-block" delay={50} dir="left" distance={180}>
          <div className="ds-cast-block-head ds-cast-block-head-center">
            <span className="ds-block-tag girl">ŽENSKÉ ZASTOUPENÍ</span>
          </div>
          <div className="ds-cards-row">
            <StaggerGroup step={160} delay={300} contents>
              {D.girls.map((g, i) => <PersonCard key={g.id} p={g} gender="girl" idx={i}
              votes={votes} count={adjustedVotes(g)} onVote={toggleVote}
              onSelectMatch={selectMatch}
              matched={match.girl === g.id} />

              )}
            </StaggerGroup>
          </div>
        </RevealSlide>

        {/* Spacing mezi holkami a kluky (lightning bude přidán později) */}
        <div className="ds-cast-divider" aria-hidden="true" />

        <RevealSlide className="ds-cast-block" delay={50} dir="right" distance={180}>
          <div className="ds-cast-block-head ds-cast-block-head-center">
            <span className="ds-block-tag boy">MUŽSKÉ ZASTOUPENÍ</span>
          </div>
          <div className="ds-cards-row">
            <StaggerGroup step={160} delay={300} contents reverse>
              {D.boys.map((b, i) =>
              <PersonCard
                key={b.id} p={b} gender="boy" idx={i}
                votes={votes} count={adjustedVotes(b)} onVote={toggleVote}
                onSelectMatch={selectMatch}
                matched={match.boy === b.id} />

              )}
            </StaggerGroup>
          </div>
        </RevealSlide>

        {/* BEST ENERGY — hlasování o nejsympatičtějšího napříč epizodami.
            Karty se DYNAMICKY přeskupují podle hlasů. Scroll skok je řešený
            v toggleVote (window.scrollTo zpět na původní pozici po re-renderu). */}
        {(() => {
          const sorted = [...D.allParticipants].sort((a, b) => adjustedVotes(b) - adjustedVotes(a));
          const topGirl = sorted.find(p => p.gender === "girl");
          const topBoy = sorted.find(p => p.gender === "boy");
          const allByVotes = sorted;
          return (
            <section id="best-energy" className="ds-best">
              <Reveal className="ds-best-head" y={20}>
                <h2 className="ds-h2 ds-best-title">BEST <em>ENERGY</em></h2>
                <p className="ds-best-sub">
                  Kdo má <em>nejlepší energii</em>? Hlasujte pro nejsympatičtějšího účinkujícího napříč všemi epizodami. <strong>Vede ten, kdo má nejvíc lajků.</strong>
                </p>
                <p className="ds-best-notice">
                  Máš lepší fotku, znáš jejich Instagram, nebo máš info? <a href="/uprav" className="ds-best-notice-link"><strong>Uprav přímo zde →</strong></a>
                </p>
              </Reveal>

              {/* Spotlight — top kluk vlevo, + uprostřed, top holka vpravo */}
              <div className="ds-best-leaders">
                {[
                  { p: topBoy,  label: "ENERGY KRÁL" },
                  { p: null,    isPlus: true },
                  { p: topGirl, label: "ENERGY KRÁLOVNA" }
                ].map((item, i) => {
                  if (item.isPlus) {
                    return <div key="plus" className="ds-best-plus" aria-hidden="true">+</div>;
                  }
                  const p = item.p;
                  if (!p) return null;
                  return (
                    <article key={p.id} className={`ds-best-leader ds-best-leader-${p.gender}`}>
                      <div className="ds-best-leader-tag">
                        <span className="ds-best-rank-num">#1</span>
                        <span className="ds-best-rank-label">{item.label}</span>
                      </div>
                      <div className="ds-best-leader-photo">
                        {p.photo ?
                          <img src={p.photo} alt={p.name} loading="lazy" decoding="async" style={p.photo_position ? { objectPosition: p.photo_position } : undefined} /> :
                          <Silhouette gender={p.gender} seed={p.id.charCodeAt(p.id.length - 1)} idx={0} />
                        }
                      </div>
                      <div className="ds-best-leader-info">
                        <h3 className="ds-best-leader-name">{p.name} <span>· {p.age}</span></h3>
                        <div className="ds-best-leader-meta">
                          <span>EP {String(p.episode).padStart(2, "0")}</span>
                          <span className="ds-best-sep">·</span>
                          <span><em>{adjustedVotes(p)}</em> hlasů</span>
                        </div>
                        {p.info && p.info.length > 0 && (
                          <ul className="ds-best-leader-bullets">
                            {p.info.slice(0, 3).map((line, i) => <li key={i}>{line}</li>)}
                          </ul>
                        )}
                        <button
                          type="button"
                          className={`ds-best-vote-btn ${bestVotes[p.id] ? "voted" : ""}`}
                          onClick={(e) => { e.preventDefault(); e.stopPropagation(); toggleBestVote(p.id); }}>
                          <Heart filled={!!bestVotes[p.id]} size={14} />
                          <span>{bestVotes[p.id] ? "Zrušit hlas" : "Hlasovat"}</span>
                        </button>
                      </div>
                    </article>
                  );
                })}
              </div>

              {/* 4×5 grid všech účinkujících — stejné karty jako na hlavní stránce */}
              <div className="ds-best-grid-head">
                <span className="ds-best-grid-label">Všichni účinkující</span>
                <span className="ds-best-grid-count">[{allByVotes.length}]</span>
              </div>
              <div className="ds-best-cards">
                <StaggerGroup step={50} contents>
                  {allByVotes.map((p, i) => (
                    <BestEnergyCard
                      key={p.id}
                      p={p}
                      rank={i + 1}
                      voted={!!bestVotes[p.id]}
                      count={adjustedVotes(p)}
                      onVote={toggleBestVote}
                    />
                  ))}
                </StaggerGroup>
              </div>
            </section>
          );
        })()}

        {/* STORIES — příběhy z minulých dílů */}
        <section id="stories" className="ds-stories">
          <Reveal className="ds-stories-head" y={20}>
            <div>
              <h2 className="ds-stories-title">Příběhy z DateShow</h2>
            </div>
          </Reveal>

          <div className="ds-stories-grid">
            {(D.stories && D.stories.length > 0
              ? D.stories
              : [
                  { id: "_s1", image: "pribeh1.png",      image_fit: "contain",       date_text: "27.03.2026",  episode: 10, title: "Polcarka &amp; Nio", description: "Po DateShow se opravdu sešli. Z účinkujících jsou šťastní partneři. Jeden z prvních párů, který show svedla dohromady." },
                  { id: "_s2", image: "pribeh2.png",      image_fit: "anchor-bottom", date_text: "Minulý týden", episode: 13, title: "100% winrate. Rekord show", description: "Poslední DateShow měli <strong>neuvěřitelný 100% winrate</strong>: každý účinkující si našel svůj match. Nejúspěšnější díl vůbec." },
                  { id: "_s3", image: "pribeh hroty.png", image_fit: "cover",         date_text: "Minulý díl",   episode: 13, title: "Nejznámější luxmaxer <em>vs.</em> Rogalator", description: "Konflikt eskaloval naživo na streamu. <strong>Nejznámější luxmaxer show</strong> se pustil do Rogalatora. Extrémně se vyhrotili, chat hořel a klipy lítaly všude." }
                ]
            ).map((s, i) => (
              <Reveal key={s.id} as="article" className="ds-story" delay={i * 140} y={20}>
                <div className={`ds-story-img ${s.image_fit === "contain" ? "ds-story-img-contain" : s.image_fit === "anchor-bottom" ? "ds-story-img-anchor-bottom" : ""}`}>
                  {s.image && <img src={s.image} alt="" loading="lazy" decoding="async" />}
                </div>
                <div className="ds-story-meta">
                  {s.date_text && <span>{s.date_text}</span>}
                  {s.date_text && s.episode != null && <span className="ds-story-sep">·</span>}
                  {s.episode != null && <span>Epizoda {s.episode}</span>}
                </div>
                <h3 className="ds-story-title" dangerouslySetInnerHTML={{ __html: s.title }} />
                <p className="ds-story-desc" dangerouslySetInnerHTML={{ __html: s.description || "" }} />
              </Reveal>
            ))}
          </div>
        </section>

        {/* PRIZE — týdenní výhra rande */}
        {/* INFO GRID — 2×2: Prize (text + image) + Sponsor (image + text) */}
        <section className="ds-info-grid">
          <div className="ds-info-2x2">
            {/* Cell 1: PRIZE TEXT (top-left) */}
            <Reveal className="ds-info-cell ds-info-cell-text" delay={0} y={24}>
              <div className="ds-info-cell-inner">
                <span className="ds-info-cell-tag">Týdenní výhra</span>
                <h3 className="ds-info-cell-title">
                  <BlurText text="Nejlepší pár vyhrává" stagger={70} />
                  <br />
                  <span className="ds-info-cell-title-em">až 1&nbsp;000&nbsp;Kč.</span>
                </h3>
                <p className="ds-info-cell-desc">
                  Každý týden po live date show <strong>chat hlasuje</strong> pro nejlepší pár — výherci si odnesou <strong>2× 500 freespinů</strong>.
                </p>
                <p className="ds-info-cell-desc">
                  Rovnou po date show si můžete dát první rande přímo při točkách. <em>Štěstí už je jen na vás.</em>
                </p>
              </div>
            </Reveal>

            {/* Cell 2: PRIZE IMAGE (top-right) — rande za 1000 Kč */}
            <Reveal className="ds-info-cell ds-info-cell-img ds-info-cell-img-prize" delay={140} y={24}>
              <img src="rande.png" alt="Rande za 1000 Kč" loading="lazy" decoding="async" />
              <div className="ds-info-cell-img-fade" aria-hidden="true" />
            </Reveal>

            {/* Cell 3: SPONSOR IMAGE (bottom-left) — Casino Akce partner */}
            <Reveal className="ds-info-cell ds-info-cell-img ds-info-cell-img-sponsor" delay={280} y={24}>
              <img src="casinoakce.jpg" alt="Casino Akce — partner pořadu" loading="lazy" decoding="async" />
              <div className="ds-info-cell-img-fade" aria-hidden="true" />
            </Reveal>

            {/* Cell 4: SPONSOR TEXT (bottom-right) */}
            <Reveal className="ds-info-cell ds-info-cell-text" delay={420} y={24}>
              <div className="ds-info-cell-inner">
                <span className="ds-info-cell-tag">Hlavní sponzor</span>
                <h3 className="ds-info-cell-title">
                  <BlurText text="casinoakce.cz" stagger={90} />
                </h3>
                <p className="ds-info-cell-desc">
                  Hlavní partner DateShow je značka, která show podporuje od první epizody — <strong>bez nich by to nebylo ono</strong>.
                </p>
                <p className="ds-info-cell-desc">
                  Kdo ještě není zaregistrovaný, na toho čekají <strong>free spiny v hodnotě tisíců korun</strong>.
                </p>
              </div>
            </Reveal>
          </div>
        </section>
      </section>

      {/* MATCH — Love Game zatím vypnutý (vrátíme později) */}

      {/* ARCHIVE */}
      <section id="archive" className="ds-archive">
        <div className="ds-section-eyebrow">
</div>
        <h2 className="ds-h2"><BlurText text="PŘEDCHOZÍ EPIZODY" stagger={90} /></h2>
        <div className="ds-archive-list">
          <StaggerGroup step={120}>
          {(D.archive && D.archive.length > 0
            ? D.archive
            : [
                { ep: 13, t: "Kdo s kým? — finále s polibkem" },
                { ep: 12, t: "Drama u stolu č. 3" },
                { ep: 11, t: "Nečekané přiznání hosta" },
                { ep: 10, t: "První slzy v kariéře show" },
                { ep: 9,  t: "Halloween special" }
              ]).slice(0, 5).map(({ ep, t }) =>
            <a key={ep} className="ds-archive-row">
              <span className="ds-arch-ep">EP {String(ep).padStart(2, "0")}</span>
              <span className="ds-arch-title">{t}</span>
              <span className="ds-arch-date">{ep * 47}k</span>
              <span className="ds-arch-arrow ds-arch-go"><ArrowUpRight size={20} /></span>
            </a>
            )}
          </StaggerGroup>
        </div>
        {(D.archive && D.archive.length > 5) && (
          <Reveal delay={400} y={16} className="ds-archive-more-wrap">
            <a href="/archive" className="ds-archive-more">
              Zobrazit všechny epizody
              <ArrowUpRight size={18} />
            </a>
          </Reveal>
        )}
      </section>

      {/* APPLY — Discord QR pozvánka (nahrazuje původní form) */}
      {(() => {
        // ⚠️ Lepší by byl pravý INVITE link (https://discord.gg/xxxxx) — channel link
        // funguje jen členům serveru. Vyměň až bude invite. Generování: server →
        // ▼ → Pozvat lidi → Upravit pozvánku (Nikdy / Bez limitu) → Generovat.
        const DISCORD_INVITE = "https://discord.com/channels/936544882091233300/1459234142364372992";
        const qrUrl = `https://api.qrserver.com/v1/create-qr-code/?size=320x320&margin=8&color=ff4d8f&bgcolor=110018&data=${encodeURIComponent(DISCORD_INVITE)}`;
        return (
          <section id="apply" className="ds-apply ds-apply-qr">
            <div className="ds-apply-qr-grid">
              <Reveal className="ds-apply-qr-text" delay={100} y={20}>
                <h2 className="ds-h2"><BlurText text="CHCEŠ BÝT U TOHO?" stagger={90} /></h2>
                <p className="ds-apply-qr-lead">
                  Naskenuj QR kód a připoj se na <strong>náš Discord</strong>.
                  Vše se domluví tam — kdo, kdy, jak.
                </p>
                <div className="ds-apply-meta">
                  <div><em>WEBKAMERA</em><span>nutná</span></div>
                  <div><em>SLUCHÁTKA</em><span>nutná</span></div>
                  <div><em>DISCORD</em><span>účet</span></div>
                  <div><em>VĚK</em><span>18+</span></div>
                </div>
                <a className="ds-apply-qr-btn" href={DISCORD_INVITE} target="_blank" rel="noreferrer noopener">
                  <span>Otevřít Discord →</span>
                </a>
              </Reveal>
              <Reveal className="ds-apply-qr-card" delay={300} y={20}>
                <a href={DISCORD_INVITE} target="_blank" rel="noreferrer noopener" className="ds-apply-qr-link">
                  <div className="ds-apply-qr-img">
                    <img src={qrUrl} alt="Discord invite QR code" loading="lazy" />
                  </div>
                  <div className="ds-apply-qr-caption">
                    <span className="ds-apply-qr-emoji">📱</span>
                    <span>Naskenuj telefonem</span>
                  </div>
                </a>
              </Reveal>
            </div>
          </section>
        );
      })()}

      <footer className="ds-footer">
        <span>OPATOVA-DATESHOW.CZ</span>
        <span>Každou sobotu 20:00 · Discord live</span>
        <span>© 2026 {D.host.name}</span>
      </footer>
    </div>);
}

window.VariantMain = VariantMain;