diff --git a/Transcendence/srcs/frontend/src/renderer.js b/Transcendence/srcs/frontend/src/renderer.js index f033660..4e63154 100644 --- a/Transcendence/srcs/frontend/src/renderer.js +++ b/Transcendence/srcs/frontend/src/renderer.js @@ -3,7 +3,7 @@ // ───────────────────────────────────────────── const CELL = 30; -const COLORS = ['#070712','#a855f7','#f97316','#3b82f6','#06b6d4','#ef4444','#22c55e','#eab308','#555577']; +const COLORS = ['#000500','#00ff41','#39ff14','#00e676','#76ff03','#b2ff59','#00ffaa','#ccff00','#2d5a2d']; const ctxMain = document.getElementById('canvas-main').getContext('2d'); const ctxNext = document.getElementById('canvas-next').getContext('2d'); @@ -12,25 +12,32 @@ const ctxOpponent = document.getElementById('canvas-opponent').getContext('2d'); function drawCell(ctx, x, y, colorIndex, size) { const p = 1; - ctx.fillStyle = COLORS[colorIndex]; + const color = COLORS[colorIndex]; + ctx.fillStyle = color; ctx.fillRect(x * size + p, y * size + p, size - p * 2, size - p * 2); - // Highlight - ctx.fillStyle = 'rgba(255,255,255,0.25)'; - ctx.fillRect(x * size + p, y * size + p, size - p * 2, 3); - ctx.fillRect(x * size + p, y * size + p, 3, size - p * 2); - // Ombre - ctx.fillStyle = 'rgba(0,0,0,0.35)'; - ctx.fillRect(x * size + p, (y + 1) * size - p - 3, size - p * 2, 3); - ctx.fillRect((x + 1) * size - p - 3, y * size + p, 3, size - p * 2); + // Glow inner + ctx.shadowColor = color; + ctx.shadowBlur = 6; + ctx.fillStyle = color; + ctx.fillRect(x * size + p + 2, y * size + p + 2, size - p * 2 - 4, size - p * 2 - 4); + ctx.shadowBlur = 0; + // Highlight top/left + ctx.fillStyle = 'rgba(200,255,200,0.2)'; + ctx.fillRect(x * size + p, y * size + p, size - p * 2, 2); + ctx.fillRect(x * size + p, y * size + p, 2, size - p * 2); + // Shadow bottom/right + ctx.fillStyle = 'rgba(0,0,0,0.5)'; + ctx.fillRect(x * size + p, (y + 1) * size - p - 2, size - p * 2, 2); + ctx.fillRect((x + 1) * size - p - 2, y * size + p, 2, size - p * 2); } function clearCanvas(ctx, w, h) { - ctx.fillStyle = '#070712'; + ctx.fillStyle = '#000500'; ctx.fillRect(0, 0, w, h); } function drawGridLines(ctx, cols, rows, size) { - ctx.strokeStyle = 'rgba(255,255,255,0.04)'; + ctx.strokeStyle = 'rgba(0,255,65,0.06)'; ctx.lineWidth = 1; for (let x = 0; x <= cols; x++) { ctx.beginPath(); ctx.moveTo(x * size, 0); ctx.lineTo(x * size, rows * size); ctx.stroke(); @@ -60,7 +67,7 @@ function drawGhost(ctx, piece, grid) { if (ghost.y === piece.getPosition().y) return; - ctx.strokeStyle = 'rgba(255,255,255,0.15)'; + ctx.strokeStyle = 'rgba(0,255,65,0.25)'; ctx.lineWidth = 1; for (let row = 0; row < shape.length; row++) for (let col = 0; col < shape[row].length; col++) diff --git a/Transcendence/srcs/frontend/src/tetris.css b/Transcendence/srcs/frontend/src/tetris.css index bc30260..29c2a08 100644 --- a/Transcendence/srcs/frontend/src/tetris.css +++ b/Transcendence/srcs/frontend/src/tetris.css @@ -1,11 +1,42 @@ :root { - --bg: #070712; - --panel: #0d0d1f; - --border: #1a1a3e; - --accent: #00ffe7; - --accent2:#ff00aa; - --dim: #3a3a6a; - --text: #c0c0e0; + --bg: #000500; + --panel: #000d00; + --border: #004400; + --accent: #00ff41; + --accent2:#39ff14; + --dim: #1a5c1a; + --text: #00cc26; +} + +@keyframes flicker { + 0%, 89%, 91%, 93%, 95%, 100% { opacity: 1; } + 90%, 92%, 94% { opacity: 0.82; } +} + +@keyframes glitch-before { + 0%, 100% { clip-path: polygon(0 0, 100% 0, 100% 0, 0 0); transform: translate(0); } + 5% { clip-path: polygon(0 15%, 100% 15%, 100% 25%, 0 25%); transform: translate(-4px, 0); color: #ff003c; } + 10% { clip-path: polygon(0 60%, 100% 60%, 100% 70%, 0 70%); transform: translate(4px, 0); color: #ff003c; } + 15%, 85% { clip-path: polygon(0 0, 100% 0, 100% 0, 0 0); transform: translate(0); } + 90% { clip-path: polygon(0 40%, 100% 40%, 100% 55%, 0 55%); transform: translate(-3px, 0); color: #ff003c; } +} + +@keyframes glitch-after { + 0%, 100% { clip-path: polygon(0 0, 100% 0, 100% 0, 0 0); transform: translate(0); } + 5% { clip-path: polygon(0 70%, 100% 70%, 100% 80%, 0 80%); transform: translate(4px, 0); color: #00ffff; } + 10% { clip-path: polygon(0 30%, 100% 30%, 100% 45%, 0 45%); transform: translate(-4px, 0); color: #00ffff; } + 15%, 85% { clip-path: polygon(0 0, 100% 0, 100% 0, 0 0); transform: translate(0); } + 90% { clip-path: polygon(0 10%, 100% 10%, 100% 25%, 0 25%); transform: translate(3px, 0); color: #00ffff; } +} + +@keyframes cursor-blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } +} + +@keyframes scan { + 0% { background-position: 0 0; } + 100% { background-position: 0 100%; } } * { margin: 0; padding: 0; box-sizing: border-box; } @@ -18,34 +49,83 @@ body { display: flex; flex-direction: column; align-items: center; - justify-content: center; + justify-content: flex-start; overflow: hidden; + animation: flicker 8s infinite; } +#scale-container { + display: flex; + flex-direction: column; + align-items: center; + width: max-content; + position: relative; + z-index: 1; + /* transform et margin-bottom gérés par JS */ +} + +/* Grid lines */ body::before { content: ''; position: fixed; inset: 0; background-image: - linear-gradient(rgba(0,255,231,0.03) 1px, transparent 1px), - linear-gradient(90deg, rgba(0,255,231,0.03) 1px, transparent 1px); + linear-gradient(rgba(0,255,65,0.04) 1px, transparent 1px), + linear-gradient(90deg, rgba(0,255,65,0.04) 1px, transparent 1px); background-size: 40px 40px; pointer-events: none; z-index: 0; } +/* Scanlines CRT */ +body::after { + content: ''; + position: fixed; + inset: 0; + background: repeating-linear-gradient( + 0deg, + transparent, + transparent 2px, + rgba(0, 0, 0, 0.12) 2px, + rgba(0, 0, 0, 0.12) 4px + ); + pointer-events: none; + z-index: 9998; +} + h1 { - font-family: 'Orbitron', monospace; + font-family: 'Share Tech Mono', monospace; font-weight: 900; font-size: 2.2rem; letter-spacing: 0.4em; color: var(--accent); - text-shadow: 0 0 20px var(--accent), 0 0 40px var(--accent); + text-shadow: 0 0 10px var(--accent), 0 0 30px var(--accent), 0 0 60px rgba(0,255,65,0.4); margin-bottom: 20px; position: relative; z-index: 1; } +h1::before { + content: attr(data-text); + position: absolute; + top: 0; left: 0; width: 100%; + color: var(--accent); + animation: glitch-before 6s infinite; +} + +h1::after { + content: attr(data-text); + position: absolute; + top: 0; left: 0; width: 100%; + color: var(--accent); + animation: glitch-after 6s infinite; +} + +.cursor { + animation: cursor-blink 1s step-end infinite; + color: var(--accent); +} + /* ── Zone de jeu globale ── */ #game-area { display: flex; @@ -86,10 +166,10 @@ h1 { .panel { background: var(--panel); border: 1px solid var(--border); - border-radius: 6px; + border-radius: 0; padding: 14px; width: 130px; - box-shadow: 0 0 20px rgba(0,255,231,0.05); + box-shadow: 0 0 20px rgba(0,255,65,0.07), inset 0 0 20px rgba(0,0,0,0.5); } .panel-title { @@ -102,11 +182,11 @@ h1 { text-align: center; } -canvas { display: block; border-radius: 4px; } +canvas { display: block; border-radius: 0; } #canvas-main { - border: 1px solid var(--border); - box-shadow: 0 0 30px rgba(0,255,231,0.08), inset 0 0 30px rgba(0,0,0,0.5); + border: 1px solid var(--accent); + box-shadow: 0 0 20px rgba(0,255,65,0.15), 0 0 40px rgba(0,255,65,0.06), inset 0 0 30px rgba(0,0,0,0.7); } #canvas-next, #canvas-hold { @@ -117,7 +197,7 @@ canvas { display: block; border-radius: 4px; } /* ── Canvas adversaire ── */ #canvas-opponent { border: 1px solid var(--accent2); - box-shadow: 0 0 30px rgba(255,0,170,0.08), inset 0 0 30px rgba(0,0,0,0.5); + box-shadow: 0 0 20px rgba(57,255,20,0.12), inset 0 0 30px rgba(0,0,0,0.5); } /* ── Score ── */ @@ -151,16 +231,16 @@ canvas { display: block; border-radius: 4px; } } button { - font-family: 'Orbitron', monospace; - font-size: 0.55rem; - letter-spacing: 0.15em; + font-family: 'Share Tech Mono', monospace; + font-size: 0.6rem; + letter-spacing: 0.12em; font-weight: 700; text-transform: uppercase; padding: 10px 8px; border: 1px solid; - border-radius: 4px; + border-radius: 0; cursor: pointer; - transition: all 0.2s; + transition: all 0.15s; background: transparent; width: 100%; } @@ -222,8 +302,8 @@ button:disabled { opacity: 0.3; cursor: not-allowed; } top: 0; left: 0; width: 300px; height: 600px; - background: rgba(7,7,18,0.88); - border-radius: 4px; + background: rgba(0,5,0,0.9); + border-radius: 0; flex-direction: column; align-items: center; justify-content: center; @@ -235,22 +315,23 @@ button:disabled { opacity: 0.3; cursor: not-allowed; } #overlay-opponent.visible { display: flex; } #overlay-title { - font-family: 'Orbitron', monospace; + font-family: 'Share Tech Mono', monospace; font-size: 1.4rem; font-weight: 900; letter-spacing: 0.2em; - color: var(--accent2); - text-shadow: 0 0 20px var(--accent2); + color: #ff003c; + text-shadow: 0 0 20px #ff003c, 0 0 40px #ff003c; } #overlay-score { - font-family: 'Orbitron', monospace; + font-family: 'Share Tech Mono', monospace; font-size: 0.9rem; color: var(--accent); + text-shadow: 0 0 10px var(--accent); } #overlay-opponent-title { - font-family: 'Orbitron', monospace; + font-family: 'Share Tech Mono', monospace; font-size: 1.4rem; font-weight: 900; letter-spacing: 0.2em; @@ -259,7 +340,7 @@ button:disabled { opacity: 0.3; cursor: not-allowed; } } #overlay-opponent-score { - font-family: 'Orbitron', monospace; + font-family: 'Share Tech Mono', monospace; font-size: 0.9rem; color: var(--accent2); } @@ -268,7 +349,7 @@ button:disabled { opacity: 0.3; cursor: not-allowed; } #duel-panel { background: var(--panel); border: 1px solid var(--border); - border-radius: 6px; + border-radius: 0; padding: 12px 20px; margin-bottom: 14px; position: relative; @@ -276,7 +357,7 @@ button:disabled { opacity: 0.3; cursor: not-allowed; } display: flex; align-items: center; gap: 14px; - box-shadow: 0 0 20px rgba(255,0,170,0.04); + box-shadow: 0 0 20px rgba(0,255,65,0.04); } .duel-row { @@ -332,9 +413,9 @@ button:disabled { opacity: 0.3; cursor: not-allowed; } #settings-panel { background: var(--panel); border: 1px solid var(--border); - border-radius: 6px; + border-radius: 0; padding: 14px; - box-shadow: 0 0 20px rgba(0,255,231,0.05); + box-shadow: 0 0 20px rgba(0,255,65,0.05); display: flex; flex-direction: column; gap: 10px; @@ -437,8 +518,9 @@ button:disabled { opacity: 0.3; cursor: not-allowed; } margin: 20px auto 30px; background: var(--panel); border: 1px solid var(--border); - border-radius: 8px; + border-radius: 0; overflow: hidden; + box-shadow: 0 0 20px rgba(0,255,65,0.05); } .leaderboard-tabs { @@ -464,7 +546,7 @@ button:disabled { opacity: 0.3; cursor: not-allowed; } .lb-tab--active { color: var(--accent); - background: rgba(0,255,231,0.05); + background: rgba(0,255,65,0.05); border-bottom: 2px solid var(--accent); } @@ -533,4 +615,4 @@ button:disabled { opacity: 0.3; cursor: not-allowed; } color: var(--accent2); } -body { overflow-y: auto; } +body { overflow: hidden; } diff --git a/Transcendence/srcs/frontend/src/tetris.html b/Transcendence/srcs/frontend/src/tetris.html index ab546b7..3f16e9c 100644 --- a/Transcendence/srcs/frontend/src/tetris.html +++ b/Transcendence/srcs/frontend/src/tetris.html @@ -9,7 +9,11 @@ -

TETRIS

+ + +
+ +

TETRIS_

@@ -164,6 +168,7 @@
+ @@ -171,5 +176,58 @@ + + + +