Skip to main content

Design Tokens

Design tokens are the foundational design decisions that create consistency across the BookWish interface. These values should be used throughout the codebase to maintain visual harmony.

Spacing Scale

BookWish uses an 8-point grid system for spacing. All spacing values should be multiples of 8 to maintain consistent rhythm and alignment.

Base Scale

TokenValueUsage
space-18pxTight spacing, inline elements
space-216pxDefault component padding, small gaps
space-324pxSection spacing, medium gaps
space-432pxLarge spacing, page margins
space-540pxExtra large spacing
space-648pxSection dividers
space-864pxPage-level spacing

Common Spacing Patterns

Vertical Spacing:

// Between form fields
const SizedBox(height: 16) // space-2

// Between sections
const SizedBox(height: 24) // space-3

// Empty state padding
padding: const EdgeInsets.all(32) // space-4

// Bottom navigation bar
bottom: 100 // custom for Browser overlay

Horizontal Spacing:

// Icon and text spacing
const SizedBox(width: 8) // space-1

// Between inline elements
const SizedBox(width: 12) // space-1.5

// Card margins
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8)

Component Padding:

// Button padding (internal)
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16)

// Card content padding
padding: const EdgeInsets.all(16)

// Speech bubble padding
padding: const EdgeInsets.all(16)

// List tile padding
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8)

Responsive Spacing

For web and tablet layouts, consider scaling up spacing:

BreakpointScale FactorExample
Mobile1x16px → 16px
Tablet1.25x16px → 20px
Desktop1.5x16px → 24px

Border Radius

Consistent corner rounding creates a cohesive, friendly aesthetic.

Radius Scale

TokenValueUsage
radius-xs4pxSmall chips, badges
radius-sm8pxSmall elements, speech bubbles, icons
radius-md12pxCards, inputs, list tiles, dialogs
radius-lg16pxLarge cards, overlays, sheets
radius-xl24pxButtons, pills
radius-full40-50%Circular avatars, icon buttons

Implementation Examples

// Input fields
borderRadius: BorderRadius.circular(12) // radius-md

// Primary buttons
borderRadius: BorderRadius.circular(24) // radius-xl

// Cards
borderRadius: BorderRadius.circular(12) // radius-md

// Browser speech bubble
borderRadius: BorderRadius.circular(16) // radius-lg

// Snackbars
borderRadius: BorderRadius.circular(8) // radius-sm

// Avatar (circular)
borderRadius: BorderRadius.circular(40) // radius-full

// Sheet top corners
borderRadius: const BorderRadius.vertical(
top: Radius.circular(16) // radius-lg
)

When to Use Each Radius

  • 4px (xs): Tiny elements, status badges, inline chips
  • 8px (sm): Small containers, tags, minor elements
  • 12px (md): Standard cards, inputs, list items (most common)
  • 16px (lg): Modal sheets, large containers, overlays
  • 24px (xl): Buttons, pill-shaped elements
  • Circular: Avatars, icon buttons, floating action buttons

Shadows & Elevation

Shadows create depth and hierarchy in the interface. BookWish uses subtle shadows for a clean, modern look.

Elevation Scale

LevelElevationUsageShadow
0NoneButtons, inline elementselevation: 0
1LowPressed statesLight shadow
2MediumCards, tileselevation: 2
4HighDropdowns, dialogselevation: 4
8NavigationBottom nav, app barelevation: 8
16ModalSheets, overlaysCustom shadow

Shadow Implementation

Card Shadow (elevation 2):

CardThemeData(
elevation: 2,
shadowColor: AppColors.inkBlue.withValues(alpha: 0.08),
)

Browser Speech Bubble Shadow:

BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 8,
offset: const Offset(0, 4),
)

Bottom Navigation Shadow (elevation 8):

BottomNavigationBarThemeData(
elevation: 8,
)

Custom Box Shadow:

// Subtle depth
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.1),
blurRadius: 8,
offset: const Offset(0, 4),
),
]

