Skip to main content

max / balanced_breakfast

css: F5 C — consolidate duplicate .btn-small onto canonical .btn-sm .btn-small and .btn-sm carried identical rules (size + .active). Dropped .btn-small, migrated all call sites (index.html, detail/bookmarks/app/ query-feeds/navigation.js) to .btn-sm, the design-system canonical. Pure dedup, no visual change. 55 JS tests pass; lint clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-07-12 19:00 UTC
Commit: a217a31307ac2092a9b51af064b6ece2e8c1f1dc
Parent: abfcb99
7 files changed, +26 insertions, -30 deletions
@@ -316,9 +316,9 @@ body {
316 316 .sort-select:focus { outline: none; border-color: var(--category-four); }
317 317
318 318 /* === 9. Buttons ========================================================
319 - Canonical: .btn (+ .btn-primary, .btn-success, .btn-small).
320 - Charter target: collapse bespoke *-btn classes (.tag-filter-btn,
321 - .toast-action, .hp-action, .mobile-tab, etc.) onto this family in F5.
319 + Canonical: .btn (+ .btn-primary, .btn-secondary, .btn-success, .btn-danger,
320 + .btn-icon, .btn-text, .btn-link; size .btn-sm; state .btn-loading).
321 + Charter target: collapse remaining bespoke *-btn classes onto this family.
322 322 ========================================================================== */
323 323 .btn {
324 324 padding: 0.4rem 0.75rem;
@@ -347,11 +347,7 @@ body {
347 347 color: var(--content-on-action);
348 348 }
349 349 .btn-success:hover { background-color: var(--accent-yellow-light); border-color: var(--accent-yellow-light); }
350 - .btn-small { padding: 0.2rem 0.5rem; font-size: 0.8rem; }
351 - .btn-small.active { background: var(--category-four); color: var(--content-on-action); border-color: var(--category-four); }
352 -
353 - /* F2 additions (2026-06-02) — see design-system.md §Button.
354 - .btn-sm is the parity name; .btn-small kept as alias until F5 dedup. */
350 + /* .btn-sm — canonical small-button size (see design-system.md §Button). */
355 351 .btn-sm { padding: 0.2rem 0.5rem; font-size: 0.8rem; }
356 352 .btn-sm.active { background: var(--category-four); color: var(--content-on-action); border-color: var(--category-four); }
357 353
@@ -16,18 +16,18 @@
16 16 <input type="text" id="search-input" placeholder="Search... (/) | ? for help" class="search-input">
17 17 <span id="search-spinner" class="search-spinner" aria-hidden="true"></span>
18 18 <label for="sort-select" class="sr-only">Sort order</label>
19 - <button id="unread-toggle" class="btn btn-small" title="Show unread only (U)" aria-pressed="false">Unread</button>
19 + <button id="unread-toggle" class="btn btn-sm" title="Show unread only (U)" aria-pressed="false">Unread</button>
20 20 <select id="sort-select" class="sort-select" title="Sort order (S)">
21 21 <option value="chronological">Newest First</option>
22 22 <option value="score">By Score</option>
23 23 <option value="unread">Unread First</option>
24 24 <option value="starred">Starred First</option>
25 25 </select>
26 - <button id="mark-all-read-btn" class="btn btn-small" title="Mark all as read (Shift+A)">Mark All Read</button>
26 + <button id="mark-all-read-btn" class="btn btn-sm" title="Mark all as read (Shift+A)">Mark All Read</button>
27 27 <button id="refresh-btn" class="btn btn-primary" title="Refresh all feeds (R)">Refresh</button>
28 28 <button id="add-feed-btn" class="btn btn-success" title="Add a new feed source">+ Add Feed</button>
29 - <button id="help-btn" class="btn btn-small" title="Keyboard shortcuts (?)" aria-label="Help">?</button>
30 - <button id="settings-btn" class="btn btn-small" title="Settings" aria-label="Settings">&#9881;</button>
29 + <button id="help-btn" class="btn btn-sm" title="Keyboard shortcuts (?)" aria-label="Help">?</button>
30 + <button id="settings-btn" class="btn btn-sm" title="Settings" aria-label="Settings">&#9881;</button>
31 31 </div>
32 32 </header>
33 33
@@ -49,7 +49,7 @@
49 49 <span id="saved-count" class="source-count">0</span>
50 50 </div>
51 51 <div class="sidebar-footer">
52 - <button id="sync-settings-btn" class="btn btn-small" title="Cloud Sync Settings">Sync</button>
52 + <button id="sync-settings-btn" class="btn btn-sm" title="Cloud Sync Settings">Sync</button>
53 53 </div>
54 54 </aside>
55 55
@@ -73,8 +73,8 @@
73 73 <!-- Item detail panel -->
74 74 <aside class="detail-panel" id="detail-panel">
75 75 <div class="detail-header">
76 - <button id="save-detail" class="btn btn-small" aria-label="Add to Reading List" title="Add to Reading List">Bookmark</button>
77 - <button id="close-detail" class="btn btn-small" aria-label="Close">&times;</button>
76 + <button id="save-detail" class="btn btn-sm" aria-label="Add to Reading List" title="Add to Reading List">Bookmark</button>
77 + <button id="close-detail" class="btn btn-sm" aria-label="Close">&times;</button>
78 78 </div>
79 79 <article id="item-detail" class="item-detail"></article>
80 80 </aside>
@@ -104,7 +104,7 @@
104 104 <div class="modal-content" role="dialog" aria-modal="true" aria-labelledby="modal-title">
105 105 <div class="modal-header">
106 106 <h2 id="modal-title">Modal</h2>
107 - <button id="close-modal" class="btn btn-small" aria-label="Close">&times;</button>
107 + <button id="close-modal" class="btn btn-sm" aria-label="Close">&times;</button>
108 108 </div>
109 109 <div id="modal-body" class="modal-body"></div>
110 110 </div>
@@ -370,13 +370,13 @@
370 370 themeActions.className = 'theme-actions';
371 371
372 372 const themeImportBtn = document.createElement('button');
373 - themeImportBtn.className = 'btn btn-small';
373 + themeImportBtn.className = 'btn btn-sm';
374 374 themeImportBtn.textContent = 'Import Theme';
375 375 themeImportBtn.onclick = () => BB.themes.importTheme();
376 376 themeActions.appendChild(themeImportBtn);
377 377
378 378 const themeExportBtn = document.createElement('button');
379 - themeExportBtn.className = 'btn btn-small';
379 + themeExportBtn.className = 'btn btn-sm';
380 380 themeExportBtn.textContent = 'Export Current';
381 381 themeExportBtn.onclick = () => BB.themes.exportTheme();
382 382 themeActions.appendChild(themeExportBtn);
@@ -395,13 +395,13 @@
395 395 dataActions.className = 'form-row';
396 396
397 397 const importBtn = document.createElement('button');
398 - importBtn.className = 'btn btn-small';
398 + importBtn.className = 'btn btn-sm';
399 399 importBtn.textContent = 'Import OPML';
400 400 importBtn.onclick = () => { BB.ui.closeModal(); BB.feeds.importOpml(); };
401 401 dataActions.appendChild(importBtn);
402 402
403 403 const exportBtn = document.createElement('button');
404 - exportBtn.className = 'btn btn-small';
404 + exportBtn.className = 'btn btn-sm';
405 405 exportBtn.textContent = 'Export OPML';
406 406 exportBtn.onclick = () => { BB.ui.closeModal(); BB.feeds.exportOpml(); };
407 407 dataActions.appendChild(exportBtn);
@@ -417,7 +417,7 @@
417 417 syncLabel.textContent = 'Cloud Sync';
418 418 syncGroup.appendChild(syncLabel);
419 419 const syncBtn = document.createElement('button');
420 - syncBtn.className = 'btn btn-small';
420 + syncBtn.className = 'btn btn-sm';
421 421 syncBtn.textContent = 'Sync Settings';
422 422 syncBtn.onclick = () => { BB.ui.closeModal(); BB.sync.openSettings(); };
423 423 syncGroup.appendChild(syncBtn);
@@ -103,12 +103,12 @@
103 103
104 104 // Actions slot: Open + more (hover-revealed via .row-actions).
105 105 const openBtn = document.createElement('button');
106 - openBtn.className = 'btn btn-small';
106 + openBtn.className = 'btn btn-sm';
107 107 openBtn.title = 'Open URL';
108 108 openBtn.textContent = 'Open';
109 109 openBtn.onclick = (e) => { e.stopPropagation(); openUrl(bm.url); };
110 110 const moreBtn = document.createElement('button');
111 - moreBtn.className = 'btn btn-small';
111 + moreBtn.className = 'btn btn-sm';
112 112 moreBtn.title = 'More actions';
113 113 moreBtn.textContent = '\u22EF';
114 114 moreBtn.onclick = (e) => { e.stopPropagation(); showContextMenu(e, bm.id); };
@@ -162,14 +162,14 @@
162 162
163 163 // "All" button
164 164 const allBtn = document.createElement('button');
165 - allBtn.className = 'btn btn-small tag-filter-btn' + (!currentTag ? ' active' : '');
165 + allBtn.className = 'btn btn-sm tag-filter-btn' + (!currentTag ? ' active' : '');
166 166 allBtn.textContent = 'All';
167 167 allBtn.onclick = () => load(null);
168 168 bar.appendChild(allBtn);
169 169
170 170 for (const tag of tags) {
171 171 const btn = document.createElement('button');
172 - btn.className = 'btn btn-small tag-filter-btn' + (currentTag === tag ? ' active' : '');
172 + btn.className = 'btn btn-sm tag-filter-btn' + (currentTag === tag ? ' active' : '');
173 173 btn.textContent = tag;
174 174 btn.onclick = () => load(tag);
175 175 bar.appendChild(btn);
@@ -177,7 +177,7 @@
177 177
178 178 // "Add Bookmark" button
179 179 const addBtn = document.createElement('button');
180 - addBtn.className = 'btn btn-small btn-primary';
180 + addBtn.className = 'btn btn-sm btn-primary';
181 181 addBtn.textContent = '+ Add';
182 182 addBtn.onclick = () => openAddModal();
183 183 bar.appendChild(addBtn);
@@ -179,7 +179,7 @@
179 179 const header = document.querySelector('.detail-header');
180 180 if (!header.querySelector('.reader-back-btn')) {
181 181 const backBtn = document.createElement('button');
182 - backBtn.className = 'btn btn-small reader-back-btn';
182 + backBtn.className = 'btn btn-sm reader-back-btn';
183 183 backBtn.textContent = '\u2190 Back';
184 184 backBtn.addEventListener('click', collapseReader);
185 185 header.prepend(backBtn);
@@ -164,7 +164,7 @@
164 164 const header = document.querySelector('.detail-header');
165 165 if (header && !header.querySelector('.mobile-back-btn')) {
166 166 const backBtn = document.createElement('button');
167 - backBtn.className = 'btn btn-small mobile-back-btn';
167 + backBtn.className = 'btn btn-sm mobile-back-btn';
168 168 backBtn.textContent = '\u2190 Back';
169 169 backBtn.addEventListener('click', () => BB.detail.close());
170 170 header.prepend(backBtn);
@@ -68,7 +68,7 @@
68 68 <div class="form-group">
69 69 <label>Conditions (all must match)</label>
70 70 <div id="qf-conditions"></div>
71 - <button class="btn btn-small add-condition-btn" type="button">+ Add Condition</button>
71 + <button class="btn btn-sm add-condition-btn" type="button">+ Add Condition</button>
72 72 </div>
73 73 <div class="match-preview" id="qf-match-preview"></div>
74 74 <div class="modal-actions">
@@ -123,7 +123,7 @@
123 123 }
124 124
125 125 row.innerHTML = `${fieldSelect} ${opSelect} ${valueInput}
126 - <button class="btn btn-small cond-remove" data-idx="${idx}" title="Remove" aria-label="Remove condition">&times;</button>`;
126 + <button class="btn btn-sm cond-remove" data-idx="${idx}" title="Remove" aria-label="Remove condition">&times;</button>`;
127 127
128 128 // Field change → update operators and re-render
129 129 row.querySelector('.cond-field').onchange = (e) => {