fix: subcategory accordion navigation, nav link white flash, collapsible sections

This commit is contained in:
jae 2026-04-04 03:46:43 +00:00
parent ad32ab3d63
commit b7c20e732e
3 changed files with 66 additions and 12 deletions

View file

@ -83,7 +83,7 @@
},
{
"label": "RECON",
"url": "/depot/recon"
"url": "/recon"
}
]
},

View file

@ -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;
}

View file

@ -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>`;