2026-01-11 01:37:48 +00:00
|
|
|
import { Palette } from 'lucide-react';
|
|
|
|
|
|
|
|
|
|
interface ThemeSwitcherProps {
|
2026-01-13 18:47:57 +00:00
|
|
|
currentTheme: string;
|
|
|
|
|
onThemeChange: (theme: string) => void;
|
2026-01-11 01:37:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const themes = [
|
2026-01-13 18:47:57 +00:00
|
|
|
{
|
2026-03-23 14:44:37 +00:00
|
|
|
id: 'bokuseki',
|
|
|
|
|
name: '墨跡 Bokuseki',
|
2026-04-30 21:05:32 +00:00
|
|
|
colors: ['var(--sumi-accent)', 'var(--sumi-accent-active)'],
|
fix: stabilize builds, tests, and lint across all stacks
Complete stabilization pass bringing all 3 stacks to green:
Frontend (apps/web/):
- Fix TypeScript nullability in useSeason.ts, useTimeOfDay.ts hooks
- Disable no-undef in ESLint config (TypeScript handles it; JSX misidentified)
- Rename 306 story imports from @storybook/react to @storybook/react-vite
- Fix conditional hook call in useMediaQuery.ts useIsTablet
- Move useQuery to top of LoginPage.tsx component
- Remove useless try/catch in GearFormModal.tsx
- Fix stale closure in ResetPasswordPage.tsx handleChange
- Make Storybook decorators (withRouter, withQueryClient, withToast, withAudio)
no-ops since global StorybookDecorator already provides these — prevents
nested Router / duplicate provider crashes in vitest-browser
- Fix nested MemoryRouter in 3 page stories (TrackDetail, PlaylistDetail, UserProfile)
- Update i18n initialization in test setup (await init before changeLanguage)
- Update ~30 test assertions from English to French to match i18n translations
- Update test assertions to match SUMI V3 design changes (shadow vs border)
- Fix remaining story type errors (PlayerError, PlaylistBatchActions,
TrackFilters, VirtualizedChatMessages)
Backend (veza-backend-api/):
- Fix response_test.go RespondWithAppError signature (2 args, not 3)
- Fix TestErrorContractAuthEndpoints expected error codes
(ErrCodeUnauthorized vs ErrCodeInvalidCredentials)
- Fix TestTrackHandler_GetTrackLikes_Success missing auth middleware setup
- Fix TestPlaybackAnalyticsService_GetTrackStats k-anonymity threshold
(needs 5 unique users, not 1)
- Replace NOW() PostgreSQL function with time.Now() parameter in marketplace
service for SQLite test compatibility
- Add missing AutoMigrate entries in marketplace_test.go
(ProductImage, ProductPreview, ProductLicense, ProductReview)
Results:
- Frontend TypeCheck: 617 errors -> 0 errors
- Frontend ESLint: 349 errors -> 0 errors
- Frontend Vitest: 196 failing tests -> 1 skipped (3396/3397 passing)
- Backend go vet: 1 error -> 0 errors
- Backend tests: 5 failing -> all 13 packages passing
- Rust: 150/150 tests passing (unchanged)
- Storybook audit: 0 errors across 1244 stories
Triage report: docs/TRIAGE_REPORT.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 14:48:07 +00:00
|
|
|
description: 'Ink Traces — mizu cyan',
|
2026-04-30 21:05:32 +00:00
|
|
|
gradient: 'linear-gradient(135deg, var(--sumi-accent) 0%, var(--sumi-accent-active) 100%)',
|
2026-01-13 18:47:57 +00:00
|
|
|
},
|
|
|
|
|
{
|
2026-03-23 14:44:37 +00:00
|
|
|
id: 'kin',
|
|
|
|
|
name: '金 Kin',
|
2026-04-30 21:05:32 +00:00
|
|
|
colors: ['var(--sumi-kin)', '#8b6a08'],
|
2026-03-23 14:44:37 +00:00
|
|
|
description: 'Gold Leaf — kinpaku',
|
2026-04-30 21:05:32 +00:00
|
|
|
gradient: 'linear-gradient(135deg, var(--sumi-kin) 0%, #8b6a08 100%)',
|
2026-01-13 18:47:57 +00:00
|
|
|
},
|
|
|
|
|
{
|
2026-03-23 14:44:37 +00:00
|
|
|
id: 'ai',
|
|
|
|
|
name: '藍 Ai',
|
2026-04-30 21:05:32 +00:00
|
|
|
colors: ['var(--sumi-ai)', '#1a3548'],
|
2026-03-23 14:44:37 +00:00
|
|
|
description: 'Indigo — deep blue',
|
2026-04-30 21:05:32 +00:00
|
|
|
gradient: 'linear-gradient(135deg, var(--sumi-ai) 0%, #1a3548 100%)',
|
2026-01-13 18:47:57 +00:00
|
|
|
},
|
|
|
|
|
{
|
2026-03-23 14:44:37 +00:00
|
|
|
id: 'matcha',
|
|
|
|
|
name: '抹茶 Matcha',
|
|
|
|
|
colors: ['#4f6840', '#3a5030'],
|
|
|
|
|
description: 'Green tea — moss',
|
|
|
|
|
gradient: 'linear-gradient(135deg, #4f6840 0%, #3a5030 100%)',
|
2026-01-13 18:47:57 +00:00
|
|
|
},
|
2026-01-11 01:37:48 +00:00
|
|
|
];
|
|
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
export function ThemeSwitcher({
|
|
|
|
|
currentTheme,
|
|
|
|
|
onThemeChange,
|
|
|
|
|
}: ThemeSwitcherProps) {
|
|
|
|
|
return (
|
|
|
|
|
<div className="space-y-6">
|
aesthetic-improvements: align spacing to 8px grid (Action 11.2.1.3)
- Created automated script (scripts/align-8px-grid.py) to align all spacing to 8px grid
- Replaced non-8px-aligned spacing: gap-3/p-3/m-3 (12px) → gap-4/p-4/m-4 (16px), gap-5/p-5/m-5 (20px) → gap-6/p-6/m-6 (24px), gap-10/p-10/m-10 (40px) → gap-12/p-12/m-12 (48px), gap-20/p-20/m-20 (80px) → gap-24/p-24/m-24 (96px)
- Preserved: 4px values (gap-1, p-1, m-1) as they may be intentional fine-tuning, responsive breakpoints (sm:, md:, lg:), test files, documentation
- Modified files across all components to ensure consistent 8px grid alignment
- Action 11.2.1.3: Align all elements to 8px grid - COMPLETE
2026-01-16 10:50:46 +00:00
|
|
|
<div className="flex items-center gap-4">
|
2026-03-23 14:44:37 +00:00
|
|
|
<div className="w-10 h-10 rounded bg-primary flex items-center justify-center">
|
2026-02-12 01:09:29 +00:00
|
|
|
<Palette className="w-5 h-5 text-foreground" />
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
|
|
|
|
<div>
|
2026-03-23 14:44:37 +00:00
|
|
|
<h3 className="text-xl text-foreground" style={{ fontWeight: 300 }}>Color Theme</h3>
|
|
|
|
|
<p className="text-sm text-muted-foreground" style={{ fontWeight: 300 }}>
|
|
|
|
|
Choose your ink palette
|
2026-01-13 18:47:57 +00:00
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-01-11 01:37:48 +00:00
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
|
|
|
{themes.map((theme) => (
|
|
|
|
|
<button
|
|
|
|
|
key={theme.id}
|
|
|
|
|
onClick={() => onThemeChange(theme.id)}
|
2026-03-23 14:44:37 +00:00
|
|
|
className={`group relative p-8 rounded border-2 transition-all duration-[var(--sumi-duration-normal)] text-left overflow-hidden ${
|
2026-01-13 18:47:57 +00:00
|
|
|
currentTheme === theme.id
|
refactor: Phase 3a — Global color class migration to SUMI semantics
- Replace all kodo-* color classes across ~100 TSX files:
kodo-void → background, kodo-ink → card, kodo-graphite → muted,
kodo-steel → muted-foreground, kodo-cyan → primary, kodo-magenta → destructive,
kodo-lime → success, kodo-red → destructive, kodo-gold → warning
- Replace cyan-500, magenta-500, lime-500 default Tailwind colors with
semantic equivalents (primary, destructive, success)
- Fix WaveformVisualizer hardcoded hex colors to SUMI values
- Delete global-effects.css (conflicting, redundant with index.css)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 00:51:49 +00:00
|
|
|
? 'border-primary bg-primary/10 shadow-lg shadow-primary/20'
|
|
|
|
|
: 'border-white/10 bg-muted/50 hover:border-white/30 hover:bg-muted'
|
2026-01-13 18:47:57 +00:00
|
|
|
}`}
|
|
|
|
|
>
|
|
|
|
|
{/* Gradient Background */}
|
|
|
|
|
<div
|
|
|
|
|
className="absolute inset-0 opacity-10 group-hover:opacity-20 transition-opacity"
|
|
|
|
|
style={{ background: theme.gradient }}
|
|
|
|
|
/>
|
2026-01-11 01:37:48 +00:00
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
{/* Content */}
|
|
|
|
|
<div className="relative z-10">
|
|
|
|
|
<div className="flex items-center gap-4 mb-3">
|
|
|
|
|
<div className="flex gap-2">
|
|
|
|
|
{theme.colors.map((color, i) => (
|
|
|
|
|
<div
|
|
|
|
|
key={i}
|
2026-03-23 14:44:37 +00:00
|
|
|
className="w-10 h-10 rounded shadow-lg transition-opacity group-hover:opacity-80"
|
2026-01-13 18:47:57 +00:00
|
|
|
style={{ backgroundColor: color }}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-01-11 01:37:48 +00:00
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
<div className="mb-2">
|
2026-03-23 14:44:37 +00:00
|
|
|
<div className="text-lg text-foreground mb-1" style={{ fontWeight: 400 }}>
|
2026-01-13 18:47:57 +00:00
|
|
|
{theme.name}
|
|
|
|
|
</div>
|
2026-03-23 14:44:37 +00:00
|
|
|
<div className="text-sm text-muted-foreground" style={{ fontWeight: 300 }}>
|
2026-01-13 18:47:57 +00:00
|
|
|
{theme.description}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2026-01-11 01:37:48 +00:00
|
|
|
|
2026-01-13 18:47:57 +00:00
|
|
|
{currentTheme === theme.id && (
|
refactor: Phase 3a — Global color class migration to SUMI semantics
- Replace all kodo-* color classes across ~100 TSX files:
kodo-void → background, kodo-ink → card, kodo-graphite → muted,
kodo-steel → muted-foreground, kodo-cyan → primary, kodo-magenta → destructive,
kodo-lime → success, kodo-red → destructive, kodo-gold → warning
- Replace cyan-500, magenta-500, lime-500 default Tailwind colors with
semantic equivalents (primary, destructive, success)
- Fix WaveformVisualizer hardcoded hex colors to SUMI values
- Delete global-effects.css (conflicting, redundant with index.css)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 00:51:49 +00:00
|
|
|
<div className="flex items-center gap-2 text-muted-foreground font-mono text-sm animate-slide-in-left">
|
ui(tokens): migrate kodo-cyan to primary (51 files, 88 instances)
Replace legacy text-kodo-cyan/border-kodo-cyan/bg-kodo-cyan with semantic
text-primary/border-primary/bg-primary across 51 components.
The brand primary color now uses the design system token, enabling proper
theme adaptation. Covers UI primitives, search, dashboard, chat, playlists,
settings, social, marketplace, and auth components.
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 23:19:12 +00:00
|
|
|
<div className="w-2 h-2 rounded-full bg-primary animate-glow-pulse" />
|
2026-03-23 14:44:37 +00:00
|
|
|
Active
|
2026-01-13 18:47:57 +00:00
|
|
|
</div>
|
|
|
|
|
)}
|
2026-01-11 01:37:48 +00:00
|
|
|
</div>
|
2026-01-13 18:47:57 +00:00
|
|
|
</button>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
2026-01-11 01:37:48 +00:00
|
|
|
}
|