put it on live
This commit is contained in:
@@ -0,0 +1,18 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 miles
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
|
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
||||||
|
following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||||
|
portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||||
|
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||||
|
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||||
|
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
// Lightweight multi-page handler for GD Demand List
|
||||||
|
(function(){
|
||||||
|
function qs(id){return document.getElementById(id)}
|
||||||
|
|
||||||
|
const page = document.body.dataset.page;
|
||||||
|
|
||||||
|
// Storage helpers
|
||||||
|
function read(key, fallback){
|
||||||
|
try{const v = localStorage.getItem(key); return v?JSON.parse(v):fallback}
|
||||||
|
catch(e){return fallback}
|
||||||
|
}
|
||||||
|
function write(key, val){localStorage.setItem(key,JSON.stringify(val))}
|
||||||
|
|
||||||
|
// Players page
|
||||||
|
if(page==='players'){
|
||||||
|
const form = qs('player-form'); const nameIn = qs('player-name'); const list = qs('players');
|
||||||
|
let players = read('gd_players',[]);
|
||||||
|
function render(){list.innerHTML=''; players.forEach((p,idx)=>{
|
||||||
|
const li=document.createElement('li'); li.innerHTML=`<span><span class="name">${escapeHtml(p.name)}</span> <span class="muted">(${p.id})</span></span>`;
|
||||||
|
const actions=document.createElement('div'); actions.className='actions';
|
||||||
|
const edit=document.createElement('button'); edit.textContent='Edit'; edit.onclick=()=>{const nv=prompt('Edit name',p.name); if(nv){players[idx].name=nv; write('gd_players',players); render()}};
|
||||||
|
const del=document.createElement('button'); del.textContent='Delete'; del.onclick=()=>{if(confirm('Delete player?')){players.splice(idx,1); write('gd_players',players); render()}};
|
||||||
|
actions.appendChild(edit); actions.appendChild(del); li.appendChild(actions); list.appendChild(li);
|
||||||
|
})}
|
||||||
|
form.addEventListener('submit',e=>{e.preventDefault(); const name=nameIn.value.trim(); if(!name) return; players.push({id:Date.now().toString(36),name}); write('gd_players',players); nameIn.value=''; render()});
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lists page
|
||||||
|
if(page==='lists'){
|
||||||
|
const levelsEl = qs('levels'); const listArea = qs('list-area'); const titleEl = qs('list-title');
|
||||||
|
// Load hard-coded data file data.txt (category|position|title|url per line)
|
||||||
|
function loadData(){
|
||||||
|
fetch('data.txt').then(r=>r.text()).then(txt=>{
|
||||||
|
const lines = txt.split(/\r?\n/).map(l=>l.trim()).filter(Boolean);
|
||||||
|
const items = lines.map(l=>{
|
||||||
|
const parts = l.split('|').map(p=>p.trim());
|
||||||
|
return {level:parts[0]||'Unknown',position:parts[1]||'',title:parts[2]||'Untitled',url:parts[3]||''};
|
||||||
|
});
|
||||||
|
setupLevels(items);
|
||||||
|
}).catch(err=>{listArea.innerHTML='<p class="muted">Failed to load data.txt — run via a local server.</p>'; console.error(err)});
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeCategories(items){
|
||||||
|
const max = items.reduce((m,it)=>Math.max(m, Number(it.position)||0), 0);
|
||||||
|
const cats = ['Full List'];
|
||||||
|
for(let i=1;i<=max;i+=10){
|
||||||
|
const start = i; const end = Math.min(i+9, max);
|
||||||
|
cats.push(`Top ${start}-${end}`);
|
||||||
|
}
|
||||||
|
return cats;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setupLevels(items){
|
||||||
|
const categories = computeCategories(items);
|
||||||
|
levelsEl.innerHTML='';
|
||||||
|
const filterSelect = qs('level-filter');
|
||||||
|
filterSelect.innerHTML = '<option value="all">Full List</option>';
|
||||||
|
categories.forEach(cat=>{
|
||||||
|
const li = document.createElement('li');
|
||||||
|
const btn = document.createElement('button');
|
||||||
|
btn.type = 'button';
|
||||||
|
btn.textContent = cat;
|
||||||
|
btn.className = 'level-link';
|
||||||
|
btn.addEventListener('click', ()=> {
|
||||||
|
selectLevel(cat, items, btn);
|
||||||
|
filterSelect.value = cat;
|
||||||
|
});
|
||||||
|
li.appendChild(btn);
|
||||||
|
levelsEl.appendChild(li);
|
||||||
|
|
||||||
|
const opt = document.createElement('option'); opt.value = cat; opt.textContent = cat; filterSelect.appendChild(opt);
|
||||||
|
});
|
||||||
|
// search and filter handlers
|
||||||
|
qs('search').addEventListener('input', ()=> renderTable(items));
|
||||||
|
filterSelect.addEventListener('change', ()=> renderTable(items));
|
||||||
|
// default select Full List
|
||||||
|
selectLevel('Full List', items, levelsEl.querySelector('.level-link'));
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectLevel(level, items, linkEl){
|
||||||
|
levelsEl.querySelectorAll('.level-link').forEach(a=>a.classList.remove('active'));
|
||||||
|
if(linkEl) linkEl.classList.add('active');
|
||||||
|
qs('level-filter').value = level;
|
||||||
|
renderTable(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderTable(items){
|
||||||
|
const q = (qs('search') && qs('search').value || '').toLowerCase();
|
||||||
|
const levelFilter = (qs('level-filter') && qs('level-filter').value) || 'all';
|
||||||
|
const filtered = items.filter(it=>{
|
||||||
|
// apply level / category filter (support range categories like "Top 1-10")
|
||||||
|
if(levelFilter && levelFilter!=='all' && levelFilter!=='Full List'){
|
||||||
|
const m = levelFilter.match(/Top\s*(\d+)-(\d+)/i);
|
||||||
|
if(m){
|
||||||
|
const s = Number(m[1]); const e = Number(m[2]); const pos = Number(it.position)||0;
|
||||||
|
if(pos < s || pos > e) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!q) return true;
|
||||||
|
return (it.title||'').toLowerCase().includes(q) || (it.level||'').toLowerCase().includes(q);
|
||||||
|
}).sort((a,b)=> (Number(a.position)||0)-(Number(b.position)||0));
|
||||||
|
|
||||||
|
const tbody = qs('list-area'); tbody.innerHTML='';
|
||||||
|
filtered.forEach(it=>{
|
||||||
|
const tr = document.createElement('tr');
|
||||||
|
const tdNum = document.createElement('td'); tdNum.textContent = it.position;
|
||||||
|
const tdTitle = document.createElement('td'); tdTitle.textContent = it.title;
|
||||||
|
const tdAct = document.createElement('td');
|
||||||
|
const a = document.createElement('a'); a.textContent='Open'; a.href='#'; a.className='btn';
|
||||||
|
a.addEventListener('click', (e)=>{e.preventDefault(); openVideo(it.url)});
|
||||||
|
tdAct.appendChild(a);
|
||||||
|
tr.appendChild(tdNum); tr.appendChild(tdTitle); tr.appendChild(tdAct);
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function openVideo(url){
|
||||||
|
if(!url) return; const id = extractYouTubeID(url);
|
||||||
|
if(!id){ window.open(url,'_blank'); return }
|
||||||
|
let modal = document.querySelector('.video-modal');
|
||||||
|
if(!modal){
|
||||||
|
modal = document.createElement('div'); modal.className='video-modal';
|
||||||
|
const inner = document.createElement('div'); inner.className='inner';
|
||||||
|
const close = document.createElement('button'); close.textContent='Close'; close.className='btn'; close.style.float='right'; close.onclick=()=>modal.remove();
|
||||||
|
inner.appendChild(close);
|
||||||
|
const iframe = document.createElement('iframe'); iframe.allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture'; iframe.allowFullscreen=true;
|
||||||
|
inner.appendChild(iframe); modal.appendChild(inner); document.body.appendChild(modal);
|
||||||
|
}
|
||||||
|
modal.querySelector('iframe').src = `https://www.youtube.com/embed/${id}`;
|
||||||
|
modal.style.display = 'flex';
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractYouTubeID(url){
|
||||||
|
const m = url.match(/(?:v=|\/embed\/|youtu\.be\/)([A-Za-z0-9_-]{6,})/); return m?m[1]:'';
|
||||||
|
}
|
||||||
|
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility
|
||||||
|
function escapeHtml(s){return String(s).replace(/[&<>"']/g, c=>({"&":"&","<":"<",">":">","\"":""","'":"'"})[c])}
|
||||||
|
})();
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
new|1|Flamewall|https://youtu.be/x4Io4zkWVRw?si=tf0DBaWahOPPEWxO
|
||||||
|
new|2|Thinking Space II|https://youtu.be/CELNmHwln_c?si=soP6SzRn92G1vKbl
|
||||||
|
new|4|Amethyst|https://youtu.be/4lfkzz1VCbA?si=6NNeWiH-nnwu21Cb
|
||||||
|
new|3|Tidal Wave|https://youtu.be/9fsZ014qB3s?si=oj4E4ceyNtRVcDvd
|
||||||
|
new|5|Orbit|https://youtu.be/QKcv8DkNPd0?si=cKBFqp7GRqmfupgJ
|
||||||
|
new|6|BOOBAWAMBA|https://youtu.be/20fYiqLAo_E?si=QSSixz31rWeeQ_8B
|
||||||
|
new|7|Nullscapes|https://youtu.be/EztneTPp5CU?si=ljn-S_bnGYwOoUyV
|
||||||
|
new|8|Quantuese Processing|https://youtu.be/j5NC0u1Q91Q?si=FvUEY2kdDtNMqWSD
|
||||||
|
new|9|Subsuming Vortex|https://youtu.be/0eYG1ogJpIQ?si=7XRxfDsmMVb0G9Si
|
||||||
|
new|10|Andromeda|https://youtu.be/mk3TDemdkC0?si=va13_RKAJUyFvhcv
|
||||||
|
new|11|Every End|https://youtu.be/AO--mVVFtKI?si=gIT5vxyc1FZ4_8Jj
|
||||||
|
new|12|Silent Clubstep|https://youtu.be/GR4OMkS3SN8?si=CMNz8bPBaUU94wiy
|
||||||
|
new|13|Anathema|https://youtu.be/_uKwmjHmySI?si=PgXwX7Z--wCay34b
|
||||||
|
new|14|Acheron|https://youtu.be/sBKR6aUorzA?si=0A9S2_W8gi1awZ81
|
||||||
|
new|15|Ashley Wave Trials|https://youtu.be/aTxt76U3e2Q?si=RVcEcOTOfs7NGWRi
|
||||||
|
new|16|Avernus|https://youtu.be/16Zh8jssanc?si=0o6d2dH4p_J7UjKB
|
||||||
|
new|17|Menace|https://youtu.be/nnkgghxxsEE?si=OuUQfD7WbXVooYyX
|
||||||
|
new|18|Spectre|https://youtu.be/MzsSLKJrLSI?si=-bXtr_jG96kTCzy4
|
||||||
|
new|19|Abyss Of Darkness|https://youtu.be/ejJkpqcMMCY?si=Rpp4HEi1kOMh-p0h
|
||||||
|
new|20|Defeated Circles|https://youtu.be/nU5AQPzd2YA?si=6eKDMPh-2QjDBBOF
|
||||||
|
new|21|Tunnel Of Despair|https://youtu.be/LpS4JREhW98?si=Z6_DRV5YZTEA0TeQ
|
||||||
|
new|22|Subterminal Point|https://youtu.be/h2wmRMgACH4?si=nDD0-bmLqPgcdVJP
|
||||||
|
new|23|KOCMOC|https://youtu.be/2CxE-UWCIG4?si=9xz4hBjtNKe8Rcbs
|
||||||
|
new|24|Slaughterhouse|https://youtu.be/kpcF1-QAHQc?si=7ybF9EbcjqHzloLM
|
||||||
|
new|25|Kyouki|https://youtu.be/KDa5c0CJTHs?si=WU0sPusFLB7Jtkam
|
||||||
|
new|26|The Lightning Rod|https://youtu.be/nQDTi077O6M?si=Kqp2Od3lJx1YWTDB
|
||||||
|
new|27|Based After Based|https://youtu.be/yQBFyUvB3lY?si=Cmxbc5jrTrNlcmG5
|
||||||
|
new|28|CHIL|https://youtu.be/DROMiCc2ZRM?si=_bR8CCnqJGVCex9F
|
||||||
|
new|29|Sakupen Circles|https://youtu.be/ofG2mJi9kEA?si=3yv78_jxidKPhtL5
|
||||||
|
new|30|Deimos (ItsHybrid)|https://youtu.be/b2yHaIk5zio?si=AMIuVFR-EW4CK8_P
|
||||||
|
new|31|Eyes In The Water|https://youtu.be/yvLwiOy3KEA?si=1991xs25WTEoTbE0
|
||||||
|
new|32|Voltage|https://youtu.be/wBRvBN9tmlc?si=GU2md9I7ZnUV7Rfr
|
||||||
|
new|33|Firework|https://youtu.be/QBe5x2o9v2w?si=dhPg9YcCRjwngxU9
|
||||||
|
new|34|Silentlocked|https://youtu.be/O-IQeUdEGvI?si=KeSHH6kwZoSVGINT
|
||||||
|
new|35|poocubed|https://youtu.be/fzL31vai1ms?si=9Gwk7RDtbEFxOJ6t
|
||||||
|
new|36|KOSETSU|https://youtu.be/hZ8vFX8z_BU?si=P6fFal0yazJbje2O
|
||||||
|
new|37|Through The Gates|https://youtu.be/4yHA6jux5UI?si=nstk3A6FDN3QR-qm
|
||||||
|
new|38|Saul Goodman|https://youtu.be/hjs5PjUaw9k?si=qJpGrru21d50gO5R
|
||||||
|
new|39|The Salt Factory|https://youtu.be/lQ7M-Sgov24?si=nXYVL0XGy5NOJLXn
|
||||||
|
new|40|Snowbound|https://youtu.be/cjHwgbtAkXU?si=ghJbRJCkN-m0zu60
|
||||||
|
new|41|CONVOLSION|https://youtu.be/qeRKuyU3eGI?si=UPaem0b3V8fX0L1r
|
||||||
|
new|42|The Apocalyptic Trilogy|https://youtu.be/RUBbpsTR5eU?si=mEsPtyMLrQgP5fWl
|
||||||
|
new|43|MINUSdry|https://youtu.be/YvA8ehhzz0Q?si=DT6DfrXOQ41swSIR
|
||||||
|
new|44|Sevvend Clubstep|https://youtu.be/TvA8EJTJFCc?si=Rm9HyExGYpeGn4qs
|
||||||
|
new|45|Edge Of Destiny|https://youtu.be/rUphe3H59yU?si=dZ8LgDyqif1ET_k1
|
||||||
|
new|46|The Halucination|https://youtu.be/tYbXsNkO9HE?si=b8hmXS98BAjDlPzF
|
||||||
|
new|47|CONVULSION|https://youtu.be/qeRKuyU3eGI?si=qJN026t6RcGjU3iW
|
||||||
|
new|48|Solar Flare|https://youtu.be/eHQNgty8ypY?si=ZdUIODdeDYLAXeHI
|
||||||
|
new|49|LIMBO|https://youtu.be/kXYMbaMVOZg?si=fWm4ngeSxBhFZadA
|
||||||
|
new|50|The Catacombs|https://youtu.be/T9-75lfKVQg?si=zEH6vP1617n5666I
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<title>GD Demand List</title>
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body data-page="index">
|
||||||
|
<header>
|
||||||
|
<h1>GD Demand List</h1>
|
||||||
|
<nav>
|
||||||
|
<a href="players.html">Players</a>
|
||||||
|
<a href="lists.html">Lists</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<section class="panel">
|
||||||
|
<h2>Welcome</h2>
|
||||||
|
<p class="small muted">Use the top navigation to view players or demand lists. This UI follows a compact table-first layout for quick browsing.</p>
|
||||||
|
</section>
|
||||||
|
<section class="layout">
|
||||||
|
<div class="panel" style="flex:1">
|
||||||
|
<h3>Quick Links</h3>
|
||||||
|
<a class="btn" href="lists.html">View Lists</a>
|
||||||
|
<a class="btn" href="players.html" style="margin-left:8px">Players</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<script src="app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<title>Lists — GD Demand List</title>
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body data-page="lists">
|
||||||
|
<header>
|
||||||
|
<h1>Demand Lists</h1>
|
||||||
|
<nav>
|
||||||
|
<a href="index.html">Home</a>
|
||||||
|
<a href="players.html">Players</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main class="layout">
|
||||||
|
<aside class="sidebar">
|
||||||
|
<div class="panel">
|
||||||
|
<h2>Levels</h2>
|
||||||
|
<ul id="levels"></ul>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<section class="panel content">
|
||||||
|
<div class="search-row">
|
||||||
|
<h2 id="list-title">All Videos</h2>
|
||||||
|
<input id="search" type="text" placeholder="Search videos or titles..." />
|
||||||
|
<select id="level-filter"><option value="all">All Levels</option></select>
|
||||||
|
</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>
|
||||||
|
</main>
|
||||||
|
<script src="app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||||
|
<title>Players — GD Demand List</title>
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body data-page="players">
|
||||||
|
<header>
|
||||||
|
<h1>Players</h1>
|
||||||
|
<nav>
|
||||||
|
<a href="index.html">Home</a>
|
||||||
|
<a href="lists.html">Lists</a>
|
||||||
|
</nav>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<section class="panel">
|
||||||
|
<h2>Add Player</h2>
|
||||||
|
<form id="player-form" style="display:flex;gap:8px">
|
||||||
|
<input id="player-name" placeholder="Player name" required />
|
||||||
|
<button class="btn" type="submit">Add</button>
|
||||||
|
</form>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="panel">
|
||||||
|
<h2>Players</h2>
|
||||||
|
<ul id="players"></ul>
|
||||||
|
</section>
|
||||||
|
</main>
|
||||||
|
<script src="app.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
:root{--bg:#0f1724;--panel:#071326;--accent:#5cc5ff;--muted:#9fb3c8;--text:#e6eef8;--card:#081220}
|
||||||
|
*{box-sizing:border-box}
|
||||||
|
html,body{height:100%;margin:0;font-family:Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,"Helvetica Neue",Arial;color:var(--text);background:linear-gradient(180deg,#061021 0%,#071426 100%)}
|
||||||
|
header{display:flex;align-items:center;justify-content:space-between;padding:14px 20px;background:linear-gradient(90deg,rgba(255,255,255,0.02),transparent);backdrop-filter:blur(4px)}
|
||||||
|
header h1{margin:0;font-size:1.1rem}
|
||||||
|
nav a{color:var(--muted);margin-left:14px;text-decoration:none}
|
||||||
|
main{padding:18px 20px}
|
||||||
|
.layout{display:flex;gap:16px;align-items:flex-start}
|
||||||
|
.sidebar{width:220px}
|
||||||
|
.sidebar .panel{padding:12px;height:calc(100vh - 120px);overflow:auto}
|
||||||
|
.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}
|
||||||
|
.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 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}
|
||||||
|
table.levels-table{width:100%;border-collapse:collapse;background:linear-gradient(180deg,rgba(255,255,255,0.012),transparent)}
|
||||||
|
table.levels-table th,table.levels-table td{padding:12px 14px;border-bottom:1px solid rgba(255,255,255,0.02);text-align:left}
|
||||||
|
table.levels-table th{color:var(--muted);font-size:0.85rem;font-weight:600}
|
||||||
|
table.levels-table tr:hover td{background:rgba(255,255,255,0.01)}
|
||||||
|
.btn{display:inline-block;padding:8px 10px;border-radius:8px;background:var(--accent);color:#042;cursor:pointer;border:none}
|
||||||
|
.muted{color:var(--muted);font-size:0.9rem}
|
||||||
|
.video-modal{position:fixed;inset:0;background:rgba(0,0,0,0.7);display:flex;align-items:center;justify-content:center;z-index:1200}
|
||||||
|
.video-modal .inner{width:90%;max-width:960px;background:var(--card);padding:12px;border-radius:8px}
|
||||||
|
.video-modal iframe{width:100%;height:540px;border:0;border-radius:6px}
|
||||||
|
@media(max-width:900px){.layout{flex-direction:column}.sidebar{width:100%}.video-modal iframe{height:320px}}
|
||||||
|
|
||||||
|
/* small helpers reused */
|
||||||
|
.small{font-size:0.9rem}
|
||||||
Reference in New Issue
Block a user