diff --git a/src/data/content.js b/src/data/content.js
index a9e379d..69297f8 100644
--- a/src/data/content.js
+++ b/src/data/content.js
@@ -28,6 +28,7 @@ import { CatHttpCode } from "../pages/activities/CatHttpCode";
import FlappyBird from "../pages/games/FlappyBird";
import RandomIdentity from "../pages/activities/RandomIdentity";
import word_scramble_icon from "../assets/games/WordScramble/word_scramble.png";
+import DontClickBomb from "../pages/games/DontClickBomb";
import TypingTest from "../pages/games/TypingTest";
export const activities = [
@@ -182,6 +183,11 @@ export const games = [
element: ,
},
{
+ title: "Don't Click the Bomb",
+ description: "Click everything except ๐ฃ. Gets harder every round.",
+ icon: "https://img.freepik.com/free-vector/round-black-bomb-realistic-style_52683-15190.jpg?semt=ais_hybrid&w=740&q=80",
+ urlTerm: "dont-click-the-bomb",
+ element: ,
title: "Typing Test",
description: "Test your typing skills",
icon :"https://typingmentor.com/_next/image/?url=https%3A%2F%2Fcdn.sanity.io%2Fimages%2Fbs3wcomf%2Fproduction%2F9f626374aa1c388a6418a077990771aff53d054f-1200x800.jpg%3Frect%3D0%2C35%2C1200%2C731%26w%3D808%26h%3D492%26fit%3Dcrop%26auto%3Dformat&w=1920&q=75",
diff --git a/src/pages/games/DontClickBomb.js b/src/pages/games/DontClickBomb.js
new file mode 100644
index 0000000..1336f74
--- /dev/null
+++ b/src/pages/games/DontClickBomb.js
@@ -0,0 +1,134 @@
+import React, { useEffect, useMemo, useState } from "react";
+import "../../styles/pages/games/DontClickBomb.css";
+
+const SAFE_EMOJIS = ["๐", "๐", "๐บ", "๐ฆ", "๐ถ", "๐ป", "๐", "๐ฉ", "๐", "๐ธ", "โญ", "๐"];
+
+export default function DontClickBomb() {
+ const [level, setLevel] = useState(1);
+ const [score, setScore] = useState(0);
+ const [gameOver, setGameOver] = useState(false);
+ const [timeLeft, setTimeLeft] = useState(2.5); // seconds per round, will shrink
+ const [tick, setTick] = useState(0); // to re-gen grid when timer refreshes
+
+ // grid scales with level
+ const gridSize = Math.min(3 + Math.floor(level / 1.3), 8); // 3..8
+ const totalCells = gridSize * gridSize;
+
+ // number of bombs grows
+ const numBombs = Math.min(Math.floor(level * 0.7) + 1, 10);
+
+
+ // choose unique bomb positions
+ const bombIndexes = useMemo(() => {
+ const set = new Set();
+ while (set.size < numBombs) {
+ set.add(Math.floor(Math.random() * totalCells));
+ }
+ return Array.from(set);
+ }, [level, totalCells, numBombs, tick]);
+
+ // timer logic: every level you get slightly less time
+ useEffect(() => {
+ if (gameOver) return;
+ setTimeLeft(Math.max(0.9, 2.6 - level * 0.1)); // min ~0.9s
+ }, [level, gameOver]);
+
+ useEffect(() => {
+ if (gameOver) return;
+ const interval = setInterval(() => {
+ setTimeLeft((t) => {
+ if (t <= 0.1) {
+ // time up -> lose
+ setGameOver(true);
+ return 0;
+ }
+ return Number((t - 0.1).toFixed(1));
+ });
+ }, 100);
+ return () => clearInterval(interval);
+ }, [gameOver]);
+
+ function handleCellClick(idx, isBomb) {
+ if (gameOver) return;
+ if (isBomb) {
+ setGameOver(true);
+ return;
+ }
+ // safe
+ setScore((s) => s + 10 + level * 2);
+ setLevel((l) => l + 1);
+ // refresh grid
+ setTick((t) => t + 1);
+ }
+
+ function handleRestart() {
+ setLevel(1);
+ setScore(0);
+ setGameOver(false);
+ setTimeLeft(2.5);
+ setTick((t) => t + 1);
+ }
+
+ return (
+
+
+
Don't Click the Bomb ๐ฃ
+
Click any safe emoji before the timer runs out. More levels = more bombs.
+
+
+
+
+ Level
+ {level}
+
+
+ Score
+ {score}
+
+
+ โฑ {timeLeft.toFixed(1)}s
+
+ {gameOver && (
+
๐ฅ Boom! Too slow / bomb clicked.
+ )}
+
+
+
+ {Array.from({ length: totalCells }).map((_, idx) => {
+ const isBomb = bombIndexes.includes(idx);
+ const emoji = isBomb
+ ? "๐ฃ"
+ : SAFE_EMOJIS[Math.floor(Math.random() * SAFE_EMOJIS.length)];
+
+ return (
+
+ );
+ })}
+
+
+
+
+
+
+
+ From level 4: 2 bombs ๐งจ. From level 8: 3 bombs ๐. Timer also gets shorter.
+
+
+ );
+}
diff --git a/src/styles/pages/games/DontClickBomb.css b/src/styles/pages/games/DontClickBomb.css
new file mode 100644
index 0000000..dad509c
--- /dev/null
+++ b/src/styles/pages/games/DontClickBomb.css
@@ -0,0 +1,173 @@
+.bomb-wrapper {
+ max-width: 700px;
+ margin: 2rem auto;
+ background: #ffffff;
+ border: 1px solid #e2e8f0;
+ border-radius: 16px;
+ padding: 1.6rem 1.4rem 1.4rem;
+ box-shadow: 0 10px 25px rgba(15, 23, 42, 0.05);
+ text-align: center;
+ font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+}
+
+.bomb-header h2 {
+ font-size: 1.6rem;
+ font-weight: 700;
+ color: #0f172a;
+ margin-bottom: 0.4rem;
+}
+
+.bomb-header p {
+ color: #64748b;
+ font-size: 0.9rem;
+ margin-bottom: 1.1rem;
+}
+
+.bomb-stats {
+ display: flex;
+ justify-content: center;
+ gap: 1rem;
+ flex-wrap: wrap;
+ margin-bottom: 1rem;
+ align-items: center;
+}
+
+.bomb-stat {
+ background: #f8fafc;
+ border: 1px solid #e2e8f0;
+ border-radius: 10px;
+ padding: 0.5rem 1.1rem;
+ min-width: 90px;
+}
+
+.bomb-stat .label {
+ font-size: 0.65rem;
+ text-transform: uppercase;
+ color: #94a3b8;
+ letter-spacing: 0.04em;
+}
+
+.bomb-stat .value {
+ font-size: 1.1rem;
+ font-weight: 600;
+ color: #0f172a;
+}
+
+.bomb-over {
+ background: #fee2e2;
+ color: #b91c1c;
+ padding: 0.35rem 0.7rem;
+ border-radius: 999px;
+ font-weight: 500;
+}
+
+.bomb-grid {
+ display: grid;
+ gap: 0.6rem;
+ margin-top: 1.1rem;
+}
+
+.bomb-cell {
+ background: #ffffff;
+ border: 1px solid #e2e8f0;
+ border-radius: 12px;
+ height: 60px;
+ font-size: 1.7rem;
+ cursor: pointer;
+ transition: transform 0.1s ease, box-shadow 0.1s ease;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.bomb-cell.is-safe:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 6px 15px rgba(37, 99, 235, 0.12);
+}
+
+.bomb-cell:disabled {
+ cursor: not-allowed;
+ opacity: 0.9;
+}
+
+/* bomb click animation */
+.explode {
+ animation: bombBoom 0.4s ease forwards;
+}
+
+@keyframes bombBoom {
+ 0% {
+ transform: scale(1);
+ background: #fee2e2;
+ }
+ 50% {
+ transform: scale(1.3);
+ background: #fca5a5;
+ }
+ 100% {
+ transform: scale(0.9);
+ background: #fee2e2;
+ }
+}
+
+.bomb-actions {
+ margin-top: 1.2rem;
+}
+
+.bomb-btn {
+ background: #2563eb;
+ color: #ffffff;
+ border: none;
+ border-radius: 10px;
+ padding: 0.5rem 1.2rem;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background 0.15s ease;
+}
+
+.bomb-btn:hover {
+ background: #1d4ed8;
+}
+
+.bomb-hint {
+ margin-top: 0.85rem;
+ color: #94a3b8;
+ font-size: 0.78rem;
+}
+
+@media (max-width: 520px) {
+ .bomb-grid {
+ grid-template-columns: repeat(auto-fit, minmax(55px, 1fr)) !important;
+ }
+ .bomb-cell {
+ height: 55px;
+ font-size: 1.4rem;
+ }
+}
+.bomb-wrapper.hard .bomb-grid {
+ margin-top: 1rem;
+}
+
+.bomb-timer {
+ background: #eff6ff;
+ border: 1px solid #bfdbfe;
+ padding: 0.35rem 0.8rem;
+ border-radius: 999px;
+ font-weight: 500;
+ color: #1d4ed8;
+ display: flex;
+ align-items: center;
+ gap: 4px;
+}
+
+.bomb-timer.low {
+ background: #fee2e2;
+ border-color: #fecaca;
+ color: #b91c1c;
+}
+
+@media (max-width: 520px) {
+ .bomb-wrapper.hard .bomb-grid {
+ grid-template-columns: repeat(auto-fit, minmax(45px, 1fr)) !important;
+ }
+}