Files
fuel-price/.superdesign/init/design-system.md
Ovidiu U 41be8e2806
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
superdesign
2026-04-06 20:01:46 +01:00

12 KiB

Design System

Comprehensive documentation of the design system, visual language, and brand identity for the Fuel Price application.


Brand Identity

App Name

"Fuel Price" (Laravel Starter Kit internally)

  • Style: Geometric, modern
  • Colors: Adapts to light/dark mode
  • Variants: Header logo (wider), Sidebar logo (square icon)
  • Usage: All pages in navigation

Design Philosophy

  • Clean, minimal aesthetic
  • Dark-first design (dark mode as primary)
  • Accessibility-focused
  • Data visualization emphasis (maps, charts)
  • Utility-oriented interface

Color System

Primary Palette - Zinc (Neutral)

Used as base colors for UI, text, and borders.

Zinc-50:   #fafafa  (Lightest backgrounds)
Zinc-100:  #f5f5f5  (Light backgrounds)
Zinc-200:  #e5e5e5  (Light borders, dividers)
Zinc-300:  #d4d4d4  (Subtle borders)
Zinc-400:  #a3a3a3  (Placeholder text)
Zinc-500:  #737373  (Secondary text)
Zinc-600:  #525252  (Body text)
Zinc-700:  #404040  (Dark text)
Zinc-800:  #262626  (Page backgrounds dark)
Zinc-900:  #171717  (Header/sidebar backgrounds)
Zinc-950:  #0a0a0a  (Darkest)

Semantic Colors

Success

  • Primary: #22c55e (Green-500)
  • Dark: #16a34a (Green-600)
  • Light: #86efac (Green-300)
  • Usage: Success messages, positive indicators, current/fresh data

Warning

  • Primary: #f59e0b (Amber-500)
  • Light: #fbbf24 (Amber-400)
  • Usage: Stale data, deprecation notices

Error/Danger

  • Primary: #ef4444 (Red-500)
  • Dark: #dc2626 (Red-600)
  • Light: #fca5a5 (Red-300)
  • Usage: Outdated data, error messages, destructive actions

Info

  • Primary: #64748b (Slate-500)
  • Usage: Neutral information, recent data

Accent Colors

Light Mode:

  • Accent: --color-neutral-800 (dark gray)
  • Accent Content: --color-neutral-800
  • Accent Foreground: --color-white

Dark Mode:

  • Accent: --color-white
  • Accent Content: --color-white
  • Accent Foreground: --color-neutral-800

Used for:

  • Primary buttons
  • Active navigation items
  • Focus states
  • Primary CTAs

Typography System

Typeface

Primary Font: Instrument Sans

  • Source: Google Fonts (fonts.bunny.net)
  • Weights Available: 400 (Regular), 500 (Medium), 600 (Semibold)
  • Category: Sans-serif, Humanist
  • Use Case: All body text, headings, UI labels

Fallback Stack:

'Instrument Sans', 
ui-sans-serif, 
system-ui, 
sans-serif,
'Apple Color Emoji',
'Segoe UI Emoji',
'Segoe UI Symbol',
'Noto Color Emoji'

Font Sizes & Hierarchy

Via Flux components (sizes managed by Flux):

  • flux:heading size="xl": Page titles (largest)
  • flux:heading size="lg": Section titles
  • flux:heading: Standard headings
  • flux:subheading: Secondary headings, descriptions
  • flux:text: Body text
  • flux🏷️ Form labels, captions
  • flux:badge: Small labels, tags

Line Heights

  • Tight: Labels, badges (leading-tight)
  • Normal: Body text, headings (default)
  • Relaxed: Long-form content (when needed)

Weight Distribution

  • 400 (Regular): Body text, regular content
  • 500 (Medium): Secondary headings, strong emphasis, labels
  • 600 (Semibold): Primary headings, buttons, strong emphasis

Spacing & Layout

Spacing Scale

Based on 4px base unit:

0:    0px
0.5:  2px
1:    4px
1.5:  6px
2:    8px
2.5:  10px
3:    12px
3.5:  14px
4:    16px
5:    20px
6:    24px
7:    28px
8:    32px
9:    36px
10:   40px
11:   44px
12:   48px
...

