# Styling Best Practices & Guidelines

**Version:** 2.0.0
**Last Updated:** 2025-11-19
**Status:** ✅ Complete

---

## Quick Reference

### Golden Rules

1. ✅ **Use global patterns first** - Check [CSS_PATTERNS.md](./CSS_PATTERNS.md)
2. ✅ **Use design tokens** - `var(--color-primary)` not `#2563eb`
3. ❌ **No `:deep()` in components** - PrimeVue styles in `vendor/primevue-overrides.css`
4. ❌ **No duplication** - Write CSS once, use everywhere
5. ❌ **No hardcoded values** - Use tokens for all values

---

## Design Token Usage

### Colors
```css
/* ✅ GOOD */
color: var(--color-primary);
background: var(--color-bg);
border-color: var(--color-border);

/* ❌ BAD */
color: #2563eb;
background: #ffffff;
border-color: #e5e7eb;
```

### Spacing
```css
/* ✅ GOOD */
padding: var(--space-md);
margin: var(--space-lg);
gap: var(--space-sm);

/* ❌ BAD */
padding: 16px;
margin: 24px;
gap: 8px;
```

### Typography
```css
/* ✅ GOOD */
font-size: var(--text-base);
font-weight: var(--font-semibold);
line-height: var(--leading-normal);

/* ❌ BAD */
font-size: 16px;
font-weight: 600;
line-height: 1.5;
```

---

## File Organization

```
src/assets/css/
├── core/              # Foundation (DO NOT MODIFY without team approval)
│   ├── variables.css  # Base CSS variables
│   ├── tokens.css     # Extended design tokens
│   ├── reset.css      # CSS reset
│   └── typography.css # Font definitions
│
├── patterns/          # Reusable interactive patterns
│   ├── interactive.css # Spinners, trends, collapse
│   ├── dashboard.css   # Page headers, metrics, breakdowns
│   └── animations.css  # Transitions & animations
│
├── components/        # Component library
│   ├── cards.css      # All card variants
│   ├── buttons.css    # All button styles
│   ├── forms.css      # Form patterns
│   ├── tables.css     # Table styles
│   └── stats.css      # Statistics displays
│
├── layout/            # Page structure
│   ├── containers.css # Content containers
│   ├── grid.css       # Grid system
│   └── navigation.css # Navigation components
│
├── utilities/         # Utility classes
│   ├── colors.css     # Color utilities
│   ├── text.css       # Typography utilities
│   ├── spacing.css    # Margin/padding utilities
│   ├── flex.css       # Flexbox utilities
│   └── display.css    # Display utilities
│
└── vendor/            # Third-party overrides
    └── primevue-overrides.css # PrimeVue customization
```

---

## Naming Conventions

### Classes

```css
/* Component classes: .component-name */
.card { }
.btn { }
.form-input { }

/* Variant classes: .component-variant */
.btn-primary { }
.btn-secondary { }
.card-elevated { }

/* State classes: .state */
.active { }
.disabled { }
.invalid { }

/* Utility classes: .utility-value */
.text-center { }
.flex { }
.mt-lg { }
```

### BEM (When Needed)

```css
/* Block__Element--Modifier */
.metric-card { }              /* Block */
.metric-card__header { }      /* Element */
.metric-card--compact { }     /* Modifier */
```

---

## Performance

### CSS Bundle Optimization

```css
/* ✅ GOOD: Group related selectors */
.btn,
.btn-primary,
.btn-secondary {
  display: inline-flex;
  align-items: center;
}

/* ❌ BAD: Repeat properties */
.btn { display: inline-flex; align-items: center; }
.btn-primary { display: inline-flex; align-items: center; }
.btn-secondary { display: inline-flex; align-items: center; }
```

### Animations

```css
/* ✅ GOOD: Use transform & opacity (GPU-accelerated) */
.card-hover:hover {
  transform: translateY(-2px);
  opacity: 0.9;
}

/* ❌ BAD: Animate layout properties */
.card-hover:hover {
  top: -2px;  /* Forces reflow */
  height: 110%;  /* Forces reflow */
}
```

