- Quick Start
- Architecture Overview
- Design Tokens
- Components Library
- Utility Classes
- Migration Guide
- Working with Markdown Files
- Best Practices
- Next Steps
This guide explains how to adopt the new centralized design system implemented in assets/css/components.css. It covers design tokens, reusable components, utilities, and migration strategies to help you modernize your pages.
Quick Start
TL;DR — The design system provides:
- Design tokens — CSS custom properties for spacing, colors, radius, shadows, and transitions
- Reusable components — Pre-built cards, buttons, grids, timelines, and more
- Automatic support — Dark mode and reduced-motion preferences work out of the box
Architecture Overview
Key Files
| File | Purpose |
|---|---|
assets/css/components.css |
Global design tokens & components (source of truth) |
assets/css/responsive.css |
Responsive utilities and breakpoint helpers |
assets/css/about-page.css |
Legacy page styles (migrate away from these) |
Best Practice: Update tokens in :root rather than modifying component rules directly.
Design Tokens
Design tokens provide consistent spacing, colors, and visual properties across your site. Reference the full documentation in docs/DESIGN_TOKENS_REFERENCE.md.
Common Token Usage
.my-component {
/* Spacing */
padding: var(--space-lg);
margin-bottom: var(--space-md);
/* Visual style */
border-radius: var(--radius-md);
box-shadow: var(--shadow-md);
/* Colors */
background: var(--card-bg);
color: var(--card-text);
border: 1px solid var(--card-border);
/* Animation */
transition: var(--transition-normal);
}
Essential Token Categories
- Spacing:
--space-xs,--space-sm,--space-md,--space-lg,--space-xl - Radius:
--radius-sm,--radius-md,--radius-lg,--radius-full - Shadows:
--shadow-sm,--shadow-md,--shadow-lg - Colors:
--card-bg,--card-text,--card-border - Transitions:
--transition-fast,--transition-normal,--transition-slow
Components Library
Buttons
Pre-styled button components with multiple variants.
<!-- Basic buttons -->
<a class="btn btn--primary">Primary Button</a>
<a class="btn btn--secondary">Secondary Button</a>
<!-- Enhanced button with multiple modifiers -->
<a class="btn btn--primary btn--large btn--rounded btn--shadow">
Call to Action
</a>
Renders as:
Primary Button Secondary Button
Available Modifiers:
- Size:
btn--large,btn--small - Style:
btn--rounded,btn--outline,btn--icon,btn--shadow
Cards
Flexible card components for content grouping.
Basic Card Structure
<div class="card">
<div class="card__header">
<h3 class="card__title">Card Title</h3>
</div>
<div class="card__body">
<p>Card content goes here...</p>
</div>
</div>
Renders as:
Card Title
Card content goes here...
Card Variants
<!-- Compact card -->
<div class="card card--compact">...</div>
<!-- Large card with elevation -->
<div class="card card--large card--elevated">...</div>
<!-- Flat card without shadow -->
<div class="card card--flat">...</div>
<!-- Light background variant -->
<div class="card card--light">...</div>
<!-- Borderless card -->
<div class="card card--borderless">...</div>
<!-- Interactive (hover effects) -->
<div class="card card--interactive">...</div>
<!-- Horizontal layout -->
<div class="card card--horizontal">...</div>
Renders as:
Blog Card
Specialized card for blog post previews.
<a href="/post-url/" class="blog-card">
<span class="blog-card__date">Nov 23, 2025</span>
<h3 class="blog-card__title">Your Post Title</h3>
<p class="blog-card__excerpt">
A brief excerpt of your blog post content...
</p>
</a>
Grid Layouts
Responsive grid system for organizing cards and content.
<!-- 3-column grid -->
<div class="card-grid card-grid--3col">
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
</div>
<!-- 2-column grid with compact spacing -->
<div class="card-grid card-grid--2col card-grid--compact">
<div class="card">...</div>
<div class="card">...</div>
</div>
<!-- 4-column grid with spacious layout -->
<div class="card-grid card-grid--4col card-grid--spacious">
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
<div class="card">...</div>
</div>
Renders as:
3-column grid
2-column grid with compact spacing
4-column grid with spacious layou
Grid Modifiers:
- Columns:
card-grid--2col,card-grid--3col,card-grid--4col - Spacing:
card-grid--compact,card-grid--spacious
Image Component (usage)
Use the .figure wrapper together with .img-responsive for consistent image handling. Float variants (.figure--left, .figure--right) provide editorial layouts that collapse to block on narrow screens.
<figure class="figure figure--left">
<img src="/assets/images/example.jpg" alt="Example" class="img-responsive" />
<figcaption class="figure-caption">Figure: Example image caption.</figcaption>
</figure>
<p>
This paragraph will flow around the floated figure on wide screens, and stack beneath the image on small screens.
</p>
<figure class="figure">
<img src="/assets/images/hero-sample.jpg" alt="Hero sample" class="img-responsive" />
<figcaption class="figure-caption">Centered image with caption</figcaption>
</figure>
Renders as:
This paragraph will flow around the floated figure on wide screens, and stack beneath the image on small screens.
Notes:
- Use
figure--left/figure--rightfor editorial float layouts. - Images are constrained by
max-width: 100%and will not overflow their containers.
Avatar Component (usage)
Use the .avatar component for user pictures, initials fallback, and presence indicators. The component supports size modifiers, shape variants, ring/border decorations and an inline status indicator.
<!-- Initials fallback -->
<span class="avatar-wrapper">
<span class="avatar avatar--md avatar--initials">JS</span>
</span>
<!-- Image avatar with online status and ring -->
<span class="avatar-wrapper">
<span class="avatar avatar--md avatar--ring">
<img src="/assets/images/avatar-alex.jpg" alt="Alex" />
</span>
<span class="avatar__status avatar__status--online" aria-hidden="true"></span>
</span>
<!-- Large square avatar with border -->
<span class="avatar-wrapper">
<span class="avatar avatar--lg avatar--square avatar--border">
<img src="/assets/images/avatar-team.jpg" alt="Team" />
</span>
</span>
Renders as:
JS
Notes:
- Use
avatar--initialswhen an image is unavailable (show initials or SVG fallback). - Add
avatar__status--online|--away|--offlinefor presence; the small indicator is decorative (use ARIA where presence conveys state). - Use
avatar--ringoravatar--borderfor emphasis in lists or profile headers.
Video Component (usage)
Videos are wrapped with the .video-wrapper helper to preserve aspect ratio and prevent overflow. Use the youtube-video-card for a compact card presentation.
<!-- Responsive embedded video (16:9) -->
<div class="video-wrapper">
<iframe
src="https://www.youtube.com/playlist?list=PLLAZ4kZ9dFpOPV5C5Ay0pHaa0RJFhcmcB"
title="Jekyll - Static Site Generator | Tutorial"
frameborder="0"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
loading="lazy">
</iframe>
</div>
<!-- Video inside a card -->
<div class="youtube-video-card">
<h3>Optimal Control Theory</h3>
<div class="video-wrapper">
<iframe
src="https://www.youtube.com/embed/F8iOU1ci19Q"
title="Meet Jekyll - The Static Site Generator"
loading="lazy"
allowfullscreen>
</iframe>
</div>
<p>Short description of the video and why it's useful.</p>
</div>
Renders as:
Meet Jekyll - The Static Site Generator
Short description of the video and why it's useful.
Notes:
- Use
loading="lazy"to defer offscreen video loads. - Keep descriptive
titleandariaattributes for accessibility. - The
.video-wrapperpreserves 16:9 aspect ratio; override with custom classes only when necessary.
Timeline
Vertical timeline for chronological content.
<div class="timeline">
<div class="timeline-item">
<span class="date-badge">2025</span>
<h3>Event Title</h3>
<p>Event description...</p>
</div>
<div class="timeline-item">
<span class="date-badge">2024</span>
<h3>Previous Event</h3>
<p>Event description...</p>
</div>
</div>
Renders as:
Event Title
Event description...
Previous Event
Event description...
Stats Grid
Display statistics with optional progress bars.
<div class="stats-grid">
<div class="stat-card">
<h4>Metric Name</h4>
<div class="stat-value">150+</div>
<!-- Optional progress bar -->
<div class="progress-bar">
<div class="progress-fill" style="width: 75%;"></div>
</div>
</div>
</div>
Renders as:
Metric Name
Skills Grid
Showcase skills with visual indicators.
<div class="skill-category">
<div class="skill-item">
<div class="skill-info">
<span class="skill-name"><i class="fab fa-python"></i> Python</span>
<span class="skill-level">Expert</span>
</div>
<div class="skill-bar">
<div class="skill-progress" style="width: 95%"></div>
</div>
</div>
</div>
Renders as:
Utility Classes
Section Titles
Consistent heading styles for page sections.
<h2 class="section-title">Section Heading</h2>
Renders as:
Section Heading
Fluid Typography
Enable responsive, viewport-based font sizing.
<div class="use-fluid-typography">
<h1>This heading scales with viewport</h1>
<p>Body text also scales appropriately...</p>
</div>
Renders as:
This heading scales with viewport
Body text also scales appropriately...
Accessibility Features
The design system automatically respects user preferences:
- Dark Mode:
prefers-color-scheme: dark - Reduced Motion:
prefers-reduced-motion: reduce
No additional classes needed — these work automatically.
Migration Guide
Step-by-Step Process
1. Remove Inline Styles
Before:
<div style="padding: 15px; background: #f8f9fa; border-radius: 10px;">
Content here
</div>
After:
<div class="card card--light">
Content here
</div>
2. Replace Custom Classes
Before:
<a class="custom-button" style="padding: 12px 24px; border-radius: 8px;">
Click me
</a>
After:
<a class="btn btn--primary btn--rounded">
Click me
</a>
3. Use Design Tokens
Before:
.custom-box {
padding: 20px;
margin-bottom: 30px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
After:
.custom-box {
padding: var(--space-lg);
margin-bottom: var(--space-xl);
border-radius: var(--radius-md);
box-shadow: var(--shadow-md);
}
4. Extract Reusable Patterns
If you find yourself repeating the same styles across multiple pages, add them to assets/css/components.css as a new component.
Working with Markdown Files
Disabling Markdown Linting
If you need to use HTML in your markdown files (like _pages/about.md), add this comment at the top:
<!-- markdownlint-disable MD033 -->
This prevents linting errors when mixing HTML with markdown.
Best Practices
Do’s ✓
- Use design tokens for all spacing, colors, and visual properties
- Prefer existing components over creating new ones
- Test in both light and dark modes
- Verify reduced-motion compatibility
- Keep component styles in
components.css
Don’ts ✗
- Don’t use inline styles in production
- Don’t create page-specific CSS for reusable patterns
- Don’t hardcode colors, spacing, or shadows
- Don’t modify component base classes (use modifiers instead)
- Don’t forget to test responsive behavior
Next Steps
- Audit existing pages — Identify inline styles and custom classes
- Plan migration — Prioritize high-traffic pages first
- Test thoroughly — Check dark mode, mobile, and accessibility
- Document patterns — Add new components to this guide if needed
For questions or contributions, refer to the project documentation or contact the maintainers.
Last updated: November 23, 2025