Common Spacing Patterns

  • Gap between elements: gap-3 (12px), gap-4 (16px), gap-6 (24px)
  • Form field spacing: gap-2 (8px) for label + input
  • Card padding: p-4 (16px) for compact, p-6 (24px) for default, p-10 (40px) for large
  • Horizontal padding: px-4 (16px) standard
  • Vertical padding: py-3 (12px) standard

Grid System

  • Flex-based layouts (no CSS Grid for most components)
  • Default gap: gap-4 (16px)
  • Settings page: 2-column on desktop (220px sidebar + flex content)
  • Station results: 1-column list, single-level nesting

Responsive Breakpoints

Default (mobile):     0px
sm:                   640px   (@media max-width: 639px = mobile)
md:                   768px   (tablet)
lg:                   1024px  (desktop)
xl:                   1280px  (large desktop)
2xl:                  1536px  (extra large)

Breakpoint Patterns:

  • max-lg: - Mobile and tablet
  • lg: - Desktop and larger
  • max-md: - Mobile only
  • md: - Tablet and larger

Border & Radius

Border Weight

  • Default: 1px (all borders)
  • Emphasis: None (single weight used)

Border Radius

  • Small: rounded-md (6-8px) - Icons, small buttons, badges
  • Medium: rounded-lg (8-10px) - Inputs, dropdowns
  • Large: rounded-xl (12-16px) - Cards, modals, large components
  • None: rounded-none - Rarely used

Border Colors

Light Mode:

  • Default border: border-zinc-200
  • Focus ring: ring-accent (accent color)

Dark Mode:

  • Default border: border-zinc-700
  • Card/modal: border-stone-800 or border-neutral-800
  • Focus ring: ring-accent with ring-offset-2 and ring-offset-accent-foreground

Focus States

All interactive elements have:

  • ring-2 ring-accent (focus ring)
  • ring-offset-2 (space between element and ring)
  • ring-offset-accent-foreground (offset background color)

Component Patterns

Form Patterns

All form elements follow consistent structure:

  1. Label (top)
  2. Input/Select/Textarea
  3. Error message (bottom, conditional)
  4. Helper text (optional)

Spacing: gap-2 between label and input

States:

  • Normal: default appearance
  • Focus: ring around element
  • Disabled: opacity/pointer-events disabled
  • Error: red text below

Button Patterns

Variants:

  • variant="primary" - Primary action (accent color background)
  • variant="secondary" - Secondary action
  • variant="danger" - Destructive action (red)

States:

  • Normal: clickable
  • Hover: slight opacity increase
  • Disabled: disabled attribute via wire:loading.attr="disabled"
  • Loading: show spinner or text change

Card Patterns

Standard card styling:

  • Border: border border-zinc-200 dark:border-zinc-700
  • Radius: rounded-xl
  • Background: white (light) / dark (dark mode)
  • Padding: p-4 to p-10 depending on content density
  • Shadow: shadow-xs for subtle lift (optional)

Navigation Patterns

Sidebar Navigation:

  • flux:sidebar.nav wrapper
  • flux:sidebar.group for sections (with heading)
  • flux:sidebar.item for links
  • Active state: current attribute
  • Icon on left, text on right

Navbar Navigation:

  • flux:navbar wrapper
  • flux:navbar.item for links
  • Icons only or icon + text
  • Horizontal layout
  • Tooltip support

Data Visualization

Station Search Map Colors (Leaflet)

Classification-based color coding for fuel price data freshness:

  • Current (< 24h): #22c55e (Green-500)
  • Recent (24-48h): #64748b (Slate-500)
  • Stale (2-5 days): #f59e0b (Amber-500)
  • Outdated (5+ days): #ef4444 (Red-500)

Map Markers

  • Shape: Circle
  • Radius: 9px
  • Stroke: White, 2px weight
  • Fill: Classification color
  • Opacity: 85% (0.85)
  • Click: Shows popup with station details

Data Table Patterns

(No explicit tables in current design, but pattern would be):

  • Striped rows (alternate bg)
  • Hover states for interactivity
  • Clear column alignment
  • Sortable headers

Animations & Transitions

Page Transitions

All navigation via wire:navigate (no full page reload):

  • Seamless SPA-like experience
  • Preserves scroll position
  • No loading screen between pages

Component Transitions

