Files
headquarter/openspec/proposals/web-ui-spacing-typography-rework.md
T

128 lines
6.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SDD Proposal: Web UI Spacing, Typography & Visual Rhythm Rework
## Status
**Phase:** proposal
**Date:** 2026-06-16
**Owner:** el Gentleman
**Based on:** Scout audit `ui-audit-spacing-typography.md`
---
## User Story
As a Headquarter user, I want the web UI to feel consistent, readable, and polished across desktop and mobile, so that I can navigate and manage workspaces, projects, and sessions without fighting cramped layouts, broken mobile views, or inconsistent spacing.
---
## Problem Statement
A comprehensive audit of `apps/web/src` found systemic spacing, typography, margin, and visual-hierarchy issues:
- **Missing primitive styles**: dozens of widely-used class names (`.btn`, `.form-error`, `.alert`, `.badge`, `.mobile-detail-*`, etc.) are referenced in TSX but have no CSS rules, causing broken or unstyled UI on multiple pages.
- **Completely unstyled mobile detail view**: `mobile-detail-view.tsx` ships layout classes that do not exist in any stylesheet.
- **Mobile layout collisions**: the bottom nav, start-tool FAB, and mobile edit sheets can overlap and do not account for safe-area insets.
- **Inconsistent design tokens**: the token scale lacks border-radius, line-height, shadow, touch-target, and nav-height primitives. Mixed `px`/`rem`/`em` values and inline `style={{...}}` blocks bypass the token system.
- **Duplicated systems**: two modal/dialog implementations, duplicated `.form-field`/`.form-group` patterns, duplicated status-badge/chip styles, and overlapping breakpoints (`767px`, `768px`, `860px`).
- **Heavy inline-style usage**: editors and sidebars embed layout CSS directly in JSX, making responsive overrides and theming impossible.
This is not a single bug; it is a design-system hygiene issue that affects nearly every page.
---
## Goals
1. Establish a complete, single-source-of-truth token scale for spacing, typography, radius, shadow, line-height, touch targets, and layout heights.
2. Add every missing primitive component style so that referenced classes actually render correctly.
3. Fix mobile layout collisions by deriving FAB/bottom-sheet offsets from a shared nav-height token.
4. Replace ad-hoc `px`/`rem` values and inline styles with token-based utility classes where feasible.
5. Consolidate duplicated patterns: one modal/dialog system, one form-field pattern, one status-badge family, one card family.
6. Standardize breakpoints to the existing token scale (`--bp-sm`, `--bp-md`, `--bp-lg`, `--bp-xl`).
7. Leave the UI visually improved without changing behavior or user-facing features.
---
## Non-Goals
- No new user-facing features or workflows.
- No changes to backend APIs, database schema, or authentication.
- No redesign of the information architecture or navigation structure.
- No replacement of Tailwind or CSS-modules; we stay in the existing global-CSS architecture.
- No runtime theme-engine rewrite; light/dark tokens remain as-is.
---
## High-Level Approach
Split the work into three reviewable passes to stay under the 400-line review budget:
### Pass 1: Foundations (P0)
- Expand `tokens.css` with missing primitives.
- Add missing primitive classes to `global.css`/`utilities.css` (buttons, alerts, errors, badges, form inputs, loading states, checkbox labels, hints, mobile detail view, etc.).
- Introduce `--mobile-nav-height` and fix FAB/bottom-sheet/shell-content collisions.
- Fix the most critical inline font-size violations (`0.7rem` → tokens).
- Add focused `:focus` visibility to interactive controls.
### Pass 2: Component Cleanup (P1)
- Refactor the highest-volume inline-style offenders into utility classes:
- `manifest-editor.tsx`
- `ConfigProfileEditorPanel.tsx`
- `ToolTypeEditorPanel.tsx`
- `ToolTypeListSidebar.tsx`
- `ConfigProfileListSidebar.tsx`
- `git-mount-editor.tsx`
- Replace hardcoded `280px` sidebars with `--sidebar-width` token.
- Unify `.form-field`/`.form-group` and migrate callers.
- Consolidate status badges/chips into a single `.status-badge` family.
### Pass 3: Consolidation & Polish (P2)
- Deprecate `.modal-*` in favor of `.dialog-*` and migrate callers.
- Consolidate card patterns across page CSS files into `global.css` modifiers.
- Standardize breakpoints to `--bp-*` tokens and remove the `860px` one-off.
- Add token documentation and a lightweight review checklist.
---
## Open Questions
1. **Which pass should include the mobile detail view styles?**
- Recommendation: Pass 1, because it is currently broken.
2. **Should we keep the existing `.utilities.css` naming convention or introduce BEM-style modifiers (`.card--elevated`, `.status-badge--error`)?**
- Recommendation: introduce BEM-style modifiers only for the new consolidated families; keep existing utilities untouched to minimize churn.
3. **Is the terminal page's hardcoded dark palette acceptable long-term, or should it become theme-aware?**
- Recommendation: keep terminal colors hardcoded for now; only convert spacing to tokens.
4. **Should we add a lint rule to block new inline `style={{...}}` layout declarations?**
- Recommendation: add a code-review checklist in Pass 3, not a blocking lint rule, to avoid false positives.
---
## Risks
| Risk | Severity | Mitigation |
|------|----------|------------|
| Large diff touching many files | High | Split into three chained PRs; each under 400 changed lines. |
| Visual regressions on pages not manually tested | Medium | Rely on typecheck/lint for TSX; do visual spot-checks on representative pages. |
| Inline-style refactor breaks dynamic values | Medium | Only refactor static layout styles; keep dynamic values (computed positions) in JS. |
| Token changes affect existing components unexpectedly | Medium | Add new tokens only; do not rename existing tokens without a compat layer. |
| Mobile safe-area behavior varies across devices | Medium | Use `env(safe-area-inset-bottom, 0px)` with a sensible fallback. |
---
## Effort Estimate
| Pass | Focus | Est. Files | Est. Lines | Complexity |
|------|-------|------------|------------|------------|
| Pass 1: Foundations | tokens, missing primitives, mobile nav/FAB | 46 | ~400 | Medium |
| Pass 2: Component Cleanup | inline styles, sidebars, forms, badges | 1014 | ~600 | High |
| Pass 3: Consolidation | modals, cards, breakpoints, docs | 812 | ~400 | Medium |
| **Total** | | **2232** | **~1400** | **High** |
**Review workload forecast:** Each pass should stay near or below the 400-line review budget. Pass 2 may need to be split further if it grows.
---
## Next Recommended Phase
**Spec** — detail the exact token additions, primitive class API, mobile-nav height calculation, and the migration path for inline styles.
Should I proceed to spec?