:root variables

The custom properties I reach for at the start of nearly every project. Defining them once in :root keeps everything consistent and makes theming trivial.

Colours

:root {
  --primary: #ab9efa;
  --background: #ffffff;
  --text: #1a1a1a;
  --muted: #6b7280;
  --border: #e5e7eb;
  --success: #9efaa7;
  --danger: #ffb5b5;
}

Typography

:root {
  --font-body: system-ui, sans-serif;
  --font-heading: "Raleway", sans-serif;
  --font-mono: Menlo, Monaco, Consolas, "Courier New", monospace;

  /* fluid type: scales between the min and max across the viewport */
  --step-0: clamp(1rem, 0.9rem + 0.5vw, 1.25rem);
  --step-1: clamp(1.25rem, 1rem + 1vw, 1.75rem);
  --step-2: clamp(1.75rem, 1.4rem + 2vw, 3rem);
}

Spacing & radius

:root {
  --space-xs: 4px;
  --space-sm: 8px;
  --space-md: 16px;
  --space-lg: 32px;
  --space-xl: 64px;

  --border-radius: 8px;
  --max-width: 1100px;
}

Dark mode

Because they’re custom properties, a theme swap is just a re-declaration:

:root[data-theme="dark"] {
  --background: #1a1a1a;
  --text: #f5f5f5;
  --muted: #9ca3af;
  --border: #374151;
}