diff options
| author | Yuval Adam <_@yuv.al> | 2025-03-05 12:21:25 +0100 |
|---|---|---|
| committer | Yuval Adam <_@yuv.al> | 2025-03-05 12:21:25 +0100 |
| commit | 5bf781f3ac381744fbec035f938d69a201f75fa4 (patch) | |
| tree | 2ec82a90ce2cd1c279d77bdd6ca83b256ac4856a | |
| parent | c6612a8b6dde5a5a9776d424ed33f5ca685699c6 (diff) | |
Replace all impl with vite
| -rw-r--r-- | .gitignore (renamed from morsehero/.gitignore) | 0 | ||||
| -rw-r--r-- | README.md (renamed from morsehero/README.md) | 0 | ||||
| -rw-r--r-- | _redirects | 1 | ||||
| -rw-r--r-- | base.css | 183 | ||||
| -rw-r--r-- | chart/index.html | 282 | ||||
| -rw-r--r-- | eslint.config.js (renamed from morsehero/eslint.config.js) | 0 | ||||
| -rw-r--r-- | index.html | 362 | ||||
| -rw-r--r-- | morsehero/index.html | 33 | ||||
| -rw-r--r-- | morsehero/public/ico/apple-touch-icon.png | bin | 1750 -> 0 bytes | |||
| -rw-r--r-- | morsehero/public/ico/favicon.ico | bin | 5238 -> 0 bytes | |||
| -rw-r--r-- | morsehero/public/ico/icon-192-maskable.png | bin | 1632 -> 0 bytes | |||
| -rw-r--r-- | morsehero/public/ico/icon-192.png | bin | 6033 -> 0 bytes | |||
| -rw-r--r-- | morsehero/public/ico/icon-512-maskable.png | bin | 7621 -> 0 bytes | |||
| -rw-r--r-- | morsehero/public/ico/icon-512.png | bin | 20242 -> 0 bytes | |||
| -rw-r--r-- | morsehero/src/index.css | 68 | ||||
| -rw-r--r-- | morsehero/src/pages/chart/styles.css | 132 | ||||
| -rw-r--r-- | package-lock.json (renamed from morsehero/package-lock.json) | 0 | ||||
| -rw-r--r-- | package.json (renamed from morsehero/package.json) | 0 | ||||
| -rw-r--r-- | public/ico/apple-touch-icon.png (renamed from ico/apple-touch-icon.png) | bin | 1750 -> 1750 bytes | |||
| -rw-r--r-- | public/ico/favicon.ico (renamed from ico/favicon.ico) | bin | 5238 -> 5238 bytes | |||
| -rw-r--r-- | public/ico/icon-192-maskable.png (renamed from ico/icon-192-maskable.png) | bin | 1632 -> 1632 bytes | |||
| -rw-r--r-- | public/ico/icon-192.png (renamed from ico/icon-192.png) | bin | 6033 -> 6033 bytes | |||
| -rw-r--r-- | public/ico/icon-512-maskable.png (renamed from ico/icon-512-maskable.png) | bin | 7621 -> 7621 bytes | |||
| -rw-r--r-- | public/ico/icon-512.png (renamed from ico/icon-512.png) | bin | 20242 -> 20242 bytes | |||
| -rw-r--r-- | public/site.webmanifest (renamed from morsehero/public/site.webmanifest) | 0 | ||||
| -rw-r--r-- | public/vite.svg (renamed from morsehero/public/vite.svg) | 0 | ||||
| -rw-r--r-- | site.webmanifest | 31 | ||||
| -rw-r--r-- | src/App.css (renamed from morsehero/src/App.css) | 0 | ||||
| -rw-r--r-- | src/App.tsx (renamed from morsehero/src/App.tsx) | 0 | ||||
| -rw-r--r-- | src/assets/react.svg (renamed from morsehero/src/assets/react.svg) | 0 | ||||
| -rw-r--r-- | src/base.css (renamed from morsehero/src/base.css) | 0 | ||||
| -rw-r--r-- | src/index.css | 0 | ||||
| -rw-r--r-- | src/main.tsx (renamed from morsehero/src/main.tsx) | 0 | ||||
| -rw-r--r-- | src/pages/HomePage.tsx (renamed from morsehero/src/pages/HomePage.tsx) | 0 | ||||
| -rw-r--r-- | src/pages/chart/ChartPage.tsx (renamed from morsehero/src/pages/chart/ChartPage.tsx) | 0 | ||||
| -rw-r--r-- | src/pages/chart/styles.css (renamed from chart/styles.css) | 0 | ||||
| -rw-r--r-- | src/styles.css (renamed from morsehero/src/styles.css) | 0 | ||||
| -rw-r--r-- | src/vite-env.d.ts (renamed from morsehero/src/vite-env.d.ts) | 0 | ||||
| -rw-r--r-- | styles.css | 605 | ||||
| -rw-r--r-- | tsconfig.app.json (renamed from morsehero/tsconfig.app.json) | 0 | ||||
| -rw-r--r-- | tsconfig.json (renamed from morsehero/tsconfig.json) | 0 | ||||
| -rw-r--r-- | tsconfig.node.json (renamed from morsehero/tsconfig.node.json) | 0 | ||||
| -rw-r--r-- | vite.config.ts (renamed from morsehero/vite.config.ts) | 0 |
43 files changed, 25 insertions, 1672 deletions
diff --git a/morsehero/.gitignore b/.gitignore index a547bf3..a547bf3 100644 --- a/morsehero/.gitignore +++ b/.gitignore diff --git a/morsehero/README.md b/README.md index 40ede56..40ede56 100644 --- a/morsehero/README.md +++ b/README.md diff --git a/_redirects b/_redirects deleted file mode 100644 index 232f1e7..0000000 --- a/_redirects +++ /dev/null @@ -1 +0,0 @@ -https://www.morsehero.com/* https://morsehero.com/:splat 301!
\ No newline at end of file diff --git a/base.css b/base.css deleted file mode 100644 index dc8d1f0..0000000 --- a/base.css +++ /dev/null @@ -1,183 +0,0 @@ -/* Morse Hero Base Styles */ -:root { - --primary-color: #3498db; - --primary-dark: #2980b9; - --secondary-color: #f39c12; - --secondary-dark: #e67e22; - --accent-color: #e74c3c; - --accent-dark: #c0392b; - --success-color: #2ecc71; - --success-dark: #27ae60; - --bg-dark: #2c3e50; - --bg-darker: #1a2530; - --bg-light: #34495e; - --text-light: #ecf0f1; - --text-dim: rgba(255, 255, 255, 0.7); - --border-radius-sm: 12px; - --border-radius-md: 20px; - --border-radius-lg: 30px; - --shadow-sm: 0 4px 6px rgba(0, 0, 0, 0.1); - --shadow-md: 0 10px 20px rgba(0, 0, 0, 0.15); - --shadow-lg: 0 15px 30px rgba(0, 0, 0, 0.2); - --transition-fast: 0.2s ease; - --transition-normal: 0.3s ease; -} - -* { - box-sizing: border-box; - margin: 0; - padding: 0; -} - -body { - font-family: 'Poppins', 'Fredoka', sans-serif; - margin: 0; - padding: 0; - background: radial-gradient(ellipse at top, var(--bg-dark) 0%, var(--bg-darker) 100%); - color: var(--text-light); - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: 18px; - line-height: 1.6; -} - -.container { - max-width: 900px; - margin: 0 auto; - padding: 30px 20px; - text-align: center; - width: 100%; -} - -h1 { - color: var(--secondary-color); - text-shadow: 3px 3px 0px rgba(0, 0, 0, 0.3), - 0 0 15px rgba(243, 156, 18, 0.5); - margin-bottom: 20px; - font-family: 'Fredoka', sans-serif; - font-weight: 600; - position: relative; - display: inline-block; -} - -h1::after { - content: ""; - position: absolute; - bottom: -10px; - left: 50%; - transform: translateX(-50%); - width: 60px; - height: 4px; - background: linear-gradient(90deg, var(--accent-color), var(--secondary-color)); - border-radius: 2px; -} - -button { - cursor: pointer; - font-family: 'Poppins', 'Fredoka', sans-serif; - transition: all var(--transition-normal); - font-weight: 600; - letter-spacing: 1px; - text-shadow: 1px 1px 0px rgba(0, 0, 0, 0.2); - border: none; - outline: none; - position: relative; - overflow: hidden; -} - -button::after { - content: ""; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - background: linear-gradient(rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); - opacity: 0; - transition: opacity var(--transition-fast); -} - -button:hover::after { - opacity: 1; -} - -.title-link { - color: inherit; - text-decoration: none; - transition: all var(--transition-normal); - position: relative; - display: inline-block; -} - -.title-link:hover { - color: var(--secondary-color); - text-shadow: 0 0 15px rgba(243, 156, 18, 0.6); -} - -.footer { - margin-top: 40px; - padding: 20px; - text-align: center; - font-size: 16px; - color: var(--text-dim); - width: 100%; - border-top: 1px solid rgba(255, 255, 255, 0.1); -} - -.footer a { - color: var(--primary-color); - text-decoration: none; - font-weight: bold; - transition: color var(--transition-normal); - position: relative; -} - -.footer a::after { - content: ''; - position: absolute; - width: 100%; - transform: scaleX(0); - height: 2px; - bottom: -2px; - left: 0; - background-color: var(--primary-color); - transform-origin: bottom right; - transition: transform 0.3s ease-out; -} - -.footer a:hover { - color: var(--secondary-color); -} - -.footer a:hover::after { - transform: scaleX(1); - transform-origin: bottom left; -} - -/* Common Media Queries */ -@media (max-width: 768px) { - .container { - padding: 20px 15px; - } - - h1 { - font-size: 36px; - } - - button { - font-size: 16px; - } -} - -@media (max-width: 480px) { - h1 { - font-size: 28px; - } - - .container { - padding: 15px 10px; - } -}
\ No newline at end of file diff --git a/chart/index.html b/chart/index.html deleted file mode 100644 index de53cd9..0000000 --- a/chart/index.html +++ /dev/null @@ -1,282 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Morse Code Chart - Morse Hero</title> - <meta name="description" - content="Complete Morse code chart with letters, numbers, and special characters. A reference guide from Morse Hero."> - <meta name="keywords" content="morse code, morse code chart, morse code reference, morse hero"> - <meta name="robots" content="index, follow"> - <meta name="canonical" href="https://morsehero.com/chart/"> - - <link rel="apple-touch-icon" sizes="180x180" href="/ico/apple-touch-icon.png"> - <link rel="icon" type="image/png" sizes="32x32" href="/ico/icon-192.png"> - <link rel="icon" type="image/png" sizes="16x16" href="/ico/icon-192.png"> - <link rel="manifest" href="/site.webmanifest"> - <meta name="theme-color" content="#2c3e50"> - <script src="https://cdn.usefathom.com/script.js" data-site="NEBPAKSA" defer></script> - <script src="https://cwjs.mastercw.com/cw.min.js"></script> - - <!-- Google Fonts --> - <link rel="preconnect" href="https://fonts.googleapis.com"> - <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> - <link - href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600&family=Poppins:wght@400;600;700&display=swap" - rel="stylesheet"> - - <!-- Main Stylesheet --> - <link rel="stylesheet" href="../base.css"> - <link rel="stylesheet" href="styles.css"> -</head> - -<body> - <div class="container"> - <h1><a href="/" class="title-link">Morse Hero</a></h1> - <h2>Morse Code Chart</h2> - - <div class="chart-section"> - <h2>Letters</h2> - <div class="morse-grid"> - <div class="morse-item"> - <div class="character">A</div> - <div class="morse">·−</div> - </div> - <div class="morse-item"> - <div class="character">B</div> - <div class="morse">−···</div> - </div> - <div class="morse-item"> - <div class="character">C</div> - <div class="morse">−·−·</div> - </div> - <div class="morse-item"> - <div class="character">D</div> - <div class="morse">−··</div> - </div> - <div class="morse-item"> - <div class="character">E</div> - <div class="morse">·</div> - </div> - <div class="morse-item"> - <div class="character">F</div> - <div class="morse">··−·</div> - </div> - <div class="morse-item"> - <div class="character">G</div> - <div class="morse">−−·</div> - </div> - <div class="morse-item"> - <div class="character">H</div> - <div class="morse">····</div> - </div> - <div class="morse-item"> - <div class="character">I</div> - <div class="morse">··</div> - </div> - <div class="morse-item"> - <div class="character">J</div> - <div class="morse">·−−−</div> - </div> - <div class="morse-item"> - <div class="character">K</div> - <div class="morse">−·−</div> - </div> - <div class="morse-item"> - <div class="character">L</div> - <div class="morse">·−··</div> - </div> - <div class="morse-item"> - <div class="character">M</div> - <div class="morse">−−</div> - </div> - <div class="morse-item"> - <div class="character">N</div> - <div class="morse">−·</div> - </div> - <div class="morse-item"> - <div class="character">O</div> - <div class="morse">−−−</div> - </div> - <div class="morse-item"> - <div class="character">P</div> - <div class="morse">·−−·</div> - </div> - <div class="morse-item"> - <div class="character">Q</div> - <div class="morse">−−·−</div> - </div> - <div class="morse-item"> - <div class="character">R</div> - <div class="morse">·−·</div> - </div> - <div class="morse-item"> - <div class="character">S</div> - <div class="morse">···</div> - </div> - <div class="morse-item"> - <div class="character">T</div> - <div class="morse">−</div> - </div> - <div class="morse-item"> - <div class="character">U</div> - <div class="morse">··−</div> - </div> - <div class="morse-item"> - <div class="character">V</div> - <div class="morse">···−</div> - </div> - <div class="morse-item"> - <div class="character">W</div> - <div class="morse">·−−</div> - </div> - <div class="morse-item"> - <div class="character">X</div> - <div class="morse">−··−</div> - </div> - <div class="morse-item"> - <div class="character">Y</div> - <div class="morse">−·−−</div> - </div> - <div class="morse-item"> - <div class="character">Z</div> - <div class="morse">−−··</div> - </div> - </div> - </div> - - <div class="chart-section"> - <h2>Numbers</h2> - <div class="morse-grid"> - <div class="morse-item"> - <div class="character">1</div> - <div class="morse">·−−−−</div> - </div> - <div class="morse-item"> - <div class="character">2</div> - <div class="morse">··−−−</div> - </div> - <div class="morse-item"> - <div class="character">3</div> - <div class="morse">···−−</div> - </div> - <div class="morse-item"> - <div class="character">4</div> - <div class="morse">····−</div> - </div> - <div class="morse-item"> - <div class="character">5</div> - <div class="morse">·····</div> - </div> - <div class="morse-item"> - <div class="character">6</div> - <div class="morse">−····</div> - </div> - <div class="morse-item"> - <div class="character">7</div> - <div class="morse">−−···</div> - </div> - <div class="morse-item"> - <div class="character">8</div> - <div class="morse">−−−··</div> - </div> - <div class="morse-item"> - <div class="character">9</div> - <div class="morse">−−−−·</div> - </div> - <div class="morse-item"> - <div class="character">0</div> - <div class="morse">−−−−−</div> - </div> - </div> - </div> - - <div class="chart-section"> - <h2>Special Characters</h2> - <div class="morse-grid"> - <div class="morse-item"> - <div class="character">=</div> - <div class="morse">−···−</div> - </div> - <div class="morse-item"> - <div class="character">.</div> - <div class="morse">·−·−·−</div> - </div> - <div class="morse-item"> - <div class="character">,</div> - <div class="morse">−−··−−</div> - </div> - <div class="morse-item"> - <div class="character">/</div> - <div class="morse">−··−·</div> - </div> - <div class="morse-item"> - <div class="character">?</div> - <div class="morse">··−−··</div> - </div> - </div> - </div> - - <div class="back-link"> - <a href="/">← Back to Morse Hero Game</a> - </div> - - <footer class="footer"> - <p>Created with <a href="https://www.mastercw.com/cw.js/">CW.js</a>. For a complete and professional - Morse Code training solution visit <a href="https://www.mastercw.com">Master CW</a>.</p> - </footer> - </div> - - <script> - // Initialize audio context - let actx = null; - - // Set up CW.js - function initAudio() { - if (!actx) { - actx = cw.initAudioContext({ tone: 600 }); - } - } - - // Play Morse code for a character - function playCharacter(character) { - // Initialize audio if not already done - initAudio(); - - // Get all morse items - const allItems = document.querySelectorAll('.morse-item'); - - // Remove playing class from all items - allItems.forEach(item => { - item.classList.remove('playing'); - }); - - const list = event.currentTarget.classList; - // Add playing class to clicked item - list.add('playing'); - - // Play the character - cw.play(character, { actx: actx, wpm: 15 }); - - // Remove playing class after animation completes - setTimeout(() => { - list.remove('playing'); - }, 1500); - } - - // Add click event listeners to all morse items - document.addEventListener('DOMContentLoaded', function () { - const morseItems = document.querySelectorAll('.morse-item'); - - morseItems.forEach(item => { - const character = item.querySelector('.character').textContent; - item.addEventListener('click', function (event) { - playCharacter(character); - }); - }); - }); - </script> -</body> - -</html>
\ No newline at end of file diff --git a/morsehero/eslint.config.js b/eslint.config.js index 092408a..092408a 100644 --- a/morsehero/eslint.config.js +++ b/eslint.config.js @@ -1,345 +1,33 @@ -<!DOCTYPE html> +<!doctype html> <html lang="en"> - -<head> - <meta charset="UTF-8"> - <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Learn Morse Code the Fun Way - Morse Hero</title> <meta name="description" - content="Morse Hero is a fun, interactive game to learn Morse code. Practice your skills with audio playback and visual hints to master Morse code quickly."> - <meta name="keywords" content="morse code, morse code game, learn morse code, morse code practice, morse hero"> - <meta name="robots" content="index, follow"> - <script src="https://cdn.usefathom.com/script.js" data-site="NEBPAKSA" defer></script> - <script src="https://cdn.jsdelivr.net/npm/cw@latest/dist/cw.min.js"></script> - <meta name="canonical" href="https://morsehero.com"> + content="Morse Hero is a fun, interactive game to learn Morse code. Practice your skills with audio playback and visual hints to master Morse code quickly." /> + <meta name="keywords" content="morse code, morse code game, learn morse code, morse code practice, morse hero" /> + <meta name="robots" content="index, follow" /> + <meta name="canonical" href="https://morsehero.com" /> - <link rel="apple-touch-icon" sizes="180x180" href="/ico/apple-touch-icon.png"> - <link rel="icon" type="image/png" sizes="32x32" href="/ico/icon-192.png"> - <link rel="icon" type="image/png" sizes="16x16" href="/ico/icon-192.png"> - <link rel="manifest" href="/site.webmanifest"> - <meta name="theme-color" content="#2c3e50"> + <link rel="apple-touch-icon" sizes="180x180" href="/ico/apple-touch-icon.png" /> + <link rel="icon" type="image/png" sizes="32x32" href="/ico/icon-192.png" /> + <link rel="icon" type="image/png" sizes="16x16" href="/ico/icon-192.png" /> + <link rel="manifest" href="/site.webmanifest" /> + <meta name="theme-color" content="#2c3e50" /> <!-- Google Fonts --> - <link rel="preconnect" href="https://fonts.googleapis.com"> - <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> + <link rel="preconnect" href="https://fonts.googleapis.com" /> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600&family=Poppins:wght@400;600;700&display=swap" - rel="stylesheet"> - - <!-- Main Stylesheet --> - <link rel="stylesheet" href="base.css"> - <link rel="stylesheet" href="styles.css"> -</head> - -<body> - <div class="container"> - <h1><a href="/" class="title-link">Morse Hero</a></h1> - - <div id="startScreen"> - <p>Learn Morse code the fun way!</p> - <button id="startButton" class="start-button">Start</button> - <div class="chart-link"> - <a href="/chart/">View Morse Code Chart</a> - </div> - </div> - - <div id="gameArea"> - <div class="score-container"> - <div class="score-widget"> - <div class="score-info"> - <div class="score-label">Score:</div> - <div class="score-value"> - <span id="score">0</span> / <span id="total">0</span> - </div> - </div> - <div class="score-tracker" id="scoreTracker"></div> - </div> - </div> - - <div class="game-container"> - <div class="options"> - <button class="option-button" id="option1"></button> - <button class="option-button" id="option2"></button> - <button class="option-button" id="option3"></button> - <button class="option-button" id="option4"></button> - </div> - - <div class="feedback" id="feedback"></div> - </div> - - <div class="settings"> - <label for="wpmSelect">Speed:</label> - <select id="wpmSelect"> - <option value="10">10 WPM</option> - <option value="15">15 WPM</option> - <option value="20" selected>20 WPM</option> - <option value="25">25 WPM</option> - <option value="30">30 WPM</option> - </select> - <div class="hint-setting"> - <input type="checkbox" id="hintMode" name="hintMode"> - <label for="hintMode">Show Hints</label> - </div> - </div> - </div> - - <footer class="footer"> - <p>Need help? View the <a href="/chart/">Morse Code Chart</a>. </p> - <p>Created with <a href="https://www.mastercw.com/cw.js/">CW.js</a>. For a complete and professional - Morse Code training solution visit <a href="https://www.mastercw.com">Master CW</a>.</p> - </footer> - </div> - - <script> - // Game variables - let actx = null; - - // Define available characters - const letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - const numbers = '0123456789'; - const specialChars = '.,?/='; - const allChars = letters + numbers + specialChars; - - // Game state - let currentChar = ''; - let score = 0; - let totalPlayed = 0; - - // DOM elements - const startButton = document.getElementById('startButton'); - const startScreen = document.getElementById('startScreen'); - const gameArea = document.getElementById('gameArea'); - - // Start button event listener - startButton.addEventListener('click', function () { - // Initialize audio context only when the start button is clicked - try { - actx = cw.initAudioContext({ tone: 600 }); - - // Hide start screen and show game area - startScreen.style.display = 'none'; - gameArea.style.display = 'block'; - document.body.classList.add('game-active'); - - // Initialize the game - init(); - } catch (error) { - console.error('Failed to initialize audio context:', error); - alert('Failed to initialize audio. Please try again.'); - } - }); - - // Initialize the game - function init() { - // DOM elements for the game - const optionButtons = [ - document.getElementById('option1'), - document.getElementById('option2'), - document.getElementById('option3'), - document.getElementById('option4') - ]; - const feedbackElement = document.getElementById('feedback'); - const scoreElement = document.getElementById('score'); - const totalElement = document.getElementById('total'); - const wpmSelect = document.getElementById('wpmSelect'); - const hintModeCheckbox = document.getElementById('hintMode'); - - optionButtons.forEach((button, index) => { - button.addEventListener('click', function () { - checkAnswer(button); - }); - // Remove number labels - we'll add character labels dynamically in newRound - const existingLabel = button.querySelector('.key-label'); - if (existingLabel) { - button.removeChild(existingLabel); - } - }); - - // Add keyboard listener for character keys - document.addEventListener('keydown', (event) => { - // Only process if we're in the game area (not on start screen) - if (gameArea.style.display === 'block') { - const key = event.key.toUpperCase(); - - // Find if any button has this character - for (let i = 0; i < optionButtons.length; i++) { - const charSpan = optionButtons[i].querySelector('.char-display'); - if (charSpan && charSpan.textContent === key && !optionButtons[i].disabled) { - // Simulate button press with visual feedback - optionButtons[i].classList.add('key-pressed'); - setTimeout(() => { - optionButtons[i].classList.remove('key-pressed'); - checkAnswer(optionButtons[i]); - }, 100); - break; - } - } - } - }); - - hintModeCheckbox.addEventListener('change', updateButtonsWithHints); - - // Start the game - newRound(); - - // Generate a new round - function newRound() { - // Clear feedback - feedbackElement.textContent = ''; - - // Reset all buttons to default state - optionButtons.forEach(button => { - button.disabled = false; - button.classList.remove('correct', 'incorrect'); - // Clear button content - button.innerHTML = ''; - }); - - // Generate a random character - const randomIndex = Math.floor(Math.random() * allChars.length); - currentChar = allChars[randomIndex]; - - // Generate 3 wrong options - let options = [currentChar]; - while (options.length < 4) { - const randomIndex = Math.floor(Math.random() * allChars.length); - const randomChar = allChars[randomIndex]; - if (!options.includes(randomChar)) { - options.push(randomChar); - } - } - - // Shuffle options - options = shuffleArray(options); - - // Set button text - for (let i = 0; i < 4; i++) { - // Create a span for the character - const charSpan = document.createElement('span'); - charSpan.className = 'char-display'; - charSpan.textContent = options[i]; - optionButtons[i].appendChild(charSpan); - } - - // Update buttons with hints if hint mode is enabled - updateButtonsWithHints(); - - // immediately play sound - playMorse(); - } - - // Update buttons with Morse code hints if hint mode is enabled - function updateButtonsWithHints() { - if (hintModeCheckbox.checked) { - optionButtons.forEach(button => { - // Remove any existing hint spans - const existingHint = button.querySelector('.morse-hint'); - if (existingHint) { - button.removeChild(existingHint); - } - - // Get the character from the button's char-display span - const charSpan = button.querySelector('.char-display'); - if (!charSpan) return; - - const char = charSpan.textContent; - - // Get the Morse code for the character - const morseCode = cw.codes[char]; - - if (morseCode) { - // Create a span for the hint - const hintSpan = document.createElement('span'); - hintSpan.className = 'morse-hint'; - hintSpan.textContent = morseCode.replace(/\./g, '·').replace(/\-/g, '−'); - - // Add the hint to the button - button.appendChild(hintSpan); - } - }); - } else { - // Remove hints if hint mode is disabled - optionButtons.forEach(button => { - const existingHint = button.querySelector('.morse-hint'); - if (existingHint) { - button.removeChild(existingHint); - } - }); - } - } - - // Play the morse code - function playMorse() { - const wpm = parseInt(wpmSelect.value); - - // Play the character with the existing audio context - cw.play(currentChar, { - actx: actx, - wpm: wpm - }); - } - - // Check the user's answer - function checkAnswer(selectedButton) { - // Disable all buttons - optionButtons.forEach(button => { - button.disabled = true; - }); - - totalPlayed++; - totalElement.textContent = totalPlayed; - - // Get the character from the button's char-display span - const charSpan = selectedButton.querySelector('.char-display'); - const selectedChar = charSpan ? charSpan.textContent : ''; - - // Create a new score dot - const scoreDot = document.createElement('div'); - scoreDot.className = 'score-dot'; - - if (selectedChar === currentChar) { - // Correct answer - score++; - scoreElement.textContent = score; - selectedButton.classList.add('correct'); - scoreDot.classList.add('correct'); - } else { - // Wrong answer - mark selected button as incorrect - selectedButton.classList.add('incorrect'); - scoreDot.classList.add('incorrect'); - - // Find and highlight the correct button - optionButtons.forEach(button => { - const buttonCharSpan = button.querySelector('.char-display'); - if (buttonCharSpan && buttonCharSpan.textContent === currentChar) { - button.classList.add('correct'); - } - }); - } - - // Add the score dot to the tracker - const scoreTracker = document.getElementById('scoreTracker'); - scoreTracker.appendChild(scoreDot); - - // Limit the number of dots shown (keep last 20) - if (scoreTracker.children.length > 20) { - scoreTracker.removeChild(scoreTracker.children[0]); - } - - // Start a new round after a delay - setTimeout(newRound, 1000); - } - } - - // Utility function to shuffle an array - function shuffleArray(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; - } - </script> -</body> - -</html>
\ No newline at end of file + rel="stylesheet" /> + + <!-- Analytics --> + <script src="https://cdn.usefathom.com/script.js" data-site="NEBPAKSA" defer></script> + </head> + <body> + <div id="root"></div> + <script type="module" src="/src/main.tsx"></script> + </body> +</html> diff --git a/morsehero/index.html b/morsehero/index.html deleted file mode 100644 index 4254c2b..0000000 --- a/morsehero/index.html +++ /dev/null @@ -1,33 +0,0 @@ -<!doctype html> -<html lang="en"> - <head> - <meta charset="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <title>Learn Morse Code the Fun Way - Morse Hero</title> - <meta name="description" - content="Morse Hero is a fun, interactive game to learn Morse code. Practice your skills with audio playback and visual hints to master Morse code quickly." /> - <meta name="keywords" content="morse code, morse code game, learn morse code, morse code practice, morse hero" /> - <meta name="robots" content="index, follow" /> - <meta name="canonical" href="https://morsehero.com" /> - - <link rel="apple-touch-icon" sizes="180x180" href="/ico/apple-touch-icon.png" /> - <link rel="icon" type="image/png" sizes="32x32" href="/ico/icon-192.png" /> - <link rel="icon" type="image/png" sizes="16x16" href="/ico/icon-192.png" /> - <link rel="manifest" href="/site.webmanifest" /> - <meta name="theme-color" content="#2c3e50" /> - - <!-- Google Fonts --> - <link rel="preconnect" href="https://fonts.googleapis.com" /> - <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> - <link - href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;600&family=Poppins:wght@400;600;700&display=swap" - rel="stylesheet" /> - - <!-- Analytics --> - <script src="https://cdn.usefathom.com/script.js" data-site="NEBPAKSA" defer></script> - </head> - <body> - <div id="root"></div> - <script type="module" src="/src/main.tsx"></script> - </body> -</html> diff --git a/morsehero/public/ico/apple-touch-icon.png b/morsehero/public/ico/apple-touch-icon.png Binary files differdeleted file mode 100644 index abd842d..0000000 --- a/morsehero/public/ico/apple-touch-icon.png +++ /dev/null diff --git a/morsehero/public/ico/favicon.ico b/morsehero/public/ico/favicon.ico Binary files differdeleted file mode 100644 index cc066f0..0000000 --- a/morsehero/public/ico/favicon.ico +++ /dev/null diff --git a/morsehero/public/ico/icon-192-maskable.png b/morsehero/public/ico/icon-192-maskable.png Binary files differdeleted file mode 100644 index 856c8c7..0000000 --- a/morsehero/public/ico/icon-192-maskable.png +++ /dev/null diff --git a/morsehero/public/ico/icon-192.png b/morsehero/public/ico/icon-192.png Binary files differdeleted file mode 100644 index 49d2d39..0000000 --- a/morsehero/public/ico/icon-192.png +++ /dev/null diff --git a/morsehero/public/ico/icon-512-maskable.png b/morsehero/public/ico/icon-512-maskable.png Binary files differdeleted file mode 100644 index 430213f..0000000 --- a/morsehero/public/ico/icon-512-maskable.png +++ /dev/null diff --git a/morsehero/public/ico/icon-512.png b/morsehero/public/ico/icon-512.png Binary files differdeleted file mode 100644 index 370613d..0000000 --- a/morsehero/public/ico/icon-512.png +++ /dev/null diff --git a/morsehero/src/index.css b/morsehero/src/index.css deleted file mode 100644 index 08a3ac9..0000000 --- a/morsehero/src/index.css +++ /dev/null @@ -1,68 +0,0 @@ -:root { - font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} diff --git a/morsehero/src/pages/chart/styles.css b/morsehero/src/pages/chart/styles.css deleted file mode 100644 index 279d421..0000000 --- a/morsehero/src/pages/chart/styles.css +++ /dev/null @@ -1,132 +0,0 @@ -/* Morse Hero Chart Styles */ - -h1 { - font-size: 48px; -} - -h2 { - font-size: 32px; - margin: 30px 0 15px; - color: var(--primary-color); - text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.2), - 0 0 10px rgba(52, 152, 219, 0.4); - font-family: 'Fredoka', sans-serif; - font-weight: 600; -} - -.chart-section { - background: linear-gradient(145deg, var(--bg-light) 0%, #2d3e50 100%); - border-radius: var(--border-radius-md); - padding: 30px 25px; - margin-bottom: 40px; - box-shadow: var(--shadow-lg); - position: relative; - overflow: hidden; -} - -.chart-section::before { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 5px; - background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); - z-index: 1; -} - -.morse-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); - gap: 20px; - margin: 0 auto; -} - -.morse-item { - background: linear-gradient(145deg, rgba(52, 152, 219, 0.1) 0%, rgba(52, 152, 219, 0.2) 100%); - border-radius: var(--border-radius-sm); - padding: 20px 15px; - display: flex; - flex-direction: column; - align-items: center; - box-shadow: var(--shadow-sm); - transition: all var(--transition-normal); - cursor: pointer; - border: 1px solid rgba(52, 152, 219, 0.2); -} - -.morse-item:hover { - transform: translateY(-5px); - box-shadow: var(--shadow-md); - background: linear-gradient(145deg, rgba(52, 152, 219, 0.2) 0%, rgba(52, 152, 219, 0.3) 100%); - border-color: rgba(52, 152, 219, 0.3); -} - -.morse-item.playing { - background: linear-gradient(145deg, rgba(243, 156, 18, 0.2) 0%, rgba(243, 156, 18, 0.3) 100%); - box-shadow: 0 0 20px rgba(243, 156, 18, 0.4); - border-color: rgba(243, 156, 18, 0.4); -} - -.character { - font-size: 32px; - font-weight: bold; - margin-bottom: 10px; - text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); -} - -.morse { - font-family: monospace; - font-size: 18px; - letter-spacing: 2px; - color: var(--text-dim); -} - -.back-link { - margin-top: 40px; - font-size: 18px; -} - -.back-link a { - color: var(--primary-color); - text-decoration: none; - transition: all var(--transition-normal); - padding: 10px 20px; - background-color: rgba(255, 255, 255, 0.05); - border-radius: var(--border-radius-sm); - display: inline-block; -} - -.back-link a:hover { - color: var(--secondary-color); - background-color: rgba(255, 255, 255, 0.1); - transform: translateY(-3px); - box-shadow: var(--shadow-sm); -} - -@media (max-width: 768px) { - .morse-grid { - grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); - gap: 15px; - } - - .morse-item { - padding: 15px 10px; - } - - .character { - font-size: 28px; - } - - .morse { - font-size: 16px; - } - - h1 { - font-size: 36px; - } - - h2 { - font-size: 24px; - } -} diff --git a/morsehero/package-lock.json b/package-lock.json index c7079ca..c7079ca 100644 --- a/morsehero/package-lock.json +++ b/package-lock.json diff --git a/morsehero/package.json b/package.json index 4967122..4967122 100644 --- a/morsehero/package.json +++ b/package.json diff --git a/ico/apple-touch-icon.png b/public/ico/apple-touch-icon.png Binary files differindex abd842d..abd842d 100644 --- a/ico/apple-touch-icon.png +++ b/public/ico/apple-touch-icon.png diff --git a/ico/favicon.ico b/public/ico/favicon.ico Binary files differindex cc066f0..cc066f0 100644 --- a/ico/favicon.ico +++ b/public/ico/favicon.ico diff --git a/ico/icon-192-maskable.png b/public/ico/icon-192-maskable.png Binary files differindex 856c8c7..856c8c7 100644 --- a/ico/icon-192-maskable.png +++ b/public/ico/icon-192-maskable.png diff --git a/ico/icon-192.png b/public/ico/icon-192.png Binary files differindex 49d2d39..49d2d39 100644 --- a/ico/icon-192.png +++ b/public/ico/icon-192.png diff --git a/ico/icon-512-maskable.png b/public/ico/icon-512-maskable.png Binary files differindex 430213f..430213f 100644 --- a/ico/icon-512-maskable.png +++ b/public/ico/icon-512-maskable.png diff --git a/ico/icon-512.png b/public/ico/icon-512.png Binary files differindex 370613d..370613d 100644 --- a/ico/icon-512.png +++ b/public/ico/icon-512.png diff --git a/morsehero/public/site.webmanifest b/public/site.webmanifest index e1e7547..e1e7547 100644 --- a/morsehero/public/site.webmanifest +++ b/public/site.webmanifest diff --git a/morsehero/public/vite.svg b/public/vite.svg index e7b8dfb..e7b8dfb 100644 --- a/morsehero/public/vite.svg +++ b/public/vite.svg diff --git a/site.webmanifest b/site.webmanifest deleted file mode 100644 index e1e7547..0000000 --- a/site.webmanifest +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "Morse Hero", - "short_name": "Morse Hero", - "icons": [ - { - "src": "/ico/icon-192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/ico/icon-512.png", - "sizes": "512x512", - "type": "image/png" - }, - { - "src": "/ico/icon-192-maskable.png", - "sizes": "192x192", - "type": "image/png", - "purpose": "maskable" - }, - { - "src": "/ico/icon-512-maskable.png", - "sizes": "512x512", - "type": "image/png", - "purpose": "maskable" - } - ], - "theme_color": "#2c3e50", - "background_color": "#2c3e50", - "display": "standalone" -}
\ No newline at end of file diff --git a/morsehero/src/App.css b/src/App.css index b9d355d..b9d355d 100644 --- a/morsehero/src/App.css +++ b/src/App.css diff --git a/morsehero/src/App.tsx b/src/App.tsx index 1512713..1512713 100644 --- a/morsehero/src/App.tsx +++ b/src/App.tsx diff --git a/morsehero/src/assets/react.svg b/src/assets/react.svg index 6c87de9..6c87de9 100644 --- a/morsehero/src/assets/react.svg +++ b/src/assets/react.svg diff --git a/morsehero/src/base.css b/src/base.css index d5afb78..d5afb78 100644 --- a/morsehero/src/base.css +++ b/src/base.css diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/index.css diff --git a/morsehero/src/main.tsx b/src/main.tsx index bef5202..bef5202 100644 --- a/morsehero/src/main.tsx +++ b/src/main.tsx diff --git a/morsehero/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index bf07bd5..bf07bd5 100644 --- a/morsehero/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx diff --git a/morsehero/src/pages/chart/ChartPage.tsx b/src/pages/chart/ChartPage.tsx index 88c1ec2..88c1ec2 100644 --- a/morsehero/src/pages/chart/ChartPage.tsx +++ b/src/pages/chart/ChartPage.tsx diff --git a/chart/styles.css b/src/pages/chart/styles.css index 279d421..279d421 100644 --- a/chart/styles.css +++ b/src/pages/chart/styles.css diff --git a/morsehero/src/styles.css b/src/styles.css index 264b6f7..264b6f7 100644 --- a/morsehero/src/styles.css +++ b/src/styles.css diff --git a/morsehero/src/vite-env.d.ts b/src/vite-env.d.ts index 11f02fe..11f02fe 100644 --- a/morsehero/src/vite-env.d.ts +++ b/src/vite-env.d.ts diff --git a/styles.css b/styles.css deleted file mode 100644 index 264b6f7..0000000 --- a/styles.css +++ /dev/null @@ -1,605 +0,0 @@ -/* Morse Hero Main Styles */ - -h1 { - font-size: 4.5em; - margin-top: 0.5rem; - letter-spacing: 2px; - font-weight: 700; - text-shadow: - 0 0 15px rgba(243, 156, 18, 0.4), - 3px 3px 0px rgba(231, 76, 60, 0.6); -} - -h1::after { - width: 80px; -} - -.game-container { - background: linear-gradient(145deg, var(--bg-dark) 0%, var(--bg-darker) 100%); - border-radius: var(--border-radius-lg); - padding: 40px; - box-shadow: var(--shadow-lg); - border: none; - position: relative; - overflow: hidden; -} - -.game-container::before { - content: ""; - position: absolute; - top: 0; - left: 0; - right: 0; - height: 5px; - background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); - z-index: 1; -} - -.options { - display: grid; - grid-template-columns: 1fr 1fr; - gap: 30px; - margin-top: 40px; -} - -.start-button { - background: linear-gradient(145deg, var(--accent-color) 0%, #c0392b 100%); - color: white; - border: none; - padding: 20px 50px; - font-size: 32px; - font-weight: 700; - border-radius: var(--border-radius-lg); - cursor: pointer; - transition: all var(--transition-normal); - box-shadow: var(--shadow-md); - text-transform: uppercase; - letter-spacing: 1px; - margin-bottom: 30px; - width: 100%; - max-width: 300px; - position: relative; - z-index: 1; -} - -.start-button:hover { - transform: translateY(-5px); - box-shadow: var(--shadow-lg); - background: linear-gradient(145deg, #e74c3c 0%, var(--accent-color) 100%); -} - -.start-button:active { - transform: translateY(-2px); - box-shadow: var(--shadow-sm); -} - -.option-button { - background: linear-gradient(145deg, var(--primary-color), var(--primary-dark)); - color: white; - border-radius: var(--border-radius-md); - font-size: 36px; - padding: 25px 15px; - box-shadow: 0 8px 0 var(--primary-dark), - var(--shadow-md); - min-height: 130px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - position: relative; - z-index: 1; -} - -.option-button:hover { - transform: translateY(-5px); - box-shadow: 0 13px 0 var(--primary-dark), - var(--shadow-lg); -} - -.option-button:active { - transform: translateY(3px); - box-shadow: 0 5px 0 var(--primary-dark), - var(--shadow-sm); -} - -.option-button.correct { - background: linear-gradient(145deg, var(--success-color), var(--success-dark)); - box-shadow: 0 8px 0 var(--success-dark), - 0 0 30px rgba(46, 204, 113, 0.5); - animation: pulse 0.5s; -} - -.option-button.incorrect { - background: linear-gradient(145deg, var(--accent-color), var(--accent-dark)); - box-shadow: 0 8px 0 var(--accent-dark), - 0 0 30px rgba(231, 76, 60, 0.5); - animation: shake 0.5s; -} - -.char-display { - font-size: 38px; - font-weight: bold; - text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2); -} - -.morse-hint { - display: block; - font-size: 18px; - margin-top: 10px; - color: var(--text-dim); - font-family: monospace; - letter-spacing: 2px; -} - -.key-label { - position: absolute; - top: 8px; - right: 12px; - font-size: 14px; - color: var(--text-dim); - font-family: monospace; - background-color: rgba(0, 0, 0, 0.2); - padding: 2px 8px; - border-radius: 10px; -} - -.key-pressed { - transform: translateY(3px) !important; - box-shadow: 0 5px 0 var(--primary-dark) !important; - transition: transform 0.05s, box-shadow 0.05s; -} - -.chart-link { - margin-top: 20px; - font-size: 18px; -} - -.chart-link a { - color: var(--primary-color); - text-decoration: none; - transition: all var(--transition-normal); - position: relative; -} - -.chart-link a:hover { - color: var(--secondary-color); - text-decoration: underline; -} - -.chart-link a::after { - content: ''; - position: absolute; - width: 100%; - transform: scaleX(0); - height: 2px; - bottom: -2px; - left: 0; - background-color: var(--primary-color); - transform-origin: bottom right; - transition: transform 0.3s ease-out; -} - -.chart-link a:hover::after { - transform: scaleX(1); - transform-origin: bottom left; - background-color: var(--secondary-color); -} - -#startScreen { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - text-align: center; - background: linear-gradient(145deg, var(--bg-dark) 0%, var(--bg-darker) 100%); - border-radius: var(--border-radius-lg); - padding: 40px 30px; - margin: 40px 0; - position: relative; - border: 2px dashed rgba(52, 152, 219, 0.3); - box-shadow: var(--shadow-md); -} - -#startScreen::before { - content: ''; - position: absolute; - left: 50%; - top: -2px; - transform: translateX(-50%); - width: 80%; - height: 4px; - background: linear-gradient(90deg, rgba(52, 152, 219, 0) 0%, rgba(52, 152, 219, 0.8) 50%, rgba(52, 152, 219, 0) 100%); - border-radius: 2px; -} - -#startScreen p { - font-size: 28px; - font-weight: 600; - color: var(--text-light); - margin-bottom: 40px; - text-shadow: var(--text-shadow); -} - -#startScreen .chart-link { - margin-top: 0; - width: 100%; - max-width: 300px; -} - -#startScreen .chart-link a { - display: block; - width: 100%; - padding: 12px 25px; - background: linear-gradient(145deg, rgba(52, 152, 219, 0.2) 0%, rgba(52, 152, 219, 0.3) 100%); - border-radius: var(--border-radius-md); - color: var(--text-light); - font-size: 18px; - font-weight: 600; - text-decoration: none; - transition: all var(--transition-normal); - border: 1px solid rgba(52, 152, 219, 0.3); - box-shadow: var(--shadow-sm); - box-sizing: border-box; -} - -#startScreen .chart-link a:hover { - background: linear-gradient(145deg, rgba(52, 152, 219, 0.3) 0%, rgba(52, 152, 219, 0.4) 100%); - transform: translateY(-3px); - box-shadow: var(--shadow-md); - color: var(--primary-color); - border-color: rgba(52, 152, 219, 0.5); -} - -.score-container { - margin-bottom: 20px; - width: 100%; -} - -.score-widget { - background-color: rgba(255, 255, 255, 0.1); - border-radius: var(--border-radius-md); - padding: 15px; - box-shadow: var(--shadow-sm); - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; -} - -.score-info { - display: flex; - flex-direction: column; - align-items: flex-start; - margin-right: 15px; - min-width: 100px; -} - -.score-label { - font-size: 18px; - margin-bottom: 5px; - color: var(--text-dim); -} - -.score-value { - font-size: 24px; - font-weight: bold; - color: var(--secondary-color); -} - -.score-tracker { - display: flex; - flex-wrap: wrap; - justify-content: center; - gap: 5px; - max-width: 100%; - margin-top: 5px; -} - -.score-dot { - width: 12px; - height: 12px; - border-radius: 50%; - margin: 2px; - transition: all 0.3s ease; -} - -.score-dot.correct { - background-color: var(--success-color); - box-shadow: 0 0 5px rgba(46, 204, 113, 0.7); -} - -.score-dot.incorrect { - background-color: var(--accent-color); - box-shadow: 0 0 5px rgba(231, 76, 60, 0.7); -} - -.feedback { - height: 40px; - margin-top: 30px; - font-weight: bold; - font-size: 28px; - color: var(--secondary-color); - text-shadow: 0 0 10px rgba(243, 156, 18, 0.5); -} - -.score { - font-size: 32px; - font-weight: bold; - color: var(--secondary-color); - margin-bottom: 30px; - text-shadow: 2px 2px 0px rgba(0, 0, 0, 0.3), - 0 0 10px rgba(243, 156, 18, 0.3); -} - -.score-display { - font-size: 24px; - font-weight: bold; - margin: 15px 0; - color: var(--secondary-color); -} - -.settings { - background: linear-gradient(145deg, rgba(52, 73, 94, 0.7) 0%, rgba(44, 62, 80, 0.7) 100%); - padding: 25px; - border-radius: var(--border-radius-md); - margin-top: 30px; - font-size: 20px; - border: none; - box-shadow: var(--shadow-md); -} - -.settings label { - font-size: 20px; - margin-right: 15px; - color: var(--primary-color); - font-weight: 600; -} - -.settings select { - padding: 12px 20px; - font-size: 18px; - border-radius: var(--border-radius-sm); - border: 2px solid var(--primary-dark); - background-color: rgba(44, 62, 80, 0.7); - color: var(--text-light); - font-family: 'Poppins', sans-serif; - cursor: pointer; - box-shadow: var(--shadow-sm); - transition: all var(--transition-normal); -} - -.settings select:hover { - border-color: var(--primary-color); - box-shadow: 0 0 10px rgba(52, 152, 219, 0.3); -} - -.settings select:focus { - outline: none; - border-color: var(--secondary-color); - box-shadow: 0 0 15px rgba(243, 156, 18, 0.3); -} - -.hint-setting { - display: inline-block; - margin-left: 30px; -} - -.hint-icon { - display: inline-block; - margin-right: 8px; -} - -.hint-setting input[type="checkbox"] { - width: 20px; - height: 20px; - vertical-align: middle; - cursor: pointer; - margin-right: 8px; -} - -.controls { - display: flex; - justify-content: center; - gap: 20px; - margin-top: 30px; -} - -.control-button { - background: linear-gradient(145deg, var(--bg-light), #2d3e50); - color: var(--text-light); - border-radius: var(--border-radius-sm); - padding: 12px 25px; - font-size: 16px; - box-shadow: var(--shadow-sm); - transition: all var(--transition-normal); - display: flex; - align-items: center; - justify-content: center; - gap: 8px; -} - -.control-button:hover { - transform: translateY(-3px); - box-shadow: var(--shadow-md); - background: linear-gradient(145deg, #3a5269, var(--bg-light)); -} - -.control-button:active { - transform: translateY(1px); - box-shadow: var(--shadow-sm); -} - -.play-again-button { - background: linear-gradient(145deg, var(--secondary-color), var(--secondary-dark)); - color: white; - border-radius: var(--border-radius-md); - padding: 15px 30px; - font-size: 20px; - margin-top: 20px; - box-shadow: 0 6px 0 var(--secondary-dark), - var(--shadow-md); -} - -.play-again-button:hover { - transform: translateY(-5px); - box-shadow: 0 11px 0 var(--secondary-dark), - var(--shadow-lg); -} - -.play-again-button:active { - transform: translateY(3px); - box-shadow: 0 3px 0 var(--secondary-dark), - var(--shadow-sm); -} - -.progress-container { - background-color: rgba(255, 255, 255, 0.1); - border-radius: 20px; - height: 10px; - width: 100%; - margin: 20px 0; - overflow: hidden; - position: relative; -} - -.progress-bar { - background: linear-gradient(90deg, var(--primary-color), var(--secondary-color)); - height: 100%; - border-radius: 20px; - transition: width 0.5s ease; -} - -.instructions { - background-color: rgba(255, 255, 255, 0.05); - border-radius: var(--border-radius-md); - padding: 25px; - margin-bottom: 30px; - text-align: left; - box-shadow: var(--shadow-sm); - border-left: 4px solid var(--primary-color); -} - -.instructions h2 { - color: var(--secondary-color); - margin-bottom: 15px; - font-size: 24px; -} - -.instructions p { - margin-bottom: 10px; - font-size: 16px; - line-height: 1.6; -} - -.instructions ul { - margin-left: 20px; - margin-bottom: 10px; -} - -.instructions li { - margin-bottom: 5px; -} - -@keyframes pulse { - 0% { - box-shadow: 0 8px 0 var(--success-dark), 0 0 20px rgba(46, 204, 113, 0.5); - } - 50% { - box-shadow: 0 8px 0 var(--success-dark), 0 0 40px rgba(46, 204, 113, 0.8); - } - 100% { - box-shadow: 0 8px 0 var(--success-dark), 0 0 20px rgba(46, 204, 113, 0.5); - } -} - -@keyframes shake { - 0%, 100% { - transform: translateX(0); - } - 20%, 60% { - transform: translateX(-10px); - } - 40%, 80% { - transform: translateX(10px); - } -} - -/* Game Area */ -#gameArea { - display: none; -} - -/* When game is active, JavaScript will override this */ -body.game-active #gameArea { - display: block; -} - -body.game-active #startScreen { - display: none; -} - -@media (max-width: 768px) { - .game-container { - padding: 30px 20px; - } - - .options { - grid-template-columns: 1fr; - gap: 20px; - } - - .option-button { - font-size: 30px; - padding: 20px 15px; - min-height: 110px; - } - - h1 { - font-size: 3.5em; - } - - .start-button { - font-size: 28px; - padding: 15px 40px; - } - - .score-container { - flex-direction: column; - align-items: center; - } - - .score-widget { - margin-bottom: 15px; - } - - .settings-toggle { - margin-left: 0; - margin-top: 10px; - } -} - -@media (max-width: 480px) { - .game-container { - padding: 25px 15px; - } - - .option-button { - font-size: 24px; - padding: 15px 10px; - min-height: 90px; - } - - h1 { - font-size: 2.8em; - } - - .start-button { - font-size: 24px; - padding: 12px 30px; - } - - .hint-setting { - margin-left: 0; - margin-top: 10px; - } -}
\ No newline at end of file diff --git a/morsehero/tsconfig.app.json b/tsconfig.app.json index 54d2c7b..54d2c7b 100644 --- a/morsehero/tsconfig.app.json +++ b/tsconfig.app.json diff --git a/morsehero/tsconfig.json b/tsconfig.json index 1ffef60..1ffef60 100644 --- a/morsehero/tsconfig.json +++ b/tsconfig.json diff --git a/morsehero/tsconfig.node.json b/tsconfig.node.json index db0becc..db0becc 100644 --- a/morsehero/tsconfig.node.json +++ b/tsconfig.node.json diff --git a/morsehero/vite.config.ts b/vite.config.ts index 8b0f57b..8b0f57b 100644 --- a/morsehero/vite.config.ts +++ b/vite.config.ts |
