Liveweave: Generative AI Web Editor & HTML/CSS/JS Playground
Initializing
Liveweave
Web
expand_more
home
Home
Palette
Color Explorer
arrow_outward
Polyline
Graphics Editor
arrow_outward
frame_source
Python Playground
arrow_outward
build
Tools
expand_more
restart_alt
Load "Hello Weaver!"
post_add
Generate Lorem ipsum...
code
Format HTML
code_blocks
Format CSS
data_object
Format JavaScript
library_add
Library
expand_more
A
Algolia JS
Animate CSS
Apex Charts JS
B
Bulma CSS
Bootstrap
C
Chart JS
Chartist
Create JS
D
D3
Dojo
F
Foundation
Fullpage JS
G
Granim JS
Google Charts
H
Halfmoon
J
jQuery
M
Materialize
Moment JS
Masonry JS
Milligram CSS
P
Pure CSS
Primer CSS
Popper JS
Pattern CSS
Picnic CSS
R
React JS
Raphael JS
Raisin CSS
S
Semantic UI
Skeleton CSS
Spectre CSS
Tachyons CSS
T
Tailwind
Three JS
U
UI Kit
Vis JS
W
Water CSS
download
Download
expand_more
developer_mode
Download as HTML
folder_zip
Download as .ZIP
cloud_upload
Fork
account_circle
Login
settings
Settings
expand_more
Editor font
14
px
A
A
Night mode
Line number
Mini map
Word wrap
sync_alt
Reset Settings
smart_display
Run
left_panel_close
AI Assistant
dashboard
All
HTML
CSS
JS
visibility
Preview
bolt
Live Preview
terminal
JS Console
<!DOCTYPE html> <html> <head> <title>Scary elevator</title> </head> <body> <!-- Start your code here --> <div class="game" id="game"> <div class="topbar"> <span>BLACKTHORN HOTEL</span> <span class="status" id="status">ELEVATOR READY</span> </div> <div class="elevator"> <div class="ceiling-light"></div> <div class="display"> <span class="display-label">FLOOR</span> <span class="floor-number" id="floorNumber">G</span> <span class="direction" id="direction">◆</span> </div> <div class="door-frame"> <div class="outside" id="outside"> <div class="hall-light"></div> <div class="hall-floor"></div> <div class="hall-content" id="hallContent"></div> </div> <div class="door door-left"></div> <div class="door door-right"></div> <div class="door-seam"></div> </div> <div class="control-panel"> <div class="panel-title">OTIS · 1926</div> <button class="floor-btn" data-floor="3">3</button> <button class="floor-btn" data-floor="2">2</button> <button class="floor-btn" data-floor="1">1</button> <button class="floor-btn" data-floor="G">G</button> <div class="panel-divider"></div> <button class="door-btn" id="closeBtn">◀▶</button> <div class="emergency">ALARM</div> <div class="alarm-light"></div> </div> <div class="elevator-floor"></div> </div> <div class="message"> <p id="message">The hotel has been abandoned for 73 years.</p> <span id="hint">Choose a floor to begin.</span> </div> <div class="bottom"> <span>EST. 1926</span> <button id="soundBtn">♪ SOUND OFF</button> <span>NO EXIT</span> </div> </div> <!-- End your code here --> </body> </html>
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Playfair+Display:wght@400;700&display=swap'); * { box-sizing: border-box; } body { margin: 0; background: #080909; } .game { --gold: #b99b65; --metal: #343735; --dark: #111614; min-height: 720px; background: radial-gradient( ellipse at 50% 45%, #252c28, #0b100e 75% ); color: #d4c6a6; font-family: 'DM Mono', monospace; position: relative; overflow: hidden; } .topbar { display: flex; justify-content: space-between; padding: 20px 30px; border-bottom: 1px solid #ffffff15; font-size: 10px; letter-spacing: 3px; color: #b9a882; } .status { color: #6e8c78; letter-spacing: 1px; } .elevator { position: relative; width: min(580px, 96%); height: 510px; margin: 15px auto 0; background: repeating-linear-gradient( 90deg, #222a26 0px, #2a302b 3px, #1b221e 6px ); border: 12px solid #343b34; border-bottom: 0; box-shadow: inset 0 0 90px #000, 0 0 90px #0008; } .ceiling-light { position: absolute; top: 0; left: 20%; width: 60%; height: 12px; background: #cbbd8b; box-shadow: 0 10px 80px #ffdd8855; opacity: .7; animation: flicker 8s infinite; } .display { position: absolute; top: 25px; left: 50%; transform: translateX(-50%); width: 110px; height: 75px; background: #090c0a; border: 5px solid #685d43; box-shadow: 0 0 0 2px #24251f, inset 0 0 20px #000; text-align: center; z-index: 6; } .display-label { display: block; font-size: 8px; letter-spacing: 3px; padding-top: 5px; color: #8e8267; } .floor-number { font-size: 37px; color: #e6ad58; text-shadow: 0 0 15px #e6a14d88; } .direction { position: absolute; right: 10px; top: 30px; color: #ba8d49; font-size: 12px; } .door-frame { position: absolute; left: 10%; top: 115px; width: 65%; height: 370px; overflow: hidden; border: 9px solid #5a5443; background: #050505; box-shadow: 0 0 0 3px #171b17, inset 0 0 40px #000; } .outside { position: absolute; inset: 0; background: radial-gradient( ellipse at 50% 20%, #363c36, #090b0b 75% ); overflow: hidden; } .hall-light { position: absolute; top: 0; left: 30%; width: 40%; height: 5px; background: #c5b994; box-shadow: 0 0 65px 35px #e2d4a422; } .hall-floor { position: absolute; bottom: 0; width: 100%; height: 42%; background: repeating-linear-gradient( 90deg, transparent 0 38px, #ffffff08 39px 40px ), linear-gradient(#252720, #0b0d0c); clip-path: polygon(25% 0, 75% 0, 100% 100%, 0 100%); } .hall-content { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; } .door { position: absolute; top: 0; height: 100%; width: 50.5%; background: repeating-linear-gradient( 90deg, #393e39 0px, #484c45 3px, #30352f 8px, #252b27 13px ); z-index: 4; transition: transform 2.2s cubic-bezier(.65,0,.25,1); box-shadow: inset 0 0 35px #0008; } .door::after { content: ""; position: absolute; inset: 18px; border: 2px solid #847b5b44; } .door-left { left: 0; border-right: 3px solid #0d0f0c; } .door-right { right: 0; border-left: 3px solid #0d0f0c; } .door-seam { position: absolute; left: 50%; top: 0; width: 2px; height: 100%; background: #0a0b09; z-index: 5; transition: opacity .3s; } .open .door-left { transform: translateX(-100%); } .open .door-right { transform: translateX(100%); } .open .door-seam { opacity: 0; } .control-panel { position: absolute; top: 130px; right: 2%; width: 18%; padding: 12px 8px; background: linear-gradient(110deg,#353b34,#151a16); border: 3px solid #71664d; box-shadow: inset 0 0 15px #000; display: grid; grid-template-columns: 1fr 1fr; gap: 8px; z-index: 6; } .panel-title { grid-column: span 2; text-align: center; font-size: 8px; color: #b5a27b; margin-bottom: 12px; } .floor-btn, .door-btn { width: 100%; aspect-ratio: 1; border-radius: 50%; border: 2px solid #716b56; background: radial-gradient(circle at 35% 25%,#444a43,#161b17); color: #d7c9a8; font: 13px 'DM Mono', monospace; cursor: pointer; box-shadow: 0 3px 5px #0008; } .floor-btn:hover, .door-btn:hover { border-color: #e2bb74; } .floor-btn.active { color: #ffbd5d; box-shadow: 0 0 15px #ff9d3655; border-color: #e2a454; } .panel-divider { grid-column: span 2; height: 1px; background: #84765b44; margin: 8px 0; } .door-btn { grid-column: span 2; width: 38px; margin: auto; font-size: 10px; } .emergency { grid-column: span 2; text-align: center; font-size: 8px; color: #91665a; margin-top: 12px; } .alarm-light { grid-column: span 2; width: 9px; height: 9px; background: #581d17; border-radius: 50%; margin: auto; } .elevator-floor { position: absolute; bottom: 0; width: 100%; height: 20px; background: linear-gradient(#5a5746,#151a17); z-index: 6; } .message { text-align: center; padding: 20px; min-height: 90px; } .message p { font: italic 17px 'Playfair Display', Georgia, serif; color: #c4b59c; margin: 0 0 9px; } .message span { color: #7b8279; font-size: 10px; letter-spacing: 2px; } .bottom { display: flex; justify-content: space-between; align-items: center; max-width: 580px; margin: 0 auto; padding: 0 15px 20px; color: #686e63; font-size: 9px; letter-spacing: 2px; } .bottom button { background: transparent; border: 1px solid #5e5b4a; color: #b9a882; padding: 10px 15px; font: 10px 'DM Mono', monospace; cursor: pointer; } /* Floor 1: ghost */ .ghost { position: relative; width: 75px; height: 175px; background: linear-gradient(#d4d9cfbb,#a5b4a122,transparent); border-radius: 50% 50% 20% 20%; filter: blur(5px); animation: ghostFloat 3s ease-in-out infinite; } .ghost::before, .ghost::after { content: ""; position: absolute; top: 45px; width: 12px; height: 25px; border-radius: 50%; background: #101814; box-shadow: 0 0 15px #101814; } .ghost::before { left: 18px; } .ghost::after { right: 18px; } /* Floor 2: shadow person */ .shadow-person { position: relative; width: 75px; height: 210px; background: #010302; border-radius: 45% 45% 10% 10%; box-shadow: 0 0 45px #000; animation: shadowApproach 7s ease-in forwards; } .shadow-person::before { content: ""; position: absolute; width: 65px; height: 70px; border-radius: 50%; background: #010302; top: -42px; left: 5px; } .shadow-eyes { position: absolute; top: -12px; left: 17px; width: 9px; height: 5px; background: #e3291c; border-radius: 50%; box-shadow: 31px 0 #e3291c,0 0 12px red,31px 0 12px red; } /* Floor 3: endless corridor */ .corridor { position: absolute; inset: 0; background: repeating-radial-gradient( ellipse at 50% 50%, #111a17 0px, #030605 28px, #2b342a 30px, #050907 52px ); animation: corridorMove 5s linear infinite; } .corridor::after { content: "DON'T LOOK BACK"; position: absolute; top: 50%; width: 100%; text-align: center; color: #b52b20; font: bold 14px Georgia,serif; letter-spacing: 3px; text-shadow: 0 0 20px red; } .game.shaking .elevator { animation: shake .12s infinite; } .game.blackout .ceiling-light { opacity: .05; } .game.blackout .outside { filter: brightness(.2); } @keyframes flicker { 0%, 92%, 96%, 100% { opacity: .7; } 93%, 95% { opacity: .05; } } @keyframes ghostFloat { 0%, 100% { transform: translateY(8px); opacity: .5; } 50% { transform: translateY(-12px); opacity: .9; } } @keyframes shadowApproach { from { transform: scale(.35); } to { transform: scale(1.5); } } @keyframes corridorMove { to { background-size: 160% 160%; } } @keyframes shake { 0% { transform: translate(0,0); } 25% { transform: translate(2px,-1px); } 50% { transform: translate(-2px,2px); } 75% { transform: translate(1px,1px); } } @media(max-width: 500px) { .game { min-height: 650px; } .elevator { height: 440px; } .door-frame { height: 310px; } .control-panel { top: 120px; } .panel-title { font-size: 6px; } .floor-btn { font-size: 11px; } .topbar { padding: 16px; font-size: 8px; } } @media(prefers-reduced-motion:reduce) { .game *, .game *::before, .game *::after { animation: none !important; transition-duration: .01ms !important; } }
const game = document.getElementById("game"); const doorFrame = document.querySelector(".door-frame"); const floorNumber = document.getElementById("floorNumber"); const direction = document.getElementById("direction"); const status = document.getElementById("status"); const message = document.getElementById("message"); const hint = document.getElementById("hint"); const hallContent = document.getElementById("hallContent"); const buttons = document.querySelectorAll(".floor-btn"); const closeBtn = document.getElementById("closeBtn"); const soundBtn = document.getElementById("soundBtn"); let currentFloor = "G"; let busy = false; let soundOn = false; let audioCtx = null; const floorData = { "G": { message: "The lobby is empty. The doors are locked.", hint: "There is no way out." }, "1": { message: "A woman has been waiting here since 1953.", hint: "She doesn't seem to have feet." }, "2": { message: "Something is standing at the end of the hall.", hint: "It's getting closer." }, "3": { message: "This floor doesn't exist on the building plans.", hint: "DON'T LOOK BACK." } }; function wait(ms) { return new Promise(function(resolve) { setTimeout(resolve, ms); }); } function tone(frequency, duration, type, volume) { if (!soundOn) return; try { if (!audioCtx) { audioCtx = new ( window.AudioContext || window.webkitAudioContext )(); } if (audioCtx.state === "suspended") { audioCtx.resume(); } const osc = audioCtx.createOscillator(); const gain = audioCtx.createGain(); const now = audioCtx.currentTime; osc.type = type || "sine"; osc.frequency.setValueAtTime(frequency, now); gain.gain.setValueAtTime(volume || .04, now); gain.gain.exponentialRampToValueAtTime( .001, now + duration ); osc.connect(gain); gain.connect(audioCtx.destination); osc.start(now); osc.stop(now + duration); } catch (e) { console.warn("Audio unavailable", e); } } function setMessage(text, subtext) { message.textContent = text; hint.textContent = subtext; } function clearHall() { hallContent.replaceChildren(); } function createHall(floor) { clearHall(); if (floor === "1") { const ghost = document.createElement("div"); ghost.className = "ghost"; hallContent.appendChild(ghost); } if (floor === "2") { const figure = document.createElement("div"); figure.className = "shadow-person"; const eyes = document.createElement("div"); eyes.className = "shadow-eyes"; figure.appendChild(eyes); hallContent.appendChild(figure); } if (floor === "3") { const corridor = document.createElement("div"); corridor.className = "corridor"; hallContent.appendChild(corridor); } } async function travel(target) { if (busy) return; if (target === currentFloor && doorFrame.classList.contains("open")) { return; } busy = true; doorFrame.classList.remove("open"); game.classList.remove("blackout"); buttons.forEach(function(btn) { btn.classList.toggle( "active", btn.dataset.floor === target ); }); status.textContent = "DOORS CLOSING"; setMessage("The doors are closing...", "Please stand clear."); tone(230, .6, "triangle", .05); await wait(2400); game.classList.add("shaking"); status.textContent = "MOVING"; setMessage("The elevator begins to move.", "The machinery groans."); const from = currentFloor === "G" ? 0 : Number(currentFloor); const to = target === "G" ? 0 : Number(target); const step = to >= from ? 1 : -1; direction.textContent = step > 0 ? "▲" : "▼"; if (from !== to) { for (let f = from + step; step > 0 ? f <= to : f >= to; f += step) { await wait(750); floorNumber.textContent = f === 0 ? "G" : String(f); tone(90 + f * 25, .25, "sawtooth", .025); } } else { await wait(900); } currentFloor = target; game.classList.remove("shaking"); direction.textContent = "◆"; status.textContent = "ARRIVED"; tone(460, .8, "sine", .05); await wait(650); createHall(target); doorFrame.classList.add("open"); setMessage( floorData[target].message, floorData[target].hint ); status.textContent = "DOORS OPEN"; busy = false; if (target === "2") { await wait(3500); if (currentFloor === "2" && doorFrame.classList.contains("open")) { game.classList.add("blackout"); tone(55, 2, "sawtooth", .09); setMessage( "The lights have gone out.", "Something is breathing." ); } } } buttons.forEach(function(button) { button.addEventListener("click", function() { travel(button.dataset.floor); }); }); closeBtn.addEventListener("click", async function() { if (busy || !doorFrame.classList.contains("open")) return; busy = true; doorFrame.classList.remove("open"); status.textContent = "DOORS CLOSING"; tone(180, .5, "triangle", .04); await wait(2300); status.textContent = "SELECT FLOOR"; setMessage( "The doors are closed.", "Choose your next destination." ); busy = false; }); soundBtn.addEventListener("click", function() { soundOn = !soundOn; soundBtn.textContent = soundOn ? "♪ SOUND ON" : "♪ SOUND OFF"; if (soundOn) { tone(440, .3, "sine", .03); } }); // Initial lobby buttons.forEach(function(btn) { btn.classList.toggle("active", btn.dataset.floor === "G"); });
terminal
JavaScript Console
Preview
Clear
close
›
Run