generate static method
Generate a full palette from seed colors.
Implementation
static ThemePalette generate(ThemeSeed seed) {
final bool isDark = seed.isDark;
final int primary = seed.primary;
// Resolve background
final int background = seed.background ?? (isDark ? 0xFF000000 : 0xFFffffff);
final int foreground = contrastingForeground(background);
// Resolve secondary (slightly off from background)
// Light mode: tint with primary hue for richer surfaces
// Dark mode: just lighten for subtle elevation
final int secondary = seed.secondary ?? (isDark
? lighten(background, 0.06) // Dark: slightly lighter
: _tintedSurface(background, primary, 0.06, 0.12)); // Light: richer tinting
// Resolve accent - more prominent tinting for light mode
final int accent = seed.accent ?? (isDark
? secondary
: _tintedSurface(background, primary, 0.10, 0.18));
// Resolve border - light mode gets visible primary tint
final int border = seed.border ?? (isDark
? lighten(background, 0.18)
: _tintedSurface(background, primary, 0.18, 0.10));
// Card is same as background or slightly elevated
// Light mode: subtle but visible primary tint
final int card = isDark
? lighten(background, 0.04)
: _tintedSurface(background, primary, 0.02, 0.05);
final int cardHover = isDark
? lighten(card, 0.04)
: _tintedSurface(card, primary, 0.04, 0.06);
// Muted - light mode gets visible tinting
final int muted = isDark ? secondary : _tintedSurface(background, primary, 0.05, 0.10);
// Note: Use blendColors for both modes since setAlpha doesn't work
// with hex output (toHex strips alpha channel)
final int mutedForeground = blendColors(
foreground,
background,
isDark ? 0.60 : 0.45,
);
// Primary foreground
final int primaryForeground = contrastingForeground(primary);
// Semantic colors
final int destructive = seed.destructive;
final int success = seed.success;
final int warning = seed.warning;
final int info = seed.info;
// Glow color for shadows
final int? glowColor = seed.accentGlow ? (seed.glowColor ?? primary) : null;
return ThemePalette(
isDark: isDark,
// Core
background: background,
foreground: foreground,
// Card
card: card,
cardForeground: foreground,
cardHover: cardHover,
popover: card,
popoverForeground: foreground,
// Primary
primary: primary,
primaryForeground: primaryForeground,
primaryContainer: container(background, primary),
// Secondary
secondary: secondary,
secondaryForeground: foreground,
secondaryContainer: container(background, secondary),
// Accent
accent: accent,
accentForeground: foreground,
accentHover: isDark ? lighten(accent, 0.05) : darken(accent, 0.05),
accentContainer: container(background, accent),
// Muted
muted: muted,
mutedForeground: mutedForeground,
// Destructive
destructive: destructive,
destructiveForeground: contrastingForeground(destructive),
destructiveHover: isDark ? lighten(destructive, 0.10) : darken(destructive, 0.10),
destructiveContainer: container(background, destructive),
// Success
success: success,
successForeground: contrastingForeground(success),
successHover: isDark ? lighten(success, 0.10) : darken(success, 0.10),
successContainer: container(background, success),
// Warning
warning: warning,
warningForeground: contrastingForeground(warning),
warningHover: isDark ? lighten(warning, 0.10) : darken(warning, 0.10),
warningContainer: container(background, warning),
// Info
info: info,
infoForeground: contrastingForeground(info),
infoHover: isDark ? lighten(info, 0.10) : darken(info, 0.10),
infoContainer: container(background, info),
// Borders
border: border,
input: isDark ? darken(border, 0.03) : border,
ring: isDark ? lighten(primary, 0.2) : primary,
// Overlays
overlay: 0x80000000, // 50% black
navbar: setAlpha(background, 0.8),
codeBackground: secondary,
// Shadows
shadowXs: _shadowXs(isDark, glowColor),
shadowSm: _shadowSm(isDark, glowColor),
shadowMd: _shadowMd(isDark, glowColor),
shadowLg: _shadowLg(isDark, glowColor),
shadowXl: _shadowXl(isDark, glowColor),
);
}