feat: group awesomelist by source list, add subcat headings, fix white flash
This commit is contained in:
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
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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', () => {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue