Design system foundation + fix white flash (Phase 10e-1, 10e-2) #22

Closed
opened 2026-03-15 03:16:45 +00:00 by forgejo_admin · 0 comments

Lineage

plan-2026-03-08-tryout-prep → Phase 10e → Phase 10e-1 (Fix white flash) + Phase 10e-2 (Design system foundation)

Repo

forgejo_admin/westside-app

User Story

As a mobile user (Marcus)
I want the app to load with a dark theme instantly and have consistent, professional styling
So that I don't see a white flash on every page load and the app looks polished on my phone

Context

Session 2026-03-15 live mobile testing revealed a white background flash on every page load. Root cause: the dark theme (background-color: #0a0a0a; color: #e0e0e0;) is defined in +layout.svelte inside <svelte:head><style> — a JS-dependent injection. The browser renders the default white app.html first, then SvelteKit hydrates and injects the dark styles. This also causes a hydration mismatch warning.

Additionally, there is zero design system. Every route has its own <style> block with hardcoded hex values copy-pasted across 9 routes + AuthStatus component. The same colors (#c41230, #141414, #222, #e0e0e0, #666, #7ec875, #ffd700, #ff6b6b, #6bb5ff) are redefined in every file. No CSS custom properties, no shared stylesheet, no design tokens.

Decision: combine 10e-1 and 10e-2 because fixing where base styles live (app.html) and extracting a design system (app.css) are tightly coupled.

File Targets

Files to modify:

  • src/app.html — add inline <style> for critical dark theme (bg, text color, box-sizing reset). This renders before JS.
  • src/routes/+layout.svelte — remove <svelte:head><style> block, import app.css instead
  • src/app.cssCREATE. Design tokens as CSS custom properties, base typography, responsive breakpoints
  • src/routes/+page.svelte — replace hardcoded hex with CSS variables
  • src/routes/admin/+page.svelte — replace hardcoded hex with CSS variables
  • src/routes/admin/teams/+page.svelte — replace hardcoded hex with CSS variables
  • src/routes/admin/users/+page.svelte — replace hardcoded hex with CSS variables
  • src/routes/coach/+page.svelte — replace hardcoded hex with CSS variables
  • src/routes/player/+page.svelte — replace hardcoded hex with CSS variables
  • src/routes/teams/+page.svelte — replace hardcoded hex with CSS variables
  • src/routes/signin/+page.svelte — replace hardcoded hex with CSS variables
  • src/routes/signout/+page.svelte — replace hardcoded hex with CSS variables
  • src/lib/components/AuthStatus.svelte — replace hardcoded hex with CSS variables

Files NOT to touch:

  • src/routes/**/+page.server.js — data fetching logic, not related
  • src/hooks.server.js — auth middleware, not related
  • src/auth.js — auth config, not related

Acceptance Criteria

  • When I load any route on mobile, the dark theme renders instantly with zero white flash
  • When I inspect the console, there are zero hydration mismatch warnings
  • When I run grep -rn '#c41230\|#0a0a0a\|#141414\|#e0e0e0' src/routes/ src/lib/ the only hex values are in app.css (routes use var(--...))
  • When I compare screenshots of all 9 routes before/after, they are visually identical
  • src/app.css exists with CSS custom properties for all design tokens
  • All routes import design tokens via app.css (loaded in layout), not per-file hardcoded values
  • Common utility classes (.container, .alert, .stat-card, .btn, etc.) that repeat across routes are consolidated into app.css where appropriate

Test Expectations

  • Visual regression: all 9 routes render identically to current state
  • White flash: load page with throttled connection — dark bg renders before JS
  • Build succeeds: npm run build completes without errors
  • Run command: npm run build && npm run preview

Constraints

  • This is a refactor, not a redesign — visual output must be pixel-identical
  • Do NOT change component structure, layouts, or HTML markup
  • Do NOT modify AuthStatus nav structure (that's Phase 10e-5)
  • Do NOT add new dependencies
  • Keep app.html inline styles minimal — only critical above-the-fold dark theme. Full design system goes in app.css
  • Preserve all existing responsive breakpoints (@media (max-width: 480px))
  • Use SvelteKit convention: src/app.css imported in root +layout.svelte

Checklist

  • PR opened
  • Tests pass (npm run build)
  • No unrelated changes
  • Zero white flash verified
  • Zero hydration warnings
  • westside-basketball — project
  • plan-2026-03-08-tryout-prep — parent plan
  • Phase 10e-3 through 10e-5 depend on this work being complete
### Lineage `plan-2026-03-08-tryout-prep` → Phase 10e → Phase 10e-1 (Fix white flash) + Phase 10e-2 (Design system foundation) ### Repo `forgejo_admin/westside-app` ### User Story As a mobile user (Marcus) I want the app to load with a dark theme instantly and have consistent, professional styling So that I don't see a white flash on every page load and the app looks polished on my phone ### Context Session 2026-03-15 live mobile testing revealed a white background flash on every page load. Root cause: the dark theme (`background-color: #0a0a0a; color: #e0e0e0;`) is defined in `+layout.svelte` inside `<svelte:head><style>` — a JS-dependent injection. The browser renders the default white `app.html` first, then SvelteKit hydrates and injects the dark styles. This also causes a hydration mismatch warning. Additionally, there is zero design system. Every route has its own `<style>` block with hardcoded hex values copy-pasted across 9 routes + AuthStatus component. The same colors (`#c41230`, `#141414`, `#222`, `#e0e0e0`, `#666`, `#7ec875`, `#ffd700`, `#ff6b6b`, `#6bb5ff`) are redefined in every file. No CSS custom properties, no shared stylesheet, no design tokens. Decision: combine 10e-1 and 10e-2 because fixing where base styles live (app.html) and extracting a design system (app.css) are tightly coupled. ### File Targets Files to modify: - `src/app.html` — add inline `<style>` for critical dark theme (bg, text color, box-sizing reset). This renders before JS. - `src/routes/+layout.svelte` — remove `<svelte:head><style>` block, import `app.css` instead - `src/app.css` — **CREATE**. Design tokens as CSS custom properties, base typography, responsive breakpoints - `src/routes/+page.svelte` — replace hardcoded hex with CSS variables - `src/routes/admin/+page.svelte` — replace hardcoded hex with CSS variables - `src/routes/admin/teams/+page.svelte` — replace hardcoded hex with CSS variables - `src/routes/admin/users/+page.svelte` — replace hardcoded hex with CSS variables - `src/routes/coach/+page.svelte` — replace hardcoded hex with CSS variables - `src/routes/player/+page.svelte` — replace hardcoded hex with CSS variables - `src/routes/teams/+page.svelte` — replace hardcoded hex with CSS variables - `src/routes/signin/+page.svelte` — replace hardcoded hex with CSS variables - `src/routes/signout/+page.svelte` — replace hardcoded hex with CSS variables - `src/lib/components/AuthStatus.svelte` — replace hardcoded hex with CSS variables Files NOT to touch: - `src/routes/**/+page.server.js` — data fetching logic, not related - `src/hooks.server.js` — auth middleware, not related - `src/auth.js` — auth config, not related ### Acceptance Criteria - [ ] When I load any route on mobile, the dark theme renders instantly with zero white flash - [ ] When I inspect the console, there are zero hydration mismatch warnings - [ ] When I run `grep -rn '#c41230\|#0a0a0a\|#141414\|#e0e0e0' src/routes/ src/lib/` the only hex values are in `app.css` (routes use `var(--...)`) - [ ] When I compare screenshots of all 9 routes before/after, they are visually identical - [ ] `src/app.css` exists with CSS custom properties for all design tokens - [ ] All routes import design tokens via `app.css` (loaded in layout), not per-file hardcoded values - [ ] Common utility classes (`.container`, `.alert`, `.stat-card`, `.btn`, etc.) that repeat across routes are consolidated into `app.css` where appropriate ### Test Expectations - [ ] Visual regression: all 9 routes render identically to current state - [ ] White flash: load page with throttled connection — dark bg renders before JS - [ ] Build succeeds: `npm run build` completes without errors - Run command: `npm run build && npm run preview` ### Constraints - This is a **refactor, not a redesign** — visual output must be pixel-identical - Do NOT change component structure, layouts, or HTML markup - Do NOT modify AuthStatus nav structure (that's Phase 10e-5) - Do NOT add new dependencies - Keep `app.html` inline styles minimal — only critical above-the-fold dark theme. Full design system goes in `app.css` - Preserve all existing responsive breakpoints (`@media (max-width: 480px)`) - Use SvelteKit convention: `src/app.css` imported in root `+layout.svelte` ### Checklist - [ ] PR opened - [ ] Tests pass (`npm run build`) - [ ] No unrelated changes - [ ] Zero white flash verified - [ ] Zero hydration warnings ### Related - `westside-basketball` — project - `plan-2026-03-08-tryout-prep` — parent plan - Phase 10e-3 through 10e-5 depend on this work being complete
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
forgejo_admin/westside-landing#22
No description provided.