26 KiB
Headquarter Web UI — Spacing, Typography & Visual Rhythm Audit
Scope: apps/web/src/components/**/*, apps/web/src/pages/**/*, apps/web/src/components/app-shell.tsx, apps/web/src/styles/*.css, apps/web/src/styles/pages/*.css, and mobile-specific components under apps/web/src/components/features/mobile.
Date: 2026-06-16
Method: Static source review; no runtime screenshots. Line numbers reference the current state of the repository.
1. Critical Issues
These are problems that break layouts, make the UI unusable on mobile, or create accessibility failures.
1.1 Missing CSS for heavily-used component classes
A large number of class names are referenced in JSX/TSX but have no rules in any stylesheet. Browsers will render them as unstyled inline elements, causing broken spacing, unreadable text, and invisible interactive states.
| Class(es) | Used in (examples) | Impact |
|---|---|---|
.mobile-detail-view, .mobile-detail-header, .mobile-detail-field, .mobile-detail-field-label, .mobile-detail-field-value, .mobile-detail-code |
components/features/mobile/mobile-detail-view.tsx (lines 30–91), pages/WorkspacesPage.tsx (detail view), ToolWorkshopMobileView.tsx, ConfigProfilesMobileView.tsx |
The entire mobile detail view has no layout styling; fields stack without gaps, labels/values are indistinguishable, code blocks overflow. |
.mobile-list-search, .mobile-list-search-input |
components/features/mobile/mobile-list-view.tsx (lines 37–42) |
Search input is unstyled on mobile list views. |
.btn, .btn-primary, .btn-secondary, .btn-sm |
pages/WorkspacesPage.tsx:150,157,183, components/features/workspace/workspace-tools-panel.tsx:26,56, components/features/workspace/workspace-card.tsx:74, components/features/project/ProjectCard.tsx:131 |
Buttons fall back to native browser styling; spacing and sizing are inconsistent with .primary-button/.secondary-button. |
.link-button |
components/features/session/session-card.tsx:187 |
Session URL button has no styling. |
.checkbox-label |
components/features/tool/tool-starter.tsx:280, components/features/session/create-session-form.tsx:368, components/features/tool/instance-list.tsx:345,490, components/features/config-profiles/ConfigProfileEditorPanel.tsx:170 |
Checkbox pills rely only on inline styles; base class is undefined. |
.hint |
components/features/tool/tool-starter.tsx:312, components/features/session/create-session-form.tsx:398 |
Helper text is unstyled and hard to read. |
.form-error, .error-message |
components/features/tool/tool-starter.tsx:318, components/features/tool/start-tool-modal.tsx:92, components/features/workspace/workspace-create-form.tsx:296, pages/ProfilePage.tsx:177, pages/ProjectSettingsPage.tsx:51,122, components/features/project/repositories-settings-tab.tsx:62, components/features/project/repository-create-dialog.tsx:384, components/features/tool/instance-list.tsx:249 |
Error states have no visual treatment (color, padding, background). |
.alert, .alert-error |
pages/WorkspacesPage.tsx:97,165 |
Alert banners are unstyled. |
.loading-state |
pages/WorkspacesPage.tsx:100,178, pages/WorkspaceDetailPage.tsx:27 |
Loading states are unstyled plain text. |
.text-muted |
components/features/mobile/mobile-detail-view.tsx:30 |
Undefined; should be .muted. |
.badge, .badge-success, .badge-secondary |
components/features/mobile/mobile-detail-view.tsx:33–36 |
Badge classes used but never defined. |
.key-signing, .key-verification, .signature-result, .verify-result |
components/features/ssh-keys/SSHKeyList.tsx (lines 79–161) |
Signing/verification sections have no spacing or typography rules; the SSH key page is visually broken below the public-key copy area. |
.form-input |
components/features/config-profiles/ConfigProfileEditorPanel.tsx (multiple lines) |
Inputs in config profile editor use .form-input, which is not defined. |
Recommendation: Add a single “missing primitives” pass to global.css or utilities.css defining .btn, .btn-primary, .btn-secondary, .btn-sm, .link-button, .checkbox-label, .hint, .form-error/.error-message, .alert/.alert-error, .loading-state, .badge*, .form-input, and the entire .mobile-detail-* block. Then remove the duplicated inline style={{...}} blocks from components.
1.2 Mobile detail view is completely unstyled
- File:
components/features/mobile/mobile-detail-view.tsx(lines 53–91) - Issue: The component defines
.mobile-detail-view,.mobile-detail-header,.mobile-detail-fields,.mobile-detail-field,.mobile-detail-field-label,.mobile-detail-field-value, and.mobile-detail-code, but no stylesheet contains these selectors. The result is a raw HTML-like stack with no padding, no separators, no label/value hierarchy, and unbounded<pre>blocks. - Recommendation: Add to
utilities.css:.mobile-detail-view { display:flex; flex-direction:column; min-height:100%; background:var(--bg); } .mobile-detail-header { position:sticky; top:0; z-index:10; display:flex; align-items:center; gap:var(--space-3); padding:var(--space-3); background:var(--panel); border-bottom:1px solid var(--border); } .mobile-detail-header-content { flex:1; min-width:0; } .mobile-detail-title { margin:0; font-size:var(--font-size-lg); } .mobile-detail-subtitle { margin:var(--space-1) 0 0; color:var(--muted); font-size:var(--font-size-sm); } .mobile-detail-actions { display:flex; gap:var(--space-2); } .mobile-detail-action { … } .mobile-detail-fields { display:flex; flex-direction:column; gap:var(--space-3); padding:var(--space-3); } .mobile-detail-field { display:flex; flex-direction:column; gap:var(--space-1); padding:var(--space-3); background:var(--panel); border:1px solid var(--border); border-radius:10px; } .mobile-detail-field-label { font-size:var(--font-size-xs); text-transform:uppercase; letter-spacing:0.05em; color:var(--muted); } .mobile-detail-field-value { font-size:var(--font-size-base); color:var(--ink); word-break:break-word; } .mobile-detail-code { overflow:auto; max-width:100%; font-size:var(--font-size-sm); }
1.3 Mobile navigation and FAB collision
- File:
styles/utilities.css(lines 2448–2474) andstyles/global.css(lines 1153–1205) - Issue:
.mobile-navis fixedbottom:0,height:64px, withpadding-bottom: env(safe-area-inset-bottom, 0)..start-tool-fabon mobile is positionedbottom: 5rem; right: 1rem(global.css:1201)..mobile-edit-actionsisposition: fixed; bottom: 64px(utilities.css:2272)..shell-content.mobileaddspadding-bottom: calc(1.25rem + 64px)(utilities.css:2412).
- Impact: The FAB, bottom sheets, edit actions, and mobile tab bar can overlap depending on safe-area insets. The
5remmagic number does not account forenv(safe-area-inset-bottom)and may collide with the nav on devices with home indicators. - Recommendation: Replace magic numbers with a CSS custom property:
--mobile-nav-height: calc(64px + env(safe-area-inset-bottom, 0px)). Then set.start-tool-fab { bottom: calc(var(--mobile-nav-height) + var(--space-3)); },.mobile-edit-actions { bottom: var(--mobile-nav-height); }, and.shell-content.mobile { padding-bottom: var(--mobile-nav-height); }.
1.4 Unreadable type scale and cramped touch targets
- Files:
styles/tokens.css(lines 40–45),styles/utilities.css(lines 2501–2526), multiple component inline styles - Issue:
- The token scale defines only six font sizes (
--font-size-xsthrough--font-size-2xl) and no line-height tokens. - Many inline styles use
fontSize: "0.7rem"(e.g.ConfigProfileListSidebar.tsx:82,95), which is below the 11 px effective minimum recommended for mobile legibility. - Several buttons use
min-heightderived only frompadding, not the design-system touch target. The global rulebutton, a, input, select, textarea, [role="button"] { min-height: 44px; min-width: 44px; }(utilities.css:2501) is too broad and can distort form elements.
- The token scale defines only six font sizes (
- Recommendation: Add
--line-height-*tokens and a--touch-target: 44pxtoken. Replace inlinefontSize: "0.7rem"withvar(--font-size-xs)(or larger). Narrow the broadmin-height/min-widthselector to interactive controls only, not everyinput/select/textarea.
1.5 Sidebars use fixed pixel widths and inline styles
- Files:
components/features/config-profiles/ConfigProfileListSidebar.tsx(lines 22–23):style={{ width: "280px", minWidth: "280px" }}components/features/tool-workshop/ToolTypeListSidebar.tsx(lines 22–23):style={{ width: "280px", minWidth: "280px" }}styles/global.css(line 35):.shell-body { grid-template-columns: 230px 1fr; }
- Issue: These values are hardcoded in pixels/rem strings inside components and CSS. They do not respond to breakpoints and are inconsistent with the shell sidebar width.
- Recommendation: Define
--sidebar-width: 280pxin tokens and use it consistently. On small desktop/large tablets (≤860 px) the shell collapses to a top nav, but the config-profiles/tool-workshop pages keep their 280 px sidebars, causing horizontal overflow.
2. Major Inconsistencies
2.1 Mixed px/rem/em units and magic numbers
The codebase uses px, rem, em, and string literals in inline styles interchangeably.
| Location | Value | Problem |
|---|---|---|
styles/syntax-highlight.css:46,87,125 |
font-size: 14px |
Hardcoded px in code areas; should use --font-size-sm. |
styles/syntax-highlight.css:21,29,55,69,104,110,115 |
px-based paddings |
Should be --space-* tokens. |
styles/global.css:36 |
height: calc(100vh - 57px) |
Magic number 57 px assumes header height; fragile if header wraps. |
styles/global.css:12 |
padding: 0.85rem 1.25rem |
Non-token values; closest tokens are --space-3/--space-4. |
styles/global.css:50 |
padding: 0.65rem 0.75rem |
Non-token; should be --space-2/--space-3. |
styles/global.css:187 |
min-height: 38px |
Below --touch-target; should be 44 px. |
styles/global.css:269 |
font-size: 1.6rem |
One-off size; should map to a token or be removed. |
styles/global.css:623–628 |
min-width: 400px, max-width: 600px, max-height: 80vh, border-radius: 8px |
Modal sizing inconsistent with .dialog rules above. |
styles/pages/git-history.css:69 |
padding: 0.15rem 0.4rem |
Should be --space-1/--space-2. |
styles/pages/sessions.css:64 |
bottom: calc(100% + 0.25rem) |
Should be --space-1. |
styles/pages/sessions.css:67 |
min-width: 12rem |
Should be a token or --space-* composition. |
styles/utilities.css:2448 |
height: 64px |
Should be a token. |
styles/utilities.css:2459 |
padding: 8px 12px |
Should be --space-2/--space-3. |
styles/utilities.css:2461 |
font-size: 11px |
Hardcoded px; should be --font-size-xs. |
styles/utilities.css:2465 |
min-width: 64px |
Should be a touch-target token. |
Inline styles in manifest-editor.tsx, ConfigProfileEditorPanel.tsx, ToolTypeEditorPanel.tsx, ToolTypeListSidebar.tsx, ConfigProfileListSidebar.tsx, git-mount-editor.tsx |
Dozens of style={{ gap:"0.5rem", padding:"1rem", borderRadius:"0.375rem" }} |
Bypass tokens entirely. |
Recommendation: Run a pass to replace ad-hoc px/rem values with --space-* and --font-size-* tokens. Create additional tokens where the current scale is insufficient (--space-7: 2.5rem, --space-12: 6rem, --radius-sm, --radius-md, --radius-lg, --radius-full).
2.2 Duplicated and overlapping responsive breakpoints
- Files:
styles/global.css(lines 198, 330, 517),styles/utilities.css(many@media (max-width: 767px)),styles/pages/workspaces.css(@media (max-width: 767px)),styles/pages/sessions.css(@media (max-width: 767px)),styles/pages/workspace-detail.css(@media (max-width: 767px)) - Issue: The codebase mixes
767px,768px,860px, and1024pxbreakpoints with no clear mobile/desktop boundary. For example:.shell-bodycollapses at860px(global.css:517) and again at767px(global.css:198)..settings-layoutcollapses at768px(global.css:742) and is overridden again at767px(utilities.css)..card-gridgoes 1-column at<768pxbut.workspaces-gridstays multi-column until<767px, causing a 1 px gap in behavior.
- Recommendation: Standardize on the token breakpoints (
--bp-sm: 480px,--bp-md: 768px,--bp-lg: 1024px,--bp-xl: 1280px) and usemin-widthmobile-first queries. Remove the860pxone-off breakpoint.
2.3 Token scale is incomplete
- File:
styles/tokens.css(lines 24–31, 40–45) - Issue:
- Spacing jumps from
--space-6: 2remto--space-8: 3remto--space-10: 4rem; no--space-7,--space-9,--space-12. - No border-radius tokens (
--radius-sm,--radius-md,--radius-lg,--radius-full). - No line-height tokens.
- No shadow/elevation tokens; shadows are copy-pasted (
box-shadow: 0 1px 0 rgba(0,0,0,0.02),0 6px 18px rgba(0,0,0,0.08),0 4px 14px rgba(0,0,0,0.25), etc.). - No touch-target or nav-height tokens.
- Spacing jumps from
- Recommendation: Expand
tokens.cssto include these primitives and refactor existing rules to consume them.
2.4 Two competing modal/dialog systems
- File:
styles/global.css(lines 394–451 and 619–643) - Issue: There are two separate modal implementations:
.dialog-overlay+.dialog/.dialog-lg(rounded, centered, responsive).modal-overlay+.modal-content(older, square, fixedmin-width: 400px)
- Impact: Different paddings, border radii, widths, and mobile behaviors. Components use both (
SessionCarduses.modal-overlay,instance-list.tsxuses.dialog-overlay). - Recommendation: Deprecate
.modal-*and migrate all modals to.dialog*tokens. Add a single.modal-content → .dialogmapping for backward compatibility, then refactor callers.
2.5 Inline styles bypass the design system
Dozens of components embed style={{...}} objects that duplicate layout primitives.
- High-volume offenders:
components/features/tool/manifest-editor.tsx— ~70 inline style props (cards, rows, gaps, padding, font sizes).components/features/config-profiles/ConfigProfileEditorPanel.tsx— ~40 inline style props.components/features/tool-workshop/ToolTypeEditorPanel.tsx— ~20 inline style props.components/features/tool-workshop/ToolTypeListSidebar.tsx— sidebar dimensions and list item spacing inline.components/features/config-profiles/ConfigProfileListSidebar.tsx— same pattern.components/features/git/git-mount-editor.tsx— many inline flex/gap/padding rules.
- Impact: Prevents theming, makes responsive overrides impossible, and scatters magic numbers across the codebase.
- Recommendation: Replace inline styles with utility classes (
.stack,.stack-sm,.row,.card,.form-group,.form-row,.p-3,.rounded-lg, etc.) and add missing utilities as needed.
2.6 Page-specific CSS files repeat global patterns
- Files:
styles/pages/projects.css,styles/pages/sessions.css,styles/pages/ssh-keys.css,styles/pages/workspace-detail.css,styles/pages/workspaces.css,styles/pages/git-history.css - Issue: Each page file redeclares card spacing, grid gaps, responsive overrides, and form field patterns that already exist (or should exist) in
global.css/utilities.css. For example:.repo-block,.workspace-chip,.instance-card,.settings-sectionall duplicatebackground: var(--panel); border: 1px solid var(--border); border-radius: 10/12/14px;.
- Recommendation: Consolidate card variants into
global.cssusing.card,.card-sm,.card-lg, and.card-elevatedmodifiers. Reserve page files for truly page-specific layout (e.g.,.history-containertwo-column grid).
3. Minor Polish
3.1 Misaligned icons and nav density
- File:
components/app-shell.tsx(lines 14–68) andstyles/global.css(lines 12–77) - Issue:
.shell-headerusespadding: 0.85rem 1.25remwhile.shell-contentusespadding: 1.25rem. The header baseline does not visually align with the content grid..nav-itemusesgapinherited from.shell-nav(gap: 0.4rem) plusborder-radius: 10px; active and hover states have inconsistent text colors (#f7fff7vsvar(--primary-fg))..nav-section-titlehasmargin-top: 0.5remandpadding: 0.25rem 0.75remwhileutilities.cssredeclares it withpadding: var(--space-2) var(--space-4)andfont-size: var(--text-xs)(an undefined variable; should be--font-size-xs).
- Recommendation: Use
--space-3/--space-4consistently for header and content padding. Unify nav active/hover colors to token values. Fix--text-xstypo inutilities.css.
3.2 Page header spacing
- File:
styles/global.css(lines 320–337) - Issue:
.page-headerusesgap: var(--space-3)and wraps to column on mobile, but the bottom margin/rhythm is inconsistent across pages. Dashboard home sections use.page-headerinside.card, while other pages use it at the section root. - Recommendation: Add
.page-header { margin-bottom: var(--space-4); }and a nested variant.card .page-header { margin-bottom: var(--space-3); }.
3.3 Card gaps and grid inconsistencies
- File:
styles/global.css(lines 230–261) andstyles/pages/workspaces.css(lines 1–236) - Issue:
.home-summary-grid,.home-project-grid,.home-session-gridusegap: var(--space-4)..card-gridusesgap: var(--space-4)and breakpoint-driven columns..workspaces-gridusesgap: var(--space-4)on desktop andvar(--space-3)on mobile..sessions-gridusesgap: var(--space-4).
- Impact: Mostly consistent, but the workspace card internal gap (
workspace-card { gap: var(--space-4); }) combined with the grid gap creates double spacing relative to project/session cards. - Recommendation: Standardize all list/grids on
--space-3mobile and--space-4desktop. Reduce workspace card internal gap to--space-3.
3.4 Form spacing
- File:
styles/global.css(lines 428–451) - Issue:
.form-fieldand.form-groupboth exist with nearly identical rules (display:flex; flex-direction:column; gap: 0.35rem)..form-fieldis newer and used in Settings;.form-groupis legacy and used in SSH keys, dialogs, and many inline forms. - Recommendation: Merge into a single
.form-fieldclass. Provide.form-rowfor horizontal groups (already partially defined) and.form-actionsfor button rows. Addmargin-bottom: var(--space-4)to each field for vertical rhythm.
3.5 Status badges use arbitrary colors
- File:
styles/utilities.css(lines 2356–2396) andstyles/global.css(lines 1092–1131) - Issue: Status badges are defined in both files with overlapping status names but different background rules.
.instance-chipalso duplicates status colors. - Recommendation: Consolidate status colors into a single
.status-badgecomponent with.status-badge--running,.status-badge--error, etc., and reuse it for chips.
3.6 Notification center positioning
- File:
components/features/notification/notification-center.tsx(lines 42–59) - Issue: Dropdown position is computed in JavaScript and applied via
style={dropdownStyle}. On mobile,left/right: 1remis hardcoded in JS; on desktop, it useswindow.innerWidth - rect.right. - Recommendation: Use CSS anchoring or simpler absolute positioning relative to
.notification-centerso the dropdown responds to tokens and does not need resize listeners.
3.7 Profile page desktop card lacks profile-specific CSS
- File:
pages/ProfilePage.tsx(lines 134–180) - Issue: Uses
.profile-avatar-section,.avatar-preview,.avatar-image,.avatar-placeholderwhich are not defined in any stylesheet. The desktop profile form will render unstyled. - Recommendation: Add profile avatar styles or reuse a generic
.avatarcomponent.
3.8 Terminal page uses hardcoded dark-theme values
- File:
styles/utilities.css(terminal section, lines ~1200–1900) - Issue: Terminal colors (
#1e1e1e,#2d2d2d,#3e3e3e,#d4d4d4) are hardcoded and do not adapt to the light/dark theme tokens. This is acceptable for a terminal surface, but many spacing values (8px,4px,2px,16px) are also hardcoded. - Recommendation: Keep terminal colors as exceptions, but convert spacing to tokens for consistency.
4. Priority-Ranked Action List
P0 — Fix before any further mobile work
-
Add missing primitive styles (
global.css/utilities.css).mobile-detail-*full block.btn,.btn-primary,.btn-secondary,.btn-sm.link-button.checkbox-label.hint.form-error/.error-message.alert,.alert-error.loading-state.badge,.badge-success,.badge-secondary.form-input.mobile-list-search,.mobile-list-search-input.key-signing,.key-verification,.signature-result,.verify-result- Profile avatar classes (
.profile-avatar-section,.avatar-preview, etc.)
-
Unify mobile nav / FAB / bottom-sheet spacing
- Introduce
--mobile-nav-height: calc(64px + env(safe-area-inset-bottom, 0px)). - Update
.start-tool-fab,.mobile-edit-actions,.shell-content.mobile,.mobile-bottom-sheet, and.mobile-action-sheetto use it.
- Introduce
-
Fix critical accessibility issues
- Ensure all interactive controls meet
min-height: 44px; min-width: 44pxwithout distorting text inputs. - Add visible
:focusstates to.nav-item,.mobile-nav-item,.tab,.tree-entry,.button, and.form-field input. - Replace
font-size: 0.7reminline styles with--font-size-xs(or larger).
- Ensure all interactive controls meet
P1 — Tokenize and consolidate
-
Expand
tokens.css- Add
--space-7,--space-9,--space-12. - Add
--radius-sm: 6px,--radius-md: 10px,--radius-lg: 14px,--radius-xl: 16px,--radius-full: 999px. - Add
--line-height-tight,--line-height-normal,--line-height-relaxed. - Add
--shadow-sm,--shadow-md,--shadow-lg,--shadow-xl. - Add
--touch-target: 44pxand--sidebar-width: 280px.
- Add
-
Standardize breakpoints
- Replace
767px,768px,860pxwith--bp-sm,--bp-md,--bp-lg,--bp-xl. - Prefer mobile-first
min-widthqueries. - Remove the redundant
.shell-bodycollapse at860px.
- Replace
-
Refactor inline styles into utility classes
- Start with the highest-volume offenders:
manifest-editor.tsx,ConfigProfileEditorPanel.tsx,ToolTypeEditorPanel.tsx,ToolTypeListSidebar.tsx,ConfigProfileListSidebar.tsx,git-mount-editor.tsx. - Replace
style={{ display:"flex", gap:"0.5rem" }}with.row.row-smor.row.gap-smutilities.
- Start with the highest-volume offenders:
P2 — Merge duplicated systems
-
Merge
.form-fieldand.form-groupinto one component class with consistent vertical rhythm. -
Deprecate
.modal-overlay/.modal-contentin favor of.dialog-overlay/.dialogand migrate callers. -
Consolidate status badges/chips into a single
.status-badgefamily and reuse across sessions, instances, and workspaces. -
Consolidate card patterns across page CSS files into
global.cssmodifiers (.card-sm,.card-lg,.card-elevated).
P3 — Polish and documentation
-
Add design-system documentation comments at the top of
tokens.csslisting the spacing/type/radius/shadow scales and naming rules. -
Add a lint rule or code-review checklist to prevent new inline
style={{...}}layout declarations and undefined class names.
Summary of Files Most Likely to Need Changes
| File | Lines to review | Why |
|---|---|---|
apps/web/src/styles/tokens.css |
1–92 | Incomplete token scale; needs spacing, radius, line-height, shadow, touch-target, and nav tokens. |
apps/web/src/styles/global.css |
1–1206 | Many magic numbers, duplicate modal/dialog systems, missing primitive classes, inconsistent breakpoints. |
apps/web/src/styles/utilities.css |
1–3270 | Overly broad touch-target rules, undefined --text-xs, missing .mobile-detail-*, duplicated badge/status styles. |
apps/web/src/styles/pages/*.css |
all | Heavy duplication of card/grid patterns; should use shared utilities. |
apps/web/src/components/app-shell.tsx |
1–150 | Header/nav padding misalignment, mobile nav/FAB collision. |
apps/web/src/components/features/mobile/mobile-detail-view.tsx |
1–95 | Component references unstyled classes. |
apps/web/src/components/features/mobile/mobile-list-view.tsx |
1–115 | Search input unstyled. |
apps/web/src/components/features/tool/manifest-editor.tsx |
~70 inline styles | Highest-volume inline-style offender. |
apps/web/src/components/features/config-profiles/ConfigProfileEditorPanel.tsx |
~40 inline styles | Second-highest inline-style offender. |
apps/web/src/components/features/tool-workshop/ToolTypeEditorPanel.tsx |
~20 inline styles | Third-highest offender. |
apps/web/src/components/features/tool-workshop/ToolTypeListSidebar.tsx |
1–150 | Hardcoded 280 px sidebar; inline styles. |
apps/web/src/components/features/config-profiles/ConfigProfileListSidebar.tsx |
1–160 | Hardcoded 280 px sidebar; inline styles. |
apps/web/src/components/features/git/git-mount-editor.tsx |
Many inline styles | Complex mount editor with inline flex/gap/padding. |
apps/web/src/components/features/ssh-keys/SSHKeyList.tsx |
1–180 | Signing/verification sections have no CSS. |
apps/web/src/pages/ProfilePage.tsx |
130–180 | Desktop profile card uses unstyled avatar classes. |
apps/web/src/pages/WorkspacesPage.tsx |
90–110 | Uses .alert alert-error and .loading-state without styles. |
End of audit. No code changes were made; this is an analysis-only report.