// More pronounced
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.15),
blurRadius: 16,
offset: const Offset(0, 8),
),
]

Shadow Guidelines

  • Use sparingly - too many shadows create visual clutter
  • Keep alpha values low (0.05 - 0.15) for subtlety
  • Offset shadows downward (positive Y) for realism
  • Blur radius typically 2x the offset distance
  • Consider removing shadows on mobile for performance

Z-Index Scale

Z-index controls stacking order of elements. While Flutter uses different layering mechanisms, this provides a mental model.

Layer Hierarchy

LayerZ-IndexUsage
Base0Page content
Elevated1Cards, tiles
Dropdown10Dropdowns, popovers
Sticky50Sticky headers, floating buttons
Overlay100Modals, sheets
Browser150Browser the Cat overlay
Toast200Snackbars, toasts
Tooltip300Tooltips

Flutter Implementation

Flutter uses widget tree order and Stack for layering:

// Browser overlay appears above main content
Stack(
children: [
// Base content (z: 0)
MainContent(),

// Browser overlay (z: 150)
Positioned(
bottom: 100,
child: BrowserOverlay(),
),
],
)

Breakpoints

Breakpoints define responsive behavior across device sizes.

Screen Size Breakpoints

BreakpointMin WidthMax WidthUsage
Mobile Small0374pxSmall phones
Mobile375px767pxStandard phones
Tablet768px1023pxTablets, small laptops
Desktop1024px1439pxLaptops, desktops
Wide1440px+-Large desktops

Implementation

// Get screen width
final screenWidth = MediaQuery.of(context).size.width;

// Responsive layout
Widget build(BuildContext context) {
if (screenWidth < 768) {
return MobileLayout();
} else if (screenWidth < 1024) {
return TabletLayout();
} else {
return DesktopLayout();
}
}

// Responsive padding
final horizontalPadding = screenWidth < 768 ? 16.0 : 32.0;

Responsive Patterns

Content Width:

  • Mobile: Full width with 16px margins
  • Tablet: Max 768px centered
  • Desktop: Max 1200px centered

Column Layouts:

  • Mobile: Single column
  • Tablet: 2 columns for cards
  • Desktop: 3-4 columns for cards

Navigation:

  • Mobile: Bottom navigation bar
  • Tablet: Side navigation rail
  • Desktop: Expanded side navigation

Animation Durations

Consistent animation timing creates a cohesive, polished experience.

Duration Scale

TokenValueUsage
instant0msReduced motion, immediate feedback
fast100-200msMicro-interactions, hovers
normal200-300msStandard transitions
slow300-500msPage transitions, complex animations
slower500ms+Dramatic reveals, special effects

Common Animation Durations

Animation TypeDurationExample
Button press200msLike button animation
Page transition300msRoute changes
Dialog open/close300msModal appearance
Snackbar2000msToast message display
Browser auto-dismiss5000msHint auto-hide
Hover effect150msButton hover state
Focus ring200msInput focus transition
Dropdown200msMenu expansion
Search debounce500msSearch input delay

Implementation Examples

// Button press animation
AnimatedContainer(
duration: const Duration(milliseconds: 200),
curve: Curves.easeInOut,
)

// Page transition
PageRouteBuilder(
transitionDuration: const Duration(milliseconds: 300),
pageBuilder: (context, animation, secondaryAnimation) => NextPage(),
)

// Browser auto-dismiss
autoDismiss: const Duration(seconds: 5)

// Search debounce
Timer(const Duration(milliseconds: 500), () {
_performSearch(query);
})

// Snackbar duration
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Success'),
duration: Duration(seconds: 2),
),
)

Animation Curves

Use appropriate easing curves for natural motion:

// Standard easing
Curves.easeInOut // Most animations

// Entrance
Curves.easeOut // Elements appearing

// Exit
Curves.easeIn // Elements disappearing

// Bouncy/playful
Curves.elasticOut // Special moments (use sparingly)

