/* REIKHELM: DESCENT — torchlit retro UI over the Primordyn-dithered frames. Palette pulls from the baked atlas: deep near-black stone, warm torch gold, ember orange, bone parchment, and a cold cistern teal for accents. */ :root { --void: #0a0908; --stone: #15131a; --stone-2: #221e26; --line: #3a3340; --bone: #e8dcc8; --dim: #8d8273; --gold: #d4a54a; --ember: #e06a28; --blood: #b03a2e; --teal: #5a9aa8; --vigor: #d8b95e; --vigor-deep: #7a6228; } * { box-sizing: border-box; margin: 0; padding: 0; } html, body { height: 100%; background: var(--void); color: var(--bone); font-family: "Menlo", "Consolas", "Courier New", monospace; font-size: 14px; overflow: hidden; user-select: none; } button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; } .dim { color: var(--dim); } .kb { font-size: 10px; color: var(--dim); border: 1px solid var(--line); border-radius: 3px; padding: 0 4px; margin-left: 6px; letter-spacing: 1px; } /* ---------------- screens ---------------- */ .screen { position: absolute; inset: 0; display: none; align-items: center; justify-content: center; } .screen.show { display: flex; } /* ---------------- title ---------------- */ #title { background: radial-gradient(ellipse at 50% 35%, #1b1410 0%, var(--void) 70%); } .title-wrap { text-align: center; animation: rise 0.9s ease-out; } @keyframes rise { from { opacity: 0; transform: translateY(18px); } } .wordmark { font-size: 72px; letter-spacing: 26px; margin-left: 26px; font-weight: 700; color: var(--gold); text-shadow: 0 0 18px rgba(224, 106, 40, 0.45), 0 2px 0 #6b4a17, 0 5px 14px #000; } .subtitle { letter-spacing: 10px; color: var(--ember); margin-top: 6px; font-size: 15px; } .tagline { margin: 26px 0 30px; color: var(--dim); line-height: 1.7; } .archetypes { display: flex; gap: 26px; justify-content: center; } .arch-card { width: 240px; padding: 16px 16px 18px; background: linear-gradient(180deg, var(--stone-2), var(--stone)); border: 1px solid var(--line); border-radius: 6px; display: flex; flex-direction: column; align-items: center; gap: 10px; transition: transform 0.15s, border-color 0.15s, box-shadow 0.15s; } .arch-card:hover { transform: translateY(-4px); border-color: var(--gold); box-shadow: 0 8px 30px rgba(212, 165, 74, 0.18); } .arch-card img { width: 168px; height: 168px; object-fit: cover; border-radius: 4px; border: 1px solid var(--line); image-rendering: auto; } .arch-name { color: var(--gold); letter-spacing: 3px; font-size: 16px; } .arch-blurb { color: var(--dim); font-size: 12px; line-height: 1.6; } .seed-row { margin-top: 30px; display: flex; gap: 10px; justify-content: center; align-items: center; } .seed { color: var(--teal); letter-spacing: 2px; } #reroll { color: var(--dim); font-size: 18px; } #reroll:hover { color: var(--gold); } .hint { margin-top: 14px; font-size: 12px; letter-spacing: 2px; } /* ---------------- stage ---------------- */ #game { background: var(--void); } #stage { position: relative; width: min(100vw, calc(100vh * 16 / 9)); aspect-ratio: 16 / 9; background: #000; overflow: hidden; box-shadow: 0 0 80px rgba(0,0,0,0.9); } #frame { position: absolute; inset: 0; width: 100%; height: 100%; image-rendering: pixelated; object-fit: cover; } #frame-fade { position: absolute; inset: 0; background: #000; opacity: 0; pointer-events: none; transition: opacity 0.1s linear; } #frame-fade.dip { opacity: 1; transition: none; } #vignette { position: absolute; inset: 0; pointer-events: none; background: radial-gradient(ellipse at 50% 46%, transparent 52%, rgba(0,0,0,0.55) 100%); } #danger-vignette { position: absolute; inset: 0; pointer-events: none; opacity: 0; background: radial-gradient(ellipse at 50% 50%, transparent 58%, rgba(140, 30, 20, 0.35) 100%); transition: opacity 1.2s; } #danger-vignette.on { opacity: 1; animation: dangerpulse 2.6s ease-in-out infinite; } @keyframes dangerpulse { 50% { opacity: 0.45; } } /* ---------------- monsters ---------------- */ #sprites { position: absolute; inset: 0; pointer-events: none; } .sprite { position: absolute; bottom: 16%; left: 50%; pointer-events: auto; cursor: pointer; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; } .sprite img { width: 30vmin; height: 30vmin; object-fit: cover; mix-blend-mode: screen; /* portraits sit on near-black — melts into the scene */ filter: drop-shadow(0 18px 26px rgba(0,0,0,0.8)) contrast(1.04); animation: sway 3.2s ease-in-out infinite; image-rendering: auto; /* feather the square portrait into the scene */ -webkit-mask-image: radial-gradient(ellipse 50% 50% at 50% 46%, #000 58%, transparent 82%); mask-image: radial-gradient(ellipse 50% 50% at 50% 46%, #000 58%, transparent 82%); } .sprite.slot-1 img { animation-delay: -1.6s; } .sprite.enter img { animation: lunge 0.45s ease-out, sway 3.2s ease-in-out 0.45s infinite; } @keyframes lunge { from { opacity: 0; transform: scale(0.6) translateY(8%); } 60% { opacity: 1; transform: scale(1.06); } to { transform: scale(1); } } @keyframes sway { 50% { transform: translateY(-1.6%) scale(1.012); } } .sprite.hurt img { animation: hurtflash 0.28s ease-out, sway 3.2s ease-in-out 0.28s infinite; } @keyframes hurtflash { 0% { filter: brightness(2.4) sepia(1) hue-rotate(-28deg) saturate(3); transform: translateX(-2%); } 50% { transform: translateX(2%); } } .sprite.dazed img { filter: drop-shadow(0 18px 26px rgba(0,0,0,0.8)) saturate(0.6) brightness(0.85); animation: dazedwobble 1.4s ease-in-out infinite; } @keyframes dazedwobble { 25% { transform: rotate(-2.4deg); } 75% { transform: rotate(2.4deg); } } .sprite.dead img { animation: collapse 0.9s ease-in forwards; mix-blend-mode: screen; } @keyframes collapse { to { opacity: 0; transform: translateY(24%) scale(0.82); filter: saturate(0) brightness(0.4); } } .sprite .tgt { margin-top: 4px; color: var(--gold); font-size: 16px; opacity: 0; text-shadow: 0 0 8px var(--ember); } .sprite.targeted .tgt { opacity: 1; animation: tgtbob 1s ease-in-out infinite; } @keyframes tgtbob { 50% { transform: translateY(-3px); } } /* ---------------- floaters ---------------- */ #floaters { position: absolute; inset: 0; pointer-events: none; overflow: hidden; } .floater { position: absolute; font-weight: 700; font-size: 22px; text-shadow: 0 2px 0 #000, 0 0 12px rgba(0,0,0,0.8); animation: floatup 1.1s ease-out forwards; } .floater.dmg { color: var(--bone); } .floater.big { color: var(--ember); font-size: 30px; } .floater.ouch { color: var(--blood); } .floater.heal { color: #7fc06a; } .floater.curse { color: #b07ad0; } .floater.info { color: var(--teal); font-size: 16px; font-weight: 400; } @keyframes floatup { from { opacity: 0; transform: translateY(10px) scale(0.8); } 20% { opacity: 1; transform: translateY(0) scale(1.06); } to { opacity: 0; transform: translateY(-58px) scale(1); } } /* ---------------- banner / floor card ---------------- */ #banner { position: absolute; top: 24%; left: 0; right: 0; text-align: center; font-size: 30px; letter-spacing: 8px; color: var(--blood); font-weight: 700; text-shadow: 0 0 18px rgba(176, 58, 46, 0.7), 0 2px 0 #000; opacity: 0; pointer-events: none; } #banner.show { animation: bannerin 1.6s ease-out; } @keyframes bannerin { 8% { opacity: 1; } 70% { opacity: 1; } 100% { opacity: 0; } } #floorcard { position: absolute; inset: 0; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; opacity: 0; pointer-events: none; } #floorcard.show { animation: floorcard 2.4s ease-in-out; } @keyframes floorcard { 12% { opacity: 1; } 78% { opacity: 1; } 100% { opacity: 0; } } #floorcard-depth { color: var(--dim); letter-spacing: 6px; font-size: 14px; } #floorcard-name { color: var(--gold); letter-spacing: 8px; font-size: 30px; } /* ---------------- enemy panels ---------------- */ #enemies { position: absolute; top: 12px; left: 50%; transform: translateX(-50%); display: flex; gap: 14px; } .epanel { width: 280px; padding: 8px 10px; background: rgba(10, 9, 8, 0.82); border: 1px solid var(--line); border-radius: 5px; cursor: pointer; transition: border-color 0.15s; } .epanel.targeted { border-color: var(--gold); } .epanel .ehead { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 5px; } .epanel .ename { color: var(--bone); letter-spacing: 1px; font-size: 13px; } .epanel .elvl { color: var(--dim); font-size: 11px; } .epanel.dead { opacity: 0.45; filter: saturate(0); } .estatus { margin-top: 4px; font-size: 10px; height: 13px; color: var(--dim); letter-spacing: 1px; } .estatus .chip { color: #b07ad0; margin-right: 7px; } .estatus .chip.daze { color: var(--gold); } /* ---------------- vigor bars ---------------- */ .vbar { position: relative; height: 16px; background: #060505; border: 1px solid var(--line); border-radius: 3px; overflow: hidden; } .vbar-cap { position: absolute; inset: 0; width: 100%; background: #241f14; } .vbar-fill { position: absolute; top: 0; bottom: 0; left: 0; width: 100%; background: linear-gradient(180deg, var(--vigor), var(--vigor-deep)); transition: width 0.18s ease-out; } .vbar-ceiling { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--gold); box-shadow: 0 0 6px var(--gold); transition: left 0.3s; } .vbar-num { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-size: 10px; color: rgba(10, 8, 4, 0.9); font-weight: 700; letter-spacing: 1px; text-shadow: 0 0 4px rgba(232, 220, 200, 0.35); } .vbar.hurtflash { animation: barflash 0.25s; } @keyframes barflash { from { box-shadow: 0 0 16px var(--blood); } } .castbar { height: 5px; margin-top: 3px; border-radius: 2px; background: #100d12; overflow: hidden; } .castbar div { height: 100%; width: 0%; background: linear-gradient(90deg, #6c4f8f, #b07ad0); } .castbar.player div { background: linear-gradient(90deg, #2e6f7e, var(--teal)); } /* ---------------- HUD ---------------- */ #hud-top { position: absolute; top: 10px; left: 14px; right: 14px; display: flex; justify-content: space-between; pointer-events: none; text-shadow: 0 1px 0 #000, 0 0 10px #000; } #floor-label { color: var(--dim); letter-spacing: 3px; font-size: 12px; } #floor-label b { color: var(--bone); } #compass { color: var(--gold); letter-spacing: 2px; font-size: 13px; } #hud { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: flex-end; justify-content: space-between; padding: 10px 12px; gap: 12px; background: linear-gradient(180deg, transparent, rgba(5, 4, 4, 0.88) 55%); } #log { width: 300px; font-size: 11.5px; line-height: 1.65; min-height: 56px; pointer-events: none; } #log .line { color: var(--dim); text-shadow: 0 1px 0 #000; } #log .line:last-child { color: var(--bone); } #log .line.good { color: var(--gold); } #log .line.bad { color: var(--blood); } #player-panel { flex: 1; max-width: 560px; } #player-vbar { height: 20px; } #player-cast.castbar { display: none; } #player-cast.castbar.on { display: block; } #belt { display: flex; gap: 16px; margin-top: 7px; justify-content: center; font-size: 13px; } .belt-item { color: var(--dim); } .belt-item b { color: var(--bone); } #belt-gold { color: var(--gold); } #belt-gold b { color: var(--gold); } .belt-item.flash { animation: beltflash 0.5s; } @keyframes beltflash { from { text-shadow: 0 0 14px var(--gold); transform: scale(1.25); } } /* ---------------- action bar ---------------- */ #actionbar { display: none; gap: 8px; margin-top: 8px; justify-content: center; } #actionbar.on { display: flex; } .slot { position: relative; width: 92px; padding: 7px 4px 5px; background: linear-gradient(180deg, var(--stone-2), var(--stone)); border: 1px solid var(--line); border-radius: 4px; text-align: center; overflow: hidden; transition: border-color 0.1s, transform 0.06s; } .slot:hover { border-color: var(--dim); } .slot:active { transform: translateY(1px); } .slot .nm { font-size: 10px; letter-spacing: 0.5px; display: block; color: var(--bone); white-space: nowrap; } .slot .cost { font-size: 9px; color: var(--dim); display: block; margin-top: 2px; } .slot .num { position: absolute; top: 2px; left: 5px; font-size: 9px; color: var(--dim); } .slot .cd { position: absolute; inset: 0; background: rgba(5, 4, 6, 0.78); transform-origin: bottom; transform: scaleY(0); pointer-events: none; } .slot[data-kind="auto"] .nm { color: var(--dim); } .slot[data-kind="skill"] .nm { color: var(--vigor); } .slot[data-kind="spell"] .nm { color: var(--ember); } .slot[data-kind="curse"] .nm { color: #b07ad0; } .slot[data-kind="recovery"] .nm { color: #7fc06a; } .slot[data-kind="defense"] .nm { color: var(--teal); } .slot.locked { opacity: 0.4; } #combat-controls { display: none; gap: 10px; margin-top: 7px; justify-content: center; } #combat-controls.on { display: flex; } .ctl { font-size: 11px; letter-spacing: 2px; color: var(--dim); border: 1px solid var(--line); border-radius: 4px; padding: 4px 12px; } .ctl:hover { color: var(--bone); border-color: var(--dim); } .ctl.lit { color: var(--gold); border-color: var(--gold); } /* ---------------- minimap ---------------- */ #minimap { width: 196px; height: 124px; border: 1px solid var(--line); border-radius: 4px; background: rgba(8, 7, 8, 0.85); image-rendering: pixelated; } /* ---------------- prompts ---------------- */ .prompt { position: absolute; bottom: 26%; left: 0; right: 0; text-align: center; color: var(--gold); letter-spacing: 2px; font-size: 16px; text-shadow: 0 0 14px rgba(212, 165, 74, 0.6), 0 2px 0 #000; opacity: 0; pointer-events: none; transition: opacity 0.3s; } .prompt.show { opacity: 1; animation: promptpulse 2s ease-in-out infinite; } @keyframes promptpulse { 50% { transform: translateY(-3px); } } #rest-overlay { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.45); color: var(--teal); letter-spacing: 6px; font-size: 18px; opacity: 0; pointer-events: none; transition: opacity 0.25s; } #rest-overlay.show { opacity: 1; } #keys-hint { position: absolute; bottom: 2px; left: 0; right: 0; text-align: center; font-size: 10px; letter-spacing: 1.5px; opacity: 0.4; pointer-events: none; } /* ---------------- end screens ---------------- */ #death { background: radial-gradient(ellipse at 50% 40%, #1a0c0a 0%, var(--void) 75%); } #victory { background: radial-gradient(ellipse at 50% 38%, #241307 0%, var(--void) 75%); } .end-wrap { text-align: center; animation: rise 1.1s ease-out; max-width: 640px; } .end-title { font-size: 38px; letter-spacing: 10px; margin-bottom: 12px; } .end-title.doom { color: var(--blood); text-shadow: 0 0 24px rgba(176, 58, 46, 0.5), 0 3px 0 #000; } .end-title.gold { color: var(--gold); text-shadow: 0 0 24px rgba(224, 106, 40, 0.6), 0 3px 0 #000; } .end-sub { color: var(--dim); margin-bottom: 28px; letter-spacing: 1px; } #victory-boss { width: 200px; height: 200px; object-fit: cover; border-radius: 6px; border: 1px solid var(--gold); margin-bottom: 22px; box-shadow: 0 0 50px rgba(224, 106, 40, 0.35); filter: saturate(0.8) brightness(0.9); } .stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px 30px; margin: 0 auto 30px; width: fit-content; } .stats .stat { text-align: center; } .stats .v { font-size: 24px; color: var(--bone); } .stats .k { font-size: 10px; color: var(--dim); letter-spacing: 2px; margin-top: 3px; } .big-btn { border: 1px solid var(--gold); color: var(--gold); border-radius: 4px; padding: 12px 34px; letter-spacing: 4px; font-size: 14px; transition: background 0.15s, box-shadow 0.15s; } .big-btn:hover { background: rgba(212, 165, 74, 0.12); box-shadow: 0 0 24px rgba(212, 165, 74, 0.25); }