Skip to content

hub-client: UI/UX modernization Phase 0 — design tokens and CSS lint - #605

Merged
shikokuchuo merged 6 commits into
mainfrom
hub-client-uiux-phase0
Aug 26, 2026
Merged

hub-client: UI/UX modernization Phase 0 — design tokens and CSS lint#605
shikokuchuo merged 6 commits into
mainfrom
hub-client-uiux-phase0

Conversation

@shikokuchuo

Copy link
Copy Markdown
Member

Phase 0 of the hub-client UI/UX modernization: token foundation and CSS hygiene. No visual changes. New baselines prove the UI is pixel-identical before and after.

What changes

  • theme.css defines the scale tokens: spacing, radii, shadows, z-index layers, type, motion, and a focus ring.
  • A header comment in theme.css documents the token layers: primitive, scale, semantic, component.
  • All hardcoded colors and bare z-index values move to tokens.
  • The .ph-* classes rename to .qh-* (611 mechanical replacements).
  • ui.css gains shared utilities: .qh-truncate, .qh-row-hover, .qh-active-accent-row.

New test infrastructure

  • npm run lint:css checks four CSS rules. An exceptions list covers old code and shrinks as later phases fix it. The color and z-index rules are already at zero exceptions.
  • New dev-harness routes render key surfaces without a server: projects home, three dialogs, sidebar, header, notifications, and a token gallery at #/dev/tokens.
  • Playwright captures visual baselines of these surfaces in light and dark themes.
  • axe-core scans the same surfaces. Current contrast violations are recorded in a baseline file. New or worse violations fail the test.

Verification

  • npm run build:all and npm run test:ci pass (1005 + 112 + 133 tests).
  • Visual suite passes 42/42, pixel-identical to the pre-change baselines.
  • The rename-affected e2e specs pass 7/7 on a real build.
  • eslint output matches main exactly (192 pre-existing problems, none added).

Notes

  • No changelog entry: this is internal work with no user-visible change.
  • CI adds the Linux screenshot baselines on the first run (existing workflow step).
  • cargo xtask verify stops at a known failure that already exists on main: the preview-renderer Equation \tag test (bd-s36g9dav, bd-kn7ln981). This PR does not cause it.

Tracks bd-2q55e6rc (Phase 0: bd-5nm6v8bl, closed). Plan: claude-notes/plans/2026-08-26-hub-client-uiux-modernization.md.

@posit-snyk-bot

posit-snyk-bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues
Licenses 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@cscheid

cscheid commented Aug 26, 2026

Copy link
Copy Markdown
Member

I assume @vezwork has taken a look at the large-scale structure of these changes - we could benefit from someone's first-hand front-end expertise here.

@shikokuchuo

shikokuchuo commented Aug 26, 2026

Copy link
Copy Markdown
Member Author

@vezwork and I discussed last week - not everything in here specifically but the direction - phases 0-4 are engineering and accessibility fixes. I do not plan to go beyond this for now (the later stages are there so we can pick up at a later date).

@cscheid

cscheid commented Aug 26, 2026

Copy link
Copy Markdown
Member

I do not plan to go beyond this for now

Ok, great. By "this", do you mean all phases or just Phase 0? (Ie, do you intend to merge Phases 1.. as well as 0? I just want to keep track.)

@shikokuchuo

Copy link
Copy Markdown
Member Author

Ah sorry - I realise it didn't upload the full plan file. I'll do that separately - but basically I've sequenced it so we do the best practices stuff (phases 0-4 I mentioned) and then there's a gate before we make any opinionated visual changes. It'll all be part of one stack so hopefully easy to follow.

@shikokuchuo
shikokuchuo force-pushed the hub-client-uiux-phase0 branch from 26a1dff to 15e1f00 Compare August 26, 2026 17:10
shikokuchuo and others added 6 commits August 26, 2026 18:12
…routes, visual + axe baselines

UI/UX modernization Phase 0 (bd-5nm6v8bl, epic bd-2q55e6rc), test
specifications first per the plan:

- scripts/lint-css.mjs (npm run lint:css): dependency-free CSS lint
  enforcing token-first rules — no hex/rgb() colors outside theme.css,
  no bare z-index integers, no outline:none without :focus-visible,
  no physical box properties where a logical equivalent exists.
  Grandfathered exceptions live in lint-css-exceptions.json (187
  entries); stale exceptions fail, so the list is self-pruning as
  rules burn down per phase.
- DevHarness grows baseline routes beyond the setup screens:
  projects-home, dialog-new-file, dialog-share, dialog-new-asset,
  sidebar (SidebarTabs + FileSidebar + OutlinePanel), header
  (MinimalHeader), notifications (Toast + UpdateAvailableToast +
  EphemeralSessionBanner) — all with canned data, no hub server.
- e2e/baseline-screens.visual.spec.ts: Playwright pixel baselines of
  every route x light/dark, clock frozen at 2026-08-25 (ProjectsHome
  renders relative dates), transitions disabled before capture.
- e2e/baseline-a11y.visual.spec.ts: @axe-core/playwright scans of the
  same routes x light/dark (approved devDependency). Characterization
  model: current serious/critical violations (all color-contrast) are
  recorded in helpers/axe-baseline.json; new or worsened violations
  fail, fixed ones force a baseline regeneration.
