8.18 Hand-Drawn style stops short of the app shell — rail/top-bar frame borders aren't roughened
Type: bug (style coverage / take-it-further) · Parent: Epic 8 (Launch readiness) · Discovered in: manual dogfooding (out-of-band)
Symptom
Under the Hand-Drawn / Indie style (data-style='hand-drawn-indie'), surface cards get the rough hand-inked edge, but the app shell frame stays straight/plain — the sidebar rail border and the top-bar bottom border are not hand-drawn. The style should extend to the shell chrome.
Root cause (verified against shipped code)
The rough-edge effect is utility-class driven, not data-surface-driven. app/globals.css (the [data-style='hand-drawn-indie'] block, ~line 1403+) applies the wobble via a pseudo-element overlay scoped to the FULL-BOX .border utility:
[data-style='hand-drawn-indie'] .border::after { ... border: 2px solid var(--el-border-strong); filter: url(#hd-rough); }
The shell frame uses directional border utilities, which .border does not match:
- Sidebar rail —
components/ui/Sidebar.tsxline ~271:border-r border-(--el-sidebar-border)(and it already emitsdata-surface="sidebar", but hand-drawn has NO[data-style='hand-drawn-indie'] [data-surface='sidebar']material rule — unlike glass/aurora/neumorphism). - Top bar —
app/(authed)/_components/TopNav.tsxline ~74:border-b border-(--el-border).
So neither shell border is reached by the rough rule (no .border class, no matching [data-surface] material rule) → the shell frame stays plain.
Fix direction
Extend the hand-drawn style to the shell frame. Preferred (mirrors the other material styles + scales): add [data-style='hand-drawn-indie'] [data-surface='sidebar'] / a tagged shell-header (data-surface on TopNav) rough-border rules, since the rail already emits data-surface="sidebar". Alternative: broaden the rough ::after rule to the directional .border-r / .border-b / .border-t utilities (more fragile — overlay positioning on a single edge). Keep the inks palette-derived (var(--el-border-strong)), no raw hue, per the surface-material contract (enforced by styleRegistry.test.ts).
Resolution
Open — filled by the closing-out subtask.