The Candi Design System provides a Flutter package for using OKLCH-based colors in cross-platform applications.
The Flutter package is published as candi_colors. Add the dependency to your pubspec.yaml:
dependencies:
candi_colors:
git:
url: https://github.com/wtasg/candi.git
path: flutterFor local development within the monorepo:
dependencies:
candi_colors:
path: ../flutterBuild a ThemeData from a CandiPalette so light and dark modes stay in sync:
import 'package:candi_colors/candi.dart';
import 'package:flutter/material.dart';
ThemeData buildTheme(CandiPalette palette, Brightness brightness) {
return ThemeData(
brightness: brightness,
scaffoldBackgroundColor: palette.bg,
colorScheme: ColorScheme.fromSeed(
seedColor: palette.accent,
brightness: brightness,
),
);
}
void main() {
runApp(
MaterialApp(
theme: buildTheme(CandiColors.light, Brightness.light),
darkTheme: buildTheme(CandiColors.dark, Brightness.dark),
themeMode: ThemeMode.system,
),
);
}import 'package:candi_colors/candi.dart';
// Access the light theme
final theme = CandiColors.light;
// Use in widgets
Container(
color: theme.bg,
child: Text(
'Candi Design',
style: TextStyle(color: theme.text),
),
)CandiColor extends Flutter's Color class and retains OKLCH metadata for advanced UI logic.
final accent = CandiColors.light.accent;
print(accent.lightness); // 0.52
print(accent.chroma); // 0.06
print(accent.hue); // 230.0 (Steel Blue)
// Compatible with standard Color parameters
Color standardColor = accent; Semantic tokens available on CandiColors.light and CandiColors.dark:
| Token | Description |
|---|---|
bg |
Main application background |
surface |
Card and secondary section background |
elevated |
Modal, popup, and input background |
text |
Primary body text |
subtle |
Secondary text |
muted |
De-emphasized text and dividers |
border |
Subtle border color |
accent |
Primary action color (Steel Blue) |
secondary |
Secondary action color (Terracotta) |
success |
Success states |
warning |
Warning states |
error |
Error states |
Use standard Flutter state management like ValueNotifier or Provider:
ValueNotifier<CandiThemeData> themeNotifier = ValueNotifier(CandiColors.light);
ValueListenableBuilder(
valueListenable: themeNotifier,
builder: (context, theme, _) {
return Container(color: theme.bg);
},
);
// Toggle
themeNotifier.value = isDark ? CandiColors.dark : CandiColors.light;