Play+ Dark Theme: Automated, Accessible, and On-Brand
Introduction
In the Play+ ecosystem, a smooth, comfortable experience in all environments is a core design goal. Whether your users prefer a darker UI or are working late into the evening, Play+ adapts effortlessly. Our Dark Theme isn’t bolted on—it’s built in, and designed to maintain your brand’s distinctiveness and readability.
You don’t need to define a separate dark theme. Just define your light theme as usual, and Play+ takes care of the rest.
Why There’s No Separate Dark Theme
Traditionally, dark mode meant duplicating styles, increasing complexity and potential bugs. In Play+, that duplication is unnecessary.
With a single theme.map.json
, Play+ intelligently derives a dark variant of your theme. It respects your brand's tone and automatically adjusts colors, backgrounds, and contrast to suit dark contexts—without disrupting your design language.
How It Works
-
Define Your Theme Provide your core tokens in
theme.map.json
, including brand colors, text styles, and backgrounds. -
Derivation Engine Kicks In Play+ processes this theme and generates a full dark mode version. No extra configuration required.
-
System Preference Detection When a user’s system is set to dark mode, Play+ switches automatically using the
prefers-color-scheme: dark
media query.
What Gets Transformed?
Surfaces
Light backgrounds are softened to rich dark grays (e.g., --global-color-gray-900
), avoiding pure black. Secondary layers maintain visual depth.
Text
Text colors are lightened to remain readable on dark surfaces, and accessibility contrast is recalculated.
Brand Colors
Bright brand colors are adapted—desaturated or brightened if needed—to reduce harsh contrast. Related tokens like --color-text-on-brand-primary
adjust accordingly.
Disabling Automatic Detection
To ignore system preferences and apply themes manually, update your config:
{
"autoDetectSystemTheme": false
}
This disables automatic switching. You can then manage the theme explicitly via toggle or app logic.
Overriding the Defaults
Most themes work great with automatic derivation. But if you need to override a specific value, just add a dark-
prefixed token:
{
"color-brand-primary": "#007BFF",
"dark-color-brand-primary": "#5AACFF"
}
This gives you precise control when needed—without losing the benefits of derivation.
Manual Theme Toggle
You can give users a manual theme toggle in your UI using the data-theme
attribute on the <html>
element. This is especially useful if you've disabled automatic OS detection.
For React
Add this logic inside a common layout component, like App.tsx
or RootLayout.tsx
:
// src/App.tsx or src/components/ThemeToggle.tsx
function toggleTheme() {
const root = document.documentElement;
const isDark = root.getAttribute("data-theme") === "dark";
if (isDark) {
root.removeAttribute("data-theme");
} else {
root.setAttribute("data-theme", "dark");
}
}
// Example usage in a button:
<button onClick={toggleTheme}>Toggle Theme</button>
For Angular
Add this logic to a shared service or component, such as theme-toggle.component.ts
:
// src/app/theme-toggle/theme-toggle.component.ts
export class ThemeToggleComponent {
toggleTheme() {
const root = document.documentElement;
const isDark = root.getAttribute("data-theme") === "dark";
if (isDark) {
root.removeAttribute("data-theme");
} else {
root.setAttribute("data-theme", "dark");
}
}
}
Template:
<!-- theme-toggle.component.html -->
<button (click)="toggleTheme()">Toggle Theme</button>
File Summary
- React: Implement in
App.tsx
or a reusableThemeToggle.tsx
- Angular: Implement in a dedicated
theme-toggle.component.ts
with corresponding HTML
🛠 Tip: You can persist user preference using localStorage if desired.
You can give users a theme toggle in your UI using the data-theme
attribute on <html>
:
function toggleTheme() {
const root = document.documentElement;
const isDark = root.getAttribute("data-theme") === "dark";
isDark ? root.removeAttribute("data-theme") : root.setAttribute("data-theme", "dark");
}
This empowers users and complements OS-level preference detection.
✅ Developer Checklist
- Define a complete light theme in
theme.map.json
- Let Play+ derive the dark variant automatically
- Preview before overriding
- Use
dark-
overrides sparingly - Confirm contrast accessibility if overridden
- Offer a user toggle if needed
Conclusion
With Play+, dark mode is automatic, accessible, and brand-aware. There’s no need to manage two sets of styles or worry about visual quality. One well-defined theme is all it takes to deliver a polished experience—day or night.