Alpine.js Transitions:

  • Fade on message dismiss: x-show.transition.out.opacity.duration.1500ms
  • Duration: 1500ms (1.5 seconds)
  • Effect: Opacity fade

Flux Built-in:

  • Dropdown/menu opens: instant or quick fade
  • Sidebar collapse: smooth width transition
  • Modal appears: fade + scale (typical Flux defaults)

Hover & Active States

  • Links: hover:underline (default Flux)
  • Buttons: Opacity change on hover
  • Navigation items: Background highlight on hover/active
  • Interactive elements: Subtle color shift

Accessibility

Color Contrast

  • Text on backgrounds meets WCAG AA standards (4.5:1 for normal text)
  • Semantic colors (green/red) supplemented with icons/patterns
  • No color-only indicators

Interactive Elements

  • Keyboard navigable (all Flux components)
  • Focus indicators visible (ring-2 ring-accent)
  • Touch-friendly sizing (minimum 44x44px recommended)
  • ARIA labels where needed

Typography

  • Font sizes readable at standard distances
  • Line height adequate for readability
  • High contrast between text and background

Dark Mode

Implementation

  • Method: class="dark" on HTML root
  • Toggle: Managed by @fluxAppearance directive
  • Detection: Optional prefers-color-scheme integration

Dark Mode Colors

Text:

  • Primary: text-zinc-100 (light gray)
  • Secondary: text-zinc-400 (medium gray)
  • Disabled: text-zinc-500 (darker gray)

Backgrounds:

  • Page: bg-zinc-800
  • Header/Sidebar: bg-zinc-900
  • Cards: bg-stone-950 (darker variant)
  • Inputs: bg-zinc-900

Borders:

  • Primary: border-zinc-700
  • Secondary: border-stone-800
  • Subtle: border-neutral-800

Accents:

  • Primary accent inverts: white (instead of dark gray)

Image/SVG Handling in Dark

  • Logo icon color inverts via fill-current and text-* classes
  • Patterns use opacity: stroke-neutral-100/20 (dark) vs stroke-gray-900/20 (light)
  • Leaflet map: Default OSM colors (already dark-friendly)

Responsive Behavior

Mobile-First Approach

Design starts at mobile (smallest), enhances at larger breakpoints.

Key Breakpoints

Mobile (0-639px):

  • Single column layouts
  • Hamburger menu (sidebar collapses)
  • Stacked form fields
  • Full-width cards

Tablet (640-1023px):

  • Narrower multi-column (if applicable)
  • Touch-friendly spacing
  • Condensed headers

Desktop (1024px+):

  • Multi-column layouts
  • Horizontal navigation
  • Sidebar persistent
  • Full feature set visible

Layout Adjustments

  • Header: Hidden navbar items on mobile (max-lg:hidden)
  • Sidebar: Becomes mobile hamburger at lg breakpoint
  • Forms: Stack vertically on mobile, horizontal on desktop
  • Grids: 1 column mobile, 2-3 columns desktop

Consistency Patterns

Consistent Component Usage

  • All buttons: flux:button (never raw <button>)
  • All inputs: flux:input (with validation/errors)
  • All selects: flux:select
  • All headings: flux:heading (sizes: xl, lg, etc.)

Consistent Spacing

  • Inter-element gaps: multiples of 4px
  • Card padding: consistent with gap sizes
  • Consistent use of flexbox for alignment

Consistent States

  • Forms show errors below input in red
  • Success messages fade out after 2 seconds
  • Disabled states use opacity + pointer-events
  • Loading states shown via spinner or text change

Implementation Notes

CSS Custom Properties

--font-sans: 'Instrument Sans', ...
--color-accent: (theme-dependent)
--color-accent-content: (theme-dependent)
--color-accent-foreground: (theme-dependent)
--color-zinc-{50-950}: (full palette)

Tailwind Integration

  • Uses Tailwind CSS v4 with @tailwindcss/vite
  • @theme block defines custom colors and fonts
  • @custom-variant for dark mode
  • @layer for CSS overrides

Flux Integration

  • Heavy reliance on Flux v2 components
  • Flux provides theming, dark mode, layout components
  • Custom CSS only overrides specific Flux defaults
  • No Flux config file needed (uses defaults + CSS)