From 43a003f6419486df76ece45b457f977b20d2c9f8 Mon Sep 17 00:00:00 2001 From: syntaxbullet Date: Wed, 7 Jan 2026 13:04:40 +0100 Subject: [PATCH] feat: visual design system overhaul (HSL palette, fonts, components) --- src/web/public/style.css | 267 ++++++++++++++++-- src/web/views/layout.ts | 3 + ...026-01-07-visual-design-system-overhaul.md | 37 --- 3 files changed, 244 insertions(+), 63 deletions(-) delete mode 100644 tickets/2026-01-07-visual-design-system-overhaul.md diff --git a/src/web/public/style.css b/src/web/public/style.css index 49de373..ddbbcbc 100644 --- a/src/web/public/style.css +++ b/src/web/public/style.css @@ -1,68 +1,283 @@ :root { - --bg-color: #0f172a; - --text-color: #f8fafc; - --accent-color: #38bdf8; - --card-bg: #1e293b; - --font-family: system-ui, -apple-system, sans-serif; + /* Color Palette - HSL (Hue, Saturation, Lightness) */ + /* Primary (Aurora Cyan) */ + --primary-h: 180; + --primary-s: 100%; + --primary-l: 50%; + --primary: hsl(var(--primary-h), var(--primary-s), var(--primary-l)); + + /* Secondary (Aurora Purple) */ + --secondary-h: 270; + --secondary-s: 100%; + --secondary-l: 65%; + --secondary: hsl(var(--secondary-h), var(--secondary-s), var(--secondary-l)); + + /* Backgrounds (Dark Slate) */ + --bg-h: 222; + --bg-s: 47%; + --bg-l: 7%; + /* Very Dark */ + --bg-color: hsl(var(--bg-h), var(--bg-s), var(--bg-l)); + + --card-bg-h: 217; + --card-bg-s: 33%; + --card-bg-l: 15%; + --card-bg: hsl(var(--card-bg-h), var(--card-bg-s), var(--card-bg-l)); + + /* Text */ + --text-main: hsl(210, 40%, 98%); + --text-muted: hsl(215, 20%, 65%); + --text-accent: var(--primary); + + /* Borders */ + --border-color: hsl(215, 25%, 25%); + + /* Typography */ + --font-heading: 'Outfit', system-ui, sans-serif; + --font-body: 'Inter', system-ui, sans-serif; + + /* Spacing & Radii */ + --radius-md: 0.75rem; + --radius-lg: 1rem; + --header-height: 4rem; + + /* Effects */ + --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); + --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.2), 0 2px 4px -2px rgb(0 0 0 / 0.1); + --shadow-glow: 0 0 15px hsla(var(--primary-h), var(--primary-s), 50%, 0.15); +} + +*, +*::before, +*::after { + box-sizing: border-box; } body { background-color: var(--bg-color); - color: var(--text-color); - font-family: var(--font-family); + color: var(--text-main); + font-family: var(--font-body); margin: 0; - line-height: 1.5; + line-height: 1.6; display: flex; flex-direction: column; min-height: 100vh; + -webkit-font-smoothing: antialiased; } +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: var(--font-heading); + margin-top: 0; + line-height: 1.2; + color: var(--text-main); +} + +h1 { + font-weight: 700; +} + +/* Header */ header { - background-color: var(--card-bg); - padding: 1rem 2rem; - border-bottom: 1px solid #334155; + background: rgba(15, 23, 42, 0.8); + /* Semi-transparent */ + backdrop-filter: blur(12px); + -webkit-backdrop-filter: blur(12px); + border-bottom: 1px solid var(--border-color); + height: var(--header-height); + padding: 0 2rem; display: flex; justify-content: space-between; align-items: center; + position: sticky; + top: 0; + z-index: 50; } header h1 { - margin: 0; font-size: 1.5rem; - color: var(--accent-color); + margin: 0; + background: linear-gradient(135deg, var(--primary), var(--secondary)); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + letter-spacing: -0.02em; } +header nav a { + color: var(--text-muted); + text-decoration: none; + font-weight: 500; + margin-left: 1.5rem; + transition: color 0.15s ease; + font-size: 0.95rem; +} + +header nav a:hover { + color: var(--primary); +} + +/* Main Layout */ main { flex: 1; padding: 2rem; max-width: 1200px; margin: 0 auto; width: 100%; - box-sizing: border-box; } +/* Card Component */ .card { background-color: var(--card-bg); - border-radius: 0.5rem; - padding: 1.5rem; + border: 1px solid var(--border-color); + border-radius: var(--radius-lg); + padding: 2rem; + margin-bottom: 1.5rem; + box-shadow: var(--shadow-md); + position: relative; + overflow: hidden; + transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease; +} + +.card:hover { + transform: translateY(-2px); + box-shadow: var(--shadow-glow), var(--shadow-md); + border-color: hsla(var(--primary-h), var(--primary-s), 50%, 0.3); +} + +.card h2 { + font-size: 1.25rem; margin-bottom: 1rem; - border: 1px solid #334155; - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); + color: var(--text-main); + display: flex; + align-items: center; + gap: 0.5rem; } -footer { - text-align: center; - padding: 1rem; - color: #94a3b8; - font-size: 0.875rem; - border-top: 1px solid #334155; +.card p { + color: var(--text-muted); + margin-bottom: 0; + font-size: 0.95rem; } +/* Links */ a { - color: var(--accent-color); + color: var(--primary); text-decoration: none; + transition: opacity 0.2s; } a:hover { - text-decoration: underline; + opacity: 0.8; } + +/* Buttons (Future Proofing) */ +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.5rem 1rem; + border-radius: var(--radius-md); + font-weight: 600; + font-family: var(--font-heading); + cursor: pointer; + transition: all 0.2s ease; + border: none; + font-size: 0.9rem; + text-decoration: none; +} + +.btn-primary { + background: linear-gradient(135deg, var(--primary), hsl(var(--primary-h), 90%, 45%)); + color: #000; + /* Contrast text on Cyan */ + box-shadow: 0 4px 6px -1px hsla(var(--primary-h), var(--primary-s), 50%, 0.2); +} + +.btn-primary:hover { + filter: brightness(1.1); + box-shadow: 0 6px 8px -1px hsla(var(--primary-h), var(--primary-s), 50%, 0.3); +} + +/* Forms & Inputs */ +input[type="text"], +input[type="email"], +input[type="password"], +textarea, +select { + width: 100%; + padding: 0.75rem 1rem; + background-color: rgba(15, 23, 42, 0.5); + border: 1px solid var(--border-color); + border-radius: var(--radius-md); + color: var(--text-main); + font-family: var(--font-body); + font-size: 0.95rem; + transition: all 0.2s; +} + +input:focus, +textarea:focus, +select:focus { + outline: none; + border-color: var(--primary); + box-shadow: 0 0 0 2px hsla(var(--primary-h), var(--primary-s), 50%, 0.2); + background-color: rgba(15, 23, 42, 0.8); +} + +/* Tables */ +table { + width: 100%; + border-collapse: collapse; + margin: 1rem 0; +} + +th { + text-align: left; + padding: 1rem; + background-color: rgba(15, 23, 42, 0.5); + color: var(--text-muted); + font-weight: 600; + font-size: 0.85rem; + text-transform: uppercase; + letter-spacing: 0.05em; + border-bottom: 1px solid var(--border-color); +} + +td { + padding: 1rem; + border-bottom: 1px solid #1e293b; + /* Fallback or specific border */ + border-bottom: 1px solid rgba(255, 255, 255, 0.05); + color: var(--text-main); +} + +tr:last-child td { + border-bottom: none; +} + +tr:hover td { + background-color: rgba(255, 255, 255, 0.02); +} + +/* Footer */ +footer { + padding: 2rem; + text-align: center; + color: var(--text-muted); + font-size: 0.875rem; + border-top: 1px solid var(--border-color); + background: var(--bg-color); +} + +/* Utilities */ +.text-gradient { + background: linear-gradient(135deg, var(--primary), var(--secondary)); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; +} \ No newline at end of file diff --git a/src/web/views/layout.ts b/src/web/views/layout.ts index e68e4f7..1ac4645 100644 --- a/src/web/views/layout.ts +++ b/src/web/views/layout.ts @@ -15,6 +15,9 @@ export function BaseLayout({ title, content }: LayoutProps): string { ${safeTitle} | Aurora + + +
diff --git a/tickets/2026-01-07-visual-design-system-overhaul.md b/tickets/2026-01-07-visual-design-system-overhaul.md deleted file mode 100644 index 7d1928c..0000000 --- a/tickets/2026-01-07-visual-design-system-overhaul.md +++ /dev/null @@ -1,37 +0,0 @@ -# 2026-01-07-visual-design-system-overhaul.md: Visual Design System Overhaul - -**Status:** Draft -**Created:** 2026-01-07 -**Tags:** ui, css, design-system, aesthetics - -## 1. Context & User Story -* **As a:** User of the Aurora Web Dashboard -* **I want to:** Experience a cohesive, modern, and premium visual design -* **So that:** The application feels professional, trustworthy, and pleasant to use for extended periods. - -## 2. Technical Requirements -### Data Model Changes -- N/A - -### API / Interface -- N/A - -## 3. Constraints & Validations (CRITICAL) -- **CSS Variables:** Must use CSS Custom Properties for all colors, spacing, and typography to ensure theming capabilities. -- **Color Palette:** Use an HSL-based color system (e.g., `--primary-h`, `--primary-s`, `--primary-l`) to allow for opacity manipulations. -- **Typography:** Integrate a modern sans-serif font like 'Inter' or 'Outfit' from Google Fonts. Do not rely on system defaults. -- **Performance:** Load fonts efficiently (display: swap). - -## 4. Acceptance Criteria -1. [ ] `style.css` is refactored to use a comprehensive set of root variables (colors, spacing, radii, shadows). -2. [ ] A modern font (Inter/Outfit) is imported and applied globally. -3. [ ] Hardcoded hex values are removed in favor of CSS variables. -4. [ ] Common components (Cards, Buttons, Inputs, Tables) have distinct, premium styles defined. -5. [ ] The color palette includes primary, secondary, background, surface, and semantic colors (success, error, warning). - -## 5. Implementation Plan -- [ ] Define the HSL color palette and typography in `:root`. -- [ ] Import Google Fonts in `layout.ts` or via `@import` in CSS. -- [ ] Refactor existing `.card` and body styles to use the new tokens. -- [ ] Create utility classes for common spacing/layout needs if necessary (or keep it semantic). -- [ ] Add styles for buttons and links with proper hover/active states.