Design Tokens
Color Palette
HSLA Color System
This project uses HSLA (Hue, Saturation, Lightness, Alpha) color format throughout for enhanced maintainability and flexibility.
Key Benefits
- Better opacity control with alpha channel
- Intuitive color manipulation (hue, saturation, lightness)
- Consistent format across all components
- Enhanced accessibility support
- Future-proof color system architecture
Usage Example
// Base color
hsla(217, 91%, 60%, 1)
// With transparency
hsla(217, 91%, 60%, 0.5)
// Lighter variant
hsla(217, 91%, 80%, 1)
Note: All color examples below show HSLA values alongside their corresponding TailwindCSS utility classes for easy implementation.
Primary Colors
Light Mode
Dark Mode
Neutral Scale
Typography System
Font Family
Headings
Heading 1
Heading 2
Heading 3
Heading 4
Body Text
Text Colors
Spacing & Layout
Container Max Widths
Content Spacing Scale
Color Token System
Color Token Structure
The color token system provides semantic color definitions that automatically adapt to light and dark themes. These tokens ensure consistent color usage across all components while maintaining proper contrast ratios.
Primary Colors (High Contrast)
// Usage example
const primaryButton = `
${colorTokens.primary.background}
${colorTokens.primary.text}
`;
// Results in:
// bg-black dark:bg-white
// text-white dark:text-black
Secondary Colors (Muted)
// Usage example
const subtleCard = `
${colorTokens.secondary.background}
${colorTokens.secondary.text}
`;
// Results in:
// bg-neutral-100 dark:bg-neutral-800
// text-neutral-700 dark:text-neutral-300
Surface Colors (Cards & Containers)
// Usage example
const cardStyles = `
${colorTokens.surface.background}
${colorTokens.surface.border}
`;
// Results in:
// bg-white dark:bg-black
// border-neutral-200 dark:border-neutral-800
Text Color Hierarchy
text-black dark:text-white
text-neutral-800 dark:text-neutral-200
text-neutral-600 dark:text-neutral-400
text-neutral-500 dark:text-neutral-500
Color Presets
Color presets provide pre-configured color combinations for specific component contexts, ensuring consistent styling patterns across similar elements.
Available Presets
Default Preset
heading
body
muted
colorPresets.default
Hero Preset
heading
body
muted
colorPresets.hero
Component Default System
The default system provides automatic color assignment for components when no specific color is provided, ensuring consistent styling while allowing for easy customization when needed.
getComponentDefaults() Function
Default Assignments
// Usage with defaults
getComponentDefaults('heading')
// Returns: text-black dark:text-white
getComponentDefaults('body')
// Returns: text-neutral-800 dark:text-neutral-200
Enhanced Utility Functions
getHeadingClasses() with Defaults
Default Heading (auto color)
getHeadingClasses('h2')
Custom Color Heading
getHeadingClasses('h2', 'muted')
getBodyClasses() with Defaults
Default body text (auto color)
getBodyClasses('default')
Custom color body text
getBodyClasses('default', 'muted')
HSLA System Integration
styleUtils HSLA Colors
The hslaColors
system in styleUtils.ts
provides a comprehensive HSLA color foundation for the project.
Direct HSLA Access
import { hslaColors, getHslaColor } from '../utils/styleUtils';
// Access color values directly
const darkBg = hslaColors.dark.bg;
// Returns: "hsla(0, 0%, 16%, 1)"
// Or use the utility function
const neutralGray = getHslaColor('neutral.500');
// Returns: "hsla(0, 0%, 52%, 1)"
Color Manipulation
import { withOpacity, adjustLightness } from '../utils/styleUtils';
// Create transparent variants
const semiTransparent = withOpacity(
'hsla(217, 91%, 60%, 1)',
0.5
);
// Adjust lightness
const lighter = adjustLightness(
'hsla(217, 91%, 60%, 1)',
80
);
💡 Pro Tip: Use the HSLA system for custom colors and shadows while leveraging TailwindCSS utility classes for standard UI elements.
🎨 CSS Variables: Global dark theme colors in global.css
use HSLA format and are accessible via CSS custom properties.
Global CSS HSLA Variables
The following HSLA colors are defined in src/styles/global.css
and mirror the styleUtils system:
/* CSS Custom Properties (global.css) */
--color-dark-bg: hsla(0, 0%, 16%, 1); /* hslaColors.dark.bg */
--color-dark-surface: hsla(215, 16%, 27%, 1); /* hslaColors.dark.surface */
--color-dark-text: hsla(0, 0%, 100%, 1); /* hslaColors.dark.text */
--color-dark-text-secondary: hsla(220, 13%, 83%, 1); /* hslaColors.dark.textSecondary */
--color-dark-text-muted: hsla(220, 9%, 66%, 1); /* hslaColors.dark.textMuted */
--color-dark-border: hsla(215, 16%, 27%, 1); /* hslaColors.dark.border */
Usage Examples
HSLA Best Practices & Guidelines
✅ Do
- Use HSLA for custom colors and shadows
- Leverage the
hslaColors
system for consistency - Use utility functions like
withOpacity()
- Prefer TailwindCSS classes for standard UI elements
- Document color choices with meaningful variable names
- Test colors in both light and dark modes
❌ Don't
- Mix hex, RGB, and HSLA formats in the same component
- Hardcode color values without using the system
- Use pure black (#000000) or white (#FFFFFF) - use HSLA variants
- Forget to handle transparency (alpha channel) properly
- Ignore accessibility contrast requirements
- Create colors without testing hover/focus states
Example: Custom Shadow with HSLA
// ✅ Good: Using HSLA system
import { hslaColors, withOpacity } from '../utils/styleUtils';
const customShadow = {
boxShadow: `0 4px 6px ${withOpacity(hslaColors.shadows.boxLight, 0.1)}`
};
// ❌ Avoid: Hardcoded values
const badShadow = {
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)' // Not consistent with system
};
Direct Token Usage
import { colorTokens } from '../utils/styleUtils';
// Direct token usage
const primaryButton = `
${colorTokens.primary.background}
${colorTokens.primary.text}
${colorTokens.primary.hover}
`;
// Text hierarchy
const textClasses = `
${colorTokens.text.primary} // Main headings
${colorTokens.text.secondary} // Body text
${colorTokens.text.muted} // Captions, metadata
${colorTokens.text.subtle} // Placeholder text
`;
// Surface elements
const cardClasses = `
${colorTokens.surface.background}
${colorTokens.surface.border}
${colorTokens.surface.hover}
`;
Color Preset Usage
import { colorPresets, getColorPreset } from '../utils/styleUtils';
// Using preset directly
const heroSection = `
<h1 class="${colorPresets.hero.heading}">
Hero Title
</h1>
<p class="${colorPresets.hero.body}">
Hero description text
</p>
`;
// Using getColorPreset function
const cardPreset = getColorPreset('card');
const cardHeading = cardPreset.heading;
const cardBody = cardPreset.body;
Enhanced Functions with Defaults
import {
getHeadingClasses,
getBodyClasses,
getComponentDefaults
} from '../utils/styleUtils';
// With automatic defaults (recommended)
const heading = getHeadingClasses('h1');
// Returns: text-4xl md:text-5xl font-bold leading-tight text-black dark:text-white
const body = getBodyClasses('default');
// Returns: text-base leading-relaxed text-neutral-800 dark:text-neutral-200
// With custom color override
const mutedHeading = getHeadingClasses('h2', 'muted');
const primaryBody = getBodyClasses('large', 'primary');
// Custom color string
const customHeading = getHeadingClasses('h3', 'text-blue-600');
// Getting defaults manually
const defaultHeadingColor = getComponentDefaults('heading');
const defaultBodyColor = getComponentDefaults('body');
Component Library
Button Patterns
Button Variants
Usage Examples
import { getButtonClasses } from '../utils/styleUtils';
<button class={getButtonClasses('primary')}>
Primary Action
</button>
<button class={getButtonClasses('secondary')}>
Secondary Action
</button>
<button class={getButtonClasses('filter')}>
Filter Option
</button>
Color Overrides
You can customize button colors by providing color overrides to getButtonClasses()
:
Color Override Usage
import { getButtonClasses } from '../utils/styleUtils';
// Custom fill color
const blueButton = getButtonClasses('primary', '', {
fillColor: 'hsla(217, 91%, 60%, 1)'
});
// Custom border and text color
const greenOutline = getButtonClasses('secondary', '', {
borderColor: 'hsla(142, 71%, 45%, 1)',
textColor: 'hsla(142, 71%, 45%, 1)'
});
// Use in template
<button
class={blueButton.classes}
style={blueButton.styles}
>
Custom Blue Button
</button>
Card Patterns
Tag Patterns
Topic Tags
Filter Buttons
Tag Size Variations
Tag Style Variations
Layout Components
Hero Component
Sample Hero Title
This demonstrates the hero component with primary and secondary call-to-action buttons.
Two Column Layout
Left Column
This is the left column content. It can contain any content and will automatically adapt to mobile by stacking vertically.
Right Column
This is the right column content. The layout is responsive and maintains consistent spacing across all screen sizes.
Content Block
Sample Content Block
Content blocks provide consistent spacing and typography for sections of content. They support various spacing options and maintain design consistency.
Project Components
Project Hero
Sample Project
A demonstration project showing how components work together
Tools & Technologies
Materials
Project Links
Project Highlight
This component highlights important aspects of a project with consistent styling and spacing.
Project Insight
Design Decision
Project Outcome
Final Result
Interactive Features
Live Theme Toggle
The theme toggle in the header affects this entire page in real-time, demonstrating how all components adapt to both light and dark modes.
Hover States
All interactive elements include hover states that provide visual feedback.
Focus States
All interactive elements include keyboard-accessible focus states with proper focus rings.
Tip: Use Tab key to navigate through focusable elements and see the focus rings in action.
Usage Guidelines
Component Import Pattern
// Import utilities
import {
getButtonClasses,
getCardClasses,
getTagClasses,
getHeadingClasses,
getBodyClasses,
colorTokens,
colorPresets,
getComponentDefaults,
textStyles,
layoutSizes
} from '../utils/styleUtils';
// Import components
import Section from '../components/Section.astro';
import ContentBlock from '../components/ContentBlock.astro';
Accessibility Requirements
- All interactive elements must be keyboard accessible
- Focus states are required for all clickable elements
- Color contrast ratios meet WCAG 2.1 AA standards in both themes
- Semantic HTML structure is maintained throughout
- Screen reader friendly markup and ARIA labels where needed
Responsive Design Principles
- Mobile-first responsive design approach
- Touch-friendly interactions on mobile devices
- Consistent spacing and typography across all screen sizes
- Flexible layouts that adapt to content length
- Optimized loading performance for all device types
Theme Consistency
- All components must work seamlessly in both light and dark modes
- Use semantic color tokens instead of hardcoded colors
- Maintain proper contrast ratios in both themes
- Test component visibility and usability in both modes
- Ensure hover and focus states work in both themes
Color System Best Practices
- Prefer color tokens over direct TailwindCSS classes for theme compatibility
- Use colorPresets for consistent component styling patterns
- Leverage getComponentDefaults() for automatic color assignment
- Override defaults only when specific design requirements demand it
- Always test color combinations in both light and dark modes
- Maintain text contrast ratios above WCAG AA standards (4.5:1)