Ty to claude for css, loooks to be working V1...no featuerts, chat, etc.

This commit is contained in:
2026-01-29 13:20:41 -06:00
parent 43317bde85
commit b4eebfaf6d
4 changed files with 1531 additions and 841 deletions

View File

@@ -33,6 +33,8 @@
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
@@ -46,121 +48,259 @@ body {
background-attachment: fixed;
color: var(--ctp-text);
min-height: 100vh;
font-size: 16px;
line-height: 1.6;
}
/* Gradient overlays */
.gradient-overlay {
position: relative;
overflow: hidden;
/* Text colors */
.text-mauve {
color: var(--ctp-mauve);
}
.text-blue {
color: var(--ctp-blue);
}
.text-red {
color: var(--ctp-red);
}
.text-green {
color: var(--ctp-green);
}
.text-yellow {
color: var(--ctp-yellow);
}
.text-sky {
color: var(--ctp-sky);
}
.text-teal {
color: var(--ctp-teal);
}
.text-text {
color: var(--ctp-text);
}
.text-subtext0 {
color: var(--ctp-subtext0);
}
.text-subtext1 {
color: var(--ctp-subtext1);
}
.text-overlay0 {
color: var(--ctp-overlay0);
}
.text-overlay1 {
color: var(--ctp-overlay1);
}
.text-base {
color: var(--ctp-base);
}
.gradient-overlay::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
135deg,
rgba(203, 166, 247, 0.1) 0%,
rgba(137, 180, 250, 0.1) 100%
);
pointer-events: none;
animation: gradient-shift 8s ease infinite;
/* Background colors */
.bg-surface0 {
background-color: var(--ctp-surface0);
}
.bg-surface1 {
background-color: var(--ctp-surface1);
}
.bg-surface2 {
background-color: var(--ctp-surface2);
}
.bg-base {
background-color: var(--ctp-base);
}
.bg-mantle {
background-color: var(--ctp-mantle);
}
@keyframes gradient-shift {
0%,
100% {
opacity: 0.5;
}
50% {
opacity: 0.8;
}
.bg-blue {
background-color: var(--ctp-blue);
}
.bg-sapphire {
background-color: var(--ctp-sapphire);
}
.bg-red {
background-color: var(--ctp-red);
}
.bg-maroon {
background-color: var(--ctp-maroon);
}
.bg-green {
background-color: var(--ctp-green);
}
.bg-teal {
background-color: var(--ctp-teal);
}
.bg-yellow {
background-color: var(--ctp-yellow);
}
.bg-peach {
background-color: var(--ctp-peach);
}
.bg-mauve {
background-color: var(--ctp-mauve);
}
/* Card styles */
/* Border colors */
.border-surface2 {
border-color: var(--ctp-surface2);
}
.border-blue {
border-color: var(--ctp-blue);
}
.border-red {
border-color: var(--ctp-red);
}
.border-mauve {
border-color: var(--ctp-mauve);
}
/* Card component */
.card {
background: var(--ctp-surface0);
border: 2px solid var(--ctp-surface2);
border-radius: 1rem;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
overflow: hidden;
}
.card::before {
content: "";
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.1),
transparent
);
transition: left 0.5s;
}
.card:hover::before {
left: 100%;
border: 3px solid var(--ctp-surface2);
border-radius: 24px;
transition: all 0.3s ease;
}
.card:hover {
border-color: var(--ctp-mauve);
transform: translateY(-2px);
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4);
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}
/* Button styles */
/* Button component */
.btn {
position: relative;
overflow: hidden;
transition: all 0.3s ease;
display: inline-block;
font-weight: 700;
border-radius: 0.75rem;
border-radius: 16px;
transition: all 0.2s ease;
cursor: pointer;
border: none;
}
.btn::before {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.2);
transform: translate(-50%, -50%);
transition:
width 0.6s,
height 0.6s;
}
.btn:active::before {
width: 300px;
height: 300px;
text-align: center;
font-size: 1.5rem;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
box-shadow: 0 12px 30px rgba(0, 0, 0, 0.4);
}
.btn:active {
transform: translateY(0);
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none !important;
}
.btn-primary {
background: linear-gradient(135deg, var(--ctp-mauve), var(--ctp-pink));
}
.btn-primary:hover {
background: linear-gradient(135deg, var(--ctp-pink), var(--ctp-mauve));
}
.btn-success {
background: linear-gradient(135deg, var(--ctp-green), var(--ctp-teal));
}
.btn-success:hover {
background: linear-gradient(135deg, var(--ctp-teal), var(--ctp-green));
}
.btn-danger {
background: linear-gradient(135deg, var(--ctp-red), var(--ctp-maroon));
}
.btn-danger:hover {
background: linear-gradient(135deg, var(--ctp-maroon), var(--ctp-red));
}
.btn-warning {
background: linear-gradient(135deg, var(--ctp-yellow), var(--ctp-peach));
}
.btn-warning:hover {
background: linear-gradient(135deg, var(--ctp-peach), var(--ctp-yellow));
}
.btn-secondary {
background: linear-gradient(135deg, var(--ctp-overlay0), var(--ctp-overlay1));
}
.btn-secondary:hover {
background: linear-gradient(135deg, var(--ctp-overlay1), var(--ctp-overlay2));
}
.btn-blue {
background: linear-gradient(135deg, var(--ctp-blue), var(--ctp-sapphire));
}
.btn-blue:hover {
background: linear-gradient(135deg, var(--ctp-sapphire), var(--ctp-blue));
}
/* Input component */
.input {
background: var(--ctp-surface1);
border: 3px solid var(--ctp-surface2);
border-radius: 16px;
color: var(--ctp-text);
transition: all 0.3s ease;
font-size: 1.25rem;
}
.input:focus {
outline: none;
border-color: var(--ctp-mauve);
box-shadow: 0 0 20px rgba(203, 166, 247, 0.3);
}
.input::placeholder {
color: var(--ctp-overlay0);
}
/* Radio option */
.radio-option {
background: var(--ctp-surface1);
border: 3px solid transparent;
border-radius: 20px;
cursor: pointer;
transition: all 0.3s ease;
}
.radio-option:hover {
background: var(--ctp-surface2);
}
.radio-option.selected {
border-color: var(--ctp-mauve);
background: var(--ctp-surface2);
}
/* Score card variants */
.score-card-blue {
background: rgba(137, 180, 250, 0.1);
border: 4px solid var(--ctp-blue);
border-radius: 24px;
}
.score-card-red {
background: rgba(243, 139, 168, 0.1);
border: 4px solid var(--ctp-red);
border-radius: 24px;
}
.player-item {
background: var(--ctp-surface0);
border-radius: 16px;
}
/* Animations */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
transform: translateY(30px);
}
to {
opacity: 1;
@@ -168,56 +308,7 @@ body {
}
}
@keyframes slideInLeft {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slideInRight {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes scaleIn {
from {
transform: scale(0.8);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
@keyframes pulse-glow {
0%,
100% {
box-shadow:
0 0 20px var(--ctp-red),
0 0 40px var(--ctp-red),
0 0 60px var(--ctp-red);
}
50% {
box-shadow:
0 0 30px var(--ctp-red),
0 0 60px var(--ctp-red),
0 0 90px var(--ctp-red);
}
}
@keyframes pulse-scale {
@keyframes pulse {
0%,
100% {
transform: scale(1);
@@ -227,240 +318,107 @@ body {
}
}
@keyframes timer-pulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}
@keyframes float {
0%,
100% {
transform: translateY(0px);
}
50% {
transform: translateY(-10px);
}
}
@keyframes shimmer {
0% {
background-position: -1000px 0;
}
100% {
background-position: 1000px 0;
}
}
@keyframes spin-slow {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
/* Utility classes */
.fade-in {
animation: fadeIn 0.5s ease-out;
}
.slide-in-left {
animation: slideInLeft 0.5s ease-out;
.pulse {
animation: pulse 2s ease-in-out infinite;
}
.slide-in-right {
animation: slideInRight 0.5s ease-out;
/* Timer styles */
.timer-container {
min-width: 300px;
}
.scale-in {
animation: scaleIn 0.4s ease-out;
.timer-bar-container {
width: 100%;
height: 16px;
background: var(--ctp-surface0);
border-radius: 999px;
overflow: hidden;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.3);
}
.float {
animation: float 3s ease-in-out infinite;
.timer-bar {
height: 100%;
transition: width 0.3s ease-out;
border-radius: 999px;
}
.timer-bar-green {
background: linear-gradient(90deg, var(--ctp-green), var(--ctp-teal));
box-shadow: 0 0 20px rgba(166, 227, 161, 0.5);
}
.timer-bar-yellow {
background: linear-gradient(90deg, var(--ctp-yellow), var(--ctp-peach));
box-shadow: 0 0 20px rgba(249, 226, 175, 0.5);
}
.timer-bar-red {
background: linear-gradient(90deg, var(--ctp-red), var(--ctp-maroon));
box-shadow: 0 0 20px rgba(243, 139, 168, 0.5);
animation: pulse 0.5s ease-in-out infinite;
}
/* Status dot */
.status-dot {
width: 16px;
height: 16px;
border-radius: 50%;
display: inline-block;
animation: pulse 2s ease-in-out infinite;
}
.status-active {
background: var(--ctp-green);
box-shadow: 0 0 12px var(--ctp-green);
}
.status-waiting {
background: var(--ctp-yellow);
box-shadow: 0 0 12px var(--ctp-yellow);
}
.status-error {
background: var(--ctp-red);
box-shadow: 0 0 12px var(--ctp-red);
}
/* Buzz button */
.buzz-button {
position: relative;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
background: linear-gradient(
135deg,
var(--ctp-red) 0%,
var(--ctp-maroon) 100%
);
box-shadow: 0 10px 40px rgba(243, 139, 168, 0.5);
width: 280px;
height: 280px;
border-radius: 50%;
background: linear-gradient(135deg, var(--ctp-red), var(--ctp-maroon));
border: none;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 10px 40px rgba(243, 139, 168, 0.6);
font-size: 2.5rem;
font-weight: 700;
color: white;
}
.buzz-button::after {
content: "";
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(
45deg,
transparent 30%,
rgba(255, 255, 255, 0.3) 50%,
transparent 70%
);
transform: rotate(45deg);
animation: shimmer 3s infinite;
}
.buzz-button:hover {
.buzz-button:hover:not(:disabled) {
transform: scale(1.1);
box-shadow: 0 15px 50px rgba(243, 139, 168, 0.7);
box-shadow: 0 15px 50px rgba(243, 139, 168, 0.8);
}
.buzz-button:active {
.buzz-button:active:not(:disabled) {
transform: scale(0.95);
}
.buzz-active {
animation:
pulse-glow 1s infinite,
pulse-scale 1s infinite;
}
.buzz-disabled {
opacity: 0.5;
.buzz-button:disabled {
opacity: 0.3;
cursor: not-allowed;
filter: grayscale(1);
}
/* Timer */
.timer-warning {
animation: timer-pulse 0.5s ease-in-out infinite;
}
.timer-bar {
transition:
width 0.3s ease-out,
background-color 0.3s ease;
border-radius: 9999px;
position: relative;
overflow: hidden;
}
.timer-bar::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(
90deg,
transparent,
rgba(255, 255, 255, 0.3),
transparent
);
animation: shimmer 2s infinite;
}
/* Score displays */
.score-card {
background: linear-gradient(
135deg,
var(--ctp-surface0) 0%,
var(--ctp-surface1) 100%
);
border: 2px solid;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.score-card::before {
content: "";
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(
circle,
rgba(255, 255, 255, 0.1) 0%,
transparent 70%
);
animation: spin-slow 20s linear infinite;
}
.team1-card {
border-color: var(--ctp-blue);
box-shadow: 0 0 30px rgba(137, 180, 250, 0.2);
}
.team2-card {
border-color: var(--ctp-red);
box-shadow: 0 0 30px rgba(243, 139, 168, 0.2);
}
.individual-card {
border-color: var(--ctp-mauve);
box-shadow: 0 0 30px rgba(203, 166, 247, 0.2);
}
/* Question cards */
.question-card {
background: linear-gradient(
135deg,
var(--ctp-surface0) 0%,
var(--ctp-surface1) 100%
);
border: 2px solid var(--ctp-surface2);
border-radius: 1.5rem;
padding: 2rem;
position: relative;
overflow: hidden;
}
.question-card::before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(
90deg,
var(--ctp-red),
var(--ctp-yellow),
var(--ctp-green),
var(--ctp-blue),
var(--ctp-mauve)
);
background-size: 200% 100%;
animation: shimmer 3s linear infinite;
}
/* Glow effects */
.glow-green {
box-shadow: 0 0 20px rgba(166, 227, 161, 0.5);
}
.glow-red {
box-shadow: 0 0 20px rgba(243, 139, 168, 0.5);
}
.glow-blue {
box-shadow: 0 0 20px rgba(137, 180, 250, 0.5);
}
.glow-yellow {
box-shadow: 0 0 20px rgba(249, 226, 175, 0.5);
}
.glow-mauve {
box-shadow: 0 0 20px rgba(203, 166, 247, 0.5);
.buzz-button.active {
animation: pulse 1s ease-in-out infinite;
box-shadow: 0 0 60px rgba(243, 139, 168, 0.9);
}
/* Scrollbar */
@@ -470,158 +428,14 @@ body {
::-webkit-scrollbar-track {
background: var(--ctp-mantle);
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: linear-gradient(
180deg,
var(--ctp-surface1) 0%,
var(--ctp-surface2) 100%
);
border-radius: 10px;
background: var(--ctp-surface1);
border-radius: 7px;
border: 2px solid var(--ctp-mantle);
}
::-webkit-scrollbar-thumb:hover {
background: linear-gradient(
180deg,
var(--ctp-surface2) 0%,
var(--ctp-overlay0) 100%
);
}
/* Text gradients */
.text-gradient-mauve {
background: linear-gradient(
135deg,
var(--ctp-mauve) 0%,
var(--ctp-pink) 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.text-gradient-blue {
background: linear-gradient(
135deg,
var(--ctp-blue) 0%,
var(--ctp-sapphire) 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.text-gradient-green {
background: linear-gradient(
135deg,
var(--ctp-green) 0%,
var(--ctp-teal) 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Loading states */
.skeleton {
background: linear-gradient(
90deg,
var(--ctp-surface0) 25%,
var(--ctp-surface1) 50%,
var(--ctp-surface0) 75%
);
background-size: 200% 100%;
animation: shimmer 2s infinite;
border-radius: 0.5rem;
}
/* Badges */
.badge {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: 9999px;
font-weight: 700;
font-size: 0.875rem;
text-transform: uppercase;
letter-spacing: 0.05em;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
/* Status indicators */
.status-dot {
width: 12px;
height: 12px;
border-radius: 50%;
display: inline-block;
margin-right: 0.5rem;
animation: pulse-scale 2s ease-in-out infinite;
}
.status-active {
background: var(--ctp-green);
box-shadow: 0 0 10px var(--ctp-green);
}
.status-waiting {
background: var(--ctp-yellow);
box-shadow: 0 0 10px var(--ctp-yellow);
}
.status-error {
background: var(--ctp-red);
box-shadow: 0 0 10px var(--ctp-red);
}
/* Glass morphism */
.glass {
background: rgba(49, 50, 68, 0.7);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(205, 214, 244, 0.1);
}
/* Neon text */
.neon-text {
text-shadow:
0 0 10px currentColor,
0 0 20px currentColor,
0 0 30px currentColor,
0 0 40px currentColor;
}
/* Particle background effect */
@keyframes particle-float {
0%,
100% {
transform: translate(0, 0) rotate(0deg);
}
33% {
transform: translate(30px, -30px) rotate(120deg);
}
66% {
transform: translate(-20px, 20px) rotate(240deg);
}
}
.particles {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 0;
}
.particle {
position: absolute;
width: 4px;
height: 4px;
background: var(--ctp-mauve);
border-radius: 50%;
opacity: 0.3;
animation: particle-float 20s infinite;
background: var(--ctp-surface2);
}

View File

@@ -1,6 +1,6 @@
"use client";
import { useState, useEffect } from "react";
import { useState, useEffect, useCallback } from "react";
import { Player } from "@/types";
import Cookies from "js-cookie";
import Timer from "@/components/Timer";
@@ -23,6 +23,17 @@ export default function HostPage() {
}
}, []);
const gameAction = useCallback(
async (action: string) => {
await fetch(`/api/game/${roomCode}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action, moderatorId }),
});
},
[roomCode, moderatorId],
);
async function createRoom() {
const res = await fetch("/api/room/create", {
method: "POST",
@@ -60,14 +71,6 @@ export default function HostPage() {
return () => clearInterval(interval);
}, [roomCode]);
async function gameAction(action: string) {
await fetch(`/api/game/${roomCode}`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action, moderatorId }),
});
}
async function closeRoom() {
await fetch(`/api/room/${roomCode}`, {
method: "POST",
@@ -100,7 +103,6 @@ export default function HostPage() {
}
}
// C for correct
if (e.code === "KeyC") {
const phase = gameState?.phase;
if (phase === "tossup_buzzing" && gameState?.buzzedPlayer) {
@@ -110,7 +112,6 @@ export default function HostPage() {
}
}
// W for wrong
if (e.code === "KeyW") {
const phase = gameState?.phase;
if (phase === "tossup_buzzing" && gameState?.buzzedPlayer) {
@@ -123,18 +124,37 @@ export default function HostPage() {
window.addEventListener("keydown", handleKeyPress);
return () => window.removeEventListener("keydown", handleKeyPress);
}, [roomCode, gameState, players]);
}, [roomCode, gameState, players, gameAction]);
if (roomClosed) {
return (
<main className="min-h-screen flex items-center justify-center p-16">
<div className="card fade-in p-20 max-w-2xl text-center">
<h1 className="text-7xl font-bold mb-12 text-[var(--ctp-red)]">
<main
style={{
minHeight: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
padding: "24px",
}}
>
<div
className="card fade-in"
style={{ padding: "32px", maxWidth: "400px", textAlign: "center" }}
>
<h1
className="text-red"
style={{
fontSize: "1.5rem",
fontWeight: "bold",
marginBottom: "24px",
}}
>
Room Closed
</h1>
<a
href="/"
className="btn inline-block px-20 py-8 bg-[var(--ctp-blue)] hover:bg-[var(--ctp-sapphire)] text-[var(--ctp-base)] text-3xl"
className="btn btn-blue text-base"
style={{ padding: "12px 24px", fontSize: "1rem" }}
>
Go Home
</a>
@@ -145,44 +165,102 @@ export default function HostPage() {
if (!roomCode) {
return (
<main className="min-h-screen flex items-center justify-center p-16">
<div className="card fade-in p-20 max-w-4xl w-full">
<h1 className="text-8xl font-bold mb-20 text-center text-[var(--ctp-mauve)]">
<main
style={{
minHeight: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
padding: "24px",
}}
>
<div
className="card fade-in"
style={{ padding: "32px", maxWidth: "500px", width: "100%" }}
>
<h1
className="text-mauve"
style={{
fontSize: "1.75rem",
fontWeight: "bold",
marginBottom: "32px",
textAlign: "center",
}}
>
Create Room
</h1>
<div className="space-y-8 mb-20">
<label className="flex items-start p-12 bg-[var(--ctp-surface1)] rounded-3xl cursor-pointer hover:bg-[var(--ctp-surface2)] transition-all border-4 border-transparent hover:border-[var(--ctp-mauve)]">
<div style={{ marginBottom: "32px" }}>
<label
className={`radio-option ${teamMode === "1" ? "selected" : ""}`}
style={{
display: "flex",
alignItems: "flex-start",
padding: "16px",
marginBottom: "12px",
}}
>
<input
type="radio"
value="1"
checked={teamMode === "1"}
onChange={(e) => setTeamMode(e.target.value as "1" | "2")}
className="mr-8 mt-2 w-8 h-8"
style={{
marginRight: "12px",
marginTop: "2px",
width: "18px",
height: "18px",
}}
/>
<div>
<div className="font-bold text-3xl text-[var(--ctp-text)] mb-4">
<div
className="text-text"
style={{
fontWeight: "bold",
fontSize: "1rem",
marginBottom: "4px",
}}
>
Individual Scoring
</div>
<div className="text-xl text-[var(--ctp-subtext0)]">
<div className="text-subtext0" style={{ fontSize: "0.875rem" }}>
Track each player separately
</div>
</div>
</label>
<label className="flex items-start p-12 bg-[var(--ctp-surface1)] rounded-3xl cursor-pointer hover:bg-[var(--ctp-surface2)] transition-all border-4 border-transparent hover:border-[var(--ctp-blue)]">
<label
className={`radio-option ${teamMode === "2" ? "selected" : ""}`}
style={{
display: "flex",
alignItems: "flex-start",
padding: "16px",
}}
>
<input
type="radio"
value="2"
checked={teamMode === "2"}
onChange={(e) => setTeamMode(e.target.value as "1" | "2")}
className="mr-8 mt-2 w-8 h-8"
style={{
marginRight: "12px",
marginTop: "2px",
width: "18px",
height: "18px",
}}
/>
<div>
<div className="font-bold text-3xl text-[var(--ctp-text)] mb-4">
<div
className="text-text"
style={{
fontWeight: "bold",
fontSize: "1rem",
marginBottom: "4px",
}}
>
Team Mode
</div>
<div className="text-xl text-[var(--ctp-subtext0)]">
<div className="text-subtext0" style={{ fontSize: "0.875rem" }}>
Two teams competing
</div>
</div>
@@ -191,7 +269,8 @@ export default function HostPage() {
<button
onClick={createRoom}
className="btn w-full px-16 py-10 bg-[var(--ctp-green)] hover:bg-[var(--ctp-teal)] text-[var(--ctp-base)] text-4xl font-bold"
className="btn btn-success text-base"
style={{ width: "100%", padding: "14px", fontSize: "1.125rem" }}
>
Create Room
</button>
@@ -209,22 +288,40 @@ export default function HostPage() {
const buzzedPlayer = players.find((p) => p.id === gameState?.buzzedPlayer);
return (
<main className="min-h-screen p-12">
<div className="max-w-[2000px] mx-auto space-y-12">
<main style={{ minHeight: "100vh", padding: "24px" }}>
<div style={{ maxWidth: "1400px", margin: "0 auto" }}>
{/* Header */}
<div className="card p-12 flex justify-between items-center">
<div
className="card"
style={{
padding: "20px",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "24px",
}}
>
<div>
<h1 className="text-9xl font-bold text-[var(--ctp-mauve)] mb-6 tracking-wider">
<h1
className="text-mauve"
style={{
fontSize: "2rem",
fontWeight: "bold",
marginBottom: "6px",
letterSpacing: "0.1em",
}}
>
{roomCode}
</h1>
<p className="text-3xl text-[var(--ctp-subtext0)]">
<p className="text-subtext0" style={{ fontSize: "0.875rem" }}>
{isIndividual ? "Individual" : "Team"} Q
{gameState?.questionNumber || 0}/{gameState?.totalQuestions || 20}
</p>
</div>
<button
onClick={closeRoom}
className="btn px-12 py-6 bg-[var(--ctp-red)] hover:bg-[var(--ctp-maroon)] text-[var(--ctp-base)] text-2xl font-bold"
className="btn btn-danger text-base"
style={{ padding: "10px 20px", fontSize: "0.875rem" }}
>
Close
</button>
@@ -232,28 +329,58 @@ export default function HostPage() {
{/* Scores */}
<div
className={`grid ${isIndividual ? "grid-cols-1" : "grid-cols-2"} gap-12`}
style={{
display: "grid",
gridTemplateColumns: isIndividual ? "1fr" : "1fr 1fr",
gap: "24px",
marginBottom: "24px",
}}
>
<div className="card bg-[var(--ctp-blue)]/10 border-[var(--ctp-blue)] border-4 p-12">
<h2 className="text-5xl font-bold mb-10 text-[var(--ctp-blue)]">
<div className="score-card-blue" style={{ padding: "20px" }}>
<h2
className="text-blue"
style={{
fontSize: "1.25rem",
fontWeight: "bold",
marginBottom: "16px",
}}
>
{isIndividual ? "Players" : "Team 1"}:{" "}
{team1.reduce((sum, p) => sum + p.score, 0)}
</h2>
<div className="space-y-5">
<div
style={{ display: "flex", flexDirection: "column", gap: "10px" }}
>
{team1.length === 0 ? (
<p className="text-[var(--ctp-overlay0)] italic text-2xl py-8">
<p
className="text-overlay0"
style={{
fontStyle: "italic",
fontSize: "0.875rem",
padding: "12px 0",
}}
>
Waiting...
</p>
) : (
team1.map((p) => (
<div
key={p.id}
className="flex justify-between items-center bg-[var(--ctp-surface0)] p-8 rounded-2xl"
className="player-item"
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "12px",
}}
>
<span className="text-[var(--ctp-text)] text-3xl">
<span className="text-text" style={{ fontSize: "1rem" }}>
{p.name}
</span>
<span className="font-bold text-4xl text-[var(--ctp-blue)]">
<span
className="text-blue"
style={{ fontWeight: "bold", fontSize: "1.125rem" }}
>
{p.score}
</span>
</div>
@@ -263,25 +390,54 @@ export default function HostPage() {
</div>
{!isIndividual && (
<div className="card bg-[var(--ctp-red)]/10 border-[var(--ctp-red)] border-4 p-12">
<h2 className="text-5xl font-bold mb-10 text-[var(--ctp-red)]">
<div className="score-card-red" style={{ padding: "20px" }}>
<h2
className="text-red"
style={{
fontSize: "1.25rem",
fontWeight: "bold",
marginBottom: "16px",
}}
>
Team 2: {team2.reduce((sum, p) => sum + p.score, 0)}
</h2>
<div className="space-y-5">
<div
style={{
display: "flex",
flexDirection: "column",
gap: "10px",
}}
>
{team2.length === 0 ? (
<p className="text-[var(--ctp-overlay0)] italic text-2xl py-8">
<p
className="text-overlay0"
style={{
fontStyle: "italic",
fontSize: "0.875rem",
padding: "12px 0",
}}
>
Waiting...
</p>
) : (
team2.map((p) => (
<div
key={p.id}
className="flex justify-between items-center bg-[var(--ctp-surface0)] p-8 rounded-2xl"
className="player-item"
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "12px",
}}
>
<span className="text-[var(--ctp-text)] text-3xl">
<span className="text-text" style={{ fontSize: "1rem" }}>
{p.name}
</span>
<span className="font-bold text-4xl text-[var(--ctp-red)]">
<span
className="text-red"
style={{ fontWeight: "bold", fontSize: "1.125rem" }}
>
{p.score}
</span>
</div>
@@ -293,24 +449,50 @@ export default function HostPage() {
</div>
{/* Game State */}
<div className="card p-20 min-h-[700px] flex items-center justify-center">
<div
className="card"
style={{
padding: "32px",
minHeight: "400px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
{phase === "lobby" && (
<div className="fade-in text-center w-full">
<h2 className="text-7xl font-bold mb-12 text-[var(--ctp-yellow)]">
<div
className="fade-in"
style={{ textAlign: "center", width: "100%" }}
>
<h2
className="text-yellow"
style={{
fontSize: "1.5rem",
fontWeight: "bold",
marginBottom: "16px",
}}
>
Waiting...
</h2>
<p className="text-4xl mb-20 text-[var(--ctp-subtext1)]">
<p
className="text-subtext1"
style={{ fontSize: "1.125rem", marginBottom: "28px" }}
>
{players.length} player{players.length !== 1 && "s"}
</p>
<button
onClick={() => gameAction("start")}
className="btn px-24 py-12 bg-[var(--ctp-green)] hover:bg-[var(--ctp-teal)] disabled:bg-[var(--ctp-surface1)] disabled:text-[var(--ctp-overlay0)] text-[var(--ctp-base)] text-5xl font-bold"
className="btn btn-success text-base"
style={{ padding: "14px 32px", fontSize: "1.125rem" }}
disabled={players.length === 0}
>
Start Game
</button>
{players.length > 0 && (
<p className="text-2xl text-[var(--ctp-subtext0)] mt-8">
<p
className="text-subtext0"
style={{ fontSize: "0.875rem", marginTop: "12px" }}
>
Press SPACE to start
</p>
)}
@@ -318,62 +500,134 @@ export default function HostPage() {
)}
{phase === "intermission" && (
<div className="fade-in text-center w-full space-y-16">
<h2 className="text-7xl font-bold text-[var(--ctp-sky)]">
<div
className="fade-in"
style={{ textAlign: "center", width: "100%" }}
>
<h2
className="text-sky"
style={{
fontSize: "1.5rem",
fontWeight: "bold",
marginBottom: "28px",
}}
>
Next Question
</h2>
<button
onClick={() => gameAction("load_question")}
className="btn px-24 py-12 bg-[var(--ctp-blue)] hover:bg-[var(--ctp-sapphire)] text-[var(--ctp-base)] text-5xl font-bold"
className="btn btn-blue text-base"
style={{ padding: "14px 32px", fontSize: "1.125rem" }}
>
Load Question
</button>
<p className="text-2xl text-[var(--ctp-subtext0)]">
<p
className="text-subtext0"
style={{ fontSize: "0.875rem", marginTop: "12px" }}
>
Press SPACE to load
</p>
</div>
)}
{phase === "tossup_reading" && question && (
<div className="fade-in w-full space-y-12">
<div className="flex justify-between items-start">
<h2 className="text-7xl font-bold text-[var(--ctp-yellow)]">
<div className="fade-in" style={{ width: "100%" }}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "flex-start",
marginBottom: "24px",
}}
>
<h2
className="text-yellow"
style={{ fontSize: "1.5rem", fontWeight: "bold" }}
>
TOSSUP
</h2>
<span className="text-3xl px-10 py-5 bg-[var(--ctp-surface1)] rounded-2xl text-[var(--ctp-yellow)] font-bold">
<span
className="bg-surface1 text-yellow"
style={{
fontSize: "0.875rem",
padding: "8px 16px",
borderRadius: "8px",
fontWeight: "bold",
}}
>
{question.category}
</span>
</div>
<p className="text-4xl mb-16 text-[var(--ctp-text)] leading-relaxed">
<p
className="text-text"
style={{
fontSize: "1.125rem",
marginBottom: "24px",
lineHeight: "1.6",
}}
>
{question.tossup_question}
</p>
<div className="p-10 bg-[var(--ctp-surface1)] rounded-2xl mb-16">
<span className="text-xl text-[var(--ctp-subtext0)] uppercase tracking-wide block mb-5">
<div
className="bg-surface1"
style={{
padding: "16px",
borderRadius: "10px",
marginBottom: "24px",
}}
>
<span
className="text-subtext0"
style={{
fontSize: "0.75rem",
display: "block",
marginBottom: "8px",
textTransform: "uppercase",
letterSpacing: "0.05em",
}}
>
Answer:
</span>
<p className="text-4xl font-bold text-[var(--ctp-green)]">
<p
className="text-green"
style={{ fontSize: "1.125rem", fontWeight: "bold" }}
>
{question.tossup_answer}
</p>
</div>
<button
onClick={() => gameAction("start_timer")}
className="btn px-20 py-10 bg-[var(--ctp-green)] hover:bg-[var(--ctp-teal)] text-[var(--ctp-base)] text-4xl font-bold"
className="btn btn-success text-base"
style={{ padding: "12px 28px", fontSize: "1rem" }}
>
Start Timer (5s)
</button>
<p className="text-2xl text-[var(--ctp-subtext0)] mt-6">
<p
className="text-subtext0"
style={{ fontSize: "0.875rem", marginTop: "12px" }}
>
Press SPACE after reading
</p>
</div>
)}
{phase === "tossup_buzzing" && question && (
<div className="fade-in w-full space-y-12">
<div className="flex justify-between items-center">
<h2 className="text-7xl font-bold text-[var(--ctp-green)]">
<div className="fade-in" style={{ width: "100%" }}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "24px",
}}
>
<h2
className="text-green"
style={{ fontSize: "1.5rem", fontWeight: "bold" }}
>
BUZZING
</h2>
<Timer startTime={gameState?.tossupStartTime} duration={5} />
@@ -381,55 +635,119 @@ export default function HostPage() {
{!buzzedPlayer ? (
<>
<p className="text-5xl text-[var(--ctp-text)] text-center py-32">
<p
className="text-text"
style={{
fontSize: "1.25rem",
textAlign: "center",
padding: "60px 0",
}}
>
Waiting...
</p>
{gameState?.tossupStartTime && (
<button
onClick={() => gameAction("move_on")}
className="btn w-full px-20 py-10 bg-[var(--ctp-overlay0)] hover:bg-[var(--ctp-overlay1)] text-[var(--ctp-text)] text-4xl font-bold"
className="btn btn-secondary text-text"
style={{
width: "100%",
padding: "12px 28px",
fontSize: "1rem",
}}
>
Move On (No Answer)
</button>
)}
</>
) : (
<div className="space-y-12">
<div className="bg-[var(--ctp-blue)]/20 border-4 border-[var(--ctp-blue)] p-12 rounded-3xl">
<p className="text-5xl font-bold text-[var(--ctp-blue)] mb-5">
<div>
<div
className="bg-surface1 border-blue"
style={{
padding: "18px",
borderRadius: "12px",
border: "2px solid var(--ctp-blue)",
marginBottom: "24px",
}}
>
<p
className="text-blue"
style={{
fontSize: "1.25rem",
fontWeight: "bold",
marginBottom: "8px",
}}
>
{buzzedPlayer.name} (Team {buzzedPlayer.teamId})
</p>
{gameState?.tossupInterrupted && (
<p className="text-[var(--ctp-red)] font-bold text-4xl">
<p
className="text-red"
style={{ fontWeight: "bold", fontSize: "1.125rem" }}
>
INTERRUPTED
</p>
)}
</div>
<div className="p-10 bg-[var(--ctp-surface1)] rounded-2xl">
<span className="text-xl text-[var(--ctp-subtext0)] uppercase tracking-wide block mb-5">
<div
className="bg-surface1"
style={{
padding: "16px",
borderRadius: "10px",
marginBottom: "24px",
}}
>
<span
className="text-subtext0"
style={{
fontSize: "0.75rem",
display: "block",
marginBottom: "8px",
textTransform: "uppercase",
letterSpacing: "0.05em",
}}
>
Answer:
</span>
<p className="text-4xl font-bold text-[var(--ctp-green)]">
<p
className="text-green"
style={{ fontSize: "1.125rem", fontWeight: "bold" }}
>
{question.tossup_answer}
</p>
</div>
<div className="grid grid-cols-2 gap-10">
<div
style={{
display: "grid",
gridTemplateColumns: "1fr 1fr",
gap: "16px",
}}
>
<button
onClick={() => gameAction("tossup_correct")}
className="btn px-16 py-12 bg-[var(--ctp-green)] hover:bg-[var(--ctp-teal)] text-[var(--ctp-base)] text-4xl font-bold"
className="btn btn-success text-base"
style={{ padding: "14px 24px", fontSize: "1rem" }}
>
Correct
</button>
<button
onClick={() => gameAction("tossup_wrong")}
className="btn px-16 py-12 bg-[var(--ctp-red)] hover:bg-[var(--ctp-maroon)] text-[var(--ctp-base)] text-4xl font-bold"
className="btn btn-danger text-base"
style={{ padding: "14px 24px", fontSize: "1rem" }}
>
Wrong
</button>
</div>
<p className="text-2xl text-[var(--ctp-subtext0)] text-center">
<p
className="text-subtext0"
style={{
fontSize: "0.875rem",
textAlign: "center",
marginTop: "12px",
}}
>
Press C for Correct, W for Wrong
</p>
</div>
@@ -438,9 +756,19 @@ export default function HostPage() {
)}
{phase === "bonus" && question && (
<div className="fade-in w-full space-y-12">
<div className="flex justify-between items-center">
<h2 className="text-7xl font-bold text-[var(--ctp-mauve)]">
<div className="fade-in" style={{ width: "100%" }}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "24px",
}}
>
<h2
className="text-mauve"
style={{ fontSize: "1.5rem", fontWeight: "bold" }}
>
BONUS (Team {gameState?.currentTeam})
</h2>
{gameState?.bonusStartTime && (
@@ -448,15 +776,41 @@ export default function HostPage() {
)}
</div>
<p className="text-4xl mb-16 text-[var(--ctp-text)] leading-relaxed">
<p
className="text-text"
style={{
fontSize: "1.125rem",
marginBottom: "24px",
lineHeight: "1.6",
}}
>
{question.bonus_question}
</p>
<div className="p-10 bg-[var(--ctp-surface1)] rounded-2xl mb-16">
<span className="text-xl text-[var(--ctp-subtext0)] uppercase tracking-wide block mb-5">
<div
className="bg-surface1"
style={{
padding: "16px",
borderRadius: "10px",
marginBottom: "24px",
}}
>
<span
className="text-subtext0"
style={{
fontSize: "0.75rem",
display: "block",
marginBottom: "8px",
textTransform: "uppercase",
letterSpacing: "0.05em",
}}
>
Answer:
</span>
<p className="text-4xl font-bold text-[var(--ctp-green)]">
<p
className="text-green"
style={{ fontSize: "1.125rem", fontWeight: "bold" }}
>
{question.bonus_answer}
</p>
</div>
@@ -465,56 +819,105 @@ export default function HostPage() {
<>
<button
onClick={() => gameAction("bonus_start_timer")}
className="btn w-full px-20 py-10 bg-[var(--ctp-yellow)] hover:bg-[var(--ctp-peach)] text-[var(--ctp-base)] text-4xl font-bold"
className="btn btn-warning text-base"
style={{
width: "100%",
padding: "12px 28px",
fontSize: "1rem",
}}
>
Start Timer (20s)
</button>
<p className="text-2xl text-[var(--ctp-subtext0)] text-center mt-6">
<p
className="text-subtext0"
style={{
fontSize: "0.875rem",
textAlign: "center",
marginTop: "12px",
}}
>
Press SPACE after reading
</p>
</>
) : (
<>
<div className="grid grid-cols-3 gap-8">
<div
style={{
display: "grid",
gridTemplateColumns: "1fr 1fr 1fr",
gap: "12px",
}}
>
<button
onClick={() => gameAction("bonus_correct")}
className="btn px-12 py-12 bg-[var(--ctp-green)] hover:bg-[var(--ctp-teal)] text-[var(--ctp-base)] text-4xl font-bold"
className="btn btn-success text-base"
style={{ padding: "14px 18px", fontSize: "1rem" }}
>
Correct
</button>
<button
onClick={() => gameAction("bonus_wrong")}
className="btn px-12 py-12 bg-[var(--ctp-red)] hover:bg-[var(--ctp-maroon)] text-[var(--ctp-base)] text-4xl font-bold"
className="btn btn-danger text-base"
style={{ padding: "14px 18px", fontSize: "1rem" }}
>
Wrong
</button>
<button
onClick={() => gameAction("move_on")}
className="btn px-12 py-12 bg-[var(--ctp-overlay0)] hover:bg-[var(--ctp-overlay1)] text-[var(--ctp-text)] text-4xl font-bold"
className="btn btn-secondary text-text"
style={{ padding: "14px 18px", fontSize: "1rem" }}
>
Move On
</button>
</div>
<p className="text-2xl text-[var(--ctp-subtext0)] text-center">
<p
className="text-subtext0"
style={{
fontSize: "0.875rem",
textAlign: "center",
marginTop: "12px",
}}
>
Press C for Correct, W for Wrong
</p>
</>
)}
</div>
)}
{phase === "finished" && (
<div className="fade-in text-center w-full">
<h2 className="text-8xl font-bold mb-20 text-[var(--ctp-green)]">
<div
className="fade-in"
style={{ textAlign: "center", width: "100%" }}
>
<h2
className="text-green"
style={{
fontSize: "2rem",
fontWeight: "bold",
marginBottom: "28px",
}}
>
Game Over!
</h2>
{isIndividual ? (
<div className="space-y-10">
<div
style={{
display: "flex",
flexDirection: "column",
gap: "14px",
}}
>
{[...team1]
.sort((a, b) => b.score - a.score)
.map((p, i) => (
<div
key={p.id}
className={`text-5xl ${i === 0 ? "text-[var(--ctp-yellow)] text-7xl font-bold" : "text-[var(--ctp-text)]"}`}
className={i === 0 ? "text-yellow" : "text-text"}
style={{
fontSize: i === 0 ? "1.5rem" : "1.125rem",
fontWeight: i === 0 ? "bold" : "normal",
}}
>
{i === 0 && "🏆 "}
{p.name}: {p.score}
@@ -522,17 +925,29 @@ export default function HostPage() {
))}
</div>
) : (
<div className="space-y-16">
<div className="flex justify-center items-center gap-20 text-6xl">
<span className="text-[var(--ctp-blue)]">
<div>
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
gap: "28px",
fontSize: "1.25rem",
marginBottom: "28px",
}}
>
<span className="text-blue">
Team 1: {team1.reduce((s, p) => s + p.score, 0)}
</span>
<span className="text-[var(--ctp-subtext0)]">|</span>
<span className="text-[var(--ctp-red)]">
<span className="text-subtext0">|</span>
<span className="text-red">
Team 2: {team2.reduce((s, p) => s + p.score, 0)}
</span>
</div>
<p className="text-7xl font-bold text-[var(--ctp-yellow)]">
<p
className="text-yellow"
style={{ fontSize: "1.75rem", fontWeight: "bold" }}
>
{team1.reduce((s, p) => s + p.score, 0) >
team2.reduce((s, p) => s + p.score, 0)
? "🏆 Team 1 Wins!"

View File

@@ -2,23 +2,220 @@ import Link from "next/link";
export default function Home() {
return (
<main className="min-h-screen flex flex-col items-center justify-center p-8">
<h1 className="text-6xl font-bold mb-12">🧪 SciBowl Quiz</h1>
<main
style={{
minHeight: "100vh",
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
padding: "24px",
position: "relative",
overflow: "hidden",
}}
>
{/* Animated background particles */}
<div className="particles">
{[...Array(30)].map((_, i) => (
<div
key={i}
className="particle"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 20}s`,
width: `${Math.random() * 6 + 2}px`,
height: `${Math.random() * 6 + 2}px`,
}}
/>
))}
</div>
<div className="flex gap-6">
<Link
href="/host"
className="px-8 py-4 bg-blue-600 text-white rounded-lg text-xl hover:bg-blue-700 transition"
{/* Main content */}
<div
style={{
position: "relative",
zIndex: 1,
textAlign: "center",
maxWidth: "800px",
}}
>
{/* Logo/Icon */}
<div
className="float"
style={{
fontSize: "6rem",
marginBottom: "24px",
animation: "float 3s ease-in-out infinite",
}}
>
Host a Game
</Link>
🧪
</div>
<Link
href="/play"
className="px-8 py-4 bg-green-600 text-white rounded-lg text-xl hover:bg-green-700 transition"
{/* Title */}
<h1
className="text-mauve fade-in"
style={{
fontSize: "4rem",
fontWeight: "bold",
marginBottom: "16px",
background:
"linear-gradient(135deg, var(--ctp-mauve), var(--ctp-pink), var(--ctp-blue))",
WebkitBackgroundClip: "text",
WebkitTextFillColor: "transparent",
backgroundClip: "text",
letterSpacing: "0.05em",
}}
>
Join a Game
</Link>
SciBowl Quiz
</h1>
<p
className="text-subtext1 fade-in"
style={{
fontSize: "1.25rem",
marginBottom: "48px",
animationDelay: "0.1s",
}}
>
Compete in real-time Science Bowl competitions
</p>
{/* Action buttons */}
<div
style={{
display: "flex",
gap: "24px",
justifyContent: "center",
flexWrap: "wrap",
}}
>
<Link
href="/host"
className="btn fade-in"
style={{
padding: "20px 40px",
fontSize: "1.25rem",
background:
"linear-gradient(135deg, var(--ctp-blue), var(--ctp-sapphire))",
color: "var(--ctp-base)",
textDecoration: "none",
display: "inline-block",
position: "relative",
overflow: "hidden",
animationDelay: "0.2s",
boxShadow: "0 10px 30px rgba(137, 180, 250, 0.4)",
}}
>
<span
style={{
position: "relative",
zIndex: 1,
display: "flex",
alignItems: "center",
gap: "12px",
}}
>
<span style={{ fontSize: "1.5rem" }}>🎮</span>
Host a Game
</span>
</Link>
<Link
href="/play"
className="btn fade-in"
style={{
padding: "20px 40px",
fontSize: "1.25rem",
background:
"linear-gradient(135deg, var(--ctp-green), var(--ctp-teal))",
color: "var(--ctp-base)",
textDecoration: "none",
display: "inline-block",
position: "relative",
overflow: "hidden",
animationDelay: "0.3s",
boxShadow: "0 10px 30px rgba(166, 227, 161, 0.4)",
}}
>
<span
style={{
position: "relative",
zIndex: 1,
display: "flex",
alignItems: "center",
gap: "12px",
}}
>
<span style={{ fontSize: "1.5rem" }}>🚀</span>
Join a Game
</span>
</Link>
</div>
{/* Footer info */}
<div
className="fade-in"
style={{ marginTop: "64px", animationDelay: "0.7s" }}
>
<p className="text-subtext0" style={{ fontSize: "0.875rem" }}>
</p>
</div>
</div>
{/* Decorative elements */}
<div
style={{
position: "absolute",
top: "10%",
left: "5%",
fontSize: "3rem",
opacity: 0.3,
animation: "float 4s ease-in-out infinite",
}}
>
</div>
<div
style={{
position: "absolute",
bottom: "15%",
right: "8%",
fontSize: "2.5rem",
opacity: 0.3,
animation: "float 5s ease-in-out infinite",
animationDelay: "1s",
}}
>
🔬
</div>
<div
style={{
position: "absolute",
top: "20%",
right: "10%",
fontSize: "2rem",
opacity: 0.3,
animation: "float 6s ease-in-out infinite",
animationDelay: "2s",
}}
>
🧪
</div>
<div
style={{
position: "absolute",
bottom: "10%",
left: "10%",
fontSize: "2.5rem",
opacity: 0.3,
animation: "float 5.5s ease-in-out infinite",
animationDelay: "1.5s",
}}
>
🌡
</div>
</main>
);

View File

@@ -119,7 +119,7 @@ export default function PlayPage() {
}
setPlayerId(data.playerId);
setTeamId(data.teamId);
setTeamId(data.teamId); // Use returned teamId (will be 1 for individual mode)
setJoined(true);
Cookies.set("player_room_code", code.toUpperCase(), { expires: 1 / 12 });
@@ -144,34 +144,42 @@ export default function PlayPage() {
if (roomClosed) {
return (
<main className="min-h-screen flex items-center justify-center p-8 relative overflow-hidden">
<div className="particles">
{[...Array(20)].map((_, i) => (
<div
key={i}
className="particle"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 20}s`,
}}
/>
))}
</div>
<div className="card scale-in p-16 max-w-lg text-center z-10 glow-red">
<div className="text-6xl mb-6">😔</div>
<h1 className="text-5xl font-bold mb-6 text-gradient-mauve">
<main
style={{
minHeight: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
padding: "24px",
}}
>
<div
className="card fade-in"
style={{ padding: "32px", maxWidth: "400px", textAlign: "center" }}
>
<div style={{ fontSize: "3rem", marginBottom: "20px" }}>😔</div>
<h1
className="text-red"
style={{
fontSize: "1.5rem",
fontWeight: "bold",
marginBottom: "16px",
}}
>
Room Closed
</h1>
<p className="text-xl text-[var(--ctp-subtext1)] mb-8">
The host has ended this game session
<p
className="text-subtext0"
style={{ fontSize: "0.875rem", marginBottom: "24px" }}
>
The host has ended this game
</p>
<a
href="/"
className="btn inline-block px-10 py-4 bg-gradient-to-r from-[var(--ctp-blue)] to-[var(--ctp-sapphire)] text-[var(--ctp-base)] text-xl"
className="btn btn-blue text-base"
style={{ padding: "12px 24px", fontSize: "1rem" }}
>
Return Home
Go Home
</a>
</div>
</main>
@@ -180,184 +188,233 @@ export default function PlayPage() {
if (!joined) {
return (
<main className="min-h-screen flex items-center justify-center p-8 relative overflow-hidden">
<div className="particles">
{[...Array(30)].map((_, i) => (
<div
key={i}
className="particle"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 20}s`,
}}
/>
))}
</div>
<div className="card scale-in p-12 max-w-md w-full z-10 glow-mauve gradient-overlay">
<h1 className="text-5xl font-bold mb-10 text-center text-gradient-mauve float">
<main
style={{
minHeight: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
padding: "24px",
}}
>
<div
className="card fade-in"
style={{ padding: "32px", maxWidth: "450px", width: "100%" }}
>
<h1
className="text-mauve"
style={{
fontSize: "1.75rem",
fontWeight: "bold",
marginBottom: "32px",
textAlign: "center",
}}
>
Join Game
</h1>
<div className="space-y-6">
<div>
<label className="block text-sm font-bold text-[var(--ctp-subtext1)] mb-2 uppercase tracking-wide">
Your Name
</label>
<input
type="text"
placeholder="Enter your name..."
value={name}
onChange={(e) => setName(e.target.value)}
className="w-full p-4 text-lg bg-[var(--ctp-surface1)] border-2 border-[var(--ctp-surface2)] rounded-xl text-[var(--ctp-text)] focus:border-[var(--ctp-mauve)] focus:outline-none transition-all placeholder-[var(--ctp-overlay0)]"
maxLength={20}
/>
</div>
<div style={{ marginBottom: "24px" }}>
<label
className="text-subtext0"
style={{
display: "block",
fontSize: "0.875rem",
marginBottom: "8px",
fontWeight: "600",
}}
>
Your Name
</label>
<input
type="text"
placeholder="Enter your name..."
value={name}
onChange={(e) => setName(e.target.value)}
className="input"
style={{ width: "100%", padding: "12px", fontSize: "1rem" }}
maxLength={20}
/>
</div>
<div>
<label className="block text-sm font-bold text-[var(--ctp-subtext1)] mb-2 uppercase tracking-wide">
Room Code
</label>
<input
type="text"
placeholder="XXXXXX"
value={code}
onChange={(e) => setCode(e.target.value.toUpperCase())}
className="w-full p-4 text-2xl font-bold bg-[var(--ctp-surface1)] border-2 border-[var(--ctp-surface2)] rounded-xl text-[var(--ctp-text)] focus:border-[var(--ctp-blue)] focus:outline-none transition-all uppercase tracking-widest text-center placeholder-[var(--ctp-overlay0)]"
maxLength={6}
/>
</div>
<div style={{ marginBottom: "24px" }}>
<label
className="text-subtext0"
style={{
display: "block",
fontSize: "0.875rem",
marginBottom: "8px",
fontWeight: "600",
}}
>
Room Code
</label>
<input
type="text"
placeholder="XXXXXX"
value={code}
onChange={(e) => setCode(e.target.value.toUpperCase())}
className="input"
style={{
width: "100%",
padding: "12px",
fontSize: "1.25rem",
fontWeight: "bold",
textAlign: "center",
letterSpacing: "0.15em",
textTransform: "uppercase",
}}
maxLength={6}
/>
</div>
<div className="grid grid-cols-2 gap-4">
<div style={{ marginBottom: "32px" }}>
<label
className="text-subtext0"
style={{
display: "block",
fontSize: "0.875rem",
marginBottom: "12px",
fontWeight: "600",
}}
>
Select Team
</label>
<div
style={{
display: "grid",
gridTemplateColumns: "1fr 1fr",
gap: "12px",
}}
>
<label
className={`card cursor-pointer p-4 transition-all ${
teamId === "1"
? "border-[var(--ctp-blue)] glow-blue"
: "border-[var(--ctp-surface2)]"
}`}
className={`card ${teamId === "1" ? "border-blue" : ""}`}
style={{
cursor: "pointer",
padding: "16px",
textAlign: "center",
border:
teamId === "1"
? "3px solid var(--ctp-blue)"
: "3px solid transparent",
transition: "all 0.2s",
}}
>
<input
type="radio"
value="1"
checked={teamId === "1"}
onChange={(e) => setTeamId(e.target.value as "1" | "2")}
className="hidden"
style={{ display: "none" }}
/>
<div className="text-center">
<div
className={`text-3xl mb-2 ${teamId === "1" ? "scale-110" : ""} transition-transform`}
>
🔵
</div>
<div
className={`font-bold ${teamId === "1" ? "text-[var(--ctp-blue)]" : "text-[var(--ctp-subtext0)]"}`}
>
Team 1
</div>
<div style={{ fontSize: "2rem", marginBottom: "8px" }}>🔵</div>
<div
className={teamId === "1" ? "text-blue" : "text-subtext0"}
style={{ fontWeight: "bold", fontSize: "1rem" }}
>
Team 1
</div>
</label>
<label
className={`card cursor-pointer p-4 transition-all ${
teamId === "2"
? "border-[var(--ctp-red)] glow-red"
: "border-[var(--ctp-surface2)]"
}`}
className={`card ${teamId === "2" ? "border-red" : ""}`}
style={{
cursor: "pointer",
padding: "16px",
textAlign: "center",
border:
teamId === "2"
? "3px solid var(--ctp-red)"
: "3px solid transparent",
transition: "all 0.2s",
}}
>
<input
type="radio"
value="2"
checked={teamId === "2"}
onChange={(e) => setTeamId(e.target.value as "1" | "2")}
className="hidden"
style={{ display: "none" }}
/>
<div className="text-center">
<div
className={`text-3xl mb-2 ${teamId === "2" ? "scale-110" : ""} transition-transform`}
>
🔴
</div>
<div
className={`font-bold ${teamId === "2" ? "text-[var(--ctp-red)]" : "text-[var(--ctp-subtext0)]"}`}
>
Team 2
</div>
<div style={{ fontSize: "2rem", marginBottom: "8px" }}>🔴</div>
<div
className={teamId === "2" ? "text-red" : "text-subtext0"}
style={{ fontWeight: "bold", fontSize: "1rem" }}
>
Team 2
</div>
</label>
</div>
<button
onClick={join}
disabled={!name.trim() || code.length !== 6}
className="btn w-full px-8 py-5 bg-gradient-to-r from-[var(--ctp-mauve)] to-[var(--ctp-pink)] disabled:from-[var(--ctp-surface1)] disabled:to-[var(--ctp-surface1)] disabled:text-[var(--ctp-overlay0)] text-[var(--ctp-base)] text-xl font-bold disabled:cursor-not-allowed"
>
Join Game
</button>
</div>
<button
onClick={join}
disabled={!name.trim() || code.length !== 6}
className="btn btn-primary text-base"
style={{ width: "100%", padding: "14px", fontSize: "1.125rem" }}
>
Join Game
</button>
</div>
</main>
);
}
const phase = gameState?.phase || "lobby";
const teamColor = teamId === "1" ? "blue" : "red";
return (
<main className="min-h-screen p-4 relative overflow-hidden">
<div className="particles">
{[...Array(25)].map((_, i) => (
<div
key={i}
className="particle"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 20}s`,
}}
/>
))}
</div>
<div className="max-w-4xl mx-auto relative z-10">
<main style={{ minHeight: "100vh", padding: "24px" }}>
<div style={{ maxWidth: "800px", margin: "0 auto" }}>
{/* Player Header */}
<div
className={`card p-8 mb-6 slide-in-left ${teamId === "1" ? "team1-card" : "team2-card"}`}
className={`card ${teamId === "1" ? "border-blue" : "border-red"}`}
style={{
padding: "20px",
marginBottom: "24px",
border: `3px solid ${teamId === "1" ? "var(--ctp-blue)" : "var(--ctp-red)"}`,
}}
>
<div className="flex justify-between items-center">
<div>
<div className="flex items-center gap-3 mb-2">
<div className="text-4xl">{teamId === "1" ? "🔵" : "🔴"}</div>
<h1 className="text-4xl font-bold text-[var(--ctp-text)]">
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<div style={{ display: "flex", alignItems: "center", gap: "12px" }}>
<div style={{ fontSize: "2rem" }}>
{teamId === "1" ? "🔵" : "🔴"}
</div>
<div>
<h1
className="text-text"
style={{ fontSize: "1.5rem", fontWeight: "bold" }}
>
{name}
</h1>
</div>
<div className="flex items-center gap-4">
<div className="badge bg-[var(--ctp-surface1)] text-[var(--ctp-text)]">
Team {teamId}
</div>
<div
className={`badge bg-gradient-to-r ${
teamId === "1"
? "from-[var(--ctp-blue)] to-[var(--ctp-sapphire)]"
: "from-[var(--ctp-red)] to-[var(--ctp-maroon)]"
} text-[var(--ctp-base)]`}
>
Room: {code}
<div className="text-subtext0" style={{ fontSize: "0.875rem" }}>
Team {teamId} Room: {code}
</div>
</div>
</div>
<div className="text-right">
<div className="text-sm text-[var(--ctp-subtext0)] uppercase tracking-wide mb-1">
<div style={{ textAlign: "right" }}>
<div
className="text-subtext0"
style={{
fontSize: "0.75rem",
textTransform: "uppercase",
marginBottom: "4px",
}}
>
Your Score
</div>
<div
className={`text-6xl font-bold ${
teamId === "1"
? "text-gradient-blue"
: "text-[var(--ctp-red)]"
} neon-text`}
className={teamId === "1" ? "text-blue" : "text-red"}
style={{
fontSize: "2.5rem",
fontWeight: "bold",
lineHeight: "1",
}}
>
{myScore}
</div>
@@ -366,60 +423,113 @@ export default function PlayPage() {
</div>
{/* Game Status */}
<div className="card p-12 question-card fade-in">
<div
className="card"
style={{
padding: "32px",
minHeight: "400px",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
{phase === "lobby" && (
<div className="text-center">
<div className="text-6xl mb-6 float"></div>
<h2 className="text-4xl font-bold mb-4 text-gradient-mauve">
<div className="fade-in" style={{ textAlign: "center" }}>
<div style={{ fontSize: "4rem", marginBottom: "20px" }}></div>
<h2
className="text-yellow"
style={{
fontSize: "1.5rem",
fontWeight: "bold",
marginBottom: "12px",
}}
>
Waiting for Game Start...
</h2>
<p className="text-xl text-[var(--ctp-subtext1)]">
<p className="text-subtext0" style={{ fontSize: "1rem" }}>
Get ready to buzz in!
</p>
<div className="mt-8">
<div className="skeleton h-8 w-64 mx-auto mb-4" />
<div className="skeleton h-8 w-48 mx-auto" />
</div>
</div>
)}
{phase === "intermission" && (
<div className="text-center">
<div className="text-6xl mb-6 float">📚</div>
<h2 className="text-4xl font-bold mb-4 text-gradient-blue">
<div className="fade-in" style={{ textAlign: "center" }}>
<div style={{ fontSize: "4rem", marginBottom: "20px" }}>📚</div>
<h2
className="text-sky"
style={{
fontSize: "1.5rem",
fontWeight: "bold",
marginBottom: "12px",
}}
>
Next Question Loading...
</h2>
<p className="text-xl text-[var(--ctp-subtext1)]">
Stay focused and ready!
<p className="text-subtext0" style={{ fontSize: "1rem" }}>
Stay focused!
</p>
</div>
)}
{(phase === "tossup_reading" || phase === "tossup_buzzing") && (
<div className="text-center">
<div className="mb-8">
<div className="badge bg-[var(--ctp-yellow)] text-[var(--ctp-base)] text-lg mb-4">
TOSSUP QUESTION
</div>
<h2 className="text-5xl font-bold text-gradient-green mb-6">
Listen Carefully!
</h2>
<div
className="fade-in"
style={{ textAlign: "center", width: "100%" }}
>
<div
className="bg-yellow text-base"
style={{
padding: "8px 20px",
borderRadius: "999px",
display: "inline-block",
fontSize: "0.875rem",
fontWeight: "bold",
marginBottom: "24px",
}}
>
TOSSUP QUESTION
</div>
<h2
className="text-green"
style={{
fontSize: "1.75rem",
fontWeight: "bold",
marginBottom: "32px",
}}
>
Listen Carefully!
</h2>
{canBuzz && !buzzing ? (
<div className="scale-in">
<button
onClick={buzz}
className="buzz-button buzz-active w-64 h-64 rounded-full text-white text-4xl font-bold relative z-10 mx-auto block"
className="buzz-button active"
style={{ margin: "0 auto", display: "block" }}
>
<div className="relative z-10">
<div className="text-6xl mb-2">🔔</div>
<div>BUZZ!</div>
<div style={{ fontSize: "3rem", marginBottom: "8px" }}>
🔔
</div>
<div style={{ fontSize: "1.5rem" }}>BUZZ!</div>
</button>
<p className="mt-8 text-2xl text-[var(--ctp-subtext1)] animate-pulse">
<p
className="text-subtext0"
style={{
fontSize: "1rem",
marginTop: "20px",
animation: "pulse 1.5s ease-in-out infinite",
}}
>
Press{" "}
<kbd className="px-3 py-1 bg-[var(--ctp-surface1)] rounded font-mono">
<kbd
style={{
padding: "4px 12px",
background: "var(--ctp-surface1)",
borderRadius: "6px",
fontFamily: "monospace",
fontSize: "0.875rem",
}}
>
SPACE
</kbd>{" "}
to buzz
@@ -427,52 +537,140 @@ export default function PlayPage() {
</div>
) : buzzing ? (
<div className="scale-in">
<div className="buzz-button buzz-active w-64 h-64 rounded-full text-white text-4xl font-bold relative z-10 mx-auto flex items-center justify-center">
<div className="text-6xl"></div>
<div
className="buzz-button"
style={{
margin: "0 auto",
display: "flex",
alignItems: "center",
justifyContent: "center",
background:
"linear-gradient(135deg, var(--ctp-green), var(--ctp-teal))",
}}
>
<div style={{ fontSize: "4rem" }}></div>
</div>
<p className="mt-8 text-3xl font-bold text-[var(--ctp-green)]">
<p
className="text-green"
style={{
fontSize: "1.5rem",
fontWeight: "bold",
marginTop: "20px",
}}
>
Buzzed!
</p>
</div>
) : gameState?.buzzedPlayer === playerId ? (
<div className="scale-in">
<div className="w-64 h-64 rounded-full bg-gradient-to-br from-[var(--ctp-yellow)] to-[var(--ctp-peach)] text-[var(--ctp-base)] text-4xl font-bold relative z-10 mx-auto flex items-center justify-center glow-yellow">
<div>
<div className="text-6xl mb-2"></div>
<div>You Buzzed!</div>
<div
style={{
width: "280px",
height: "280px",
borderRadius: "50%",
background:
"linear-gradient(135deg, var(--ctp-yellow), var(--ctp-peach))",
margin: "0 auto",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
boxShadow: "0 0 40px rgba(249, 226, 175, 0.6)",
}}
>
<div style={{ fontSize: "3rem", marginBottom: "12px" }}>
</div>
<div
className="text-base"
style={{ fontSize: "1.5rem", fontWeight: "bold" }}
>
You Buzzed!
</div>
</div>
<p className="mt-8 text-2xl text-[var(--ctp-yellow)] font-bold">
Waiting for moderator judgment...
<p
className="text-yellow"
style={{
fontSize: "1.125rem",
fontWeight: "bold",
marginTop: "20px",
}}
>
Waiting for moderator...
</p>
</div>
) : gameState?.buzzedPlayer ? (
<div className="scale-in">
<div className="w-64 h-64 rounded-full bg-[var(--ctp-surface1)] border-4 border-[var(--ctp-overlay0)] text-4xl font-bold relative z-10 mx-auto flex items-center justify-center">
<div>
<div className="text-6xl mb-2 opacity-50">🔔</div>
<div className="text-[var(--ctp-overlay1)]">
Someone
<br />
Buzzed
</div>
<div
style={{
width: "280px",
height: "280px",
borderRadius: "50%",
background: "var(--ctp-surface1)",
border: "4px solid var(--ctp-overlay0)",
margin: "0 auto",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
}}
>
<div
style={{
fontSize: "3rem",
marginBottom: "12px",
opacity: 0.5,
}}
>
🔔
</div>
<div
className="text-overlay1"
style={{ fontSize: "1.25rem", fontWeight: "bold" }}
>
Someone
<br />
Buzzed
</div>
</div>
<p className="mt-8 text-xl text-[var(--ctp-subtext0)]">
<p
className="text-subtext0"
style={{ fontSize: "1rem", marginTop: "20px" }}
>
Waiting for answer...
</p>
</div>
) : (
<div className="scale-in">
<div className="w-64 h-64 rounded-full bg-[var(--ctp-surface1)] border-4 border-dashed border-[var(--ctp-overlay0)] text-4xl font-bold relative z-10 mx-auto flex items-center justify-center buzz-disabled">
<div>
<div className="text-6xl mb-2">👂</div>
<div className="text-[var(--ctp-overlay1)]">
Listen...
</div>
<div
style={{
width: "280px",
height: "280px",
borderRadius: "50%",
background: "var(--ctp-surface1)",
border: "4px dashed var(--ctp-overlay0)",
margin: "0 auto",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
opacity: 0.4,
}}
>
<div style={{ fontSize: "3rem", marginBottom: "12px" }}>
👂
</div>
<div
className="text-overlay1"
style={{ fontSize: "1.25rem", fontWeight: "bold" }}
>
Listen...
</div>
</div>
<p className="mt-8 text-xl text-[var(--ctp-subtext0)]">
<p
className="text-subtext0"
style={{ fontSize: "1rem", marginTop: "20px" }}
>
Question being read...
</p>
</div>
@@ -481,34 +679,73 @@ export default function PlayPage() {
)}
{phase === "bonus" && (
<div className="text-center">
<div className="mb-8">
<div className="badge bg-[var(--ctp-mauve)] text-[var(--ctp-base)] text-lg mb-4">
BONUS QUESTION
</div>
<h2 className="text-5xl font-bold text-gradient-mauve mb-4">
{gameState?.currentTeam === parseInt(teamId)
? "Your Team Bonus!"
: "Other Team Bonus"}
</h2>
<div className="fade-in" style={{ textAlign: "center" }}>
<div
className="bg-mauve text-base"
style={{
padding: "8px 20px",
borderRadius: "999px",
display: "inline-block",
fontSize: "0.875rem",
fontWeight: "bold",
marginBottom: "24px",
}}
>
BONUS QUESTION
</div>
<h2
className="text-mauve"
style={{
fontSize: "1.75rem",
fontWeight: "bold",
marginBottom: "12px",
}}
>
{gameState?.currentTeam === parseInt(teamId)
? "Your Team Bonus!"
: "Other Team Bonus"}
</h2>
{gameState?.currentTeam === parseInt(teamId) ? (
<div className="scale-in">
<div className="text-7xl mb-6 float">🎯</div>
<p className="text-2xl text-[var(--ctp-text)] mb-6">
<div className="scale-in" style={{ marginTop: "32px" }}>
<div style={{ fontSize: "4rem", marginBottom: "20px" }}>
🎯
</div>
<p
className="text-text"
style={{ fontSize: "1.25rem", marginBottom: "20px" }}
>
Work together with your team!
</p>
<div className="inline-block px-8 py-4 bg-[var(--ctp-mauve)]/20 border-2 border-[var(--ctp-mauve)] rounded-xl">
<p className="text-[var(--ctp-mauve)] font-bold text-lg">
<div
style={{
display: "inline-block",
padding: "16px 28px",
background: "rgba(203, 166, 247, 0.2)",
border: "2px solid var(--ctp-mauve)",
borderRadius: "12px",
}}
>
<p
className="text-mauve"
style={{ fontWeight: "bold", fontSize: "1.125rem" }}
>
+10 points if correct
</p>
</div>
</div>
) : (
<div className="scale-in">
<div className="text-7xl mb-6 opacity-50"></div>
<p className="text-2xl text-[var(--ctp-subtext0)]">
<div className="scale-in" style={{ marginTop: "32px" }}>
<div
style={{
fontSize: "4rem",
marginBottom: "20px",
opacity: 0.5,
}}
>
</div>
<p className="text-subtext0" style={{ fontSize: "1.125rem" }}>
Waiting for other team...
</p>
</div>
@@ -517,16 +754,42 @@ export default function PlayPage() {
)}
{phase === "finished" && (
<div className="text-center">
<div className="text-8xl mb-8 float">🏁</div>
<h2 className="text-6xl font-bold mb-6 text-gradient-green">
<div className="fade-in" style={{ textAlign: "center" }}>
<div style={{ fontSize: "5rem", marginBottom: "24px" }}>🏁</div>
<h2
className="text-green"
style={{
fontSize: "2rem",
fontWeight: "bold",
marginBottom: "20px",
}}
>
Game Over!
</h2>
<div className="inline-block px-12 py-8 bg-gradient-to-br from-[var(--ctp-surface0)] to-[var(--ctp-surface1)] rounded-2xl border-4 border-[var(--ctp-mauve)] glow-mauve">
<p className="text-[var(--ctp-subtext1)] text-xl mb-2">
<div
style={{
display: "inline-block",
padding: "24px 40px",
background:
"linear-gradient(135deg, var(--ctp-surface0), var(--ctp-surface1))",
borderRadius: "16px",
border: "4px solid var(--ctp-mauve)",
}}
>
<p
className="text-subtext1"
style={{ fontSize: "1rem", marginBottom: "8px" }}
>
Your Final Score
</p>
<p className="text-7xl font-bold text-gradient-mauve neon-text">
<p
className="text-mauve"
style={{
fontSize: "3rem",
fontWeight: "bold",
lineHeight: "1",
}}
>
{myScore}
</p>
</div>
@@ -535,10 +798,11 @@ export default function PlayPage() {
</div>
{/* Leave Button */}
<div className="mt-6 text-center slide-in-right">
<div style={{ marginTop: "24px", textAlign: "center" }}>
<button
onClick={leave}
className="btn px-8 py-4 bg-[var(--ctp-overlay0)] hover:bg-[var(--ctp-overlay1)] text-[var(--ctp-text)] font-bold"
className="btn btn-secondary text-text"
style={{ padding: "12px 24px", fontSize: "0.875rem" }}
>
Leave Game
</button>