import fs from 'node:fs'; import path from 'node:path'; import { describe, expect, it } from 'vitest'; function readIndexCss() { return fs.readFileSync(path.resolve(process.cwd(), 'src/index.css'), 'utf8'); } function getCssBlock(source: string, selector: string) { const selectorIndex = source.indexOf(selector); expect(selectorIndex, `${selector} should exist in src/index.css`).toBeGreaterThanOrEqual(0); const openBraceIndex = source.indexOf('{', selectorIndex); expect(openBraceIndex, `${selector} should open a CSS block`).toBeGreaterThanOrEqual(0); let depth = 0; for (let index = openBraceIndex; index < source.length; index += 1) { const char = source[index]; if (char === '{') { depth += 1; } else if (char === '}') { depth -= 1; if (depth === 0) { return source.slice(openBraceIndex + 1, index); } } } throw new Error(`${selector} block is not closed`); } describe('index stylesheet unread dots', () => { it('uses warm brown tokens for draft unread markers instead of red literals', () => { const css = readIndexCss(); expect(css).toContain('--platform-unread-dot-fill: #8b5a3d;'); expect(css).toContain('--platform-unread-dot-glow: rgba(139, 90, 61, 0.34);'); expect(css).toContain('--platform-unread-dot-fill: #d6a27c;'); expect(css).toContain('--platform-unread-dot-glow: rgba(214, 162, 124, 0.24);'); for (const selector of [ '.creation-work-card__unread-dot', '.platform-nav-unread-dot', ]) { const block = getCssBlock(css, selector); expect(block).toContain('background: var(--platform-unread-dot-fill);'); expect(block).toContain('var(--platform-unread-dot-glow)'); expect(block).not.toContain('#b64a35'); expect(block).not.toContain('rgba(239, 68, 68'); } }); }); describe('index stylesheet draft mobile cards', () => { it('disables long-press text selection on the whole mobile draft tab', () => { const css = readIndexCss(); const mobileQueryIndex = css.indexOf('@media (max-width: 639px)'); expect(mobileQueryIndex).toBeGreaterThanOrEqual(0); const draftPanelSelector = '#platform-tab-panel-saves,\n #platform-tab-panel-saves *'; const draftPanelSelectorIndex = css.indexOf(draftPanelSelector, mobileQueryIndex); expect(draftPanelSelectorIndex).toBeGreaterThanOrEqual(0); const draftPanelBlock = getCssBlock(css, draftPanelSelector); expect(draftPanelBlock).toContain('-webkit-user-select: none;'); expect(draftPanelBlock).toContain('user-select: none;'); expect(draftPanelBlock).toContain('-webkit-touch-callout: none;'); const editableSelector = "#platform-tab-panel-saves :is(input, textarea, [contenteditable='true'])"; const editableSelectorIndex = css.indexOf(editableSelector, mobileQueryIndex); expect(editableSelectorIndex).toBeGreaterThanOrEqual(0); const editableBlock = getCssBlock(css, editableSelector); expect(editableBlock).toContain('-webkit-user-select: text;'); expect(editableBlock).toContain('user-select: text;'); expect(editableBlock).toContain('-webkit-touch-callout: default;'); }); }); describe('index stylesheet creation agent hero contrast', () => { it('keeps dark creation progress hero text light inside remap surfaces', () => { const css = readIndexCss(); expect(css).toContain('.platform-remap-surface'); expect(css).toContain('.creation-agent-hero'); const labelBlock = getCssBlock( css, ':where(.creation-agent-hero__summary, .creation-agent-hero__progress-label)', ); expect(labelBlock).toContain('rgba(255, 255, 255, 0.76) !important'); const valueBlock = getCssBlock(css, '.creation-agent-hero__progress-value'); expect(valueBlock).toContain('rgba(255, 255, 255, 0.92) !important'); const hintBlock = getCssBlock(css, '.creation-agent-hero__progress-hint'); expect(hintBlock).toContain('rgba(255, 255, 255, 0.72) !important'); }); });