const { useState, useEffect, useRef } = React;

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accentColor": "#5b9cf6",
  "accentColor2": "#9b7bf8",
  "trailerUrl": "https://player.vimeo.com/video/1189614771?context=Vimeo%5CController%5CApi%5CResources%5CVideoController.&h=ba9a0b6152&s=c07487c8fecf29f2ba0acf1ef9c6c86e3ec65bf4_1778882686",
  "showGridBg": true
} /*EDITMODE-END*/;

// Media library
// To replace a placeholder, put a file in /uploads and add its path below.
// Use src for images, or video for short local clips. Leave the other field blank.
// Example: "Dash Ability": { src: "uploads/dash.jpg", video: "", alt: "Dash Ability" }
const MEDIA_LIBRARY = {
  "Dash Ability": {
    "src": "",
    "video": "uploads/Dash_vid.mp4",
    "alt": "Dash Ability"
  },
  "Scan Ability": {
    "src": "",
    "video": "",
    "alt": "Scan Ability"
  },
  "Traversal": {
    "src": "",
    "video": "",
    "alt": "Traversal"
  },
  "Prune Gun": {
    "src": "",
    "video": "",
    "alt": "Prune Gun"
  },
  "Pruning Puzzle": {
    "src": "",
    "video": "",
    "alt": "Pruning Puzzle"
  },
  "Incursion Event": {
    "src": "",
    "video": "",
    "alt": "Incursion Event"
  },
  "Rift": {
    "src": "",
    "video": "",
    "alt": "Rift"
  },
  "Foreign Matter": {
    "src": "",
    "video": "",
    "alt": "Foreign Matter"
  },
  "DE Meter HUD": {
    "src": "",
    "video": "",
    "alt": "DE Meter HUD"
  },
  "Anomaly VFX": {
    "src": "",
    "video": "",
    "alt": "Anomaly VFX"
  },
  "Protective Suit": {
    "src": "",
    "video": "",
    "alt": "Protective Suit"
  },
  "HUD Guidance": {
    "src": "",
    "video": "",
    "alt": "HUD Guidance"
  },
  "Pause Menu": {
    "src": "",
    "video": "",
    "alt": "Pause Menu"
  },
  "Audio / Music": {
    "src": "",
    "video": "",
    "alt": "Audio / Music"
  },
  "Atmosphere / VFX": {
    "src": "",
    "video": "",
    "alt": "Atmosphere / VFX"
  },
  "Scan / Locate": {
    "src": "",
    "video": "",
    "alt": "Scan / Locate"
  },
  "Pruning": {
    "src": "",
    "video": "",
    "alt": "Pruning"
  },
  "Containment Device": {
    "src": "",
    "video": "",
    "alt": "Containment Device"
  },
  "Stabilize Phase": {
    "src": "",
    "video": "",
    "alt": "Stabilize Phase"
  },
  "Extraction Portal": {
    "src": "",
    "video": "",
    "alt": "Extraction Portal"
  },
  "LU/VO #2403 — New Level": {
    "src": "",
    "video": "",
    "alt": "LU/VO #2403 — New Level"
  },
  "Variants Gym — Test Level": {
    "src": "",
    "video": "",
    "alt": "Variants Gym — Test Level"
  },
  "UE Sub-levels": {
    "src": "",
    "video": "",
    "alt": "UE Sub-levels"
  },
  "Bureau Office": {
    "src": "",
    "video": "",
    "alt": "Bureau Office"
  },
  "Group Travel — Bureau Portal": {
    "src": "",
    "video": "",
    "alt": "Group Travel — Bureau Portal"
  },
  "Replication — Co-op Features": {
    "src": "",
    "video": "",
    "alt": "Replication — Co-op Features"
  },
  "Web Prototype 01": {
    "src": "",
    "video": "",
    "alt": "Web Prototype 01"
  },
  "Web Prototype 02": {
    "src": "",
    "video": "",
    "alt": "Web Prototype 02"
  },
  "Web Prototype 03": {
    "src": "",
    "video": "",
    "alt": "Web Prototype 03"
  },
  "Web Prototype 04": {
    "src": "",
    "video": "",
    "alt": "Web Prototype 04"
  }
};


// ── FRAME SVG OUTLINE ──
// Draws the white corner-cut polygon outline matching clip-path
function FrameBorder({ cut = 20, color = "rgba(255,255,255,0.75)", thickness = 1.5 }) {
  // We use a viewBox approach with preserveAspectRatio=none
  // The polygon points are in % coordinates matching the clip-path
  const c = cut; // corner cut px relative to 100-unit viewBox
  // We'll use a large viewBox so the corner size is meaningful
  return (
    <svg
      className="img-frame-border"
      viewBox="0 0 400 225"
      preserveAspectRatio="none"
      xmlns="http://www.w3.org/2000/svg"
      style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', pointerEvents: 'none', zIndex: 1 }}>
      
          <polygon
        points={`${c},0 400,0 400,${225 - c} ${400 - c},225 0,225 0,${c}`}
        fill="none"
        stroke={color}
        strokeWidth={thickness}
        vectorEffect="non-scaling-stroke" />
      
        </svg>);

}

