ui: unify aero chrome surfaces and shared hero across kanban/graph

This commit is contained in:
zenchantlive 2026-02-13 12:17:57 -08:00
parent c8d7f8eb0d
commit e6317594b6
18 changed files with 540 additions and 995 deletions

View file

@ -61,6 +61,8 @@ test('extracted graph section has viewport and legend', async () => {
assert.match(graphSection, /Read left to right/, 'legend should include plain directional hint');
assert.match(graphSection, /Left = blockers/, 'legend should include left/right dependency meaning');
assert.match(graphSection, /Right = work unblocked by this task/, 'legend should include downstream meaning');
assert.match(graphSection, /min-h-\[24rem\]/, 'graph container should enforce bounded minimum height');
assert.match(graphSection, /md:min-h-\[35rem\]/, 'graph container should scale minimum height on desktop');
});
test('graph node card supports tooltips and actionable glow', async () => {
@ -73,3 +75,8 @@ test('graph node card supports tooltips and actionable glow', async () => {
assert.match(nodeCard, /isDimmed/, 'should support dimming non-chain nodes');
assert.match(nodeCard, /Ready to work/, 'actionable tooltip text');
});
test('graph edges expose explicit relation labels', async () => {
const graphPage = await read('src/components/graph/dependency-graph-page.tsx');
assert.match(graphPage, /label:\s*'BLOCKS'/, 'edges should include plain-language relation labels');
});

View file

@ -0,0 +1,50 @@
import test from 'node:test';
import assert from 'node:assert/strict';
import fs from 'node:fs/promises';
import path from 'node:path';
const ROOT = process.cwd();
async function read(relativePath) {
return fs.readFile(path.join(ROOT, relativePath), 'utf8');
}
test('layout uses Noto Sans without JetBrains Mono dependency', async () => {
const layout = await read('src/app/layout.tsx');
assert.match(layout, /Noto_Sans/, 'should use Noto Sans font family');
assert.match(layout, /--font-ui/, 'should expose ui font css variable');
assert.doesNotMatch(layout, /JetBrains_Mono/, 'should not include JetBrains Mono');
assert.doesNotMatch(layout, /--font-mono/, 'should not expose mono font css variable from layout');
});
test('global stylesheet defines aero chrome foundation tokens and anti-banding layers', async () => {
const css = await read('src/app/globals.css');
assert.match(css, /--bg-base:/, 'should define matte base token');
assert.match(css, /--glass-base:/, 'should define glass surface token');
assert.match(css, /--edge-top:/, 'should define top chrome edge token');
assert.match(css, /--font-ui-stack:/, 'should define ui font stack token');
assert.match(css, /--font-mono-stack:/, 'should define mono font stack token');
assert.match(css, /font-family:\s*var\(--font-ui-stack\)/, 'body should consume ui font token');
assert.match(css, /body::before/, 'should define anti-banding grid layer');
assert.match(css, /body::after/, 'should define anti-banding noise layer');
assert.match(css, /--status-rdy-glow:/, 'should define ready glow token');
assert.match(css, /--status-blk-glow:/, 'should define blocked glow token');
assert.match(css, /--status-wip-glow:/, 'should define in-progress glow token');
assert.match(css, /--elevation-tight:/, 'should define tight elevation token');
assert.match(css, /--elevation-ambient:/, 'should define ambient elevation token');
assert.match(css, /\.glass-panel/, 'should define reusable glass panel primitive');
});
test('kanban and graph surfaces apply semantic typography classes', async () => {
const kanbanControls = await read('src/components/kanban/kanban-controls.tsx');
const kanbanCard = await read('src/components/kanban/kanban-card.tsx');
const graphCardGrid = await read('src/components/graph/task-card-grid.tsx');
const graphNodeCard = await read('src/components/graph/graph-node-card.tsx');
assert.match(kanbanControls, /ui-text/, 'kanban controls should use ui-text class');
assert.match(kanbanCard, /system-data/, 'kanban card should use system-data class for metadata');
assert.match(graphCardGrid, /ui-text/, 'graph task grid should use ui-text class for prose labels');
assert.match(graphNodeCard, /system-data/, 'graph node card should use system-data class for machine data');
});