From c2f89bd55f0bd701b292af6c9d39450f77ae8ae6 Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Thu, 18 Jun 2026 12:12:42 -0400 Subject: [PATCH 1/2] feat(17-01): restructure tokens.css to combined :root,[data-theme=light] selector + add --bottom-chrome-h - Change :root { to :root, [data-theme="light"] { (D-06 combined selector) - Add --bottom-chrome-h: calc(56px + env(safe-area-inset-bottom, 0px)) to spacing scale - Keep all 12 --sx-color-* overrides inside the combined block (cascade unchanged) - Keep --brand-logo-* tokens inside the combined block (verbatim, no value changes) - Add dark-theme stub as comment-only (Phase 999.20 fills values; no live rule) - All existing values unchanged; PWA build passes; Schedule-X colors verified via playwright-cli --- apps/pwa/src/styles/tokens.css | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/apps/pwa/src/styles/tokens.css b/apps/pwa/src/styles/tokens.css index ea5d94e..0edc200 100644 --- a/apps/pwa/src/styles/tokens.css +++ b/apps/pwa/src/styles/tokens.css @@ -13,7 +13,8 @@ * theme-default import so they win the cascade. */ -:root { +:root, +[data-theme="light"] { /* ───────────────────────────────────────────────────────────────────────── * BASE SURFACE / BORDER / TEXT PALETTE * ───────────────────────────────────────────────────────────────────────── */ @@ -62,6 +63,11 @@ --space-8: 32px; --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 * ───────────────────────────────────────────────────────────────────────── */ @@ -135,6 +141,15 @@ --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 * Used by SkeletonCalendar.tsx — no third-party animation library. From d01ec2388c34ea6b339288a5ec779f14423e906c Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Thu, 18 Jun 2026 12:14:45 -0400 Subject: [PATCH 2/2] =?UTF-8?q?docs(17-01):=20complete=20token=20groundwor?= =?UTF-8?q?k=20plan=20=E2=80=94=20SUMMARY?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tokens.css restructured to :root,[data-theme=light] combined selector; --bottom-chrome-h added; all --sx-color-* overrides intact; build green; layout.spec.ts pixel profile 15/15 pass; Schedule-X colors verified. --- .../17-01-SUMMARY.md | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 .planning/phases/17-ui-optimization-polish/17-01-SUMMARY.md diff --git a/.planning/phases/17-ui-optimization-polish/17-01-SUMMARY.md b/.planning/phases/17-ui-optimization-polish/17-01-SUMMARY.md new file mode 100644 index 0000000..92a943d --- /dev/null +++ b/.planning/phases/17-ui-optimization-polish/17-01-SUMMARY.md @@ -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 166–167) +- `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 |