Default Admin mode and token guide
This page explains the report sections that describe theme contrast mode, forced-colors mode, APCA polarity, and the accent token derivation logic used by Default Admin.
Important: Theme "Increase Contrast Mode" vs Forced-Colors Mode
This guide distinguishes the theme's built-in "Increase contrast mode" setting from CSS @media (forced-colors: active) mode so the report is easier to interpret.
- Theme "Increase contrast mode": Toggles alternative CSS token values inside Default Admin, such as
--gin-color-text,--gin-color-focus, and related semantic tokens. - CSS forced-colors mode: Activated by Windows High Contrast, Ubuntu contrast themes, or browser emulation. The browser replaces author colors with system colors like
Canvas,CanvasText, andHighlight.
Default Admin already includes @media (forced-colors: active) rules for borders, buttons, links, and other components. Test it separately from the theme toggle because the browser, not the theme, controls the final colors in forced-colors mode.
Use Chrome DevTools forced-colors emulation or a real Windows High Contrast environment to verify those system-color overrides.
APCA Polarity Matters
WCAG 2.x contrast ratios are symmetric: swapping foreground and background produces the same numeric ratio. APCA is directional: dark text on a light background and light text on a dark background can produce different signed Lc values for the same two colors.
That means APCA should always be interpreted together with the intended foreground and background roles for a token pair. In this report, APCA threshold checks currently use absolute Lc magnitude, so the summary numbers do not fully expose polarity on their own.
ACCESSIBILITY.md Best Practices Reference
This report aligns with COLOR_CONTRAST_ACCESSIBILITY_BEST_PRACTICES.html from the ACCESSIBILITY.md project. Below are the relevant patterns applied to Default Admin:
WCAG 2.2 Level AA Compliance (Our Baseline)
- WCAG 1.4.3 (Text Contrast): 4.5:1 for normal text, 3:1 for large text — all buttons, labels, and body text meet this threshold
- WCAG 1.4.11 (Non-text Contrast): 3:1 for UI component borders (form inputs, checkboxes, focus rings)
- WCAG 2.4.13 (Focus Appearance): Focus indicators have ≥3:1 contrast against adjacent colors and sufficient visual size
- WCAG 1.4.1 (Use of Color): Color is never the sole means of conveying information; error states include text and icons
CSS Custom Properties Pattern (Best Practice from ACCESSIBILITY.md)
Default Admin follows the semantic token pattern recommended in section 8 of the guide:
/* Design token layer (raw colors) */
--accent-base: #015efe;
/* Semantic layer (component usage) */
--gin-color-primary: var(--accent-color-500);
--button-bg-color--primary: var(--accent-color-500);
--button-fg-color--primary: var(--gin-color-button-text);
/* Components reference semantic tokens, not raw colors */
.button--primary {
background-color: var(--button-bg-color--primary);
color: var(--button-fg-color--primary);
}
Benefit: Changes to token values cascade across all components automatically, and contrast can be validated at the token layer.
Light/Dark Mode Pattern
Section 8 of ACCESSIBILITY.md recommends using @media (prefers-color-scheme: dark) to define separate tokens for each mode.
Default Admin implements this via:
- Direct CSS:
@media (prefers-color-scheme: dark)rules incss/base/variables.pcss.css - Color-mix() derivation: Dark-mode accent ramps recomputed from transformed base (LCH lightness scaling)
- Theme toggle: "Increase contrast mode" class on
<body>overrides token values independently of OS preference
Forced-Colors Mode Support
Section 9 of ACCESSIBILITY.md covers Windows High Contrast and @media (forced-colors: active) rules.
Default Admin includes forced-colors support in multiple components:
- Toolbar:
@media (forced-colors: active) { border-color: ButtonBorder; } - Tables: Borders and cells use
ButtonBorder,CanvasTextsystem colors - Forms: Inputs use
ButtonFaceandButtonTextfor visibility - Focus rings: CSS
outlineproperty (preserved in forced-colors) rather than box-shadow
APCA — Emerging Next-Generation Standard
Section 10 of ACCESSIBILITY.md covers APCA (Advanced Perceptual Contrast Algorithm), which improves on WCAG 2.x for saturated colors and perceptual accuracy.
- Current requirement: WCAG 2.2 AA (4.5:1 for text)
- Emerging guidance: APCA ≥60 Lc for body text (more stringent for small/thin fonts)
- This report: Calculates both WCAG and APCA scores to show forward compatibility
- Future work: When WCAG 3.0 with APCA is finalized, update tokens to meet both standards
Testing and Validation (from Section 12)
This report and theme follow the validation checklist:
- ✓ Automated checks: Contrast ratio calculation via WCAG luminance formula + APCA
- ✓ Manual checks: All states tested (default, hover, focus, active) in light and dark modes
- ✓ Forced-colors testing: Rules defined for @media (forced-colors: active); recommend browser DevTools emulation
- ✓ Color independence: Error states, required fields, and status indicators use text + icons + color
- ⚠ Real device testing: Windows High Contrast mode and screen reader testing recommended before release
Related ACCESSIBILITY.md Guides
- Light/Dark Mode Accessibility Best Practices — Implementing dual-mode palettes and @media (prefers-color-scheme)
- Keyboard Accessibility Best Practices — Focus management and visible focus indicators (WCAG 2.4.7 and 2.4.13)
- Forms Accessibility Best Practices — Error messages, label contrast, and focus styling
- User Personalization Accessibility Best Practices — Respecting prefers-color-scheme, prefers-contrast, and other user settings
Token Derivation Mathematics
This section explains how accent tokens are computed, especially the difference between light mode and dark mode derivation.
Overview
The Default Admin accent system derives an entire ramp of color values (030, 100, 200, ..., 900) from a single --accent-base hex value.
The ramp uses CSS color-mix(in lch, ...) to blend colors in the LCH color space (perceptually uniform lightness, chroma, hue).
Light mode and dark mode recompute the ramp from different base values, resulting in different hex values for the same token across modes.
Light Mode Derivation
In light mode, the accent system blends toward white:
/* Source: core/themes/default_admin/css/base/accents.css (light mode) */
--accent-base: (user preset, e.g., #015efe for blue)
--accent-mix-base: color-mix(in lch, --accent-base, #ffffff 97%)
// Result: Very light tint of the accent (98% white blended)
--accent-color-030: color-mix(in lch, --accent-mix-base 85%, --accent-color-base 15%)
--accent-color-100: color-mix(in lch, --accent-mix-base 70%, --accent-color-base 30%)
--accent-color-200: color-mix(in lch, --accent-mix-base 55%, --accent-color-base 45%)
--accent-color-500: --accent-color-base // Mid-tone, used for primary buttons
--accent-color-900: --accent-color-base // Darkest, used for hover/active states
--gin-color-primary: --accent-color-500 // In light mode, = --accent-base
Dark Mode Derivation (Different Math!)
Dark mode recomputes the accent system by first transforming the base accent using LCH lightness adjustment, then deriving a new ramp:
/* Source: core/themes/default_admin/css/base/accents.css (dark mode) */
/* Transform accent-base via LCH lightness scaling and black blend */
--accent-color-base: color-mix(
in lch,
lch(from --accent-base calc(l * 20) c h), // Scale lightness to ~20% of original
#000000 12% // Blend 12% black
)
/* Then derive ramp from the dark-transformed base (same mix percentages as light) */
--accent-mix-base: color-mix(in lch, --accent-base, #000000 80%)
// Result: Very dark tint of the accent
--accent-color-030: color-mix(in lch, --accent-mix-base 85%, --accent-color-base 15%)
--accent-color-500: --accent-color-base // Recomputed dark-mode base
--accent-color-900: color-mix(in lch, --accent-mix-base 15%, --accent-color-base 85%)
--gin-color-primary: --accent-color-500 // In dark mode, ≠ --accent-base (different hex)
Example: Blue Accent (#015efe)
To illustrate, here's what the blue accent derives to in each mode:
Light mode:
--accent-base: #015efe (original blue)
--accent-mix-base: ≈ #e8f3ff (very pale blue, 98% white)
--gin-color-primary (--accent-color-500): #015efe (same as base)
Dark mode:
--accent-color-base: ≈ #0a2c6b (darkened and desaturated via LCH transform)
--accent-mix-base: ≈ #001a3d (very dark blue, 80% black)
--gin-color-primary (--accent-color-500): ≈ #0a2c6b (different hex than light mode!)
Result:
Light: White text (#fff) on #015efe needs 4.52:1 contrast ✓
Dark: Dark text (#1a1a1a) on #0a2c6b needs 5.74:1 contrast (light text fallback ✓)
Why This Matters for Accessibility
- Non-symmetric light/dark: The same token name maps to different hex values in light vs dark modes, requiring separate contrast validation for each.
- Ramp independence: High-contrast mode can override
--accent-baseto a higher-contrast value, automatically regenerating the entire ramp. - LCH blending: Using
color-mix(in lch)instead of RGB blending ensures perceptually uniform ramps, but adds complexity to manual color prediction. - Contrast-Color opportunity: Future CSS
contrast-color()function could automate the dark-mode transform and ensure optimal contrast automatically.