# 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:label:** 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

```css
--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)

