๐จ Frontend Design System
Semantic tokens, Ace components, and the rules that keep the UI consistent.
:::tip TL;DR
- Design tokens in
lib/theme/(colors, typography, spacing, motion, icons) โ never use raw hex values - 17 Ace components in
lib/components/โ buttons, cards, chips, text fields, nav, dialogs (incl. AI/region consent), password sheets, etc. - Apple HIG-inspired with a dark-first, lime-green brand identity
- WCAG AA compliant โ all interactive elements pass 3:1 non-text contrast minimum :::
๐จ Color Tokensโ
All colors live in lib/theme/colors.dart โ AceColors.
Backgroundsโ
| Token | Hex | Purpose |
|---|---|---|
background | #0A0B0C | App-level base canvas |
surfacePrimary | #111315 | Cards, sheets, modals |
surfaceSecondary | #17191C | Nested containers |
surfaceTertiary | #222225 | Subtle elevation distinctions |
Labels (text)โ
| Token | Hex | Contrast on background | Purpose |
|---|---|---|---|
labelPrimary | #FBFAF6 | ~18:1 | High-emphasis โ headings, primary body (warm paper white) |
labelSecondary | #A1A1AA | 8.2:1 | Medium-emphasis โ descriptions |
labelTertiary | #71717A | 4.7:1 | Low-emphasis โ captions, timestamps |
labelQuaternary | #5A5A5E | 3.4:1 | Disabled / placeholder โ passes WCAG 1.4.11 |
Brandโ
| Token | Hex | Purpose |
|---|---|---|
tintPrimary | #CCFF00 | Primary accent (lime green) |
tintPrimaryDimmed | 12% opacity | Backgrounds behind tinted text |
Functionalโ
| Token | Purpose |
|---|---|
success / successDimmed | Completed states |
warning / warningDimmed | Attention states |
error / errorDimmed | Errors, failures |
info / infoDimmed | Informational callouts |
:::warning Never use raw hex
Write AceColors.labelSecondary, not Color(0xFFA1A1AA). Raw values defeat the token system and make rebranding a nightmare.
:::
๐ค Typographyโ
lib/theme/typography.dart โ AceTypography. Inter Tight (bundled at assets/fonts/InterTight.ttf) for UI text and JetBrains Mono for monospace โ no google_fonts dependency. Apple HIG naming.
| Style | Size | Weight | Use for |
|---|---|---|---|
largeTitle | 34px | Bold | Section headers, onboarding |
title1 | 28px | Bold | Screen titles |
title2 | 22px | Bold | Card headings |
title3 | 20px | Semibold | Sub-sections |
headline | 17px | Semibold | List item titles |
body | 17px | Regular | Body text (default) |
callout | 16px | Regular | Callout blocks |
subheadline | 15px | Regular | Secondary descriptions |
footnote | 13px | Regular | Timestamps, captions |
caption1 | 12px | Regular | Badges, metadata |
caption2 | 11px | Regular | Fine print |
Usage:
Text('Session Summary', style: AceTypography.title2);
Text('Last played 3 days ago', style: AceTypography.footnote.copyWith(color: AceColors.labelTertiary));
๐ Spacing & Sizingโ
lib/theme/spacing.dart โ AceSpacing, AceRadius, AceSizes.
8pt gridโ
| Token | px | Use for |
|---|---|---|
xs | 4 | Tight inline gaps |
sm | 8 | Base unit, small gaps |
smd | 12 | Dense content padding |
md | 16 | Default content padding |
mdl | 20 | Generous card interiors |
lg | 24 | Section spacing |
xl | 32 | Large separations |
xxl | 48 | Major layout divisions |
xxxl | 64 | Hero sections |
Convenience EdgeInsetsโ
| Constant | Value | Use for |
|---|---|---|
AceSpacing.pagePadding | 24pt all | Screen-level padding |
AceSpacing.cardPadding | 16pt all | Card interiors |
AceSpacing.listItemPadding | 16h ร 12v | List items |
Border radiiโ
| Token | px | Use for |
|---|---|---|
AceRadius.sm | 8 | Chips, tags |
AceRadius.md | 12 | Buttons, text fields |
AceRadius.lg | 16 | Cards, surfaces |
AceRadius.xl | 20 | Dialogs, modals |
AceRadius.full | 999 | Pill badges |
Key sizesโ
| Constant | px | Notes |
|---|---|---|
AceSizes.buttonHeight | 50 | Primary actions |
AceSizes.minTouchTarget | 44 | Apple HIG minimum |
AceSizes.sidebarWidth | 260 | Desktop expanded |
AceSizes.maxContentWidth | 1200 | Readable line length |
๐ฌ Motionโ
lib/theme/motion.dart โ AceMotion.
| Token | Duration | Curve | Use for |
|---|---|---|---|
fast | 200ms | easeOut | Taps, toggles, micro-interactions |
normal | 350ms | easeInOut | Page transitions, reveals |
slow | 500ms | easeInOut | Layout shifts, drag completions |
All page transitions use AcePageRoute which applies an iOS-style right-to-left slide with AceMotion.normal duration.
๐งฉ Ace Component Libraryโ
14 components in lib/components/. All follow the naming convention Ace<Name>.
| Component | File | Purpose |
|---|---|---|
AceButton | ace_button.dart | Primary/secondary/ghost/danger buttons with loading state |
AceCard | ace_card.dart | Surface container with optional onTap |
AceChip | ace_chip.dart | Tags, filters, status badges |
AceTabBar | ace_tab_bar.dart | Segmented control / top tabs |
AceTextField | ace_text_field.dart | Input with label, error, autofill hints |
AceBottomSheet | ace_bottom_sheet.dart | Modal sheet with drag handle |
AceDialog | ace_dialog.dart | Confirmation dialogs with primary/secondary actions |
AceBadge | ace_badge.dart | Small status indicators (e.g., "SAMPLE DATA") |
AceEmptyState | ace_empty_state.dart | Placeholder for screens with no data |
AceListTile | ace_list_tile.dart | Consistent list items with leading/trailing |
AceNavBar | ace_nav_bar.dart | Bottom navigation bar |
AceSidebar | ace_sidebar.dart | Responsive sidebar for desktop/tablet |
AceSkeleton | ace_skeleton.dart | Loading shimmer placeholders |
AceAnimatedListItem | ace_animated_list_item.dart | Staggered fade+slide list animation |
When to use whatโ
| Scenario | Component |
|---|---|
| Primary CTA ("Upload", "Analyze") | AceButton(variant: AceButtonVariant.primary) |
| Destructive action ("Delete session") | AceButton(variant: AceButtonVariant.danger) |
| Filter toggle ("Forehand", "Backhand") | AceChip |
| Data card on the dashboard | AceCard with child content |
| Confirmation ("Are you sure?") | AceDialog.show(context, ...) |
| Empty dashboard | AceEmptyState(icon: ..., message: ...) |
| Loading placeholder | AceSkeleton(width: 200, height: 20) |
โฟ Accessibilityโ
The April 2026 UX audit brought the app to WCAG AA compliance:
- All interactive elements have
Semanticswrappers - Error messages use
liveRegion: truefor screen readers - Text fields include
autofillHintsfor OS-level form autofill - Minimum touch targets are 44pt (
AceSizes.minTouchTarget) labelQuaternarywas raised from 2.4:1 to 3.4:1 contrast to pass WCAG 1.4.11- Focus indicators present on all interactive components
๐ฏ Next Stepsโ
- ๐ฑ Frontend Overview โ architecture and screen map
- ๐ง Frontend Setup โ get it running locally
- ๐จ Designs โ Figma assets and brand guidelines