NEON SURVIVORS v1.1 — full-featured bullet-heaven survivor game
Vanilla JS + Canvas, zero dependencies, offline-first PWA. Gameplay: - 11 weapons x8 levels + 11 evolutions (chest-based), incl. timed mines - 13 passives, crit system with directional hit-sparks & hit-stop - 10 characters w/ unique mods + unlock conditions, gold cosmetic skins - 3 biomes (Neon Graveyard / Frozen Hollow / Magma Rift) each with own spawn tables, boss plans and music flavor; Endless mode + surges; 4 difficulty grades; breakable crystal-lamp props - Elite random affixes (Swift/Sturdy/Volatile), 4 bosses, win flow - Achievements (23) w/ gold rewards, run history, daily seeded challenge Tech: - Cinematic canvas main-menu scene, game-feel FX suite (trails, muzzle, status tints, low-HP pulse), viewport culling + particle pooling - WebAudio synth SFX + generative per-biome soundtrack - Gamepad support, remappable keys, touch joystick, fullscreen - i18n VI/EN, localStorage saves w/ export-import codes - Cloudflare Workers leaderboard scaffold (KV) w/ signed submits - Headless integrity test-suite (node test/integrity.js)
This commit is contained in:
+387
@@ -0,0 +1,387 @@
|
||||
/* ============================================================
|
||||
NEON SURVIVORS — stylesheet
|
||||
Dark neon arcade theme. No external assets.
|
||||
============================================================ */
|
||||
:root{
|
||||
--bg:#07070f;
|
||||
--panel:#10101f;
|
||||
--panel2:#161630;
|
||||
--line:#262650;
|
||||
--txt:#e8e8ff;
|
||||
--dim:#8a8ab8;
|
||||
--neon:#7c5cff;
|
||||
--neon2:#00e5ff;
|
||||
--gold:#ffd24a;
|
||||
--red:#ff4d6d;
|
||||
--green:#3ddc84;
|
||||
font-size:16px;
|
||||
}
|
||||
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
|
||||
html,body{height:100%;overflow:hidden;background:var(--bg)}
|
||||
body{
|
||||
font-family:"Segoe UI",system-ui,-apple-system,Roboto,"Helvetica Neue",Arial,sans-serif;
|
||||
color:var(--txt);user-select:none;-webkit-user-select:none;touch-action:none;
|
||||
}
|
||||
.hidden{display:none !important}
|
||||
|
||||
#game{position:fixed;inset:0;width:100%;height:100%;display:block;background:#05050c}
|
||||
|
||||
/* ---------- generic ---------- */
|
||||
.btn{
|
||||
display:inline-flex;align-items:center;justify-content:center;gap:.5em;
|
||||
background:var(--panel2);color:var(--txt);
|
||||
border:1px solid var(--line);border-radius:12px;
|
||||
padding:.65em 1.4em;font-size:1rem;font-weight:600;letter-spacing:.03em;
|
||||
cursor:pointer;transition:transform .08s,border-color .15s,box-shadow .15s,background .15s;
|
||||
}
|
||||
.btn:hover{border-color:var(--neon);box-shadow:0 0 14px rgba(124,92,255,.45)}
|
||||
.btn:active{transform:scale(.96)}
|
||||
.btn-primary{background:linear-gradient(135deg,#6d4bff,#9b3dff);border-color:#8f6bff;box-shadow:0 0 18px rgba(124,92,255,.5)}
|
||||
.btn-danger{background:#3a1020;border-color:#7a2038;color:#ffb3c2}
|
||||
.btn-danger:hover{border-color:var(--red);box-shadow:0 0 14px rgba(255,77,109,.4)}
|
||||
.btn-big{font-size:1.25rem;padding:.8em 2em}
|
||||
.btn-small{font-size:.85rem;padding:.45em .9em}
|
||||
.btn-icon{padding:.35em .7em;font-size:1rem;border-radius:10px}
|
||||
.btn:disabled{opacity:.4;cursor:not-allowed;box-shadow:none}
|
||||
|
||||
.screen,.modal{position:fixed;inset:0;z-index:20;display:flex;align-items:center;justify-content:center;flex-direction:column}
|
||||
.screen{background:radial-gradient(1200px 700px at 50% -10%,rgba(124,92,255,.16),transparent 60%),var(--bg)}
|
||||
#scr-chars,#scr-stage,#scr-shop,#scr-codex,#scr-history{
|
||||
background:radial-gradient(1200px 700px at 50% -10%,rgba(124,92,255,.14),transparent 60%),rgba(5,5,12,.86)}
|
||||
.modal{background:rgba(4,4,12,.72);backdrop-filter:blur(3px)}
|
||||
|
||||
.panel{
|
||||
background:linear-gradient(180deg,var(--panel2),var(--panel));
|
||||
border:1px solid var(--line);border-radius:18px;
|
||||
padding:1.4rem 1.6rem;min-width:min(92vw,430px);max-width:min(94vw,560px);
|
||||
max-height:88vh;overflow-y:auto;text-align:center;
|
||||
box-shadow:0 10px 60px rgba(0,0,0,.6),0 0 40px rgba(124,92,255,.12) inset;
|
||||
animation:pop .22s ease-out;
|
||||
}
|
||||
@keyframes pop{from{transform:scale(.9);opacity:0}to{transform:scale(1);opacity:1}}
|
||||
.panel h2{font-size:1.5rem;margin-bottom:.6rem;letter-spacing:.06em}
|
||||
.panel .sub{color:var(--dim);margin-bottom:1rem;font-size:.95rem}
|
||||
|
||||
.col-btns{display:flex;flex-direction:column;gap:.6rem;margin-top:1rem}
|
||||
.row-btns{display:flex;gap:.6rem;margin-top:1rem;justify-content:center}
|
||||
|
||||
/* ---------- loading / logo ---------- */
|
||||
#scr-loading{background:var(--bg);z-index:99}
|
||||
.logo-pop{font-size:clamp(2rem,7vw,3.6rem);font-weight:900;letter-spacing:.08em;color:var(--neon2);text-shadow:0 0 18px rgba(0,229,255,.8);animation:logoIn .8s ease-out}
|
||||
.logo-pop span{display:block;color:var(--neon);text-shadow:0 0 18px rgba(124,92,255,.9)}
|
||||
@keyframes logoIn{from{transform:scale(.6);opacity:0}to{transform:scale(1);opacity:1}}
|
||||
.loading-bar{width:min(60vw,300px);height:6px;border-radius:4px;background:#1c1c38;margin-top:1.6rem;overflow:hidden}
|
||||
.loading-bar i{display:block;height:100%;width:40%;background:linear-gradient(90deg,var(--neon),var(--neon2));animation:load 1s infinite ease-in-out;border-radius:4px}
|
||||
@keyframes load{0%{transform:translateX(-120%)}100%{transform:translateX(320%)}}
|
||||
|
||||
/* ---------- main menu (cinematic) ---------- */
|
||||
#scr-menu{background:transparent;overflow:hidden}
|
||||
.menu-wrap{width:min(94vw,560px);height:100%;display:flex;flex-direction:column;
|
||||
align-items:center;justify-content:space-between;padding:max(4vh,1.2rem) 1rem 1.4rem;text-align:center}
|
||||
|
||||
.menu-head{display:flex;flex-direction:column;align-items:center;gap:.55rem;margin-top:2vh}
|
||||
.logo{display:flex;flex-direction:column;line-height:.92;font-weight:900;letter-spacing:.04em;
|
||||
animation:logoFloat 5s ease-in-out infinite}
|
||||
.logo .l1{font-size:clamp(2.6rem,10vw,5rem);color:#fff;
|
||||
text-shadow:0 0 14px rgba(0,229,255,.9),0 0 48px rgba(0,229,255,.45),0 2px 0 rgba(0,80,120,.6)}
|
||||
.logo .l2{font-size:clamp(1.7rem,6.6vw,3.3rem);color:var(--neon);
|
||||
text-shadow:0 0 12px rgba(124,92,255,.95),0 0 52px rgba(124,92,255,.5)}
|
||||
@keyframes logoFloat{0%,100%{transform:translateY(0) rotate(-.4deg)}50%{transform:translateY(-7px) rotate(.4deg)}}
|
||||
.tagline{color:var(--dim);font-size:.95rem;max-width:38ch;text-shadow:0 1px 4px rgba(0,0,0,.8)}
|
||||
.ver-chip{font-size:.62rem;letter-spacing:.28em;color:var(--neon2);border:1px solid rgba(0,229,255,.35);
|
||||
border-radius:999px;padding:.28em .9em;background:rgba(0,229,255,.06)}
|
||||
|
||||
.menu-btns{display:flex;flex-direction:column;gap:.62rem;width:min(84vw,320px)}
|
||||
.mbtn{position:relative;display:flex;align-items:center;gap:.85em;width:100%;
|
||||
padding:.72em 1.15em;border-radius:14px;font-weight:700;font-size:1rem;letter-spacing:.04em;
|
||||
color:var(--txt);text-align:left;cursor:pointer;
|
||||
background:linear-gradient(180deg,rgba(30,26,66,.78),rgba(16,13,40,.82));
|
||||
border:1px solid var(--line);backdrop-filter:blur(6px);
|
||||
transition:transform .14s,border-color .14s,box-shadow .14s;overflow:hidden}
|
||||
.mbtn i{font-style:normal;font-size:1.15em;width:1.5em;text-align:center;filter:drop-shadow(0 0 6px rgba(124,92,255,.8))}
|
||||
.mbtn span{flex:1}
|
||||
.mbtn:hover,.mbtn:focus-visible{transform:translateX(6px);border-color:var(--neon);
|
||||
box-shadow:0 0 20px rgba(124,92,255,.35),inset 0 0 18px rgba(124,92,255,.08)}
|
||||
.mbtn:hover::after{content:"";position:absolute;top:0;bottom:0;left:-70%;width:45%;
|
||||
background:linear-gradient(100deg,transparent,rgba(255,255,255,.09),transparent);
|
||||
animation:shine .7s ease-out}
|
||||
@keyframes shine{to{left:130%}}
|
||||
.mbtn.primary{background:linear-gradient(180deg,rgba(124,92,255,.32),rgba(60,40,160,.42));
|
||||
border-color:rgba(124,92,255,.65);box-shadow:0 0 24px rgba(124,92,255,.25)}
|
||||
.mbtn.primary:hover{box-shadow:0 0 30px rgba(124,92,255,.5)}
|
||||
.mbtn.primary i{color:#fff}
|
||||
.daily-best{font-size:.68rem;color:#ffd24a;font-style:normal}
|
||||
|
||||
.menu-foot{width:min(88vw,520px);display:flex;flex-direction:column;align-items:center;gap:.5rem}
|
||||
.menu-stats{display:flex;gap:.6rem;flex-wrap:wrap;justify-content:center}
|
||||
.chip{background:rgba(12,10,30,.72);border:1px solid var(--line);border-radius:999px;
|
||||
padding:.34em .95em;color:var(--dim);font-size:.85rem;backdrop-filter:blur(4px)}
|
||||
.chip b{color:var(--gold)}
|
||||
.hint{color:var(--dim);font-size:.74rem;opacity:.75;max-width:52ch;text-align:center}
|
||||
|
||||
/* staggered entrance — replayed by re-adding .enter on #scr-menu */
|
||||
#scr-menu.enter .menu-head,#scr-menu.enter .menu-btns,#scr-menu.enter .menu-foot{
|
||||
animation:fadeUp .55s cubic-bezier(.2,.7,.2,1) both}
|
||||
#scr-menu.enter .menu-btns{animation-delay:.08s}
|
||||
#scr-menu.enter .menu-foot{animation-delay:.16s}
|
||||
@keyframes fadeUp{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
|
||||
@media (prefers-reduced-motion:reduce){
|
||||
.logo,.mbtn::after{animation:none!important}
|
||||
#scr-menu.enter *{animation:none!important}
|
||||
}
|
||||
|
||||
/* ---------- screen headers ---------- */
|
||||
.scr-head{position:absolute;top:0;left:0;right:0;display:flex;align-items:center;gap:.8rem;
|
||||
padding:.8rem 1rem;background:linear-gradient(180deg,rgba(7,7,15,.95),rgba(7,7,15,.6) 70%,transparent)}
|
||||
.scr-head h2{flex:1;text-align:center;font-size:1.25rem;letter-spacing:.08em}
|
||||
.head-gold{color:var(--gold);font-weight:700;min-width:64px;text-align:right}
|
||||
.back-btn{background:var(--panel2)}
|
||||
.card-grid,.shop-grid,.codex-list,.opt-panel{
|
||||
margin-top:4.2rem;width:min(94vw,900px);max-height:calc(100vh - 5.4rem);
|
||||
overflow-y:auto;padding:.4rem .6rem 1.4rem;scrollbar-width:thin;scrollbar-color:var(--line) transparent;
|
||||
}
|
||||
.card-grid::-webkit-scrollbar,.shop-grid::-webkit-scrollbar,.codex-list::-webkit-scrollbar,.opt-panel::-webkit-scrollbar{width:8px}
|
||||
.card-grid::-webkit-scrollbar-thumb{background:var(--line);border-radius:4px}
|
||||
|
||||
/* ---------- character cards ---------- */
|
||||
.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(190px,1fr));gap:.9rem}
|
||||
.char-card{
|
||||
background:linear-gradient(180deg,var(--panel2),var(--panel));border:1px solid var(--line);border-radius:16px;
|
||||
padding:1rem .8rem;text-align:center;cursor:pointer;position:relative;overflow:hidden;
|
||||
transition:border-color .15s,box-shadow .15s,transform .1s;
|
||||
}
|
||||
.char-card:hover{border-color:var(--neon);box-shadow:0 0 18px rgba(124,92,255,.35);transform:translateY(-2px)}
|
||||
.char-card.selected{border-color:var(--neon2);box-shadow:0 0 22px rgba(0,229,255,.5)}
|
||||
.char-card.locked{filter:grayscale(.9) brightness(.65);cursor:default}
|
||||
.char-card.locked:hover{border-color:var(--line);box-shadow:none;transform:none}
|
||||
.char-sym{font-size:2.6rem;line-height:1;filter:drop-shadow(0 0 8px rgba(124,92,255,.7))}
|
||||
.char-name{font-weight:800;letter-spacing:.05em;margin-top:.35rem}
|
||||
.char-weapon{color:var(--dim);font-size:.78rem;margin-top:.15rem}
|
||||
.char-traits{font-size:.78rem;color:var(--neon2);margin-top:.5rem;min-height:2.1em}
|
||||
.char-lock{position:absolute;inset:auto 0 0 0;background:rgba(5,5,14,.85);padding:.5rem;font-size:.75rem;color:#ffb3c2}
|
||||
.char-lock::before{content:"🔒 "}
|
||||
|
||||
/* ---------- stage select ---------- */
|
||||
.stage-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:.9rem;padding:4.2rem 1.2rem .5rem;overflow-y:auto;max-height:52vh}
|
||||
.stage-card{position:relative;background:linear-gradient(180deg,var(--panel2),var(--panel));border:1px solid var(--line);border-radius:16px;
|
||||
padding:1rem .8rem;text-align:center;cursor:pointer;transition:border-color .15s,box-shadow .15s,transform .1s}
|
||||
.stage-card:hover{border-color:var(--neon);box-shadow:0 0 18px rgba(124,92,255,.35);transform:translateY(-2px)}
|
||||
.stage-card.selected{border-color:var(--neon2);box-shadow:0 0 22px rgba(0,229,255,.5)}
|
||||
.stage-card.locked{filter:grayscale(.9) brightness(.6)}
|
||||
.lock-tag{position:absolute;inset:auto 0 0 0;background:rgba(5,5,14,.88);padding:.45rem;font-size:.72rem;color:#ffb3c2}
|
||||
.stage-best{font-size:.75rem;color:#ffd24a;margin-top:.4rem;min-height:1.1em}
|
||||
.stage-opts{padding:.6rem 1.4rem;display:flex;flex-direction:column;gap:.15rem;max-width:520px;margin:0 auto;width:100%}
|
||||
.seg{display:flex;gap:.3rem;flex-wrap:wrap}
|
||||
.seg .btn.active{border-color:var(--neon2);color:var(--neon2);box-shadow:0 0 10px rgba(0,229,255,.35)}
|
||||
|
||||
/* ---------- run history ---------- */
|
||||
.hist-summary{display:flex;gap:1.2rem;flex-wrap:wrap;padding:4rem 1.4rem .6rem;color:var(--dim);font-size:.85rem}
|
||||
.hist-summary b{color:#fff}
|
||||
.hist-list{overflow-y:auto;max-height:60vh;padding:.2rem 1.2rem 1rem;display:flex;flex-direction:column;gap:.4rem}
|
||||
.hist-row{display:flex;align-items:center;gap:.7rem;background:var(--panel);border:1px solid var(--line);border-radius:10px;padding:.45rem .8rem;font-size:.85rem}
|
||||
.hist-row.win{border-color:rgba(255,210,74,.5)}
|
||||
.h-sym{font-size:1.2rem}
|
||||
.h-stage{font-size:1rem}
|
||||
.h-date{color:var(--dim);min-width:5.2em}
|
||||
.h-time{font-weight:800;color:var(--neon2);min-width:3.4em}
|
||||
.h-meta{color:var(--dim);font-size:.78rem}
|
||||
.h-grade{color:#ff9db0;font-weight:700;font-size:.75rem}
|
||||
.h-badge{margin-left:auto;color:#ffd24a;font-weight:800;font-size:.75rem}
|
||||
.hist-empty{text-align:center;color:var(--dim);padding:2rem}
|
||||
|
||||
/* ---------- save transfer modal ---------- */
|
||||
.panel-save{background:var(--panel2);border:1px solid var(--line);border-radius:16px;padding:1.1rem;width:min(92vw,560px)}
|
||||
.panel-save h3{margin-bottom:.6rem}
|
||||
.panel-save textarea{width:100%;background:#0a0a18;color:#bfeaff;border:1px solid var(--line);border-radius:8px;padding:.6rem;font-size:.72rem;resize:vertical}
|
||||
.save-btns{display:flex;gap:.5rem;margin-top:.6rem;justify-content:flex-end}
|
||||
|
||||
/* ---------- tutorial bubble ---------- */
|
||||
#tutTip{position:fixed;left:50%;bottom:5.4rem;transform:translateX(-50%);z-index:40;
|
||||
background:rgba(8,8,22,.94);border:1px solid var(--neon);border-radius:12px;
|
||||
padding:.65rem 2.4rem .65rem 1rem;max-width:min(88vw,480px);
|
||||
font-size:.88rem;box-shadow:0 0 22px rgba(124,92,255,.35);pointer-events:auto}
|
||||
#bt-tut-skip{position:absolute;top:.25rem;right:.35rem;background:none;border:none;color:var(--dim);cursor:pointer;font-size:.95rem}
|
||||
|
||||
/* endless overtime clock */
|
||||
#hudTimer.endless{color:var(--neon2);text-shadow:0 0 10px rgba(0,229,255,.7)}
|
||||
#hudTimer.endless small{font-size:.62em;opacity:.8}
|
||||
|
||||
/* ---------- skins ---------- */
|
||||
.skin-row{display:flex;align-items:center;justify-content:center;gap:.35rem;margin-top:.5rem}
|
||||
.skin-name{font-size:.75rem;color:var(--dim);display:inline-flex;align-items:center;gap:.3em}
|
||||
.skin-name i{width:.85em;height:.85em;border-radius:50%;display:inline-block;box-shadow:0 0 6px currentColor}
|
||||
.btn-mini{font-size:.72rem;padding:.25em .55em;border-radius:8px}
|
||||
.btn-mini.buy{color:#ffd24a}
|
||||
|
||||
/* ---------- options text inputs ---------- */
|
||||
.opt-input{flex:1;background:#0a0a18;border:1px solid var(--line);border-radius:8px;
|
||||
color:#e8e8ff;padding:.45em .6em;font-size:.8rem;max-width:60%}
|
||||
.opt-input:focus{outline:none;border-color:var(--neon)}
|
||||
|
||||
/* ---------- leaderboard modal ---------- */
|
||||
.panel-lb{background:var(--panel2);border:1px solid var(--line);border-radius:16px;
|
||||
padding:1.1rem;width:min(94vw,520px)}
|
||||
.lb-scopes{margin:.7rem 0}
|
||||
.lb-list{max-height:46vh;overflow-y:auto;display:flex;flex-direction:column;gap:.35rem;margin-top:.4rem}
|
||||
.h-rank{font-weight:800;color:var(--neon2);min-width:2.4em}
|
||||
.h-name{font-weight:700}
|
||||
|
||||
/* ---------- meta shop ---------- */
|
||||
.shop-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:.8rem}
|
||||
.shop-item{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:.85rem;text-align:left}
|
||||
.shop-item h4{font-size:1rem;display:flex;align-items:center;gap:.45em}
|
||||
.shop-item p{color:var(--dim);font-size:.78rem;margin:.3rem 0 .55rem;min-height:2.2em}
|
||||
.rank-pips{display:flex;gap:4px;margin-bottom:.55rem}
|
||||
.rank-pips i{width:16px;height:6px;border-radius:3px;background:#232345}
|
||||
.rank-pips i.on{background:linear-gradient(90deg,var(--neon),var(--neon2));box-shadow:0 0 6px rgba(124,92,255,.7)}
|
||||
.shop-buy{width:100%;font-size:.85rem;padding:.5em}
|
||||
|
||||
/* ---------- codex ---------- */
|
||||
.tabs{position:absolute;top:3.2rem;left:0;right:0;display:flex;justify-content:center;gap:.4rem;flex-wrap:wrap;padding:.4rem}
|
||||
.tab{background:var(--panel);border:1px solid var(--line);color:var(--dim);padding:.4em 1em;border-radius:999px;cursor:pointer;font-size:.85rem;font-weight:600}
|
||||
.tab.active{color:var(--txt);border-color:var(--neon);box-shadow:0 0 10px rgba(124,92,255,.4)}
|
||||
.codex-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:.7rem;align-content:start}
|
||||
.cx-card{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:.75rem .85rem;display:flex;gap:.7rem;align-items:flex-start;text-align:left}
|
||||
.cx-sym{font-size:1.7rem;filter:drop-shadow(0 0 6px rgba(124,92,255,.6))}
|
||||
.cx-body h4{font-size:.98rem}
|
||||
.cx-body p{color:var(--dim);font-size:.76rem;margin-top:.2rem}
|
||||
.cx-tag{display:inline-block;font-size:.66rem;background:#1e1e40;border:1px solid var(--line);border-radius:6px;padding:.1em .5em;margin-top:.35em;color:var(--neon2)}
|
||||
.cx-lock{opacity:.45}
|
||||
|
||||
/* ---------- options ---------- */
|
||||
.opt-panel{max-width:min(94vw,520px);margin-left:auto;margin-right:auto}
|
||||
.opt-group{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:.9rem 1rem;margin-bottom:.8rem;text-align:left}
|
||||
.opt-group h3{font-size:.85rem;text-transform:uppercase;letter-spacing:.12em;color:var(--neon2);margin-bottom:.6rem}
|
||||
.opt-row{display:flex;align-items:center;justify-content:space-between;gap:1rem;padding:.4rem 0;font-size:.92rem}
|
||||
.opt-row label{color:var(--txt)}
|
||||
input[type=range]{-webkit-appearance:none;appearance:none;width:150px;height:5px;border-radius:3px;background:#232345;outline:none}
|
||||
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:17px;height:17px;border-radius:50%;
|
||||
background:var(--neon2);box-shadow:0 0 8px rgba(0,229,255,.8);cursor:pointer}
|
||||
input[type=range]::-moz-range-thumb{width:17px;height:17px;border-radius:50%;background:var(--neon2);border:none;cursor:pointer}
|
||||
.toggle{position:relative;width:48px;height:25px;border-radius:99px;background:#232345;cursor:pointer;transition:background .2s;flex-shrink:0}
|
||||
.toggle::after{content:"";position:absolute;top:3px;left:3px;width:19px;height:19px;border-radius:50%;background:#8888bb;transition:left .18s,background .18s}
|
||||
.toggle.on{background:linear-gradient(90deg,var(--neon),var(--neon2))}
|
||||
.toggle.on::after{left:26px;background:#fff}
|
||||
.seg{display:flex;gap:.3rem}
|
||||
.seg button{background:#181832;border:1px solid var(--line);color:var(--dim);border-radius:8px;padding:.3em .7em;font-size:.78rem;cursor:pointer}
|
||||
.seg button.on{color:var(--txt);border-color:var(--neon2);background:#12303a}
|
||||
|
||||
/* ---------- HUD ---------- */
|
||||
#hud{position:fixed;inset:0;z-index:10;pointer-events:none}
|
||||
#xpBar{position:absolute;top:0;left:0;right:0;height:16px;background:rgba(10,10,25,.85);border-bottom:1px solid var(--line)}
|
||||
#xpFill{display:block;height:100%;width:0%;background:linear-gradient(90deg,#28d7fe,#7c5cff);transition:width .15s;box-shadow:0 0 10px rgba(40,215,254,.7)}
|
||||
#lvlTag{position:absolute;right:8px;top:-1px;font-size:.68rem;font-weight:800;line-height:16px;color:#fff;text-shadow:0 1px 2px #000;letter-spacing:.08em}
|
||||
#hudTop{position:absolute;top:24px;left:0;right:0;display:flex;align-items:center;justify-content:space-between;padding:0 .8rem}
|
||||
#hudPortrait{position:relative;width:52px;height:52px;border-radius:50%;background:rgba(12,12,30,.85);
|
||||
border:2px solid var(--neon);display:flex;align-items:center;justify-content:center;font-size:1.6rem;box-shadow:0 0 14px rgba(124,92,255,.5)}
|
||||
#hudPortrait em{position:absolute;bottom:-6px;right:-6px;background:var(--neon2);color:#00232b;font-style:normal;
|
||||
font-size:.68rem;font-weight:900;border-radius:8px;padding:.05em .45em;border:1px solid #063a44}
|
||||
#hudTimer{font-size:1.7rem;font-weight:900;letter-spacing:.1em;text-shadow:0 0 12px rgba(0,229,255,.6);font-variant-numeric:tabular-nums}
|
||||
#hudRight{display:flex;flex-direction:column;align-items:flex-end;gap:.2rem;font-weight:700;font-size:1rem;text-shadow:0 1px 3px #000}
|
||||
#hudGold{color:var(--gold)}#hudKills{color:#ff9db0}
|
||||
#bossBar{position:absolute;top:86px;left:50%;transform:translateX(-50%);width:min(70vw,480px);text-align:center}
|
||||
#bossBar label{font-size:.85rem;font-weight:800;letter-spacing:.14em;color:#ffb3c2;text-shadow:0 0 8px rgba(255,77,109,.8)}
|
||||
.bb-track{height:10px;background:rgba(20,8,16,.85);border:1px solid #5a1830;border-radius:6px;margin-top:3px;overflow:hidden}
|
||||
#bossFill{display:block;height:100%;width:100%;background:linear-gradient(90deg,#ff2740,#ff7a3d);box-shadow:0 0 10px rgba(255,60,80,.8)}
|
||||
#slotWeapons,#slotPassives{position:absolute;left:.7rem;display:flex;flex-wrap:wrap;gap:5px;max-width:200px}
|
||||
#slotWeapons{bottom:.7rem}
|
||||
#slotPassives{bottom:4.1rem}
|
||||
.slot{width:36px;height:36px;border-radius:9px;background:rgba(12,12,30,.85);border:1px solid var(--line);
|
||||
display:flex;align-items:center;justify-content:center;font-size:1.15rem;position:relative}
|
||||
.slot.evolved{border-color:var(--gold);box-shadow:0 0 10px rgba(255,210,74,.55)}
|
||||
.slot .lv{position:absolute;bottom:-3px;right:-3px;font-size:.58rem;font-weight:900;background:#000c;border-radius:5px;padding:0 .25em;color:var(--neon2)}
|
||||
.slot.passive{width:28px;height:28px;font-size:.9rem}
|
||||
.slot.cd::before{content:"";position:absolute;inset:0;background:conic-gradient(rgba(0,0,0,.62) var(--p,0%),transparent 0);border-radius:9px}
|
||||
|
||||
/* ---------- level up choices ---------- */
|
||||
.choice-list{display:flex;flex-direction:column;gap:.55rem;margin:.4rem 0 .2rem}
|
||||
.choice{
|
||||
display:flex;align-items:center;gap:.8rem;text-align:left;
|
||||
background:linear-gradient(180deg,#1b1b3a,#12122a);border:1px solid var(--line);border-radius:13px;
|
||||
padding:.6rem .8rem;cursor:pointer;transition:border-color .12s,transform .1s,box-shadow .12s;
|
||||
animation:slideUp .25s ease-out backwards;
|
||||
}
|
||||
.choice:nth-child(2){animation-delay:.05s}.choice:nth-child(3){animation-delay:.1s}.choice:nth-child(4){animation-delay:.15s}
|
||||
@keyframes slideUp{from{transform:translateY(14px);opacity:0}to{transform:none;opacity:1}}
|
||||
.choice:hover{border-color:var(--neon2);box-shadow:0 0 16px rgba(0,229,255,.35);transform:translateX(4px)}
|
||||
.choice.neww{border-color:#2affd0}
|
||||
.ch-sym{width:46px;height:46px;border-radius:11px;background:#0d0d20;border:1px solid var(--line);
|
||||
display:flex;align-items:center;justify-content:center;font-size:1.5rem;flex-shrink:0}
|
||||
.choice.evolve .ch-sym{border-color:var(--gold);box-shadow:0 0 12px rgba(255,210,74,.5)}
|
||||
.ch-info{flex:1;min-width:0}
|
||||
.ch-info h4{font-size:1rem}
|
||||
.ch-info p{color:var(--dim);font-size:.78rem;margin-top:.15rem}
|
||||
.ch-lv{font-size:.72rem;font-weight:800;color:var(--neon2);white-space:nowrap}
|
||||
.choice.evolve .ch-lv{color:var(--gold)}
|
||||
|
||||
/* ---------- chest modal ---------- */
|
||||
.panel-chest{min-width:min(90vw,380px)}
|
||||
.chest-art{font-size:4rem;animation:chestBounce .7s infinite alternate ease-in-out;filter:drop-shadow(0 0 18px rgba(255,210,74,.8))}
|
||||
@keyframes chestBounce{from{transform:translateY(0) rotate(-4deg)}to{transform:translateY(-10px) rotate(4deg)}}
|
||||
.chest-line{display:flex;align-items:center;gap:.6rem;background:#14142c;border:1px solid var(--line);
|
||||
border-radius:11px;padding:.5rem .7rem;margin:.4rem 0;text-align:left;font-size:.92rem}
|
||||
.chest-line b{color:var(--gold)}
|
||||
|
||||
/* ---------- game over ---------- */
|
||||
.panel-over{min-width:min(92vw,420px)}
|
||||
.record{color:var(--gold);font-weight:900;letter-spacing:.14em;margin-bottom:.5rem;animation:pulseR 1s infinite alternate}
|
||||
@keyframes pulseR{from{text-shadow:0 0 6px rgba(255,210,74,.6)}to{text-shadow:0 0 20px rgba(255,210,74,1)}}
|
||||
.over-grid{display:grid;grid-template-columns:1fr auto;gap:.45rem 1.2rem;text-align:left;background:#12122a;
|
||||
border:1px solid var(--line);border-radius:12px;padding:.9rem 1.1rem;margin:.8rem 0;font-size:.95rem}
|
||||
.over-grid span{color:var(--dim)}.over-grid b{text-align:right;color:var(--txt)}
|
||||
|
||||
.pause-stats{display:grid;grid-template-columns:auto auto;gap:.3rem 1.4rem;justify-content:center;margin:.6rem 0 .2rem;color:var(--dim);font-size:.9rem}
|
||||
.pause-stats b{color:var(--txt)}
|
||||
|
||||
/* ---------- toasts ---------- */
|
||||
#toasts{position:fixed;top:22vh;left:0;right:0;z-index:40;display:flex;flex-direction:column;align-items:center;gap:.4rem;pointer-events:none}
|
||||
.toast{background:rgba(10,10,26,.92);border:1px solid var(--neon);border-radius:99px;padding:.45em 1.3em;
|
||||
font-weight:800;letter-spacing:.1em;animation:toastIn 2.6s forwards;box-shadow:0 0 18px rgba(124,92,255,.5);font-size:.95rem}
|
||||
.toast.warn{border-color:var(--red);box-shadow:0 0 18px rgba(255,77,109,.6);color:#ffc9d4}
|
||||
.toast.gold{border-color:var(--gold);box-shadow:0 0 18px rgba(255,210,74,.55);color:#ffe9ad}
|
||||
@keyframes toastIn{0%{transform:translateY(-18px);opacity:0}10%{transform:none;opacity:1}80%{opacity:1}100%{opacity:0;transform:translateY(-8px)}}
|
||||
|
||||
/* ---------- fps meter ---------- */
|
||||
#fpsMeter{position:fixed;top:44px;left:10px;z-index:30;font-size:.72rem;font-family:monospace;color:#7dffce;
|
||||
background:rgba(0,0,0,.5);padding:2px 7px;border-radius:6px;pointer-events:none}
|
||||
|
||||
/* ---------- touch controls ---------- */
|
||||
#touchLayer{position:fixed;inset:0;z-index:15;pointer-events:none}
|
||||
#stickBase{position:absolute;width:110px;height:110px;border-radius:50%;border:2px solid rgba(124,92,255,.5);
|
||||
background:rgba(20,20,50,.35);display:none}
|
||||
#stickKnob{position:absolute;left:50%;top:50%;width:48px;height:48px;border-radius:50%;
|
||||
background:rgba(0,229,255,.5);border:2px solid rgba(0,229,255,.9);transform:translate(-50%,-50%)}
|
||||
|
||||
/* ---------- developer mode ---------- */
|
||||
#devBtn{
|
||||
position:fixed;top:86px;right:10px;z-index:35;
|
||||
width:44px;height:44px;border-radius:12px;font-size:1.25rem;
|
||||
background:rgba(15,15,35,.9);border:1px dashed var(--neon2);color:#fff;cursor:pointer;
|
||||
box-shadow:0 0 12px rgba(0,229,255,.4);
|
||||
}
|
||||
#devBtn:hover{transform:scale(1.06)}
|
||||
.panel-dev{min-width:min(94vw,560px);text-align:left}
|
||||
.panel-dev h2{color:var(--neon2);letter-spacing:.12em;font-size:1.05rem;display:flex;justify-content:space-between;align-items:center}
|
||||
.panel-dev .dev-close{background:none;border:none;color:var(--dim);font-size:1.3rem;cursor:pointer;line-height:1}
|
||||
.panel-dev .dev-close:hover{color:var(--red)}
|
||||
.dev-sec{border-top:1px solid var(--line);margin-top:.7rem;padding-top:.55rem}
|
||||
.dev-sec h3{font-size:.72rem;text-transform:uppercase;letter-spacing:.14em;color:var(--gold);margin-bottom:.45rem}
|
||||
.dev-row{display:flex;flex-wrap:wrap;gap:.4rem;align-items:center;margin-bottom:.5rem}
|
||||
.dev-row label{font-size:.82rem;color:var(--txt);min-width:110px}
|
||||
.dev-btn{font-size:.75rem;padding:.32em .7em;border-radius:8px;background:#181838;border:1px solid var(--line);color:var(--txt);cursor:pointer}
|
||||
.dev-btn:hover{border-color:var(--neon2)}
|
||||
.dev-grid{display:grid;grid-template-columns:1fr 1fr;gap:.25rem .9rem;max-height:200px;overflow-y:auto;padding-right:.2rem}
|
||||
.dev-item{display:flex;align-items:center;gap:.35rem;font-size:.78rem;background:#12122a;border-radius:8px;padding:.22rem .4rem}
|
||||
.dev-item .nm{flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.dev-item .lv{color:var(--neon2);font-weight:800;font-size:.68rem;min-width:26px;text-align:right}
|
||||
.dev-item button{font-size:.62rem;padding:.18em .5em;border-radius:6px;background:#20204a;border:1px solid var(--line);color:var(--txt);cursor:pointer}
|
||||
.dev-item button:hover{border-color:var(--gold)}
|
||||
.dev-note{font-size:.7rem;color:var(--dim);margin-top:.5rem}
|
||||
|
||||
@media (max-height:520px){
|
||||
.menu-btns{gap:.4rem;width:min(84vw,300px)}
|
||||
.mbtn{padding:.5em 1em;font-size:.92rem}
|
||||
.logo .l1{font-size:clamp(2rem,9vw,3.4rem)}
|
||||
.logo .l2{font-size:clamp(1.3rem,6vw,2.3rem)}
|
||||
.menu-head{margin-top:0}
|
||||
}
|
||||
Reference in New Issue
Block a user