Story 4.1.1: Setup shadcn/ui & Dark Theme
Table of Contents
- Story 4.1.1: Setup shadcn/ui & Dark Theme
- Status
- Story
- Domain Context
- Requirements Context
- Architecture Context
- Wireframe Context
- Acceptance Criteria
- Tasks / Subtasks
- Dev Notes - Implementation Guide
- Change Log
- Dev Agent Record
- QA Results
- Review Date: 2025-11-02
- Reviewed By: Quinn (Test Architect)
- Code Quality Assessment
- Refactoring Performed
- Compliance Check
- Improvements Checklist
- Security Review
- Performance Considerations
- Test Architecture Assessment
- Requirements Traceability
- Non-Functional Requirements Assessment
- Files Modified During Review
- Gate Status
- Recommended Status
Story 4.1.1: Setup shadcn/ui & Dark Theme
Status
Done
Story
As a developer, I want to set up shadcn/ui components with a dark theme design system, so that we can build the modern public website with consistent styling and components.
Domain Context
Primary Domain
Shared/Infrastructure (Cross-cutting concerns - Frontend foundation)
Involved Services
- web-frontend (React 19 + TypeScript)
- No backend services involved in this setup story
Cross-Domain Dependencies
None - This is pure frontend infrastructure setup
Requirements Context
Related Functional Requirements
- Epic 4: Public Website & Content Discovery
- Story 4.1: Current Event Landing Page with Registration
- Supports all UI requirements with modern component library
Acceptance Criteria Source
Setup requirements derived from implementation plan for Story 4.1
Architecture Context
Architecture Patterns
- Frontend Architecture (05-frontend-architecture.md): React components, Tailwind CSS
- Design System: shadcn/ui components (new for public website)
- Existing: Material-UI for authenticated portal (unchanged)
Infrastructure Components
- Node.js 20+ runtime
- npm package manager
- Vite build tool (already configured)
- Tailwind CSS 4.1.14 (already installed)
Wireframe Context
Wireframe References
/docs/wireframes/batbern-newdesign.html- Reference for dark theme aesthetic
Design Specifications
Dark Theme Colors:
- Background:
zinc-950(almost black) - Text:
zinc-100(off-white) - Accent:
blue-400(bright blue for CTAs) - Secondary:
zinc-800(dark gray for cards)
Typography:
- Font weight: Ultra-light headings (
font-light) - Generous whitespace for modern feel
- Sans-serif font family
Component Style:
- Clean, minimal design
- Rounded corners (
rounded-lg) - Subtle shadows and borders
- Hover states with smooth transitions
Acceptance Criteria
- shadcn/ui dependencies installed and configured
- Tailwind dark theme configured with zinc/blue color palette
- Component directory structure created at
src/components/public/ui/ - Core shadcn components installed (button, card, badge, dialog, form, tabs)
- TypeScript utilities configured for component composition (clsx, class-variance-authority)
- Existing Material-UI components for portal unaffected
- Build completes successfully with no errors
Tasks / Subtasks
-
Task 1: Install shadcn/ui dependencies
- Install Radix UI primitives:
@radix-ui/react-dialog,@radix-ui/react-dropdown-menu,@radix-ui/react-select, - Install composition utilities:
class-variance-authority,clsx,
- Install Radix UI primitives:
-
Task 2: Initialize shadcn/ui configuration
- Run
npx shadcn-ui@latest init - Configure
components.json- style: βnew-yorkβ
- baseColor: βzincβ
- cssVariables: true
- Component alias:
@/components/public/ui
- Create
src/lib/utils.ts
- Run
-
Task 3: Configure Tailwind dark theme
- Update
tailwind.config.js
- Update
-
Task 4: Install core shadcn components
- Install button:
- Install card:
- Install badge:
- Install dialog:
- Install form:
- Install tabs:
- Verify all components created in
-
Task 5: Create public component directory structure
- Create
src/components/public/ - Create
src/components/public/ui/ - Create
src/styles/public.css - Update
src/index.css
- Create
-
Task 6: Verify build and compatibility
- Run
npm run build - Run
npm run type-check - Test dev server starts:
- Run
-
Task 7: Create simple test component
- Create
src/components/public/ShadcnTest.tsx - Add dark theme wrapper with
- Create
Dev Notes - Implementation Guide
Service Setup
Location: BATbern-develop/web-frontend/
Directory Structure:
web-frontend/
βββ src/
β βββ components/
β β βββ auth/ # Existing Material-UI
β β βββ organizer/ # Existing Material-UI
β β βββ shared/ # Existing Material-UI
β β βββ public/ # NEW - shadcn components
β β βββ ui/ # Auto-created by shadcn CLI
β βββ lib/
β β βββ utils.ts # NEW - cn() utility
β βββ styles/
β βββ public.css # NEW - Custom public styles
βββ components.json # NEW - shadcn config
βββ package.json
Installation Commands
Step 1: Install dependencies
cd web-frontend
npm install @radix-ui/react-dialog @radix-ui/react-dropdown-menu @radix-ui/react-select @radix-ui/react-tabs @radix-ui/react-slot
npm install class-variance-authority clsx tailwind-merge
Step 2: Initialize shadcn/ui
npx shadcn-ui@latest init
# Select:
# - TypeScript: Yes
# - Style: New York
# - Base color: Zinc
# - CSS variables: Yes
# - Import alias: @/components/public/ui
Step 3: Install components
npx shadcn-ui@latest add button card badge dialog form tabs
Configuration Files
components.json (created by init):
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "tailwind.config.js",
"css": "src/index.css",
"baseColor": "zinc",
"cssVariables": true
},
"aliases": {
"components": "@/components/public/ui",
"utils": "@/lib/utils"
}
}
src/lib/utils.ts (utility for component composition):
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
tailwind.config.js (update for dark theme):
/** @type {import('tailwindcss').Config} */
export default {
darkMode: ["class"],
content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {
colors: {
// Existing MUI colors remain
// shadcn zinc palette (auto-configured by CLI)
// Custom accents
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
},
},
},
plugins: [require("tailwindcss-animate")],
}
src/index.css (ensure Tailwind directives present):
@tailwind base;
@tailwind components;
@tailwind utilities;
/* Dark theme CSS variables will be auto-injected by shadcn */
Verification Test Component
Create temporary test component to verify setup:
src/components/public/ShadcnTest.tsx:
import { Button } from "@/components/public/ui/button"
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/public/ui/card"
import { Badge } from "@/components/public/ui/badge"
export const ShadcnTest = () => {
return (
<div className="dark min-h-screen bg-zinc-950 p-8">
<Card className="max-w-md">
<CardHeader>
<CardTitle>shadcn/ui Setup Test</CardTitle>
<CardDescription>Dark theme with zinc palette</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex gap-2">
<Badge>Technology</Badge>
<Badge variant="outline">Innovation</Badge>
</div>
<Button className="w-full">Test Button</Button>
<Button variant="outline" className="w-full">Outline Button</Button>
</CardContent>
</Card>
</div>
)
}
Render in App.tsx temporarily to verify, then remove.
Code Patterns
Using shadcn components in public pages:
// Public components use shadcn/ui
import { Button } from "@/components/public/ui/button"
// Authenticated portal components still use Material-UI
import { Button as MuiButton } from "@mui/material"
Dark theme wrapper:
export const PublicLayout = ({ children }) => {
return (
<div className="dark min-h-screen bg-zinc-950 text-zinc-100">
{children}
</div>
)
}
Package.json Changes
After installation, verify these new dependencies in package.json:
{
"dependencies": {
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-slot": "^1.0.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"tailwind-merge": "^2.2.1",
"tailwindcss-animate": "^1.0.7"
}
}
Testing Requirements
Build Verification:
# Type check
npm run type-check
# Build
npm run build
# Should complete with no errors
Compatibility Check:
- Ensure existing Material-UI components still work
- No conflicts between MUI and shadcn imports
- Both design systems can coexist
Visual Verification:
- Render ShadcnTest component
- Verify dark background (zinc-950)
- Verify components render with proper styling
- Check responsive behavior
Definition of Done Checklist
Development Complete:
No Tests Required - This is infrastructure setup only
Change Log
| Date | Version | Description | Author |
|---|---|---|---|
| 2025-11-02 | 1.0 | Initial story creation | Winston (Architect Agent) |
| 2025-11-02 | 1.1 | Implementation completed - shadcn/ui setup with dark theme | James (Dev Agent) |
Dev Agent Record
Agent Model Used
Claude Sonnet 4.5 (claude-sonnet-4-5-20250929)
Completion Notes
- β All shadcn/ui dependencies installed successfully
- β Configuration files created (components.json, utils.ts)
- β Tailwind dark mode configured with zinc palette and CSS variables
- β All core components installed (button, card, badge, dialog, form, tabs, label)
- β Fixed nested ui directory issue (moved files from ui/ui/ to ui/)
- β Fixed form.tsx import path for label component
- β Installed missing @radix-ui/react-icons dependency
- β TypeScript compilation successful
- β Production build successful (built in 10.01s)
- β Material-UI components remain unaffected
- β Test component created, verified, and removed as per requirements
Debug Log References
None - implementation completed without issues
File List
Created:
web-frontend/components.jsonweb-frontend/src/lib/utils.tsweb-frontend/src/styles/public.cssweb-frontend/src/components/public/ui/button.tsxweb-frontend/src/components/public/ui/card.tsxweb-frontend/src/components/public/ui/badge.tsxweb-frontend/src/components/public/ui/dialog.tsxweb-frontend/src/components/public/ui/form.tsxweb-frontend/src/components/public/ui/tabs.tsxweb-frontend/src/components/public/ui/label.tsx
Modified:
web-frontend/package.json(added shadcn dependencies)web-frontend/package-lock.json(dependency lockfile)web-frontend/tailwind.config.js(dark mode, CSS variables, animations)web-frontend/src/index.css(CSS variables for dark theme)
Deployment Notes
- No deployment required - local development only
- Changes will be deployed with Story 4.1.2
QA Results
Review Date: 2025-11-02
Reviewed By: Quinn (Test Architect)
Code Quality Assessment
Overall: EXCELLENT β
This infrastructure setup story demonstrates high-quality implementation with careful attention to configuration details. All acceptance criteria have been fully met with proper dependency management, configuration, and verification steps. The implementation follows shadcn/ui best practices and successfully integrates the dark theme design system without disrupting existing Material-UI components.
Strengths:
- Clean, well-organized configuration files (components.json, utils.ts)
- Proper CSS variable setup for themeable components
- Comprehensive dark theme implementation with HSL color values
- All required Radix UI primitives and utilities installed
- TypeScript compilation successful with no errors
- Production build successful (10.01s)
- Material-UI compatibility verified and maintained
Minor Observations:
- The implementation correctly handles the dual design system approach (shadcn for public, MUI for authenticated)
- Import aliases properly configured in vite.config.ts (@/ resolving to src/)
- Dev identified and fixed nested directory issue (ui/ui/ β ui/)
- Dev proactively installed missing @radix-ui/react-icons dependency
Refactoring Performed
No refactoring performed - This is a pure infrastructure setup story with generated component code from shadcn CLI. The components are standard shadcn templates and should not be modified.
Compliance Check
- Coding Standards: β N/A - Infrastructure setup, no custom code written
- Project Structure: β PASS - Correctly created
src/components/public/ui/directory structure - Testing Strategy: β PASS - Appropriate for infrastructure setup (manual verification)
- All ACs Met: β PASS - All 7 acceptance criteria fully satisfied
AC Validation:
- β shadcn/ui dependencies installed and configured
- β Tailwind dark theme configured with zinc/blue color palette (verified in tailwind.config.js and index.css)
- β
Component directory structure created at
src/components/public/ui/ - β Core shadcn components installed (button, card, badge, dialog, form, tabs + label)
- β TypeScript utilities configured (clsx, class-variance-authority)
- β Existing Material-UI components for portal unaffected
- β Build completes successfully with no errors
Improvements Checklist
All items completed by Dev during implementation:
No additional improvements needed - Implementation is production-ready.
Security Review
Status: PASS β
No security concerns for this infrastructure setup story. The shadcn/ui components and Radix UI primitives are well-maintained open-source libraries with active security maintenance.
Dependency Security:
- All dependencies are from trusted sources (@radix-ui, shadcn/ui official registry)
- No custom code that could introduce vulnerabilities
- Dependencies follow semantic versioning with caret ranges (^)
Performance Considerations
Status: PASS β
Build Performance:
- Production build completed in 10.01s (excellent)
- Gzip compression active and working
- Brotli compression active and working
- Code splitting maintained for shadcn components
Runtime Performance:
- shadcn/ui components are lightweight and performant
- CSS-in-JS avoided (uses Tailwind utility classes)
- Dark theme uses CSS variables (no runtime overhead)
- No performance regressions expected
Bundle Size Impact:
- New dependencies add ~87 packages (reasonable for component library)
- Components are tree-shakeable
- Only imported components will be bundled in final build
Test Architecture Assessment
Status: APPROPRIATE β
Testing Approach: This infrastructure setup story appropriately does not require automated tests. The story explicitly states βNo Tests Required - This is infrastructure setup only.β
Verification Strategy Used:
- β
TypeScript compilation (
npm run type-check) - β
Production build verification (
npm run build) - β
Linting verification (
npm run lint- 4 warnings, acceptable) - β Manual component rendering test (ShadcnTest.tsx created and removed)
- β Material-UI compatibility check (existing components unaffected)
Rationale: Infrastructure setup stories are validated through:
- Build-time checks (TypeScript, linting)
- Integration verification (build success)
- Manual visual verification (test component)
This approach is appropriate and aligns with industry best practices for design system/component library integration.
Requirements Traceability
All Acceptance Criteria β Verification Mapping:
AC1: shadcn/ui dependencies installed and configured
- Given: New project needs shadcn/ui components
- When: Dependencies installed via npm
- Then: package.json contains all required @radix-ui packages and utilities
- Evidence: package.json lines showing @radix-ui/react-dialog, dropdown-menu, select, tabs, slot, icons, label + class-variance-authority, clsx, tailwind-merge, tailwindcss-animate
AC2: Tailwind dark theme configured with zinc/blue color palette
- Given: Dark theme design requirements
- When: Tailwind config and CSS variables configured
- Then: Dark mode uses βclassβ strategy with zinc palette and CSS variables
- Evidence: tailwind.config.js (darkMode: [βclassβ]), index.css (CSS variables for :root and .dark)
AC3: Component directory structure created at src/components/public/ui/
- Given: Need for isolated public component directory
- When: Directory structure created
- Then: src/components/public/ui/ exists with shadcn components
- Evidence: Directory listing shows 7 component files in correct location
AC4: Core shadcn components installed
- Given: Need for button, card, badge, dialog, form, tabs components
- When: Components installed via shadcn CLI
- Then: All 7 components (including label) exist as .tsx files
- Evidence: button.tsx, card.tsx, badge.tsx, dialog.tsx, form.tsx, tabs.tsx, label.tsx
AC5: TypeScript utilities configured
- Given: Need for component composition utilities
- When: class-variance-authority, clsx, tailwind-merge installed and utils.ts created
- Then: cn() utility function available for component styling
- Evidence: src/lib/utils.ts with cn() function implementation
AC6: Existing Material-UI components unaffected
- Given: Dual design system requirement
- When: shadcn added alongside existing MUI
- Then: Build succeeds and MUI imports work correctly
- Evidence: Build success + lint shows only 4 fast-refresh warnings (not MUI conflicts)
AC7: Build completes successfully
- Given: All setup complete
- When: Production build executed
- Then: Build completes with no errors
- Evidence: Build log shows successful completion in 10.01s with PWA and compression
Coverage Assessment: 7/7 acceptance criteria validated (100%)
Non-Functional Requirements Assessment
Maintainability: EXCELLENT β
- Configuration files are well-structured and documented
- shadcn components follow consistent patterns
- Import aliases simplify component usage
- CSS variables enable easy theme customization
Compatibility: EXCELLENT β
- Successfully maintains dual design system (shadcn + MUI)
- No conflicts between component libraries
- Separate namespaces prevent collisions
Extensibility: EXCELLENT β
- Easy to add additional shadcn components via CLI
- Theme customization through CSS variables
- Component composition via cn() utility
Documentation: GOOD β
- Story file includes comprehensive implementation guide
- Configuration examples provided
- Dev notes document all setup steps
- Minor: Could benefit from inline comments in tailwind.config.js explaining color variable structure
Files Modified During Review
None - No files modified during QA review. Implementation is complete and correct.
Gate Status
Gate: PASS β docs/qa/gates/4.1.1-setup-shadcn-dark-theme.yml
Decision Rationale: All acceptance criteria met with high-quality implementation. No blocking issues, no security concerns, appropriate testing strategy for infrastructure setup. Build verification and compatibility checks confirm production readiness.
Recommended Status
β Ready for Done
This story is complete and ready to move to Done status. The infrastructure setup provides a solid foundation for Story 4.1.2 (Public Layout & Navigation) to build upon.
Next Steps:
- Story owner to update status to βDoneβ
- Subsequent stories (4.1.2+) can proceed with building public website components using shadcn/ui