feat: group awesomelist by source list, add subcat headings, fix white flash

This commit is contained in:
jae 2026-04-04 03:28:08 +00:00
parent dd6423d9b5
commit ad32ab3d63
32 changed files with 115 additions and 91 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -10,7 +10,7 @@
"slug": "prp-001",
"entry_count": 25113,
"starred_count": 0,
"subcategory_count": 1609
"subcategory_count": 73
},
{
"code": "PRP-002",
@ -19,7 +19,7 @@
"slug": "prp-002",
"entry_count": 13343,
"starred_count": 0,
"subcategory_count": 947
"subcategory_count": 76
},
{
"code": "PRP-003",
@ -28,7 +28,7 @@
"slug": "prp-003",
"entry_count": 4525,
"starred_count": 0,
"subcategory_count": 333
"subcategory_count": 30
},
{
"code": "PRP-004",
@ -37,7 +37,7 @@
"slug": "prp-004",
"entry_count": 16336,
"starred_count": 0,
"subcategory_count": 1014
"subcategory_count": 53
},
{
"code": "PRP-005",
@ -46,7 +46,7 @@
"slug": "prp-005",
"entry_count": 8327,
"starred_count": 0,
"subcategory_count": 415
"subcategory_count": 40
},
{
"code": "PRP-006",
@ -55,7 +55,7 @@
"slug": "prp-006",
"entry_count": 2041,
"starred_count": 0,
"subcategory_count": 173
"subcategory_count": 15
},
{
"code": "PRP-007",
@ -64,7 +64,7 @@
"slug": "prp-007",
"entry_count": 8038,
"starred_count": 0,
"subcategory_count": 583
"subcategory_count": 24
},
{
"code": "PRP-008",
@ -73,7 +73,7 @@
"slug": "prp-008",
"entry_count": 6242,
"starred_count": 0,
"subcategory_count": 479
"subcategory_count": 24
},
{
"code": "PRP-009",
@ -82,7 +82,7 @@
"slug": "prp-009",
"entry_count": 3252,
"starred_count": 0,
"subcategory_count": 359
"subcategory_count": 24
},
{
"code": "PRP-010",
@ -91,7 +91,7 @@
"slug": "prp-010",
"entry_count": 1283,
"starred_count": 0,
"subcategory_count": 166
"subcategory_count": 14
},
{
"code": "PRP-011",
@ -100,7 +100,7 @@
"slug": "prp-011",
"entry_count": 705,
"starred_count": 0,
"subcategory_count": 74
"subcategory_count": 10
},
{
"code": "PRP-012",
@ -109,7 +109,7 @@
"slug": "prp-012",
"entry_count": 1419,
"starred_count": 0,
"subcategory_count": 138
"subcategory_count": 10
},
{
"code": "PRP-013",
@ -118,7 +118,7 @@
"slug": "prp-013",
"entry_count": 2044,
"starred_count": 0,
"subcategory_count": 118
"subcategory_count": 9
},
{
"code": "PRP-014",
@ -127,7 +127,7 @@
"slug": "prp-014",
"entry_count": 1913,
"starred_count": 0,
"subcategory_count": 149
"subcategory_count": 16
},
{
"code": "PRP-015",
@ -136,7 +136,7 @@
"slug": "prp-015",
"entry_count": 1127,
"starred_count": 0,
"subcategory_count": 87
"subcategory_count": 10
},
{
"code": "PRP-016",
@ -145,7 +145,7 @@
"slug": "prp-016",
"entry_count": 1119,
"starred_count": 0,
"subcategory_count": 112
"subcategory_count": 9
},
{
"code": "PRP-017",
@ -154,7 +154,7 @@
"slug": "prp-017",
"entry_count": 1456,
"starred_count": 0,
"subcategory_count": 80
"subcategory_count": 9
},
{
"code": "PRP-018",
@ -163,7 +163,7 @@
"slug": "prp-018",
"entry_count": 819,
"starred_count": 0,
"subcategory_count": 112
"subcategory_count": 8
},
{
"code": "PRP-019",
@ -172,7 +172,7 @@
"slug": "prp-019",
"entry_count": 3172,
"starred_count": 0,
"subcategory_count": 157
"subcategory_count": 10
},
{
"code": "PRP-020",
@ -181,7 +181,7 @@
"slug": "prp-020",
"entry_count": 1216,
"starred_count": 0,
"subcategory_count": 60
"subcategory_count": 7
},
{
"code": "PRP-021",
@ -190,7 +190,7 @@
"slug": "prp-021",
"entry_count": 1865,
"starred_count": 0,
"subcategory_count": 145
"subcategory_count": 6
},
{
"code": "PRP-022",
@ -199,7 +199,7 @@
"slug": "prp-022",
"entry_count": 966,
"starred_count": 0,
"subcategory_count": 73
"subcategory_count": 5
},
{
"code": "PRP-023",
@ -208,7 +208,7 @@
"slug": "prp-023",
"entry_count": 893,
"starred_count": 0,
"subcategory_count": 70
"subcategory_count": 4
},
{
"code": "PRP-024",
@ -217,7 +217,7 @@
"slug": "prp-024",
"entry_count": 1989,
"starred_count": 0,
"subcategory_count": 290
"subcategory_count": 6
},
{
"code": "PRP-025",
@ -226,7 +226,7 @@
"slug": "prp-025",
"entry_count": 81,
"starred_count": 0,
"subcategory_count": 19
"subcategory_count": 3
},
{
"code": "PRP-026",
@ -235,7 +235,7 @@
"slug": "prp-026",
"entry_count": 546,
"starred_count": 0,
"subcategory_count": 50
"subcategory_count": 4
},
{
"code": "PRP-027",
@ -244,7 +244,7 @@
"slug": "prp-027",
"entry_count": 121,
"starred_count": 0,
"subcategory_count": 18
"subcategory_count": 2
},
{
"code": "PRP-099",
@ -253,7 +253,8 @@
"slug": "prp-099",
"entry_count": 25228,
"starred_count": 0,
"subcategory_count": 2579
"subcategory_count": 154
}
]
],
"total_lists": 655
}

