Standardize on the .agents/ directory (shared with project skills): phases/, user_stories/, reports/, screenshots/, validate.sh, and phase-sessions/ + pipeline.log all move to .agents/ (git mv preserves history; runtime artifacts move alongside). Updates every reference in AGENTS.md, README.md, .gitignore, app docstrings, and test story headers. Historical KB content in data/ and the runtime pipeline.log transcript are left untouched.
4.2 KiB
4.2 KiB
Story: Dark Tech Theme
Phase: 08_story_dark_tech_theme.md · E2E: tests/e2e/test_dark_tech_theme.py
Narrative
As a user, I want Brain of Reese to look like a serious piece of my infrastructure — dark, technical, free of emojis, with a subtly animated background — so the app feels at home next to my dashboards and is comfortable to use at night, instead of a generic light-mode chat widget.
- Given the v1 UI (light palette, emoji avatars/brand/favicon, static background)
- When the theme phase is complete
- Then every page is dark with a tech aesthetic, no emoji appear anywhere in the UI chrome, a subtle pure-CSS animated background (drifting grid + breathing glows) is visible but never distracting, all layout metrics and behavior are unchanged, and WCAG 2.1 AA still holds on the new palette.
Acceptance criteria
- Dark palette (tokens in the phase file) applied to both pages
(
/,/sources.html); every text/background pair ≥4.5:1 — computed, not eyeballed. - Zero emoji in UI chrome — HTML templates, JS-rendered chrome, favicon, CSS — replaced by inline SVG glyphs. An integration test enforces this as a permanent regression guard.
- Subtly animated background: a fine drifting grid + two slow breathing
radial glows, pure CSS, zero JS,
pointer-events: none, never blocking or dimming content. prefers-reduced-motion: reduce→ background animations disabled (static grid + glows remain).- No-CDN invariant holds on both pages (all script/link refs local or
data:). - Layout metrics unchanged (PLAN §7.1): 72rem frame, 46rem centered chat column, full-width Sources table, mobile rules; behavior unchanged (chat state machine, chips, banners).
- WCAG 2.1 AA: landmarks, labels, skip link,
:focus-visible, live regions intact on the new palette. - LLM answer content is out of scope (the model may output anything; the rule binds UI chrome only).
- Whole pytest suite green,
app/coverage >90%, story E2E green in isolation.
UI Visualization & Structure
- Palette (all pairs computed, ≥4.5:1): page
#0a0e17, surface#121a2e, ink#e8ebf4(14.5:1 on surface), ink-soft#9aa4bd(6.9:1), line#26304a, brand#6d78f2with dark text#0a0e17(5.2:1 — white on brand is 3.7:1, forbidden for text), brand-soft#232b52+ brand-ink#a5b4fc(6.9:1), deflection#2b2110/#fbbf24(9.5:1) + border#f59e0b, error#2d1318/#fca5a5(9.1:1), ok#10241b/#6ee7a8(10.6:1). - Busy button keeps its
#a5b4fcbackground (the existing unit test asserts the token) with a dark arc (#0a0e17, 9.7:1). - Avatars: brain → inline SVG circuit-node glyph; user → minimal
silhouette SVG;
aria-hiddenretained. - Favicon / brand mark: tech SVG mark (hex + node), still an inline
data:URI (no CDN). - Tech details: mono wordmark + stat values, 1px
--lineborders, radii 10px/6px, a 2px brand→cyan gradient hairline under the sticky header. - Background:
body::beforegrid (44px cells, ~35% alpha 1px lines, radial mask fade, 60s seamless diagonal drift);body::aftertwo radial glows (indigo ~14% top-left, cyan ~10% bottom-right, 14s breathing). Bothposition: fixed; inset: 0; pointer-events: none.
Playwright Mapping Rule
Test Scenario → tests/e2e/test_dark_tech_theme.py (mock LLM, seeded KB):
test_dark_palette_and_contrast— body background isrgb(10, 14, 23); computed ink-on-surface and brand-button text/background pairs ≥4.5:1 (same contrast helper as Phase 07).test_no_emoji_in_chrome— neither page'sdocument.body.innerTextnor rawouterHTMLcontains any emoji code point.test_animated_background— computed style ofbody::beforehas a non-nonebackground-imageandanimation-name;body::afteranimates too.test_reduced_motion_honored— a browser context created withreduced_motion="reduce"→animation-name: noneon both layers.test_behavior_unchanged_smoke— on-topic question streams an answer + a source chip + the send button recovers (state machine intact under the new skin).test_all_assets_local— everyscript[src]/link[href]on both pages is relative ordata:(no CDN).