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)
Logo
- 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 tabletlg:- Desktop and largermax-md:- Mobile onlymd:- 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-800orborder-neutral-800 - Focus ring:
ring-accentwithring-offset-2andring-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:
- Label (top)
- Input/Select/Textarea
- Error message (bottom, conditional)
- 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 actionvariant="danger"- Destructive action (red)
States:
- Normal: clickable
- Hover: slight opacity increase
- Disabled:
disabledattribute viawire: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-4top-10depending on content density - Shadow:
shadow-xsfor subtle lift (optional)
Navigation Patterns
Sidebar Navigation:
flux:sidebar.navwrapperflux:sidebar.groupfor sections (with heading)flux:sidebar.itemfor links- Active state: current attribute
- Icon on left, text on right
Navbar Navigation:
flux:navbarwrapperflux:navbar.itemfor 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
@fluxAppearancedirective - 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-currentandtext-*classes - Patterns use opacity:
stroke-neutral-100/20(dark) vsstroke-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 @themeblock defines custom colors and fonts@custom-variantfor dark mode@layerfor 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)