Apply the prototype new look across Let's Chat (phased) #539
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/lc-ui-port"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Applies the new look from the prototype (
~/projects/lets-chat-prototype) across the app. Phased; this PR grows as regions land. Each phase is its own commit so it stays reviewable.Phase 1 - global CSS foundation (this commit)
Accessibility + surface-separation fixes that the prototype's
contrast-check.mjs(WCAG text contrast AND adjacent-surface separation, all 7 palettes x 4 modes) surfaced. The app's existingcontrast-check.mjs(3 pairs x 28) still passes 84/84; these fixes cover the pairs it does not test.--content-subtledarkened in the five light palettes below the 3.0 floor (cobalt, ink-ice, arctic, deep-sea, royal-navy).--accent-surface-contentraised to blue-700 (reaction-pill / unread-banner text, was 4.24 vs AA 4.5).--borderstrengthened so cards separate from the near-white page.--sidebar-elevatedlightened in blue-harbor-dark / ink-ice / amethyst so the sidebar hover + active-count state is visible.#switcherborder-right) so the rail reads as distinct chrome even when both are near-black (identical#000in high-contrast, where the boundary vanished).Rationale and per-token detail are in the prototype's
DEVIATIONS.md.Remaining phases (landing on this branch)
#LC-569
Port complete - all phases landed and verified
2. UI scaling (
c8f075f9) -theme_scale(compact/default/large/xl) plumbed exactly liketheme_palette: migration 0038, the column in every users SELECT + row projection, setter, validation, anlc-scalecookie synced by the locale middleware (follows the account across devices), a no-flashdata-scalestamp in the base.html bootstrap,POST /settings/scale, and the appearance-form control. Applied as a root rem scale so type and spacing scale together. Distinct from the device-locallc-textsize, which only scales the message body.3. Chat surface (
3211d38f) - reconciled to the prototype. Active room row is now a solid--accentfill with--accent-contenttext (replacing the raised tint + accent text + left bar), with the unread pill inverting on it so it stays legible. Message rows become inset rounded cards (12px padding, 10px radius) with the 20px gutter moved onto the scroll container; avatars 24px to 36px with the content indent and follow-up gutter widened to match; bold author names. The day divider drops its bordered uppercase pill for plain text between hairlines, and the unread separator switches from danger red to the accent "new messages" divider. Reactions sit on the elevated surface at rest. Composer and hover-action button sizes take the prototype's values.4. Room info hero (
3bc4a417) - accent-surface hash badge, name, topic; keeps the existing tab shell.5. Extrapolation - verified no-op. Outside the chat surface no template carries a hardcoded palette color or raw hex (the only hex matches are emoji entities), so the corrected tokens from phase 1 already carry the new look into admin, auth, onboarding, and the modals with no further change.
How it was verified
The room view needs a real Bunyip login, which the mock-SSO overlay cannot do, so
03740847mirrors the reconciled chat components into/dev/theme-gallery(which exists precisely to render every shared component across all palettes x modes). Booted against the mock-SSO stack and screenshotted: the solid-accent active row with inverted count pill, the plain day divider, the 36px message row with reaction pills and hover bar, the accent "new messages" divider, and the composer all render correctly in all 28 states (light, dark, hc-light, hc-dark all checked). Migration 0038 applied cleanly on boot.cargo checkand the i18n parity test pass; the existing contrast-check still reports 84/84.Deliberately not ported
The four LC-77 render fixtures assert the exact message markup, so reconciling the row to the prototype (36px avatar, 12px padding with a 10px radius, 48px content indent, bold author) diverged them. Regenerated with FIXTURE_WRITE=1; the diff is exactly that geometry change and nothing else. Also forwards FIXTURE_WRITE through the dockerized ./dev/cargo wrapper. The wrapper only passed a fixed set of env vars, so the regeneration path the fixture test itself prints ("Run with FIXTURE_WRITE=1 to regenerate") could not actually be used through it. Extending the wrapper rather than reaching around it with a raw docker run. #LC-569Merged
main(LC-558 / LC-574 overlap) + fixed a broken gateRebased onto the newer
main, which had landed overlapping mockup work: LC-558 (timeline polish) and LC-574 (composer one-row restructure). Both touch the same files as this branch.Conflicts resolved in favour of
main. Where this branch and the landed, reviewed work disagreed, I keptmain's version rather than silently reverting an approved PR inside a merge. That leaves three deliberate divergences from the prototype, flagged for a call:main)font-bold(700)font-semibold(600) - LC-558 Option AWorth noting on the day divider: LC-558's stated reason for keeping the pill was WCAG AA on the label. The plain-text form now clears AA anyway, because this branch's first commit darkened
--content-subtlein the light palettes. So that constraint no longer forces the pill - it is purely a look call now.Everything non-conflicting from this branch survived the merge and is verified present: 36px avatars + indent, solid-accent active row, neutral count pill, rail seam, accent unread divider, scrollbars, UI scaling, the token fixes.
A real gate that was failing
The full test suite had never been run on this branch - only
cargo checkand the i18n test. It was red: four golden-file fixtures inlc77_webhook_render_fixture.rsassert the rendered message markup, and the 24px-to-36px avatar change invalidated them. Regenerated (diff is exactly the intended geometry, nothing else).Regenerating them required extending
dev/cargoto forwardFIXTURE_WRITE: the wrapper only passes a fixed allowlist of env vars, so nobody could regenerate these fixtures through it at all. One line, and the documentedFIXTURE_WRITE=1path in the test now actually works.Gates now
just check(fmt + clippy): cleancontrast-check.mjs: 84/84/dev/theme-gallerySay the word on any of the three divergences and I will align them in a follow-up commit.