← back to Wallpaperdefinitions
add sort + density controls to definitions grid (Curated/A-Z/Z-A/Category + 1-3 col slider, localStorage-persisted)
ae7164e9b822beea09d564992b139ee366affcba · 2026-05-30 21:08:17 -0700 · SteveStudio2
Files touched
Diff
commit ae7164e9b822beea09d564992b139ee366affcba
Author: SteveStudio2 <stevestudio2@SteveStacStudio.lan>
Date: Sat May 30 21:08:17 2026 -0700
add sort + density controls to definitions grid (Curated/A-Z/Z-A/Category + 1-3 col slider, localStorage-persisted)
---
public/index.html | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 113 insertions(+), 4 deletions(-)
diff --git a/public/index.html b/public/index.html
index 570cf16..eafb7f0 100644
--- a/public/index.html
+++ b/public/index.html
@@ -164,19 +164,48 @@ body {
}
.intro-text { font-size: 1.05rem; color: var(--ink-soft); max-width: 680px; line-height: 1.85; }
+/* ===== DEFINITION CONTROLS (sort + density) ===== */
+.def-controls {
+ display: flex; flex-wrap: wrap; align-items: center; gap: 1.5rem;
+ margin: 0 0 2rem; padding: 1rem 1.2rem;
+ background: var(--card-bg);
+ border: 1px solid var(--line);
+ border-radius: 10px;
+}
+.def-control { display: flex; align-items: center; gap: 0.6rem; }
+.def-control label {
+ font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase;
+ color: var(--ink-faint); white-space: nowrap;
+}
+.def-control select {
+ background: var(--bg); color: var(--ink);
+ border: 1px solid var(--line); border-radius: 6px;
+ padding: 0.45rem 0.7rem; font-size: 0.85rem;
+ font-family: inherit; cursor: pointer;
+}
+.def-control select:focus { outline: none; border-color: var(--accent); }
+.def-control.density { flex: 1; min-width: 180px; }
+.def-control.density input[type="range"] {
+ flex: 1; accent-color: var(--accent); cursor: pointer; min-width: 90px;
+}
+
/* ===== CARD STACK (scroll-snap) ===== */
.card-stack {
display: grid;
- grid-template-columns: 1fr;
- gap: 0;
+ grid-template-columns: repeat(var(--cols, 1), minmax(0, 1fr));
+ gap: 1rem;
+ align-items: start;
}
+.card-stack .image-break { grid-column: 1 / -1; margin: 1.5rem 0; }
+/* multi-column: collapse each card's inner term|body layout to a single column */
+.card-stack.cols-multi .def-card { grid-template-columns: 1fr; gap: 0.7rem; padding: 1.5rem 1.6rem; }
.def-card {
scroll-snap-align: start;
background: var(--card-bg);
border: 1px solid var(--line);
border-radius: 12px;
padding: 2rem 2.2rem;
- margin-bottom: 1rem;
+ margin-bottom: 0;
backdrop-filter: blur(20px) saturate(180%);
-webkit-backdrop-filter: blur(20px) saturate(180%);
transition: transform 0.25s, box-shadow 0.25s, border-color 0.25s;
@@ -259,6 +288,8 @@ body {
@media (max-width: 680px) {
.header-nav { display: none; }
.def-card { grid-template-columns: 1fr; }
+ .card-stack { --cols: 1 !important; }
+ .def-controls { gap: 1rem; }
.hero h1 { font-size: 2.2rem; }
}
</style>
@@ -392,7 +423,24 @@ body {
<p class="section-label">20 Core Concepts</p>
<h2>What does it mean?</h2>
- <div class="card-stack">
+ <div class="def-controls">
+ <div class="def-control">
+ <label for="defSort">Sort</label>
+ <select id="defSort" aria-label="Sort definitions">
+ <option value="curated">Curated</option>
+ <option value="az">Term A→Z</option>
+ <option value="za">Term Z→A</option>
+ <option value="category">Category</option>
+ </select>
+ </div>
+ <div class="def-control density">
+ <label for="defDensity">Density</label>
+ <input type="range" id="defDensity" min="1" max="3" step="1" value="1"
+ aria-label="Grid density (columns)">
+ </div>
+ </div>
+
+ <div class="card-stack" id="cardStack">
<div class="def-card">
<div class="def-term">Non-Woven</div>
@@ -604,6 +652,67 @@ toggle.addEventListener('click', () => {
applyTheme(current === 'dark' ? 'light' : 'dark');
});
</script>
+<!-- Definition grid: sort + density controls (Steve standing rule) -->
+<script>
+(function(){
+ var stack = document.getElementById('cardStack');
+ var sortSel = document.getElementById('defSort');
+ var densInput = document.getElementById('defDensity');
+ if (!stack || !sortSel || !densInput) return;
+
+ // Snapshot original DOM order once (def-cards + narrative image-breaks).
+ var original = Array.prototype.slice.call(stack.children);
+ var cards = original.filter(function(el){ return el.classList.contains('def-card'); });
+ var breaks = original.filter(function(el){ return el.classList.contains('image-break'); });
+
+ function termOf(el){ var t = el.querySelector('.def-term'); return t ? t.textContent.trim().toLowerCase() : ''; }
+ function catOf(el){ var t = el.querySelector('.def-tag'); return t ? t.textContent.trim().toLowerCase() : ''; }
+
+ function applySort(mode){
+ if (mode === 'curated') {
+ // Restore full original order, including the narrative image-breaks.
+ original.forEach(function(el){
+ if (el.classList.contains('image-break')) el.style.display = '';
+ stack.appendChild(el);
+ });
+ return;
+ }
+ // Reordered views: hide the narrative image-breaks (they only make sense in curated flow).
+ breaks.forEach(function(el){ el.style.display = 'none'; });
+ var sorted = cards.slice();
+ if (mode === 'az') sorted.sort(function(a,b){ return termOf(a).localeCompare(termOf(b)); });
+ else if (mode === 'za') sorted.sort(function(a,b){ return termOf(b).localeCompare(termOf(a)); });
+ else if (mode === 'category') sorted.sort(function(a,b){
+ var c = catOf(a).localeCompare(catOf(b));
+ return c !== 0 ? c : termOf(a).localeCompare(termOf(b));
+ });
+ sorted.forEach(function(el){ stack.appendChild(el); });
+ }
+
+ function applyDensity(n){
+ n = Math.max(1, Math.min(3, parseInt(n, 10) || 1));
+ stack.style.setProperty('--cols', n);
+ stack.classList.toggle('cols-multi', n > 1);
+ }
+
+ sortSel.addEventListener('change', function(){
+ applySort(sortSel.value);
+ try { localStorage.setItem('wpd-sort', sortSel.value); } catch(e){}
+ });
+ densInput.addEventListener('input', function(){
+ applyDensity(densInput.value);
+ try { localStorage.setItem('wpd-density', densInput.value); } catch(e){}
+ });
+
+ // Restore persisted choices (survive reload — standing rule).
+ var savedSort = null, savedDens = null;
+ try { savedSort = localStorage.getItem('wpd-sort'); savedDens = localStorage.getItem('wpd-density'); } catch(e){}
+ if (savedSort) sortSel.value = savedSort;
+ if (savedDens) densInput.value = savedDens;
+ applySort(sortSel.value);
+ applyDensity(densInput.value);
+})();
+</script>
<!-- DW-HAMBURGER-NAV v1 (canonical 2026-05-10) -->
<style id="dw-hamburger-styles">
/* Canonical hamburger nav — always visible top-right, all viewports.
← 0fff334 add .deploy.conf for Kamatera deploy (port 9901, /health)
·
back to Wallpaperdefinitions
·
Remove Big Red widget — never UX-worked, collided with Help fc91905 →