Skip to content

Commit 45680b0

Browse files
Add chip counts, focus glow, and Clear button to catalog filter
Categorical pills now show per-category card counts, the active state is more visible (stronger background + inset ring), the search input gets a teal focus halo with a more inviting placeholder, the result count turns teal when filtering, and a Clear button appears beside the count to reset all filters in one click. Also adds an inline SVG favicon to silence the favicon.ico 404. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1b39920 commit 45680b0

1 file changed

Lines changed: 116 additions & 11 deletions

File tree

index.html

Lines changed: 116 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Crypto Lab — Paul Clark / systemslibrarian</title>
77
<meta name="description" content="A curated cryptography lab — from fundamentals to cutting-edge research" />
8+
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' rx='6' fill='%23162b2a'/%3E%3Ctext x='16' y='22' font-family='monospace' font-size='14' font-weight='700' text-anchor='middle' fill='%234dcfb0'%3ECL%3C/text%3E%3C/svg%3E" />
89
<link rel="preconnect" href="https://fonts.googleapis.com" />
910
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
1011
<link href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@300;400;500&family=Fraunces:opsz,wght,SOFT@9..144,400,50;9..144,500,50&display=swap" rel="stylesheet" />
@@ -385,14 +386,14 @@
385386

386387
.search-bar input {
387388
width: 100%;
388-
padding: 14px 18px 14px 44px;
389+
padding: 14px 50px 14px 44px;
389390
font-family: var(--mono);
390391
font-size: 13px;
391392
color: var(--text-hi);
392393
background: rgba(9, 18, 24, 0.9);
393394
border: 1px solid var(--border-strong);
394395
outline: none;
395-
transition: border-color 0.2s ease;
396+
transition: border-color 0.2s ease, box-shadow 0.2s ease;
396397
}
397398

398399
.search-bar input::placeholder {
@@ -402,6 +403,7 @@
402403

403404
.search-bar input:focus {
404405
border-color: var(--teal);
406+
box-shadow: 0 0 0 3px rgba(53, 214, 187, 0.15);
405407
}
406408

407409
.search-bar::before {
@@ -494,6 +496,9 @@
494496
}
495497

496498
.filter-chip {
499+
display: inline-flex;
500+
align-items: center;
501+
gap: 7px;
497502
padding: 6px 10px;
498503
min-height: 30px;
499504
border: 1px solid var(--border-strong);
@@ -504,26 +509,77 @@
504509
font-family: var(--mono);
505510
background: rgba(8, 17, 24, 0.78);
506511
cursor: pointer;
507-
transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease;
512+
transition: border-color 0.2s ease, color 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
513+
}
514+
515+
.filter-chip .chip-count {
516+
color: var(--text-dim);
517+
opacity: 0.65;
518+
font-variant-numeric: tabular-nums;
519+
letter-spacing: 0.04em;
520+
transition: color 0.2s ease, opacity 0.2s ease;
508521
}
509522

510523
.filter-chip:hover {
511-
border-color: rgba(242, 248, 251, 0.3);
524+
border-color: rgba(53, 214, 187, 0.45);
525+
color: var(--text);
526+
background: rgba(53, 214, 187, 0.04);
527+
}
528+
529+
.filter-chip:hover .chip-count {
512530
color: var(--text);
531+
opacity: 0.9;
513532
}
514533

515534
.filter-chip.active {
516535
border-color: var(--teal);
517536
color: var(--teal);
518-
background: rgba(53, 214, 187, 0.08);
537+
background: rgba(53, 214, 187, 0.16);
538+
box-shadow: inset 0 0 0 1px rgba(53, 214, 187, 0.4);
539+
}
540+
541+
.filter-chip.active .chip-count {
542+
color: var(--teal);
543+
opacity: 1;
519544
}
520545

521546
.card-count {
547+
display: inline-flex;
548+
align-items: center;
549+
gap: 12px;
522550
color: var(--text-dim);
523551
font-size: 11px;
524552
letter-spacing: 0.06em;
525553
white-space: nowrap;
526554
padding-top: 4px;
555+
transition: color 0.2s ease;
556+
}
557+
558+
.card-count.filtered .card-count-text {
559+
color: var(--teal);
560+
}
561+
562+
.filter-clear {
563+
font-family: var(--mono);
564+
font-size: 10px;
565+
letter-spacing: 0.1em;
566+
text-transform: uppercase;
567+
color: var(--text-dim);
568+
background: transparent;
569+
border: 1px solid var(--border-strong);
570+
padding: 4px 9px;
571+
cursor: pointer;
572+
transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
573+
}
574+
575+
.filter-clear:hover {
576+
color: var(--text-hi);
577+
border-color: var(--teal);
578+
background: rgba(53, 214, 187, 0.10);
579+
}
580+
581+
.filter-clear[hidden] {
582+
display: none;
527583
}
528584

529585
.no-results {
@@ -958,7 +1014,17 @@
9581014
}
9591015

9601016
html.light .filter-chip.active {
961-
background: rgba(26, 171, 148, 0.08);
1017+
background: rgba(26, 171, 148, 0.16);
1018+
box-shadow: inset 0 0 0 1px rgba(26, 171, 148, 0.4);
1019+
}
1020+
1021+
html.light .filter-chip:hover {
1022+
border-color: rgba(26, 171, 148, 0.55);
1023+
background: rgba(26, 171, 148, 0.06);
1024+
}
1025+
1026+
html.light .search-bar input:focus {
1027+
box-shadow: 0 0 0 3px rgba(26, 171, 148, 0.18);
9621028
}
9631029

9641030
html.light .search-kbd {
@@ -1305,13 +1371,16 @@
13051371
<div class="wrap">
13061372
<div class="filter-bar" id="filter-bar">
13071373
<div class="search-bar">
1308-
<input type="text" id="demo-search" placeholder="Filter demos…" aria-label="Filter demos" />
1374+
<input type="text" id="demo-search" placeholder="Filter demos… try FROST, noise, or Shor" aria-label="Filter demos" />
13091375
<button class="search-clear" id="search-clear" aria-label="Clear search" hidden></button>
13101376
<kbd class="search-kbd" aria-hidden="true">/</kbd>
13111377
</div>
13121378
<div class="filter-row">
13131379
<div class="filter-chips" id="filter-chips"></div>
1314-
<div class="card-count" id="card-count"></div>
1380+
<div class="card-count" id="card-count">
1381+
<span class="card-count-text"></span>
1382+
<button class="filter-clear" id="filter-clear" type="button" hidden>Clear</button>
1383+
</div>
13151384
</div>
13161385
</div>
13171386
<div class="no-results" id="no-results" hidden></div>
@@ -3208,6 +3277,8 @@
32083277
var input = document.getElementById('demo-search');
32093278
var noResults = document.getElementById('no-results');
32103279
var cardCount = document.getElementById('card-count');
3280+
var cardCountText = cardCount.querySelector('.card-count-text');
3281+
var filterClearBtn = document.getElementById('filter-clear');
32113282
var chipsEl = document.getElementById('filter-chips');
32123283
var clearBtn = document.getElementById('search-clear');
32133284
var treeEl = document.querySelector('.crypto-tree');
@@ -3387,7 +3458,14 @@
33873458
});
33883459
}
33893460

