diff --git a/frontend/src/ts/constants/firebase-config-example.ts b/frontend/src/ts/constants/firebase-config-example.ts deleted file mode 100644 index 018be69720df..000000000000 --- a/frontend/src/ts/constants/firebase-config-example.ts +++ /dev/null @@ -1,14 +0,0 @@ -// To find your config, go to https://console.firebase.google.com/ and select your project -// Go to (top left) Settings > Project Settings > General -// scroll down to Your apps > Web Apps (if it doesnt exist, create one) > SDK setup and configuration > select npm -// your config should be visible there - -export const firebaseConfig = { - apiKey: "", - authDomain: "", - databaseURL: "", - projectId: "", - storageBucket: "", - messagingSenderId: "", - appId: "", -}; diff --git a/frontend/static/themes/_list.json b/frontend/static/themes/_list.json index 458a7464f900..aea1f2a7df8a 100644 --- a/frontend/static/themes/_list.json +++ b/frontend/static/themes/_list.json @@ -1280,6 +1280,13 @@ "subColor": "#788386", "textColor": "#ccdae6" }, + { + "name": "item", + "bgColor": "#1a1025", + "mainColor": "#e4c2ff", + "subColor": "#8a7ca3", + "textColor": "#ffffff" + }, { "name": "sunset", "bgColor": "#211e24", diff --git a/frontend/static/themes/item.css b/frontend/static/themes/item.css new file mode 100644 index 000000000000..84cdc3767a86 --- /dev/null +++ b/frontend/static/themes/item.css @@ -0,0 +1,616 @@ +:root { + --bg-color: #1a1025; + --caret-color: #e4c2ff; + --main-color: #e4c2ff; + --sub-color: #8a7ca3; + --sub-alt-color: #251a36; + --text-color: #ffffff; + --error-color: #ff5e94; + --error-extra-color: #8c2950; + --colorful-error-color: #ff5e94; + --colorful-error-extra-color: #8c2950; + + /* Font variables */ + --font-main: "JetBrains Mono", "Fira Code", monospace; + --font-headings: "Space Mono", monospace; + --font-alt: "IBM Plex Mono", "Courier Prime", monospace; + --letter-spacing-main: 0.05em; + --letter-spacing-headings: 0.1em; + + /* Animation variables */ + --transition-speed: 0.3s; + --animation-curve: cubic-bezier(0.4, 0, 0.2, 1); + + /* Custom theme colors */ + --accent-purple: #b278ff; + --accent-pink: #ff6bcf; + --accent-blue: #78c9ff; + --accent-green: #78ffb9; + --accent-orange: #ff9349; + --accent-yellow: #ffcf78; + --accent-red: #f94348; +} + +/* Typography styling */ +#words { + font-family: var(--font-main); + letter-spacing: var(--letter-spacing-main); + font-weight: 400; +} + +.keyTips, +.keyTip { + font-family: var(--font-headings); +} + +.pageTitle { + font-family: var(--font-headings); + font-weight: 700; + text-shadow: 0 0 10px var(--main-color); +} + +nav { + gap: 0.5rem; + font-family: var(--font-headings); +} + +header.focus nav > .textButton, +header.focus nav:before, +header.focus nav:after { + background: var(--sub-color); + transition: all 0.2s ease; +} + +nav > .textButton { + border-radius: 10rem !important; + color: #1a1025; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + font-size: 0.85rem; + transition: all 0.3s ease; + transform: translateY(0); +} + +nav > .textButton:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); +} + +/* Uncomment if you want the red circle at the beginning +nav:before { + content: ""; + background: #f94348; + width: 1.25rem; + height: 1.25rem; + padding: 0.5rem; + border-radius: 10rem; +} */ + +/* Navigation button colors */ +nav > .textButton:nth-child(1) { + background: #ff6bcf; +} + +nav > .textButton:nth-child(2) { + background: #b278ff; +} + +nav > .textButton:nth-child(3) { + background: #78c9ff; +} + +nav > .textButton:nth-child(4) { + background: #78ffb9; +} + +header.focus nav > .textButton:nth-child(6) { + background: transparent !important; +} + +nav > .textButton:nth-child(6) { + color: var(--sub-color); +} + +nav > .textButton:nth-child(6):hover { + color: var(--text-color); +} + +nav > .textButton:nth-child(7) { + background: #ffcf78; +} + +nav > .textButton:nth-child(8) { + background: #f94348; +} + +nav:after { + content: ""; + background: #ff9349; + width: 1.25rem; + height: 1.25rem; + padding: 0.5rem; + border-radius: 10rem; +} + +header.focus nav > .textButton.discord::after { + border-color: transparent; +} + +nav > .textButton.view-account .xpBar { + bottom: -0.75rem !important; +} + +/* CRT Mode Effects */ +body.crtmode nav > .textButton:nth-child(1) { + box-shadow: 3px 0 1px color-mix(in srgb, #ff6bcf 20%, transparent), + -3px 0 color-mix(in srgb, #ff6bcf 30%, transparent), 0 0 3px; +} + +body.crtmode nav > .textButton:nth-child(2) { + box-shadow: 3px 0 1px color-mix(in srgb, #b278ff 20%, transparent), + -3px 0 color-mix(in srgb, #b278ff 30%, transparent), 0 0 3px; +} + +body.crtmode nav > .textButton:nth-child(3) { + box-shadow: 3px 0 1px color-mix(in srgb, #78c9ff 20%, transparent), + -3px 0 color-mix(in srgb, #78c9ff 30%, transparent), 0 0 3px; +} + +body.crtmode nav > .textButton:nth-child(4) { + box-shadow: 3px 0 1px color-mix(in srgb, #78ffb9 20%, transparent), + -3px 0 color-mix(in srgb, #78ffb9 30%, transparent), 0 0 3px; +} + +body.crtmode nav > .textButton:nth-child(7) { + box-shadow: 3px 0 1px color-mix(in srgb, #ffcf78 20%, transparent), + -3px 0 color-mix(in srgb, #ffcf78 30%, transparent), 0 0 3px; +} + +body.crtmode nav > .textButton:nth-child(8) { + box-shadow: 3px 0 1px color-mix(in srgb, #ff9cd8 20%, transparent), + -3px 0 color-mix(in srgb, #ff9cd8 30%, transparent), 0 0 3px; +} + +body.crtmode header.focus nav > .textButton { + box-shadow: 3px 0 1px var(--crt-sub-color-glow), + -3px 0 var(--crt-sub-color-glow); +} + +body.crtmode header.focus nav > .textButton.view-account { + box-shadow: none; +} + +/* Text input styling */ +#wordsInput { + caret-color: var(--caret-color); + caret-width: 0.15em; + font-family: var(--font-main); + position: relative; +} + +#wordsInput::after { + content: ""; + position: absolute; + bottom: -5px; + left: 0; + width: 100%; + height: 2px; + background: linear-gradient( + to right, + var(--accent-purple), + var(--accent-pink), + var(--accent-blue) + ); + transform: scaleX(0); + transform-origin: center; + transition: transform 0.5s var(--animation-curve); +} + +#wordsInput:focus::after { + transform: scaleX(1); +} + +/* Letter styling */ +letter { + transition: all var(--transition-speed) var(--animation-curve); + font-family: var(--font-main); + position: relative; + padding: 0 1px; +} + +letter.correct { + color: var(--main-color); + text-shadow: 0 0 5px rgba(228, 194, 255, 0.5); +} + +letter.incorrect { + color: var(--error-color); + text-shadow: 0 0 5px rgba(255, 94, 148, 0.5); + animation: shake 0.2s ease-in-out; +} + +@keyframes shake { + 0%, + 100% { + transform: translateX(0); + } + 25% { + transform: translateX(-1px); + } + 75% { + transform: translateX(1px); + } +} + +letter.active { + background: linear-gradient( + to bottom, + transparent 60%, + var(--accent-purple) 60%, + var(--accent-purple) 70%, + transparent 70% + ); + font-weight: 700; +} + +/* UI elements */ +.button, +.keyTip { + border-radius: 8px; + font-family: var(--font-headings); + text-transform: uppercase; + letter-spacing: var(--letter-spacing-headings); + transition: all var(--transition-speed) var(--animation-curve); + position: relative; + border: none; + background: linear-gradient(135deg, var(--sub-alt-color), var(--bg-color)); + color: var(--main-color); + overflow: hidden; + z-index: 1; +} + +.button::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: linear-gradient(135deg, var(--accent-purple), var(--accent-pink)); + opacity: 0; + z-index: -1; + transition: opacity var(--transition-speed) var(--animation-curve); +} + +.button:hover::before { + opacity: 0.2; +} + +.button::after { + content: ""; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: radial-gradient( + circle, + rgba(228, 194, 255, 0.3) 0%, + transparent 50% + ); + opacity: 0; + transform: scale(0.5); + transition: transform 0.5s var(--animation-curve), + opacity 0.5s var(--animation-curve); +} + +.button:hover::after { + opacity: 1; + transform: scale(1); +} + +.button:hover { + transform: translateY(-2px); + box-shadow: 0 4px 12px rgba(228, 194, 255, 0.3); + color: var(--text-color); +} + +.button:active { + transform: translateY(1px); + box-shadow: 0 2px 5px rgba(228, 194, 255, 0.2); +} + +.keyTip { + background: var(--sub-alt-color); + border-left: 3px solid var(--accent-blue); + padding: 0.5rem 1rem; + position: relative; + overflow: hidden; +} + +.keyTip::after { + content: ""; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: linear-gradient( + to right, + transparent, + rgba(120, 201, 255, 0.1), + transparent + ); + transform: translateX(-100%); + animation: shimmer 3s infinite; +} + +@keyframes shimmer { + 100% { + transform: translateX(100%); + } +} + +/* Custom scrollbar */ +::-webkit-scrollbar { + width: 8px; +} + +::-webkit-scrollbar-track { + background: var(--sub-alt-color); + border-radius: 10px; +} + +::-webkit-scrollbar-thumb { + background: linear-gradient( + to bottom, + var(--accent-purple), + var(--accent-pink) + ); + border-radius: 10px; + border: 2px solid var(--sub-alt-color); +} + +::-webkit-scrollbar-thumb:hover { + background: linear-gradient( + to bottom, + var(--accent-pink), + var(--accent-purple) + ); + box-shadow: 0 0 8px var(--accent-pink); +} + +#result .stats { + font-family: var(--font-headings); +} + +.stats .stat { + border-radius: 8px; + transition: all 0.3s ease; +} + +.stats .stat:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3); +} + +#timerNumber { + font-family: var(--font-alt); + font-weight: 700; + color: var(--main-color); + font-size: 1.5rem; + position: relative; + padding: 0.5rem 1rem; + border-radius: 50px; + background: linear-gradient( + 135deg, + rgba(26, 16, 37, 0.7), + rgba(37, 26, 54, 0.8) + ); + box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.2); + backdrop-filter: blur(2px); + border: 2px solid transparent; + background-clip: padding-box; +} + +#timerNumber::before { + content: ""; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + background: linear-gradient( + 135deg, + var(--accent-purple), + var(--accent-pink), + var(--accent-blue) + ); + border-radius: 50px; + z-index: -1; +} + +@keyframes timerPulse { + 0% { + opacity: 1; + } + 50% { + opacity: 0.7; + } + 100% { + opacity: 1; + } +} + +#timerNumber.hurry { + color: var(--accent-red); + animation: timerPulse 0.5s infinite; +} + +/* Dropdown menu styling */ +.dropdown { + background: rgba(26, 16, 37, 0.95); + backdrop-filter: blur(10px); + border-radius: 10px; + border: 2px solid var(--sub-color); + overflow: hidden; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3), 0 0 15px rgba(138, 124, 163, 0.2); + animation: dropdownFadeIn 0.3s var(--animation-curve); +} + +@keyframes dropdownFadeIn { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.dropdown .text { + font-family: var(--font-headings); + letter-spacing: var(--letter-spacing-headings); +} + +.dropdown .hint { + font-family: var(--font-alt); + opacity: 0.7; + font-size: 0.8rem; +} + +/* Result screen custom animation */ +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +#result { + animation: fadeInUp 0.5s ease-out; + border-radius: 15px; + border: 2px solid var(--accent-purple); + background: linear-gradient( + 135deg, + rgba(26, 16, 37, 0.8), + rgba(37, 26, 54, 0.9) + ); + backdrop-filter: blur(10px); + box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2), 0 0 15px rgba(178, 120, 255, 0.2); + padding: 2rem; + position: relative; + overflow: hidden; +} + +#result::before { + content: ""; + position: absolute; + top: -50%; + left: -50%; + width: 200%; + height: 200%; + background: radial-gradient( + circle, + rgba(228, 194, 255, 0.1) 0%, + transparent 50% + ); + animation: pulse 15s infinite linear; + z-index: -1; +} + +@keyframes pulse { + 0% { + transform: scale(1); + opacity: 0.5; + } + 50% { + transform: scale(1.2); + opacity: 0.3; + } + 100% { + transform: scale(1); + opacity: 0.5; + } +} + +#result .stats { + display: flex; + flex-wrap: wrap; + gap: 1rem; + justify-content: center; +} + +#result .stats .stat { + flex: 1; + min-width: 120px; + background: linear-gradient( + 135deg, + rgba(37, 26, 54, 0.8), + rgba(26, 16, 37, 0.9) + ); + border-left: 3px solid var(--accent-pink); + border-radius: 8px; + padding: 1rem; + backdrop-filter: blur(5px); + animation: fadeInRight 0.5s ease-out forwards; + animation-delay: calc(var(--stat-index, 0) * 0.1s); + opacity: 0; +} + +@keyframes fadeInRight { + from { + opacity: 0; + transform: translateX(-20px); + } + to { + opacity: 1; + transform: translateX(0); + } +} + +#result .stats .stat:nth-child(1) { + --stat-index: 0; +} +#result .stats .stat:nth-child(2) { + --stat-index: 1; +} +#result .stats .stat:nth-child(3) { + --stat-index: 2; +} +#result .stats .stat:nth-child(4) { + --stat-index: 3; +} +#result .stats .stat:nth-child(5) { + --stat-index: 4; +} + +#result .stats .stat .title { + font-family: var(--font-headings); + letter-spacing: var(--letter-spacing-headings); + text-transform: uppercase; + font-size: 0.8rem; + color: var(--sub-color); + margin-bottom: 0.5rem; +} + +#result .stats .stat .value { + font-family: var(--font-alt); + font-size: 1.5rem; + font-weight: 700; + color: var(--main-color); + background: linear-gradient( + to right, + var(--accent-purple), + var(--accent-pink) + ); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); +}