<!DOCTYPE html>
<html lang=“de“>
<head>
<meta charset=“UTF-8″>
<title>Lustiges Memory-Spiel – 10 Emoji-Paare</title>
<meta name=“viewport“ content=“width=device-width, initial-scale=1.0″>
<style>
body {
background: linear-gradient(135deg, #232946 0%, #5f6caf 100%);
font-family: ‚Segoe UI‘, ‚Arial‘, sans-serif;
margin: 0;
min-height: 100vh;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
}
header {
margin-top: 32px;
margin-bottom: 16px;
text-align: center;
}
h1 {
font-size: 2.2rem;
letter-spacing: 1px;
margin-bottom: 8px;
}
.controls {
display: flex;
gap: 24px;
align-items: center;
justify-content: center;
margin-bottom: 24px;
}
.moves {
font-size: 1.1rem;
background: rgba(35,41,70,0.7);
padding: 6px 18px;
border-radius: 18px;
box-shadow: 0 1px 4px rgba(0,0,0,0.08);
}
.restart-btn {
background: linear-gradient(90deg, #ffb800 0%, #ff6f3c 100%);
color: #232946;
border: none;
border-radius: 18px;
padding: 8px 22px;
font-size: 1rem;
font-weight: bold;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0,0,0,0.10);
transition: background 0.2s, transform 0.1s;
}
.restart-btn:hover {
background: linear-gradient(90deg, #ff6f3c 0%, #ffb800 100%);
transform: scale(1.05);
}
.game-board {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
gap: 18px;
max-width: 480px;
margin: 0 auto 32px auto;
width: 100%;
padding: 0 8px;
}
@media (max-width: 600px) {
.game-board {
max-width: 340px;
gap: 12px;
}
}
.card {
perspective: 800px;
width: 100%;
aspect-ratio: 1/1.3;
cursor: pointer;
position: relative;
user-select: none;
outline: none;
}
.card-inner {
width: 100%;
height: 100%;
transition: transform 0.5s cubic-bezier(.4,2,.6,1);
transform-style: preserve-3d;
position: relative;
}
.card.flipped .card-inner,
.card.matched .card-inner {
transform: rotateY(180deg);
}
.card-front, .card-back {
position: absolute;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2.5rem;
font-weight: bold;
box-shadow: 0 2px 12px rgba(0,0,0,0.13);
transition: box-shadow 0.2s;
}
.card-front {
background: #fff;
color: #232946;
transform: rotateY(180deg);
font-size: 2.7rem;
letter-spacing: 1px;
justify-content: center;
align-items: center;
display: flex;
}
.card-back {
background: #232946;
background-image:
repeating-linear-gradient(135deg, #fff2 0 2px, transparent 2px 20px),
radial-gradient(circle at 70% 30%, #ffe066 0 2px, transparent 2px 100%),
radial-gradient(circle at 30% 70%, #ffb800 0 2px, transparent 2px 100%);
color: #ffe066;
font-size: 2.1rem;
display: flex;
align-items: center;
justify-content: center;
transition: box-shadow 0.2s;
}
.card:not(.flipped):not(.matched):hover .card-back {
box-shadow: 0 0 0 4px #ffe06655, 0 2px 12px rgba(0,0,0,0.18);
filter: brightness(1.08);
}
.card.matched .card-inner {
box-shadow: 0 0 16px 4px #00e67688, 0 2px 12px rgba(0,0,0,0.18);
}
.card.matched .card-front {
border: 3px solid gold;
box-shadow: 0 0 16px 4px #ffe06688;
filter: brightness(1.13);
animation: matched-glow 1.2s infinite alternate;
}
@keyframes matched-glow {
from { box-shadow: 0 0 16px 4px #ffe06688; }
to { box-shadow: 0 0 32px 8px #ffe066cc; }
}
/* Overlay for win message */
.overlay {
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(35,41,70,0.92);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 100;
color: #ffe066;
font-size: 2.1rem;
letter-spacing: 1px;
opacity: 0;
pointer-events: none;
transition: opacity 0.4s;
}
.overlay.show {
opacity: 1;
pointer-events: all;
}
.overlay .congrats {
font-size: 2.5rem;
margin-bottom: 18px;
font-weight: bold;
text-shadow: 0 2px 12px #232946;
}
.overlay .moves {
color: #fff;
font-size: 1.2rem;
margin-bottom: 24px;
}
.overlay .restart-btn {
font-size: 1.1rem;
padding: 10px 28px;
}
/* Remove tap highlight on mobile */
.card, .restart-btn {
-webkit-tap-highlight-color: transparent;
}
</style>
</head>
<body>
<header>
<h1>🎲 Lustiges Memory-Spiel</h1>
<div class=“controls“>
<span class=“moves“>Züge: <span id=“moveCounter“>0</span></span>
<button class=“restart-btn“ id=“restartBtn“>🔄 Neues Spiel</button>
</div>
</header>
<main>
<div class=“game-board“ id=“gameBoard“></div>
</main>
<div class=“overlay“ id=“winOverlay“>
<div class=“congrats“>🎉 Glückwunsch! 🎉</div>
<div class=“moves“>Du hast das Spiel in <span id=“finalMoves“>0</span> Zügen geschafft!</div>
<button class=“restart-btn“ id=“overlayRestartBtn“>Nochmal spielen</button>
</div>
<script>
// Emoji Motive
const EMOJIS = [‚🤡‘,’🎃‘,’👾‘,’🦄‘,’🐸‘,’🤖‘,’👻‘,’🦊‘,’🎯‘,’🍕‘];
const PAIRS = 10;
let cards = [];
let flippedCards = [];
let matchedCount = 0;
let moves = 0;
let lockBoard = false;
const gameBoard = document.getElementById(‚gameBoard‘);
const moveCounter = document.getElementById(‚moveCounter‘);
const restartBtn = document.getElementById(‚restartBtn‘);
const winOverlay = document.getElementById(‚winOverlay‘);
const finalMoves = document.getElementById(‚finalMoves‘);
const overlayRestartBtn = document.getElementById(‚overlayRestartBtn‘);
function shuffle(array) {
for (let i = array.length – 1; i > 0; i–) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
function createCards() {
// Create 2 of each emoji, assign unique IDs
let cardData = [];
EMOJIS.forEach((emoji, idx) => {
cardData.push({emoji, id: idx + ‚a‘});
cardData.push({emoji, id: idx + ‚b‘});
});
return shuffle(cardData);
}
function renderBoard() {
gameBoard.innerHTML = “;
cards = createCards();
matchedCount = 0;
moves = 0;
flippedCards = [];
lockBoard = false;
moveCounter.textContent = ‚0‘;
cards.forEach((card, idx) => {
const cardElem = document.createElement(‚div‘);
cardElem.className = ‚card‘;
cardElem.tabIndex = 0;
cardElem.dataset.emoji = card.emoji;
cardElem.dataset.id = card.id;
cardElem.innerHTML = `
<div class=“card-inner“>
<div class=“card-front“>${card.emoji}</div>
<div class=“card-back“>⭐</div>
</div>
`;
cardElem.addEventListener(‚click‘, () => handleCardClick(cardElem));
cardElem.addEventListener(‚keydown‘, (e) => {
if (e.key === ‚Enter‘ || e.key === ‚ ‚) {
e.preventDefault();
handleCardClick(cardElem);
}
});
gameBoard.appendChild(cardElem);
});
}
function handleCardClick(cardElem) {
if (lockBoard) return;
if (cardElem.classList.contains(‚flipped‘) || cardElem.classList.contains(‚matched‘)) return;
if (flippedCards.length === 2) return;
cardElem.classList.add(‚flipped‘);
flippedCards.push(cardElem);
if (flippedCards.length === 2) {
moves++;
moveCounter.textContent = moves;
const [card1, card2] = flippedCards;
if (card1.dataset.emoji === card2.dataset.emoji) {
// Match!
setTimeout(() => {
card1.classList.add(‚matched‘);
card2.classList.add(‚matched‘);
flippedCards = [];
matchedCount++;
if (matchedCount === PAIRS) {
setTimeout(showWinOverlay, 600);
}
}, 350);
} else {
// Not a match
lockBoard = true;
setTimeout(() => {
card1.classList.remove(‚flipped‘);
card2.classList.remove(‚flipped‘);
flippedCards = [];
lockBoard = false;
}, 1000);
}
}
}
function showWinOverlay() {
finalMoves.textContent = moves;
winOverlay.classList.add(’show‘);
}
function hideWinOverlay() {
winOverlay.classList.remove(’show‘);
}
function restartGame() {
hideWinOverlay();
renderBoard();
}
// Event Listeners
restartBtn.addEventListener(‚click‘, restartGame);
overlayRestartBtn.addEventListener(‚click‘, restartGame);
// Start game on load
renderBoard();
</script>
</body>
</html>