Dark Mode Development Guide

Overview

This site uses a CSS variable-based dark mode system. All theme colors are defined in _sass/base/variables-css.sass and automatically switch when dark mode is toggled.

✅ Best Practices

1. Always Use CSS Variables

Never hardcode colors directly. Instead, use the predefined CSS variables:

/* ❌ DON'T DO THIS */
.my-component {
    background: #ffffff;
    color: #333333;
    border: 1px solid #ededed;
}

/* ✅ DO THIS INSTEAD */
.my-component {
    background: var(--background-color);
    color: var(--text-color);
    border: 1px solid var(--border-color);
}

2. Available CSS Variables

All variables are defined in _sass/base/variables-css.sass:

Main Colors

Muted/Secondary Text

Borders

Background Variations

Accent Colors

3. When You Need Dark Mode Overrides

Sometimes CSS variables aren’t enough. Use .dark-mode class selectors:

.my-component {
    background: var(--background-color);
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

/* Override specific properties for dark mode */
.dark-mode .my-component {
    box-shadow: 0 2px 4px rgba(0,0,0,0.4);
}

4. Testing Dark Mode

Always test new components in both light and dark modes:

  1. Add your component HTML/styles
  2. Toggle dark mode (button in navbar)
  3. Check:
    • Text is readable (good contrast)
    • Borders are visible
    • Backgrounds don’t blend together
    • Hover states work properly
    • Shadows/effects look good

5. Common Patterns

Buttons

.my-button {
    background: var(--signature-color);
    color: var(--background-color); /* Ensures contrast */
    border: none;
}

.my-button:hover {
    background: var(--signature-color-hover);
}

Cards/Boxes

.my-card {
    background: var(--background-elevated);
    border: 1px solid var(--border-color);
    color: var(--text-color);
}

.my-card:hover {
    border-color: var(--border-color-hover);
    background: var(--background-hover);
}

Muted/Secondary Text

.my-label {
    color: var(--text-muted);
}

.my-helper-text {
    color: var(--text-muted-light);
}
.my-link {
    color: var(--signature-color);
}

.my-link:hover {
    color: var(--signature-color-hover);
}

🚫 Anti-Patterns (Things to Avoid)

1. Hardcoded Colors

/* ❌ BAD - breaks in dark mode */
.component {
    background: #ffffff;
    color: #333333;
}

2. Using Undefined Variables

/* ❌ BAD - these don't exist */
.component {
    border: 1px solid var(--epsilon);
    color: var(--alpha);
}

3. Opacity Without Base Variable

/* ❌ BAD - opacity on hardcoded color won't adapt */
.component {
    background: rgba(255, 255, 255, 0.5);
}

/* ✅ BETTER - but may need dark mode override for opacity */
.component {
    background: var(--background-color);
    opacity: 0.9;
}

4. Forgetting Pseudo-elements

/* ❌ BAD - ::placeholder might not be readable */
input::placeholder {
    color: #999;
}

/* ✅ GOOD */
input::placeholder {
    color: var(--text-muted-light);
}

📋 Quick Checklist for New Components

When adding a new component, check these:

🔧 How to Add New Variables

If you need a new theme color:

  1. Add it to _sass/base/variables-css.sass under both :root and html.dark-mode
  2. Give it a semantic name (e.g., --warning-color, not --orange)
  3. Document it in this guide
  4. Use it consistently across components

📚 Files to Know

💡 Example: Converting Legacy Component

Before (hardcoded):

<style>
.my-widget {
    background: #fff;
    color: #333;
    border: 1px solid #ededed;
}

.my-widget .label {
    color: #666;
}
</style>

After (dark mode compatible):

<style>
.my-widget {
    background: var(--background-elevated);
    color: var(--text-color);
    border: 1px solid var(--border-color);
}

.my-widget .label {
    color: var(--text-muted);
}
</style>

That’s it! Following these patterns will prevent dark mode from breaking when you add new components.

rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora