Redesign lists and roulette pages UI

Revamp the Lists and Roulette pages with new semantic panels and updated layout. lists.html: replace the simple list panel with a sidebar Quick Jump, a prominent hero section, dedicated controls (search + filter) and a separate table panel while preserving existing IDs (search, level-filter, list-area, list-title). roulette.html: reorganize into a roulette-shell with a main roulette panel (spin button, card) and a rules sidebar/card with concise rule items; interactive IDs (roulette-spin, roulette-card, roulette-open, etc.) remain intact. styles.css: add styles for the new components (.list-*, .control-block, .roulette-shell, .roulette-rules-card, .roulette-rule-list, .sidebar-kicker and more), tweak search-row spacing and responsive behaviors to support the new layout. No JS behavior changed in this diff (app.js left referenced but untouched).
This commit is contained in:
2026-03-31 19:54:57 -05:00
parent 5acf920143
commit 463fa222ff
3 changed files with 130 additions and 55 deletions
+47 -16
View File
@@ -18,27 +18,58 @@
</header>
<main class="layout">
<aside class="sidebar">
<div class="panel">
<h2>Levels</h2>
<div class="panel list-sidebar-panel">
<p class="sidebar-kicker">Quick Jump</p>
<h2>Rank ranges</h2>
<p class="muted">Jump straight to a section of the list and narrow things down fast.</p>
<ul id="levels"></ul>
</div>
</aside>
<section class="panel content">
<div class="search-row">
<h2 id="list-title">FEDL List</h2>
<input id="search" type="text" placeholder="Search videos or titles..." />
<select id="level-filter"><option value="all">All Levels</option></select>
</div>
<section class="content list-page-shell">
<section class="panel list-hero-panel">
<div class="list-hero-copy">
<p class="hero-kicker">FEDL Rankings</p>
<h2 id="list-title">FEDL List</h2>
<p class="muted list-hero-text">Browse the full ranking, search for a level by name, filter by placement range, and open linked videos directly from the table.</p>
</div>
<div class="list-hero-badge">
<strong>Live list</strong>
<span>Updates pull from the current FEDL data source when available.</span>
</div>
</section>
<div class="table-wrap">
<table class="levels-table">
<thead>
<tr><th style="width:80px">#</th><th>Title</th><th style="width:140px">Action</th></tr>
</thead>
<tbody id="list-area"></tbody>
</table>
</div>
<section class="panel list-controls-panel">
<div class="search-row">
<label class="control-block" for="search">
<span>Search</span>
<input id="search" type="text" placeholder="Search titles..." />
</label>
<label class="control-block control-select" for="level-filter">
<span>Filter</span>
<select id="level-filter"><option value="all">All Levels</option></select>
</label>
</div>
</section>
<section class="panel list-table-panel">
<div class="table-header">
<div>
<p class="status-label">List Table</p>
<h3>Current placements</h3>
</div>
<p class="muted table-hint">Click <strong>Open</strong> on any row to watch the linked run.</p>
</div>
<div class="table-wrap">
<table class="levels-table">
<thead>
<tr><th style="width:80px">#</th><th>Title</th><th style="width:140px">Action</th></tr>
</thead>
<tbody id="list-area"></tbody>
</table>
</div>
</section>
</section>
</main>
<script src="app.js"></script>
+41 -30
View File
@@ -17,38 +17,49 @@
</nav>
</header>
<main>
<section class="panel roulette-rules">
<p class="roulette-kicker">Rules</p>
<h2>How Roulette Works</h2>
<ul class="rules-list">
<li>Extreme Demon Roulette is a community challenge built around a roulette of hard demons from a chosen list.</li>
<li>You can use a main list, extended list, legacy list, or a custom list like this FEDL list.</li>
<li>A common format is to start at <strong>1%</strong> and raise the goal by <strong>1%</strong> for each new level until you fail or finish the challenge.</li>
<li>Some versions allow skips, rerolls, or custom limits, depending on the rules you want to use.</li>
<li>This page shows the demon name, rank, and level ID for the selected result.</li>
<li>Percent targets are stored in <code>level-ids.txt</code> using the format <code>title|levelId|percent</code>.</li>
<li>If a level ID is missing in that file, this page will try to look it up through the Geometry Dash community API automatically.</li>
</ul>
</section>
<section class="panel roulette-panel">
<div class="roulette-head">
<div>
<p class="roulette-kicker">Random Challenge</p>
<h2>Demon Roulette</h2>
<p class="muted">Spin the FEDL list to get a random demon for your roulette run.</p>
<section class="roulette-shell">
<section class="panel roulette-panel">
<div class="roulette-head">
<div>
<p class="roulette-kicker">Random Challenge</p>
<h2>Demon Roulette</h2>
<p class="muted roulette-intro">Spin the FEDL list to get a random demon for your next roulette run, practice grind, or bad decision.</p>
</div>
<button class="btn roulette-btn" id="roulette-spin" type="button">Spin</button>
</div>
<button class="btn roulette-btn" id="roulette-spin" type="button">Spin</button>
</div>
<div class="roulette-card" id="roulette-card">
<p class="roulette-status muted" id="roulette-status">Press spin to choose a demon.</p>
<h3 id="roulette-title">No demon selected</h3>
<p class="roulette-rank" id="roulette-rank">Rank: -</p>
<p class="roulette-meta" id="roulette-level-id">Level ID: -</p>
<p class="roulette-note muted" id="roulette-note">Level IDs come from your local file first, then API lookup if needed.</p>
<a class="btn roulette-open" id="roulette-open" href="#" target="_blank" rel="noopener noreferrer" hidden>Open Video</a>
</div>
<div class="roulette-card" id="roulette-card">
<p class="roulette-status muted" id="roulette-status">Press spin to choose a demon.</p>
<h3 id="roulette-title">No demon selected</h3>
<p class="roulette-rank" id="roulette-rank">Rank: -</p>
<p class="roulette-meta" id="roulette-level-id">Level ID: -</p>
<p class="roulette-note muted" id="roulette-note">Level IDs come from your local file first, then API lookup if needed.</p>
<a class="btn roulette-open" id="roulette-open" href="#" target="_blank" rel="noopener noreferrer" hidden>Open Video</a>
</div>
</section>
<aside class="panel roulette-rules-card">
<p class="roulette-kicker">How It Works</p>
<h2>Quick rules</h2>
<div class="roulette-rule-list">
<article>
<strong>Pick from a list</strong>
<p>Use FEDL or any demon list format you want for your roulette session.</p>
</article>
<article>
<strong>Raise the target</strong>
<p>A common setup starts at 1% and increases by 1% after each new level.</p>
</article>
<article>
<strong>Use your own rules</strong>
<p>Skips, rerolls, and loss conditions can be adjusted to match your challenge format.</p>
</article>
<article>
<strong>Extra data included</strong>
<p>This page shows rank and level ID, and it tries API lookup when local info is missing.</p>
</article>
</div>
</aside>
</section>
</main>
<script src="app.js"></script>
+42 -9
View File
@@ -13,11 +13,12 @@ h1,h2,h3,h4{line-height:1.15}
.sidebar h2{margin:0 0 8px 0;font-size:0.95rem}
.sidebar ul{list-style:none;padding:0;margin:0}
.sidebar li{margin:6px 0}
.sidebar-kicker{margin:0 0 8px 0;text-transform:uppercase;letter-spacing:.16em;font-size:.72rem;font-weight:800;color:var(--accent)}
.level-link{display:block;width:100%;text-align:left;padding:8px;border-radius:6px;border:0;background:transparent;color:var(--muted);cursor:pointer;font-weight:600}
.level-link.active{background:rgba(92,197,255,0.06);color:var(--accent)}
.content{flex:1}
.panel{background:var(--panel);padding:14px;border-radius:10px;margin-bottom:12px;box-shadow:0 3px 12px rgba(2,6,23,0.6)}
.search-row{display:flex;gap:8px;align-items:center;margin-bottom:12px}
.search-row{display:flex;gap:14px;align-items:end;margin-bottom:0}
.search-row input[type=text]{flex:1;padding:10px 12px;border-radius:8px;border:1px solid rgba(255,255,255,0.04);background:transparent;color:var(--text)}
.search-row select{padding:8px;border-radius:8px;border:1px solid rgba(255,255,255,0.04);background:transparent;color:var(--text)}
.table-wrap{overflow:auto;border-radius:8px}
@@ -71,6 +72,30 @@ table.levels-table tr:hover td{background:rgba(255,255,255,0.01)}
.spotlight-card{padding:18px;border-radius:18px;background:rgba(255,255,255,0.05);border:1px solid rgba(255,255,255,0.08)}
.spotlight-card h3{margin:0 0 10px 0;font-size:1.08rem}
.spotlight-card p{margin:0;color:#dce8f5;line-height:1.6}
.list-page-shell{display:flex;flex-direction:column;gap:16px}
.list-sidebar-panel{padding:18px 16px;border-radius:24px;background:linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.02));border:1px solid rgba(255,255,255,0.06)}
.list-sidebar-panel h2{margin:0 0 10px 0;font-size:1.2rem}
.list-sidebar-panel .muted{margin:0 0 16px 0;line-height:1.55}
.list-hero-panel{display:flex;align-items:end;justify-content:space-between;gap:18px;padding:28px;border-radius:28px;background:linear-gradient(135deg,rgba(92,197,255,0.14),rgba(7,19,38,0.95));border:1px solid rgba(92,197,255,0.16)}
.list-hero-copy h2{margin:0 0 10px 0;font-size:clamp(2rem,4vw,3rem)}
.list-hero-text{max-width:60ch;line-height:1.7}
.list-hero-badge{max-width:230px;padding:16px 18px;border-radius:18px;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.08)}
.list-hero-badge strong{display:block;margin-bottom:8px;font-size:1rem}
.list-hero-badge span{display:block;color:#d7e5f4;line-height:1.55;font-size:.92rem}
.list-controls-panel{padding:20px 22px;border-radius:24px;background:linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.03));border:1px solid rgba(255,255,255,0.06)}
.control-block{display:flex;flex:1;flex-direction:column;gap:8px;font-weight:700;color:#f2f7fd}
.control-block span{font-size:.82rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.control-block input,.control-block select{width:100%;padding:12px 14px;border-radius:14px;border:1px solid rgba(255,255,255,0.08);background:rgba(255,255,255,0.03);color:var(--text)}
.control-select{max-width:220px}
.list-table-panel{padding:22px 22px 16px;border-radius:26px;background:linear-gradient(180deg,rgba(255,255,255,0.04),rgba(255,255,255,0.02));border:1px solid rgba(255,255,255,0.06)}
.table-header{display:flex;align-items:end;justify-content:space-between;gap:16px;margin-bottom:16px}
.table-header h3{margin:0;font-size:1.45rem}
.table-hint{max-width:320px;line-height:1.6;text-align:right}
table.levels-table{border-radius:18px;overflow:hidden}
table.levels-table th{background:rgba(255,255,255,0.03)}
table.levels-table td{font-size:.98rem}
table.levels-table td:last-child{text-align:right}
table.levels-table .btn{padding:9px 14px}
.wip-hero{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(280px,.85fr);gap:22px;align-items:stretch;min-height:calc(100vh - 132px)}
.wip-copy,.wip-stage{position:relative}
.wip-copy{display:flex;flex-direction:column;justify-content:center;padding:32px;border-radius:26px;background:linear-gradient(145deg,rgba(255,184,77,0.1),rgba(7,19,38,0.96) 40%),radial-gradient(circle at top left,rgba(255,255,255,0.08),transparent 36%);border:1px solid rgba(255,184,77,0.16);overflow:hidden}
@@ -117,19 +142,27 @@ table.levels-table tr:hover td{background:rgba(255,255,255,0.01)}
/* small helpers reused */
.small{font-size:0.9rem}
.roulette-shell{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(280px,.75fr);gap:18px;align-items:start}
.roulette-rules{margin-bottom:18px}
.roulette-panel{margin-top:18px;padding:24px 26px;background:linear-gradient(135deg,rgba(92,197,255,0.12),rgba(7,19,38,0.96));border:1px solid rgba(92,197,255,0.16)}
.roulette-panel{margin-top:0;padding:28px;border-radius:28px;background:linear-gradient(135deg,rgba(92,197,255,0.14),rgba(7,19,38,0.96));border:1px solid rgba(92,197,255,0.18)}
.roulette-head{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin-bottom:18px}
.roulette-kicker{margin:0 0 8px 0;text-transform:uppercase;letter-spacing:0.14em;font-size:0.72rem;font-weight:700;color:var(--accent)}
.roulette-head h2{margin:0 0 8px 0;font-size:1.9rem}
.roulette-btn{min-width:110px;font-weight:700}
.roulette-card{padding:22px;border-radius:14px;background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.05)}
.roulette-head h2{margin:0 0 8px 0;font-size:clamp(2rem,4vw,3rem)}
.roulette-intro{max-width:50ch;line-height:1.7}
.roulette-btn{min-width:120px;font-weight:700}
.roulette-card{padding:24px;border-radius:22px;background:linear-gradient(180deg,rgba(255,255,255,0.08),rgba(255,255,255,0.03));border:1px solid rgba(255,255,255,0.08);box-shadow:0 20px 40px rgba(2,6,23,0.28)}
.roulette-status{margin:0 0 8px 0}
.roulette-card h3{margin:0 0 8px 0;font-size:1.5rem}
.roulette-rank{margin:0 0 16px 0;font-size:1rem;color:#dce8f5}
.roulette-card h3{margin:0 0 10px 0;font-size:clamp(1.6rem,3vw,2.3rem)}
.roulette-rank{margin:0 0 16px 0;font-size:1.02rem;color:#dce8f5}
.roulette-meta{margin:0 0 10px 0;font-size:1rem;color:#dce8f5}
.roulette-note{margin:10px 0 16px 0}
.roulette-open{color:#042}
.roulette-rules-card{padding:24px;border-radius:28px;background:linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.02));border:1px solid rgba(255,255,255,0.08)}
.roulette-rules-card h2{margin:0 0 16px 0;font-size:1.8rem}
.roulette-rule-list{display:grid;gap:14px}
.roulette-rule-list article{padding:16px;border-radius:18px;background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.06)}
.roulette-rule-list strong{display:block;margin-bottom:8px;font-size:1rem;color:#fff}
.roulette-rule-list p{margin:0;color:#dce8f5;line-height:1.6}
.discord-panel{display:flex;align-items:center;justify-content:space-between;gap:24px;margin-top:18px;padding:26px 28px;background:linear-gradient(135deg,rgba(88,101,242,0.18),rgba(7,19,38,0.95));border:1px solid rgba(88,101,242,0.22)}
.discord-copy{flex:1}
.discord-badge{display:flex;align-items:center;gap:16px;margin-bottom:14px}
@@ -181,7 +214,7 @@ linear-gradient(180deg,rgba(8,18,32,0.98),rgba(7,19,38,0.94))}
.status-card{display:block;padding:18px;border-radius:14px;background:linear-gradient(180deg,rgba(255,255,255,0.05),rgba(255,255,255,0.02));border:1px solid rgba(255,255,255,0.06);text-decoration:none;color:var(--text)}
.status-card strong{display:block;margin-bottom:6px;font-size:1.65rem}
.status-card span{display:block;color:var(--muted);line-height:1.5}
@media(max-width:900px){.layout{flex-direction:column}.sidebar{width:100%}.video-modal iframe{height:320px}.home-hero{grid-template-columns:1fr;min-height:auto}.home-copy,.hero-stage{padding:24px 22px}.hero-stats,.home-section-grid,.spotlight-grid{grid-template-columns:1fr}.spotlight-panel{grid-template-columns:1fr;padding:24px 22px}.roulette-head{flex-direction:column;align-items:flex-start}.discord-panel{flex-direction:column;align-items:flex-start;padding:22px 20px}.discord-panel h2{font-size:1.55rem}.discord-actions{width:100%;justify-content:flex-start}.rules-view header{padding:16px 18px}.rules-view header h1{font-size:1.55rem}.rules-page{padding:24px 20px}.rules-page h2{font-size:1.65rem}}
@media(max-width:900px){.layout{flex-direction:column}.sidebar{width:100%}.sidebar .panel{height:auto}.video-modal iframe{height:320px}.home-hero{grid-template-columns:1fr;min-height:auto}.home-copy,.hero-stage{padding:24px 22px}.hero-stats,.home-section-grid,.spotlight-grid{grid-template-columns:1fr}.spotlight-panel{grid-template-columns:1fr;padding:24px 22px}.list-hero-panel,.table-header,.search-row,.roulette-head{flex-direction:column;align-items:flex-start}.control-select{max-width:none;width:100%}.roulette-shell{grid-template-columns:1fr}.discord-panel{flex-direction:column;align-items:flex-start;padding:22px 20px}.discord-panel h2{font-size:1.55rem}.discord-actions{width:100%;justify-content:flex-start}.rules-view header{padding:16px 18px}.rules-view header h1{font-size:1.55rem}.rules-page{padding:24px 20px}.rules-page h2{font-size:1.65rem}}
@media(max-width:900px){.error-grid{grid-template-columns:1fr}.error-copy,.error-side{padding:24px 20px}.error-copy h2{font-size:2.5rem}}
@media(max-width:900px){.admin-toolbar{flex-direction:column;align-items:stretch}.admin-actions{flex-direction:column;align-items:stretch}.admin-actions input[type=text]{min-width:0;width:100%}}
@media(max-width:640px){header{flex-direction:column;align-items:flex-start;gap:12px}nav{display:flex;flex-wrap:wrap;gap:10px}nav a{margin-left:0}.home-copy h2{max-width:none}.hero-actions{flex-direction:column;align-items:stretch}.hero-actions .btn{width:100%;text-align:center}}
@media(max-width:640px){header{flex-direction:column;align-items:flex-start;gap:12px}nav{display:flex;flex-wrap:wrap;gap:10px}nav a{margin-left:0}.home-copy h2{max-width:none}.hero-actions{flex-direction:column;align-items:stretch}.hero-actions .btn,.roulette-btn{width:100%;text-align:center}.list-hero-panel,.list-controls-panel,.list-table-panel,.roulette-panel,.roulette-rules-card{padding:22px 18px}.table-hint{text-align:left}}