3390-
/* Build filter chips */
3461+
/* Build filter chips with per-category counts */
3462+
var categoryCounts = {};
3463+
cardData.forEach(function (d) {
3464+
d.categories.forEach(function (c) {
3465+
categoryCounts[c] = (categoryCounts[c] || 0) + 1;
3466+
});
3467+
});
3468+
33913469
var categoriesWithAll = ['ALL'].concat(CATEGORIES);
33923470
var splitIndex = Math.ceil(categoriesWithAll.length / 2);
33933471
var topRowEl = document.createElement('div');
@@ -3402,7 +3480,14 @@
34023480
var isAll = cat === 'ALL';
34033481
btn.className = 'filter-chip' + (isAll ? ' active' : '');
34043482
btn.setAttribute('data-category', isAll ? '' : cat);
3405-
btn.textContent = cat;
3483+
var labelSpan = document.createElement('span');
3484+
labelSpan.className = 'chip-label';
3485+
labelSpan.textContent = cat;
3486+
var countSpan = document.createElement('span');
3487+
countSpan.className = 'chip-count';
3488+
countSpan.textContent = isAll ? total : (categoryCounts[cat] || 0);
3489+
btn.appendChild(labelSpan);
3490+
btn.appendChild(countSpan);
34063491
if (index < splitIndex) topRowEl.appendChild(btn);
34073492
else bottomRowEl.appendChild(btn);
34083493
});
@@ -3432,10 +3517,30 @@
34323517
noResults.hidden = !empty;
34333518
noResults.style.display = empty ? 'block' : 'none';
34343519
noResults.textContent = empty ? 'No demos found.' : '';
3435-
cardCount.textContent = 'Showing ' + visible + ' of ' + total;
3520+
cardCountText.textContent = 'Showing ' + visible + ' of ' + total;
3521+
var isFiltered = !!(activeCategory || activeSet || input.value);
3522+
cardCount.classList.toggle('filtered', isFiltered);
3523+
filterClearBtn.hidden = !isFiltered;
34363524
syncHash();
34373525
}
34383526

3527+
function resetFilters() {
3528+
input.value = '';
3529+
updateClear();
3530+
activeCategory = '';
3531+
activeSet = null;
3532+
clearTreeActive();
3533+
Array.from(chipsEl.querySelectorAll('.filter-chip')).forEach(function (c) {
3534+
c.classList.toggle('active', c.getAttribute('data-category') === '');
3535+
});
3536+
filter();
3537+
}
3538+
3539+
filterClearBtn.addEventListener('click', function () {
3540+
resetFilters();
3541+
input.focus();
3542+
});
3543+
34393544
/* Category clicks */
34403545
chipsEl.addEventListener('click', function (e) {
34413546
var btn = e.target.closest('.filter-chip');

0 commit comments

Comments
 (0)