Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions src/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,116 @@ h1.title {
font-weight: 700;
color: var(--vault-yellow);
font-size: 1.4rem;
transition: all 0.3s ease;
}

/* Professional Timer Warning - Polished & Theme-Aware */
.score-big.timer-critical {
color: #ff3333 !important;
font-size: 2.2rem !important;
font-weight: 800 !important;
animation: timerUrgent 1.4s ease-in-out infinite;
transition: all 0.3s ease;
}

/* Light theme adjustment */
[data-theme="light"] .score-big.timer-critical {
color: #cc0000 !important;
}

@keyframes timerUrgent {
0%, 100% {
transform: scale(1);
text-shadow: 0 0 15px rgba(255, 51, 51, 0.7),
0 0 30px rgba(255, 51, 51, 0.4),
0 2px 6px rgba(0, 0, 0, 0.3);
}
50% {
transform: scale(1.08);
text-shadow: 0 0 25px rgba(255, 51, 51, 0.9),
0 0 50px rgba(255, 51, 51, 0.6),
0 3px 8px rgba(0, 0, 0, 0.4);
}
}

/* Light theme timer glow */
[data-theme="light"] .score-big.timer-critical {
text-shadow: 0 0 12px rgba(204, 0, 0, 0.6),
0 0 25px rgba(204, 0, 0, 0.3),
0 2px 4px rgba(0, 0, 0, 0.2);
}

/* Timer bar - smooth professional pulse */
.timer-bar-fill.timer-bar-critical {
background: linear-gradient(90deg, #ff1a1a, #ff4444) !important;
animation: barPulse 1.4s ease-in-out infinite;
box-shadow: 0 0 12px rgba(255, 26, 26, 0.6);
transition: all 0.3s ease;
}

/* Light theme bar */
[data-theme="light"] .timer-bar-fill.timer-bar-critical {
background: linear-gradient(90deg, #cc0000, #ff3333) !important;
box-shadow: 0 0 10px rgba(204, 0, 0, 0.5);
}

@keyframes barPulse {
0%, 100% {
box-shadow: 0 0 12px rgba(255, 26, 26, 0.6);
}
50% {
box-shadow: 0 0 20px rgba(255, 26, 26, 0.8),
0 0 35px rgba(255, 26, 26, 0.4);
}
}

/* Light theme bar pulse */
[data-theme="light"] .timer-bar-fill.timer-bar-critical {
animation: barPulseLight 1.4s ease-in-out infinite;
}

@keyframes barPulseLight {
0%, 100% {
box-shadow: 0 0 10px rgba(204, 0, 0, 0.5);
}
50% {
box-shadow: 0 0 18px rgba(204, 0, 0, 0.7),
0 0 30px rgba(204, 0, 0, 0.3);
}
}

/* Subtle screen vignette - professional urgency effect */
body.game-critical::before {
content: '';
position: fixed;
inset: 0;
pointer-events: none;
z-index: 1;
animation: screenVignette 2s ease-in-out infinite;
transition: opacity 0.3s ease;
}

@keyframes screenVignette {
0%, 100% {
box-shadow: inset 0 0 100px rgba(255, 0, 0, 0.12);
}
50% {
box-shadow: inset 0 0 140px rgba(255, 0, 0, 0.18);
}
}

/* Light theme vignette - more subtle */
[data-theme="light"] body.game-critical::before {
animation: screenVignetteLight 2s ease-in-out infinite;
}

@keyframes screenVignetteLight {
0%, 100% {
box-shadow: inset 0 0 120px rgba(204, 0, 0, 0.08);
}
50% {
box-shadow: inset 0 0 160px rgba(204, 0, 0, 0.12);
}
}

.stars {
Expand Down
22 changes: 20 additions & 2 deletions src/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,26 @@
timeEl.textContent = formatTime(Math.floor(timeLeft / 60), timeLeft % 60);
const pct = Math.max(0, (timeLeft / timeTotal) * 100);
timerBarFill.style.width = pct + '%';

// Game-style urgent warning at 10 seconds
if (timeLeft === 10) {
alert("Hurry up! Only 10 seconds left!");
playTone(800, 0.15); // warning sound
timeEl.classList.add('timer-critical');
timerBarFill.classList.add('timer-bar-critical');
document.body.classList.add('game-critical');
}
}, 1000);
}
function stopTimer() { if (timerId) { clearInterval(timerId); timerId = null } }
function stopTimer() {
if (timerId) {
clearInterval(timerId);
timerId = null;
// Remove critical state when timer stops
timeEl.classList.remove('timer-critical');
timerBarFill.classList.remove('timer-bar-critical');
document.body.classList.remove('game-critical');
}
}
function resetTimer() {
stopTimer();
pairCount = Math.floor(difficulties[selectedDifficulty].tiles / 2);
Expand All @@ -189,6 +203,10 @@
timeLeft = timeTotal;
timeEl.textContent = formatTime(Math.floor(timeLeft / 60), timeLeft % 60);
timerBarFill.style.width = '100%';
// Remove all critical classes
timeEl.classList.remove('timer-critical');
timerBarFill.classList.remove('timer-bar-critical');
document.body.classList.remove('game-critical');
}

// audio helpers (small tones using WebAudio)
Expand Down