diff --git a/2048.css b/2048.css index d425735..349a044 100644 --- a/2048.css +++ b/2048.css @@ -1,6 +1,10 @@ -/* ====================== - GLOBAL -====================== */ + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + body { background: radial-gradient(circle at center, #0a0a0a, #000); background-size: 300% 300%; @@ -8,93 +12,245 @@ body { font-family: 'Poppins', sans-serif; color: white; text-align: center; - padding-top: 20px; + min-height: 100vh; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 10px; + overflow: hidden; } -/* Background animasi lembut */ @keyframes bgMove { 0% { background-position: 0% 30%; } 50% { background-position: 50% 70%; } 100% { background-position: 100% 30%; } } +/* ====================== + GAME CONTAINER +====================== */ +.game-container { + width: 100%; + max-width: 480px; + margin: 0 auto; + display: flex; + flex-direction: column; + align-items: center; + transform: scale(0.95); +} + +/* ====================== + HEADER - All Centered Vertically +====================== */ +.game-header { + display: flex; + flex-direction: column; + align-items: center; + margin-bottom: 20px; + width: 100%; +} + h1 { - font-size: 40px; - font-weight: bold; - text-shadow: 0 0 20px #00eaff, 0 0 40px #0099ff; + font-size: clamp(42px, 7vw, 68px); + font-weight: 800; + text-shadow: 0 0 25px #00eaff, 0 0 45px #0099ff; + letter-spacing: clamp(4px, 1vw, 8px); + margin: 0 0 clamp(10px, 1.5vh, 16px) 0; + line-height: 1; } -button { - padding: 12px 22px; - margin: 8px; - background: #111; +/* Score Container - Centered below title */ +.score-container { + display: flex; + gap: clamp(10px, 2vw, 14px); + justify-content: center; + margin-bottom: clamp(12px, 2vh, 16px); +} + +.score-box { + background: rgba(30, 0, 50, 0.85); + backdrop-filter: blur(15px); + border: 2px solid rgba(0, 217, 255, 0.45); + border-radius: 12px; + padding: clamp(10px, 1.5vh, 12px) clamp(20px, 3vw, 26px); + min-width: clamp(85px, 12vw, 105px); + box-shadow: + 0 5px 20px rgba(0, 0, 0, 0.4), + 0 0 20px rgba(0, 217, 255, 0.25), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + transition: all 0.3s ease; +} + +.score-box:hover { + border-color: rgba(0, 217, 255, 0.7); + box-shadow: + 0 5px 20px rgba(0, 0, 0, 0.4), + 0 0 30px rgba(0, 217, 255, 0.4), + inset 0 1px 0 rgba(255, 255, 255, 0.15); +} + +.score-label { + font-size: clamp(10px, 1.3vw, 12px); + text-transform: uppercase; + color: rgba(0, 234, 255, 0.85); + letter-spacing: 1.2px; + margin-bottom: 5px; + font-weight: 700; +} + +.score-value { + font-size: clamp(22px, 3vw, 28px); + font-weight: 800; color: white; - border: 2px solid #00eaff; - border-radius: 10px; + text-shadow: 0 0 12px rgba(0, 234, 255, 0.9); + line-height: 1; +} + +/* ====================== + TOP CONTROLS - Icon Buttons (Top Right) +====================== */ +.top-controls { + position: fixed; + top: clamp(10px, 2vh, 20px); + right: clamp(10px, 2vw, 20px); + display: flex; + gap: clamp(8px, 1.5vw, 12px); + z-index: 100; +} + +.icon-btn { + width: clamp(36px, 6vw, 48px); + height: clamp(36px, 6vw, 48px); + padding: 0; + background: rgba(30, 0, 50, 0.85); + backdrop-filter: blur(15px); + border: 2px solid rgba(0, 217, 255, 0.45); + border-radius: 12px; cursor: pointer; - transition: 0.25s; - font-weight: bold; -} -button:hover { - box-shadow: 0 0 15px #00eaff; - transform: scale(1.05); + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + display: flex; + align-items: center; + justify-content: center; + box-shadow: + 0 4px 18px rgba(0, 0, 0, 0.35), + 0 0 20px rgba(0, 217, 255, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); } -#score { - color: #00eaff; - text-shadow: 0 0 10px #00eaff; - font-weight: bold; - font-size: 20px; +.icon-btn svg { + width: clamp(18px, 3vw, 24px); + height: clamp(18px, 3vw, 24px); + color: rgba(0, 234, 255, 0.9); + transition: all 0.3s ease; } +.icon-btn:hover { + background: rgba(0, 234, 255, 0.15); + border-color: rgba(0, 234, 255, 0.8); + box-shadow: + 0 6px 25px rgba(0, 0, 0, 0.45), + 0 0 35px rgba(0, 234, 255, 0.4), + inset 0 1px 0 rgba(255, 255, 255, 0.15); + transform: translateY(-2px); +} + +.icon-btn:hover svg { + color: rgba(0, 234, 255, 1); + transform: scale(1.1); +} + +.btn-restart-icon:hover svg { + transform: scale(1.1) rotate(180deg); +} + +.icon-btn:active { + transform: translateY(0); + box-shadow: + 0 2px 12px rgba(0, 0, 0, 0.35), + 0 0 20px rgba(0, 234, 255, 0.3), + inset 0 2px 6px rgba(0, 0, 0, 0.25); +} + +/* Tutorial Button Specific */ +.btn-tutorial { + background: rgba(50, 0, 70, 0.85); + border-color: rgba(200, 100, 255, 0.45); +} + +.btn-tutorial svg { + color: rgba(200, 100, 255, 0.9); +} + +.btn-tutorial:hover { + background: rgba(200, 100, 255, 0.15); + border-color: rgba(200, 100, 255, 0.8); + box-shadow: + 0 6px 25px rgba(0, 0, 0, 0.45), + 0 0 35px rgba(200, 100, 255, 0.4), + inset 0 1px 0 rgba(255, 255, 255, 0.15); +} + +.btn-tutorial:hover svg { + color: rgba(200, 100, 255, 1); +} /* ========================== - BOARD — MIRIP BORDER LOGIN + BOARD ========================== */ - #board { - width: 460px; - height: 460px; - margin: 35px auto; - padding: 20px; - + width: 100%; + max-width: min(480px, 85vmin); + aspect-ratio: 1; + margin: 0 auto; + padding: clamp(10px, 2vmin, 18px); display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: repeat(4, 1fr); - gap: 12px; - - background: rgba(30, 0, 50, 0.6); /* DALAM GELAP SAMA LOGIN */ - backdrop-filter: blur(10px); - - border: 2px solid rgba(0, 217, 255, 0.3); /* SAMA LOGIN */ + gap: clamp(6px, 1.2vmin, 12px); + background: rgba(30, 0, 50, 0.65); + backdrop-filter: blur(12px); + border: 2px solid rgba(0, 217, 255, 0.35); border-radius: 20px; - box-shadow: - 0 20px 60px rgba(0, 0, 0, 0.5), - 0 0 40px rgba(0, 217, 255, 0.3), - inset 0 0 30px rgba(0, 217, 255, 0.1); - - animation: glowBorderBoard 3s ease-in-out infinite; + 0 25px 70px rgba(0, 0, 0, 0.6), + 0 0 45px rgba(0, 217, 255, 0.35), + inset 0 0 35px rgba(0, 217, 255, 0.12); + animation: glowBorderBoard 3.5s ease-in-out infinite; + position: relative; + z-index: 2; } -/* Border berubah warna seperti login */ @keyframes glowBorderBoard { 0%, 100% { border-color: rgba(0, 217, 255, 0.4); box-shadow: - 0 20px 60px rgba(0, 0, 0, 0.5), - 0 0 40px rgba(0, 217, 255, 0.3), - inset 0 0 30px rgba(0, 217, 255, 0.1); + 0 25px 70px rgba(0, 0, 0, 0.6), + 0 0 45px rgba(0, 217, 255, 0.35), + inset 0 0 35px rgba(0, 217, 255, 0.12); } 50% { - border-color: rgba(255, 0, 255, 0.5); + border-color: rgba(255, 0, 255, 0.55); box-shadow: - 0 20px 60px rgba(0, 0, 0, 0.5), - 0 0 50px rgba(255, 0, 255, 0.4), - inset 0 0 40px rgba(255, 0, 255, 0.15); + 0 25px 70px rgba(0, 0, 0, 0.6), + 0 0 55px rgba(255, 0, 255, 0.45), + inset 0 0 45px rgba(255, 0, 255, 0.18); } } +#board::after { + content: ""; + position: absolute; + bottom: -40px; + left: 50%; + transform: translateX(-50%); + width: 360px; + height: 90px; + background: radial-gradient(ellipse at center, rgba(0,234,255,0.14), transparent 65%); + filter: blur(35px); + z-index: -1; +} /* ====================== TILE @@ -102,171 +258,777 @@ button:hover { .tile { width: 100%; height: 100%; - border-radius: 14px; + border-radius: clamp(8px, 1.8vmin, 14px); display: flex; align-items: center; justify-content: center; - - font-size: 32px; - font-weight: bold; - + font-size: clamp(20px, 3.5vmin, 32px); + font-weight: 800; color: white; - background: rgba(255, 255, 255, 0.06); - text-shadow: 0 0 10px white; - - transition: 0.1s; + background: rgba(255, 255, 255, 0.07); + text-shadow: 0 0 12px rgba(255, 255, 255, 0.9); + transition: transform 0.15s cubic-bezier(.2,.85,.2,1), opacity 0.13s linear, box-shadow 0.13s; + will-change: transform, opacity, box-shadow; + backface-visibility: hidden; + -webkit-backface-visibility: hidden; } -/* animasi tile baru */ .tile.new { - animation: pop 0.25s ease-out; + animation: pop 0.24s cubic-bezier(.2,.9,.2,1); } + @keyframes pop { - 0% { transform: scale(0.2); opacity: 0; } + 0% { transform: scale(0.15); opacity: 0; } 100% { transform: scale(1); opacity: 1; } } -/* Neon warna berdasarkan angka */ -.tile-2 { background: #00eaff55; box-shadow: 0 0 10px #00eaff; } -.tile-4 { background: #00ff9955; box-shadow: 0 0 10px #00ff99; } -.tile-8 { background: #ff00ff55; box-shadow: 0 0 10px #ff00ff; } -.tile-16 { background: #ff006655; box-shadow: 0 0 10px #ff0066; } -.tile-32 { background: #ffaa0055; box-shadow: 0 0 10px #ffaa00; } -.tile-64 { background: #ff000055; box-shadow: 0 0 10px #ff0000; } -.tile-128 { background: #5f00ff55; box-shadow: 0 0 10px #5f00ff; } -.tile-256 { background: #00ffea55; box-shadow: 0 0 10px #00ffea; } -.tile-512 { background: #ff00aa55; box-shadow: 0 0 10px #ff00aa; } -.tile-1024 { background: #00ffaa55; box-shadow: 0 0 10px #00ffaa; } -.tile-2048 { background: #ffd70066; box-shadow: 0 0 15px #ffd700; } +.tile.merge { + animation: mergePop 0.26s ease-out; + z-index: 3; +} -/* ======= ENHANCEMENTS: Animations, Particles, Glows ======= */ +@keyframes mergePop { + 0% { transform: scale(1); box-shadow: 0 0 8px rgba(255,255,255,0.12); } + 50% { transform: scale(1.2); box-shadow: 0 0 35px rgba(255,255,255,0.4); } + 100% { transform: scale(1); box-shadow: 0 0 8px rgba(255,255,255,0.12); } +} -/* ensure board stacking context for absolute animations */ -#board { position: relative; z-index: 2; } +#board.shake { + animation: shakeBoard 0.4s; +} +@keyframes shakeBoard { + 0%,100% { transform: translateX(0); } + 25% { transform: translateX(-10px); } + 75% { transform: translateX(10px); } +} + +/* Tile Colors */ +.tile-2 { background: #00eaff55; box-shadow: 0 0 12px #00eaff; } +.tile-4 { background: #00ff9955; box-shadow: 0 0 12px #00ff99; } +.tile-8 { background: #ff00ff55; box-shadow: 0 0 12px #ff00ff; } +.tile-16 { background: #ff006655; box-shadow: 0 0 12px #ff0066; } +.tile-32 { background: #ffaa0055; box-shadow: 0 0 12px #ffaa00; } +.tile-64 { background: #ff000055; box-shadow: 0 0 12px #ff0000; } +.tile-128 { background: #5f00ff55; box-shadow: 0 0 12px #5f00ff; } +.tile-256 { background: #00ffea55; box-shadow: 0 0 12px #00ffea; } +.tile-512 { background: #ff00aa55; box-shadow: 0 0 12px #ff00aa; } +.tile-1024 { background: #00ffaa55; box-shadow: 0 0 12px #00ffaa; } +.tile-2048 { + background: #ffd70066; + box-shadow: 0 0 18px #ffd700; + animation: goldShimmer 2.6s infinite; +} + +@keyframes goldShimmer { + 0% { box-shadow: 0 0 12px #ffd70066; transform: translateZ(0); } + 50% { box-shadow: 0 0 30px #ffd700aa; transform: translateY(-2px); } + 100% { box-shadow: 0 0 12px #ffd70066; transform: translateZ(0); } +} + +/* Enhanced Merge Animation */ +.tile.merge { + animation: mergeBounce 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); + z-index: 10; +} + +@keyframes mergeBounce { + 0% { + transform: scale(1); + filter: brightness(1); + } + 40% { + transform: scale(1.25) rotate(5deg); + filter: brightness(1.4) drop-shadow(0 0 25px currentColor); + } + 60% { + transform: scale(0.95) rotate(-3deg); + filter: brightness(1.2); + } + 80% { + transform: scale(1.08); + filter: brightness(1.1); + } + 100% { + transform: scale(1) rotate(0deg); + filter: brightness(1); + } +} + +/* Particle Effect */ +.merge-particle { + position: fixed; + width: 10px; + height: 10px; + border-radius: 50%; + pointer-events: none; + z-index: 9998; + box-shadow: + 0 0 10px currentColor, + 0 0 20px currentColor, + inset 0 0 5px rgba(255, 255, 255, 0.5); + filter: blur(0.5px); +} + +/* Score Popup Animation */ +.score-popup { + animation: scoreFloat 1s cubic-bezier(0.34, 1.56, 0.64, 1) forwards; +} + +@keyframes scoreFloat { + 0% { + transform: translate(-50%, -50%) scale(0.5); + opacity: 0; + } + 30% { + transform: translate(-50%, -70px) scale(1.2); + opacity: 1; + } + 100% { + transform: translate(-50%, -120px) scale(1); + opacity: 0; + } +} + +/* Enhanced Tile Glow on Merge */ +.tile.merge { + box-shadow: + 0 0 30px currentColor, + 0 0 50px currentColor, + inset 0 0 20px rgba(255, 255, 255, 0.3) !important; +} + +/* Smoother New Tile Animation */ +.tile.new { + animation: popIn 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55); +} + +@keyframes popIn { + 0% { + transform: scale(0) rotate(-180deg); + opacity: 0; + filter: blur(4px); + } + 70% { + transform: scale(1.15) rotate(10deg); + filter: blur(0); + } + 100% { + transform: scale(1) rotate(0deg); + opacity: 1; + filter: blur(0); + } +} + +/* Tile Hover Effect - Make it more interactive */ +.tile:not(:empty):hover { + transform: scale(1.05); + transition: transform 0.2s ease; + filter: brightness(1.2); +} + +/* Add ripple effect on board when moving */ +#board.moving { + animation: boardPulse 0.3s ease-out; +} + +@keyframes boardPulse { + 0%, 100% { + transform: scale(1); + } + 50% { + transform: scale(1.01); + } +} + +/* ========================== + TUTORIAL MODAL +========================== */ +.tutorial-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.88); + backdrop-filter: blur(10px); + display: flex; + align-items: center; + justify-content: center; + z-index: 998; + animation: fadeIn 0.3s ease-out; +} + +.tutorial-modal { + background: rgba(20, 0, 40, 0.96); + backdrop-filter: blur(25px); + border: 3px solid rgba(200, 100, 255, 0.5); + border-radius: 24px; + padding: 45px 50px; + max-width: 500px; + width: 90%; + text-align: center; + box-shadow: + 0 35px 90px rgba(0, 0, 0, 0.75), + 0 0 60px rgba(200, 100, 255, 0.4), + inset 0 0 50px rgba(200, 100, 255, 0.1); + animation: modalSlideUp 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); + position: relative; +} + +.modal-close { + position: absolute; + top: 15px; + right: 15px; + width: 36px; + height: 36px; + padding: 0; + background: rgba(255, 255, 255, 0.05); + border: 2px solid rgba(255, 255, 255, 0.2); + border-radius: 8px; + cursor: pointer; + transition: all 0.3s; + display: flex; + align-items: center; + justify-content: center; +} + +.modal-close svg { + width: 20px; + height: 20px; + color: rgba(255, 255, 255, 0.7); +} + +.modal-close:hover { + background: rgba(255, 50, 50, 0.2); + border-color: rgba(255, 50, 50, 0.6); + transform: rotate(90deg); +} + +.modal-close:hover svg { + color: #ff5050; +} + +.tutorial-title { + font-size: 32px; + font-weight: 800; + color: #c864ff; + text-shadow: 0 0 25px rgba(200, 100, 255, 0.8); + margin-bottom: 30px; + letter-spacing: 2px; +} + +.tutorial-content { + display: flex; + flex-direction: column; + gap: 30px; +} + +.tutorial-section h3 { + font-size: 18px; + color: rgba(200, 100, 255, 0.9); + margin-bottom: 15px; + font-weight: 700; +} + +/* Show/Hide based on device */ +.mobile-controls { + display: none; +} + +@media (max-width: 768px) { + .pc-controls { + display: none !important; + } + + .mobile-controls { + display: block; + } +} + +/* Keys Display */ +.keys-container { + display: flex; + align-items: center; + justify-content: center; + gap: clamp(20px, 5vw, 40px); + flex-wrap: nowrap; +} + +.keys-group { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; +} + +.keys-grid-wasd, +.keys-grid-arrow { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: repeat(2, 1fr); + gap: 8px; + justify-items: center; + align-items: center; +} + +.keys-separator { + font-size: clamp(14px, 2.2vw, 18px); + color: rgba(255, 255, 255, 0.5); + font-weight: 700; + padding: 0 clamp(10px, 2vw, 15px); +} + +.key-box { + width: clamp(42px, 6.5vw, 52px); + height: clamp(42px, 6.5vw, 52px); + background: rgba(0, 234, 255, 0.15); + border: 2px solid rgba(0, 234, 255, 0.5); + border-radius: 10px; + display: flex; + align-items: center; + justify-content: center; + font-size: clamp(17px, 2.8vw, 22px); + font-weight: 700; + color: #00eaff; + text-shadow: 0 0 10px rgba(0, 234, 255, 0.8); + box-shadow: + 0 4px 15px rgba(0, 0, 0, 0.3), + 0 0 20px rgba(0, 234, 255, 0.2), + inset 0 -2px 0 rgba(0, 0, 0, 0.3), + inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +.key-empty { + width: clamp(42px, 6.5vw, 52px); + height: clamp(42px, 6.5vw, 52px); + visibility: hidden; +} + +.keys-label { + font-size: clamp(12px, 1.8vw, 14px); + color: rgba(255, 255, 255, 0.6); + margin-top: 5px; + font-weight: 600; + text-align: center; +} + +/* Swipe Demo */ +.swipe-demo { + display: flex; + flex-direction: column; + align-items: center; + gap: 10px; +} + +.swipe-icon { + font-size: 48px; + animation: swipeAnimation 2s ease-in-out infinite; +} + +@keyframes swipeAnimation { + 0%, 100% { transform: translateX(0); } + 25% { transform: translateX(-15px); } + 50% { transform: translateX(0); } + 75% { transform: translateX(15px); } +} + +.swipe-demo p { + font-size: 14px; + color: rgba(255, 255, 255, 0.7); +} + +/* Objective Text */ +.objective-text { + font-size: 15px; + color: rgba(255, 255, 255, 0.85); + line-height: 1.6; +} + +.objective-text strong { + color: #ffd700; + text-shadow: 0 0 10px rgba(255, 215, 0, 0.6); + font-weight: 800; +} + +/* ========================== + GAME OVER MODAL - WITH ICON BUTTONS +========================== */ +/* ========================== + GAME OVER MODAL - REVISED VERSION + Copy bagian ini dan replace yang lama di 2048.css +========================== */ + +.game-over-overlay { + position: fixed; + inset: 0; + background: rgba(0, 0, 0, 0.93); + backdrop-filter: blur(15px); + display: flex; + align-items: center; + justify-content: center; + z-index: 999; + animation: fadeIn 0.3s ease-out; +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +.game-over-modal { + background: linear-gradient(145deg, rgba(15, 0, 35, 0.98), rgba(25, 0, 45, 0.98)); + backdrop-filter: blur(30px); + border: 3px solid rgba(255, 50, 100, 0.5); + border-radius: 32px; + padding: 55px 50px 45px; + max-width: 460px; + width: 90%; + text-align: center; + box-shadow: + 0 50px 120px rgba(0, 0, 0, 0.85), + 0 0 100px rgba(255, 50, 100, 0.4), + inset 0 2px 80px rgba(255, 50, 100, 0.06); + animation: modalSlideUp 0.4s cubic-bezier(0.2, 0.8, 0.2, 1); + position: relative; +} + +@keyframes modalSlideUp { + from { + opacity: 0; + transform: translateY(60px) scale(0.85); + } + to { + opacity: 1; + transform: translateY(0) scale(1); + } +} + +/* Close Button (X) - Top Right */ +.game-over-close { + position: absolute; + top: 18px; + right: 18px; + width: 38px; + height: 38px; + padding: 0; + background: rgba(255, 255, 255, 0.06); + border: 2px solid rgba(255, 255, 255, 0.15); + border-radius: 10px; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + display: flex; + align-items: center; + justify-content: center; + z-index: 10; +} + +.game-over-close svg { + width: 20px; + height: 20px; + color: rgba(255, 255, 255, 0.6); + transition: all 0.3s ease; +} + +.game-over-close:hover { + background: rgba(255, 80, 80, 0.2); + border-color: rgba(255, 80, 80, 0.6); + transform: rotate(90deg) scale(1.05); +} + +.game-over-close:hover svg { + color: #ff6666; +} + +.game-over-close:active { + transform: rotate(90deg) scale(0.95); +} + +/* Title - Gradient Pink/Red */ +.game-over-title { + font-size: clamp(32px, 5vw, 42px); + font-weight: 900; + background: linear-gradient(135deg, #ff3366 0%, #ff6699 50%, #ff99cc 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + filter: drop-shadow(0 0 35px rgba(255, 51, 102, 0.5)); + margin-bottom: 12px; + letter-spacing: 4px; + text-transform: uppercase; + line-height: 1.2; +} + +/* Subtitle */ +.game-over-subtitle { + font-size: 14px; + color: rgba(255, 255, 255, 0.5); + letter-spacing: 2px; + margin-bottom: 35px; + font-weight: 600; + text-transform: uppercase; +} + +/* Score Section - PURPLE/VIOLET gradient */ +.game-over-score { + margin: 0 0 38px; +} + +.game-over-score-label { + font-size: 11px; + text-transform: uppercase; + color: rgba(200, 100, 255, 0.7); + letter-spacing: 3px; + margin-bottom: 14px; + font-weight: 700; +} + +.game-over-score-value { + font-size: clamp(52px, 8vw, 68px); + font-weight: 900; + background: linear-gradient(135deg, #c864ff 0%, #8b5cf6 50%, #a855f7 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + filter: drop-shadow(0 0 30px rgba(200, 100, 255, 0.6)); + margin-bottom: 10px; + line-height: 1; + letter-spacing: -2px; +} + +/* New High Score Badge - GOLD */ +.new-high-score { + display: inline-block; + background: linear-gradient(135deg, rgba(255, 215, 0, 0.2), rgba(255, 165, 0, 0.2)); + border: 2.5px solid rgba(255, 215, 0, 0.7); + color: #ffd700; + padding: 12px 26px; + border-radius: 50px; + font-size: 13px; + font-weight: 800; + text-transform: uppercase; + letter-spacing: 2px; + margin-top: 18px; + box-shadow: + 0 0 35px rgba(255, 215, 0, 0.35), + inset 0 0 30px rgba(255, 215, 0, 0.1); + animation: newHighScorePulse 2s ease-in-out infinite; +} + +@keyframes newHighScorePulse { + 0%, 100% { + box-shadow: + 0 0 30px rgba(255, 215, 0, 0.4), + inset 0 0 30px rgba(255, 215, 0, 0.1); + border-color: rgba(255, 215, 0, 0.7); + transform: scale(1); + } + 50% { + box-shadow: + 0 0 50px rgba(255, 215, 0, 0.7), + inset 0 0 40px rgba(255, 215, 0, 0.2); + border-color: rgba(255, 215, 0, 1); + transform: scale(1.02); + } +} + +/* Best Score Display - ORANGE gradient */ +.best-score-display { + margin-top: 28px; + padding-top: 28px; + border-top: 2px solid rgba(255, 140, 0, 0.25); +} + +.best-score-label { + font-size: 11px; + text-transform: uppercase; + color: rgba(255, 160, 50, 0.7); + letter-spacing: 2.5px; + margin-bottom: 10px; + font-weight: 700; +} + +.best-score-value { + font-size: clamp(34px, 5vw, 42px); + font-weight: 900; + background: linear-gradient(135deg, #ff8c00 0%, #ffa500 50%, #ffb347 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; + filter: drop-shadow(0 0 20px rgba(255, 140, 0, 0.5)); + line-height: 1; + letter-spacing: -1px; +} + +/* =========================== + ICON BUTTONS - Enhanced Color +=========================== */ +.game-over-buttons { + display: flex; + gap: 16px; + justify-content: center; + margin-top: 42px; +} + +/* Icon Button Base Style */ +.btn-game-icon { + width: clamp(70px, 10vw, 80px); + height: clamp(70px, 10vw, 80px); + padding: 0; + background: rgba(255, 255, 255, 0.06); + border: 2px solid rgba(255, 255, 255, 0.2); + border-radius: 20px; + cursor: pointer; + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + display: flex; + align-items: center; + justify-content: center; + backdrop-filter: blur(10px); + box-shadow: + 0 8px 30px rgba(0, 0, 0, 0.4), + inset 0 1px 0 rgba(255, 255, 255, 0.1); + position: relative; + overflow: hidden; +} + +.btn-game-icon svg { + width: clamp(32px, 5vw, 38px); + height: clamp(32px, 5vw, 38px); + transition: all 0.3s ease; + position: relative; + z-index: 2; +} + +/* Shine Effect */ +.btn-game-icon::before { + content: ""; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.15), transparent); + transition: left 0.5s ease; +} + +.btn-game-icon:hover::before { + left: 100%; +} + +.btn-game-icon:hover { + background: rgba(255, 255, 255, 0.12); + border-color: rgba(255, 255, 255, 0.4); + box-shadow: + 0 12px 40px rgba(0, 0, 0, 0.5), + 0 0 40px rgba(255, 255, 255, 0.15), + inset 0 1px 0 rgba(255, 255, 255, 0.2); + transform: translateY(-4px); +} + +.btn-game-icon:active { + transform: translateY(0); + box-shadow: + 0 4px 20px rgba(0, 0, 0, 0.4), + inset 0 2px 8px rgba(0, 0, 0, 0.3); +} + +/* Restart Button - EMERALD GREEN */ +.btn-restart-game { + background: linear-gradient(135deg, rgba(16, 185, 129, 0.2), rgba(5, 150, 105, 0.2)); + border-color: rgba(16, 185, 129, 0.6); + box-shadow: + 0 8px 30px rgba(0, 0, 0, 0.4), + 0 0 30px rgba(16, 185, 129, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +.btn-restart-game svg { + color: #10b981; + filter: drop-shadow(0 0 12px rgba(16, 185, 129, 0.5)); +} + +.btn-restart-game:hover { + background: linear-gradient(135deg, rgba(16, 185, 129, 0.3), rgba(5, 150, 105, 0.3)); + border-color: rgba(16, 185, 129, 0.9); + box-shadow: + 0 12px 40px rgba(0, 0, 0, 0.5), + 0 0 50px rgba(16, 185, 129, 0.5), + inset 0 1px 0 rgba(255, 255, 255, 0.2); +} + +.btn-restart-game:hover svg { + transform: rotate(180deg); + color: #34d399; +} + +/* Home Button - SKY BLUE */ +.btn-home-game { + background: linear-gradient(135deg, rgba(14, 165, 233, 0.2), rgba(2, 132, 199, 0.2)); + border-color: rgba(14, 165, 233, 0.6); + box-shadow: + 0 8px 30px rgba(0, 0, 0, 0.4), + 0 0 30px rgba(14, 165, 233, 0.2), + inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +.btn-home-game svg { + color: #0ea5e9; + filter: drop-shadow(0 0 12px rgba(14, 165, 233, 0.5)); +} + +.btn-home-game:hover { + background: linear-gradient(135deg, rgba(14, 165, 233, 0.3), rgba(2, 132, 199, 0.3)); + border-color: rgba(14, 165, 233, 0.9); + box-shadow: + 0 12px 40px rgba(0, 0, 0, 0.5), + 0 0 50px rgba(14, 165, 233, 0.5), + inset 0 1px 0 rgba(255, 255, 255, 0.2); +} + +.btn-home-game:hover svg { + transform: scale(1.1); + color: #38bdf8; +} + +/* Responsive Design */ +@media (max-width: 480px) { + .game-over-modal { + padding: 45px 35px 38px; + } + + .game-over-buttons { + gap: 12px; + } + + .btn-game-icon { + width: clamp(65px, 15vw, 75px); + height: clamp(65px, 15vw, 75px); + } + + .btn-game-icon svg { + width: clamp(28px, 6vw, 34px); + height: clamp(28px, 6vw, 34px); + } +} +/* ========================== + BACKGROUND EFFECTS +========================== */ .particles { position: fixed; inset: 0; pointer-events: none; z-index: 0; - background: - radial-gradient(circle at 20% 30%, rgba(0,234,255,0.18), transparent 45%), - radial-gradient(circle at 80% 70%, rgba(255,0,90,0.18), transparent 45%), - radial-gradient(circle at 50% 50%, rgba(140,0,255,0.14), transparent 55%), - radial-gradient(circle at 10% 85%, rgba(0,255,200,0.12), transparent 55%), - radial-gradient(circle at 90% 15%, rgba(255,0,255,0.15), transparent 45%); - - filter: blur(55px) brightness(120%) saturate(130%); - animation: particlesFloat 18s ease-in-out infinite alternate; + radial-gradient(circle at 20% 30%, rgba(0,234,255,0.2), transparent 48%), + radial-gradient(circle at 80% 70%, rgba(255,0,90,0.2), transparent 48%), + radial-gradient(circle at 50% 50%, rgba(140,0,255,0.16), transparent 58%), + radial-gradient(circle at 10% 85%, rgba(0,255,200,0.14), transparent 58%), + radial-gradient(circle at 90% 15%, rgba(255,0,255,0.17), transparent 48%); + filter: blur(60px) brightness(125%) saturate(135%); + animation: particlesFloat 20s ease-in-out infinite alternate; } @keyframes particlesFloat { 0% { transform: translateY(0px) translateX(0px); } - 50% { transform: translateY(-25px) translateX(10px); } - 100% { transform: translateY(-40px) translateX(-15px); } -} - - -.cursor-light { - position: absolute; - width: 240px; - height: 240px; - background: radial-gradient(circle, rgba(0,255,255,0.25), transparent 70%); - border-radius: 50%; - pointer-events: none; - transform: translate(-50%, -50%); - filter: blur(40px); - mix-blend-mode: screen; - opacity: 0.6; -} - - -/* gentle vertical float */ -@keyframes floatBg { 0% { transform: translateY(0);} 100% { transform: translateY(-14px);} } - -/* Tile move / slide illusion: tiles appear from direction */ -.tile { - transition: transform 0.14s cubic-bezier(.2,.8,.2,1), opacity 0.12s linear, box-shadow 0.12s; - will-change: transform, opacity, box-shadow; -} - -/* 'new' pop kept but slightly tuned */ -.tile.new { - animation: pop 0.22s cubic-bezier(.2,.9,.2,1); -} - -/* merge pop */ -.tile.merge { - animation: mergePop 0.24s ease-out; - z-index: 3; -} -@keyframes mergePop { - 0% { transform: scale(1); box-shadow: 0 0 6px rgba(255,255,255,0.1); } - 50% { transform: scale(1.18); box-shadow: 0 0 30px rgba(255,255,255,0.35); } - 100% { transform: scale(1); box-shadow: 0 0 6px rgba(255,255,255,0.1); } -} - -/* board shake when invalid move */ -#board.shake { - animation: shakeBoard 0.36s; -} -@keyframes shakeBoard { - 0%,100% { transform: translateX(0); } - 25% { transform: translateX(-8px); } - 75% { transform: translateX(8px); } -} - -/* ambient glow under board (keeps aesthetics) */ -#board::after { - content: ""; - position: absolute; - bottom: -36px; - left: 50%; - transform: translateX(-50%); - width: 340px; - height: 84px; - background: radial-gradient(ellipse at center, rgba(0,234,255,0.12), transparent 60%); - filter: blur(30px); - z-index: 0; -} - -/* special 2048 tile sparkle (adds shimmer) */ -.tile-2048 { - animation: goldShimmer 2.4s infinite; -} -@keyframes goldShimmer { - 0% { box-shadow: 0 0 10px #ffd70066; transform: translateZ(0); } - 50% { box-shadow: 0 0 26px #ffd700aa; transform: translateY(-2px); } - 100% { box-shadow: 0 0 10px #ffd70066; transform: translateZ(0); } -} - -/* small particle bits that appear for merge */ -.merge-particle { - position: absolute; - width: 8px; - height: 8px; - border-radius: 50%; - pointer-events: none; - opacity: 0.95; - will-change: transform, opacity; - filter: blur(1px) drop-shadow(0 0 6px rgba(255,255,255,0.08)); -} - -/* ensure base tile readability on animation */ -.tile { backface-visibility: hidden; -webkit-backface-visibility: hidden; } - -/* mobile touch hint (optional) */ -.touch-hint { - position: fixed; - right: 18px; - bottom: 18px; - background: rgba(0,0,0,0.45); - padding: 8px 10px; - border-radius: 10px; - font-size: 12px; - z-index: 4; - color: #cfefff; + 50% { transform: translateY(-30px) translateX(12px); } + 100% { transform: translateY(-45px) translateX(-18px); } } .starfield { @@ -281,14 +1043,65 @@ button:hover { position: absolute; width: 4px; height: 4px; - background: rgba(0,255,255,0.8); + background: rgba(0,255,255,0.85); border-radius: 50%; filter: blur(2px); animation: starMove linear infinite; } -/* bintang bergerak random */ @keyframes starMove { - 0% { transform: translateY(0); opacity: 0.8; } - 100% { transform: translateY(-700px); opacity: 0; } + 0% { transform: translateY(0); opacity: 0.85; } + 100% { transform: translateY(-750px); opacity: 0; } } + +.cursor-light { + position: absolute; + width: 250px; + height: 250px; + background: radial-gradient(circle, rgba(0,255,255,0.28), transparent 72%); + border-radius: 50%; + pointer-events: none; + transform: translate(-50%, -50%); + filter: blur(45px); + mix-blend-mode: screen; + opacity: 0.65; +} + +.merge-particle { + position: absolute; + width: 8px; + height: 8px; + border-radius: 50%; + pointer-events: none; + opacity: 0.95; + will-change: transform, opacity; + filter: blur(1px) drop-shadow(0 0 8px rgba(255,255,255,0.1)); +} + +/* ========================== + RESPONSIVE DESIGN +========================== */ + +/* Touch hint for mobile only */ +.touch-hint { + display: none; +} + +@media (max-width: 768px) { + .touch-hint { + display: block; + position: fixed; + right: clamp(10px, 2vw, 16px); + bottom: clamp(10px, 2vh, 16px); + background: rgba(0, 0, 0, 0.65); + backdrop-filter: blur(12px); + padding: clamp(7px, 1.5vw, 9px) clamp(11px, 2vw, 14px); + border-radius: 10px; + font-size: clamp(10px, 1.5vw, 11px); + z-index: 4; + color: #cfefff; + border: 1px solid rgba(0, 217, 255, 0.35); + box-shadow: 0 5px 18px rgba(0, 0, 0, 0.35); + font-weight: 500; + } +} \ No newline at end of file diff --git a/2048.html b/2048.html index c5c2f07..7a97490 100644 --- a/2048.html +++ b/2048.html @@ -1,26 +1,172 @@ - -
- - -