// Sharp
Curves.fastOutSlowIn // Material design standard

Reduced Motion

Always respect system reduced motion preferences:

final disableAnimations = MediaQuery.of(context).disableAnimations;

final duration = disableAnimations
? Duration.zero
: Duration(milliseconds: 300);

Icon Sizes

Consistent icon sizing improves visual balance and usability.

Size Scale

TokenValueUsage
icon-xs16pxInline icons, small chips
icon-sm20pxList item icons, small buttons
icon-md24pxStandard icons, app bar icons
icon-lg32pxFeature icons, empty states
icon-xl48pxLarge feature illustrations
icon-2xl64pxError/success states
icon-3xl100pxOnboarding, major empty states

Implementation

// Standard icon
Icon(Icons.favorite, size: 24) // icon-md

// App bar icon button
Icon(Icons.menu, size: 24) // icon-md

// List item leading icon
Icon(Icons.book, size: 20) // icon-sm

// Empty state icon
Icon(Icons.inbox, size: 64) // icon-2xl

// Bottom nav icons (selected/unselected)
selectedIconTheme: IconThemeData(size: 28, opacity: 1.0)
unselectedIconTheme: IconThemeData(size: 24, opacity: 0.6)

Icon Guidelines

  • Use 24px as default size for most icons
  • Ensure icon touch target is at least 48x48dp
  • Match icon weight to surrounding text weight
  • Use outlined icons for unselected states
  • Use filled icons for selected/active states
  • Maintain consistent icon family (Cupertino or Material)

Typography Tokens

Typography tokens are defined in /app/lib/config/theme.dart.

Type Scale

TokenSizeWeightLine HeightUsage
headingLarge24pt6001.25Page titles
heading20pt6001.3Section headers
bookTitle17pt6001.3Book titles (serif)
label16pt5001.0UI labels, button text
body16pt4001.5Body text
bodySmall14pt4001.4Secondary text
caption12pt4001.3Metadata, timestamps

See Typography documentation for full details.

Color Tokens

Color tokens are defined in /app/lib/config/theme.dart.

Primary Palette

TokenHexUsage
inkBlue#233548Primary text, headers
parchment#FAF4E8Background, surface
amberStar#FFC857Primary buttons, premium
tealEdge#4BB4C8Interactive elements, links
coralSpine#F37C7CWarnings, destructive actions

Semantic Colors

TokenHexUsage
success#3FA37BSuccess messages
error#C44545Error messages
border#E0D7C8Borders, dividers
forestGreen#2D6A4FBook covers, accents
maroonLeather#7B2D26Book covers, accents

See Color System documentation for full palette and usage.

Usage Guidelines

Consistency

  • Always use tokens instead of hard-coded values
  • Reference theme values: AppColors.inkBlue, AppTypography.body
  • Use token names in comments for clarity
  • Document deviations from the token system

Scaling

When creating new components:

  1. Start with existing tokens
  2. Use spacing scale (8px multiples)
  3. Choose appropriate border radius
  4. Apply consistent shadows
  5. Use standard animation durations

Responsive Adaptation

Tokens should scale appropriately:

  • Spacing: Increase by 25-50% on larger screens
  • Typography: Increase by 1-2pt on desktop
  • Touch targets: Maintain 48dp minimum on mobile
  • Shadows: Can be more pronounced on desktop

Performance

Consider performance implications:

  • Shadows impact render performance on mobile
  • Animations should respect reduced motion
  • Large border radius can impact performance
  • Use elevation wisely to minimize overdraw

Future Enhancements

Potential token system improvements:

  1. CSS custom properties - For web version
  2. Dark mode tokens - Alternative color palette
  3. Platform-specific tokens - iOS vs Android differences
  4. Theming system - User-customizable themes
  5. Token documentation - Auto-generated from code
  6. Design token library - Shared with design tools
  7. Component-specific tokens - Per-component variables
  8. Semantic spacing - Named spacing (buttonPadding vs space-2)