From 5717b0a38a6aa613c027e6e14d9e4f1b40d27952 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 28 Aug 2026 10:15:42 -0400 Subject: [PATCH] =?UTF-8?q?Compact=20feed=20header=20on=20phones=20so=20mo?= =?UTF-8?q?re=20Pok=C3=A9mon=20are=20visible?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Filter chips + sort + type/gen/random collapse behind a 'Filters & sort' toggle on < 900px (always shown on desktop); toggle carries a badge with the active-filter count; open state persists - Smaller title / progress ring / search on < 560px - Shorter dex cards on phones (tighter padding, 94px sprite): ~209px vs ~250px, so ~4-5 Pokémon fit above the fold instead of ~2-3 Co-Authored-By: Claude Sonnet 5 --- src/styles/layout.css | 109 ++++++++++++++++++++++++++++++++++++++++++ src/views/DexGrid.js | 43 +++++++++++++---- 2 files changed, 143 insertions(+), 9 deletions(-) diff --git a/src/styles/layout.css b/src/styles/layout.css index 9d404a8..be91e96 100644 --- a/src/styles/layout.css +++ b/src/styles/layout.css @@ -1899,3 +1899,112 @@ font-size: 0.7rem; padding: 6px 11px; } + +/* ---- Feed: collapsible tools + compact header on phones ------ */ +.feed-tools__toggle { + display: flex; + align-items: center; + gap: 8px; + margin-top: 12px; + padding: 8px 14px; + border: 1.5px solid var(--border); + border-radius: 999px; + background: var(--surface); + color: var(--text-dim); + font: inherit; + font-size: 0.84rem; + font-weight: 600; + cursor: pointer; +} +.feed-tools__chev { + transition: transform 0.15s ease; + margin-left: auto; +} +.feed-tools__toggle[aria-expanded="true"] .feed-tools__chev { + transform: rotate(180deg); +} +.feed-tools__toggle[data-active]:not([data-active=""])::before { + content: attr(data-active); + min-width: 17px; + height: 17px; + padding: 0 4px; + border-radius: 999px; + background: var(--accent); + color: var(--accent-text); + font-size: 0.68rem; + display: grid; + place-items: center; +} +.feed-tools { + display: none; +} +.feed-tools.is-open { + display: block; +} +.feed-tools > * { + margin-top: 10px; +} +@media (min-width: 900px) { + .feed-tools__toggle { + display: none; + } + .feed-tools { + display: block; + } +} +@media (max-width: 560px) { + .feed-head { + margin: -8px 0 12px; + padding: 10px 0 8px; + } + .feed-head__id h1 { + font-size: 1.5rem; + } + .feed-head__game { + margin-top: 2px; + } + .ring { + width: 48px; + height: 48px; + } + .ring__label { + font-size: 0.74rem; + } + .field-search { + margin: 10px 0 0; + } + .field-search__input { + padding-top: 10px; + padding-bottom: 10px; + } + + /* Shorter cards so more fit on screen */ + .grid { + gap: 12px; + } + .card { + padding: 12px 12px 12px; + } + .card__art { + min-height: 116px; + padding-top: 22px; + } + .card__art .sprite { + width: 94px; + height: 94px; + } + .card__ghost { + font-size: 2.3rem; + } + .card__spot { + top: 24px; + width: 100px; + height: 100px; + } + .card__body { + margin-top: 4px; + } + .card__name { + font-size: 0.88rem; + } +} diff --git a/src/views/DexGrid.js b/src/views/DexGrid.js index 84331e2..a189873 100644 --- a/src/views/DexGrid.js +++ b/src/views/DexGrid.js @@ -119,6 +119,7 @@ export async function DexGrid() { chipEls.forEach((c, i) => c.btn.classList.toggle('is-active', FILTERS[i].key === f.key)); paintGrid(); resetScroll(); + syncToolsBadge(); }, }, el('span', {}, f.label), @@ -170,6 +171,7 @@ export async function DexGrid() { ui.set({ filterType }); paintGrid(); resetScroll(); + syncToolsBadge(); }, }, el('option', { value: '' }, 'Any type'), @@ -184,6 +186,7 @@ export async function DexGrid() { ui.set({ filterGen }); paintGrid(); resetScroll(); + syncToolsBadge(); }, }, el('option', { value: '0' }, 'Any gen'), @@ -254,6 +257,35 @@ export async function DexGrid() { } renderRecent(); + const tools = el( + 'div', + { class: `feed-tools${ui.get().toolsOpen ? ' is-open' : ''}` }, + filterBar, + el('div', { class: 'feed-sort' }, el('span', { class: 'feed-sort__label' }, 'Sort'), sortSelect, dirBtn), + el('div', { class: 'feed-sort feed-filters' }, typeSelect, genSelect, randomBtn), + ); + const toolsToggle = el( + 'button', + { + class: 'feed-tools__toggle', + type: 'button', + 'aria-expanded': String(!!ui.get().toolsOpen), + onclick: () => { + const open = tools.classList.toggle('is-open'); + toolsToggle.setAttribute('aria-expanded', String(open)); + ui.set({ toolsOpen: open }); + }, + }, + 'Filters & sort', + el('span', { class: 'feed-tools__chev', 'aria-hidden': 'true' }, '▾'), + ); + function syncToolsBadge() { + const n = + (filterKey !== 'all' ? 1 : 0) + (filterType ? 1 : 0) + (filterGen ? 1 : 0); + toolsToggle.dataset.active = n ? String(n) : ''; + } + syncToolsBadge(); + view.append( el( 'header', @@ -270,15 +302,8 @@ export async function DexGrid() { el('span', { class: 'field-search__icon', html: SEARCH_ICON, 'aria-hidden': 'true' }), search, ), - filterBar, - el( - 'div', - { class: 'feed-sort' }, - el('span', { class: 'feed-sort__label' }, 'Sort'), - sortSelect, - dirBtn, - ), - el('div', { class: 'feed-sort feed-filters' }, typeSelect, genSelect, randomBtn), + toolsToggle, + tools, ), recentStrip, grid,