feat(ui): dark design-token foundation and app-shell chrome (extracted from #1412) - #1540
Merged
Conversation
Extracted from #1412 (Epic 2, story 2.1) so the visual foundation can land without the Review Console's Feed, Manager Lens or dashboard restructure. Re-applied onto current main rather than cherry-picked: that branch forked before input.css grew the floating-surface layer. - Semantic dark-only token layer in `@theme` (ground / surface ramp / text ramp / violet brand / teal action / four status colors / overlay shadow), so `bg-ground`, `text-text-muted`, `border-border` etc. generate. - Geist Sans + Geist Mono self-hosted as variable woff2; drops the two font CDN links (Outfit on every page, JetBrains Mono on chat detail) and points the hardcoded families at `--font-sans` / `--font-mono`. - Global `:focus-visible` teal ring and a blanket reduced-motion switch. - Shell reflows at 768px instead of 640px: nav sheet + four-tab bottom bar below `md`, icon rail from `md` to `lg`, full sidebar from `lg`. The `--sheet-inset-*` switch and its guards move to `md` with it, since their bound is "the sidebar is on screen". - `<main>` pads by `--app-tabbar-height` below `md` so the chat surface's sticky dock stays clear of the fixed bar. - Repoints the page-colored masks (chat dock and its fade, login divider, homepage nav) at `--color-ground`; they were literal #030712.
Cleanup pass over the design-foundation commit. No intended visual change except where noted; the three tiers were re-measured in a browser. - `--app-sidebar-width` becomes the rail's 4rem, widened to 15rem by a `:root` switch at `lg:`. The rail no longer restates the width to beat the utility on the root, and `--sheet-inset-start` now tracks the real sidebar in both tiers — it was insetting bottom sheets by 16.5rem against a 4rem rail between 768 and 1023px. - The rail's bounds read `theme(--breakpoint-md/-lg)` instead of the px they compile to, so they cannot drift from the `md:`/`lg:` utilities beside them. - Six sidebar hooks that all meant "hide me in the rail" become one, `sidebar__collapsible`. - Nav-item appearance moves into a `.sidebar__nav-item` component class, and the active item's 3px rail is drawn by `.sidebar__nav-item--active::before` — replacing 13 copies of a 12-utility chain and 13 hidden indicator spans. - The four bottom tabs come from `NAV_TABS` in `accounts.context_processors`, beside the section keys they highlight against, rendered by one loop over a `.tabbar__link` class. - `main:has(.chat-shell)` keeps only its `md:` reset: below `md`, `<main>`'s own `pb-(--app-tabbar-height)` was already the clearance, so the unconditional rule restated it. - Drops the now-dead `--surface-rise-duration` reduced-motion switch (the blanket `!important` kill switch subsumes it) and an inert `scroll-behavior` declaration; `--color-focus` reads `accent-bright` instead of repeating its hex. - Visual: the floating panels (composer sheet + autocomplete, pickers, filter menu, the three drawers, the repo combobox) painted a literal `#0d1117`, which the new ground now *is* — they move to `surface-2` to stay lifted. `test_surface_contrast` follows `--color-*` tokens so it still measures the colour that ships; AA margin holds at 5.43:1.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extracts the design foundation and app-shell chrome from #1412 (Epic 2, story 2.1) so the visual layer can land on its own, ahead of the Review Console's Feed, Manager Lens and dashboard restructure.
Re-applied onto current
mainrather than cherry-picked: #1412 forked at871ca767, beforeinput.cssgrew the floating-surface layer, soinput.css,_sidebar.html,base_app.htmlandDESIGN.mdwere 3-way merged by hand.What's in
@theme— ground + surface ramp, text ramp, violet brand (never a CTA), teal action, four status colors, and the single sanctionedshadow-overlay. Utilities generate automatically (bg-ground,text-text-muted,border-border, …).font-display: swap). Drops both font CDN links — Outfit on every page, JetBrains Mono on chat detail — and points the hardcoded families at--font-sans/--font-mono.:focus-visibleteal ring and a blanketprefers-reduced-motionswitch.md, icon rail frommdtolg, full sidebar fromlg.base.html,base_app.html,_sidebar.html(BEM hooks for the rail tier) andnav_tags.ACTIVE_CLASSES. New{% block topbar_start %}slot in the top bar.DESIGN.mdupdated to match, including a new §App Shell.What's deliberately not in
Still on
feat/epic-2-review-console: theRUN_FEEDemitter, Feed templates + SSE, notifications migration0007, the Manager Lens, the dashboard console body, and theviews.py/ context-processor changes.Three couplings that needed handling here
These did not exist at #1412's base and are the substance of the review:
--sheet-inset-*with it.mainkeys that switch to--breakpoint-smbecause "the sidebar is on screen" wassm:. With the sidebar appearing atmd:, the switch and the two guards intest_picker_popovers.pyfollow — otherwise bottom sheets inset for a sidebar that isn't there between 640 and 767px.main:has(.chat-shell)zeroed<main>'s bottom padding so the sticky dock could reach the viewport bottom. Belowmdit now pads by--app-tabbar-heightinstead: a stickybottom: 0sticks to the padding box, which is what lifts the dock clear of the bar. A new guard pins the bar's height and that padding to the same token.#030712 → #0d1117left page-colored masks behind. The chat dock and its fade gradient, the login "or" divider and the homepage sticky nav were literal#030712; they now read--color-ground.Verification
make test→ 4929 passed, 163 skipped.make lintclean (ruff check + format, djade);django-admin compilemessagescompilespt.@font-facepaths resolve,--sheet-inset-*lands at48rem.surface-1, tab bar hidden,<main>padding-bottom: 40px.aria-current="page"on the active tab,padding-bottom: 56px, no horizontal overflow, burger 44×44.New tests
tests/unit_tests/accounts/test_app_shell.py— four static guards plus a render check. Both discovered-set guards were mutation-checked (drop asidebar__label, or restate the tab bar height as a literal, and they fail):sidebar__*hook the template carries is handled by the rail tier, and vice versa;sidebar__label, so it cannot overflow the 4rem rail;<main>'s chat padding both read--app-tabbar-height;Note
daiv/static/css/styles.cssis gitignored, somake tailwind-buildis required before deploying this branch.Follow-up cleanup (second commit)
A quality pass over the above — reuse / simplification / efficiency / altitude. No intended visual change except the last bullet; the three tiers were re-measured in a browser.
--app-sidebar-widthis now the tier, 4rem widened to 15rem by a:rootswitch atlg:. This fixes a real defect in the first commit: the rail restatedwidth: 4remwhile the token stayed 15rem, so--sheet-inset-startinsetting off the token pushed every bottom sheet ~11rem too far between 768 and 1023px. One token, both tiers, and the rail block no longer carries geometry (guarded).theme(--breakpoint-md/-lg)instead of the px they compile to — the same rule the sheet switch follows, so they can't drift from themd:/lg:utilities beside them.sidebar__collapsible..sidebar__nav-item, and the active item's 3px rail into.sidebar__nav-item--active::before— replacing 13 copies of a 12-utility chain and 13 hidden indicator spans, plus a deadgroupmarker on each.NAV_TABSinaccounts.context_processors, beside the section keys they highlight against, rendered by one loop over a.tabbar__linkclass (was 4× copy-paste with the section key spelled twice per tab).main:has(.chat-shell)keeps only itsmd:reset — belowmd,<main>'s ownpb-(--app-tabbar-height)was already the clearance, so the unconditional rule just restated it.--surface-rise-durationreduced-motion switch (the blanket!importantkill switch subsumes it), an inertscroll-behaviordeclaration, and--color-focus's duplicate hex (now readsaccent-bright).#0d1117, which the new ground is, leaving them flush with the page. They move tosurface-2to stay lifted.test_surface_contrastnow resolves--color-*tokens so it keeps measuring the colour that ships; the tightest real contrast is 5.43:1.Tests: 4928 passed, 163 skipped;
make lintclean;lint-typingat the pre-existing 457-diagnostic baseline with none in the touched files.