JSFiddle - React, Tailwind, and code Playground

HTML

<div id="candyGame">
  <section id="startScreen" class="screen active start-screen">
    <p class="eyebrow">WEEKLY SMALL TALKS · CANDY HOUSE</p>
    <div class="hero-candy">🍬</div>
    <h1>Candy Label Rescue</h1>
    <p class="lead">The Cursed Piece has mixed up every label in the Candy House. Remember where each label belongs, then fix the chaos.</p>
    <div class="how-to">
      <span><b>1</b> Remember</span>
      <span><b>2</b> Watch the shuffle</span>
      <span><b>3</b> Choose YES or BUT…</span>
    </div>
    <button id="startBtn" class="main-btn">Enter the Candy House</button>
  </section>

  <section id="gameScreen" class="screen">
    <header class="game-header">
      <div>
        <p class="eyebrow">CANDY LABEL RESCUE</p>
        <h2 id="roundTitle">Level 1</h2>
      </div>
      <div class="score-box"><strong id="scoreText">0</strong><small>stars</small></div>
    </header>

    <div class="progress-track"><div id="progressFill"></div></div>
    <div id="phaseMessage" class="phase-message" aria-live="polite"></div>
    <div id="countdown" class="countdown"></div>
    <div id="candyBoard" class="candy-board"></div>

    <div id="decisionPanel" class="decision-panel hidden">
      <p id="decisionQuestion"></p>
      <div class="decision-buttons">
        <button id="yesBtn" class="yes-btn">YES</button>
        <button id="butBtn" class="but-btn">BUT…</button>
      </div>
    </div>

    <div id="feedbackPanel" class="feedback-panel hidden">
      <div id="feedbackIcon" class="feedback-icon"></div>
      <h3 id="feedbackTitle"></h3>
      <p id="feedbackText"></p>
      <button id="nextBtn" class="main-btn">Next level</button>
    </div>
  </section>

  <section id="machineScreen" class="screen machine-screen">
    <p class="eyebrow">ALL THREE LEVELS COMPLETE</p>
    <h2>Pull the Candy Machine Lever</h2>
    <p class="lead">Pull the handle downward to print your final Candy House result.</p>

    <div...

CSS

:root {
  --ink: #35222d;
  --cream: #fff3df;
  --pink: #e75f92;
  --plum: #6d336d;
  --gold: #f0b64b;
  --mint: #64ad9b;
  --red: #bd3f59;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  color: var(--ink);
  background:
    radial-gradient(circle at 15% 8%, rgba(255,255,255,.82), transparent 22%),
    radial-gradient(circle at 85% 15%, rgba(231,95,146,.18), transparent 25%),
    linear-gradient(145deg, #f9dfbc, #d9b5bc);
  font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}

button { font: inherit; }

#candyGame {
  width: min(100%, 940px);
  min-height: 100vh;
  margin: auto;
  padding: clamp(20px, 4vw, 44px);
}

.screen { display: none; animation: screenIn .35s ease; }
.screen.active { display: block; }
.hidden { display: none !important; }

@keyframes screenIn {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}

.start-screen, .machine-screen, .result-screen { max-width: 720px; margin: auto; text-align: center; }
.eyebrow { margin: 0 0 10px; color: #83536b; font-size: 12px; font-weight: 950; letter-spacing: .14em; }
h1, h2, h3 { margin: 0; font-family: Georgia, "Times New Roman", serif; line-height: 1.05; }
h1 { font-size: clamp(42px, 8vw, 72px); }
h2 { font-size: clamp(32px, 5vw, 48px); }
h3 { font-size: 28px; }
.lead { max-width: 650px; margin: 16px auto 24px; font-size: clamp(16px, 2.4vw, 20px); line-height: 1.55; }
.hero-candy { margin: 6px 0 10px; font-size: 84px; filter: drop-shadow(0 12px 10px rgba(68,37,51,.18)); animation: candyFloat 1.5s ease-in-out infinite alternate; }
@keyframes candyFloat { to { transform: translateY(-8px) rotate(5deg); } }

.how-to { display: flex; justify-content: center; gap: 10px; flex-wrap: wrap; margin: 26px 0; }
.how-to span { padding: 10px 14px; border: 1px solid rgba(53,34,45,.15); border-radius: 999px; background: rgba(255,243,223,.72); font-size: 13px;...

JavaScript

function initCandyGame() {
  const CANDIES = [
    { emoji: "💗", label: "Velvet Whisper", effect: "It tastes like berries… BUT it makes you speak only in rhymes for one minute." },
    { emoji: "🌙", label: "Fizz No. 7", effect: "It tastes fizzy… BUT it makes everything around you seem to move in slow motion." },
    { emoji: "🦇", label: "Lucky Loop", effect: "It tastes sour… BUT it makes your next little mistake feel surprisingly funny." },
    { emoji: "🎃", label: "Secret Snap", effect: "It tastes creamy… BUT it gives you one wonderfully impractical idea." },
    { emoji: "⭐", label: "Tiny Thunder", effect: "It tastes slightly salty… BUT it makes your footsteps sparkle for ten seconds." },
    { emoji: "🔮", label: "Glass Echo", effect: "It tastes like lemon… BUT it repeats the last funny sound it heard." }
  ];
  const LABEL_COLOR = "#6d336d";

  const ROUNDS = [
    { title: "Level 1 · First Mix-Up", candyIds: [0,1,2,3], shuffle: [1,0,3,2], target: 2, seconds: 3, answerSeconds: 7 },
    { title: "Level 2 · Candy Rush", candyIds: [0,1,2,3,4], shuffle: [4,2,1,3,0], target: 3, seconds: 3, answerSeconds: 7 },
    { title: "Level 3 · Total Candy Chaos", candyIds: [0,1,2,3,4,5], shuffle: [5,2,4,0,1,3], target: 4, seconds: 3, answerSeconds: 7 }
  ];

  const $ = selector => document.querySelector(selector);
  const screens = [...document.querySelectorAll(".screen")];
  let roundIndex = 0;
  let score = 0;
  let phase = "idle";
  let currentRound = null;
  let displayedLabels = [];
  let toastTimer = null;
  let decisionTimer = null;

  function showScreen(id) {
    screens.forEach(screen => screen.classList.toggle("active", screen.id === id));
    window.scrollTo({ top: 0, behavior: "smooth" });
  }

  function toast(message) {
    const el = $("#toast");
    el.textContent = message;
    el.classList.add("show");
    clearTimeout(toastTimer);
    toastTimer = setTimeout(() => el.classList.remove("show"), 1900);
  }

  function...