diff --git a/client/src/App.jsx b/client/src/App.jsx index a7cb72a..fcf746c 100644 --- a/client/src/App.jsx +++ b/client/src/App.jsx @@ -1,19 +1,63 @@ import Game from "./pages/Game"; -import {useContext} from "react"; +import {useContext, useEffect, useState} from "react"; import {StateContext} from "@/common/contexts/StateContext"; import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; -import {faMusic} from "@fortawesome/free-solid-svg-icons"; +import {faDrum, faGuitar, faHeadphones, faMusic} from "@fortawesome/free-solid-svg-icons"; import Home from "@/pages/Home"; const App = () => { const {currentState} = useContext(StateContext); + const [cursorPos, setCursorPos] = useState({ x: 0, y: 0 }); + + const musicNotes = [ + { id: 1, top: "8%", left: "20%", icon: faMusic, scale: 1.2 }, + { id: 2, top: "75%", left: "85%", icon: faGuitar, scale: 1 }, + { id: 3, top: "65%", left: "12%", icon: faHeadphones, scale: 1.1 }, + { id: 4, top: "20%", left: "70%", icon: faDrum, scale: 0.9 } + ]; + + useEffect(() => { + const handleMouseMove = (e) => { + if (!handleMouseMove.ticking) { + handleMouseMove.ticking = true; + requestAnimationFrame(() => { + setCursorPos({ x: e.clientX, y: e.clientY }); + handleMouseMove.ticking = false; + }); + } + }; + handleMouseMove.ticking = false; + + window.addEventListener('mousemove', handleMouseMove); + return () => window.removeEventListener('mousemove', handleMouseMove); + }, []); + return ( <>
- - - +
+
+
+ + {musicNotes.map((note) => ( +
+ +
+ ))}
{currentState === "Home" && } {currentState === "Game" && } diff --git a/client/src/common/styles/colors.sass b/client/src/common/styles/colors.sass index 1da91a4..d8fafb0 100644 --- a/client/src/common/styles/colors.sass +++ b/client/src/common/styles/colors.sass @@ -5,4 +5,11 @@ $green: #26EE5E $black: #000 $dark-gray: #1e1e1e $light-gray: #aaa -$red: #ff0000 \ No newline at end of file +$red: #ff0000 + +$pink: #ff6bb3 +$blue: #4d9dff +$purple: #9c6bff +$cyan: #6bffea +$yellow: #ffde6b +$mint-green: #85ffbd \ No newline at end of file diff --git a/client/src/common/styles/main.sass b/client/src/common/styles/main.sass index cfec2ed..83a9d7b 100644 --- a/client/src/common/styles/main.sass +++ b/client/src/common/styles/main.sass @@ -10,10 +10,70 @@ body color: #E0E0E0 font-family: 'Bangers', sans-serif height: 100vh - background: linear-gradient(135deg, #0f2027, #203a43, #2c5364) + width: 100vw + background-size: 300% 300% + animation: shifting-background 30s ease infinite + background: linear-gradient(45deg, #4d3ae7 0%, #b84bc3 50%, #ff6a88 100%) fixed user-select: none overflow: hidden position: relative + + &:before + content: "" + position: fixed + top: 0 + left: 0 + right: 0 + bottom: 0 + background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%23ffffff' fill-opacity='0.05' fill-rule='evenodd'/%3E%3C/svg%3E") + + .background-overlay + position: fixed + top: 0 + left: 0 + width: 100vw + height: 100vh + z-index: 0 + pointer-events: none + + .rotating-gradient + position: absolute + top: 50% + left: 50% + width: 250vh + height: 250vh + transform: translate(-50%, -50%) + background: conic-gradient(from 0deg, rgba(255, 102, 196, 0.2), rgba(102, 204, 255, 0.2), rgba(255, 209, 128, 0.2), rgba(133, 255, 189, 0.2), rgba(255, 102, 196, 0.2)) + border-radius: 50% + animation: rotate-background 180s linear infinite + will-change: transform + transform-origin: center center + opacity: 0.7 + filter: blur(40px) + + &:after + content: "" + position: fixed + top: 0 + left: 0 + right: 0 + bottom: 0 + background: radial-gradient(circle at center, transparent 0%, rgba(0, 0, 0, 0.1) 60%, rgba(0, 0, 0, 0.4) 100%) + z-index: 1 + pointer-events: none + +::-webkit-scrollbar + width: 8px + background-color: rgba(0, 0, 0, 0.2) + border-radius: 4px + +::-webkit-scrollbar-thumb + background-color: rgba(255, 255, 255, 0.15) + border-radius: 4px + border: 1px solid rgba(255, 255, 255, 0.05) + + &:hover + background-color: rgba(255, 255, 255, 0.25) .glassy background: $background @@ -21,40 +81,150 @@ body border: 2px solid $border border-radius: 0.8rem -::-webkit-scrollbar - width: 10px - .background-elements - position: absolute + position: fixed top: 0 left: 0 - width: 100% - height: 100% + width: 100vw + height: 100vh overflow: hidden - z-index: 0 + z-index: 2 + pointer-events: none + + .glow-point + position: absolute + width: 250px + height: 250px + border-radius: 50% + filter: blur(100px) + opacity: 0.4 + will-change: transform + transform: translateZ(0) + + &.point-1 + top: 20% + left: 10% + background-color: rgba(255, 102, 196, 0.8) + animation: float-glow 15s infinite alternate ease-in-out + + &.point-2 + top: 70% + left: 80% + background-color: rgba(102, 204, 255, 0.8) + animation: float-glow 18s infinite alternate-reverse ease-in-out + + &.point-3 + top: 80% + left: 20% + background-color: rgba(133, 255, 189, 0.8) + animation: float-glow 12s infinite alternate ease-in-out 2s .music-note position: absolute - font-size: 24pt - color: rgba(255, 255, 255, 0.5) - animation: float-notes 5s infinite ease-in-out + font-size: 60pt + opacity: 0.7 + will-change: transform, opacity, filter + filter: drop-shadow(0 0 15px rgba(255, 255, 255, 0.7)) + transform: translateZ(0) + backface-visibility: hidden + + @for $i from 1 through 5 + &.note-#{$i} + animation-name: float-note-#{$i}, pulse-note + animation-duration: #{10 + ($i * 1)}s, 5s + animation-timing-function: ease-in-out, ease-in-out + animation-iteration-count: infinite, infinite + animation-direction: alternate, alternate + animation-delay: #{$i * 0.7}s, #{$i * 0.4}s + + @if $i % 4 == 0 + color: rgba(255, 102, 196, 0.8) + @else if $i % 4 == 1 + color: rgba(102, 204, 255, 0.8) + @else if $i % 4 == 2 + color: rgba(255, 209, 128, 0.8) + @else + color: rgba(133, 255, 189, 0.8) - &.note-1 - top: 20% - left: 30% +.card-element + background: rgba(255, 255, 255, 0.07) + backdrop-filter: blur(10px) + border: 1px solid rgba(255, 255, 255, 0.2) + border-radius: 20px + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1), 0 0 20px rgba(255, 255, 255, 0.1) + overflow: hidden + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) + animation: card-float 6s infinite ease-in-out alternate - &.note-2 - top: 60% - left: 80% + &:hover + transform: translateY(-10px) scale(1.02) + box-shadow: 0 15px 50px rgba(0, 0, 0, 0.2), 0 0 40px rgba(255, 255, 255, 0.2) + border: 1px solid rgba(255, 255, 255, 0.4) - &.note-3 - top: 90% - left: 50% - -@keyframes float-notes +@keyframes shifting-background 0% + background-position: 0% 0% + 50% + background-position: 100% 100% + 100% + background-position: 0% 0% + +@keyframes rotate-background + 0% + transform: translate(-50%, -50%) rotate(0deg) + 100% + transform: translate(-50%, -50%) rotate(360deg) + +@keyframes float-glow + 0%, 100% + transform: translate(0, 0) scale(1) + filter: blur(100px) + 50% + transform: translate(30px, -20px) scale(1.2) + filter: blur(80px) + +@keyframes card-float + 0%, 100% transform: translateY(0) 50% - transform: translateY(-10px) - 100% - transform: translateY(0) \ No newline at end of file + transform: translateY(-8px) + +@keyframes float-note-1 + 0%, 100% + transform: translateY(0) rotate(0deg) + 50% + transform: translateY(-40px) rotate(10deg) + +@keyframes float-note-2 + 0%, 100% + transform: translateY(0) rotate(0deg) + 50% + transform: translateY(-30px) rotate(-8deg) + +@keyframes float-note-3 + 0%, 100% + transform: translateY(0) rotate(0deg) + 50% + transform: translateY(-50px) rotate(15deg) + +@keyframes float-note-4 + 0%, 100% + transform: translateY(0) rotate(0deg) + 33% + transform: translateY(-25px) rotate(-5deg) + 66% + transform: translateY(-40px) rotate(5deg) + +@keyframes float-note-5 + 0%, 100% + transform: translateY(0) rotate(0deg) + 50% + transform: translateY(-35px) rotate(-12deg) + +@keyframes pulse-note + 0%, 100% + filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.5)) + opacity: 0.6 + 50% + filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.7)) + opacity: 0.9 \ No newline at end of file diff --git a/client/src/pages/Game/Game.jsx b/client/src/pages/Game/Game.jsx index ae56947..a652052 100644 --- a/client/src/pages/Game/Game.jsx +++ b/client/src/pages/Game/Game.jsx @@ -7,10 +7,11 @@ import {faMessage} from "@fortawesome/free-solid-svg-icons"; export const Game = () => { const {setCurrentState} = useContext(StateContext); - const [messages, setMessages] = useState([{sender: "Marco", text: "Hallo!"},]); + const [messages, setMessages] = useState([{sender: "Marco", text: "Hallo!"}]); const [inputValue, setInputValue] = useState(""); const messageEndRef = useRef(null); + useEffect(() => { messageEndRef.current?.scrollIntoView({behavior: "smooth"}); }, [messages]); @@ -24,13 +25,15 @@ export const Game = () => { return (
+
+
+
+

ToneGuessr

- Song + Song
Black Steam
von Carrot Quest GmbH
@@ -52,7 +55,8 @@ export const Game = () => {
- setInputValue(e.target.value)} + setInputValue(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()} placeholder="Gib eine Nachricht ein..." /> diff --git a/client/src/pages/Game/components/MusicSlider/MusicSlider.jsx b/client/src/pages/Game/components/MusicSlider/MusicSlider.jsx index e377b1c..d54b4d9 100644 --- a/client/src/pages/Game/components/MusicSlider/MusicSlider.jsx +++ b/client/src/pages/Game/components/MusicSlider/MusicSlider.jsx @@ -32,7 +32,7 @@ export const MusicSlider = () => { useEffect(() => { const handleMouseMove = (e) => dragging && handleFrequencyChange(e); const handleMouseUpGlobal = () => dragging && handleMouseUp(); - + document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUpGlobal); @@ -83,25 +83,22 @@ export const MusicSlider = () => { return (
+
+
+
+
+
+
+
-
-
-
-
-
-
-
) diff --git a/client/src/pages/Game/components/MusicSlider/styles.sass b/client/src/pages/Game/components/MusicSlider/styles.sass index 6372dbc..6333a4e 100644 --- a/client/src/pages/Game/components/MusicSlider/styles.sass +++ b/client/src/pages/Game/components/MusicSlider/styles.sass @@ -8,77 +8,169 @@ left: 0 right: 0 bottom: 0 - padding: 20px - background-color: rgba(30, 30, 30, 0.5) - backdrop-filter: blur(10px) - border-radius: 20px - margin: 20px - z-index: 1 + padding: 20px 30px 30px 30px + background: rgba(20, 20, 30, 0.75) + backdrop-filter: blur(15px) + border-radius: 30px 30px 0 0 + margin: 0 + z-index: 10 + box-shadow: 0 -5px 30px rgba(0, 0, 0, 0.3), 0 -2px 10px rgba(255, 255, 255, 0.1) + border-top: 1px solid rgba(255, 255, 255, 0.3) + border-left: 1px solid rgba(255, 255, 255, 0.2) + border-right: 1px solid rgba(255, 255, 255, 0.2) + transition: transform 0.3s ease + width: 100% .otamatone display: flex flex-direction: row align-items: center cursor: pointer - padding: 10px + padding: 15px width: 100% + max-width: 1200px + margin: 0 auto .otamatone-neck flex: 1 - height: 20px - background: linear-gradient(135deg, #000, #444) - border-radius: 10px + height: 40px + background: linear-gradient(135deg, #2c2c3a, #444455) + border-radius: 20px position: relative + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5), inset 0 -2px 10px rgba(255, 255, 255, 0.15) + margin: 0 20px + + &:before + content: "" + position: absolute + left: 0 + right: 0 + top: 0 + height: 50% + border-radius: 20px 20px 0 0 + background: linear-gradient(to bottom, rgba(255, 255, 255, 0.3), transparent) + pointer-events: none + + &:after + content: "" + position: absolute + left: 5% + right: 5% + top: 50% + height: 1px + background: rgba(255, 255, 255, 0.2) + pointer-events: none .frequency-indicator position: absolute - top: -10px - width: 20px - height: 20px - background-color: #ff0000 + top: -20px + width: 40px + height: 40px + background: linear-gradient(135deg, $pink, darken($pink, 15%)) border-radius: 50% transform: translateX(-50%) + box-shadow: 0 0 20px rgba(255, 107, 179, 0.7) + border: 2px solid rgba(255, 255, 255, 0.8) + z-index: 1 + transition: transform 0.1s ease + cursor: grab + + &:hover + transform: translateX(-50%) scale(1.1) + + &:active + cursor: grabbing + transform: translateX(-50%) scale(0.95) .note-marker position: absolute - top: -30px - font-size: 24pt + top: -50px + font-size: 32pt color: $white + text-shadow: 0 0 15px rgba(255, 255, 255, 0.7) + font-weight: bold .otamatone-face - width: 100px - height: 100px - background: radial-gradient(circle, #fff, #ddd) + width: 140px + height: 140px + background: radial-gradient(circle at 30% 30%, #fff, #f0f0f0) border-radius: 50% display: flex flex-direction: column align-items: center justify-content: center - position: absolute + position: relative left: 0 - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2) + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5), inset 0 -3px 10px rgba(0, 0, 0, 0.2), inset 0 3px 10px rgba(255, 255, 255, 0.8) + border: 1px solid rgba(255, 255, 255, 0.9) + margin-right: 15px + + &:before + content: "" + position: absolute + width: 80% + height: 80% + border-radius: 50% + background: radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.9), transparent) + pointer-events: none .otamatone-eyes display: flex justify-content: space-between width: 60% position: absolute - top: 30px + top: 40px .eye - width: 15px - height: 15px + width: 22px + height: 22px background-color: #000 border-radius: 50% + position: relative + animation: blink 4s infinite ease-in-out + + &:before + content: "" + position: absolute + width: 30% + height: 30% + background-color: #fff + border-radius: 50% + top: 15% + left: 15% .left-eye - margin-right: 10px + margin-right: 20px .right-eye - margin-left: 10px + margin-left: 20px .otamatone-mouth background-color: #000 border-radius: 50% position: absolute - bottom: 10px \ No newline at end of file + bottom: 30px + width: 30px + height: 30px + transition: all 0.3s ease + animation: mouth-pulse 5s infinite alternate ease-in-out + +@keyframes blink + 0%, 90%, 100% + transform: scaleY(1) + 95% + transform: scaleY(0.1) + +@keyframes mouth-pulse + 0%, 100% + transform: scale(1) + 50% + transform: scale(1.2) + +@keyframes slider-enter + 0% + transform: translateY(100%) + opacity: 0 + 100% + transform: translateY(0) + opacity: 1 \ No newline at end of file diff --git a/client/src/pages/Game/styles.sass b/client/src/pages/Game/styles.sass index 432c3d1..8925e12 100644 --- a/client/src/pages/Game/styles.sass +++ b/client/src/pages/Game/styles.sass @@ -6,7 +6,10 @@ align-items: center justify-content: center height: 100vh + width: 100vw padding: 20px + position: relative + animation: page-fade-in 1s ease-in-out .main-content display: flex @@ -15,7 +18,9 @@ justify-content: center width: 100% padding: 20px - z-index: 1 + z-index: 2 + position: relative + animation: float-up 1.5s ease-out .song-display display: flex @@ -28,27 +33,70 @@ text-align: center h2 - font-size: 36pt + font-size: 52pt color: $white - margin-bottom: 20px + margin-bottom: 25px + position: relative + z-index: 2 + background: linear-gradient(135deg, $pink, $blue 45%, $mint-green 65%, $yellow 85%, $pink) + background-size: 300% 100% + animation: title-shimmer 10s infinite alternate ease-in-out, title-float 6s infinite ease-in-out + -webkit-background-clip: text + background-clip: text + -webkit-text-fill-color: transparent + filter: drop-shadow(0 0 15px rgba(255, 255, 255, 0.7)) + letter-spacing: 0.1em + font-weight: bold + + &:before + content: "ToneGuessr" + position: absolute + z-index: -1 + left: 0 + top: 0 + background: none + -webkit-text-fill-color: transparent + filter: blur(15px) brightness(1.3) + opacity: 0.6 + width: 100% + height: 100% .song-card display: flex flex-direction: row align-items: center - background-color: rgba(255, 255, 255, 0.1) - padding: 20px + background: rgba(255, 255, 255, 0.08) + padding: 25px border-radius: 20px - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5) + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.2), 0 0 20px rgba(255, 255, 255, 0.1) backdrop-filter: blur(10px) border: 1px solid rgba(255, 255, 255, 0.2) max-width: 500px + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) + will-change: transform, box-shadow + transform: translateZ(0) + backface-visibility: hidden + animation: card-pulse 6s infinite alternate ease-in-out + + &:hover + transform: translateY(-10px) scale(1.02) + box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3), 0 0 30px rgba(255, 255, 255, 0.15) + border: 1px solid rgba(255, 255, 255, 0.4) img - width: 100px - height: 100px - border-radius: 10px - margin-right: 20px + width: 120px + height: 120px + border-radius: 15px + margin-right: 25px + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4) + transition: transform 0.3s ease + will-change: transform + transform: translateZ(0) + animation: album-rotate 10s infinite alternate ease-in-out + + &:hover + transform: scale(1.1) rotate(5deg) + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5), 0 0 40px rgba(102, 204, 255, 0.3) .song-info display: flex @@ -56,76 +104,227 @@ align-items: flex-start .song-names - font-size: 24pt + font-size: 28pt color: $white margin-bottom: 10px + text-shadow: 0 0 10px rgba(255, 255, 255, 0.5) + animation: text-shimmer 5s infinite alternate ease-in-out .song-description - font-size: 14pt + font-size: 16pt color: $border + opacity: 0.8 + position: relative + + &:after + content: "" + position: absolute + bottom: -5px + left: 0 + width: 0% + height: 1px + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent) + transition: all 0.4s ease + + &:hover:after + width: 100% .chat-window width: 50% - height: 400px - background: rgba(255, 255, 255, 0.1) + height: 450px + background: rgba(255, 255, 255, 0.08) backdrop-filter: blur(10px) - border-radius: 10px - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1) + border-radius: 20px + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.2), 0 0 20px rgba(255, 255, 255, 0.1) border: 1px solid rgba(255, 255, 255, 0.2) display: flex flex-direction: column overflow: hidden + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) + will-change: box-shadow, border + transform: translateZ(0) + backface-visibility: hidden + animation: card-float 6s infinite ease-in-out alternate 0.5s + + &:hover + box-shadow: 0 15px 40px rgba(0, 0, 0, 0.3), 0 0 30px rgba(255, 255, 255, 0.15) + border: 1px solid rgba(255, 255, 255, 0.4) .chat-header display: flex align-items: center - padding: 10px + padding: 15px background: rgba(30, 30, 30, 0.5) border-bottom: 1px solid rgba(255, 255, 255, 0.2) + + svg + font-size: 18pt + color: $white + filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.5)) + animation: icon-pulse 3s infinite alternate ease-in-out .chat-title - margin-left: 10px - font-size: 16pt + margin-left: 15px + font-size: 18pt color: $white + text-shadow: 0 0 10px rgba(255, 255, 255, 0.5) .chat-messages flex: 1 padding: 10px overflow-y: auto color: $white + position: relative + + &::-webkit-scrollbar + width: 8px + background: rgba(0, 0, 0, 0.2) + border-radius: 4px + + &::-webkit-scrollbar-thumb + background: rgba(255, 255, 255, 0.2) + border-radius: 4px + + &:hover + background: rgba(255, 255, 255, 0.3) .message margin-bottom: 10px + padding: 8px 12px + border-radius: 12px + background: rgba(255, 255, 255, 0.05) + backdrop-filter: blur(5px) + border: 1px solid rgba(255, 255, 255, 0.1) + transition: all 0.3s ease + animation: message-fade-in 0.5s ease-out + + &:hover + background: rgba(255, 255, 255, 0.1) + transform: translateY(-2px) .message-sender font-weight: bold + color: $yellow + margin-right: 5px .message-text - margin-left: 10px + margin-left: 5px .chat-input display: flex - padding: 10px + padding: 15px background: rgba(30, 30, 30, 0.5) border-top: 1px solid rgba(255, 255, 255, 0.2) input flex: 1 - padding: 10px + padding: 12px 15px border: none - border-radius: 5px + border-radius: 10px outline: none - background: $background + background: rgba(0, 0, 0, 0.3) color: $white + font-family: 'Bangers', sans-serif + letter-spacing: 0.1rem + backdrop-filter: blur(5px) + transition: all 0.3s ease + will-change: box-shadow + + &:focus + box-shadow: 0 0 20px rgba(255, 255, 255, 0.3) + background: rgba(0, 0, 0, 0.4) button - margin-left: 10px - padding: 10px - background-color: #203a43 - color: #fff + margin-left: 15px + padding: 12px 20px + background: linear-gradient(135deg, $purple, $blue) + color: $white border: none - border-radius: 5px + border-radius: 10px cursor: pointer - + font-family: 'Bangers', sans-serif + letter-spacing: 0.1rem + transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) + text-shadow: 0 0 10px rgba(255, 255, 255, 0.5) + will-change: transform, background, box-shadow + transform: translateZ(0) + position: relative + overflow: hidden + + &:before + content: "" + position: absolute + top: -50% + left: -50% + width: 200% + height: 200% + background: radial-gradient(circle, rgba(255, 255, 255, 0.3) 0%, transparent 70%) + opacity: 0 + transition: opacity 0.5s ease + &:hover - background-color: #1e1e1e \ No newline at end of file + transform: translateY(-3px) scale(1.05) + background: linear-gradient(135deg, lighten($purple, 5%), lighten($blue, 5%)) + box-shadow: 0 0 20px rgba(102, 204, 255, 0.7) + + &:before + opacity: 1 + animation: rotate-background 5s linear infinite + +@keyframes subtle-text-glow + 0%, 100% + text-shadow: 0 0 10px rgba(255, 255, 255, 0.4) + 50% + text-shadow: 0 0 15px rgba(255, 255, 255, 0.6), 0 0 25px rgba(255, 255, 255, 0.3) + +@keyframes title-glow + 0%, 100% + text-shadow: 0 0 10px rgba(255, 255, 255, 0.5), 0 0 30px rgba(102, 204, 255, 0.4) + 50% + text-shadow: 0 0 15px rgba(255, 255, 255, 0.7), 0 0 40px rgba(102, 204, 255, 0.6), 0 0 60px rgba(102, 204, 255, 0.3) + +@keyframes text-shimmer + 0%, 100% + opacity: 0.95 + text-shadow: 0 0 10px rgba(255, 255, 255, 0.5) + 50% + opacity: 1 + text-shadow: 0 0 15px rgba(255, 255, 255, 0.7), 0 0 25px rgba(133, 255, 189, 0.5) + +@keyframes album-rotate + 0%, 100% + transform: rotate(-2deg) + 50% + transform: rotate(2deg) + +@keyframes icon-pulse + 0%, 100% + filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.5)) + transform: scale(1) + 50% + filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.8)) + transform: scale(1.1) + +@keyframes message-fade-in + 0% + opacity: 0 + transform: translateY(10px) + 100% + opacity: 1 + transform: translateY(0) + +@keyframes title-shimmer + 0% + background-position: 0% 50% + 50% + background-position: 100% 50% + 100% + background-position: 0% 50% + +@keyframes title-float + 0%, 100% + transform: translateY(0) scale(1) rotate(-1deg) + filter: drop-shadow(0 0 15px rgba(255, 255, 255, 0.7)) + 50% + transform: translateY(-10px) scale(1.05) rotate(1deg) + filter: drop-shadow(0 0 25px rgba(255, 255, 255, 0.9)) drop-shadow(0 0 50px rgba(102, 204, 255, 0.6)) \ No newline at end of file diff --git a/client/src/pages/Home/Home.jsx b/client/src/pages/Home/Home.jsx index 2c7a5ff..269db92 100644 --- a/client/src/pages/Home/Home.jsx +++ b/client/src/pages/Home/Home.jsx @@ -9,9 +9,18 @@ export const Home = () => { return (
+
+
+
+ +
+

ToneGuessr

+

Das Frequenzspiel für Marco :3

+
+
- {}} /> - setCurrentState("Game")} /> + {}} /> + setCurrentState("Game")} />
); diff --git a/client/src/pages/Home/components/ActionCard/ActionCard.jsx b/client/src/pages/Home/components/ActionCard/ActionCard.jsx index 4f1aa68..75691e5 100644 --- a/client/src/pages/Home/components/ActionCard/ActionCard.jsx +++ b/client/src/pages/Home/components/ActionCard/ActionCard.jsx @@ -1,11 +1,11 @@ -import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import "./styles.sass"; +import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; -export const ActionCard = ({ title, icon, onClick }) => { - return ( -
- -

{title}

-
- ); -} \ No newline at end of file +export const ActionCard = ({title, icon, onClick}) => { + return ( +
+ +

{title}

+
+ ); +}; \ No newline at end of file diff --git a/client/src/pages/Home/components/ActionCard/styles.sass b/client/src/pages/Home/components/ActionCard/styles.sass index 44aa13d..1d1e61e 100644 --- a/client/src/pages/Home/components/ActionCard/styles.sass +++ b/client/src/pages/Home/components/ActionCard/styles.sass @@ -3,21 +3,94 @@ .action-card display: flex flex-direction: column - padding: 2rem 0 - width: 13rem + padding: 2.5rem 1.5rem + width: 15rem text-align: center gap: 2rem - transition: all 0.3s ease-in-out + transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) cursor: pointer user-select: none + background: rgba(255, 255, 255, 0.07) + backdrop-filter: blur(10px) + border: 1px solid rgba(255, 255, 255, 0.2) + border-radius: 20px + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1), 0 0 20px rgba(255, 255, 255, 0.1) + position: relative + overflow: hidden + transform: translateZ(0) + backface-visibility: hidden + animation: card-pulse 6s infinite alternate ease-in-out + + &:nth-child(odd) + animation-delay: 1s + + &:before + content: "" + position: absolute + top: -50% + left: -50% + width: 200% + height: 200% + background: radial-gradient(circle, rgba(255, 255, 255, 0.15) 0%, transparent 70%) + opacity: 0 + transition: opacity 0.5s ease svg - font-size: 52pt + font-size: 62pt color: $white + filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3)) + transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) + transform: translateZ(0) + animation: icon-glow 5s infinite alternate ease-in-out h1 margin: 0 color: $white + text-shadow: 0 0 10px rgba(255, 255, 255, 0.5) + transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275) + transform: translateZ(0) + position: relative + + &:after + content: "" + position: absolute + bottom: -5px + left: 25% + width: 0% + height: 2px + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.7), transparent) + transition: all 0.4s ease &:hover - transform: scale(1.1) translate(0, -0.5rem) rotate(0.5deg) \ No newline at end of file + transform: scale(1.05) translate(0, -0.5rem) rotate(0.5deg) + border: 1px solid rgba(255, 255, 255, 0.5) + box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2), 0 0 30px rgba(255, 255, 255, 0.15), 0 0 0 2px rgba(255, 255, 255, 0.3) + + &:before + opacity: 1 + animation: rotate-background 15s linear infinite + + svg + transform: scale(1.2) + filter: drop-shadow(0 0 25px rgba(255, 255, 255, 0.8)) + + h1 + transform: scale(1.05) + + &:after + width: 50% + left: 25% + +@keyframes card-pulse + 0%, 100% + transform: scale(1) + box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1), 0 0 20px rgba(255, 255, 255, 0.1) + 50% + transform: scale(1.02) + box-shadow: 0 6px 35px rgba(0, 0, 0, 0.15), 0 0 25px rgba(255, 255, 255, 0.15) + +@keyframes icon-glow + 0%, 100% + filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.3)) + 50% + filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.6)) \ No newline at end of file diff --git a/client/src/pages/Home/styles.sass b/client/src/pages/Home/styles.sass index 49e186f..cbc97c4 100644 --- a/client/src/pages/Home/styles.sass +++ b/client/src/pages/Home/styles.sass @@ -5,13 +5,116 @@ flex-direction: column align-items: center justify-content: center - height: 100% - width: 100% + height: 100vh + width: 100vw + position: relative + z-index: 1 + animation: page-fade-in 1s ease-in-out +.logo-container + text-align: center + margin-bottom: 2rem + animation: logo-entrance 1.2s cubic-bezier(0.175, 0.885, 0.32, 1.275) + position: relative + + .logo + font-size: 80pt + line-height: 1.1 + margin: 0 + padding: 0 15px + background: linear-gradient(135deg, $pink, $blue 45%, $mint-green 65%, $yellow 85%, $pink) + background-size: 300% 100% + animation: logo-shimmer 10s infinite alternate ease-in-out, logo-glow 5s infinite alternate ease-in-out + -webkit-background-clip: text + background-clip: text + -webkit-text-fill-color: transparent + filter: drop-shadow(0 0 12px rgba(255, 255, 255, 0.6)) + position: relative + letter-spacing: 0.1em + font-weight: bold + + &:before + content: "ToneGuessr" + position: absolute + z-index: -1 + left: 0 + top: 0 + background: none + -webkit-text-fill-color: transparent + filter: blur(15px) brightness(1.2) + opacity: 0.7 + width: 100% + height: 100% + animation: text-pulse 5s infinite alternate ease-in-out + + .tagline + font-size: 24pt + margin: 5px 0 0 0 + color: rgba(255, 255, 255, 0.9) + text-shadow: 0 0 15px rgba(255, 255, 255, 0.4) + animation: tagline-fade 2s ease-in-out + letter-spacing: 0.1em .action-area - margin-top: 5rem + margin-top: 2rem display: flex gap: 3rem flex-wrap: wrap - justify-content: center \ No newline at end of file + justify-content: center + position: relative + z-index: 2 + animation: float-up 1.5s ease-out + +@keyframes logo-entrance + 0% + opacity: 0 + transform: scale(0.8) translateY(-50px) + 100% + opacity: 1 + transform: scale(1) translateY(0) + +@keyframes logo-glow + 0%, 100% + filter: drop-shadow(0 0 12px rgba(255, 255, 255, 0.6)) + transform: scale(1) rotate(-1deg) + 50% + filter: drop-shadow(0 0 20px rgba(255, 255, 255, 0.9)) drop-shadow(0 0 40px rgba(102, 204, 255, 0.5)) + transform: scale(1.05) rotate(1deg) + +@keyframes tagline-fade + 0% + opacity: 0 + transform: translateY(10px) + 100% + opacity: 1 + transform: translateY(0) + +@keyframes page-fade-in + 0% + opacity: 0 + 100% + opacity: 1 + +@keyframes float-up + 0% + opacity: 0 + transform: translateY(50px) + 100% + opacity: 1 + transform: translateY(0) + +@keyframes logo-shimmer + 0% + background-position: 0% 50% + 50% + background-position: 100% 50% + 100% + background-position: 0% 50% + +@keyframes text-pulse + 0%, 100% + opacity: 0.5 + filter: blur(15px) brightness(1.2) + 50% + opacity: 0.8 + filter: blur(20px) brightness(1.5) \ No newline at end of file