site: filter changelog by component (Skill / CLI / Extension / All)

Bare /impeccable changelog defaults to Skill-only; CLI, Extension, and All
toggle the rest. Component is derived from each entry's id prefix (cli-/ext-),
so no per-entry tagging. Accessible button group, kinpaku segmented styling,
shows all with JS off.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-05-28 16:00:00 -07:00
co-authored by Claude Opus 4.8
parent d97bdef0e8
commit f6a516940e
2 changed files with 76 additions and 1 deletions
+38
View File
@@ -16,6 +16,13 @@ import '../styles/changelog-faq-kinpaku.css';
<h1 class="cf-title">Changelog</h1>
<p class="cf-lede">What shipped, when, and why. Newest at the top, back through the v3.0 launch.</p>
<div class="cf-filter" role="group" aria-label="Filter changelog by component">
<button type="button" class="cf-filter-btn is-active" data-cf-filter="skill" aria-pressed="true">Skill</button>
<button type="button" class="cf-filter-btn" data-cf-filter="cli" aria-pressed="false">CLI</button>
<button type="button" class="cf-filter-btn" data-cf-filter="ext" aria-pressed="false">Extension</button>
<button type="button" class="cf-filter-btn" data-cf-filter="all" aria-pressed="false">All</button>
</div>
<article id="v3.5.0" class="cf-entry cf-entry--current">
<header class="cf-entry-head"><span class="cf-version">v3.5.0</span><span class="cf-date">May 28, 2026</span><span class="cf-current-badge">Current</span></header>
<p class="cf-entry-lead">The biggest release yet. Per-provider skill compilation, a much less biased skill, and Live Mode out of its rough edges.</p>
@@ -208,4 +215,35 @@ import '../styles/changelog-faq-kinpaku.css';
</ul>
</article>
</div>
<script is:inline>
(function () {
const buttons = Array.from(document.querySelectorAll('.cf-filter-btn'));
const entries = Array.from(document.querySelectorAll('.cf-entry'));
if (!buttons.length || !entries.length) return;
// Component is derived from the entry id prefix: cli-*, ext-*, else skill.
const kindOf = (entry) => {
const id = entry.id || '';
if (id.startsWith('cli-')) return 'cli';
if (id.startsWith('ext-')) return 'ext';
return 'skill';
};
const apply = (filter) => {
entries.forEach((entry) => {
const show = filter === 'all' || kindOf(entry) === filter;
entry.classList.toggle('cf-entry--hidden', !show);
});
buttons.forEach((btn) => {
const active = btn.dataset.cfFilter === filter;
btn.classList.toggle('is-active', active);
btn.setAttribute('aria-pressed', active ? 'true' : 'false');
});
};
buttons.forEach((btn) => btn.addEventListener('click', () => apply(btn.dataset.cfFilter)));
apply('skill'); // default view: skill only
})();
</script>
</Base>
+38 -1
View File
@@ -40,10 +40,47 @@
font-size: 1.05rem;
line-height: 1.65;
color: var(--ks-text);
margin: 0 0 clamp(40px, 5vw, 64px);
margin: 0 0 clamp(28px, 4vw, 40px);
max-width: 60ch;
}
/* Component filter (Skill / CLI / Extension / All) */
.cf-filter {
display: inline-flex;
flex-wrap: wrap;
gap: 4px;
padding: 4px;
margin: 0 0 clamp(40px, 5vw, 64px);
background: var(--ks-lacquer-raised);
border: 1px solid color-mix(in oklab, var(--ks-champagne) 12%, transparent);
border-radius: 999px;
}
.cf-filter-btn {
font-family: var(--ks-font-body, inherit);
font-size: 0.86rem;
font-weight: 500;
color: var(--ks-text-muted);
background: transparent;
border: 0;
padding: 7px 18px;
min-height: 36px;
border-radius: 999px;
cursor: pointer;
transition: color 160ms ease, background 160ms ease;
}
.cf-filter-btn:hover { color: var(--ks-text); }
.cf-filter-btn.is-active {
color: var(--ks-lacquer);
background: var(--ks-kinpaku);
font-weight: 600;
}
.cf-filter-btn:focus-visible {
outline: 2px solid var(--ks-kinpaku);
outline-offset: 2px;
}
.cf-entry--hidden { display: none; }
/* ============================================================================
Changelog
============================================================================ */