diff --git a/src/app/components/login-dialog/login-dialog.component.css b/src/app/components/login-dialog/login-dialog.component.css index acea1e8..813b554 100644 --- a/src/app/components/login-dialog/login-dialog.component.css +++ b/src/app/components/login-dialog/login-dialog.component.css @@ -1,58 +1,293 @@ -@import '../../button-template.css'; +:host { + --auth-sans: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + --auth-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace; + --auth-neon: #ff45c8; + --auth-neon-soft: rgba(255, 69, 200, 0.55); + --auth-bg: #06060d; +} .dialog-overlay { position: fixed; inset: 0; - background: rgba(2, 2, 10, 0.58); + background: rgba(4, 2, 12, 0.72); + backdrop-filter: blur(6px); display: grid; place-items: center; z-index: 350; padding: 1rem; + animation: backdrop-in 180ms ease-out both; } .dialog-card { - width: min(460px, 100%); - background: var(--dlg-bg); - border: 1.5px solid var(--dlg-border); - box-shadow: var(--bb-glow); - border-radius: 4px; - padding: 1rem; + position: relative; + width: min(420px, 100%); + background: + radial-gradient(120% 80% at 50% 0%, rgba(255, 69, 200, 0.10), transparent 60%), + linear-gradient(180deg, #0a0612 0%, #06060d 100%); + border: 1px solid var(--auth-neon-soft); + border-radius: 14px; + padding: 28px 26px 22px; display: grid; - gap: 0.7rem; + gap: 14px; + font-family: var(--auth-sans); + color: #fff; + box-shadow: + 0 0 0 1px rgba(255, 69, 200, 0.06) inset, + 0 0 30px rgba(255, 69, 200, 0.18), + 0 30px 60px rgba(0, 0, 0, 0.55); + overflow: hidden; + animation: dialog-in 220ms cubic-bezier(0.2, 0.8, 0.2, 1) both; +} + +.dialog-card::before { + content: ''; + position: absolute; + inset: 0; + pointer-events: none; + background: linear-gradient( + 180deg, + transparent 0%, + rgba(255, 69, 200, 0.06) 50%, + transparent 100% + ); + height: 35%; + animation: scanline 4.5s linear infinite; + mix-blend-mode: screen; +} + +.dialog-card::after { + content: ''; + position: absolute; + inset: 0; + pointer-events: none; + background-image: + repeating-linear-gradient( + 0deg, + rgba(255, 255, 255, 0.012) 0px, + rgba(255, 255, 255, 0.012) 1px, + transparent 1px, + transparent 3px + ); + border-radius: inherit; +} + +.dialog-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + position: relative; + z-index: 1; +} + +.brand-tag { + font-family: var(--auth-mono); + font-size: 10px; + letter-spacing: 2.5px; + color: var(--auth-neon); + text-transform: uppercase; + opacity: 0.85; + animation: pulse-glow 2.4s ease-in-out infinite; +} + +.brand-tag::before { + content: ''; + display: inline-block; + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--auth-neon); + margin-right: 8px; + vertical-align: 1px; + box-shadow: 0 0 8px var(--auth-neon); +} + +.close-btn { + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.08); + color: rgba(255, 255, 255, 0.65); + width: 28px; + height: 28px; + border-radius: 8px; + cursor: pointer; + font-size: 16px; + line-height: 1; + display: grid; + place-items: center; + transition: all 0.18s ease; +} + +.close-btn:hover { + color: var(--auth-neon); + border-color: var(--auth-neon-soft); + box-shadow: 0 0 10px rgba(255, 69, 200, 0.35); } .dialog-title { - font-family: 'Bebas Neue', sans-serif; - font-size: 22px; - letter-spacing: 2px; - color: var(--bb-title); - text-align: center; + font-family: var(--auth-sans); + font-weight: 700; + font-size: 26px; + letter-spacing: 0.5px; + color: #fff; + margin: 4px 0 0; + position: relative; + z-index: 1; +} + +.dialog-subtitle { + font-family: var(--auth-mono); + font-size: 11px; + color: rgba(255, 255, 255, 0.45); + letter-spacing: 0.6px; + margin-bottom: 6px; + position: relative; + z-index: 1; +} + +form { + display: grid; + gap: 12px; + position: relative; + z-index: 1; +} + +.field { + display: grid; + gap: 6px; +} + +.field-label { + font-family: var(--auth-mono); + font-size: 10px; + letter-spacing: 1.5px; + text-transform: uppercase; + color: rgba(255, 255, 255, 0.55); } .dialog-input { width: 100%; - background: rgba(4, 4, 20, 0.62); - border: 1px solid var(--bb-border); - color: var(--bb-title); - border-radius: 2px; - padding: 0.6rem 0.7rem; - font-family: 'Space Mono', monospace; + background: rgba(8, 5, 20, 0.6); + border: 1px solid rgba(255, 255, 255, 0.08); + color: #fff; + border-radius: 10px; + padding: 12px 14px; + font-family: var(--auth-mono); font-size: 13px; + letter-spacing: 0.3px; + transition: border-color 0.18s ease, box-shadow 0.18s ease, background 0.18s ease; +} + +.dialog-input::placeholder { + color: rgba(255, 255, 255, 0.28); } .dialog-input:focus { outline: none; - box-shadow: 0 0 0 2px rgba(0, 213, 255, 0.25); -} - -.dialog-textarea { - min-height: 120px; - resize: vertical; + border-color: var(--auth-neon); + background: rgba(20, 6, 26, 0.7); + box-shadow: 0 0 0 3px rgba(255, 69, 200, 0.15), 0 0 18px rgba(255, 69, 200, 0.18); } .text-danger { - color: #dc3545; - font-size: 0.875rem; + color: #ff6ea0; + font-family: var(--auth-mono); + font-size: 11px; + letter-spacing: 0.3px; +} + +.error-banner { + font-family: var(--auth-mono); + font-size: 12px; + padding: 10px 12px; + border-radius: 8px; + background: rgba(255, 69, 110, 0.08); + border: 1px solid rgba(255, 69, 110, 0.35); + color: #ff9bb4; + animation: shake 0.35s ease-out; +} + +.dialog-actions { + display: flex; + gap: 10px; + margin-top: 6px; + position: relative; + z-index: 1; +} + +.btn { + flex: 1; + border-radius: 10px; + padding: 12px 14px; + font-family: var(--auth-sans); + font-weight: 600; + font-size: 13px; + letter-spacing: 0.4px; + cursor: pointer; + transition: all 0.18s ease; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.btn-ghost { + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.1); + color: rgba(255, 255, 255, 0.7); +} + +.btn-ghost:hover:not(:disabled) { + color: #fff; + border-color: rgba(255, 255, 255, 0.25); + background: rgba(255, 255, 255, 0.03); +} + +.btn-primary { + background: var(--auth-neon); + border: 1px solid var(--auth-neon); + color: #1a0210; + box-shadow: 0 0 18px rgba(255, 69, 200, 0.45); +} + +.btn-primary:hover:not(:disabled) { + transform: translateY(-1px); + box-shadow: 0 0 26px rgba(255, 69, 200, 0.7); +} + +.btn:disabled { + opacity: 0.45; + cursor: not-allowed; + transform: none; +} + +.alt-line { + margin-top: 4px; + text-align: center; + font-family: var(--auth-mono); + font-size: 11px; + color: rgba(255, 255, 255, 0.45); + position: relative; + z-index: 1; +} + +.alt-line a { + color: var(--auth-neon); + cursor: pointer; + text-decoration: none; + margin-left: 4px; +} + +.alt-line a:hover { + text-shadow: 0 0 8px var(--auth-neon-soft); +} + +.spinner { + width: 14px; + height: 14px; + border: 2px solid rgba(26, 2, 16, 0.35); + border-top-color: #1a0210; + border-radius: 50%; + animation: spin 0.7s linear infinite; } .sr-only { @@ -66,3 +301,28 @@ white-space: nowrap !important; border: 0 !important; } + +@keyframes scanline { + 0% { transform: translateY(-100%); } + 100% { transform: translateY(300%); } +} +@keyframes pulse-glow { + 0%, 100% { opacity: 0.85; } + 50% { opacity: 1; } +} +@keyframes dialog-in { + from { opacity: 0; transform: translateY(8px) scale(0.96); } + to { opacity: 1; transform: translateY(0) scale(1); } +} +@keyframes backdrop-in { + from { opacity: 0; } + to { opacity: 1; } +} +@keyframes shake { + 0%, 100% { transform: translateX(0); } + 20%, 60% { transform: translateX(-4px); } + 40%, 80% { transform: translateX(4px); } +} +@keyframes spin { + to { transform: rotate(360deg); } +} diff --git a/src/app/components/login-dialog/login-dialog.component.html b/src/app/components/login-dialog/login-dialog.component.html index 0be3592..e6ff05d 100644 --- a/src/app/components/login-dialog/login-dialog.component.html +++ b/src/app/components/login-dialog/login-dialog.component.html @@ -1,34 +1,49 @@
-
LOGIN
+
+ NowChess // Auth + +
+ +

Welcome back

+
Sign in to continue your match
- - - @if (loginForm.get('username')?.invalid && loginForm.get('username')?.touched) { - Username must be at least 3 characters - } +
+ + + @if (loginForm.get('username')?.invalid && loginForm.get('username')?.touched) { + Username must be at least 3 characters + } +
- - - @if (loginForm.get('password')?.invalid && loginForm.get('password')?.touched) { - Password must be at least 6 characters - } +
+ + + @if (loginForm.get('password')?.invalid && loginForm.get('password')?.touched) { + Password must be at least 6 characters + } +
@if (errorMessage) { -
{{ errorMessage }}
+
{{ errorMessage }}
}
- - - +
+ +
+ New here?Create an account +
-
\ No newline at end of file + diff --git a/src/app/components/register-dialog/register-dialog.component.css b/src/app/components/register-dialog/register-dialog.component.css index acea1e8..dbc3953 100644 --- a/src/app/components/register-dialog/register-dialog.component.css +++ b/src/app/components/register-dialog/register-dialog.component.css @@ -1,58 +1,298 @@ -@import '../../button-template.css'; +:host { + --auth-sans: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; + --auth-mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace; + --auth-neon: #ff45c8; + --auth-neon-soft: rgba(255, 69, 200, 0.55); + --auth-bg: #06060d; +} .dialog-overlay { position: fixed; inset: 0; - background: rgba(2, 2, 10, 0.58); + background: rgba(4, 2, 12, 0.72); + backdrop-filter: blur(6px); display: grid; place-items: center; z-index: 350; padding: 1rem; + animation: backdrop-in 180ms ease-out both; } .dialog-card { - width: min(460px, 100%); - background: var(--dlg-bg); - border: 1.5px solid var(--dlg-border); - box-shadow: var(--bb-glow); - border-radius: 4px; - padding: 1rem; + position: relative; + width: min(440px, 100%); + background: + radial-gradient(120% 80% at 50% 0%, rgba(255, 69, 200, 0.10), transparent 60%), + linear-gradient(180deg, #0a0612 0%, #06060d 100%); + border: 1px solid var(--auth-neon-soft); + border-radius: 14px; + padding: 28px 26px 22px; display: grid; - gap: 0.7rem; + gap: 14px; + font-family: var(--auth-sans); + color: #fff; + box-shadow: + 0 0 0 1px rgba(255, 69, 200, 0.06) inset, + 0 0 30px rgba(255, 69, 200, 0.18), + 0 30px 60px rgba(0, 0, 0, 0.55); + overflow: hidden; + animation: dialog-in 220ms cubic-bezier(0.2, 0.8, 0.2, 1) both; +} + +.dialog-card::before { + content: ''; + position: absolute; + inset: 0; + pointer-events: none; + background: linear-gradient( + 180deg, + transparent 0%, + rgba(255, 69, 200, 0.06) 50%, + transparent 100% + ); + height: 35%; + animation: scanline 4.5s linear infinite; + mix-blend-mode: screen; +} + +.dialog-card::after { + content: ''; + position: absolute; + inset: 0; + pointer-events: none; + background-image: repeating-linear-gradient( + 0deg, + rgba(255, 255, 255, 0.012) 0px, + rgba(255, 255, 255, 0.012) 1px, + transparent 1px, + transparent 3px + ); + border-radius: inherit; +} + +.dialog-head { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + position: relative; + z-index: 1; +} + +.brand-tag { + font-family: var(--auth-mono); + font-size: 10px; + letter-spacing: 2.5px; + color: var(--auth-neon); + text-transform: uppercase; + opacity: 0.85; + animation: pulse-glow 2.4s ease-in-out infinite; +} + +.brand-tag::before { + content: ''; + display: inline-block; + width: 6px; + height: 6px; + border-radius: 50%; + background: var(--auth-neon); + margin-right: 8px; + vertical-align: 1px; + box-shadow: 0 0 8px var(--auth-neon); +} + +.close-btn { + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.08); + color: rgba(255, 255, 255, 0.65); + width: 28px; + height: 28px; + border-radius: 8px; + cursor: pointer; + font-size: 16px; + line-height: 1; + display: grid; + place-items: center; + transition: all 0.18s ease; +} + +.close-btn:hover { + color: var(--auth-neon); + border-color: var(--auth-neon-soft); + box-shadow: 0 0 10px rgba(255, 69, 200, 0.35); } .dialog-title { - font-family: 'Bebas Neue', sans-serif; - font-size: 22px; - letter-spacing: 2px; - color: var(--bb-title); - text-align: center; + font-family: var(--auth-sans); + font-weight: 700; + font-size: 26px; + letter-spacing: 0.5px; + color: #fff; + margin: 4px 0 0; + position: relative; + z-index: 1; +} + +.dialog-subtitle { + font-family: var(--auth-mono); + font-size: 11px; + color: rgba(255, 255, 255, 0.45); + letter-spacing: 0.6px; + margin-bottom: 6px; + position: relative; + z-index: 1; +} + +form { + display: grid; + gap: 12px; + position: relative; + z-index: 1; +} + +.field { + display: grid; + gap: 6px; +} + +.field-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 10px; +} + +.field-label { + font-family: var(--auth-mono); + font-size: 10px; + letter-spacing: 1.5px; + text-transform: uppercase; + color: rgba(255, 255, 255, 0.55); } .dialog-input { width: 100%; - background: rgba(4, 4, 20, 0.62); - border: 1px solid var(--bb-border); - color: var(--bb-title); - border-radius: 2px; - padding: 0.6rem 0.7rem; - font-family: 'Space Mono', monospace; + background: rgba(8, 5, 20, 0.6); + border: 1px solid rgba(255, 255, 255, 0.08); + color: #fff; + border-radius: 10px; + padding: 12px 14px; + font-family: var(--auth-mono); font-size: 13px; + letter-spacing: 0.3px; + transition: border-color 0.18s ease, box-shadow 0.18s ease, background 0.18s ease; +} + +.dialog-input::placeholder { + color: rgba(255, 255, 255, 0.28); } .dialog-input:focus { outline: none; - box-shadow: 0 0 0 2px rgba(0, 213, 255, 0.25); -} - -.dialog-textarea { - min-height: 120px; - resize: vertical; + border-color: var(--auth-neon); + background: rgba(20, 6, 26, 0.7); + box-shadow: 0 0 0 3px rgba(255, 69, 200, 0.15), 0 0 18px rgba(255, 69, 200, 0.18); } .text-danger { - color: #dc3545; - font-size: 0.875rem; + color: #ff6ea0; + font-family: var(--auth-mono); + font-size: 11px; + letter-spacing: 0.3px; +} + +.error-banner { + font-family: var(--auth-mono); + font-size: 12px; + padding: 10px 12px; + border-radius: 8px; + background: rgba(255, 69, 110, 0.08); + border: 1px solid rgba(255, 69, 110, 0.35); + color: #ff9bb4; + animation: shake 0.35s ease-out; +} + +.dialog-actions { + display: flex; + gap: 10px; + margin-top: 6px; + position: relative; + z-index: 1; +} + +.btn { + flex: 1; + border-radius: 10px; + padding: 12px 14px; + font-family: var(--auth-sans); + font-weight: 600; + font-size: 13px; + letter-spacing: 0.4px; + cursor: pointer; + transition: all 0.18s ease; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; +} + +.btn-ghost { + background: transparent; + border: 1px solid rgba(255, 255, 255, 0.1); + color: rgba(255, 255, 255, 0.7); +} + +.btn-ghost:hover:not(:disabled) { + color: #fff; + border-color: rgba(255, 255, 255, 0.25); + background: rgba(255, 255, 255, 0.03); +} + +.btn-primary { + background: var(--auth-neon); + border: 1px solid var(--auth-neon); + color: #1a0210; + box-shadow: 0 0 18px rgba(255, 69, 200, 0.45); +} + +.btn-primary:hover:not(:disabled) { + transform: translateY(-1px); + box-shadow: 0 0 26px rgba(255, 69, 200, 0.7); +} + +.btn:disabled { + opacity: 0.45; + cursor: not-allowed; + transform: none; +} + +.alt-line { + margin-top: 4px; + text-align: center; + font-family: var(--auth-mono); + font-size: 11px; + color: rgba(255, 255, 255, 0.45); + position: relative; + z-index: 1; +} + +.alt-line a { + color: var(--auth-neon); + cursor: pointer; + text-decoration: none; + margin-left: 4px; +} + +.alt-line a:hover { + text-shadow: 0 0 8px var(--auth-neon-soft); +} + +.spinner { + width: 14px; + height: 14px; + border: 2px solid rgba(26, 2, 16, 0.35); + border-top-color: #1a0210; + border-radius: 50%; + animation: spin 0.7s linear infinite; } .sr-only { @@ -66,3 +306,28 @@ white-space: nowrap !important; border: 0 !important; } + +@keyframes scanline { + 0% { transform: translateY(-100%); } + 100% { transform: translateY(300%); } +} +@keyframes pulse-glow { + 0%, 100% { opacity: 0.85; } + 50% { opacity: 1; } +} +@keyframes dialog-in { + from { opacity: 0; transform: translateY(8px) scale(0.96); } + to { opacity: 1; transform: translateY(0) scale(1); } +} +@keyframes backdrop-in { + from { opacity: 0; } + to { opacity: 1; } +} +@keyframes shake { + 0%, 100% { transform: translateX(0); } + 20%, 60% { transform: translateX(-4px); } + 40%, 80% { transform: translateX(4px); } +} +@keyframes spin { + to { transform: rotate(360deg); } +} diff --git a/src/app/components/register-dialog/register-dialog.component.html b/src/app/components/register-dialog/register-dialog.component.html index 4c75996..123ad58 100644 --- a/src/app/components/register-dialog/register-dialog.component.html +++ b/src/app/components/register-dialog/register-dialog.component.html @@ -1,40 +1,65 @@
-
CREATE ACCOUNT
+
+ NowChess // Register + +
+ +

Create account

+
Join the board and start playing
- - @if (registerForm.get('username')?.invalid && registerForm.get('username')?.touched) { - Username must be at least 3 characters - } +
+ + + @if (registerForm.get('username')?.invalid && registerForm.get('username')?.touched) { + Username must be at least 3 characters + } +
- - @if (registerForm.get('email')?.invalid && registerForm.get('email')?.touched) { - Please enter a valid email - } +
+ + + @if (registerForm.get('email')?.invalid && registerForm.get('email')?.touched) { + Please enter a valid email + } +
- - @if (registerForm.get('password')?.invalid && registerForm.get('password')?.touched) { - Password must be at least 6 characters - } - - +
+
+ + + @if (registerForm.get('password')?.invalid && registerForm.get('password')?.touched) { + Min 6 characters + } +
+
+ + +
+
@if (errorMessage) { -
{{ errorMessage }}
+
{{ errorMessage }}
}
- - - +
+ +
+ Already have an account?Sign in +
-
\ No newline at end of file + diff --git a/src/app/pages/welcome/Auth Dialog.html b/src/app/pages/welcome/Auth Dialog.html new file mode 100644 index 0000000..32dfb08 --- /dev/null +++ b/src/app/pages/welcome/Auth Dialog.html @@ -0,0 +1,89 @@ + + + + + + NowChess — Auth Dialog + + + + + + +
+ + + + + + + + + diff --git a/src/app/pages/welcome/welcome.component.css b/src/app/pages/welcome/welcome.component.css index 7317008..e7162bc 100644 --- a/src/app/pages/welcome/welcome.component.css +++ b/src/app/pages/welcome/welcome.component.css @@ -652,240 +652,6 @@ font-weight: 600; } -/* Speech Bubble Styles */ -.speech-bubble-container { - position: fixed; - top: 35%; - left: 55%; - transform: translate(-50%, -50%); - z-index: 500; - cursor: pointer; - animation: slideInBubble 0.8s cubic-bezier(0.34, 1.56, 0.64, 1); -} - -@keyframes slideInBubble { - 0% { - opacity: 0; - transform: translate(-50%, -50%) scale(0.5); - } - 100% { - opacity: 1; - transform: translate(-50%, -50%) scale(1); - } -} - -.speech-bubble { - background: linear-gradient(135deg, #B9DAD1 0%, #B9C2DA 100%); - border: 2px solid #8b1270; - border-radius: 20px; - padding: 16px 24px; - font-family: 'Comic Sans MS', 'Comic Sans', cursive; - font-size: 18px; - font-weight: bold; - color: #5A2C28; - white-space: nowrap; - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2), - inset 0 1px 3px rgba(255, 255, 255, 0.3); - position: relative; - transition: all 0.3s ease; -} - -.speech-bubble:hover { - transform: scale(1.05); - box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3), - inset 0 1px 3px rgba(255, 255, 255, 0.5); -} - -.bubble-text { - margin: 0; -} - -.bubble-tail { - position: absolute; - bottom: -12px; - left: 20px; - width: 0; - height: 0; - border-left: 10px solid transparent; - border-right: 0px solid transparent; - border-top: 12px solid #B9DAD1; -} - -/* Zoom Overlay and Window */ -.zoom-overlay { - position: fixed; - inset: 0; - background: rgba(0, 0, 0, 0.7); - z-index: 1000; - display: flex; - align-items: center; - justify-content: center; - animation: fadeIn 0.3s ease; - cursor: pointer; -} - -@keyframes fadeIn { - from { - opacity: 0; - } - to { - opacity: 1; - } -} - -.zoom-window-wrapper { - cursor: auto; - animation: zoomInWindow 1.2s cubic-bezier(0.34, 1.56, 0.64, 1); -} - -@keyframes zoomInWindow { - 0% { - transform: scale(0.1); - opacity: 0; - } - 100% { - transform: scale(1); - opacity: 1; - } -} - -.zoom-window-frame { - background: #13072a; - border: 8px solid #f26ae2; - border-radius: 16px; - padding: 40px 20px 20px 20px; - box-shadow: 0 0 40px rgba(242, 106, 226, 0.6), - inset 0 0 20px rgba(242, 106, 226, 0.2); - max-width: 90vw; - max-height: 90vh; - position: relative; -} - -.zoom-player-2 { - position: relative; - display: flex; - align-items: center; - justify-content: center; -} - -.player-2-gif { - max-width: 100%; - max-height: 70vh; - width: auto; - height: auto; - display: block; - border-radius: 12px; - cursor: pointer; - transition: transform 0.2s ease; -} - -.player-2-gif:hover { - transform: scale(1.02); -} - -.second-speech-bubble { - position: absolute; - top: -60px; - left: 50%; - transform: translateX(-50%); - background: linear-gradient(135deg, #C19EF5 0%, #E1EAA9 100%); - border: 2px solid #BA6D4B; - border-radius: 20px; - padding: 12px 18px; - font-family: 'Comic Sans MS', 'Comic Sans', cursive; - font-size: 16px; - font-weight: bold; - color: #5A2C28; - white-space: nowrap; - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2), - inset 0 1px 3px rgba(255, 255, 255, 0.3); - animation: popInBubble 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); - z-index: 10; -} - -@keyframes popInBubble { - 0% { - opacity: 0; - transform: translateX(-50%) scale(0.3); - } - 100% { - opacity: 1; - transform: translateX(-50%) scale(1); - } -} - -.second-speech-bubble .bubble-tail { - top: 100%; - bottom: auto; - left: 50%; - transform: translateX(-50%); - border-top: 12px solid #C19EF5; -} - -/* Happy Meow Bubble */ -.happy-speech-bubble { - position: absolute; - top: -60px; - left: 50%; - transform: translateX(-50%); - background: linear-gradient(135deg, #F3C8A0 0%, #BA6D4B 100%); - border: 2px solid #5A2C28; - border-radius: 20px; - padding: 12px 18px; - font-family: 'Comic Sans MS', 'Comic Sans', cursive; - font-size: 16px; - font-weight: bold; - color: #fff; - white-space: nowrap; - box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3), - inset 0 1px 3px rgba(255, 255, 255, 0.4), - 0 0 20px rgba(243, 200, 160, 0.5); - animation: popInBubble 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); - z-index: 10; -} - -.happy-speech-bubble .bubble-tail { - top: 100%; - bottom: auto; - left: 50%; - transform: translateX(-50%); - border-top: 12px solid #F3C8A0; -} - -/* Meat Emoji */ -.meat-emoji { - position: fixed; - font-size: 48px; - cursor: grab; - user-select: none; - z-index: 1001; - display: flex; - align-items: center; - justify-content: center; - width: 60px; - height: 60px; - animation: meatAppear 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); - filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.3)); - transition: transform 0.1s ease; -} - -.meat-emoji:active { - cursor: grabbing; - transform: scale(1.1); - filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.5)); -} - -@keyframes meatAppear { - 0% { - opacity: 0; - transform: scale(0); - } - 100% { - opacity: 1; - transform: scale(1); - } -} - @media (max-width: 900px) { .bwrap { transform: scale(0.9); diff --git a/src/app/pages/welcome/welcome.component.html b/src/app/pages/welcome/welcome.component.html index e192bff..73cbf94 100644 --- a/src/app/pages/welcome/welcome.component.html +++ b/src/app/pages/welcome/welcome.component.html @@ -46,13 +46,6 @@
- - - @if (showMeatEmoji) { -
- 🍖 -
- }
@@ -145,50 +138,6 @@
- - @if (showSpeechBubble) { -
-
-
{{ bubbleMessage }}
-
-
-
- } - - - @if (isZoomedIn) { -
-
-
-
- Player 2 - @if (showSecondSpeechBubble) { -
-
Feed me! 🍖
-
-
- } - @if (showHappyBubble) { -
-
Happy meow! 😸
-
-
- } -
-
- - - @if (showMeatEmoji) { -
- 🍖 -
- } -
-
- } -
diff --git a/src/app/pages/welcome/welcome.component.ts b/src/app/pages/welcome/welcome.component.ts index 9a3bbaa..5126331 100644 --- a/src/app/pages/welcome/welcome.component.ts +++ b/src/app/pages/welcome/welcome.component.ts @@ -79,28 +79,11 @@ export class WelcomeComponent implements OnInit, OnDestroy { private authDialogState: 'login' | 'register' | null = null; private pendingAction: (() => void) | null = null; - // Speech bubble and zoom features - showSpeechBubble = false; - isZoomedIn = false; - showSecondSpeechBubble = false; - showHappyBubble = false; - showMeatEmoji = false; - bubbleMessage = 'meow'; - - // Meat emoji drag state - meatX = 0; - meatY = 0; - isDraggingMeat = false; - meatDragOffsetX = 0; - meatDragOffsetY = 0; - stars: Star[] = []; bgBuildings: BackgroundBuilding[] = []; windows: Record = {}; private flickerIntervalId: ReturnType | undefined; - private speechBubbleTimeoutId: ReturnType | undefined; - private zoomTimeoutId: ReturnType | undefined; private coolColors = ['#7de8ff', '#00d5ff', '#5bc0de', '#31b0d5', '#4fc3f7', '#29b6f6']; private coolGlowColors = ['#00d5ff', '#00d5ff', '#31b0d5', '#31b0d5', '#03a9f4', '#0288d1']; @@ -140,21 +123,10 @@ export class WelcomeComponent implements OnInit, OnDestroy { this.generateBackgroundBuildings(); this.generateWindowsForAllBuildings(); this.startWindowFlicker(); - - // Show speech bubble after 5 seconds - this.speechBubbleTimeoutId = setTimeout(() => { - this.showSpeechBubble = true; - }, 5000); } ngOnDestroy(): void { this.stopWindowFlicker(); - if (this.speechBubbleTimeoutId) { - clearTimeout(this.speechBubbleTimeoutId); - } - if (this.zoomTimeoutId) { - clearTimeout(this.zoomTimeoutId); - } } openDifficultyDialog(): void { @@ -265,84 +237,6 @@ export class WelcomeComponent implements OnInit, OnDestroy { this.performSubmitImportGame(); } - onSpeechBubbleClick(): void { - this.showSpeechBubble = false; - this.isZoomedIn = true; - this.bubbleMessage = 'meow'; - this.showMeatEmoji = true; - this.showHappyBubble = false; - this.showSecondSpeechBubble = true; - - // Reset meat position - this.meatX = window.innerWidth / 2 - 100; - this.meatY = window.innerHeight / 2 + 150; - } - - onZoomedViewClick(): void { - this.isZoomedIn = false; - this.showSecondSpeechBubble = false; - this.showHappyBubble = false; - this.showMeatEmoji = false; - this.bubbleMessage = 'meow'; - - if (this.zoomTimeoutId) { - clearTimeout(this.zoomTimeoutId); - } - } - - onMeatMouseDown(event: MouseEvent): void { - this.isDraggingMeat = true; - const rect = (event.target as HTMLElement).getBoundingClientRect(); - this.meatDragOffsetX = event.clientX - rect.left; - this.meatDragOffsetY = event.clientY - rect.top; - } - - onMouseMove(event: MouseEvent): void { - if (!this.isDraggingMeat) { - return; - } - - this.meatX = event.clientX - this.meatDragOffsetX; - this.meatY = event.clientY - this.meatDragOffsetY; - - const gifElement = document.querySelector('.player-2-gif') as HTMLElement; - if (!gifElement) { - return; - } - - const gifRect = gifElement.getBoundingClientRect(); - const gifCenterX = gifRect.left + gifRect.width / 2; - const gifCenterY = gifRect.top + gifRect.height / 2; - - const meatElement = document.querySelector('.meat-emoji') as HTMLElement; - if (!meatElement) { - return; - } - - const meatRect = meatElement.getBoundingClientRect(); - const meatCenterX = meatRect.left + meatRect.width / 2; - const meatCenterY = meatRect.top + meatRect.height / 2; - - const distance = Math.sqrt( - Math.pow(meatCenterX - gifCenterX, 2) + Math.pow(meatCenterY - gifCenterY, 2) - ); - - if (distance < 50) { - this.onMeatFed(); - } - } - - onMouseUp(): void { - this.isDraggingMeat = false; - } - - onMeatFed(): void { - this.showMeatEmoji = false; - this.showSecondSpeechBubble = false; - this.showHappyBubble = true; - this.isDraggingMeat = false; - } - private requireAuth(action: () => void): boolean { if (this.authService.isLoggedIn()) { return true;