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

6.6 KiB
Raw Blame History

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.


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?