- claude-notes plan pointer for the braid epic.

Verified: full visual suite 38/38 green across repeated runs;
vitest 1005/1005; typecheck + eslint clean.
…lines

bd-5nm6v8bl. Additive only — no computed value changes (verified: the
Phase 0 visual baselines diff clean against pre-token captures):

- theme.css gains the scale layer: --space-1..8 (4px base),
  --radius-sm/md/lg, --shadow-1/2/3 (per-theme where the source value
  was per-theme), --z-base..--z-max layer scale, --text-xs..xl +
  --font-weight-* + --leading-* + --font-mono, --duration-fast/base +
  --ease-out/standard, --focus-ring. --modal-shadow now aliases
  --shadow-3 (identical values, both themes).
- Fixed primitives for the coming migration: --alpha-black/white-*,
  --posit-teal/blue/green-alpha-*, the attribution palette
  (ReplayDrawer ring), the Catppuccin Macchiato debug-inspector
  palette, and the legacy ProjectSelector palette.
- Header comment documents the token layering convention
  (primitive → scale → semantic → component).
- DevHarness #/dev/tokens page renders every scale token (spacing
  swatches, radii, shadows, type specimens, focus ring); covered by
  new visual + axe baselines in both themes.
- lint:css color rule refined: token *definitions* (custom-property
  declarations) may hold literals in any file — standalone dev pages
  (src/debug/) don't load theme.css and keep a local token block.
  Use sites still must reference var(--token).
- Baseline determinism: bootHarness pins a fixed IndexedDB identity
  (the app's random anonymous avatar color was an intermittent 4th
  axe color-contrast node and sub-threshold screenshot noise), freezes
  the clock (relative dates), disables transitions (mid-transition
  contrast measurement drifted), and waits for fonts. Visual config
  gets retries: 1 for dev-server contention flakes (assertion
  failures remain deterministic and fail through).

Verified: full visual suite 42/42 green across repeated runs.
bd-5nm6v8bl. Mechanical rename of all 130-ish ph- (projects-home)
class tokens to the .qh-* (Quarto Hub) prefix — 611 replacements
across 22 files (components, CSS, e2e selectors, unit tests), done
early in the modernization before more CSS accrues. The ui.css header
comment's 'rename pending' note is now resolved.

Also drops 10 lint:css exceptions made stale by the token-definition
relaxation (debug.css local token block) — the self-pruning
exceptions list working as designed.

Verified: typecheck clean, vitest 1005/1005, lint:css clean, visual
suite 42/42 (pixel-identical against pre-rename baselines).
…shared utilities

bd-5nm6v8bl. Every hardcoded color and bare z-index outside token
definitions now flows through theme.css (or debug.css's local token
block). lint:css exceptions: 187 → 85, with no-hardcoded-color and
no-bare-z-index burned to EMPTY — the rules are now enforced
repo-wide for all future changes.

All migrations are value-preserving by construction; the Phase 0
visual baselines (16 screens x 2 themes) diff clean and the axe
baselines hold. Two notes:

- ProjectsHome menu z-index 70 → --z-dropdown (60): order-preserving
  renumber — no layer exists between 60 and 70, and the menu must
  only beat the sticky header (40). Pixel-invisible by construction.
- Editor.css drops a dead var() fallback (rgba(0,0,0,0.1)) on
  --error-overlay-border — the token is always defined.

Token mapping highlights: fixed alpha tints (--alpha-black/white-*,
--posit-teal-alpha-*) for drop overlays/shadows/focus rings;
--text-on-accent for text on colored fills; --backdrop-bg for dialog
scrims; --selector-* legacy palette (classic selector, light-only);
--debug-* Catppuccin Macchiato palette (permanently-dark dev panel);
--attribution-* for the ReplayDrawer collaborator ring; --z-* layers
everywhere (incl. --z-revealjs-menu for the preview iframe's own
stacking context).

Shared utilities extracted to ui.css and adopted at exact-match
sites: .qh-truncate (5 sites across FileSidebar + MinimalHeader),
.qh-row-hover and .qh-active-accent-row (FileSidebar rows; the
active-accent utility uses the always-transparent-border pattern and
logical border-inline-start, so two physical-properties exceptions
burned down with it). .file-item's margin-offset variant of the
active treatment is deliberately left for Phase 1 sidebar work —
unifying it is an alignment change, not a value-preserving one.

Verified: lint:css clean, typecheck clean, vitest 1005/1005, visual
suite 42/42 pixel-clean.
…/UX modernization pointer

bd-5nm6v8bl closed.
@shikokuchuo
shikokuchuo force-pushed the hub-client-uiux-phase0 branch from 15e1f00 to 79f15ac Compare August 26, 2026 17:13
@shikokuchuo
shikokuchuo merged commit c8115e9 into main Aug 26, 2026
10 checks passed
@shikokuchuo
shikokuchuo deleted the hub-client-uiux-phase0 branch August 26, 2026 19:39
shikokuchuo added a commit that referenced this pull request Aug 26, 2026
The 2026-08-26 entries referenced the pre-squash branch commits from
PRs #605-#613, which are not ancestors of main. Repoint the ten
affected entries at the squash-merge commits that contain each change
(20fa2ba, 83c818f, 7a73982, 1ccb9cc).
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.

3 participants