tictactoe/style.css
Parley Hatch 4b7d42dc13 Initial commit: original tic-tac-toe game
Existing 2-player hotseat game with name entry, emoji avatars,
scoreboard, sound effects, and celebration animations.
2026-05-31 17:43:45 -06:00

832 lines
16 KiB
CSS

* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 25%, #f093fb 50%, #4facfe 75%, #667eea 100%);
background-size: 400% 400%;
animation: gradientShift 15s ease infinite;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
overflow-x: hidden;
overflow-y: auto;
position: relative;
padding: 20px 0;
}
@keyframes gradientShift {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* Animated Stars Background */
.stars {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 0;
}
.stars::before,
.stars::after {
content: '';
position: absolute;
width: 2px;
height: 2px;
background: white;
box-shadow:
100px 200px white, 300px 100px white, 500px 300px white,
700px 150px white, 200px 400px white, 600px 450px white,
150px 50px white, 450px 250px white, 350px 500px white,
800px 400px white, 50px 300px white, 550px 50px white,
250px 150px rgba(255,255,255,0.5), 650px 350px rgba(255,255,255,0.5),
400px 100px rgba(255,255,255,0.5), 100px 450px rgba(255,255,255,0.5);
border-radius: 50%;
animation: twinkle 3s infinite;
}
.stars::after {
animation-delay: 1.5s;
}
@keyframes twinkle {
0%, 100% { opacity: 0.3; transform: scale(1); }
50% { opacity: 1; transform: scale(1.2); }
}
.container {
width: 100%;
max-width: 900px;
padding: 20px;
position: relative;
z-index: 1;
}
/* Screens */
.screen {
display: none;
animation: fadeIn 0.5s ease;
}
.screen.active {
display: block;
}
@keyframes fadeIn {
from { opacity: 0; transform: scale(0.9); }
to { opacity: 1; transform: scale(1); }
}
/* Name Input Screen */
.name-card {
background: rgba(255, 255, 255, 0.95);
border-radius: 30px;
padding: 30px 30px;
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.3),
0 0 40px rgba(246, 79, 254, 0.5),
inset 0 0 60px rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 3px solid rgba(255, 255, 255, 0.8);
max-height: 95vh;
overflow-y: auto;
}
/* Custom Scrollbar */
.name-card::-webkit-scrollbar {
width: 8px;
}
.name-card::-webkit-scrollbar-track {
background: rgba(240, 147, 251, 0.1);
border-radius: 10px;
}
.name-card::-webkit-scrollbar-thumb {
background: linear-gradient(135deg, #f093fb, #4facfe);
border-radius: 10px;
}
.name-card::-webkit-scrollbar-thumb:hover {
background: linear-gradient(135deg, #f5576c, #f093fb);
}
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
.title {
font-size: 2.2em;
text-align: center;
background: linear-gradient(45deg, #f093fb, #f5576c, #4facfe, #f093fb);
background-size: 200% 200%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradientText 3s ease infinite;
margin-bottom: 15px;
font-weight: bold;
text-shadow: 0 0 30px rgba(245, 87, 108, 0.5);
}
@keyframes gradientText {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
.sparkle-divider {
height: 3px;
background: linear-gradient(90deg, transparent, #f093fb, #4facfe, #f093fb, transparent);
margin: 15px 0;
border-radius: 10px;
animation: sparkleMove 2s linear infinite;
}
@keyframes sparkleMove {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
.name-input-group {
margin-bottom: 20px;
}
.name-input-group label {
display: block;
margin-bottom: 10px;
font-size: 1.2em;
font-weight: bold;
color: #764ba2;
display: flex;
align-items: center;
gap: 10px;
}
.player-icon {
font-size: 1.5em;
animation: bounce 1s infinite;
}
@keyframes bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-5px); }
}
.name-input-group input {
width: 100%;
padding: 15px 20px;
font-size: 1.1em;
border: 3px solid #f093fb;
border-radius: 15px;
outline: none;
transition: all 0.3s ease;
background: rgba(255, 255, 255, 0.9);
font-family: inherit;
}
.name-input-group input:focus {
border-color: #4facfe;
box-shadow: 0 0 20px rgba(79, 172, 254, 0.5);
transform: scale(1.02);
}
/* Avatar Selection */
.avatar-section {
margin: 25px 0 15px 0;
}
.avatar-title {
text-align: center;
font-size: 1.3em;
color: #764ba2;
margin-bottom: 15px;
font-weight: bold;
}
.avatar-selection {
display: flex;
flex-direction: column;
gap: 15px;
}
.player-avatar-group label {
display: block;
font-size: 1em;
font-weight: bold;
color: #764ba2;
margin-bottom: 8px;
text-align: center;
}
.avatar-options {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}
.avatar-option {
aspect-ratio: 1;
font-size: 1.8em;
display: flex;
align-items: center;
justify-content: center;
border: 2px solid #e0e0e0;
border-radius: 12px;
cursor: pointer;
transition: all 0.3s ease;
background: white;
padding: 8px;
}
.avatar-option:hover {
transform: scale(1.15);
border-color: #4facfe;
box-shadow: 0 0 15px rgba(79, 172, 254, 0.5);
}
.avatar-option.selected {
border-color: #f093fb;
background: linear-gradient(135deg, rgba(240, 147, 251, 0.2), rgba(79, 172, 254, 0.2));
box-shadow: 0 0 20px rgba(240, 147, 251, 0.6);
transform: scale(1.1);
}
.avatar-option.selected:hover {
transform: scale(1.2);
}
.start-btn {
width: 100%;
padding: 15px;
font-size: 1.3em;
font-weight: bold;
border: none;
border-radius: 20px;
background: linear-gradient(135deg, #f093fb, #f5576c);
color: white;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 10px 30px rgba(245, 87, 108, 0.4);
margin-top: 15px;
}
.start-btn:hover {
transform: translateY(-5px) scale(1.05);
box-shadow: 0 15px 40px rgba(245, 87, 108, 0.6);
}
.start-btn:active {
transform: translateY(-2px) scale(1.02);
}
/* Game Screen */
.game-card {
background: rgba(255, 255, 255, 0.95);
border-radius: 30px;
padding: 40px;
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.3),
0 0 40px rgba(246, 79, 254, 0.5),
inset 0 0 60px rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 3px solid rgba(255, 255, 255, 0.8);
}
.game-title {
font-size: 2.5em;
text-align: center;
background: linear-gradient(45deg, #f093fb, #f5576c, #4facfe);
background-size: 200% 200%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradientText 3s ease infinite;
margin-bottom: 20px;
font-weight: bold;
}
/* Game Layout - Horizontal Split */
.game-layout {
display: flex;
gap: 30px;
align-items: flex-start;
}
.game-area {
flex: 1;
min-width: 0;
}
/* Score Sidebar */
.score-sidebar {
width: 220px;
flex-shrink: 0;
background: linear-gradient(135deg, rgba(240, 147, 251, 0.15), rgba(79, 172, 254, 0.15));
border-radius: 20px;
padding: 25px 20px;
border: 2px solid rgba(240, 147, 251, 0.3);
display: flex;
flex-direction: column;
gap: 20px;
}
.score-title {
text-align: center;
font-size: 1.4em;
font-weight: bold;
color: #764ba2;
margin-bottom: 10px;
}
.score-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
padding: 15px;
background: rgba(255, 255, 255, 0.5);
border-radius: 15px;
}
.score-avatar {
font-size: 3em;
animation: bounce 2s infinite;
}
.score-name {
font-size: 1em;
font-weight: bold;
color: #764ba2;
}
.score-value {
font-size: 2.5em;
font-weight: bold;
color: #f5576c;
padding: 8px 20px;
background: white;
border-radius: 15px;
border: 3px solid #f093fb;
min-width: 70px;
text-align: center;
box-shadow: 0 5px 15px rgba(240, 147, 251, 0.3);
}
.score-divider {
font-size: 2.5em;
text-align: center;
animation: rotate 3s linear infinite;
}
.score-item.player1-score .score-value {
color: #f5576c;
border-color: #f5576c;
}
.score-item.player2-score .score-value {
color: #4facfe;
border-color: #4facfe;
}
/* Player Info */
.player-info {
display: flex;
justify-content: space-around;
align-items: center;
margin-bottom: 30px;
gap: 20px;
}
.player-display {
display: flex;
flex-direction: column;
align-items: center;
padding: 15px 25px;
border-radius: 20px;
background: rgba(255, 255, 255, 0.7);
border: 3px solid transparent;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.player-display.active {
border-color: #f093fb;
box-shadow: 0 0 30px rgba(240, 147, 251, 0.6);
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
.player-glow {
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: radial-gradient(circle, rgba(240, 147, 251, 0.3), transparent 70%);
opacity: 0;
transition: opacity 0.3s ease;
}
.player-display.active .player-glow {
opacity: 1;
animation: rotate 3s linear infinite;
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.player-symbol {
font-size: 2em;
font-weight: bold;
margin-bottom: 5px;
}
.player1-display .player-symbol {
color: #f5576c;
}
.player2-display .player-symbol {
color: #4facfe;
}
.player-name {
font-size: 1.1em;
font-weight: bold;
color: #764ba2;
}
.vs {
font-size: 1.5em;
font-weight: bold;
color: #764ba2;
}
/* Game Board */
.game-board {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
margin: 30px 0;
padding: 20px;
background: linear-gradient(135deg, rgba(240, 147, 251, 0.2), rgba(79, 172, 254, 0.2));
border-radius: 20px;
}
.cell {
aspect-ratio: 1;
background: white;
border: 4px solid #f093fb;
border-radius: 15px;
display: flex;
justify-content: center;
align-items: center;
font-size: 4em;
font-weight: bold;
cursor: pointer;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
}
.cell::before {
content: '';
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(45deg, transparent, rgba(240, 147, 251, 0.3), transparent);
transform: translateX(-100%);
transition: transform 0.6s ease;
}
.cell:hover:not(.x):not(.o)::before {
transform: translateX(100%);
}
.cell:hover:not(.x):not(.o) {
transform: scale(1.1);
border-color: #4facfe;
box-shadow: 0 0 20px rgba(79, 172, 254, 0.5);
}
.cell.x,
.cell.o {
cursor: not-allowed;
}
.cell.x {
color: #f5576c;
animation: cellAppear 0.3s ease;
}
.cell.o {
color: #4facfe;
animation: cellAppear 0.3s ease;
}
@keyframes cellAppear {
from {
transform: scale(0) rotate(180deg);
opacity: 0;
}
to {
transform: scale(1) rotate(0deg);
opacity: 1;
}
}
.cell.winning {
animation: winningCell 0.6s ease infinite;
background: linear-gradient(135deg, #f093fb, #4facfe);
color: white;
}
@keyframes winningCell {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.1); }
}
/* Game Status */
.game-status {
text-align: center;
font-size: 1.5em;
font-weight: bold;
color: #764ba2;
min-height: 40px;
margin: 20px 0;
}
/* Buttons */
.button-group {
display: flex;
gap: 15px;
margin-top: 20px;
}
.game-btn {
flex: 1;
padding: 15px;
font-size: 1.1em;
font-weight: bold;
border: 3px solid #f093fb;
border-radius: 15px;
background: white;
color: #764ba2;
cursor: pointer;
transition: all 0.3s ease;
}
.game-btn:hover {
background: linear-gradient(135deg, #f093fb, #f5576c);
color: white;
transform: translateY(-3px);
box-shadow: 0 10px 20px rgba(240, 147, 251, 0.4);
}
/* Winner Screen */
.winner-card {
background: rgba(255, 255, 255, 0.95);
border-radius: 30px;
padding: 60px 40px;
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.3),
0 0 40px rgba(246, 79, 254, 0.5),
inset 0 0 60px rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 3px solid rgba(255, 255, 255, 0.8);
text-align: center;
position: relative;
overflow: hidden;
}
.winner-title {
font-size: 3em;
background: linear-gradient(45deg, #f093fb, #f5576c, #4facfe);
background-size: 200% 200%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: gradientText 3s ease infinite;
margin-bottom: 30px;
font-weight: bold;
}
.trophy {
font-size: 8em;
animation: trophyBounce 1s ease-in-out infinite;
margin: 20px 0;
}
@keyframes trophyBounce {
0%, 100% { transform: translateY(0) rotate(-5deg); }
50% { transform: translateY(-20px) rotate(5deg); }
}
.winner-name {
font-size: 2.5em;
font-weight: bold;
color: #764ba2;
margin: 30px 0;
text-shadow: 0 0 20px rgba(240, 147, 251, 0.5);
}
/* Confetti */
.confetti {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
pointer-events: none;
}
.confetti::before,
.confetti::after {
content: '🎉 ✨ 🌟 💫 🎊 ⭐';
position: absolute;
font-size: 2em;
animation: confettiFall 3s linear infinite;
width: 100%;
text-align: center;
}
.confetti::after {
animation-delay: 1.5s;
}
@keyframes confettiFall {
0% {
top: -10%;
opacity: 1;
transform: rotate(0deg);
}
100% {
top: 110%;
opacity: 0.5;
transform: rotate(360deg);
}
}
/* Fireworks */
.fireworks {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
pointer-events: none;
}
.firework {
position: absolute;
width: 10px;
height: 10px;
border-radius: 50%;
animation: fireworkExplode 2s ease-out infinite;
}
.firework:nth-child(1) {
top: 20%;
left: 20%;
background: #f093fb;
}
.firework:nth-child(2) {
top: 30%;
right: 20%;
background: #4facfe;
animation-delay: 0.7s;
}
.firework:nth-child(3) {
bottom: 20%;
left: 50%;
background: #f5576c;
animation-delay: 1.4s;
}
@keyframes fireworkExplode {
0% {
transform: scale(1);
opacity: 1;
box-shadow:
0 0 0 0 currentColor,
0 0 0 0 currentColor,
0 0 0 0 currentColor,
0 0 0 0 currentColor;
}
100% {
transform: scale(2);
opacity: 0;
box-shadow:
0 -50px 0 5px currentColor,
50px 0 0 5px currentColor,
0 50px 0 5px currentColor,
-50px 0 0 5px currentColor;
}
}
/* Particle Effects */
.particle {
position: fixed;
pointer-events: none;
font-size: 1.5em;
z-index: 9999;
animation: particleBurst 0.8s ease-out forwards;
}
@keyframes particleBurst {
0% {
transform: translate(0, 0) scale(1) rotate(0deg);
opacity: 1;
}
100% {
transform: translate(var(--tx), var(--ty)) scale(0) rotate(360deg);
opacity: 0;
}
}
/* Score Update Animation */
.score-value.score-update {
animation: scorePopAnimation 0.5s ease;
}
@keyframes scorePopAnimation {
0% { transform: scale(1); }
50% { transform: scale(1.5); box-shadow: 0 0 30px currentColor; }
100% { transform: scale(1); }
}
/* Responsive Design */
@media (max-width: 768px) {
.game-layout {
flex-direction: column;
}
.score-sidebar {
width: 100%;
flex-direction: row;
justify-content: space-around;
padding: 20px;
}
.score-title {
display: none;
}
.score-item {
flex: 1;
}
.score-divider {
display: flex;
align-items: center;
}
}
@media (max-width: 600px) {
.title {
font-size: 2em;
}
.game-title {
font-size: 1.8em;
}
.cell {
font-size: 2.5em;
}
.button-group {
flex-direction: column;
}
.player-info {
flex-direction: column;
gap: 10px;
}
.vs {
display: none;
}
.container {
max-width: 100%;
}
}