Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@
--card-bg: #ffffff;
--border-color: #dde4ea;
--input-border: #c6d2dc;
/* Hamburger glyph + 1px border on the menu surface: mvp.css paints every
button in --color-bg (the page background), which is invisible here, so
the toggle re-drives from this accent (7.8:1 on --surface-color). */
--menu-toggle-color: #1f5273;
/* vizdom WASM graph edges bake black stroke/fill attributes into the SVG;
palette-driven so the dark theme can swap them to a readable tint. */
--graph-line: #000000;
Expand Down Expand Up @@ -94,6 +98,8 @@ html:root {
--card-bg: #1a2330;
--border-color: #2c3a4d;
--input-border: #5b7396;
/* Hamburger glyph + 1px border on the dark menu surface (6.8:1). */
--menu-toggle-color: #6fb1d9;
--graph-line: #9fb0c0;
--error-color: #f0928c;
--success-color: #5bbd8b;
Expand Down Expand Up @@ -136,6 +142,8 @@ html:root {
--card-bg: #1a2330;
--border-color: #2c3a4d;
--input-border: #5b7396;
/* Hamburger glyph + 1px border on the dark menu surface (6.8:1). */
--menu-toggle-color: #6fb1d9;
--graph-line: #9fb0c0;
--error-color: #f0928c;
--success-color: #5bbd8b;
Expand Down Expand Up @@ -326,7 +334,11 @@ pre {
.menu-toggle {
display: none;
background: none;
border: 1px solid var(--input-border);
/* mvp.css paints every button in var(--color-bg) — the page background —
which is invisible on the menu surface; re-drive glyph and border from
the palette so the control stays perceivable in both themes. */
color: var(--menu-toggle-color);
border: 1px solid var(--menu-toggle-color);
border-radius: var(--radius);
font-size: 1.1rem;
padding: 0.25rem 0.6rem;
Expand Down
47 changes: 47 additions & 0 deletions tests/unit/theme-css.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,53 @@ describe('table filter accessibility', () => {
}
});

// Hamburger toggle (mobile view): mvp.css paints every button's text in
// var(--color-bg), and .menu-toggle only overrode background/border, so the
// ☰ glyph rendered in the page background color and the 1px --input-border
// edge fell below 3:1 on the menu surface. Both must be re-driven from a
// per-palette variable.
describe('menu toggle contrast', () => {
/**
* Concatenates every declaration block for a selector: the rules map keeps
* only the last occurrence (the responsive block) for repeated selectors,
* so assertions must run against all of them together.
*
* @param {string} selector - CSS selector to collect.
* @returns {string} Combined declarations.
*/
function combinedRule(selector) {
const bodies = [];
const ruleRe = /([^{}]+)\{([^{}]*)\}/g;
let match;
while ((match = ruleRe.exec(noComments)) !== null) {
if (match[1].trim() === selector) bodies.push(match[2]);
}
return bodies.join(';');
}

it('re-drives the glyph and border from the palette', () => {
const toggle = combinedRule('.menu-toggle');
expect(toggle).toMatch(/(?:^|;)\s*color:\s*var\(--menu-toggle-color\)/);
expect(toggle).toMatch(/border:\s*1px solid var\(--menu-toggle-color\)/);
});

for (const [name, palette] of [['light', lightPalette], ['dark', darkPalette]]) {
it(`declares a ${name} palette color for the toggle`, () => {
expect(palette.get('--menu-toggle-color')).toBeTruthy();
});

it(`the glyph keeps AA text contrast on the menu surface (${name}, SC 1.4.3)`, () => {
expect(contrastOf(palette, '--surface-color', '--menu-toggle-color'))
.toBeGreaterThanOrEqual(4.5);
});

it(`the border is perceivable on the menu surface (${name}, SC 1.4.11)`, () => {
expect(contrastOf(palette, '--surface-color', '--menu-toggle-color'))
.toBeGreaterThanOrEqual(3);
});
}
});

describe('report CSS selector boundaries', () => {
it('themes only graph edges and arrowheads, preserving red cycles and node glyphs', () => {
const fixture = document.createElement('div');
Expand Down
Loading