Each component picks its own screen width for switching to a narrower layout, so pages change in several separate steps as the window narrows instead of all at once. The app uses 16 different widths, and nothing tells a new component which one to use.
On the Servers page, narrowing the window from 1000 to 600 px changes the layout five times:
+page.svelte:1026 squashes the attention rows at 1000 px.
+layout.svelte:678 hides the sidebar at 960 px. +layout.svelte:118 repeats that width in JavaScript (min-width: 961px) to close the drawer.
+layout.svelte:708 tightens the top bar at 720 px.
ServerCard.svelte:449 shrinks the server cards' padding at 640 px.
+page.svelte:1034 shrinks the page summary and hides its metric link at 600 px.
Between those widths, the page is part desktop layout and part phone layout. Across src/, the 77 width media queries use 360, 440, 480, 500, 540, 600, 620, 640, 700, 720, 760, 800, 850, 960, 1000 and 1100 px. 640 and 600 account for 38 of them, and 500, 620, 700, 760 and 850 are used once each. docs/development/ui-patterns.md doesn't mention breakpoints.
CSS custom properties don't work inside @media, so a variable in tokens.css can't be used in the queries themselves. check-ui-styles.mjs already enforces the shared font sizes and can check widths the same way.
Fix
List the shared widths in tokens.css and ui-patterns.md, for example 360, 640, 960 and 1100 px
Move the app shell, Servers page and server cards onto those widths: 720 → 640 in +layout.svelte, and 1000 → 1100 and 600 → 640 in +page.svelte
Make check-ui-styles.mjs reject other widths in @media queries, with an allowlist of the files that haven't moved yet
Each component picks its own screen width for switching to a narrower layout, so pages change in several separate steps as the window narrows instead of all at once. The app uses 16 different widths, and nothing tells a new component which one to use.
On the Servers page, narrowing the window from 1000 to 600 px changes the layout five times:
- `+page.svelte:1026` squashes the attention rows at 1000 px.
- `+layout.svelte:678` hides the sidebar at 960 px. `+layout.svelte:118` repeats that width in JavaScript (`min-width: 961px`) to close the drawer.
- `+layout.svelte:708` tightens the top bar at 720 px.
- `ServerCard.svelte:449` shrinks the server cards' padding at 640 px.
- `+page.svelte:1034` shrinks the page summary and hides its metric link at 600 px.
Between those widths, the page is part desktop layout and part phone layout. Across `src/`, the 77 width media queries use 360, 440, 480, 500, 540, 600, 620, 640, 700, 720, 760, 800, 850, 960, 1000 and 1100 px. 640 and 600 account for 38 of them, and 500, 620, 700, 760 and 850 are used once each. `docs/development/ui-patterns.md` doesn't mention breakpoints.
CSS custom properties don't work inside `@media`, so a variable in `tokens.css` can't be used in the queries themselves. `check-ui-styles.mjs` already enforces the shared font sizes and can check widths the same way.
**Fix**
- [x] List the shared widths in `tokens.css` and `ui-patterns.md`, for example 360, 640, 960 and 1100 px
- [x] Move the app shell, Servers page and server cards onto those widths: 720 → 640 in `+layout.svelte`, and 1000 → 1100 and 600 → 640 in `+page.svelte`
- [x] Make `check-ui-styles.mjs` reject other widths in `@media` queries, with an allowlist of the files that haven't moved yet
josh
was assigned by goddard2026-10-09 19:55:59 -04:00
goddard
changed title from Layouts use 16 different breakpoints to Layouts switch at 16 different screen widths, so pages reflow in several steps2026-10-09 23:38:44 -04:00
Reviewed d2b2958700. All three fix items are done, so I'm closing this.
Checklist
List the shared widths.tokens.css:133-136 defines 360, 640, 960 and 1100 px, and ui-patterns.md:53 adds a "Responsive widths" section with what each is for and how to match them in JavaScript.
Move the app shell, Servers page and server cards.
+layout.svelte:709 moved from 720 to 640.
The drawer's JavaScript now uses the sidebar's own (max-width: 960px) query, inverted (+layout.svelte:119), instead of min-width: 961px.
+page.svelte:1022,1030 moved from 1000 to 1100 and from 600 to 640.
These three files now use only 360, 640, 960 and 1100 px (ServerCard.svelte was already on 640). Narrowing the Servers page from 1100 to 600 px now changes the layout at 1100, 960 and 640 px instead of at five widths.
Reject other widths in the style check.checkMediaWidths (check-ui-styles.mjs:61) reads the scale from tokens.css and rejects any other width, with an allowlist of 45 widths across 39 files (check-ui-styles.mjs:15). All 45 are still in use. I called it on sample queries:
In a new file, 640 px passes, and 700 px, 961 px and the 400 px side of a range query fail.
In the Leaderboard, its listed 800 px passes and 720 px fails.
Review notes
npm run check:styles passes and ui-style-check.test.js passes. Run 860 passed on this commit.
src/ still uses 16 widths in total, all from the allowlisted files. That's expected until they move; 600 px (15 uses) and 720 px (10) are the largest groups left.
Reviewed d2b29587000afff66019e0753c86ed7d82d2dee6. All three fix items are done, so I'm closing this.
**Checklist**
- [x] **List the shared widths.** `tokens.css:133-136` defines 360, 640, 960 and 1100 px, and `ui-patterns.md:53` adds a "Responsive widths" section with what each is for and how to match them in JavaScript.
- [x] **Move the app shell, Servers page and server cards.**
- `+layout.svelte:709` moved from 720 to 640.
- The drawer's JavaScript now uses the sidebar's own `(max-width: 960px)` query, inverted (`+layout.svelte:119`), instead of `min-width: 961px`.
- `+page.svelte:1022,1030` moved from 1000 to 1100 and from 600 to 640.
- These three files now use only 360, 640, 960 and 1100 px (`ServerCard.svelte` was already on 640). Narrowing the Servers page from 1100 to 600 px now changes the layout at 1100, 960 and 640 px instead of at five widths.
- [x] **Reject other widths in the style check.** `checkMediaWidths` (`check-ui-styles.mjs:61`) reads the scale from `tokens.css` and rejects any other width, with an allowlist of 45 widths across 39 files (`check-ui-styles.mjs:15`). All 45 are still in use. I called it on sample queries:
- In a new file, 640 px passes, and 700 px, 961 px and the 400 px side of a range query fail.
- In the Leaderboard, its listed 800 px passes and 720 px fails.
**Review notes**
- `npm run check:styles` passes and `ui-style-check.test.js` passes. [Run 860](https://gitea.thewrightserver.net/josh/electric-cherry/actions/runs/860) passed on this commit.
- `src/` still uses 16 widths in total, all from the allowlisted files. That's expected until they move; 600 px (15 uses) and 720 px (10) are the largest groups left.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Each component picks its own screen width for switching to a narrower layout, so pages change in several separate steps as the window narrows instead of all at once. The app uses 16 different widths, and nothing tells a new component which one to use.
On the Servers page, narrowing the window from 1000 to 600 px changes the layout five times:
+page.svelte:1026squashes the attention rows at 1000 px.+layout.svelte:678hides the sidebar at 960 px.+layout.svelte:118repeats that width in JavaScript (min-width: 961px) to close the drawer.+layout.svelte:708tightens the top bar at 720 px.ServerCard.svelte:449shrinks the server cards' padding at 640 px.+page.svelte:1034shrinks the page summary and hides its metric link at 600 px.Between those widths, the page is part desktop layout and part phone layout. Across
src/, the 77 width media queries use 360, 440, 480, 500, 540, 600, 620, 640, 700, 720, 760, 800, 850, 960, 1000 and 1100 px. 640 and 600 account for 38 of them, and 500, 620, 700, 760 and 850 are used once each.docs/development/ui-patterns.mddoesn't mention breakpoints.CSS custom properties don't work inside
@media, so a variable intokens.csscan't be used in the queries themselves.check-ui-styles.mjsalready enforces the shared font sizes and can check widths the same way.Fix
tokens.cssandui-patterns.md, for example 360, 640, 960 and 1100 px+layout.svelte, and 1000 → 1100 and 600 → 640 in+page.sveltecheck-ui-styles.mjsreject other widths in@mediaqueries, with an allowlist of the files that haven't moved yetLayouts use 16 different breakpointsto Layouts switch at 16 different screen widths, so pages reflow in several stepsReviewed
d2b2958700. All three fix items are done, so I'm closing this.Checklist
tokens.css:133-136defines 360, 640, 960 and 1100 px, andui-patterns.md:53adds a "Responsive widths" section with what each is for and how to match them in JavaScript.+layout.svelte:709moved from 720 to 640.(max-width: 960px)query, inverted (+layout.svelte:119), instead ofmin-width: 961px.+page.svelte:1022,1030moved from 1000 to 1100 and from 600 to 640.ServerCard.sveltewas already on 640). Narrowing the Servers page from 1100 to 600 px now changes the layout at 1100, 960 and 640 px instead of at five widths.checkMediaWidths(check-ui-styles.mjs:61) reads the scale fromtokens.cssand rejects any other width, with an allowlist of 45 widths across 39 files (check-ui-styles.mjs:15). All 45 are still in use. I called it on sample queries:Review notes
npm run check:stylespasses andui-style-check.test.jspasses. Run 860 passed on this commit.src/still uses 16 widths in total, all from the allowlisted files. That's expected until they move; 600 px (15 uses) and 720 px (10) are the largest groups left.