mobile bluesky app made with flutter lazurite.stormlightlabs.org/
mobile bluesky flutter
1# Theming System 2 3## Overview 4 5- Many Material 3 components rely on the broader set of tone-based 6 surfaces/containers and "onSurfaceVariant/outlineVariant" emphasis roles. 7- Material 3 is explicitly designed around *color roles* applied consistently 8 across UI. 9- Flutter has been expanding Material 3 ColorScheme roles (tone surfaces + 10 containers, and more accent roles), and some older roles are deprecated (e.g., 11 background/onBackground, surfaceVariant). 12 13## Architecture 14 15### Core Types 16 17**ThemePack** (`lib/src/app/theming/theme_pack.dart`) 18 19- Collection of theme variants (e.g., "Oxocarbon" pack with light/dark variants) 20- Contains metadata: id, name, author 21- Provides accessors: `lightVariant`, `darkVariant`, `getVariant(id)` 22 23**ThemeVariant** (`lib/src/app/theming/theme_variant.dart`) 24 25- Single brightness variant with a Material 3 ColorScheme 26- Built from ThemeSpec palette definitions 27- Contains: id, brightness, derivedScheme 28 29**ThemeSpec** (`lib/src/app/theming/theme_spec.dart`) 30 31- Palette definition for a theme variant 32- Maps raw colors to M3 ColorScheme roles 33- Defines: surfaces, containers, outlines, accents, typography, shapes 34 35**ThemeFactory** (`lib/src/app/theming/theme_factory.dart`) 36 37- Builds complete ThemeData from ThemeVariant 38- Centralizes component themes (NavBar, Chips, Cards, ListTiles, Dividers, Inputs) 39- Ensures consistent M3 role usage across all components 40 41### Principles (Material 3) 42 43- Use semantic color roles (surface containers, outlineVariant, 44 onSurfaceVariant) rather than raw hex values sprinkled through widgets. 45- Create hierarchy with tone-based surfaces/containers rather than heavy 46 dividers. 47- Navigation components must have a clear active indicator (selected state). 48- Chips have specific color roles in spec (filter chip uses onSurfaceVariant + 49 outline and optionally surfaceContainerLow). 50 51## Material 3 Role Usage 52 53### Surface Containers (Hierarchy) 54 55Tone-based surfaces create visual hierarchy without heavy elevation: 56 57```text 58surfaceContainerLowest ← dialogs, sheets (highest elevation) 59surfaceContainerHigh ← embeds, elevated cards 60surfaceContainer ← default containers 61surfaceContainerLow ← posts, cards (slightly elevated) 62surface ← base background 63surfaceDim/surfaceBright ← adaptive surface tones 64``` 65 66### Component Patterns 67 68#### NavigationBar 69 70- Active indicator: uses container role (NOT primary tint overlay) 71- Selected icons/labels: onSurface 72- Unselected icons/labels: onSurfaceVariant 73 74#### FilterChips (Feed selector) 75 76- Unselected: outline + onSurfaceVariant 77- Selected: secondaryContainer + onSecondaryContainer 78 79#### Cards (Posts) 80 81- Use surfaceContainerLow for slight elevation from background 82- Embeds use surfaceContainerHigh (higher than parent post) 83 84#### Dividers 85 86- Default: outlineVariant (subtle) 87- Emphasized boundaries: outline 88 89#### Text Emphasis 90 91- Body text: onSurface (highest legibility) 92- Metadata (handle, timestamp): onSurfaceVariant 93 94## Creating Theme Packs 95 96### 1. Define Palette 97 98Map your palette to M3 surface/container/outline/accent roles: 99 100```dart 101final mySpec = ThemeSpec( 102 // Base surfaces 103 surface: Color(0xFF1A1A1A), 104 surfaceDim: Color(0xFF121212), 105 surfaceBright: Color(0xFF242424), 106 107 // Container ladder (dark theme: lowest is darkest) 108 surfaceContainerLowest: Color(0xFF0F0F0F), 109 surfaceContainerLow: Color(0xFF1E1E1E), 110 surfaceContainer: Color(0xFF242424), 111 surfaceContainerHigh: Color(0xFF2E2E2E), 112 surfaceContainerHighest: Color(0xFF393939), 113 114 // Outlines 115 outline: Color(0xFF525252), 116 outlineVariant: Color(0xFF393939), 117 118 // Text 119 onSurface: Color(0xFFF2F4F8), 120 onSurfaceVariant: Color(0xFFB0B0B0), 121 122 // Accents 123 primary: Color(0xFF0085FF), 124 onPrimary: Color(0xFFFFFFFF), 125 secondary: Color(0xFF78A9FF), 126 onSecondary: Color(0xFF000000), 127 // ... other accent roles 128); 129``` 130 131### 2. Create Variants 132 133```dart 134final darkVariant = ThemeVariant( 135 id: 'mypack-dark', 136 brightness: Brightness.dark, 137 spec: myDarkSpec, 138); 139 140final lightVariant = ThemeVariant( 141 id: 'mypack-light', 142 brightness: Brightness.light, 143 spec: myLightSpec, 144); 145``` 146 147### 3. Build ThemePack 148 149```dart 150final myPack = ThemePack( 151 id: 'mypack', 152 name: 'My Pack', 153 author: 'Me', 154 variants: [darkVariant, lightVariant], 155); 156``` 157 158### 4. Validate with Role Lint Tests 159 160Role lint checks ensure: 161 162- All required M3 roles are defined 163- Hierarchy integrity (surface != surfaceContainerLow, etc.) 164- Container ladder ordering matches brightness (dark: lowest is darkest, light: lowest is lightest) 165- Emphasis differentiation (onSurface != onSurfaceVariant) 166 167## Accent Strategy by Theme Type 168 169### High-contrast themes (Oxocarbon, One Dark) 170 171- Use vivid primary colors 172- Strong secondary/tertiary for highlights 173 174### Pastel themes (Catppuccin, Rosé Pine, Nord) 175 176- Keep accents restrained 177- Use secondary for chips, tertiary for highlights 178- Avoid overwhelming soft palettes with saturated accents