diff --git a/docs/superpowers/specs/audit-findings.md b/docs/superpowers/specs/audit-findings.md index 94f566f..11c1d08 100644 --- a/docs/superpowers/specs/audit-findings.md +++ b/docs/superpowers/specs/audit-findings.md @@ -1,8 +1,8 @@ # UI Audit Findings Report **Date:** 2026-03-11 -**Total findings:** 913 -**High:** 64 | **Medium:** 663 | **Low:** 186 +**Total findings:** 806 +**High:** 64 | **Medium:** 594 | **Low:** 148 --- @@ -13,20 +13,19 @@ | High | Token/Styling | Hardcoded color | 37 | | High | Token/Styling | Primitive token leakage | 5 | | High | Convention | Inline style | 22 | -| Medium | Token/Styling | Hardcoded transition | 71 | -| Medium | Token/Styling | Hardcoded spacing | 98 | +| Medium | Token/Styling | Hardcoded transition | 11 | +| Medium | Token/Styling | Hardcoded spacing | 91 | | Medium | Token/Styling | Hardcoded box-shadow | 26 | | Medium | Token/Styling | Hardcoded radius | 3 | | Medium | Token/Styling | Missing theme coverage | 315 | | Medium | Token/Styling | Missing IDE alias | 33 | | Medium | Performance | Inline function prop | 25 | | Medium | Performance | Missing memo | 81 | -| Medium | Performance | Inline array prop | 1 | -| Medium | Accessibility | Missing keyboard handler | 9 | +| Medium | Accessibility | Missing keyboard handler | 8 | | Medium | Accessibility | Missing ARIA | 1 | -| Low | Token/Styling | Hardcoded opacity | 114 | -| Low | Token/Styling | Hardcoded font-size | 21 | -| Low | Token/Styling | Hardcoded z-index | 32 | +| Low | Token/Styling | Hardcoded opacity | 96 | +| Low | Token/Styling | Hardcoded z-index | 18 | +| Low | Token/Styling | Hardcoded font-size | 15 | | Low | Convention | Large component file | 19 | --- @@ -38,1084 +37,1206 @@ **37 finding(s)** - `packages/base-ui/src/components/avatar/Avatar.module.css:107` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #0b8f5a; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:108` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #f5fbf9; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:112` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #1f7ae0; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:113` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #f4f8ff; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:117` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #7e57c2; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:118` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #f6f1ff; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:122` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #d56a1f; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:123` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #1a0e04; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:127` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #c94153; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:128` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #fff1f3; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:132` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #137c8b; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:133` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #ebfbff; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:137` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #556274; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:138` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #f4f7ff; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:142` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #3f9153; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:143` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #f1fff5; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:147` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #9a5a2d; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:148` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #fff5ec; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:152` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #2f5bbb; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:153` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #eff3ff; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:157` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #7f4458; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:158` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #fff2f8; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:162` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-bg: #49508f; ``` + - `packages/base-ui/src/components/avatar/Avatar.module.css:163` — Hex color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-fallback-fg: #f0f2ff; ``` + - `packages/base-ui/src/components/card/Card.module.css:22` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css --_card-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.08), 0 1px 4px rgb(0 0 0 / 0.06); ``` + - `packages/base-ui/src/components/card/Card.module.css:24` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css --_card-shadow-lg: 0 4px 12px rgb(0 0 0 / 0.14), 0 2px 6px rgb(0 0 0 / 0.10); ``` + - `packages/base-ui/src/components/data-table/DataTable.module.css:27` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css --_ov-dt-pinned-shadow: rgb(0 0 0 / 0.12); ``` + - `packages/base-ui/src/components/editor-tabs/EditorTabs.module.css:5` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css --_shadow-drag: 0 2px 8px rgb(0 0 0 / 0.25); ``` + - `packages/base-ui/src/components/editor-tabs/EditorTabs.module.css:6` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css --_shadow-ghost: 0 4px 16px rgb(0 0 0 / 0.3); ``` + - `packages/base-ui/src/components/sheet/Sheet.module.css:9` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css --_sheet-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.08), 0 1px 4px rgb(0 0 0 / 0.06); /* TODO: replace with --ov-shadow-surface- ``` + - `packages/base-ui/src/components/sheet/Sheet.module.css:11` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css --_sheet-shadow-lg: 0 4px 12px rgb(0 0 0 / 0.14), 0 2px 6px rgb(0 0 0 / 0.10); /* TODO: replace with --ov-shadow-surface ``` + - `packages/base-ui/src/components/slider/Slider.module.css:193` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css 0 0 0 1px rgb(0 0 0 / 0.08), ``` + - `packages/base-ui/src/components/slider/Slider.module.css:194` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css 0 1px 3px rgb(0 0 0 / 0.24); ``` + - `packages/base-ui/src/components/switch/Switch.module.css:144` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css 0 0 0 1px rgb(0 0 0 / 0.06), ``` + - `packages/base-ui/src/components/switch/Switch.module.css:145` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + + ```css 0 1px 2px rgb(0 0 0 / 0.28); ``` -- `packages/base-ui/src/components/toast/Toast.module.css:59` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + +- `packages/base-ui/src/components/toast/Toast.module.css:60` — rgb/hsl color found — use a semantic token (--ov-color-*) + + ```css --_toast-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.08), 0 1px 4px rgb(0 0 0 / 0.06); ``` -- `packages/base-ui/src/components/toast/Toast.module.css:61` — rgb/hsl color found — use a semantic token (--ov-color-*) - ``` + +- `packages/base-ui/src/components/toast/Toast.module.css:62` — rgb/hsl color found — use a semantic token (--ov-color-*) + + ```css --_toast-shadow-lg: 0 4px 12px rgb(0 0 0 / 0.14), 0 2px 6px rgb(0 0 0 / 0.10); ``` + ### High: Primitive token leakage (Token/Styling) **5 finding(s)** - `packages/base-ui/src/components/grid/Grid.module.css:60` — Primitive token used directly — use a semantic token instead - ``` + + ```css --_ov-spacing: 4px; /* --ov-primitive-space-1; no --ov-space-stack-xs semantic token */ ``` + - `packages/base-ui/src/components/grid/Grid.module.css:78` — Primitive token used directly — use a semantic token instead - ``` + + ```css row-gap: 4px; /* --ov-primitive-space-1; no --ov-space-stack-xs semantic token */ ``` + - `packages/base-ui/src/components/grid/Grid.module.css:96` — Primitive token used directly — use a semantic token instead - ``` + + ```css column-gap: 4px; /* --ov-primitive-space-1; no --ov-space-stack-xs semantic token */ ``` + - `packages/base-ui/src/components/image/Image.module.css:36` — Primitive token used directly — use a semantic token instead - ``` + + ```css --_ov-radius: 4px; /* --ov-primitive-radius-sm; no --ov-radius-sm semantic token (closest: --ov-radius-control at 6px) * ``` + - `packages/base-ui/src/components/tag-input/TagInput.module.css:4` — Primitive token used directly — use a semantic token instead - ``` + + ```css --_ov-gap: var(--ov-space-stack-xs, var(--ov-primitive-space-1)); /* no --ov-space-stack-xs semantic token yet */ ``` + ### High: Inline style (Convention) **22 finding(s)** - `packages/ai-ui/src/components/chat/ChatMessageList.tsx:130` — style={{}} found — use CSS Modules + data attributes - ``` + + ```tsx style={{ height: `${virtualizer.getTotalSize()}px` }} // eslint-disable-line react/forbid-component-props -- required by ``` + - `packages/ai-ui/src/components/chat/ChatMessageList.tsx:138` — style={{}} found — use CSS Modules + data attributes - ``` + + ```tsx style={{ // eslint-disable-line react/forbid-component-props -- required by virtualizer ``` + - `packages/ai-ui/src/components/content/AIImageGeneration.tsx:37` — style={{}} found — use CSS Modules + data attributes - ``` + + ```tsx style={{ '--_image-aspect-ratio': aspectRatio } as CSSProperties} ``` + - `packages/base-ui/src/components/aspect-ratio/AspectRatio.tsx:17` — style={{}} found — use CSS Modules + data attributes - ``` + + ```tsx style={{ '--_aspect-ratio': ratio, ...style } as CSSProperties} ``` + - `packages/base-ui/src/components/command-list/CommandList.tsx:315` — style={{}} found — use CSS Modules + data attributes - ``` + + ```tsx