283 lines
7.6 KiB
Markdown
283 lines
7.6 KiB
Markdown
# Rocky Mountain Vending - Master Style Guide
|
|
|
|
## Color Palette
|
|
|
|
### Primary Colors
|
|
|
|
- **Background**: `#fff8eb` (Warm cream)
|
|
- **Foreground**: Dark text color for body text
|
|
- **Primary**: Purple/blue accent color
|
|
- **Secondary**: Green accent color
|
|
|
|
### Link Colors
|
|
|
|
- **Link Default**: Standard foreground color
|
|
- **Link Hover/Active**: `#c4142c` (Red - RGB: 196, 20, 44)
|
|
- **Link Highlight**: Red background highlight on hover
|
|
|
|
## Typography
|
|
|
|
### Fonts
|
|
|
|
- **Body Font**: Inter (with fallback)
|
|
- **Mono Font**: Geist Mono (with fallback)
|
|
|
|
### Font Sizes
|
|
|
|
- Base: 16px
|
|
- Small: 14px
|
|
- Medium: 16px
|
|
- Large: 18px+
|
|
|
|
## Hyperlinks
|
|
|
|
### Standard Link Styling
|
|
|
|
All hyperlinks (`<a>` tags and Next.js `<Link>` components) should follow these rules:
|
|
|
|
1. **Default State**:
|
|
- Color: Foreground color (readable text color)
|
|
- No underline
|
|
- Smooth transition on hover
|
|
|
|
2. **Hover State**:
|
|
- Color: Red (`#c4142c` or `rgb(196, 20, 44)`)
|
|
- Optional: Subtle background highlight
|
|
- Smooth color transition
|
|
|
|
3. **Active State**:
|
|
- Same as hover state
|
|
- May include underline for emphasis
|
|
|
|
### Implementation
|
|
|
|
- Use CSS variable `--link-color` for default state
|
|
- Use CSS variable `--link-hover-color` for hover/active states
|
|
- Apply globally via `@layer base` in `globals.css`
|
|
|
|
## Components
|
|
|
|
### Navigation Links
|
|
|
|
- Follow standard link styling
|
|
- Hover state changes to red
|
|
- Smooth transitions
|
|
|
|
### Footer Links
|
|
|
|
- Follow standard link styling
|
|
- May include underline on hover
|
|
|
|
### Button Links
|
|
|
|
- Use button component styling
|
|
- May override link colors for consistency
|
|
|
|
## Spacing
|
|
|
|
### Standard Spacing Scale
|
|
|
|
- XS: 0.5rem (8px)
|
|
- SM: 1rem (16px)
|
|
- MD: 1.5rem (24px)
|
|
- LG: 2rem (32px)
|
|
- XL: 3rem (48px)
|
|
|
|
## Border Radius
|
|
|
|
- Default: 0.5rem (8px)
|
|
- Small: calc(var(--radius) - 4px)
|
|
- Medium: calc(var(--radius) - 2px)
|
|
- Large: var(--radius)
|
|
- XL: calc(var(--radius) + 4px)
|
|
|
|
## Layout & Containers
|
|
|
|
### Page Containers
|
|
|
|
- **Standard pages**: `container mx-auto px-4 py-8 md:py-12 max-w-4xl`
|
|
- **Wide pages**: `container mx-auto px-4 py-8 md:py-12 max-w-6xl`
|
|
- **Full-width pages**: `container mx-auto px-4 py-8 md:py-12` (no max-width)
|
|
|
|
### Section Containers
|
|
|
|
- **Standard sections**: `py-20 md:py-28` with optional `bg-muted/30` for alternating backgrounds
|
|
- **Hero sections**: `py-20 md:py-32`
|
|
- **Container wrapper**: Always use `container mx-auto px-4` inside sections
|
|
|
|
## Typography Standards
|
|
|
|
### Headings
|
|
|
|
#### H1 (Page Titles)
|
|
|
|
- **Classes**: `text-4xl md:text-5xl font-bold mb-4` (or `mb-6` for more spacing)
|
|
- **Usage**: Only one H1 per page (page title)
|
|
- **Example**: `<h1 className="text-4xl md:text-5xl font-bold mb-4">Page Title</h1>`
|
|
|
|
#### H2 (Section Headers)
|
|
|
|
- **Section headers** (centered): `text-3xl font-bold tracking-tight md:text-4xl lg:text-5xl mb-4 text-balance`
|
|
- **Page headers** (left-aligned): `text-2xl md:text-3xl font-semibold mb-6`
|
|
- **Header wrapper**: `text-center mb-12 md:mb-16` for section headers
|
|
|
|
#### H3
|
|
|
|
- **Standard**: `text-xl font-semibold mb-2` or `mb-3`
|
|
|
|
### Paragraphs
|
|
|
|
- **Standard text**: `text-lg text-muted-foreground text-pretty leading-relaxed`
|
|
- **Centered text**: Add `max-w-2xl mx-auto` for centered paragraphs
|
|
- **Small text**: `text-sm text-muted-foreground`
|
|
|
|
## Cards
|
|
|
|
### Standard Card Styling
|
|
|
|
- **Border**: `border-border/50` (preferred) or `border-2` for emphasis
|
|
- **Hover states**: `hover:border-secondary/50 transition-colors`
|
|
- **Shadow**: `shadow-lg` or `shadow-md` as needed
|
|
- **Padding**: `p-6` or `p-6 md:p-8` for CardContent
|
|
|
|
### Card Examples
|
|
|
|
```tsx
|
|
// Standard card
|
|
<Card className="border-border/50 hover:border-secondary/50 transition-colors">
|
|
<CardContent className="p-6">
|
|
{/* content */}
|
|
</CardContent>
|
|
</Card>
|
|
|
|
// Emphasis card
|
|
<Card className="border-2 shadow-lg">
|
|
<CardContent className="p-6 md:p-8">
|
|
{/* content */}
|
|
</CardContent>
|
|
</Card>
|
|
```
|
|
|
|
## Images
|
|
|
|
### Image Sizing Standards
|
|
|
|
#### Maximum Dimensions
|
|
|
|
- **Grid/Card images**: Maximum 300px per dimension
|
|
- **Full-width images**: Maximum 600px per dimension
|
|
- **Always preserve aspect ratio** when constraining
|
|
|
|
#### Image Layout Patterns
|
|
|
|
**Single Image (Centered)**
|
|
|
|
```tsx
|
|
<div className="max-w-md mx-auto">
|
|
<div className="relative w-full overflow-hidden rounded-lg bg-muted shadow-sm">
|
|
<Image
|
|
src={src}
|
|
alt={alt}
|
|
width={Math.min(originalWidth, 600)}
|
|
height={Math.min(originalHeight, 600)}
|
|
className="object-contain w-full h-auto"
|
|
/>
|
|
</div>
|
|
</div>
|
|
```
|
|
|
|
**Grid Images (2-4 images)**
|
|
|
|
```tsx
|
|
<div className="grid gap-6 md:grid-cols-2">
|
|
{images.map((img) => (
|
|
<div key={img.id} className="max-w-xs mx-auto">
|
|
<div className="relative w-full overflow-hidden rounded-lg bg-muted shadow-sm">
|
|
<Image
|
|
src={img.src}
|
|
alt={img.alt}
|
|
width={Math.min(img.width, 300)}
|
|
height={Math.min(img.height, 300)}
|
|
className="object-contain w-full h-auto"
|
|
/>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
```
|
|
|
|
**Card Images (Aspect Ratio)**
|
|
|
|
```tsx
|
|
<Card>
|
|
<div className="aspect-video relative bg-muted">
|
|
<Image src={src} alt={alt} fill className="object-cover" />
|
|
</div>
|
|
<CardContent>{/* content */}</CardContent>
|
|
</Card>
|
|
```
|
|
|
|
### Image Requirements
|
|
|
|
1. **Always constrain large images**: Use `Math.min(width, MAX)` pattern
|
|
2. **Add max-width constraints**: Use `max-w-xs` (320px), `max-w-md` (448px), or `max-w-lg` (512px)
|
|
3. **Use proper object-fit**: `object-contain` for preserving aspect ratio, `object-cover` for filling containers
|
|
4. **Prevent stacking**: Use grid layouts for multiple images instead of vertical stacking
|
|
5. **Wrapper classes**: `relative w-full overflow-hidden rounded-lg bg-muted shadow-sm`
|
|
|
|
### Image Size Constraints by Context
|
|
|
|
- **In grid layouts**: Max 300px per dimension
|
|
- **In cards**: Use `aspect-video` or `aspect-square` with `fill` prop
|
|
- **Standalone images**: Max 600px per dimension with `max-w-md mx-auto` wrapper
|
|
|
|
## Spacing Standards
|
|
|
|
### Section Spacing
|
|
|
|
- **Section padding**: `py-20 md:py-28` (standard sections)
|
|
- **Section margin bottom**: `mb-12 md:mb-16` for section headers
|
|
- **Page padding**: `py-8 md:py-12` (page containers)
|
|
|
|
### Element Spacing
|
|
|
|
- **Header margin**: `mb-12 md:mb-16` for section headers, `mb-8` for page headers
|
|
- **Card gaps**: `gap-6` or `gap-8` in grid layouts
|
|
- **Paragraph spacing**: `mb-4` or `mb-6` between paragraphs
|
|
|
|
## Best Practices
|
|
|
|
1. **Consistency**: Always use the defined color variables and spacing scale
|
|
2. **Accessibility**: Ensure sufficient contrast ratios (WCAG AA minimum)
|
|
3. **Transitions**: Use smooth transitions for interactive elements (`transition-colors`)
|
|
4. **Responsive**: All styles should work across device sizes (use `md:` breakpoints)
|
|
5. **Image optimization**: Always constrain image dimensions and use proper aspect ratios
|
|
6. **Link styling**: Rely on global CSS variables - avoid hardcoded `text-primary` or `text-secondary` on links
|
|
7. **Grid layouts**: Use grid layouts for multiple images instead of vertical stacking
|
|
|
|
## Formatting Script
|
|
|
|
A formatting standardization script is available at `scripts/standardize-formatting.py` that automatically applies these standards across all TSX files.
|
|
|
|
### Usage
|
|
|
|
```bash
|
|
# Test mode (dry run)
|
|
python3 scripts/standardize-formatting.py --dry-run
|
|
|
|
# Test specific file
|
|
python3 scripts/standardize-formatting.py --dry-run --file code/components/about-page.tsx
|
|
|
|
# Apply changes to all files
|
|
python3 scripts/standardize-formatting.py
|
|
```
|
|
|
|
The script will:
|
|
|
|
- Standardize container classes and spacing
|
|
- Fix typography classes (H1, H2, paragraphs)
|
|
- Standardize card borders and shadows
|
|
- Remove hardcoded link colors
|
|
- Constrain large images while preserving aspect ratio
|
|
- Add proper image wrapper classes
|
|
- Generate backups and detailed reports
|