Skip to content

design-system-v1: token foundation + main-screen overhaul#174

Merged
utof merged 11 commits into
mainfrom
design-system-v1/v0.6.x
May 2, 2026
Merged

design-system-v1: token foundation + main-screen overhaul#174
utof merged 11 commits into
mainfrom
design-system-v1/v0.6.x

Conversation

@utof

@utof utof commented May 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • Tailwind v4 @theme inline token system; shadcn-compatible names
  • ThemeProvider — dark / light / system, prefers-color-scheme aware, localStorage-persisted (NOT Zustand persist mw)
  • Self-hosted variable fonts via @fontsource-variable/{fraunces,inter,jetbrains-mono}
  • Tree-shaken icons via @phosphor-icons/react
  • Main-screen rewrite: App shell + 11 components + 2 routes against new tokens
  • New /type hidden route — type scale + opsz grid + spectrum + theme palette swatches

Test plan

  • CI green (Linux + macOS + Windows)
  • bun run build clean
  • bun test 100% pass
  • bun run lint zero warnings
  • cargo nextest run -p perima-desktop pass (no Rust touched, sanity)
  • just bindings no specta drift
  • bun run tauri dev boots cleanly; no console errors at startup
  • App boots in dark mode; matches reference design at a glance
  • Theme toggle: dark → light → system, each shows expected palette
  • System mode picks up OS-level pref change while running
  • Theme persists after tauri dev restart (localStorage)
  • All 11 components render without layout breaks
  • #/type route renders the full type scale + spectrum + opsz grid
  • Fonts load (no FOUC; Fraunces serif visible on headings)
  • Search / Scan / Backup / dedup all functional (no behavior regressions)

utof added 11 commits May 1, 2026 22:14
…er + Fontsource

- Tailwind v4 @theme inline aliases bound to :root CSS vars; light theme via [data-theme="light"]
- Self-hosted variable fonts via @fontsource-variable/{fraunces,inter,jetbrains-mono}
- @phosphor-icons/react added (consumed in later tasks)
- ThemeProvider context — dark/light/system, prefers-color-scheme aware, localStorage-persisted
  (NOT Zustand persist mw — different state category; preserves Batch H rule)
- Existing components unchanged; they still render via built-in Tailwind colors not affected by @theme
- App.tsx mounts ThemeToggle in topbar; removes legacy bg-gray-900/text-gray-100 classes; adds <main> slot
- ThemeToggle: 3-state cycle (dark → light → system) via Phosphor MoonIcon/SunIcon/MonitorIcon
- aria-label encodes current mode + next action for screen readers
- StatusBar: bg-card / border-border / text-muted-foreground; Backup button uses bg-secondary + design-token focus ring
- NotificationStack: toasts use bg-popover + shadow-e2; error variant uses bg-destructive/10; container moved to top-4 right-4 with pointer-events isolation
- No logic changed — className-only refactor
…Bar + ViewModeToggle)

- ScanButton: bg-primary capsule with DownloadSimpleIcon; preserves existing dialog + scanMutation flow
- SearchBar: bg-input capsule with MagnifyingGlassIcon prefix; debounce/MIN_QUERY_LEN logic untouched
- ViewModeToggle: bg-secondary segmented with GridFourIcon/ListIcon; active state via bg-accent
A11y gap surfaced in T4 review — segmented buttons inside the bg-secondary
pill had no visible focus indicator (Tailwind preflight resets browser default).
Adds focus-visible:ring-2 ring-ring with offset-0 so the indicator stays inside
the pill instead of breaking its rounded edge.
…Table + FileSidebar)

- FileGrid: bg-card tiles + shadow-e1 → shadow-e2 hover; aspect-square moved to thumbnail wrapper so tile fits filename + tags without cropping
- FileTable: hairline rows on border-border; selected row uses bg-accent; mono-metadata for hash/path/volume cells; eyebrow class for column headers
- FileSidebar: bg-popover panel widened to w-96; XIcon close button; mono-metadata for hashes; primary capsule for Compute action; click-to-copy hover uses text-primary
- TagSidebar: bg-card panel widened to w-64; bg-accent active row; rounded-md hover; tabular-nums on count badges
- TagChip: uniform bg-muted capsule (drops 12-color procedural palette); XIcon replaces &times; on removable variant; text-sm
…osition

- Outer wrapper: bg-background; h-full instead of flex-1 (route fills the App.tsx <main> slot)
- Center pane: <section> with min-w-0 overflow-y-auto; drops redundant p-4 (children pad themselves)
- All data-flow + Zustand selectors byte-identical
- CollisionPill: bg-warning pill (unverified) / bg-success pill (all verified) with CopyIcon; drops blue/green/amber text colors
- dedup route: collision cards use bg-card + shadow-e1 + border-border; verify-all = bg-warning capsule; cancel = bg-destructive capsule; per-group verify = bg-primary capsule
- All data-testid + virtualizer config + handler logic byte-identical
…trum + theme palette

- Hidden route; no nav link; reach via #/type
- Static demo of typography classes + Fraunces opsz×weight grid + spectrum specimens + token-color swatches
- Useful for designer iteration and font swaps; survives shipping
…tchMedia mock

- ThemeProvider wraps the test render tree so useTheme() consumers don't crash
- jsdom matchMedia mock installed once at module load (vs per-test beforeEach)
- Defaults to system mode → dark effective theme; tests needing light set localStorage["perima-theme"] in beforeEach
- Cast window to unknown to bypass lib.dom.d.ts "always-defined" typing for the runtime guard
@utof
utof merged commit 073d2a3 into main May 2, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant