WCAG 2.2: contrast fixes and guaranteed focus rings across all themes - #17
Open
jeremiahbeasley wants to merge 8 commits into
Open
WCAG 2.2: contrast fixes and guaranteed focus rings across all themes#17jeremiahbeasley wants to merge 8 commits into
jeremiahbeasley wants to merge 8 commits into
Conversation
Audited every theme with tools/contrast_audit.py against the 2.4.x panel (both the v2 token vocabulary and the legacy variables as mapped by the panel's theme bridge), including tokens a theme omits and therefore inherits at stock values: - 13 failing contrast pairs fixed (1.4.3 text 4.5:1, links-on-bg 4.5:1, focus 3:1): dark themes inheriting mid-gray secondary text / indigo accent on dark backgrounds, and white button text on light accents (flipped to dark text where the accent is mid-tone). - Every theme now carries a --focus-ring with >=3:1 contrast against its own backgrounds (1.4.11). - Removed 4 'outline: 0/none !important' focus suppressions (Ragnarock, HMM x2, VJ-Dark-v2) that killed keyboard focus visibility (2.4.7). All adjustments are hue-preserving lightness moves; the audit/fix tool is committed and re-runnable: python3 tools/contrast_audit.py [--fix]
…ity catalog - DO-Inpired-flat-blue / flat-black rewritten for the 2.4 design-token system (their old-UI selectors no longer exist in the panel, so they had zero visible effect): light content, themed dark sidebar via the new sidebar tokens, original palette and credit preserved. - Audit tool extended: sidebar-token pairs (sidebar-text/bg-sidebar, section header, hover) with proper var() fallback-chain modeling; failing sidebar pairs are fixed by declaring the sidebar token itself, never by mutating the theme accent. 8 further pairs fixed; audit is again clean across all themes. - tools/build_catalog.py generates catalog.json classifying every theme as native / partial (bridged palette) / legacy (no effect on 2.4) so the panel can label its theme dropdown honestly.
Every theme except the archived legacy-VJ-* series (superseded by the VJ-*-v2 themes) now fully restyles the 2.4 panel. Each port preserves the original palette, character, and attribution, extracted from the old-UI selector rules that no longer match anything: - Barracuda Dark: charcoal + near-black chrome, cornflower accent (dark-on-blue buttons — white on cornflower is ~3:1) - CF Inspired White: Cloudflare-style whites, pale-blue hover pills, navy ink; accent deepened in-hue to #3b6fd4 for 4.5:1 links - CyberSpace Dark: deep blue-dark with teal/sky accents; alpha panel overlays composited to solids, remote background image dropped - Gaussian Style: glassmorphism composited onto its indigo base, signature gold promoted to accent - HMM NEXT: pink-tinted light theme, Outfit/Be Vietnam Pro typography kept, deep-blue brand accent - Ragnarock: parchment content + navy sidebar, orange/gold/red accents tuned to pass 4.5:1 - blue-green / red-orange: accent reskins of the stock light UI with gradient identity kept as section/table bands - l-dark / true-dark: near-black ladders mapped one-to-one, signature green accents - dark-theme / soft-dark-theme: full-fidelity ports replacing the bridge approximation All 18 non-archived themes pass tools/contrast_audit.py (0 failing pairs); catalog.json now classifies them all as native.
The panel's dark-mode toggle flips any token a theme leaves unset between the stock light and dark palettes, which broke contrast catastrophically across modes (e.g. a light theme's #292929 text on the dark-mode #23252d code background: 1.05:1). - New --complete pass pins every mode-sensitive token from the theme's own palette (surfaces, text, borders, code/muted backgrounds, table head, accent hover, focus ring), so a theme is one coherent skin in both modes. - Audit now models both modes: unset tokens resolve from the stock light OR dark ([data-theme=dark]) palette; --dark audits the dark toggle. New pairs: text on bg-muted/bg-code, table head, text-on-accent vs accent-hover. - Archived legacy-* dirs excluded from audit scope (superseded by the *-v2 ports, no longer served by the panel catalog). All 18 served themes: 0 failing pairs in light AND dark mode.
… mechanical passes
Architecture change per review feedback: instead of pinning one look, each theme now carries an audited :root palette (default look) AND an explicit [data-theme=dark] palette the moon toggle renders — dark themes mirror themselves (stable no-op), light themes get designed dark companions tinted with their own hue identity. - Audit v2: resolves var() indirection (a var()-declared token was previously skipped, not checked — this hid Ragnarock's invisible navy-on-navy active menu item), strips !important, audits both modes, checks active-menu-item visibility (new sidebar-item-active-bg/text tokens in the panel). - tools/consolidate.py: folds accumulated correction blocks into one clean :root + one dark block per theme, derives designed dark companions, solves all pairs in-memory. - Hand fixes: VJ-Dark solid hovers + light hover text (translucent white-over-black hovers under mid-gray text), VJ-Green darker accent-hover so white button text passes on both states. All 18 served themes: [v2+dark] OK, 0 failing pairs, both modes.
…ification
- Every theme now has a genuinely LIGHT :root palette and a genuinely
DARK [data-theme=dark] palette (per review: the mode toggle must mean
something for every theme). Originally-dark themes keep their original
design as the dark palette and get a designed light companion — light
content surfaces tinted with the theme hue, the dark sidebar kept as
identity. Audit enforces polarity (content surfaces light in light
mode, dark in dark mode) plus all contrast pairs in BOTH modes.
- Renamed mode-implying themes (each theme now ships both modes):
dark-theme -> Graphite, soft-dark-theme -> Slate, l-dark-theme -> Onyx,
true-dark-cyberpanel -> Evergreen, CyberSpace-Dark-By-Interpryce ->
CyberSpace-By-Interpryce, VJ-Theme-Dark-v2 -> VJ-Theme-Mono-v2
('formerly named' notes kept in each file).
- tools/consolidate.py derives the companions and solves pairs in-memory;
audit v2 resolves var() indirection and !important (a var()-declared
token was previously skipped unchecked — this had hidden an invisible
navy-on-navy active menu item).
- Visually verified: all 18 themes screenshotted in both modes with
headless Chromium against the real panel CSS.
All 18 themes: 0 failing pairs, both modes, polarity clean.
Review feedback: keeping a theme's dark sidebar in light mode (as 'identity') contradicts true-mode semantics. All 11 light palettes that carried a dark sidebar now use a hue-tinted light sidebar (dark text, accent-colored section/active pills keep the identity). The audit's polarity check now covers bg-sidebar in both modes, so this can't regress. Verified with headless-Chromium screenshots of all 18 themes; 0 failing contrast pairs in both modes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Contrast-audited every theme against the CyberPanel 2.4.x UI and fixed the failures — including the ones caused by variables a theme doesn't define, where the panel's stock value lands on the theme's backgrounds (e.g. dark themes inheriting the stock mid-gray secondary text on near-black backgrounds).
Changes
--focus-ringwith ≥3:1 contrast against its own backgrounds (WCAG 1.4.11).outline: 0/none !importantfocus suppressions (Ragnarock, HMM-Theme ×2, VJ-Theme-Dark-v2) that made keyboard focus invisible (WCAG 2.4.7). Modern browsers only show outlines on:focus-visible, so mouse users see no change.tools/contrast_audit.py: the audit/fix tool, committed and re-runnable —python3 tools/contrast_audit.pyreports,--fixrepairs. It understands both the v2 token vocabulary and the legacy variable set, so future theme submissions can be checked in CI.Current state:
python3 tools/contrast_audit.py .→ 0 failing pairs, 0 outline suppressions across all 22 themes.