/* Main layout */ .pinball-wrapper { width: min(90vw, 1300px); height: min(90vh, 800px); display: grid; grid-template-columns: 3fr 1fr; gap: 1.5vh; padding: 1.8vh 1.8vw; background: radial-gradient(circle at center, #333 0%, #111 60%, #000 100%); border-radius: 2vh; box-shadow: 0 0 0.8vh rgba(255,255,255,0.15) inset, 0 1.2vh 4vh rgba(0,0,0,0.9); position: relative; }
/* Screen shake */ .shake { animation: screenShake 0.2s ease-out; } @keyframes screenShake { 0% { transform: translate(0,0); } 20% { transform: translate(-4px, 3px); } 40% { transform: translate(3px, -4px); } 60% { transform: translate(-2px, 2px); } 80% { transform: translate(2px, -2px); } 100% { transform: translate(0,0); } }
/* Playfield */ .playfield-container { position: relative; overflow: hidden; border-radius: 2vh; background: linear-gradient(145deg, #083130 0%, #041619 40%, #0b151a 100%); box-shadow: 0 0 0 4px #050809, 0 0 0 7px #14191c, 0 1.5vh 3vh rgba(0,0,0,0.8); }
/* Glass highlight */ .playfield-container::before { content: ""; position: absolute; inset: 0; background: linear-gradient(135deg, rgba(255,255,255,0.12), transparent 40%, transparent 60%, rgba(255,255,255,0.05)); mix-blend-mode: screen; pointer-events: none; }
/* Inner playfield for physics */ .playfield { position: absolute; inset: 3% 4% 8% 4%; border-radius: 2vh; background: radial-gradient(circle at 50% 0%, #0b3b3a 0%, #031214 40%, #020507 100%); overflow: hidden; }
/* Side rails */ .rail { position: absolute; top: 0; bottom: 0; width: 1.2vw; max-width: 12px; background: linear-gradient(180deg, #6f7d86, #252b30); box-shadow: 0 0 1vh rgba(0,0,0,0.7); } .rail.left { left: 0; } .rail.right { right: 0; }
/* Playfield markings */ .playfield-markings { position: absolute; inset: 4% 6% 10% 6%; border-radius: 1.5vh; border: 2px solid rgba(180,220,255,0.12); box-shadow: 0 0 15px rgba(120,210,255,0.2), 0 0 35px rgba(120,210,255,0.1) inset; pointer-events: none; }
/* Ball */ .ball { position: absolute; width: 26px; height: 26px; border-radius: 50%; background: radial-gradient(circle at 30% 25%, #ffffff 0%, #dcdcdc 18%, transparent 40%), radial-gradient(circle at 70% 70%, #999 0%, #444 35%, #111 80%); box-shadow: 0 0 10px rgba(255,255,255,0.3), 0 10px 18px rgba(0,0,0,0.9); transform: translate(-50%, -50%); } .ball::after { content: ""; position: absolute; inset: 18% 10% 30% 35%; border-radius: 50%; background: radial-gradient(circle at 30% 30%, rgba(255,255,255,0.7), transparent 60%); mix-blend-mode: screen; }
/* Ball shadow */ .ball-shadow { position: absolute; width: 30px; height: 12px; border-radius: 50%; background: radial-gradient(ellipse at center, rgba(0,0,0,0.7) 0%, transparent 70%); transform: translate(-50%, -50%); filter: blur(2px); pointer-events: none; }
/* Bumpers */ .bumper { position: absolute; width: 70px; height: 70px; border-radius: 50%; background: radial-gradient(circle at 30% 25%, #fff 0%, #ffeecc 18%, #ffb347 45%, #5a0808 100%); box-shadow: 0 0 25px rgba(255, 180, 90, 0.8), 0 0 50px rgba(255, 120, 40, 0.6); display: flex; align-items: center; justify-content: center; } .bumper-core { width: 42%; height: 42%; border-radius: 50%; background: radial-gradient(circle at 30% 20%, #fff 0%, #ffe5c7 25%, #ff7810 85%); box-shadow: 0 0 18px rgba(255,200,120,0.9), 0 0 40px rgba(255,150,70,0.7); } .bumper-flash { animation: bumperFlash 0.25s ease-out; } @keyframes bumperFlash { 0% { transform: scale(1); filter: brightness(1); } 50% { transform: scale(1.12); filter: brightness(1.8); } 100% { transform: scale(1); filter: brightness(1); } }
/* Flippers */ .flipper { position: absolute; width: 130px; height: 26px; border-radius: 20px; background: linear-gradient(180deg, #cbd3da, #8f9aa5); box-shadow: 0 0 10px rgba(255,255,255,0.15), 0 3px 10px rgba(0,0,0,0.8); transform-origin: 80% 50%; } .flipper.left { left: 38%; bottom: 7%; } .flipper.right { right: 38%; bottom: 7%; transform-origin: 20% 50%; } .flipper-inner { position: absolute; inset: 10% 8%; border-radius: 16px; background: linear-gradient(180deg, #f7f7f7, #d0d6dd); } .flipper.left.auto-up { animation: flipperLeftUp 0.18s ease-out forwards; } .flipper.left.auto-down { animation: flipperLeftDown 0.18s ease-in forwards; } .flipper.right.auto-up { animation: flipperRightUp 0.18s ease-out forwards; } .flipper.right.auto-down { animation: flipperRightDown 0.18s ease-in forwards; } @keyframes flipperLeftUp { from { transform: rotate(0deg); } to { transform: rotate(-26deg); } } @keyframes flipperLeftDown { from { transform: rotate(-26deg); } to { transform: rotate(0deg); } } @keyframes flipperRightUp { from { transform: rotate(0deg); } to { transform: rotate(26deg); } } @keyframes flipperRightDown { from { transform: rotate(26deg); } to { transform: rotate(0deg); } }
/* Drain / Outlane */ .drain { position: absolute; left: 18%; right: 18%; bottom: 2%; height: 18px; border-radius: 999px; background: radial-gradient(circle at 50% 150%, #000 0%, #111 55%, #555 100%); box-shadow: 0 -6px 12px rgba(0,0,0,0.9) inset; }
/* HUD / Side panel */ .hud { position: relative; border-radius: 2vh; background: radial-gradient(circle at 0% 0%, #1e252a 0%, #06090b 60%, #020203 100%); box-shadow: 0 0 0 4px #040708, 0 0 0 6px #151b1f, 0 1.5vh 3vh rgba(0,0,0,0.85); padding: 2.5vh 1.8vw; display: flex; flex-direction: column; justify-content: space-between; }
/* Game title */ .game-title { text-align: center; font-size: 2.1rem; letter-spacing: 0.25em; text-transform: uppercase; color: #fdfdfd; margin-bottom: 1.5vh; text-shadow: 0 0 15px rgba(0,255,255,0.6), 0 0 40px rgba(0,200,255,0.7); } .game-subtitle { text-align: center; font-size: 0.75rem; letter-spacing: 0.25em; text-transform: uppercase; color: rgba(220,240,255,0.6); margin-bottom: 3vh; }
/* Score display */ .score-box { border-radius: 1.2vh; padding: 1.6vh 1.2vw; background: linear-gradient(145deg, #070b0e, #111820); box-shadow: 0 0 0 1px rgba(120,200,255,0.22), 0 0 18px rgba(40,170,255,0.45), 0 10px 20px rgba(0,0,0,0.75); } .score-label { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.15em; color: rgba(160,220,255,0.7); margin-bottom: 0.5vh; } .score-value { font-family: "SF Mono", "Consolas", monospace; font-size: 2.4rem; letter-spacing: 0.12em; color: #fefefe; text-shadow: 0 0 12px rgba(140,235,255,0.9), 0 0 30px rgba(60,180,255,0.8); }
/* Balls indicator */ .balls-box { margin-top: 2vh; border-radius: 1vh; padding: 1.2vh 1vw; background: radial-gradient(circle at 0% 0%, #19212a 0%, #05070b 65%); box-shadow: 0 0 0 1px rgba(150, 200, 255, 0.2), 0 10px 16px rgba(0,0,0,0.75); } .balls-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.16em; color: rgba(180,215,240,0.75); margin-bottom: 0.8vh; } .ball-icons { display: flex; gap: 0.6vw; } .ball-icon { width: 20px; height: 20px; border-radius: 50%; background: radial-gradient(circle at 30% 25%, #fff 0%, #ddd 20%, #777 80%); box-shadow: 0 0 8px rgba(255,255,255,0.4), 0 0 18px rgba(120,180,255,0.55); opacity: 0.15; transition: opacity 0.25s ease; } .ball-icon.active { opacity: 1; }
/* Status / hints */ .status-box { margin-top: 3vh; padding-top: 1.2vh; border-top: 1px solid rgba(120,150,180,0.4); font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase; color: rgba(200,230,255,0.7); } .status-line { margin-top: 0.6vh; color: rgba(190,220,250,0.6); } .hint { font-size: 0.66rem; margin-top: 1.5vh; color: rgba(140,170,200,0.6); }
/* Game over overlay */ .game-over-overlay { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; pointer-events: none; opacity: 0; transition: opacity 1.5s ease; background: radial-gradient(circle at center, rgba(0,0,0,0) 0%, rgba(0,0,0,0.9) 65%); } .game-over-overlay.visible { opacity: 1; } .game-over-text { font-size: clamp(3rem, 5vw, 4.5rem); letter-spacing: 0.4em; text-transform: uppercase; color: #ff4060; text-shadow: 0 0 18px rgba(255,140,150,0.9), 0 0 40px rgba(255,70,120,0.9); margin-bottom: 1.5vh; } .game-over-sub { font-size: 1rem; letter-spacing: 0.25em; text-transform: uppercase; color: rgba(255, 220, 230, 0.78); }
/* Responsive tweaks */ @media (max-width: 960px) { .pinball-wrapper { grid-template-columns: 1fr; grid-template-rows: 3fr minmax(220px, 1.1fr); } .hud { margin-top: 2vh; } .game-title { font-size: 1.6rem; } .score-value { font-size: 2rem; } } @media (max-width: 640px) { .pinball-wrapper { width: 100vw; height: 100vh; border-radius: 0; padding: 1vh 2vw; } .game-title { font-size: 1.3rem; letter-spacing: 0.16em; } .game-subtitle { letter-spacing: 0.18em; } .score-value { font-size: 1.7rem; } }
</style> </head> <body> <div class="pinball-wrapper" id="pinballRoot"> <div class="playfield-container" id="playfieldContainer"> <div class="playfield" id="playfield"> <div class="rail left"></div> <div class="rail right"></div> <div class="playfield-markings"></div> <div class="bumper" id="bumper1">
<div class="bumper-core"></div>
</div>
<div class="bumper" id="bumper2">
<div class="bumper-core"></div>
</div>
<div class="bumper" id="bumper3">
<div class="bumper-core"></div>
</div>
<div class="flipper left" id="flipperLeft">
<div class="flipper-inner"></div>
</div>
<div class="flipper right" id="flipperRight">
<div class="flipper-inner"></div>
</div>
<div class="drain"></div>
<div class="ball-shadow" id="ballShadow"></div>
<div class="ball" id="ball"></div>
<div class="game-over-overlay" id="gameOverOverlay">
<div class="game-over-text">GAME OVER</div>
<div class="game-over-sub">thanks for playing</div>
</div>
</div>
<div class="bumper" id="bumper1">
<div class="bumper-core"></div>
</div>
<div class="bumper" id="bumper2">
<div class="bumper-core"></div>
</div>
<div class="bumper" id="bumper3">
<div class="bumper-core"></div>
</div>
<div class="flipper left" id="flipperLeft">
<div class="flipper-inner"></div>
</div>
<div class="flipper right" id="flipperRight">
<div class="flipper-inner"></div>
</div>
<div class="drain"></div>
<div class="ball-shadow" id="ballShadow"></div>
<div class="ball" id="ball"></div>
<div class="game-over-overlay" id="gameOverOverlay">
<div class="game-over-text">GAME OVER</div>
<div class="game-over-sub">thanks for playing</div>
</div>
</div>
<div class="score-box">
<div class="score-label">Score</div>
<div class="score-value" id="scoreDisplay">000000</div>
</div>
<div class="balls-box">
<div class="balls-label">Balls</div>
<div class="ball-icons">
<div class="ball-icon active" id="ballIcon1"></div>
<div class="ball-icon active" id="ballIcon2"></div>
<div class="ball-icon active" id="ballIcon3"></div>
</div>
</div>
</div>
<div class="status-box">
<div id="statusMain">Autoplay: running</div>
<div class="status-line" id="statusSub">Watch the chrome ball roll, bump, and flip.</div>
<div class="hint">This table is fully self‑playing. Sit back and enjoy the light show.</div>
</div>
<div class="score-box">
<div class="score-label">Score</div>
<div class="score-value" id="scoreDisplay">000000</div>
</div>
<div class="balls-box">
<div class="balls-label">Balls</div>
<div class="ball-icons">
<div class="ball-icon active" id="ballIcon1"></div>
<div class="ball-icon active" id="ballIcon2"></div>
<div class="ball-icon active" id="ballIcon3"></div>
</div>
</div>
</div>
<div class="status-box">
<div id="statusMain">Autoplay: running</div>
<div class="status-line" id="statusSub">Watch the chrome ball roll, bump, and flip.</div>
<div class="hint">This table is fully self‑playing. Sit back and enjoy the light show.</div>
</div>