Skip to main content

๐ŸŽจ 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โ€‹

TokenHexPurpose
background#0A0B0CApp-level base canvas
surfacePrimary#111315Cards, sheets, modals
surfaceSecondary#17191CNested containers
surfaceTertiary#222225Subtle elevation distinctions

Labels (text)โ€‹

TokenHexContrast on backgroundPurpose
labelPrimary#FBFAF6~18:1High-emphasis โ€” headings, primary body (warm paper white)
labelSecondary#A1A1AA8.2:1Medium-emphasis โ€” descriptions
labelTertiary#71717A4.7:1Low-emphasis โ€” captions, timestamps
labelQuaternary#5A5A5E3.4:1Disabled / placeholder โ€” passes WCAG 1.4.11

Brandโ€‹

TokenHexPurpose
tintPrimary#CCFF00Primary accent (lime green)
tintPrimaryDimmed12% opacityBackgrounds behind tinted text

Functionalโ€‹

TokenPurpose
success / successDimmedCompleted states
warning / warningDimmedAttention states
error / errorDimmedErrors, failures
info / infoDimmedInformational 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.

StyleSizeWeightUse for
largeTitle34pxBoldSection headers, onboarding
title128pxBoldScreen titles
title222pxBoldCard headings
title320pxSemiboldSub-sections
headline17pxSemiboldList item titles
body17pxRegularBody text (default)
callout16pxRegularCallout blocks
subheadline15pxRegularSecondary descriptions
footnote13pxRegularTimestamps, captions
caption112pxRegularBadges, metadata
caption211pxRegularFine 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โ€‹

TokenpxUse for
xs4Tight inline gaps
sm8Base unit, small gaps
smd12Dense content padding
md16Default content padding
mdl20Generous card interiors
lg24Section spacing
xl32Large separations
xxl48Major layout divisions
xxxl64Hero sections

Convenience EdgeInsetsโ€‹

ConstantValueUse for
AceSpacing.pagePadding24pt allScreen-level padding
AceSpacing.cardPadding16pt allCard interiors
AceSpacing.listItemPadding16h ร— 12vList items

Border radiiโ€‹

TokenpxUse for
AceRadius.sm8Chips, tags
AceRadius.md12Buttons, text fields
AceRadius.lg16Cards, surfaces
AceRadius.xl20Dialogs, modals
AceRadius.full999Pill badges

Key sizesโ€‹

ConstantpxNotes
AceSizes.buttonHeight50Primary actions
AceSizes.minTouchTarget44Apple HIG minimum
AceSizes.sidebarWidth260Desktop expanded
AceSizes.maxContentWidth1200Readable line length

๐ŸŽฌ Motionโ€‹

lib/theme/motion.dart โ†’ AceMotion.

TokenDurationCurveUse for
fast200mseaseOutTaps, toggles, micro-interactions
normal350mseaseInOutPage transitions, reveals
slow500mseaseInOutLayout 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>.

ComponentFilePurpose
AceButtonace_button.dartPrimary/secondary/ghost/danger buttons with loading state
AceCardace_card.dartSurface container with optional onTap
AceChipace_chip.dartTags, filters, status badges
AceTabBarace_tab_bar.dartSegmented control / top tabs
AceTextFieldace_text_field.dartInput with label, error, autofill hints
AceBottomSheetace_bottom_sheet.dartModal sheet with drag handle
AceDialogace_dialog.dartConfirmation dialogs with primary/secondary actions
AceBadgeace_badge.dartSmall status indicators (e.g., "SAMPLE DATA")
AceEmptyStateace_empty_state.dartPlaceholder for screens with no data
AceListTileace_list_tile.dartConsistent list items with leading/trailing
AceNavBarace_nav_bar.dartBottom navigation bar
AceSidebarace_sidebar.dartResponsive sidebar for desktop/tablet
AceSkeletonace_skeleton.dartLoading shimmer placeholders
AceAnimatedListItemace_animated_list_item.dartStaggered fade+slide list animation

When to use whatโ€‹

ScenarioComponent
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 dashboardAceCard with child content
Confirmation ("Are you sure?")AceDialog.show(context, ...)
Empty dashboardAceEmptyState(icon: ..., message: ...)
Loading placeholderAceSkeleton(width: 200, height: 20)

โ™ฟ Accessibilityโ€‹

The April 2026 UX audit brought the app to WCAG AA compliance:

  • All interactive elements have Semantics wrappers
  • Error messages use liveRegion: true for screen readers
  • Text fields include autofillHints for OS-level form autofill
  • Minimum touch targets are 44pt (AceSizes.minTouchTarget)
  • labelQuaternary was 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โ€‹