feat(ui): comprehensive design system improvements

This PR addresses 53 design issues identified in the UI codebase,
implementing a more consistent and polished neobrutalism design system.

Typography:
- Improved font stacks with proper fallbacks
- Added font smoothing for crisp text rendering

Color/Theme:
- Added neutral scale (50-900) for consistent grays
- Added semantic log level colors with dark mode variants
- Added category colors for feature cards
- Added GLM badge color variable
- Full dark mode support for all new variables

Design Tokens:
- Spacing scale (xs to 2xl)
- Z-index scale (dropdown to toast)
- Border radius tokens
- Inset shadow variants

Animations:
- New transition timing variables
- New easing curves (bounce, smooth, out-back)
- Slide-in animations (top/bottom/left)
- Bounce, shake, scale-pop animations
- Stagger delay utilities
- Enhanced YOLO fire effect with parallax layers

Components:
- Button size variants (sm/lg/icon) and loading state
- Input variants (error/disabled/textarea)
- Badge color and size variants
- Card elevation variants (elevated/flat/sunken)
- Progress bar shimmer animation
- Stronger modal backdrop with blur
- Neobrutalist tooltips
- Enhanced empty state with striped pattern

Component Fixes:
- Replaced hardcoded colors with CSS variables
- Fixed ProgressDashboard percentage alignment
- Improved ChatMessage role-specific styling
- Consistent category badge colors in FeatureModal
- Improved step input styling in forms

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
M Zubair
2026-01-14 22:14:29 +01:00
parent d1b8eb5f99
commit 501719f77a
26 changed files with 911 additions and 301 deletions

View File

@@ -21,31 +21,37 @@ export function ChatMessage({ message }: ChatMessageProps) {
minute: '2-digit',
})
// Role-specific styling
// Role-specific styling using CSS variables for theme consistency
const roleConfig = {
user: {
icon: User,
bgColor: 'bg-[var(--color-neo-pending)]',
textColor: 'text-[var(--color-neo-text-on-bright)]',
borderColor: 'border-[var(--color-neo-border)]',
align: 'justify-end',
bubbleAlign: 'items-end',
iconBg: 'bg-[var(--color-neo-pending)]',
shadow: 'var(--shadow-neo-md)',
},
assistant: {
icon: Bot,
bgColor: 'bg-white',
bgColor: 'bg-[var(--color-neo-card)]',
textColor: 'text-[var(--color-neo-text)]',
borderColor: 'border-[var(--color-neo-border)]',
align: 'justify-start',
bubbleAlign: 'items-start',
iconBg: 'bg-[var(--color-neo-progress)]',
shadow: 'var(--shadow-neo-md)',
},
system: {
icon: Info,
bgColor: 'bg-[var(--color-neo-done)]',
textColor: 'text-[var(--color-neo-text-on-bright)]',
borderColor: 'border-[var(--color-neo-border)]',
align: 'justify-center',
bubbleAlign: 'items-center',
iconBg: 'bg-[var(--color-neo-done)]',
shadow: 'var(--shadow-neo-sm)',
},
}
@@ -61,9 +67,9 @@ export function ChatMessage({ message }: ChatMessageProps) {
${config.bgColor}
border-2 ${config.borderColor}
px-4 py-2
text-sm font-mono
shadow-[2px_2px_0px_rgba(0,0,0,1)]
text-sm font-mono text-[var(--color-neo-text-on-bright)]
`}
style={{ boxShadow: 'var(--shadow-neo-sm)' }}
>
<span className="flex items-center gap-2">
<Icon size={14} />
@@ -85,11 +91,11 @@ export function ChatMessage({ message }: ChatMessageProps) {
${config.iconBg}
border-2 border-[var(--color-neo-border)]
p-1.5
shadow-[2px_2px_0px_rgba(0,0,0,1)]
flex-shrink-0
`}
style={{ boxShadow: 'var(--shadow-neo-sm)' }}
>
<Icon size={16} className="text-white" />
<Icon size={16} className="text-[var(--color-neo-text-on-bright)]" />
</div>
)}
@@ -98,13 +104,13 @@ export function ChatMessage({ message }: ChatMessageProps) {
${config.bgColor}
border-3 ${config.borderColor}
px-4 py-3
shadow-[4px_4px_0px_rgba(0,0,0,1)]
${isStreaming ? 'animate-pulse-neo' : ''}
`}
style={{ boxShadow: config.shadow }}
>
{/* Parse content for basic markdown-like formatting */}
{content && (
<div className="whitespace-pre-wrap text-sm leading-relaxed text-[#1a1a1a]">
<div className={`whitespace-pre-wrap text-sm leading-relaxed ${config.textColor}`}>
{content.split('\n').map((line, i) => {
// Bold text
const boldRegex = /\*\*(.*?)\*\*/g
@@ -144,7 +150,8 @@ export function ChatMessage({ message }: ChatMessageProps) {
{attachments.map((attachment) => (
<div
key={attachment.id}
className="border-2 border-[var(--color-neo-border)] p-1 bg-white shadow-[2px_2px_0px_rgba(0,0,0,1)]"
className="border-2 border-[var(--color-neo-border)] p-1 bg-[var(--color-neo-card)]"
style={{ boxShadow: 'var(--shadow-neo-sm)' }}
>
<img
src={attachment.previewUrl}
@@ -153,7 +160,7 @@ export function ChatMessage({ message }: ChatMessageProps) {
onClick={() => window.open(attachment.previewUrl, '_blank')}
title={`${attachment.filename} (click to enlarge)`}
/>
<span className="text-xs text-[var(--color-neo-text-secondary)] block mt-1 text-center">
<span className="text-xs text-neo-text-secondary block mt-1 text-center">
{attachment.filename}
</span>
</div>
@@ -163,7 +170,7 @@ export function ChatMessage({ message }: ChatMessageProps) {
{/* Streaming indicator */}
{isStreaming && (
<span className="inline-block w-2 h-4 bg-[var(--color-neo-accent)] ml-1 animate-pulse" />
<span className="inline-block w-2 h-4 bg-neo-accent ml-1 animate-pulse" />
)}
</div>
@@ -173,11 +180,11 @@ export function ChatMessage({ message }: ChatMessageProps) {
${config.iconBg}
border-2 border-[var(--color-neo-border)]
p-1.5
shadow-[2px_2px_0px_rgba(0,0,0,1)]
flex-shrink-0
`}
style={{ boxShadow: 'var(--shadow-neo-sm)' }}
>
<Icon size={16} />
<Icon size={16} className="text-[var(--color-neo-text-on-bright)]" />
</div>
)}
</div>