Skip to content

feat(ui): dark design-token foundation and app-shell chrome (extracted from #1412) - #1540

Merged
srtab merged 2 commits into
mainfrom
claude/extract-pr-1412-design-7a62a4
Aug 28, 2026
Merged

feat(ui): dark design-token foundation and app-shell chrome (extracted from #1412)#1540
srtab merged 2 commits into
mainfrom
claude/extract-pr-1412-design-7a62a4

Conversation

@srtab

@srtab srtab commented Aug 28, 2026

Copy link
Copy Markdown
Owner

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 main rather than cherry-picked: #1412 forked at 871ca767, before input.css grew the floating-surface layer, so input.css, _sidebar.html, base_app.html and DESIGN.md were 3-way merged by hand.

What's in

  • Semantic dark-only token layer in @theme — ground + surface ramp, text ramp, violet brand (never a CTA), teal action, four status colors, and the single sanctioned shadow-overlay. Utilities generate automatically (bg-ground, text-text-muted, border-border, …).
  • Geist Sans + Geist Mono self-hosted as variable woff2 (latin subset, 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.
  • Global :focus-visible teal ring and a blanket prefers-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.
  • Chrome restyled to tokensbase.html, base_app.html, _sidebar.html (BEM hooks for the rail tier) and nav_tags.ACTIVE_CLASSES. New {% block topbar_start %} slot in the top bar.
  • DESIGN.md updated to match, including a new §App Shell.

What's deliberately not in

Still on feat/epic-2-review-console: the RUN_FEED emitter, Feed templates + SSE, notifications migration 0007, the Manager Lens, the dashboard console body, and the views.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:

  1. The 768px reflow moves --sheet-inset-* with it. main keys that switch to --breakpoint-sm because "the sidebar is on screen" was sm:. With the sidebar appearing at md:, the switch and the two guards in test_picker_popovers.py follow — otherwise bottom sheets inset for a sidebar that isn't there between 640 and 767px.
  2. The chat dock vs. the new fixed tab bar. main:has(.chat-shell) zeroed <main>'s bottom padding so the sticky dock could reach the viewport bottom. Below md it now pads by --app-tabbar-height instead: a sticky bottom: 0 sticks 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.
  3. Moving the body ground #030712 → #0d1117 left 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 test4929 passed, 163 skipped.
  • make lint clean (ruff check + format, djade); django-admin compilemessages compiles pt.
  • CSS compiles on the pinned Tailwind v4.2.2 standalone CLI; every new utility generates, @font-face paths resolve, --sheet-inset-* lands at 48rem.
  • Rendered the dashboard in a browser and probed all three tiers:
    • 1280px — 240px sidebar on surface-1, tab bar hidden, <main> padding-bottom: 40px.
    • 820px — 64px rail, labels / brand text / build info hidden, nav items centred, burger hidden.
    • 375px — sidebar gone, 4 tabs at 94×55 in a 56px bar, 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 a sidebar__label, or restate the tab bar height as a literal, and they fail):

  • every sidebar__* hook the template carries is handled by the rail tier, and vice versa;
  • every sidebar nav item wraps its text in sidebar__label, so it cannot overflow the 4rem rail;
  • the tab bar and <main>'s chat padding both read --app-tabbar-height;
  • no template loads a font from a CDN.

Note

daiv/static/css/styles.css is gitignored, so make tailwind-build is 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-width is now the tier, 4rem widened to 15rem by a :root switch at lg:. This fixes a real defect in the first commit: the rail restated width: 4rem while the token stayed 15rem, so --sheet-inset-start insetting 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).
  • The rail's bounds read theme(--breakpoint-md/-lg) instead of the px they compile to — the same rule the sheet switch follows, so they can't 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 .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 dead group marker on each.
  • 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 (was 4× copy-paste with the section key spelled twice per tab).
  • 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 just restated it.
  • Dead code out: the --surface-rise-duration reduced-motion switch (the blanket !important kill switch subsumes it), an inert scroll-behavior declaration, and --color-focus's duplicate hex (now reads accent-bright).
  • Visual: the floating panels — composer sheet + autocomplete, pickers, filter menu, the three drawers, the repo combobox — painted a literal #0d1117, which the new ground is, leaving them flush with the page. They move to surface-2 to stay lifted. test_surface_contrast now 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 lint clean; lint-typing at the pre-existing 457-diagnostic baseline with none in the touched files.

srtab added 2 commits August 28, 2026 23:46
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.
@srtab
srtab enabled auto-merge August 28, 2026 23:32
@srtab
srtab merged commit 20723cc into main Aug 28, 2026
6 checks passed
@srtab
srtab deleted the claude/extract-pr-1412-design-7a62a4 branch August 28, 2026 23:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant