Repository navigation
ADR Styling and UI Framework
status: implemented decided: 2026-08-26 decision: "Target state: Tailwind CSS + shadcn/ui (Radix-based). #117 lands the foundation; #118 migrates the rest against a written guideline." related_issues: [76, 117, 118, 54, 46]
Status: Implemented Related: Architecture · Contributing-UI-Guidelines · GitHub #76 (this spike) · #117 (foundation) · #118 (compliance) · follow-up from #54 (Next.js migration) · part of #46
The Next.js migration (#54) kept CSS Modules as-is to stay in scope, leaving styling and components undecided. Current state:
- 15
*.module.cssfiles (src/screens/,src/components/), all hand-written, no shared primitives. - No shared
Button/Input/etc. layer — every screen builds its own controls. -
ShareModal.tsx(a representative interactive component) has no focus trap, no Escape-to-close, norole="dialog"/aria-modal, and no focus return on close. - Codebase is expected to grow; migration cost compounds with every new component added under the old approach.
This ADR fixes one target state for styling and components, recorded operationally in Contributing-UI-Guidelines, so new work has a single direction instead of a per-change judgment call.
| Criterion | CSS Modules (status quo) | Tailwind CSS | Winner |
|---|---|---|---|
| Setup cost | Built into Next.js, zero config | Needs Tailwind config + PostCSS (one-time) | CSS Modules |
| Cost to bring existing code to target state | None — already written | ~15 files rewritten as utility classes | CSS Modules |
| shadcn/ui compatibility | Not supported — shadcn ships Tailwind-styled components | Native | Tailwind |
| AI-assisted edit consistency | Less represented in LLM training data | Majority of AI-generated Next.js/React code in 2026 uses Tailwind | Tailwind |
| Next.js ecosystem adoption, 2026 | Minority choice for new projects | Majority choice for new projects | Tailwind |
| Bundle size at this project's scale | Negligible | Negligible | Tie |
| Criterion | Hand-rolled (status quo) | Radix UI (bare, unstyled) | shadcn/ui | Winner |
|---|---|---|---|---|
| Accessibility (focus trap, ARIA, keyboard nav) | Missing — confirmed gap in ShareModal.tsx
|
Correct out of the box | Correct (built on Radix) | Radix / shadcn |
Shared Button/Input/Dialog set |
None exists | None — each primitive hand-styled from scratch | Ships pre-styled, copy-in | shadcn/ui |
| Ownership / lock-in | Full (all in-repo) | Full (plain npm dependency) | Full — components are copied into the repo, not installed as a black box | Tie |
| Time to a working primitives layer | N/A, not built | Slow — style every primitive by hand | Fast — CLI copies ready components | shadcn/ui |
| Styling-system dependency | None | None (unstyled) | Assumes Tailwind | Radix, but moot — Tailwind already wins above |
Tailwind CSS + shadcn/ui, shadcn's Radix-based components as the shared primitives layer (Button, Input, Select, Dialog, etc.).
- Tailwind over CSS Modules: wins 3 of 5 non-tied criteria above, and is a hard prerequisite for shadcn/ui, which wins the components comparison outright.
- shadcn/ui over bare Radix: same accessibility fix, but ships a real component set immediately instead of requiring every primitive to be hand-styled first.
-
Rollout, not a rewrite: #117 installs the tooling and pilots the pattern on
ShareModal— the one component with a confirmed, concrete accessibility gap. #118 migrates the remaining CSS Modules and hand-rolled components against Contributing-UI-Guidelines as its own follow-up, not a single large rewrite.
- New UI work uses Tailwind + shadcn/ui — no new
*.module.cssfiles, no new hand-rolled interactive components. -
ShareModal,UploadModal, and the remaining*.module.cssfiles migrate via #117 (foundation +ShareModalpilot) and #118 (the rest). - Contributing-UI-Guidelines is the operational reference: when to use a shadcn primitive vs. custom composition, Tailwind conventions, design-token definitions.
- CLAUDE.md's tech stack line changes from "CSS Modules" to "Tailwind CSS + shadcn/ui" once #117 and #118 land.
Researched August 2026: Tailwind vs CSS Modules tradeoffs (bundle size, DX, AI-tooling fit) and Radix UI vs shadcn/ui vs hand-rolled components for small Next.js projects, cross-referenced against this repo's actual CSS Module usage and the accessibility gap in ShareModal.tsx. Ecosystem-adoption claims move fast — re-verify against current sources before treating "majority choice" as settled fact.