// ── IMAGE FRAME ──
// ImgFrame — shows a video clip, a static image, or a labelled placeholder.
// How to use:
//   video clip:   <ImgFrame video="uploads/my-clip.mp4" label="Dash Ability" />
//   static image: <ImgFrame src="uploads/my-image.jpg" label="Dash Ability" />
//   placeholder:  <ImgFrame label="Dash Ability" sublabel="Drop a screenshot here" />
function ImgFrame({ src, video, alt, label, sublabel, cut = 20, style = {} }) {
  const media = label ? MEDIA_LIBRARY[label] : null;
  const resolvedVideo = video || media?.video || "";
  const resolvedSrc = src || media?.src || "";
  const resolvedAlt = alt || media?.alt || label || "";
  const clipPath = `polygon(${cut}px 0%, 100% 0%, 100% calc(100% - ${cut}px), calc(100% - ${cut}px) 100%, 0% 100%, 0% ${cut}px)`;

  let content;
  if (resolvedVideo) {
    // autoPlay + muted is required by all browsers to play without user interaction
    // playsInline prevents fullscreen takeover on iOS
    content = (
      <video
        src={resolvedVideo}
        autoPlay
        loop
        muted
        playsInline
        style={{ clipPath, display: 'block', width: '100%', aspectRatio: '16/9', objectFit: 'cover' }}
      />
    );
  } else if (resolvedSrc) {
    content = (
      <img
        src={resolvedSrc} alt={resolvedAlt}
        style={{ clipPath, display: 'block', width: '100%' }}
      />
    );
  } else {
    content = (
      <div className="img-frame-inner placeholder-bg" style={{ clipPath }}>
        <div style={{ fontSize: 30, opacity: 0.22 }}>⬚</div>
        {label && <div style={{ fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--muted)', lineHeight: 1.5, maxWidth: 220, textAlign: 'center' }}>{label}</div>}
        {sublabel && <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--faint)', marginTop: 4 }}>{sublabel}</div>}
      </div>
    );
  }

  return (
    <div className="img-frame" style={style}>
      {content}
      <FrameBorder cut={cut} />
    </div>
  );
}

// ── VIDEO FRAME ──
function VideoFrame({ src, cut = 24 }) {
  const clipPath = `polygon(${cut}px 0%, 100% 0%, 100% calc(100% - ${cut}px), calc(100% - ${cut}px) 100%, 0% 100%, 0% ${cut}px)`;
  return (
    <div style={{ position: 'relative', width: '100%' }}>
          <div style={{ position: 'relative', width: '100%', paddingTop: '56.25%', clipPath }}>
            <iframe
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', border: 'none', display: 'block' }}
          src={src}
          title="Variants Prototype 3 Trailer"
          allow="autoplay; fullscreen; picture-in-picture"
          allowFullScreen />
        
          </div>
          <FrameBorder cut={cut} />
        </div>);

}

// ── TIMELINE ──
const TIMELINE_STEPS = [
{ label: "Proto 1", name: "First Loop", desc: "Base → level → objectives → enemies → extraction. Established the core gameplay skeleton and proved the concept could work end-to-end." },
{ label: "Proto 2", name: "Co-op Foundation", desc: "Basic P2P multiplayer, second level, improved enemies and escalation. Validated that multiplayer was achievable and identified key replication challenges." },
{ label: "Proto 3", name: "Direction Prototype", desc: "Dash, scan, pruning, anomalies, DE, rifts, new objective flow, co-op travel. This is the current milestone — begin to shape the identity of Variants.", active: true },
{ label: "Next", name: "PoC Prototype", desc: "Connect scoped and WIP systems into a cohesive playable concept-scale demo — one loop, all systems working together." }];


function Timeline() {
  const [active, setActive] = useState(2);
  return (
    <div className="timeline-wrapper">
          {TIMELINE_STEPS.map((step, i) =>
      <div key={i} className={`timeline-step${active === i ? ' ts-active' : ''}`} onClick={() => setActive(i)}>
              <div className="ts-indicator" />
              <div className="ts-label">{step.label}</div>
              <div className="ts-name">{step.name}</div>
              <div className="ts-desc">{step.desc}</div>
            </div>
      )}
        </div>);

}

// ── ACCORDION DATA ──
const ADDITIONS = [
{
  icon: "⚡", iconBg: "rgba(91,156,246,0.12)",
  title: "Player Movement, Tools & Abilities",
  intro: "Proto 3 introduces the core player toolkit that defines Variants' feel — fast traversal, information gathering, and multiverse-specific tools.",
  features: [
  {
    name: "Dash Ability",
    desc: "A quick directional burst of movement for traversal and combat repositioning.",
    detail: "The dash is designed to give players decisive agency in firefights and traversal. By tapping dash in any direction, the player gets a short burst of movement — enough to break line-of-sight, close a gap, or dodge an incoming threat. Cooldown tuning is ongoing; the goal is to make it feel impactful without removing all consequence. In Proto 3, the dash is fully replicated for co-op.",
    imgLabel: "Dash Ability", imgSub: "Replace with in-game footage of dash"
  },
  {
    name: "Scan Ability",
    desc: "360° radial pulse that highlights foreign matter, objectives, and enemies through walls.",
    detail: "Scan is the player's primary information tool. Triggered from a button press, it emits a visible shockwave that highlights nearby foreign objects, enemy positions, and objective markers through geometry. This is critical to the mission loop — without scan, players would have to explore blindly. The visual language of the scan is still being refined for clarity and atmosphere.",
    imgLabel: "Scan Ability", imgSub: "Replace with 360° scan pulse VFX screenshot"
  },
  {
    name: "Vaulting, Climbing & Mantling",
    desc: "Enables verticality and more flexible level design throughout the game world.",
    detail: "With the new traversal system, players can vault over low obstacles, climb ledges, and mantle onto surfaces without dedicated jump pads or workarounds. This unlocks much richer level design possibilities, allowing designers to build vertical spaces, rooftops, and interiors that feel authentic. The Level Designer's first level (LU/VO #2403) was built with this system in mind.",
    imgLabel: "Traversal", imgSub: "Replace with climbing / vaulting screenshot"
  },
  {
    name: "Prune Gun",
    desc: "Special tool used to interact with and remove foreign matter found during missions.",
    detail: "The Prune Gun is the player's primary multiverse tool — the thing that makes Variants feel different from a conventional shooter. It's used specifically on foreign matter and triggers the pruning mini-puzzle sequence. Visually it should feel clinical and technological, and the interaction should have clear feedback to signal success or failure of the pruning attempt.",
    imgLabel: "Prune Gun", imgSub: "Replace with Prune Gun in-hand screenshot"
  },
  {
    name: "Pruning Mechanic",
    desc: "Mid-game mini-puzzle used to remove foreign matter at Rift-adjacent locations.",
    detail: "When the player activates the Prune Gun on a foreign matter site, a brief interactive puzzle plays out. The current implementation is placeholder — it exists to establish the rhythm and pacing of the action rather than the final puzzle design. Future iterations should make this moment feel tense and skill-rewarding, balancing pressure from nearby enemies with the focus required to complete the prune.",
    imgLabel: "Pruning Puzzle", imgSub: "Replace with pruning mechanic UI/gameplay screenshot"
  }]

},
{
  icon: "🌀", iconBg: "rgba(155,123,248,0.12)",
  title: "Incursions, Rifts & Foreign Matter",
  intro: "The multiverse systems that give Variants its identity — foreign matter, rifts, and the events that create them.",
  features: [
  {
    name: "Incursions",
    desc: "World events where foreign matter from another universe pushes into the current one.",
    detail: "An Incursion is the inciting event of a mission. Something from another universe is bleeding through — foreign objects, creatures, or energy. The active Incursion in LU/VO #2403 is built around a stable foreign object that has created a persistent Rift. The escalation pressure of 'more keeps coming through' is what drives urgency and pacing throughout the mission.",
    imgLabel: "Incursion Event", imgSub: "Replace with incursion VFX / atmosphere screenshot"
  },
  {
    name: "Rifts",
    desc: "Spacetime tears formed when foreign matter pushes through from another universe.",
    detail: "A Rift is a visible, physical portal in space — a wound in the fabric of reality. It serves as both the visual anchor for the mission and the mechanical source of escalation. While the Rift is open, more foreign matter and enemies can enter the level. Closing the Rift (through containment) is the primary objective. The visual design of the Rift is a key artistic moment and should communicate danger, otherness, and urgency.",
    imgLabel: "Rift", imgSub: "Replace with Rift spacetime tear screenshot"
  },
  {
    name: "Foreign Matter",
    desc: "Physical objects or entities that have crossed from another universe.",
    detail: "The contrast between Bureau (safe, civilian, office) and expedition (suited, armed, dangerous) is a key part of Variants' narrative identity. The suit visually communicates that the player is crossing into hostile territory. It also opens the door for DE-affecting suit upgrades, damage to the suit as a DE escalation signal, and deeper character customisation in future milestones.",
    imgLabel: "Foreign Matter", imgSub: "Replace with foreign matter prop screenshot"
  }]

},
{
  icon: "📡", iconBg: "rgba(80,227,194,0.12)",
  title: "DE, Anomalies & Suit Direction",
  intro: "The first steps toward representing Dimensional Exposure — the survival pressure system unique to Variants.",
  features: [
  {
    name: "DE Meter",
    desc: "HUD element tracking Dimensional Exposure — the player's accumulation of interdimensional energy.",
    detail: "The DE meter is a first draft of what will become a critical survival mechanic. Prolonged exposure to foreign matter, Rifts, and high-DE zones increases the player's DE level. In future iterations, high DE will trigger anomalies, impair the player, and ultimately become a life-or-death resource to manage. In Proto 3, it's present in the HUD to establish the visual language and validate legibility during play.",
    imgLabel: "DE Meter HUD", imgSub: "Replace with DE meter HUD screenshot"
  },
  {
    name: "Anomalies",
    desc: "Perceptual and physical distortions caused by high Dimensional Exposure.",
    detail: "Anomalies are currently implemented as visual distortion effects with three intensity levels (mild, moderate, severe). At higher intensity, the screen warps, edges pulse, and the world feels unstable. This is a placeholder for a deeper system — future anomalies should affect gameplay meaningfully, not just visually. The goal is to make high DE feel genuinely threatening and to reward careful exposure management.",
    imgLabel: "Anomaly VFX", imgSub: "Replace with anomaly visual distortion screenshot"
  },
  {
    name: "Protective Suit",
    desc: "Players now wear expedition gear in the field and civilian clothes at the Bureau.",
    detail: "Proto 3 introduces a two-state music system: ambient (exploration, base, downtime) and action (combat, objective moments, escalation). The transition between states responds to what the player is doing. This is a significant step toward audio-driven atmosphere. The tracks are placeholder compositions intended to validate the system and establish the tone, not final audio.",
    imgLabel: "Protective Suit", imgSub: "Replace with player suit / Bureau contrast screenshot"
  }]

},
{
  icon: "🎮", iconBg: "rgba(246,180,91,0.12)",
  title: "Presentation, Guidance & Atmosphere",
  intro: "The systems that make Proto 3 feel like a more complete experience — onboarding, audio, and atmosphere.",
  features: [
  {
    name: "Dynamic HUD Guidance",
    desc: "Tutorial text that appears contextually to introduce mechanics and objectives.",
    detail: "The dynamic HUD tutorial system displays contextual guidance at key moments — when the player first encounters foreign matter, when they need to use scan, or when an objective updates. This removes the need for static tutorial screens and keeps the player in the world. The implementation is intentionally minimal for Proto 3; the goal is to validate that players can understand the loop without external documentation.",
    imgLabel: "HUD Guidance", imgSub: "Replace with HUD tutorial text in-game screenshot"
  },
  {
    name: "Pause Menu",
    desc: "In-mission pause with return-to-Bureau and quit options.",
    detail: "A clean pause menu has been added with two key options: return to the Bureau (soft exit, preserving co-op session state where possible) and full quit. This is a quality-of-life improvement that also begins to establish the navigation language between the Bureau hub and expedition levels — a relationship that will become more significant as the game develops.",
    imgLabel: "Pause Menu", imgSub: "Replace with pause menu screenshot"
  },
  {
    name: "Music System",
    desc: "Adaptive music with ambient and action states responding to gameplay.",
    detail: "Proto 3 introduces a two-state music system: ambient (exploration, base, downtime) and action (combat, objective moments, escalation). The transition between states responds to what the player is doing. This is a significant step toward audio-driven atmosphere. The tracks are placeholder compositions intended to validate the system and establish the tone, not final audio.",
    imgLabel: "Audio / Music", imgSub: "Replace with atmosphere / audio VFX screenshot"
  },
  {
    name: "Atmosphere & VFX",
    desc: "Additional visual effects to reinforce the multiverse mood throughout the level.",
    detail: "New VFX have been added to strengthen the sense that the player is operating in a world where reality is unstable. These include ambient particle effects near foreign matter, energy distortions around Rift edges, and subtle environmental reactions to DE. The Bureau has also received minor visual updates to better communicate the contrast between the safety of HQ and the danger of the field.",
    imgLabel: "Atmosphere / VFX", imgSub: "Replace with atmosphere VFX screenshot"
  }]

}];


// ── ACCORDION ──
function Accordion({ items }) {
  const [openItems, setOpenItems] = useState([0]);
  const toggleItem = (index) => {
    setOpenItems((current) =>
      current.includes(index)
        ? current.filter((item) => item !== index)
        : [...current, index]
    );
  };
  return (
    <div className="accordion-list">
          {items.map((item, i) => {
      const isOpen = openItems.includes(i);
      return (
      <div key={i} className={`accordion-item${isOpen ? ' open' : ''}`}>
              <div className="accordion-header" onClick={() => toggleItem(i)}>
                <div className="accordion-title-row">
                  <div className="accordion-icon" style={{ background: item.iconBg }}>
                    <span>{item.icon}</span>
                  </div>
                  <div>
                    <div className="accordion-title">{item.title}</div>
                    {!isOpen && <div style={{ fontSize: 13, color: 'var(--muted)', marginTop: 3 }}>{item.intro}</div>}
                  </div>
                </div>
                <div className="accordion-chevron">▾</div>
              </div>
              <div className="accordion-body">
                <div className="accordion-body-inner">
                  <div className="accordion-content">
                    <div style={{ padding: '22px 28px 10px', borderBottom: '1px solid var(--line)' }}>
                      <p style={{ fontSize: 15, color: 'var(--muted)', lineHeight: 1.7 }}>{item.intro}</p>
                    </div>
                    {item.features.map((f, j) =>
              <div key={j} className={`feature-entry${j % 2 === 1 ? ' reverse' : ''}`}>
                        <div className="feature-img-col">
                          <ImgFrame label={f.imgLabel} sublabel={f.imgSub} />
                        </div>
                        <div className="feature-text-col">
                          <div className="feature-title">{f.name}</div>
                          <div className="feature-desc">{f.desc}</div>
                          <div className="feature-detail" style={{ color: "rgb(100, 109, 135)" }}>{f.detail}</div>
                        </div>
                      </div>
              )}
                  </div>
                </div>
              </div>
            </div>
      );
    })}
        </div>);

}

// ── OBJECTIVE FLOW ──
const FLOW_STEPS = [
{
  name: "Locate", desc: "Use scanner to find nearby Foreign Matter and mission-critical points.",
  detail: "The scan ability emits a 360° radial pulse that reveals foreign matter, enemy positions, and objective markers through geometry. This gives players contextual awareness of what they're dealing with before committing to an approach. The scan has a cooldown and a visible VFX readout so co-op partners can see when their teammate is scanning.",
  imgLabel: "Scan / Locate", imgSub: "Replace with scan radial pulse screenshot"
},
{
  name: "Prune", desc: "Use the Prune Gun and puzzle mechanic to remove foreign matter.",
  detail: "The Prune Gun is activated at a foreign matter site, triggering a brief interactive puzzle. Successfully completing it removes the matter and reduces Rift escalation. This is the core identity mechanic — it differentiates Variants from a standard shooter and creates a moment of focus and tension within each mission beat.",
  imgLabel: "Pruning", imgSub: "Replace with pruning mechanic in-game screenshot"
},
{
  name: "Contain", desc: "Unlock the Rift and install a Containment device.",
  detail: "Once sufficient foreign matter is pruned, the Rift becomes accessible. Players must install a Containment device and defend it while it charges — introducing a defend-the-objective pressure moment with environmental and enemy escalation. This is a natural co-op synchronisation point: one player installs, one defends.",
  imgLabel: "Containment Device", imgSub: "Replace with containment device / Rift screenshot"
},
{
  name: "Stabilize", desc: "Prune additional foreign matter near the active Rift.",
  detail: "With the Containment device active, secondary foreign matter continues to spawn near the Rift. Players must quickly prioritise and prune these incursions to maintain Containment integrity. This phase introduces time pressure and tests whether players have internalised the scan-locate-prune loop from earlier in the mission.",
  imgLabel: "Stabilize Phase", imgSub: "Replace with foreign matter near Rift screenshot"
},
{
  name: "Extract", desc: "Locate the extraction portal and return to base.",
  detail: "The final scan reveals the extraction portal location. Players navigate back under potential pressure from remaining enemies and a narrowing window before the Rift destabilises. Reaching the portal and extracting completes the mission loop and returns the team to the Bureau. Future iterations may add extraction holdout pressure for co-op.",
  imgLabel: "Extraction Portal", imgSub: "Replace with extraction portal / end-of-mission screenshot"
}];


function ObjectiveFlow() {
  const [active, setActive] = useState(0);
  const step = FLOW_STEPS[active];
  return (
    <div>
          <div style={{ position: 'relative' }}>
            <div className="flow-steps">
              <div className="flow-connector" />
              {FLOW_STEPS.map((s, i) =>
          <div
            key={i}
            className={`flow-step${active === i ? ' flow-active' : ''}${i < active ? ' flow-done' : ''}`}
            onClick={() => setActive(i)}>
            
                  <div className="flow-num">{i < active ? '✓' : i + 1}</div>
                  <div className="flow-label">{s.name}</div>
                  <div className="flow-desc">{s.desc}</div>
                </div>
          )}
            </div>
          </div>
          <div className="flow-detail-panel">
            <div className="flow-detail-inner">
              <div>
                <div className="flow-detail-title">{step.name}</div>
                <div className="flow-detail-desc">{step.detail}</div>
                <div className="flow-nav">
                  <button className="flow-nav-btn" onClick={() => setActive((a) => a - 1)} disabled={active === 0}>← Previous</button>
                  <button className="flow-nav-btn" onClick={() => setActive((a) => a + 1)} disabled={active === FLOW_STEPS.length - 1}>Next →</button>
                  <span className="flow-progress-text">{active + 1} / {FLOW_STEPS.length}</span>
                </div>
              </div>
              <ImgFrame label={step.imgLabel} sublabel={step.imgSub} />
            </div>
          </div>
        </div>);

}

// ── VALIDATION ──
const VALIDATION_ITEMS = [
{ num: "01", title: "Variants Identity", desc: "A more distinctive gameplay direction beyond a generic shooter foundation. Proto 3 introduces the mechanics and systems that make Variants feel like its own thing." },
{ num: "02", title: "Mission Structure", desc: "A thematic loop built around Incursions, Rifts, Foreign Matter, pruning, and extraction. This milestone validates whether the loop is fun and comprehensible." },
{ num: "03", title: "Gameplay Variety", desc: "Early traversal, combat, tool, and scanning systems that support more varied play. Each mechanic is tested for how well it integrates with the others." },
{ num: "04", title: "DE & Anomalies", desc: "First visible steps toward Dimensional Exposure, anomalies, and future survival pressure. Validates the HUD language and visual clarity of the system." },
{ num: "05", title: "Co-op Foundation", desc: "Group travel, replication progress, and better basis for future multiplayer integration. Tests whether the new mechanics hold up in two-player sessions." },
{ num: "06", title: "Production Process", desc: "Expanded team working through rapid prototyping, iteration, and concept validation. Validates our ability to iterate quickly with a growing team." }];


// ── APP ──
function App() {
  const [tweaks, setTweak] = useTweaks(TWEAK_DEFAULTS);

  // scroll / nav effects
  useEffect(() => {
    const bar = document.getElementById('progress-bar');
    const onScroll = () => {
      const pct = window.scrollY / (document.documentElement.scrollHeight - window.innerHeight) * 100;
      bar.style.width = pct + '%';
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  useEffect(() => {
    const sections = ['context', 'additions', 'flow', 'levels', 'coop', 'validation', 'next'];
    const onScroll = () => {
      const y = window.scrollY + 80;
      let cur = '';
      sections.forEach((id) => {const el = document.getElementById(id);if (el && el.offsetTop <= y) cur = id;});
      document.querySelectorAll('.nav-link').forEach((l) => l.classList.toggle('active', l.dataset.section === cur));
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    document.querySelectorAll('.nav-link').forEach((link) => {
      link.addEventListener('click', () => {
        const el = document.getElementById(link.dataset.section);
        if (el) window.scrollTo({ top: el.offsetTop - 65, behavior: 'smooth' });
      });
    });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  // scroll reveal
  useEffect(() => {
    const els = document.querySelectorAll('.reveal');
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((e) => {if (e.isIntersecting) e.target.classList.add('visible');});
    }, { threshold: 0.07 });
    els.forEach((el) => obs.observe(el));
    return () => obs.disconnect();
  }, []);

  // accent
  useEffect(() => {
    document.documentElement.style.setProperty('--accent', tweaks.accentColor);
    document.documentElement.style.setProperty('--accent2', tweaks.accentColor2);
  }, [tweaks.accentColor, tweaks.accentColor2]);

  const trailerUrl = tweaks.trailerUrl || "https://player.vimeo.com/video/1189614771?context=Vimeo%5CController%5CApi%5CResources%5CVideoController.&h=ba9a0b6152&s=c07487c8fecf29f2ba0acf1ef9c6c86e3ec65bf4_1778882686";

  return (
    <>
          {/* ── HERO ── */}
          <section style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column', justifyContent: 'center', padding: '90px 0 80px', position: 'relative', overflow: 'hidden' }}>
            <div className="hero-bg">
              <div className="hero-orb hero-orb-1" />
              <div className="hero-orb hero-orb-2" />
              {tweaks.showGridBg && <div className="hero-grid-bg" />}
            </div>
            <div className="hero-content shell">
              <div className="eyebrow"><span className="eyebrow-dot" />Internal Prototype Milestone Update</div>
              <div className="hero-layout">
                <div className="hero-left">
                  <h1 className="hero-title">
                    Proto&shy;type 3<br />
                    <span className="grad">Interactive</span><br />
                    <span className="dim">Brief</span>
                  </h1>
                  <p className="hero-lead">
                    Prototype 3 demonstrates the general direction of Variants — new mechanics, co-op progress, WIP systems, and mission structure that better represent the future gameplay experience.
                  </p>
                  <div className="hero-ctas">
                    <button className="btn btn-primary" onClick={() => {const el = document.getElementById('context');if (el) window.scrollTo({ top: el.offsetTop - 65, behavior: 'smooth' });}}>
                      Read Brief →
                    </button>
                    <button className="btn btn-ghost" onClick={() => {const el = document.getElementById('flow');if (el) window.scrollTo({ top: el.offsetTop - 65, behavior: 'smooth' });}}>
                      Objective Flow
                    </button>
                  </div>
                  <div className="hero-stats">
                    <div className="stat-cell"><div className="stat-label">Milestone</div><div className="stat-value">Prototype 3</div></div>
                    <div className="stat-cell"><div className="stat-label">Next Up</div><div className="stat-value">PoC Prototype</div></div>
                    <div className="stat-cell"><div className="stat-label">Team Growth</div><div className="stat-value">+3 Hires</div></div>
                    <div className="stat-cell"><div className="stat-label">Review</div><div className="stat-value">Stakeholder</div></div>
                  </div>
                </div>
                <div>
                  <div style={{ marginBottom: 12 }}>
                    <div style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--faint)', textTransform: 'uppercase', letterSpacing: '0.1em', marginBottom: 8 }}>Prototype 3 Trailer</div>
                    <VideoFrame src={trailerUrl} />
                    <div style={{ marginTop: 10, fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--faint)' }}>
                      Vimeo trailer embed
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </section>

          <div className="divider" />

          {/* ── CONTEXT ── */}
          <section id="context" className="section shell">
            <div className="section-head reveal">
              <div className="section-label">Milestone Timeline</div>
              <h2 className="section-title">Context Since Prototype 2</h2>
              <p className="section-sub">Prototype 2 was shown at the beginning of March. Since then, the team expanded and the project moved into a more focused gameplay direction.</p>
            </div>
            <div className="reveal reveal-delay-1"><Timeline /></div>
            <div className="team-grid reveal reveal-delay-2">
              <div className="team-card">
                <div className="team-tag tag-team">LEVELS</div>
                <h3>Level Designer</h3>
                <p>Joined roughly one month ago to support layouts, level flow, and future world variety. Responsible for LU/VO #2403.</p>
              </div>
              <div className="team-card">
                <div className="team-tag tag-gameplay" style={{ color: "rgb(173, 115, 231)" }}>Gameplay</div>
                <h3>Senior 3Cs / Combat Designer</h3>
                <p>Joined roughly one month ago to define moment-to-moment gameplay identity, including dash, scan, and combat tuning.</p>
              </div>
              <div className="team-card">
                <div className="team-tag tag-network">Network</div>
                <h3>Senior UE Multiplayer Engineer</h3>
                <p>Joined roughly three weeks ago to stabilise and improve multiplayer foundations and resolve replication issues.</p>
              </div>
            </div>
          </section>

          <div className="divider" />

          {/* ── ADDITIONS ── */}
          <section id="additions" className="section shell">
            <div className="section-head reveal">
              <div className="section-label">Since Prototype 2</div>
              <h2 className="section-title">Major Additions</h2>
              <p className="section-sub">Every new mechanic, system, and feature added in Prototype 3 — with screenshots and expanded detail on what each one is doing and why.</p>
            </div>
            <div className="reveal reveal-delay-1">
              <Accordion items={ADDITIONS} />
            </div>
          </section>

          <div className="divider" />

          {/* ── FLOW ── */}
          <section id="flow" className="section shell">
            <div className="section-head reveal">
              <div className="section-label">Mission Loop</div>
              <h2 className="section-title">New Objective Flow</h2>
              <p className="section-sub">Prototype 3 moves toward a more thematic mission loop built around scanning, pruning, containment, and extraction. Step through each phase below.</p>
            </div>
            <div className="reveal reveal-delay-1">
              <ObjectiveFlow />
            </div>
          </section>

          <div className="divider" />

          {/* ── LEVELS ── */}
          <section id="levels" className="section shell">
            <div className="section-head reveal">
              <div className="section-label">Environments</div>
              <h2 className="section-title">Levels & Environments</h2>
              <p className="section-sub">Prototype 3 adds a new handmade level, sub-level technology, a dedicated test space, and base updates.</p>
            </div>
            <div className="level-grid reveal reveal-delay-1">
              <div className="level-card">
                <div style={{ padding: '0 0 0 0' }}>
                  <ImgFrame label="LU/VO #2403 — New Level" sublabel="Replace with level overview screenshot" style={{ borderRadius: 0 }} />
                </div>
                <div className="level-card-body">
                  <div className="team-tag tag-new">New Level</div>
                  <h3>LU/VO #2403</h3>
                  <p>Third playable level, fully handmade by the new Level Designer. Built around an active Incursion with a Rift and multiple POIs containing foreign objects to prune. Sub-levels are used to load and unload unstable high-DE zones around foreign objects.</p>
                </div>
              </div>
              <div className="level-card">
                <ImgFrame label="Variants Gym — Test Level" sublabel="Replace with Gym level screenshot" style={{ borderRadius: 0 }} />
                <div className="level-card-body">
                  <div className="team-tag tag-testing">Testing</div>
                  <h3>Variants Gym</h3>
                  <p>Controlled test level with reference metrics for testing new mechanics and features in a repeatable, consistent environment. Essential for tuning dash, scan range, enemy behaviour, and pruning feel without level-specific variables.</p>
                </div>
              </div>
              <div className="level-card">
                <ImgFrame label="UE Sub-levels" sublabel="Replace with sub-level loading screenshot" style={{ borderRadius: 0 }} />
                <div className="level-card-body">
                  <div className="team-tag tag-tech">Tech</div>
                  <h3>UE Sub-levels</h3>
                  <p>Implemented in LU/VO #2403 to load and unload sections dynamically. Demonstrated as unstable high-DE zones around foreign objects — the level visually changes as players interact with the environment.</p>
                </div>
              </div>
              <div className="level-card">
                <ImgFrame label="Bureau Office" sublabel="Replace with Bureau base screenshot" style={{ borderRadius: 0 }} />
                <div className="level-card-body">
                  <div className="team-tag tag-hub">Hub</div>
                  <h3>Bureau Office Updates</h3>
                  <p>Minor visual updates to support the evolving base-to-field contrast. The Bureau should feel safe, ordered, and civilian compared to the tension of the field. Co-op group travel now starts here, with the host initiating departure through the portal.</p>
                </div>
              </div>
            </div>
          </section>

          <div className="divider" />

          {/* ── CO-OP ── */}
          <section id="coop" className="section shell">
            <div className="section-head reveal">
              <div className="section-label">Multiplayer</div>
              <h2 className="section-title">Co-op & Multiplayer Progress</h2>
              <p className="section-sub">The prototype continues improving the multiplayer foundation while new mechanics are added and replicated.</p>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14, marginBottom: 20 }} className="reveal reveal-delay-1">
              <div className="team-card">
                <div style={{ marginBottom: 16 }}>
                  <ImgFrame label="Group Travel — Bureau Portal" sublabel="Replace with co-op portal screenshot" />
                </div>
                <div className="team-tag tag-coop">Group Travel</div>
                <h3>Bureau → Mission</h3>
                <p>The full party can gather in the Bureau office and travel to a level together through a portal initiated by the host. This is a significant step toward the fantasy of a co-op agency deploying together on missions.</p>
              </div>
              <div className="team-card">
                <div style={{ marginBottom: 16 }}>
                  <ImgFrame label="Replication — Co-op Features" sublabel="Replace with 2-player co-op gameplay screenshot" />
                </div>
                <div className="team-tag tag-rep">Replication</div>
                <h3>Feature Support</h3>
                <p>Various replication issues were solved with the new Multiplayer Engineer and most new features — dash, scan, pruning, DE — were fully replicated for two-player use. A solid foundation for continued multiplayer development.</p>
              </div>
            </div>
            <div className="reveal reveal-delay-2">
              <h3 style={{ fontFamily: 'var(--font-heading)', fontSize: 24, fontWeight: 600, marginBottom: 6, marginTop: 32 }}>Web Prototypes</h3>
              <p style={{ fontSize: 15, color: 'var(--muted)', lineHeight: 1.7, marginBottom: 20, maxWidth: 720 }}>
                Designers are also using modern AI tools and interactive <strong style={{ color: 'var(--accent)' }}>web prototypes</strong> to test and explore mechanics outside of Unreal Engine. This allows faster experimentation — weeks rather than months — and helps validate ideas earlier before committing to full in-engine implementation. Below are four examples currently being explored.
              </p>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
                <div className="team-card">
                  <div style={{ marginBottom: 16 }}>
                    <ImgFrame label="Web Prototype 01" sublabel="Replace with clip — pass video='uploads/clip01.mp4'" />
                  </div>
                  <div className="team-tag tag-gameplay">Mechanic Test</div>
                  <h3>Prototype 01</h3>
                  <p>Short description of what this web prototype is exploring — the mechanic, the question being tested, and what was learned.</p>
                </div>
                <div className="team-card">
                  <div style={{ marginBottom: 16 }}>
                    <ImgFrame label="Web Prototype 02" sublabel="Replace with clip — pass video='uploads/clip02.mp4'" />
                  </div>
                  <div className="team-tag tag-coop">Mechanic Test</div>
                  <h3>Prototype 02</h3>
                  <p>Short description of what this web prototype is exploring — the mechanic, the question being tested, and what was learned.</p>
                </div>
                <div className="team-card">
                  <div style={{ marginBottom: 16 }}>
                    <ImgFrame label="Web Prototype 03" sublabel="Replace with clip — pass video='uploads/clip03.mp4'" />
                  </div>
                  <div className="team-tag tag-rep">Mechanic Test</div>
                  <h3>Prototype 03</h3>
                  <p>Short description of what this web prototype is exploring — the mechanic, the question being tested, and what was learned.</p>
                </div>
                <div className="team-card">
                  <div style={{ marginBottom: 16 }}>
                    <ImgFrame label="Web Prototype 04" sublabel="Replace with clip — pass video='uploads/clip04.mp4'" />
                  </div>
                  <div className="team-tag tag-tech">Mechanic Test</div>
                  <h3>Prototype 04</h3>
                  <p>Short description of what this web prototype is exploring — the mechanic, the question being tested, and what was learned.</p>
                </div>
              </div>
            </div>
          </section>

          <div className="divider" />

          {/* ── VALIDATION ── */}
          <section id="validation" className="section shell">
            <div className="section-head reveal">
              <div className="section-label">Goals</div>
              <h2 className="section-title">What Prototype 3 Is Validating</h2>
              <p className="section-sub">This milestone is about direction, not final polish. Six key questions the prototype is designed to answer.</p>
            </div>
            <div className="validation-grid">
              {VALIDATION_ITEMS.map((item, i) =>
          <div key={i} className={`val-card reveal reveal-delay-${i % 3 + 1}`}>
                  <span className="val-number">{item.num}</span>
                  <h3>{item.title}</h3>
                  <p>{item.desc}</p>
                </div>
          )}
            </div>
          </section>

          <div className="divider" />

          {/* ── NEXT ── */}
          <section id="next" className="section shell">
            <div className="section-head reveal">
              <div className="section-label">Roadmap</div>
              <h2 className="section-title">Next Step</h2>
            </div>
            <div className="next-banner reveal reveal-delay-1">
              <h3>PoC Prototype</h3>
              <p>
                The Proof of Concept prototype should connect the current mechanics and systems into one stronger gameplay loop and validate Variants at a larger concept scale: scanning, pruning, DE, anomalies, co-op, mission flow, combat pressure, and extraction — all working together as one coherent experience.
              </p>
              <button className="btn btn-primary" onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}>↑ Back to top</button>
            </div>
          </section>

          <div className="divider" />

          <footer>
            <div className="shell footer-inner">
              <span className="footer-text">Variants — Prototype 3 Interactive Brief</span>
              <span className="footer-text">Internal stakeholder review · May 2026</span>
            </div>
          </footer>

          <TweaksPanel>
            <TweakSection label="Colors" />
            <TweakColor label="Primary accent" value={tweaks.accentColor} onChange={(v) => setTweak('accentColor', v)} />
            <TweakColor label="Secondary accent" value={tweaks.accentColor2} onChange={(v) => setTweak('accentColor2', v)} />
            <TweakSection label="Content" />
            <TweakText label="Trailer URL" value={tweaks.trailerUrl} onChange={(v) => setTweak('trailerUrl', v)} />
            <TweakSection label="Background" />
            <TweakToggle label="Show hero grid" value={tweaks.showGridBg} onChange={(v) => setTweak('showGridBg', v)} />
          </TweaksPanel>
        </>);

}

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