You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Filters are toggle/checkbox-heavy — give them clear on/off states. Favorites is a simple list view, similar treatment to other list screens in the app for consistency.
Restyled web/src/routes/filters/+page.svelte and web/src/routes/favorites/+page.svelte using only the landed component classes/tokens from web/src/app.css (.page-title, .section-title, .label-rule, .card, .empty-state, .btn/.btn-primary/.btn-ghost/.btn-sm, .badge) plus Tailwind utilities built from the existing @theme tokens. No app.css edits, no new colors.
Filters: page-title header, section-title'd "Avoid allergens"/"Require diet tags" sections, .empty-state for the no-data case, .btn-primary Save, .badge for the "Saved" status. Each allergen/diet-tag checkbox is wrapped in a chip-style <label> that fills maroon (bg-maroon-600 text-paper-50) when checked vs. an outlined border-ink-900/25 chip when not — the issue calls out that filters need "clear on/off states," so this is a real visual, not just decoration on the same 1px checkbox.
Favorites: page-title header, section-title'd "Dishes"/"Dining Halls", .card rows matching the treatment already established on / and /halls/[slug] (same list-row pattern), .empty-state for empty lists, .btn-ghost btn-sm Remove (per app.css's own stated intent: "low-stakes/destructive-lite").
Native checkbox/button roles and accessible names are unchanged: getByRole("checkbox", { name: "Milk" }), the favorite star's glyph-only text-content contract on the hall/home pages, and the Remove button's accessible name all still resolve exactly as before.
Both are device-only per CLAUDE.md's data-residency table — FoodPreferences in localStorage, Favorites in IndexedDB via IndexedDbFavoritesStorage. No Supabase calls added, no auth gate.
Red/green evidence (strict TDD)
Extended web/e2e/filters.spec.ts and web/e2e/favorites.spec.ts write-first with new assertions for the new visual behavior, using toHaveCSS (not class-name matching, so the test verifies an actual rendered difference, not a string in an attribute).
Red — ran PORT=4303 npx playwright test filters.spec.ts favorites.spec.ts against the unstyled pages, before any .svelte changes:
PORT=4303 npx playwright test (full suite, all 17 specs, including sibling-owned shell.spec.ts, halls-menu.spec.ts, rank.spec.ts, vertical-slice.spec.ts): 17 passed, confirming this restyle didn't regress shell.spec.ts's proveHydrated() (which also depends on the favorite star's text-content contract) or any concurrently-landing sibling work.
pnpm --filter web check: 0 errors, 0 warnings (396 files).
pnpm --filter web build (after cp web/.env.example web/.env): succeeds; only the expected pre-existing adapter-auto "could not detect a supported production environment" notice, not an error.
Eyeballed both routes live against the dev server (PORT=4303 vite dev, screenshotted via Playwright's own chromium since no system Chrome was available in this sandbox): confirmed the maroon page-title/label-rule header, chip-style checkboxes with a visibly filled checked state, and the dashed .empty-state panel on /favorites all render as intended.
npx playwright test passes unchanged — extended, not modified in place; all pre-existing assertions (checkbox accessible names, Saved status text, star button text-content contract, Remove button name) still pass as written
pnpm --filter web check clean, CI passes (checked locally; CI to confirm)
Scope
Touched only: web/src/routes/filters/+page.svelte, web/src/routes/favorites/+page.svelte, web/e2e/filters.spec.ts, web/e2e/favorites.spec.ts. No app.css, no +layout.svelte, no other route dirs, no other e2e specs, no halls/ files.
Not merging — leaving for review per dispatch instructions.
Activity
TSVRN9 commentedon Aug 19, 2026
Closes #40
What changed
Restyled
web/src/routes/filters/+page.svelteandweb/src/routes/favorites/+page.svelteusing only the landed component classes/tokens fromweb/src/app.css(.page-title,.section-title,.label-rule,.card,.empty-state,.btn/.btn-primary/.btn-ghost/.btn-sm,.badge) plus Tailwind utilities built from the existing@themetokens. Noapp.cssedits, no new colors..empty-statefor the no-data case,.btn-primarySave,.badgefor the "Saved" status. Each allergen/diet-tag checkbox is wrapped in a chip-style<label>that fills maroon (bg-maroon-600 text-paper-50) when checked vs. an outlinedborder-ink-900/25chip when not — the issue calls out that filters need "clear on/off states," so this is a real visual, not just decoration on the same 1px checkbox..cardrows matching the treatment already established on/and/halls/[slug](same list-row pattern),.empty-statefor empty lists,.btn-ghost btn-smRemove (per app.css's own stated intent: "low-stakes/destructive-lite").Native checkbox/button roles and accessible names are unchanged:
getByRole("checkbox", { name: "Milk" }), the favorite star's glyph-only text-content contract on the hall/home pages, and the Remove button's accessible name all still resolve exactly as before.Both are device-only per CLAUDE.md's data-residency table —
FoodPreferencesinlocalStorage,Favorites in IndexedDB viaIndexedDbFavoritesStorage. No Supabase calls added, no auth gate.Red/green evidence (strict TDD)
Extended
web/e2e/filters.spec.tsandweb/e2e/favorites.spec.tswrite-first with new assertions for the new visual behavior, usingtoHaveCSS(not class-name matching, so the test verifies an actual rendered difference, not a string in an attribute).Red — ran
PORT=4303 npx playwright test filters.spec.ts favorites.spec.tsagainst the unstyled pages, before any.sveltechanges:Green — after restyling both pages, same command:
Verification
PORT=4303 npx playwright test(full suite, all 17 specs, including sibling-ownedshell.spec.ts,halls-menu.spec.ts,rank.spec.ts,vertical-slice.spec.ts): 17 passed, confirming this restyle didn't regressshell.spec.ts'sproveHydrated()(which also depends on the favorite star's text-content contract) or any concurrently-landing sibling work.pnpm --filter web check: 0 errors, 0 warnings (396 files).pnpm --filter web build(aftercp web/.env.example web/.env): succeeds; only the expected pre-existingadapter-auto"could not detect a supported production environment" notice, not an error.PORT=4303 vite dev, screenshotted via Playwright's own chromium since no system Chrome was available in this sandbox): confirmed the maroon page-title/label-rule header, chip-style checkboxes with a visibly filled checked state, and the dashed.empty-statepanel on/favoritesall render as intended.Acceptance criteria (from #40)
npx playwright testpasses unchanged — extended, not modified in place; all pre-existing assertions (checkbox accessible names, Saved status text, star button text-content contract, Remove button name) still pass as writtenpnpm --filter web checkclean, CI passes (checked locally; CI to confirm)Scope
Touched only:
web/src/routes/filters/+page.svelte,web/src/routes/favorites/+page.svelte,web/e2e/filters.spec.ts,web/e2e/favorites.spec.ts. Noapp.css, no+layout.svelte, no other route dirs, no other e2e specs, nohalls/files.Not merging — leaving for review per dispatch instructions.
TSVRN9 commentedon Aug 19, 2026
PR: #57 (branch
ux/filters-favorites, not merged — left for review).