Phase 17: UI Optimization & Polish #24

Merged
luckberg merged 61 commits from gsd/phase-17-ui-optimization-polish into main 2026-06-18 16:24:54 -04:00
2 changed files with 121 additions and 1 deletions
Showing only changes of commit 58d11caee0 - Show all commits
@@ -0,0 +1,105 @@
---
phase: "17"
plan: "01"
subsystem: pwa/styles
tags: [css-tokens, theme-groundwork, workstream-c, d-06]
dependency_graph:
requires: []
provides:
- apps/pwa/src/styles/tokens.css — combined :root,[data-theme="light"] selector
- --bottom-chrome-h token (consumed by Workstreams A and D plans)
affects:
- apps/pwa/src/styles/tokens.css (selector restructure, new token)
tech_stack:
added: []
patterns:
- "CSS combined selector :root,[data-theme=light] for future dark-theme override"
- "--bottom-chrome-h: calc(56px + env(safe-area-inset-bottom, 0px)) layout-chrome token"
key_files:
created: []
modified:
- apps/pwa/src/styles/tokens.css
decisions:
- "D-06: combined :root,[data-theme=light] selector is purely structural — all token values unchanged; enables future data-theme=dark override without any component-file changes"
- "Dark-theme stub is a comment-only block — no live [data-theme=dark] rule; Phase 999.20 owns that work"
- "--bottom-chrome-h placed in spacing-scale section (alongside --space-* tokens) as its conceptual peer"
- "All --sx-color-* overrides remain inside the combined rule block (do not split); prevents Schedule-X cascade break (Pitfall 3)"
metrics:
duration: "3m 23s"
completed_date: "2026-06-18"
tasks_completed: 2
tasks_total: 2
files_changed: 1
status: complete
---
# Phase 17 Plan 01: Token Groundwork — Summary
Restructured `apps/pwa/src/styles/tokens.css` from a single `:root {}` block to a combined `:root, [data-theme="light"]` selector (D-06 theme-token groundwork), and added the `--bottom-chrome-h` layout-chrome token as the single source of truth for BottomTabBar effective height.
## What Was Built
**One-liner:** CSS selector restructure to `[data-theme="light"]-capable pattern + `--bottom-chrome-h` token for BottomTabBar height, zero value changes.
### tokens.css structural change
- The opening `:root {` selector changed to `:root,\n[data-theme="light"] {`
- All 12 `--sx-color-*` Schedule-X overrides remain inside the same combined rule block (cascade order unchanged)
- All `--brand-logo-*` tokens remain inside the combined rule block (verbatim)
- New token added to spacing scale: `--bottom-chrome-h: calc(56px + env(safe-area-inset-bottom, 0px))`
- Dark theme stub added as `/* ... */` comment below the closing brace (no live rule)
### No component/route file changes
This plan is groundwork only. No component, route, or App file was touched. Workstream A (Plan 17-02) and Workstream D (Plans 17-04, 17-05) consume `--bottom-chrome-h` from this foundation.
## Verification Results
### Task 1 acceptance criteria
| Criterion | Result |
|-----------|--------|
| `[data-theme="light"]` selector present | PASS |
| `--bottom-chrome-h` present with exact value `calc(56px + env(safe-area-inset-bottom, 0px))` | PASS |
| `--sx-color-*` count still 12 (unchanged) | PASS (12 occurrences) |
| No live `[data-theme="dark"]` rule (commented stub only) | PASS — line is inside `/* ... */` block comment |
| `pnpm --filter @familysync/pwa build` exits 0 | PASS |
### Task 2 verification
| Check | Result |
|-------|--------|
| Grep invariant — no NEW hard-coded hex/px in component/route files | PASS — zero literals introduced by this plan (selector-only change, no component files touched) |
| playwright-cli `/calendar` Schedule-X color sweep | PASS — calendar renders with FamilySync custom colors (member-0 blue #4a90d9 for today-circle + nav active state; shared-family rose #f25c7a for seeded event chip). Not reverting to Schedule-X default blue/green. Screenshot captured. |
| `layout.spec.ts` pixel profile | PASS — 15 passed, 1 skipped (desktop-only, expected); 0 failures |
## Deviations from Plan
None. Plan executed exactly as written. The single selector change in tokens.css was the only modification; all values are verbatim from the original file.
## Known Stubs
None introduced by this plan.
## Noted Observations (Task 2 — Out of Scope)
The grep invariant sweep of `apps/pwa/src/components/` and `apps/pwa/src/routes/` found pre-existing hard-coded literals in multiple files (not introduced by this plan):
- `SyncStateToast.tsx` — hardcoded `#50C878` color (line 105) and `rgba(0,0,0,0.12)` box shadow
- `ListCard.tsx` — hardcoded `56px` min-height (line 68), `4px` border-radius (line 127), `44px`/`44px` touch targets (lines 166167)
- `EmptyState.tsx` — hardcoded `280px` max-width
- Other component files — similar pre-existing literals
These are pre-existing at commit eb0db8b and are explicitly out of scope for Plan 17-01 (selector-only change). They do not affect the plan's deliverable. Noted here per Task 2 instructions.
## Threat Surface Scan
No new trust boundaries, network endpoints, auth paths, or schema changes. This is a static CSS file selector change — no runtime data flow, no new dependencies. Threat model confirmed: T-17-01-01 accepted (CSS custom properties carry no executable content; no new threat above LOW).
## Self-Check: PASSED
| Item | Status |
|------|--------|
| `apps/pwa/src/styles/tokens.css` exists | FOUND |
| `17-01-SUMMARY.md` exists | FOUND |
| Task 1 commit `c2f89bd` in git log | FOUND |
+16 -1
View File
@@ -13,7 +13,8 @@
* theme-default import so they win the cascade. * theme-default import so they win the cascade.
*/ */
:root { :root,
[data-theme="light"] {
/* ───────────────────────────────────────────────────────────────────────── /* ─────────────────────────────────────────────────────────────────────────
* BASE SURFACE / BORDER / TEXT PALETTE * BASE SURFACE / BORDER / TEXT PALETTE
* ───────────────────────────────────────────────────────────────────────── */ * ───────────────────────────────────────────────────────────────────────── */
@@ -62,6 +63,11 @@
--space-8: 32px; --space-8: 32px;
--space-12: 48px; --space-12: 48px;
/* Layout-chrome token — single source of truth for BottomTabBar effective height.
* Consumed by: FAB offset (CalendarShell.tsx), content padding (App.tsx), BottomTabBar.
* Workstreams A and D reference this token; do not hard-code 56px elsewhere. */
--bottom-chrome-h: calc(56px + env(safe-area-inset-bottom, 0px));
/* ───────────────────────────────────────────────────────────────────────── /* ─────────────────────────────────────────────────────────────────────────
* TYPOGRAPHY * TYPOGRAPHY
* ───────────────────────────────────────────────────────────────────────── */ * ───────────────────────────────────────────────────────────────────────── */
@@ -135,6 +141,15 @@
--sx-internal-color-text: var(--color-text-primary); --sx-internal-color-text: var(--color-text-primary);
} }
/* ─────────────────────────────────────────────────────────────────────────
* DARK THEME STUB — Phase 17 groundwork only.
* Values are intentionally absent. Phase 999.20 fills these values and
* wires prefers-color-scheme / data-theme toggle.
* DO NOT add a live rule here until Phase 999.20.
* ─────────────────────────────────────────────────────────────────────────
* [data-theme="dark"] { ... }
* ───────────────────────────────────────────────────────────────────────── */
/* ───────────────────────────────────────────────────────────────────────── /* ─────────────────────────────────────────────────────────────────────────
* SKELETON SHIMMER ANIMATION * SKELETON SHIMMER ANIMATION
* Used by SkeletonCalendar.tsx — no third-party animation library. * Used by SkeletonCalendar.tsx — no third-party animation library.