TT5 Dark Mode
TT5 Dark Mode is a Gutenberg-native plugin that Add dark / light mode switching to WordPress Twenty Twenty-Five — plus global focus fixes, shadow presets, and link hover customization.
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/satoshiwp/tt5-dark-mode/archive/refs/heads/main.zipAdd dark / light mode switching to WordPress Twenty Twenty-Five — plus global focus fixes, shadow presets, and link hover customization.
Overview
TT5 Dark Mode is a companion plugin for the WordPress Twenty Twenty-Five theme. It adds what the stock theme is missing:
| Problem | Solution |
|---|---|
| No way for visitors to switch between dark and light mode | Cookie-persisted toggle with zero FOUC |
Crude :focus outlines (no color, no offset, no :focus-visible) |
Comprehensive, customizable focus system |
Broken var:preset\|shadow\|natural reference in Noon variation |
Shadow presets injected via wp_theme_json_data_theme |
| Link hover only changes underline to dotted — no color or animation | Configurable hover color, underline style, and transition |
Everything is managed through a tabbed settings panel under Settings → TT5 Dark Mode.
Features
Dark / Light Mode
- Two-state toggle — Dark ↔ Light (default).
- Three-state cycle — Auto → Dark → Light, honoring
prefers-color-scheme. - Four official palettes — Evening, Twilight, Midnight, Sunrise.
- Smart inversion — Automatically provides a light-mode switch when the active style variation is already dark.
- Zero FOUC — Inline
<head>script reads the cookie before first paint. - Cookie persistence —
tt5dm_pref, SameSite=Lax, Secure flag on HTTPS.
Gutenberg Blocks
| Block | Description |
|---|---|
| Dark Mode Toggle | Styleable button (pill / icon-only / switch). Full block support: color, spacing, typography, border. |
| Mode-Aware Content | Container that shows its children only in dark or light mode. Pure CSS — no JS on the frontend. |
Block Patterns: Header with Toggle · Mode-Aware Hero Section · Mode-Aware Logo
Focus & Outline System
- Global
:focus-visiblewith color, width, style, and offset controls. - Element-level overrides for buttons, form inputs, and navigation.
- Separate outline color for dark mode.
- Three modes:
focus-visible(recommended) /focus/ disabled.
Box Shadow Presets
- Natural, Soft, and Hard presets — appear in the Gutenberg Shadow picker.
- Fixes the broken
var:preset|shadow|naturalreference. - Dark mode adjustment: Inherit / Darken / Glow.
Link & Hover
- Hover color, underline style, transition duration (0–1000 ms).
- Button hover opacity via
color-mix().
Custom CSS
- Inject arbitrary CSS with mode-specific selectors (
html.tt5-dark-mode,html.tt5-light-mode).
Installation
From ZIP
- Download the latest release
.zipfile. - In WordPress, go to Plugins → Add New → Upload Plugin and upload the zip.
- Activate the plugin.
Manual
cd wp-content/plugins/
git clone https://github.com/developer/tt5-dark-mode.git
Activate through the WordPress admin.
Configuration
- Settings → TT5 Dark Mode — Configure palette, focus, shadows, links, and custom CSS.
- Site Editor → Header template — Insert the Dark Mode Toggle block.
Architecture
index.php (main plugin file)
│
├── [FOUC inline script] ← <head> priority 1, reads cookie, sets html class
│
├── [Frontend CSS] ← wp_add_inline_style: palette + focus + links + custom
│
├── [Shadow presets] ← wp_theme_json_data_theme → Gutenberg Shadow picker
│
├── dark-mode-core.js ← Singleton state manager, loaded on-demand via viewScript
│ └── view.js ← Toggle block frontend interactivity
│
├── blocks/toggle/ ← Dark Mode Toggle Gutenberg block
│ ├── block.json
│ ├── edit.js ← Editor component (no build step, raw createElement)
│ ├── render.php ← Server-side render (<button> = block root)
│ ├── view.js ← Frontend JS (depends on core.js)
│ ├── style.css ← Shared styles
│ └── editor.css ← Editor-only styles
│
├── blocks/mode-content/ ← Mode-Aware Content Gutenberg block
│ ├── block.json
│ ├── edit.js
│ ├── render.php
│ ├── style.css ← Pure CSS visibility switching
│ └── editor.css
│
├── assets/css/admin.css ← Admin settings page styles
├── assets/js/admin.js ← Tab switching, color swatches, shadow preview
│
└── includes/blocks.php ← Block registration, patterns, editor data injection
For Developers
Filters
// Customize the dark palette programmatically
add_filter( 'tt5dm_dark_palette', function ( $palette, $selected_key ) {
$palette['colors']['accent-1'] = '#FF6600';
return $palette;
}, 10, 2 );
CSS Custom Properties
/* Global focus variables (set by plugin settings) */
:root {
--tt5c-focus-color: #007cba;
--tt5c-focus-width: 2px;
--tt5c-focus-style: solid;
--tt5c-focus-offset: 2px;
}
/* Toggle-specific focus variables (override per-block) */
:root {
--tt5dm-focus-color: currentColor;
--tt5dm-focus-width: 2px;
--tt5dm-focus-offset: 2px;
}
JavaScript API
// The global state object (available after core.js loads)
window.__tt5dm.getPref(); // 'auto' | 'dark' | 'light'
window.__tt5dm.isDark(); // boolean — current computed state
window.__tt5dm.cycle(); // Advance to next preference
window.__tt5dm.apply('dark'); // Set a specific preference
// Listen for changes
document.addEventListener('tt5dm:change', (e) => {
console.log(e.detail.pref); // 'auto' | 'dark' | 'light'
console.log(e.detail.isDark); // boolean
});
Mode-Specific CSS Selectors
html.tt5-dark-mode { /* dark mode active */ }
html.tt5-light-mode { /* light mode active */ }
/* Example: different background image per mode */
html.tt5-dark-mode .hero { background-image: url(hero-dark.jpg); }
html.tt5-light-mode .hero { background-image: url(hero-light.jpg); }
Requirements
| Requirement | Version |
|---|---|
| WordPress | 6.7+ |
| PHP | 7.4+ |
| Theme | Twenty Twenty-Five (or child theme) |
Technical Details
- No build step — Editor scripts use
wp.element.createElementdirectly. - No dependencies — No jQuery, no external frameworks.
- Under 8 KB total — All files combined.
- Inline CSS only — Zero extra HTTP requests for styles.
- Full i18n — All strings use the
tt5-dark-modetext domain. - WordPress Coding Standards — Follows WPCS conventions.
Contributing
Contributions are welcome! Please:
- Fork the repository.
- Create a feature branch:
git checkout -b feature/my-improvement - Commit your changes following the WordPress Coding Standards.
- Open a Pull Request with a clear description.
Coding Guidelines
- PHP: Follow WordPress PHP Coding Standards.
- JavaScript: Follow WordPress JavaScript Coding Standards.
- CSS: Follow WordPress CSS Coding Standards.
- No build tools — keep the plugin dependency-free.
License
This project is licensed under the GNU General Public License v2.0 or later.
TT5 Dark Mode — Making Twenty Twenty-Five comfortable at any hour.