From 153c0e9f136de30db283f6295ba1060836fe5c38 Mon Sep 17 00:00:00 2001 From: vikingowl Date: Tue, 4 Nov 2025 20:07:05 +0100 Subject: [PATCH] feat: implement CS2-inspired design system and UI components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- docs/DESIGN.md | 587 ++++++++++++++++++++++++ src/app.css | 4 - src/lib/components/layout/Footer.svelte | 132 ++++++ src/lib/components/layout/Header.svelte | 77 ++++ src/lib/components/ui/Badge.svelte | 37 ++ src/lib/components/ui/Button.svelte | 56 +++ src/lib/components/ui/Card.svelte | 49 ++ src/routes/+layout.svelte | 10 +- src/routes/+page.svelte | 215 ++++++++- src/routes/about/+page.svelte | 87 ++++ src/routes/matches/+page.svelte | 50 ++ src/routes/players/+page.svelte | 42 ++ 12 files changed, 1326 insertions(+), 20 deletions(-) create mode 100644 docs/DESIGN.md create mode 100644 src/lib/components/layout/Footer.svelte create mode 100644 src/lib/components/layout/Header.svelte create mode 100644 src/lib/components/ui/Badge.svelte create mode 100644 src/lib/components/ui/Button.svelte create mode 100644 src/lib/components/ui/Card.svelte create mode 100644 src/routes/about/+page.svelte create mode 100644 src/routes/matches/+page.svelte create mode 100644 src/routes/players/+page.svelte diff --git a/docs/DESIGN.md b/docs/DESIGN.md new file mode 100644 index 0000000..1be86b8 --- /dev/null +++ b/docs/DESIGN.md @@ -0,0 +1,587 @@ +# CS2.WTF Design System + +A modern, tactical design language inspired by Counter-Strike 2's in-game aesthetics. + +--- + +## 🎨 Design Philosophy + +### Core Principles + +1. **Tactical & Data-Dense**: Inspired by CS2's HUD - information at a glance +2. **Dark-First**: Gaming-optimized dark theme as default +3. **Team Identity**: Leverage T-side (orange) and CT-side (blue) throughout +4. **Performance**: Smooth animations, no bloat +5. **Accessible**: WCAG 2.1 AA compliant + +### Visual Language + +- **Sharp Corners**: Minimal border radius (2-4px) for tactical feel +- **Neon Accents**: Subtle glows on interactive elements +- **Grid-Based**: 8px base unit for consistent spacing +- **Monospace Numbers**: Stats feel more tactical +- **Depth Through Layers**: Elevated cards with subtle shadows + +--- + +## 🎨 Color Palette + +### Brand Colors + +```css +/* Primary (CT Blue) */ +--ct-blue: #5e98d9; +--ct-blue-light: #7eaee5; +--ct-blue-dark: #4a7ab3; + +/* Secondary (T Orange) */ +--t-orange: #d4a74a; +--t-orange-light: #e5c674; +--t-orange-dark: #b38a3a; + +/* Accent (Success Green) */ +--accent-green: #36d399; +``` + +### Base Colors (Dark Theme) + +```css +/* Backgrounds */ +--bg-primary: #0f172a; /* Slate 900 - Main background */ +--bg-secondary: #1e293b; /* Slate 800 - Card background */ +--bg-tertiary: #334155; /* Slate 700 - Hover states */ + +/* Text */ +--text-primary: #e2e8f0; /* Slate 200 - Main text */ +--text-secondary: #94a3b8; /* Slate 400 - Muted text */ +--text-tertiary: #64748b; /* Slate 500 - Disabled text */ + +/* Borders */ +--border-default: #334155; /* Slate 700 */ +--border-accent: #475569; /* Slate 600 - Hover */ +``` + +### Semantic Colors + +```css +/* Status */ +--success: #36d399; /* Win, positive stats */ +--warning: #fbbd23; /* Neutral, info */ +--error: #f87272; /* Loss, negative stats */ +--info: #3abff8; /* Information, CT-related */ +``` + +--- + +## 📐 Typography + +### Font Families + +**Primary (UI Text):** + +```css +font-family: + 'Inter', + system-ui, + -apple-system, + sans-serif; +``` + +**Monospace (Stats & Numbers):** + +```css +font-family: 'JetBrains Mono', 'Fira Code', Consolas, monospace; +``` + +### Type Scale + +```css +/* Display */ +--text-6xl: 3.75rem; /* 60px - Hero headings */ +--text-5xl: 3rem; /* 48px - Page titles */ +--text-4xl: 2.25rem; /* 36px - Section headers */ + +/* Headings */ +--text-3xl: 1.875rem; /* 30px - Card titles */ +--text-2xl: 1.5rem; /* 24px - Subsection headers */ +--text-xl: 1.25rem; /* 20px - Large body */ + +/* Body */ +--text-lg: 1.125rem; /* 18px - Prominent text */ +--text-base: 1rem; /* 16px - Default body */ +--text-sm: 0.875rem; /* 14px - Small text */ +--text-xs: 0.75rem; /* 12px - Captions */ +``` + +### Font Weights + +```css +--font-normal: 400; +--font-medium: 500; +--font-semibold: 600; +--font-bold: 700; +``` + +--- + +## 🏗️ Layout + +### Spacing System (8px Grid) + +```css +--space-1: 0.25rem; /* 4px */ +--space-2: 0.5rem; /* 8px */ +--space-3: 0.75rem; /* 12px */ +--space-4: 1rem; /* 16px */ +--space-6: 1.5rem; /* 24px */ +--space-8: 2rem; /* 32px */ +--space-12: 3rem; /* 48px */ +--space-16: 4rem; /* 64px */ +--space-24: 6rem; /* 96px */ +``` + +### Container Widths + +```css +--container-sm: 640px; /* Mobile landscape */ +--container-md: 768px; /* Tablet */ +--container-lg: 1024px; /* Desktop */ +--container-xl: 1280px; /* Large desktop */ +--container-2xl: 1536px; /* Extra large */ +``` + +### Breakpoints + +```css +/* Mobile first approach */ +sm: 640px /* Tablet */ +md: 768px /* Small desktop */ +lg: 1024px /* Desktop */ +xl: 1280px /* Large desktop */ +2xl: 1536px /* Extra large */ +``` + +--- + +## 🎭 Components + +### Cards + +**Default Card:** + +```css +background: var(--bg-secondary); +border: 1px solid var(--border-default); +border-radius: 4px; +padding: 1.5rem; +box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1); +``` + +**Elevated Card:** + +```css +box-shadow: + 0 10px 15px -3px rgb(0 0 0 / 0.2), + 0 4px 6px -4px rgb(0 0 0 / 0.1); +``` + +**Interactive Card (Hover):** + +```css +transition: all 0.2s ease; + +&:hover { + border-color: var(--ct-blue); + box-shadow: 0 0 0 2px rgb(94 152 217 / 0.2); + transform: translateY(-2px); +} +``` + +### Buttons + +**Primary (CT Blue):** + +```css +background: var(--ct-blue); +color: white; +padding: 0.75rem 1.5rem; +border-radius: 4px; +font-weight: 600; +transition: all 0.2s; + +&:hover { + background: var(--ct-blue-dark); + box-shadow: 0 0 20px rgb(94 152 217 / 0.3); +} +``` + +**Secondary (T Orange):** + +```css +background: var(--t-orange); +color: white; +/* Similar styling */ +``` + +**Ghost:** + +```css +background: transparent; +border: 1px solid var(--border-default); +color: var(--text-primary); + +&:hover { + background: var(--bg-tertiary); + border-color: var(--ct-blue); +} +``` + +### Badges + +**Team Badge:** + +```css +/* T-Side */ +background: rgb(212 167 74 / 0.1); +color: var(--t-orange-light); +border: 1px solid var(--t-orange-dark); + +/* CT-Side */ +background: rgb(94 152 217 / 0.1); +color: var(--ct-blue-light); +border: 1px solid var(--ct-blue-dark); +``` + +**Status Badge:** + +```css +/* Win */ +background: rgb(54 211 153 / 0.1); +color: var(--success); + +/* Loss */ +background: rgb(248 114 114 / 0.1); +color: var(--error); +``` + +--- + +## 🌊 Animations + +### Transitions + +```css +/* Standard */ +transition: all 0.2s ease; + +/* Slow */ +transition: all 0.3s ease; + +/* Fast */ +transition: all 0.15s ease; +``` + +### Keyframes + +**Fade In:** + +```css +@keyframes fadeIn { + from { + opacity: 0; + transform: translateY(-10px); + } + to { + opacity: 1; + transform: translateY(0); + } +} +``` + +**Pulse (Live Indicator):** + +```css +@keyframes pulse { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 0.5; + } +} +``` + +**Glow:** + +```css +@keyframes glow { + 0%, + 100% { + box-shadow: 0 0 10px rgb(94 152 217 / 0.3); + } + 50% { + box-shadow: 0 0 20px rgb(94 152 217 / 0.5); + } +} +``` + +--- + +## 🎯 Iconography + +**Icon Library:** Lucide Icons (clean, modern, consistent) + +**Icon Sizes:** + +```css +--icon-xs: 16px; +--icon-sm: 20px; +--icon-md: 24px; +--icon-lg: 32px; +--icon-xl: 48px; +``` + +**Icon Colors:** + +- Default: `text-slate-400` +- Active: `text-primary` or `text-secondary` +- Success: `text-success` +- Error: `text-error` + +--- + +## 📊 Data Visualization + +### Chart Colors + +**Team Performance:** + +- T-Side: `#d4a74a` +- CT-Side: `#5e98d9` + +**Heatmaps:** + +- Low: `#334155` (Slate 700) +- Medium: `#f59e0b` (Amber 500) +- High: `#ef4444` (Red 500) + +**Line Charts:** + +- Primary line: `#5e98d9` +- Secondary line: `#d4a74a` +- Grid: `rgb(51 65 85 / 0.3)` + +### Tables + +**Header:** + +```css +background: var(--bg-primary); +font-weight: 600; +text-transform: uppercase; +font-size: 0.75rem; +letter-spacing: 0.05em; +color: var(--text-secondary); +``` + +**Row:** + +```css +border-bottom: 1px solid var(--border-default); + +&:hover { + background: var(--bg-tertiary); +} +``` + +**Stats (Numbers):** + +```css +font-family: var(--font-mono); +font-variant-numeric: tabular-nums; +``` + +--- + +## ♿ Accessibility + +### Focus States + +```css +&:focus-visible { + outline: 2px solid var(--ct-blue); + outline-offset: 2px; +} +``` + +### Color Contrast + +- Text on dark bg: Minimum 4.5:1 (WCAG AA) +- Large text: Minimum 3:1 +- UI components: Minimum 3:1 + +### Motion + +```css +@media (prefers-reduced-motion: reduce) { + * { + animation-duration: 0.01ms !important; + transition-duration: 0.01ms !important; + } +} +``` + +--- + +## 🎮 CS2-Specific Elements + +### Rank Display + +- Show Premier rating (0-30,000) with color coding +- Bronze: `#cd7f32` +- Silver: `#c0c0c0` +- Gold: `#ffd700` +- Legend: `#9b59b6` + +### Map Thumbnails + +- 16:9 aspect ratio +- Slight overlay gradient (bottom to top) +- Map name in bottom-left corner + +### Weapon Icons + +- Monochrome with subtle glow +- Size: 32x32px default +- Color: Match rarity (Consumer White, Mil-Spec Blue, etc.) + +### Kill Feed + +```css +.kill-feed-item { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 0.25rem 0.5rem; + background: rgb(15 23 42 / 0.9); + border-left: 2px solid var(--t-orange); +} +``` + +--- + +## 📱 Responsive Design + +### Mobile (< 768px) + +- Stack layouts vertically +- Reduce padding/spacing by 25% +- Hide secondary information +- Larger tap targets (min 44x44px) +- Bottom navigation for main actions + +### Tablet (768px - 1024px) + +- Two-column layouts +- Collapsible sidebar +- Touch-optimized interactions + +### Desktop (> 1024px) + +- Three-column layouts where appropriate +- Hover states and tooltips +- Keyboard shortcuts +- Dense data tables + +--- + +## 🎨 Example Compositions + +### Hero Section (Homepage) + +``` +┌─────────────────────────────────────────┐ +│ │ +│ CS2.WTF (Large Logo) │ +│ Statistics for CS2 Matches │ +│ │ +│ [Search Match] [Browse Players] │ +│ │ +│ Featured Matches (Carousel) ────> │ +│ │ +└─────────────────────────────────────────┘ +``` + +### Match Card + +``` +┌─────────────────────────────────────┐ +│ de_inferno 13 - 10 LIVE │ +│ ─────────────────────────────────── │ +│ 👤 Player1 24K 18D ⭐⭐⭐ │ +│ 👤 Player2 21K 20D ⭐⭐ │ +│ ... │ +│ ─────────────────────────────────── │ +│ 📅 2 hours ago ⏱️ 42:33 │ +└─────────────────────────────────────┘ +``` + +### Stats Table + +``` +┌──────────────────────────────────────────────┐ +│ PLAYER K D A HS% ADR RATING │ +├──────────────────────────────────────────────┤ +│ 👤 Player1 24 18 6 50% 98 1.32 🥇 │ +│ 👤 Player2 21 20 8 48% 87 1.12 │ +│ 👤 Player3 19 22 5 44% 82 0.98 │ +└──────────────────────────────────────────────┘ +``` + +--- + +## 🚀 Performance Guidelines + +- Lazy load images and charts +- Use CSS transforms for animations (GPU-accelerated) +- Debounce search inputs (300ms) +- Virtual scrolling for large tables (> 100 rows) +- Optimize bundle size (< 200KB initial) + +--- + +## 📝 Naming Conventions + +### CSS Classes + +```css +/* Component */ +.match-card { +} + +/* Element */ +.match-card__header { +} + +/* Modifier */ +.match-card--featured { +} + +/* State */ +.match-card.is-active { +} +``` + +### Tailwind Utilities + +Prefer utility classes for spacing, colors, and common patterns: + +```html +
+``` + +--- + +**Last Updated**: 2025-11-04 +**Status**: Active Development diff --git a/src/app.css b/src/app.css index 3a83cff..9c7fd7c 100644 --- a/src/app.css +++ b/src/app.css @@ -8,10 +8,6 @@ color-scheme: dark; } - * { - @apply border-border; - } - body { @apply bg-base-100 text-base-content; font-feature-settings: diff --git a/src/lib/components/layout/Footer.svelte b/src/lib/components/layout/Footer.svelte new file mode 100644 index 0000000..f201796 --- /dev/null +++ b/src/lib/components/layout/Footer.svelte @@ -0,0 +1,132 @@ + + +
+
+
+ +
+ + CS2.WTF + +

+ Statistics for CS2 matchmaking matches. Free and open source. +

+ +
+ + +
+

+ Navigate +

+ +
+ +
+

+ About +

+ +
+ +
+

+ Resources +

+ +
+
+ + +
+

+ © {currentYear} CSGOW.TF Team. Licensed under + GPL-3.0 +

+

+ Made with by the community, for the community. +

+
+
+
diff --git a/src/lib/components/layout/Header.svelte b/src/lib/components/layout/Header.svelte new file mode 100644 index 0000000..ed18889 --- /dev/null +++ b/src/lib/components/layout/Header.svelte @@ -0,0 +1,77 @@ + + +
+
+
+ + + CS2.WTF + + + + + + +
+ + + + +
+
+ + + {#if mobileMenuOpen} + + {/if} +
+
diff --git a/src/lib/components/ui/Badge.svelte b/src/lib/components/ui/Badge.svelte new file mode 100644 index 0000000..ab97501 --- /dev/null +++ b/src/lib/components/ui/Badge.svelte @@ -0,0 +1,37 @@ + + + + {@render children()} + diff --git a/src/lib/components/ui/Button.svelte b/src/lib/components/ui/Button.svelte new file mode 100644 index 0000000..124de2d --- /dev/null +++ b/src/lib/components/ui/Button.svelte @@ -0,0 +1,56 @@ + + +{#if href} + + {@render children()} + +{:else} + +{/if} diff --git a/src/lib/components/ui/Card.svelte b/src/lib/components/ui/Card.svelte new file mode 100644 index 0000000..60acdb5 --- /dev/null +++ b/src/lib/components/ui/Card.svelte @@ -0,0 +1,49 @@ + + +{#if onclick} + +{:else} +
+ {@render children()} +
+{/if} diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index c9cfbbf..ccefdef 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -1,9 +1,15 @@ -
- {@render children()} +
+
+
+ {@render children()} +
+
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index c09e125..e9322da 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,19 +1,206 @@ -
-
-

- CS2.WTF -

-

Statistics for CS2 matchmaking matches

- -
-

🚧 Rewrite in progress - Phase 1 complete

+ + CS2.WTF - Statistics for CS2 Matchmaking + + + + +
+
+
+
+ 🎮 Now supporting CS2 +
+ +

+ CS2.WTF +

+ +

+ Track your performance, analyze matches, and improve your game with + detailed statistics and insights. +

+ +
+ + +
+ + +
+ {#each stats as stat} +
+ +
{stat.value}
+
{stat.label}
+
+ {/each} +
-
+ + + +
+ +
+ + +
+
+
+

Why CS2.WTF?

+

Everything you need to analyze your CS2 performance

+
+ +
+ +
+ +
+

Detailed Statistics

+

+ Track K/D, ADR, HS%, KAST, and more. Analyze your performance round-by-round with + comprehensive stats. +

+
+ + +
+ +
+

Economy Tracking

+

+ Understand money management with round-by-round economy analysis and spending patterns. +

+
+ + +
+ +
+

Player Profiles

+

+ View comprehensive player profiles with match history, favorite maps, and performance + trends. +

+
+
+
+
+ + +
+
+ +
+

Ready to improve your game?

+

+ Start tracking your CS2 matches and get insights that help you rank up. +

+ +

Free and open source. No signup required.

+
+
+
+
diff --git a/src/routes/about/+page.svelte b/src/routes/about/+page.svelte new file mode 100644 index 0000000..bf0b8f7 --- /dev/null +++ b/src/routes/about/+page.svelte @@ -0,0 +1,87 @@ + + + + About - CS2.WTF + + +
+

About CS2.WTF

+ + +

Our Mission

+

+ CS2.WTF is a free and open-source platform for analyzing Counter-Strike 2 matchmaking matches. + We provide detailed statistics, performance insights, and tools to help players improve their + game. +

+

+ Originally created for CS:GO, we've completely rewritten the platform to support CS2 with + modern technologies and enhanced features. +

+
+ +
+ + +

Open Source

+

+ Built by the community, for the community. All code is available on GitHub. +

+
+ + + +

Free Forever

+

+ No paywalls, no premium features. Everyone gets full access to all statistics. +

+
+ + + +

Community Driven

+

+ Contributions welcome! Help us make CS2.WTF better for everyone. +

+
+
+ + +

Technology Stack

+
+
+

Frontend

+
    +
  • • SvelteKit 2.0 + Svelte 5
  • +
  • • TypeScript (Strict Mode)
  • +
  • • Tailwind CSS + DaisyUI
  • +
  • • Vitest + Playwright
  • +
+
+
+

Backend

+
    +
  • • Go + Gin Framework
  • +
  • • PostgreSQL Database
  • +
  • • Redis Cache
  • +
  • • Demo Parser
  • +
+
+
+
+ +
+ + +
+
diff --git a/src/routes/matches/+page.svelte b/src/routes/matches/+page.svelte new file mode 100644 index 0000000..3544371 --- /dev/null +++ b/src/routes/matches/+page.svelte @@ -0,0 +1,50 @@ + + + + Matches - CS2.WTF + + +
+
+

Matches

+

Browse and search through CS2 competitive matches

+
+ + + +
+
+
+ + +
+
+ +
+
+ + +
+
+

Coming Soon

+

Match listings will be available in Phase 3

+
+ Phase 3 - In Development +
+
+
+
diff --git a/src/routes/players/+page.svelte b/src/routes/players/+page.svelte new file mode 100644 index 0000000..5abda10 --- /dev/null +++ b/src/routes/players/+page.svelte @@ -0,0 +1,42 @@ + + + + Players - CS2.WTF + + +
+
+

Players

+

Search and browse player profiles

+
+ + + +
+ + +
+
+ + +
+
+ +

Coming Soon

+

Player search and profiles will be available in Phase 3

+
+ Phase 3 - In Development +
+
+
+