---

## Accessibility

### Color Contrast (WCAG 2.1 AA)

```css
/* ✅ GOOD: 4.5:1 contrast ratio */
color: var(--color-text);        /* #111827 on #ffffff = 16.9:1 */
background: var(--color-bg);

/* ✅ GOOD: Large text (18px+) needs 3:1 */
.heading {
  font-size: var(--text-xl);
  color: var(--color-text-secondary);  /* #6b7280 = 4.6:1 */
}
```

### Focus States

```css
/* ✅ GOOD: Visible focus indicator */
.btn:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* ❌ BAD: Removing focus */
.btn:focus {
  outline: none;  /* Never do this! */
}
```

### Touch Targets (Mobile)

```css
/* ✅ GOOD: Minimum 44x44px */
.btn {
  min-height: 44px;
  min-width: 44px;
  padding: var(--space-sm) var(--space-md);
}
```

---

## Browser Compatibility

### Supported Browsers

- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+

### Use Modern CSS

```css
/* ✅ GOOD: Modern CSS features */
.grid {
  display: grid;
  gap: var(--space-md);
}

.card {
  aspect-ratio: 16 / 9;
}

/* ⚠️ If using very new features, check caniuse.com */
```

---

## Testing

### Before Committing

```bash
# 1. Build check
npm run build

# 2. Visual regression tests
npm run test:e2e

# 3. Check bundle size
ls -lh dist/assets/*.css
```

### Manual Testing Checklist

- [ ] Desktop (1920x1080, 1366x768)
- [ ] Tablet (768x1024)
- [ ] Mobile (375x667, 414x896)
- [ ] Dark mode (if applicable)
- [ ] Print view (`@media print`)
- [ ] Keyboard navigation (Tab through elements)
- [ ] Screen reader (test with NVDA/JAWS)

---

## Code Review Standards

### CSS in PRs

Reviewers check for:

1. **No duplication** - Pattern exists in global CSS?
2. **Design tokens** - All values use `var(--*)`?
3. **No `:deep()`** - PrimeVue overrides in correct file?
4. **Scoped CSS justified** - < 50 lines & documented?
5. **Responsive** - Works on all breakpoints?
6. **Accessible** - Focus states, contrast ratios?
7. **Performance** - No layout thrashing animations?
8. **Tested** - Build passes, E2E tests pass?

---

## Common Mistakes

### ❌ Mistake #1: Not Checking Pattern Library

```vue
<!-- Wrong: Recreating existing pattern -->
<style scoped>
.my-button {
  background: var(--color-primary);
  /* ... 20 lines duplicating btn class */
}
</style>

<!-- Correct: Use existing pattern -->
<button class="btn btn-primary">Click</button>
```

### ❌ Mistake #2: Hardcoded Values

```css
/* Wrong */
padding: 16px;
color: #2563eb;
border-radius: 8px;

/* Correct */
padding: var(--space-md);
color: var(--color-primary);
border-radius: var(--radius-md);
```

### ❌ Mistake #3: Using `:deep()` for PrimeVue

```vue
<!-- Wrong: In component -->
<style scoped>
:deep(.p-inputtext) {
  border: 2px solid blue !important;
}
</style>

<!-- Correct: In vendor/primevue-overrides.css -->
```

---

## Resources

- **Pattern Library:** [CSS_PATTERNS.md](./CSS_PATTERNS.md)
- **Component Guidelines:** [COMPONENT_STYLING.md](./COMPONENT_STYLING.md)
- **Form Template:** [FORM_TEMPLATE.md](./FORM_TEMPLATE.md)
- **Design Tokens:** [DESIGN_TOKENS.md](./DESIGN_TOKENS.md)
- **Onboarding:** [ONBOARDING_CSS.md](./ONBOARDING_CSS.md)

---

**Last Updated:** 2025-11-19
**Version:** 2.0.0
**Maintained By:** Frontend Team
