fix: subcategory accordion navigation, nav link white flash, collapsible sections
This commit is contained in:
parent
ad32ab3d63
commit
b7c20e732e
3 changed files with 66 additions and 12 deletions
|
|
@ -83,7 +83,7 @@
|
|||
},
|
||||
{
|
||||
"label": "RECON",
|
||||
"url": "/depot/recon"
|
||||
"url": "/recon"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -595,16 +595,34 @@
|
|||
|
||||
/* ─── Subcategory Group Headings (Awesomelist) ─────────── */
|
||||
.crt-subcat-group {
|
||||
margin-bottom: 1.5rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
.crt-subcat-heading {
|
||||
font-family: 'Orbitron', monospace;
|
||||
font-size: 0.75rem;
|
||||
color: rgba(255, 170, 0, 0.8);
|
||||
letter-spacing: 2px;
|
||||
padding: 0.6rem 0;
|
||||
padding: 0.6rem 0.8rem;
|
||||
border-bottom: 1px solid rgba(255, 170, 0, 0.15);
|
||||
margin-bottom: 0.5rem;
|
||||
margin-bottom: 0;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: background 0.2s, color 0.2s;
|
||||
}
|
||||
.crt-subcat-heading:hover {
|
||||
background: rgba(255, 170, 0, 0.06);
|
||||
color: rgba(255, 170, 0, 1);
|
||||
}
|
||||
.crt-subcat-heading.expanded {
|
||||
background: rgba(255, 170, 0, 0.08);
|
||||
border-bottom-color: rgba(255, 170, 0, 0.3);
|
||||
}
|
||||
.crt-subcat-arrow {
|
||||
display: inline-block;
|
||||
width: 1rem;
|
||||
font-size: 0.7rem;
|
||||
color: rgba(255, 170, 0, 0.6);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
.crt-subcat-count {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
|
|
@ -612,3 +630,8 @@
|
|||
color: #666;
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
.crt-subcat-entries {
|
||||
padding-left: 0.5rem;
|
||||
border-left: 1px solid rgba(255, 170, 0, 0.1);
|
||||
margin-left: 0.4rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@
|
|||
// ─── Render: Sector Detail ───────────────────────────
|
||||
function renderSector(sec) {
|
||||
state.view = 'detail';
|
||||
state.currentSector = sec;
|
||||
let html = '';
|
||||
|
||||
// Back button
|
||||
|
|
@ -203,7 +204,9 @@
|
|||
// ─── Event Bindings: Index ───────────────────────────
|
||||
function bindIndexEvents() {
|
||||
document.querySelectorAll('.crt-card').forEach(card => {
|
||||
card.addEventListener('click', () => {
|
||||
card.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
loadSector(card.dataset.slug);
|
||||
});
|
||||
});
|
||||
|
|
@ -232,13 +235,18 @@
|
|||
// ─── Event Bindings: Detail ──────────────────────────
|
||||
function bindDetailEvents(sec) {
|
||||
// Back button
|
||||
document.getElementById('crtBack').addEventListener('click', () => {
|
||||
document.getElementById('crtBack').addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
loadIndex();
|
||||
});
|
||||
|
||||
// List card clicks — show all subcategories and entries for that source list
|
||||
document.querySelectorAll('.crt-sub-card').forEach(card => {
|
||||
card.addEventListener('click', () => {
|
||||
card.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const idx = parseInt(card.dataset.listIdx);
|
||||
const lst = sec.lists[idx];
|
||||
const panel = document.getElementById('crtSubDetail');
|
||||
|
|
@ -262,9 +270,10 @@
|
|||
notesEl.innerHTML = '';
|
||||
notesEl.style.display = 'none';
|
||||
|
||||
// Build entries grouped by subcategory
|
||||
// Build entries grouped by subcategory with collapsible headings
|
||||
let eh = '';
|
||||
for (const sub of lst.subcategories) {
|
||||
for (let si = 0; si < lst.subcategories.length; si++) {
|
||||
const sub = lst.subcategories[si];
|
||||
if (sub.entries.length === 0) continue;
|
||||
// Strip the source prefix from subcategory name if it starts with list name
|
||||
let subName = sub.name;
|
||||
|
|
@ -274,13 +283,35 @@
|
|||
}
|
||||
if (subName === lst.name) subName = 'General';
|
||||
|
||||
eh += `<div class="crt-subcat-group">`;
|
||||
eh += `<div class="crt-subcat-heading">${esc(subName)} <span class="crt-subcat-count">${sub.entries.length}</span></div>`;
|
||||
eh += `<div class="crt-subcat-group" data-subcat-idx="${si}">`;
|
||||
eh += `<div class="crt-subcat-heading" data-subcat-toggle="${si}"><span class="crt-subcat-arrow">▸</span> ${esc(subName)} <span class="crt-subcat-count">${sub.entries.length}</span></div>`;
|
||||
eh += `<div class="crt-subcat-entries" data-subcat-body="${si}" style="display:none">`;
|
||||
for (const entry of sub.entries) eh += renderEntry(entry);
|
||||
eh += `</div>`;
|
||||
eh += `</div>`;
|
||||
}
|
||||
entriesEl.innerHTML = eh;
|
||||
|
||||
// Bind subcategory toggle clicks
|
||||
entriesEl.querySelectorAll('.crt-subcat-heading').forEach(heading => {
|
||||
heading.addEventListener('click', (ev) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
const toggleIdx = heading.dataset.subcatToggle;
|
||||
const body = entriesEl.querySelector(`[data-subcat-body="${toggleIdx}"]`);
|
||||
const arrow = heading.querySelector('.crt-subcat-arrow');
|
||||
if (body.style.display === 'none') {
|
||||
body.style.display = '';
|
||||
if (arrow) arrow.textContent = '▾';
|
||||
heading.classList.add('expanded');
|
||||
} else {
|
||||
body.style.display = 'none';
|
||||
if (arrow) arrow.textContent = '▸';
|
||||
heading.classList.remove('expanded');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
panel.style.display = '';
|
||||
panel.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
});
|
||||
|
|
@ -320,7 +351,7 @@
|
|||
try {
|
||||
const data = await api(`/${slug}`);
|
||||
renderSector(data);
|
||||
history.pushState({ view: 'detail', slug }, '', `/recon?sector=${slug}`);
|
||||
history.pushState({ view: 'detail', slug: slug }, '', `/recon?sector=${slug}`);
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
} catch (e) {
|
||||
root.innerHTML = `<div class="crt-empty">SECTOR NOT FOUND // ${esc(e.message)}</div>`;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue