02-Architecture / 02.03.UI-Design-System

02.03.UI Design System

02.03. UI Design System

Overview

This document describes the LuxDrive design system implementation for Car Pulse Tracker. The system uses a design tokens architecture where all styling is controlled from a single CSS file (style.css), not hardcoded in Vue components.

Architecture

style.css
├── :root (Design Tokens)
│   ├── Colors
│   ├── Typography
│   ├── Spacing
│   ├── Border Radius
│   ├── Shadows
│   └── Transitions
├── @layer base (Base Styles)
├── @layer components (Semantic Classes)
└── @layer utilities (Utility Classes)

Design Tokens

Colors

Token Value Usage
--color-primary 30 41 59 (deep indigo-slate) Primary brand color, buttons, links
--color-primary-hover 30 64 175 (indigo-700) Hover state for primary
--color-background 248 250 255 (cool off-white) Page background
--color-surface 238 242 255 (indigo-50) Card backgrounds, inputs
--color-surface-dark 15 23 42 (slate-900) Dark panels (brand selector)
--color-foreground 15 23 42 (slate-900) Primary text
--color-foreground-light 255 255 255 (white) Text on dark backgrounds
--color-foreground-muted 71 85 105 (slate-600) Secondary text
--color-border 226 232 240 (slate-200) Default borders

Semantic Colors

Token Value Usage
--color-success 34 197 94 (green-500) Success states
--color-warning 234 179 8 (yellow-500) Warning states
--color-error 239 68 68 (red-500) Error states
--color-info 59 130 246 (blue-500) Info states

Typography

Token Value
--font-family-base 'Inter', system-ui, sans-serif
--font-family-display 'Playfair Display', Georgia, serif

Font Sizes: - --font-size-xs: 0.625rem (10px) - --font-size-sm: 0.75rem (12px) - --font-size-base: 0.875rem (14px) - --font-size-lg: 1rem (16px) - --font-size-xl: 1.25rem (20px) - --font-size-2xl: 1.5rem (24px) - --font-size-3xl: 2rem (32px) - --font-size-4xl: 2.5rem (40px) - --font-size-7xl: 5rem (80px - hero)

Spacing

Token Value
--spacing-xs 0.25rem (4px)
--spacing-sm 0.5rem (8px)
--spacing-md 1rem (16px)
--spacing-lg 1.5rem (24px)
--spacing-xl 2rem (32px)
--spacing-2xl 3rem (48px)

Border Radius

Token Value
--radius-sm 0.375rem (6px)
--radius-md 0.5rem (8px)
--radius-lg 0.75rem (12px)
--radius-xl 1rem (16px)
--radius-2xl 1.5rem (24px)
--radius-full 9999px

Product Branding

Current CPT product branding is split into two separate concerns:

This distinction should remain explicit. Tesla, BMW, Audi, and other OEM marks are not substitutes for the CPT product mark.

Planned Branding Update

Approved concept source:

Implementation target:

Branding Rules


Component Classes

<nav class="nav">
  <div class="nav-brand">
    <div class="logo-icon">
      <span class="logo-icon-text">C</span>
    </div>
    <span>Car Pulse Tracker</span>
  </div>
  <div class="lang-selector">
    <button class="lang-option lang-option-active">EN</button>
    <button class="lang-option">FI</button>
  </div>
</nav>

Buttons

<!-- Primary button -->
<button class="btn btn-primary">Continue</button>

<!-- Secondary button -->
<button class="btn btn-secondary">Cancel</button>

<!-- Ghost button -->
<button class="btn btn-ghost">Learn More</button>

<!-- Full width -->
<button class="btn btn-primary w-full">Submit</button>

Cards

<!-- Standard card -->
<div class="card">Content</div>

<!-- Card with hover effect -->
<div class="card card-hover">Hoverable</div>

<!-- Selected card -->
<div class="card card-selected">Selected</div>

<!-- Dark card -->
<div class="card-dark">Dark content</div>

Plan Cards (Payment)

<div class="plan-grid">
  <div class="plan-card">
    <h3 class="plan-title">Basic Report</h3>
    <p class="plan-price">€19</p>
    <p class="plan-desc">Service history, battery health</p>
  </div>

  <div class="plan-card plan-card-popular">
    <span class="plan-badge">Popular</span>
    <h3 class="plan-title">Pro Report</h3>
    <p class="plan-price">€29</p>
  </div>
</div>

Form Elements

<div class="form-group">
  <label class="form-label">Email</label>
  <input type="email" class="form-input" placeholder="you@example.com" />
</div>

<label class="terms-row">
  <input type="checkbox" class="checkbox" />
  <span class="terms-text">I agree to the terms</span>
</label>

Alerts

<div class="alert alert-error">Error message</div>
<div class="alert alert-success">Success message</div>
<div class="alert alert-warning">Warning message</div>
<div class="alert alert-info">Info message</div>

Report Sections

<div class="report-section">
  <div class="report-section-header">
    <span class="report-section-indicator indicator-success"></span>
    <h3 class="report-section-title">Service History</h3>
  </div>

  <div class="data-grid">
    <div class="data-item">
      <span class="data-label">Battery Level</span>
      <span class="data-value">85%</span>
    </div>
  </div>
</div>

Info Lists

<div class="info-list">
  <div class="info-list-item">
    <span class="info-list-label">Make:</span>
    <span class="info-list-value">Tesla</span>
  </div>
  <div class="info-list-item">
    <span class="info-list-label">Model:</span>
    <span class="info-list-value">Model 3</span>
  </div>
</div>

Alert Badges

<span class="alert-badge badge-high">High</span>
<span class="alert-badge badge-medium">Medium</span>
<span class="alert-badge badge-low">Low</span>

Modals

<div class="modal-backdrop">
  <div class="modal-content">
    <div class="modal-header">
      <h2 class="modal-title">Title</h2>
      <button class="modal-close">×</button>
    </div>
    <div class="modal-body">Content</div>
    <div class="modal-footer">
      <button class="btn btn-secondary">Cancel</button>
      <button class="btn btn-primary">Confirm</button>
    </div>
  </div>
</div>

Spinner

<!-- Default spinner -->
<div class="spinner"></div>

<!-- Light spinner (on dark background) -->
<div class="spinner spinner-light"></div>

Utility Classes

Layout

Class Description
flex-center Flex container, centered
flex-between Flex container, space-between
gap-sm 8px gap
gap-md 16px gap
gap-lg 24px gap
w-full 100% width

Spacing (Stack)

Class Description
stack-sm 8px vertical spacing between children
stack-md 16px vertical spacing
stack-lg 24px vertical spacing
stack-xl 32px vertical spacing

Typography

Class Description
text-primary Primary text color
text-muted Muted text color
text-subtle Subtle text color
text-success Success color
text-error Error color
font-display Playfair Display font
font-base Inter font
font-black 900 font weight

Visibility

Class Description
hide-mobile Hidden on mobile, visible on desktop
hide-desktop Visible on mobile, hidden on desktop
no-print Hidden when printing

Responsive Breakpoints

Breakpoint Width
Mobile < 640px
Tablet 640px - 768px
Desktop 768px - 1024px
Large > 1024px

Theming

To change the entire app's appearance, modify the CSS variables in :root:

:root {
  /* Change primary color to blue */
  --color-primary: 59 130 246;

  /* Change to dark theme */
  --color-background: 9 9 11;
  --color-foreground: 255 255 255;
  --color-surface: 24 24 27;
}

No component changes are required when modifying the theme.


Component File Reference

Component Purpose Key Classes Used
Header.vue Navigation bar nav, nav-brand, lang-selector
Hero.vue Landing hero section hero-section, feature-grid, feature-card
BrandSelector.vue Brand selection panel split-panel-dark, selection-item-dark
ModelSelector.vue Model selection panel split-panel-light, model-item, stats-grid
PaymentStep.vue Payment plan selection plan-grid, plan-card, payment-methods-grid
PaymentGateway.vue Payment processing card, gateway-container
PaymentSuccessStep.vue Success confirmation success-icon, success-title
OAuthStep.vue OAuth connection card, stack-lg
MockupTeslaLogin.vue Login form mockup login-card, form-group, form-input
ServiceAgreement.vue Terms modal modal-backdrop, modal-content
ReportDashboard.vue Final report display report-section, data-grid, info-list

Build

cd bnc-cpt-wui/src/vue/app
npm run build

Output: - JS: ~256 KB (gzip: ~85 KB) - CSS: ~45 KB (gzip: ~8 KB)