Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
177 lines
15 KiB
Markdown
177 lines
15 KiB
Markdown
# Project Research Summary
|
|
|
|
**Project:** Ready2Blob v1.2 -- UI Polish & MD3 Overhaul
|
|
**Domain:** Material Design 3 theming layer on existing React + Tailwind v4 wizard app
|
|
**Researched:** 2026-03-31
|
|
**Confidence:** HIGH
|
|
|
|
## Executive Summary
|
|
|
|
Ready2Blob v1.2 is a pure styling and UX content overhaul of an already-functional 4-step rclone configuration wizard. The existing stack (Vite 6, React 18, TypeScript 5, Tailwind v4, react-hook-form 7, Zod 4, 159 passing tests) is solid and does not need architectural changes. The research unanimously recommends a **zero new runtime dependencies** approach: define Material Design 3 color tokens as CSS custom properties, wire them into Tailwind v4's native `@theme` directive, and build a small set of reusable UI primitives (Button, Input, Card, Select) that replace the current scattered inline markup. The only new dependency is `@material/material-color-utilities` as a dev-only tool for generating MD3 color palettes from a seed color -- it never ships to the browser.
|
|
|
|
The recommended approach is a bottom-up, layer-by-layer migration. First establish the CSS token foundation and dark mode infrastructure (zero component changes, zero test impact). Then extract UI primitives as new additive components. Then swap existing hardcoded colors for semantic tokens one component at a time, running all 159 tests after each change. This ordering is critical because the token system is the foundation for everything else -- dark mode, accent colors, MD3 components, and responsive improvements all depend on it. Content improvements (app intro, step descriptions, remote name clarity) are independent and can be parallelized.
|
|
|
|
The primary risks are: breaking the 131 test selectors across 5 UI test files during component restyling, dark mode contrast failures (WCAG AA), and flash of unstyled content on dark mode load. All three are preventable with the disciplined layer-by-layer approach. The most dangerous anti-pattern is a big-bang restyle where all components are changed at once -- this makes test failures impossible to isolate and virtually guarantees regressions.
|
|
|
|
## Key Findings
|
|
|
|
### Recommended Stack
|
|
|
|
Zero new runtime dependencies. The existing Tailwind v4 handles all styling needs through its CSS-first `@theme` directive and `@custom-variant` for dark mode. One dev dependency added: `@material/material-color-utilities` (v0.4.0) to generate MD3 palettes at build time via a Node script. The output is static CSS custom properties -- zero bundle impact.
|
|
|
|
**Core technologies (all existing, no changes):**
|
|
- **Tailwind v4 `@theme`**: Maps MD3 tokens to utility classes (`bg-surface`, `text-on-primary`) -- native, no plugins
|
|
- **Tailwind v4 `@custom-variant dark`**: Class-based dark mode toggle replacing the removed `darkMode: 'class'` config
|
|
- **CSS custom properties**: ~20 semantic MD3 color roles, elevation shadows, shape radii, motion tokens
|
|
|
|
**New dev dependency only:**
|
|
- **`@material/material-color-utilities` 0.4.0**: Official Google library, generates full MD3 palette from a single seed hex color. Used by a build script (`scripts/generate-theme.ts`) that outputs `src/theme-tokens.css`. NOT bundled.
|
|
|
|
**Explicitly rejected:** MUI, Material Tailwind, shadcn/ui, CSS-in-JS, next-themes, framer-motion, PostCSS plugins, tailwind.config.js, runtime color generation. See STACK.md for detailed rationale on each.
|
|
|
|
### Expected Features
|
|
|
|
**Must have (table stakes -- P1):**
|
|
- MD3 color token system (CSS custom properties for all color roles)
|
|
- MD3 text fields (outlined variant with floating labels)
|
|
- MD3 button hierarchy (filled, outlined, text)
|
|
- MD3 card components with elevation
|
|
- Dark mode toggle (system/light/dark, localStorage persistence)
|
|
- MD3 step indicator (numbered circles, connecting lines, state indicators)
|
|
- Responsive layout (mobile-friendly grids, collapsible step indicator)
|
|
- App intro/landing section explaining what Ready2Blob does
|
|
- Step-level descriptions on each wizard step
|
|
- Remote name field clarity (prominent explanation, examples)
|
|
- Accessible focus states (focus-visible, 3px outline)
|
|
- Tech debt: FieldRenderer aria fix, StepIndicator inline style migration
|
|
|
|
**Should have (differentiators -- P2, add after core is stable):**
|
|
- User-selectable accent color (5-8 curated presets)
|
|
- Animated step transitions (CSS fade/slide, 200ms)
|
|
- Upgraded contextual help popovers
|
|
- Scroll-to-error on validation failure
|
|
|
|
**Defer (v2+):**
|
|
- Custom MD3 select/dropdown (HIGH complexity for 2-3 selects)
|
|
- Code syntax highlighting in review step
|
|
- Arbitrary user hex color theming
|
|
|
|
### Architecture Approach
|
|
|
|
A CSS custom properties layer bridges MD3 tokens with Tailwind v4. A thin `ThemeToggle` component manages the `.dark` class on `<html>` via direct DOM manipulation -- NOT via React Context, to avoid re-rendering the entire wizard tree on toggle. Components are refactored bottom-up: primitives first (Button, Input, Card, Select), then composed components (FieldRenderer, BackendCard), then layout (AppShell, StepIndicator). The critical architectural insight is that theme state belongs in CSS (class on `<html>` + custom properties), not in React state.
|
|
|
|
**Major components:**
|
|
1. **CSS Token Layer** (`index.css` + `theme-tokens.css`) -- MD3 color roles, elevation, shape, motion as `@theme` values
|
|
2. **UI Primitives** (`ui/Button`, `ui/Input`, `ui/Select`, `ui/Card`) -- MD3-styled presentational components using `forwardRef` for react-hook-form compatibility
|
|
3. **ThemeToggle** -- standalone component, local state only, toggles `.dark` class on `<html>`
|
|
4. **AppShell** -- layout wrapper extracted from current WizardShell, houses ThemeToggle
|
|
5. **Modified existing components** -- FieldRenderer, BackendCard, PasswordField, all wizard steps -- swap hardcoded colors for semantic tokens
|
|
|
|
### Critical Pitfalls
|
|
|
|
1. **Tailwind v4 dark mode misconfiguration** -- v3 `darkMode: 'class'` does not exist. Must use `@custom-variant dark (&:where(.dark, .dark *))` in CSS. Address in Phase 1 before any `dark:` classes are added.
|
|
2. **73 hardcoded color classes** -- Adding `dark:` counterparts to each creates unmaintainable 100+ char classNames. Instead, replace all with semantic tokens (`bg-surface`, `text-on-surface`) that swap values automatically via CSS variable override.
|
|
3. **Breaking 131 test selectors** -- Restyling touches the same JSX that tests query. Must restyle one component at a time, running all 159 tests after each. Never batch-restyle.
|
|
4. **FOUC on dark mode load** -- React applies `.dark` class after first paint. Add a synchronous inline `<script>` in `index.html <head>` to set the class before paint.
|
|
5. **Dark mode contrast failures** -- `text-gray-500` on dark backgrounds fails WCAG AA. Semantic tokens must define separate light/dark values verified for 4.5:1 contrast on every pair.
|
|
6. **Theme context re-renders** -- Do NOT use React Context for theme. CSS class toggle on `<html>` causes zero React re-renders. Only the toggle button needs local state.
|
|
|
|
## Implications for Roadmap
|
|
|
|
Based on research, suggested phase structure:
|
|
|
|
### Phase 1: Theme Foundation
|
|
**Rationale:** The token system is the dependency root -- every visual component, dark mode, and accent colors depend on it. Must come first. Zero test impact makes it safe.
|
|
**Delivers:** MD3 color tokens in CSS, dark mode infrastructure (`@custom-variant`, `.dark` overrides), FOUC prevention script in `index.html`, ThemeToggle component, theme generation script (`scripts/generate-theme.ts`)
|
|
**Addresses:** Color token system, dark mode toggle (infrastructure)
|
|
**Avoids:** Tailwind v4 dark mode misconfiguration (P1), FOUC (P5), theme context re-renders (P6)
|
|
|
|
### Phase 2: UI Primitives
|
|
**Rationale:** Primitives are the reuse boundary -- Input, Button, Card are used by multiple steps. Building them before modifying existing components means additive-only changes with zero existing test impact.
|
|
**Delivers:** `ui/Button` (filled/outlined/text), `ui/Input` (outlined, floating label, error), `ui/Select`, `ui/Card` (elevation), new component tests
|
|
**Addresses:** MD3 text fields, MD3 buttons, MD3 cards
|
|
**Avoids:** Big-bang rewrite anti-pattern (P4)
|
|
|
|
### Phase 3: Component Token Migration
|
|
**Rationale:** With tokens and primitives in place, swap hardcoded colors across all existing components. This is the highest-risk phase for test breakage -- one component at a time, tests after each.
|
|
**Delivers:** All components using semantic tokens, FieldRenderer delegating to primitives, BackendCard using Card, PasswordField using Input, StepIndicator inline style migration, FieldRenderer aria-describedby fix
|
|
**Addresses:** Hardcoded color migration (73 usages), tech debt items, form accessibility, MD3 step indicator
|
|
**Avoids:** Hardcoded color dual-track (P2), test breakage (P4), accessibility regressions (P7)
|
|
|
|
### Phase 4: Layout, Content, and Responsive
|
|
**Rationale:** With all components styled, add the layout shell, content improvements, and responsive behavior. These are mostly independent of each other and can be parallelized.
|
|
**Delivers:** AppShell layout, app intro section, step descriptions, remote name clarity, responsive grid/breakpoints, dark mode UX polish (scrollbars, select dropdowns, focus rings)
|
|
**Addresses:** App intro, step descriptions, remote name clarity, responsive layout, accessible focus states
|
|
**Avoids:** Dark mode contrast failures (P3) -- final contrast audit here
|
|
|
|
### Phase 5: Polish and Differentiators
|
|
**Rationale:** Accent colors and transitions layer on top of the stable token system. These are P2 features that should only land after core is validated.
|
|
**Delivers:** Accent color selector (5-8 presets), step transitions (CSS), upgraded popovers, scroll-to-error
|
|
**Addresses:** All P2 differentiator features
|
|
**Avoids:** Premature accent color work before token system is proven
|
|
|
|
### Phase Ordering Rationale
|
|
|
|
- **Token system first** because 100% of visual components depend on it (see FEATURES.md dependency graph)
|
|
- **Primitives before migration** because building new components is additive (zero test risk), while modifying existing components carries test risk
|
|
- **One-component-at-a-time migration** because the 131 test selectors across 5 files make batch changes dangerous
|
|
- **Content and layout after components** because layout depends on component dimensions and spacing, and content is independent
|
|
- **Differentiators last** because accent colors multiply token sets (N accents x 2 themes) and must not be attempted until the base system is stable
|
|
|
|
### Research Flags
|
|
|
|
Phases likely needing deeper research during planning:
|
|
- **Phase 2 (UI Primitives):** MD3 outlined text field with floating label is the most complex primitive. CSS-only floating label animation needs prototyping. `forwardRef` integration with react-hook-form `register()` needs verification.
|
|
- **Phase 3 (Component Migration):** The FieldRenderer refactor to delegate to primitives is the highest-risk change. DOM structure changes could break tests. Needs careful planning of the migration path per field type.
|
|
|
|
Phases with standard patterns (skip research-phase):
|
|
- **Phase 1 (Theme Foundation):** Fully documented in Tailwind v4 official docs. Token structure is defined. FOUC script is a known 5-line pattern.
|
|
- **Phase 4 (Layout/Content):** Content writing and responsive Tailwind grids are standard work. No novel patterns.
|
|
- **Phase 5 (Polish):** Accent colors are a token swap. Step transitions are CSS-only. Well-documented patterns.
|
|
|
|
## Confidence Assessment
|
|
|
|
| Area | Confidence | Notes |
|
|
|------|------------|-------|
|
|
| Stack | HIGH | Zero new runtime deps. Tailwind v4 `@theme` and `@custom-variant` verified in official docs. `@material/material-color-utilities` is official Google package. |
|
|
| Features | MEDIUM | Table stakes and differentiators well-identified. MD3 web implementation patterns less established than MUI-based approaches since we are hand-rolling with Tailwind. |
|
|
| Architecture | HIGH | CSS custom properties + Tailwind v4 `@theme` is the documented approach. Bottom-up migration is low-risk. ThemeToggle via DOM class (not Context) avoids re-render cascade. |
|
|
| Pitfalls | HIGH | Based on direct codebase analysis (73 classNames, 131 selectors, 3 inline styles). Tailwind v4 dark mode gotchas verified against official docs and community reports. |
|
|
|
|
**Overall confidence:** HIGH
|
|
|
|
### Gaps to Address
|
|
|
|
- **MD3 elevation box-shadow values**: Sourced from community reference, not official Google CSS. The exact shadow values are approximations. Validate visually during Phase 1 and adjust if needed.
|
|
- **MD3 outlined text field floating label**: CSS-only implementation needs prototyping. May require a small JS hook for detecting input fill state (`:placeholder-shown` selector or `onFocus`/`onBlur` handlers). Validate during Phase 2 planning.
|
|
- **Native `<select>` in dark mode**: Browser renders `<option>` with OS colors. May look broken on dark backgrounds in some browsers. Evaluate during Phase 4 whether to accept native rendering or build custom dropdown (deferred to v2+ per feature research).
|
|
- **Pre-generated accent color token sets**: The approach of pre-generating N accent x 2 theme token sets at build time has not been prototyped. If the CSS file grows too large, runtime generation (bundling the color utility) may be reconsidered. Validate during Phase 5.
|
|
|
|
## Sources
|
|
|
|
### Primary (HIGH confidence)
|
|
- [Tailwind v4 Dark Mode Documentation](https://tailwindcss.com/docs/dark-mode) -- `@custom-variant` syntax, class-based toggle
|
|
- [Tailwind v4 Theme Documentation](https://tailwindcss.com/docs/theme) -- `@theme` directive, CSS variable generation
|
|
- [Material Design 3 Color Roles](https://m3.material.io/styles/color/roles) -- semantic color role definitions
|
|
- [Material Design 3 Design Tokens](https://m3.material.io/foundations/design-tokens) -- token naming conventions
|
|
- [Material Design 3 Shape Scale](https://m3.material.io/styles/shape/corner-radius-scale) -- radius values
|
|
- [Material Design 3 Elevation](https://m3.material.io/styles/elevation/applying-elevation) -- elevation levels 0-5
|
|
- [@material/material-color-utilities](https://www.npmjs.com/package/@material/material-color-utilities) -- v0.4.0, official Google package
|
|
- Codebase analysis: 73 className usages, 131 test selectors, 159 tests, 3 inline styles in StepIndicator
|
|
|
|
### Secondary (MEDIUM confidence)
|
|
- [MD3 Box-Shadow CSS Values](https://studioncreations.com/blog/material-design-3-box-shadow-css-values/) -- elevation shadow approximations
|
|
- [Tailwind v4 dark mode @custom-variant discussion](https://github.com/tailwindlabs/tailwindcss/discussions/15083) -- community verified pattern
|
|
- [Tailwind v4 Multi-Theme Strategy](https://simonswiss.com/posts/tailwind-v4-multi-theme) -- community pattern for theme switching
|
|
- [Material Theme Builder](https://material-foundation.github.io/material-theme-builder/) -- CSS export format reference
|
|
- [Wizard Design Pattern (UX Planet)](https://uxplanet.org/wizard-design-pattern-8c86e14f2a38) -- wizard UX fundamentals
|
|
- [Wizards (NN/g)](https://www.nngroup.com/articles/wizards/) -- Nielsen Norman Group guidelines
|
|
- [Input Field Design Best Practices 2025](https://fireart.studio/blog/input-field-design-best-practice/) -- floating labels, error patterns
|
|
|
|
### Tertiary (LOW confidence)
|
|
- [m3-tailwind-colors](https://github.com/somteacodes/m3-tailwind-colors) -- evaluated and rejected (3 stars, single maintainer)
|
|
|
|
---
|
|
*Research completed: 2026-03-31*
|
|
*Ready for roadmap: yes*
|