- Total findings: 1 issue across 1 file
- By severity: 0 critical, 0 high, 0 medium, 1 warning (low severity)
{
"antipattern": "design-system-font",
"name": "Font outside DESIGN.md",
"description": "A font is used that is not declared in DESIGN.md typography",
"severity": "warning",
"category": "quality",
"file": "src/components/DashboardPage.tsx",
"line": 312,
"snippet": "fontFamily: Cascadia Code is not declared in DESIGN.md typography",
"ignoreValue": "Cascadia Code"
}- design-system-font (1 occurrence)
- Location:
src/components/DashboardPage.tsx, line 312 - Issue: Inline style uses
fontFamily: 'Cascadia Code, Consolas, monospace'which is not documented in DESIGN.md - Context: Used in a URI/URL search input field in the Dashboard page for monospace display
- Severity: Warning (design system consistency)
- Location:
- src/components/DashboardPage.tsx:312 — Cascadia Code font used in URI lookup input field
- Dev Server: Running on http://localhost:4321/workbench/
- Testing Method: CSS analysis, DOM inspection, contrast ratio calculation, responsive breakpoint review
- Color System Verified: Light and dark mode configurations
| Element | Foreground | Background | Ratio | WCAG AA | Issue |
|---|---|---|---|---|---|
| Green text (links) | #009485 | #ffffff | 3.77 | ✗ FAIL | Green on white — 0.73 below threshold (needs 4.5) |
| Green text (links) | #009485 | #fafafa | 3.61 | ✗ FAIL | Green on light gray — 0.89 below threshold |
| White on green (buttons) | #ffffff | #009485 | 3.77 | ✗ FAIL | Insufficient contrast for button text on green bg |
| Neutral on green | #424242 | #009485 | 2.67 | ✗ FAIL | Gray text on green — severe contrast issue |
| Green on light green | #009485 | #d9f7f3 | 3.33 | ✗ FAIL | Green text on light green bg (badge/highlight) |
| Element | Foreground | Background | Ratio | WCAG AA |
|---|---|---|---|---|
| Primary text | #242424 | #ffffff | 15.52 | ✓ AA |
| Secondary text | #424242 | #ffffff | 10.05 | ✓ AA |
| Tertiary text | #616161 | #ffffff | 6.19 | ✓ AA |
| Neutral on light green | #242424 | #d9f7f3 | 13.71 | ✓ AA |
| Element | Foreground | Background | Ratio | WCAG AA | Issue |
|---|---|---|---|---|---|
| Light-gray on dark green | #d6d6d6 | #4db8ad | 1.65 | ✗ FAIL | Severe contrast failure when green text is overlaid on dark backgrounds |
| Element | Foreground | Background | Ratio | WCAG AA |
|---|---|---|---|---|
| White text on dark | #ffffff | #1f1f1f | 16.48 | ✓ AA |
| Light gray on dark | #d6d6d6 | #1f1f1f | 11.34 | ✓ AA |
| Medium gray on dark | #adadad | #1f1f1f | 7.34 | ✓ AA |
| Green text on dark | #4db8ad | #1f1f1f | 6.89 | ✓ AA |
| Green text on dark gray | #4db8ad | #292929 | 6.08 | ✓ AA |
| Black on green | #000000 | #4db8ad | 8.78 | ✓ AA |
Critical Observation: Green color (#009485) in light mode does NOT meet WCAG AA for text on white/light backgrounds. Green achieves AA only when used as a background with white/light text, or in dark mode on dark backgrounds.
- Limited Focus Ring Coverage: Only one explicit focus style found in CSS (
.skip-to-content:focus). Remaining focus behavior relies entirely on Fluent UI components' default focus rings. - Fluent UI Default Focus: The components use Fluent UI's built-in focus behavior, which typically includes visible focus rings on buttons, inputs, and interactive elements. This is generally acceptable but not explicitly styled in the project CSS.
- Keyboard Support: Strong — verified in components:
GlobalSearch.tsxdefines FOCUSABLE selector and keyboard event handlers (onKeyDown)- Arrow key navigation (↑↓) implemented in app list
- Escape key closes overlays
- Ctrl+K triggers global search
/focuses search inputftoggles favorites?shows keyboard shortcuts
Keyboard Navigation Status: ✓ PASS — All documented shortcuts appear to be implemented with proper event handlers.
- 767px and below (mobile): Sidebar becomes overlay, padding reduced, fonts scale down
- 600px and below (small mobile): Additional adjustments for tight layouts
- 480px and below (small phone): Extra spacing/sizing tweaks
- 1024px and below (tablet): Sidebar width reduced from 320px to 260px
- Mobile Sidebar: Properly implemented as fixed overlay with
transform: translateX(-100%)animation. Shadow applied correctly (2px 0 12px rgba(0, 0, 0, 0.2)). - Text Truncation: Extensive use of
text-overflow: ellipsiswithoverflow: hiddenandwhite-space: nowrapto prevent content overflow (34 instances in CSS). - No Observed Layout Breakage: CSS media queries follow best practices with:
- Reduced padding on mobile
- Font size scaling (13px from 14px headers)
- Full-width main content on mobile
- Proper gap/spacing adjustments
Responsive Status: ✓ PASS — Breakpoints and responsive behavior appear well-designed.
- Hover on list items:
background: var(--colorBrandBackground2)(#d9f7f3 — light green) ✓ Clear - Active list item:
background: #009485(green) +color: white✓ Clear - Button hover: Color darkens from #009485 → #008575 ✓ Clear
- Button pressed: Color darkens to #016e61 ✓ Clear
- Link hover: Green text, may include underline (not explicitly styled but browser default applies)
- Favorite star visibility: Hidden by default, appears on
item:hover✓ Good UX
- Hover/active states: Green shifts to #4db8ad, with appropriate darkening for pressed state
- Contrast maintained: Dark mode state changes are visible (though light-gray text on green bg has low contrast — see contrast section)
State Visibility Status: ✓ PASS — Hover and active states are clear and intentional. Focus states rely on Fluent UI defaults.
✓ Properly inverted:
- Light backgrounds (#ffffff, #fafafa, #f0f0f0) → Dark backgrounds (#1f1f1f, #292929, #333333)
- Dark text (#242424, #424242, #616161) → Light text (#ffffff, #d6d6d6, #adadad)
- Green (#009485) → Adjusted to #4db8ad for better readability on dark backgrounds
- RSS orange (#C55A11) → Lightened to #E07A3A for dark mode
✓ Contrast is generally better in dark mode:
- Primary text: 16.48 ratio (vs. 15.52 in light mode)
- Green text: 6.89 ratio (vs. 3.77 in light mode — FAIL)
- Secondary text: 11.34 ratio (vs. 10.05 in light mode)
⚠ Light gray text on green background (#d6d6d6 on #4db8ad): 1.65 ratio — severely fails WCAG. This occurs when secondary text is displayed on green backgrounds in dark mode (e.g., active app list items with secondary text).
Dark Mode Status: Mostly ✓ PASS, with one contrast violation on secondary text over green.
✓ Found and working:
role="option"on app list items in sidebararia-selectedon active list itemsaria-labelon buttons and inputs (e.g., "Search by download URL", "Clear")aria-haspopup="listbox"on filter dropdown buttons
⚠ Potential gaps:
- No explicit
<label>elements for form inputs (relying onaria-labelinstead) - No
role="listbox"on the app list container (has items withrole="option"but no parent role) - Global search overlay doesn't explicitly expose role (should be
role="dialog"or similar)
Not performed (browser rendering only), but based on code review:
- App list navigation should be announced as options in an option group
- Search results should be announced to screen readers
- Button purposes are clearly labeled with
aria-label
Accessibility Status: ⚠ PARTIAL — Core functionality labeled, but some semantic structure gaps (missing dialog roles, listbox container roles, and form label associations).
✓ Correct: 'Segoe UI', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Arial, sans-serif (matches DESIGN.md)
✓ Verified:
- Body text: 14px (--font-size-300)
- Labels/small: 12px (--font-size-200)
- Headers: 16px (--font-size-400)
✓ Adequate: 1.4 line height for body; 1.25 for headlines
✓ PASS — No text is smaller than 12px; 14px body text is comfortable for screen reading.
✓ Service worker configured and manifest present ✓ Theme color meta tag matches Evergreen green (#009485) ✓ Initial theme paint prevention script avoids flash (checks localStorage for saved theme) ✓ Skip-to-content link properly positioned off-screen and focusable
Finding: Font outside DESIGN.md (Cascadia Code)
Analysis:
- Is it a false positive? No, this is a valid finding.
- Is it an actual issue? Borderline.
- The font is used only in a URI/URL input field in the Dashboard (line 312 of DashboardPage.tsx)
- It's intentional — monospace fonts are appropriate for displaying URIs and paths
- However, DESIGN.md does NOT document a monospace font family for such use cases
- Recommendation: Either (a) add a documented monospace font token to DESIGN.md (e.g.,
fontFamily-mono), or (b) use a system monospace fallback stack (which Cascadia Code already does withCascadia Code, Consolas, monospace)
- ✓ Server startup: Successful (dev server on port 4321)
- ✓ Page loads: Confirmed via curl
- ✗ Interactive testing (clicks, keyboard nav, mobile viewport emulation): Not performed
- Reason: CLI-only environment; no browser/headless browser available for visual testing
- Mitigation: Analyzed CSS, DOM structure, keyboard event handlers, and responsive design rules statically
- Confidence: High for layout and contrast analysis; medium for real-time interactive behavior
- ✓ Static accessibility review: CSS/HTML/component structure analyzed
- ✗ Automated accessibility scanner (axe, Wave, Lighthouse): Not run
- ✗ Screen reader testing: Not performed
- Solid keyboard navigation — Shortcuts well-implemented
- Good responsive design — Mobile and tablet breakpoints configured correctly
- Dark mode parity — Colors properly inverted with thoughtful adjustments
- High-contrast text — Primary, secondary, tertiary text all pass WCAG AA on their default backgrounds
- Clear state feedback — Hover, active, and pressed states are visible
-
Green color fails WCAG AA for light-mode text
- #009485 on white (#ffffff): 3.77 ratio (fails; needs 4.5)
- #009485 on light gray (#fafafa): 3.61 ratio (fails)
- Impact: Links, button text, and UI labels in green may be unreadable for users with color vision deficiency
- Fix: Use green as background only (with white/light text), or choose a darker green for text contrast
-
Light gray text on green fails WCAG AAA in dark mode
- #d6d6d6 on #4db8ad: 1.65 ratio (critical)
- Impact: Secondary text on active/highlighted green elements is nearly invisible in dark mode
- Fix: Use white or lighter text on green; OR avoid green backgrounds in dark mode for non-primary-action elements
-
Missing semantic roles for compound widgets
- App list lacks
role="listbox"container - Global search overlay lacks
role="dialog" - Impact: Screen reader users may not understand component structure
- Fix: Add explicit ARIA roles to main structural components
- App list lacks
- Cascadia Code font not documented — Add to DESIGN.md or use system monospace fallback
- Form inputs use aria-label instead of — Consider adding visible/associated labels
- Focus indicators rely on Fluent UI defaults — No custom focus styling; verify Fluent UI provides adequate rings
- Detector findings: 1 warning (low severity, documented above)
- Responsive design: Well-implemented
- Keyboard navigation: Comprehensive
- Typography: Meets DESIGN.md and accessibility standards
src/components/DashboardPage.tsx(detector hit + contrast analysis)src/components/GlobalSearch.tsx(accessibility, keyboard nav)src/components/AppsSidebar.tsx(semantic roles, list structure)src/components/AppDetails.tsx(table structure, filters)src/styles/global.css(all styling, colors, responsive design)DESIGN.md(design system consistency)