feat: implement CS2-inspired design system and UI components
This commit delivers a comprehensive design system and component library inspired by Counter-Strike 2's tactical aesthetic. Design System: - Created docs/DESIGN.md with complete design language documentation - CS2-inspired color palette: T-side orange (#d4a74a), CT-side blue (#5e98d9) - Dark-first approach with tactical, data-dense layouts - Typography scale, spacing system, and animation guidelines Component Library: - Button component: 4 variants (primary, secondary, ghost, danger), 3 sizes - Badge component: 7 variants including team-specific badges - Card component: 3 variants (default, elevated, interactive) - Header component: Responsive navigation with mobile menu - Footer component: Site-wide footer with organized link sections Pages: - Redesigned homepage with hero section, featured matches, features grid, CTA - Created placeholder pages: /matches, /players, /about - All pages follow CS2 aesthetic with proper component usage Technical Fixes: - Fixed Svelte 5 snippet syntax errors (removed incorrect render prop pattern) - Fixed Card component accessibility (conditional button/div rendering) - Removed invalid CSS border-border class from app.css - Ensured zero TypeScript errors and warnings Build Status: ✓ Verified with 0 errors, 0 warnings 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
56
src/lib/components/ui/Button.svelte
Normal file
56
src/lib/components/ui/Button.svelte
Normal file
@@ -0,0 +1,56 @@
|
||||
<script lang="ts">
|
||||
import type { Snippet } from 'svelte';
|
||||
|
||||
interface Props {
|
||||
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
href?: string;
|
||||
type?: 'button' | 'submit' | 'reset';
|
||||
disabled?: boolean;
|
||||
class?: string;
|
||||
onclick?: () => void;
|
||||
children: Snippet;
|
||||
}
|
||||
|
||||
let {
|
||||
variant = 'primary',
|
||||
size = 'md',
|
||||
href,
|
||||
type = 'button',
|
||||
disabled = false,
|
||||
class: className = '',
|
||||
onclick,
|
||||
children
|
||||
}: Props = $props();
|
||||
|
||||
const baseClasses =
|
||||
'inline-flex items-center justify-center font-semibold transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-base-100 disabled:opacity-50 disabled:cursor-not-allowed';
|
||||
|
||||
const variantClasses = {
|
||||
primary:
|
||||
'bg-primary text-white hover:bg-primary-focus focus:ring-primary shadow-sm hover:shadow-lg hover:shadow-primary/30',
|
||||
secondary:
|
||||
'bg-secondary text-white hover:bg-secondary-focus focus:ring-secondary shadow-sm hover:shadow-lg hover:shadow-secondary/30',
|
||||
ghost:
|
||||
'bg-transparent border border-base-300 text-base-content hover:bg-base-300 hover:border-primary focus:ring-primary',
|
||||
danger: 'bg-error text-white hover:bg-error/90 focus:ring-error shadow-sm hover:shadow-lg'
|
||||
};
|
||||
|
||||
const sizeClasses = {
|
||||
sm: 'px-3 py-1.5 text-sm rounded',
|
||||
md: 'px-4 py-2 text-base rounded-md',
|
||||
lg: 'px-6 py-3 text-lg rounded-lg'
|
||||
};
|
||||
|
||||
const classes = `${baseClasses} ${variantClasses[variant]} ${sizeClasses[size]} ${className}`;
|
||||
</script>
|
||||
|
||||
{#if href}
|
||||
<a {href} class={classes} aria-disabled={disabled}>
|
||||
{@render children()}
|
||||
</a>
|
||||
{:else}
|
||||
<button {type} {disabled} {onclick} class={classes}>
|
||||
{@render children()}
|
||||
</button>
|
||||
{/if}
|
||||
Reference in New Issue
Block a user