View file

@ -592,3 +592,23 @@
gap: 0.4rem;
}
}
/* ─── Subcategory Group Headings (Awesomelist) ─────────── */
.crt-subcat-group {
margin-bottom: 1.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;
border-bottom: 1px solid rgba(255, 170, 0, 0.15);
margin-bottom: 0.5rem;
}
.crt-subcat-count {
font-family: 'JetBrains Mono', monospace;
font-size: 0.65rem;
color: #666;
margin-left: 0.5rem;
}

View file

@ -1,5 +1,5 @@
/*
RECON // Curated Lists Controller (flattened)
RECON // Curated Lists Controller (grouped by source)
*/
(function () {
'use strict';
@ -73,7 +73,7 @@
<div class="crt-card-name">${esc(sec.name)}</div>
<div class="crt-card-meta">
<span class="crt-card-count">${fmt(sec.entry_count)} assets</span>
<span class="crt-card-stars">${sec.subcategory_count} sections</span>
<span class="crt-card-stars">${sec.subcategory_count} lists</span>
</div>
<div class="crt-card-status"> ACCESSIBLE</div>
</div>`;
@ -98,7 +98,7 @@
<div class="crt-detail-title">${esc(sec.icon)} ${esc(sec.name)}</div>
<div class="crt-detail-meta">
<span>${fmt(sec.total_entries)} ASSETS</span>
<span>${sec.subcategory_count} SECTIONS</span>
<span>${sec.list_count} LISTS</span>
</div>
</div>`;
@ -108,15 +108,16 @@
<input type="text" class="crt-search-input" id="crtCatSearch" placeholder="FILTER THIS SECTOR..." autocomplete="off">
</div>`;
// Subcategory grid (3-col cards)
// List cards (one per source list)
html += `<div class="crt-sub-grid" id="crtSubGrid">`;
for (let i = 0; i < sec.subcategories.length; i++) {
const sub = sec.subcategories[i];
if (sub.entries.length === 0) continue;
html += `<div class="crt-sub-card" data-sub-idx="${i}">
<div class="crt-sub-card-name">${esc(sub.name)}</div>
for (let i = 0; i < sec.lists.length; i++) {
const lst = sec.lists[i];
if (lst.total_entries === 0) continue;
html += `<div class="crt-sub-card" data-list-idx="${i}">
<div class="crt-sub-card-name">${esc(lst.name)}</div>
<div class="crt-sub-card-stats">
<span>${sub.entries.length} items</span>
<span>${lst.total_entries} items</span>
<span>${lst.subcategories.length} sections</span>
</div>
</div>`;
}
@ -201,15 +202,12 @@
// ─── Event Bindings: Index ───────────────────────────
function bindIndexEvents() {
// Card clicks
document.querySelectorAll('.crt-card').forEach(card => {
card.addEventListener('click', () => {
const slug = card.dataset.slug;
loadSector(slug);
loadSector(card.dataset.slug);
});
});
// Global search
const searchInput = document.getElementById('crtSearch');
if (searchInput) {
searchInput.addEventListener('input', () => {
@ -238,17 +236,16 @@
loadIndex();
});
// Subcategory card clicks
// List card clicks — show all subcategories and entries for that source list
document.querySelectorAll('.crt-sub-card').forEach(card => {
card.addEventListener('click', () => {
const idx = parseInt(card.dataset.subIdx);
const sub = sec.subcategories[idx];
const idx = parseInt(card.dataset.listIdx);
const lst = sec.lists[idx];
const panel = document.getElementById('crtSubDetail');
const headerEl = document.getElementById('crtSubDetailHeader');
const notesEl = document.getElementById('crtSubDetailNotes');
const entriesEl = document.getElementById('crtSubDetailEntries');
// If clicking the already active card, collapse
const wasActive = card.classList.contains('active');
document.querySelectorAll('.crt-sub-card').forEach(c => c.classList.remove('active'));
@ -259,23 +256,29 @@
card.classList.add('active');
// Populate header
headerEl.innerHTML = `<span class="crt-sub-toggle">▾</span> <span class="crt-sub-detail-name">${esc(sub.name)}</span> <span class="crt-sub-count">${sub.entries.length} items</span>`;
// Header
headerEl.innerHTML = `<span class="crt-sub-toggle">▾</span> <span class="crt-sub-detail-name">${esc(lst.name)}</span> <span class="crt-sub-count">${lst.total_entries} items across ${lst.subcategories.length} sections</span>`;
// Populate notes
if (sub.notes && sub.notes.length > 0) {
let nh = '';
for (const note of sub.notes) nh += `${esc(note)}<br>`;
notesEl.innerHTML = nh;
notesEl.style.display = '';
} else {
notesEl.innerHTML = '';
notesEl.style.display = 'none';
}
notesEl.innerHTML = '';
notesEl.style.display = 'none';
// Populate entries
// Build entries grouped by subcategory
let eh = '';
for (const entry of sub.entries) eh += renderEntry(entry);
for (const sub of lst.subcategories) {
if (sub.entries.length === 0) continue;
// Strip the source prefix from subcategory name if it starts with list name
let subName = sub.name;
const prefix = lst.name + ' — ';
if (subName.startsWith(prefix)) {
subName = subName.slice(prefix.length);
}
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>`;
for (const entry of sub.entries) eh += renderEntry(entry);
eh += `</div>`;
}
entriesEl.innerHTML = eh;
panel.style.display = '';
@ -283,7 +286,7 @@
});
});
// Category search (local filter on subcategory cards)
// Local filter on list cards
const catSearch = document.getElementById('crtCatSearch');
if (catSearch) {
catSearch.addEventListener('input', () => {

View file

@ -10,7 +10,7 @@
<link rel="stylesheet" href="/css/section.css">
<link rel="stylesheet" href="/css/contraband.css">
</head>
<body>
<body style="background:#0a0a0c;">
<div class="scanline-overlay"></div>
<div class="grid-bg"></div>