Theming (Light/Dark Mode)
Relevant source files
The following files were used as context for generating this wiki page:The Norm Macdonald Archive redesign implements a dynamic theming system that allows users to switch between a light and a dark mode. This system is designed to provide a clean, modern aesthetic, with a default dark theme inspired by "Norm Macdonald Live". It prioritizes user experience by respecting system-level color scheme preferences and persisting the user's choice across sessions.
The implementation relies on a combination of CSS Custom Properties for defining theme colors and JavaScript for managing the theme state. This approach allows for efficient theme switching without page reloads and provides a consistent look and feel across all pages of the application.
Sources: README.md, redesign/styles.css:1-10, redesign/index.html:230-265
CSS Architecture
The theming architecture is built entirely within styles.css using CSS Custom Properties (variables). This allows for a centralized definition of color palettes that can be easily swapped.
Sources: redesign/styles.css
Color Variable Definitions
Two primary sets of color variables are defined: a dark theme palette (the default) and a light theme palette. The dark theme variables are defined directly within the :root selector.
Sources: redesign/styles.css:10-38
A separate set of generic variables (e.g., --bg-primary, --text-1) are also defined in :root, defaulting to the dark theme values. This abstraction allows components to use theme-agnostic variables.
/* redesign/styles.css:41-54 */
/* Default to dark */
--bg-primary: var(--studio-dark);
--bg-secondary: var(--studio-surface);
--bg-tertiary: var(--studio-elevated);
--bg-hover: var(--studio-hover);
--border-color: var(--studio-border);
--text-1: var(--text-primary);
--text-2: var(--text-secondary);
--text-3: var(--text-tertiary);
--accent: var(--accent-blue);
--accent-hover: var(--accent-blue-hover);
--accent-dim: var(--accent-blue-dim);
Sources: redesign/styles.css:41-54
Theme Switching
The theme is switched by applying a data-theme attribute to the root <html> element. The CSS specifically targets [data-theme="light"] to override the default dark theme variables with the light theme values.
/* redesign/styles.css:101-112 */
/* Light Theme */
:root[data-theme="light"] {
--bg-primary: var(--light-bg);
--bg-secondary: var(--light-surface);
--bg-tertiary: var(--light-elevated);
--bg-hover: var(--light-surface);
--border-color: var(--light-border);
--text-1: var(--light-text-primary);
--text-2: var(--light-text-secondary);
--text-3: var(--light-text-tertiary);
/* ... */
}
Sources: redesign/styles.css:101-112
The following table summarizes the key color variables and their values for each theme.
| Variable Name | Dark Theme Value | Light Theme Value | Description |
|---|---|---|---|
--bg-primary | #0D1117 | #FFFFFF | Main page background color. |
--bg-secondary | #161B22 | #F6F8FA | Secondary background for cards, footers, etc. |
--text-1 | #E6EDF3 | #1F2328 | Primary text color. |
--text-2 | #7D8590 | #656D76 | Secondary text color for subtitles, meta info. |
--border-color | #30363D | #D0D7DE | Standard border color. |
--accent | #3882F6 | #3882F6 | Accent color for links, buttons, and highlights. |
Sources: redesign/styles.css:10-54, 101-112
System Preference Detection
The system automatically applies the light theme if the user's operating system is set to a light color scheme and no explicit theme has been set by the user. This is achieved using the prefers-color-scheme media query. The :not([data-theme="dark"]) selector ensures that a user's manual selection of the dark theme is respected, even if their system preference is light.
/* redesign/styles.css:118-128 */
@media (prefers-color-scheme: light) {
:root:not([data-theme="dark"]) {
--bg-primary: var(--light-bg);
--bg-secondary: var(--light-surface);
--bg-tertiary: var(--light-elevated);
--bg-hover: var(--light-surface);
--border-color: var(--light-border);
--text-1: var(--light-text-primary);
--text-2: var(--light-text-secondary);
--text-3: var(--light-text-tertiary);
}
}
Sources: redesign/styles.css:118-128
JavaScript Logic
The theme state is managed by a JavaScript function named initTheme(), which is included on every page (e.g., inline in index.html or as part of transcripts.js). This function handles theme initialization, user-triggered toggling, and persistence.
Sources: redesign/index.html:230-265, redesign/transcripts.js:5-30, redesign/videos.js:15-40
Theme Initialization Flow
On page load, the initTheme function determines which theme to apply based on a clear priority order.
This diagram illustrates the logic flow for setting the initial theme on page load.
Sources: redesign/about.html:203-213
- Check
localStorage: It first checks if a theme preference ('light'or'dark') has been saved inlocalStorage. If found, it applies this theme. - Check System Preference: If no preference is stored, it checks the user's system preference via
window.matchMedia('(prefers-color-scheme: dark)').matches. - Apply Theme: It sets the
data-themeattribute on the<html>element (document.documentElement) to either the stored value or the detected system preference.
Theme Toggle Component
A theme toggle button is present on all pages, allowing the user to manually switch between light and dark modes.
HTML Structure
The button contains two SVG icons, one for the sun (light mode) and one for the moon (dark mode). CSS rules control which icon is visible based on the current data-theme.
<!-- redesign/index.html:16-29 -->
<button id="theme-toggle" class="theme-toggle" aria-label="Toggle theme between dark and light mode">
<svg class="sun-icon" ...>
<!-- sun icon paths -->
</svg>
<svg class="moon-icon" ...>
<!-- moon icon paths -->
</svg>
</button>
Sources: redesign/index.html:16-29, redesign/about.html:15-28
CSS Icon Visibility
The visibility of the sun and moon icons is controlled by the data-theme attribute on the :root element.
/* redesign/styles.css:251-257 */
:root[data-theme="dark"] .theme-toggle .sun-icon {
display: none;
}
:root[data-theme="light"] .theme-toggle .moon-icon {
display: none;
}
Sources: redesign/styles.css:251-257
User Interaction Flow
When a user clicks the theme toggle button, an event listener fires to update the theme.
This sequence diagram shows the events that occur when a user clicks the theme toggle button.
Sources: redesign/index.html:240-245
The click event handler performs two main actions:
- It toggles the
data-themeattribute on the<html>element between'light'and'dark'. - It saves the newly selected theme to
localStorageunder the key'theme', ensuring the choice persists for subsequent visits.
Conclusion
The theming system in the Norm Macdonald Archive redesign is a robust and user-centric feature. By leveraging CSS Custom Properties, it provides a clean and maintainable way to manage color schemes. The accompanying JavaScript logic intelligently detects user preferences, persists choices, and provides a seamless manual override, resulting in a polished and modern user experience.
Sources: README.md, redesign/styles.css, redesign/index.html