huevora 1.0.2+1 copy "huevora: ^1.0.2+1" to clipboard
huevora: ^1.0.2+1 copied to clipboard

A production-grade color engine for Dart. Derive complete design-system palettes from a single hex color, generate Material-style tonal palettes, validate contrast via APCA and WCAG 2.x, and export to [...]

Huevora #

A production-grade color engine for Dart. Derive complete design-system palettes from a single hex color, generate Material-style tonal palettes, validate contrast via APCA and WCAG 2.x, and export to JSON or plain text.

Dart SDK GitHub Stars Issues Pub Version Pub Points Likes


Features #

Feature Description
Bidirectional color conversion HEX ↔ OKLCH ↔ RGB with prism-backed precision
Branded palette derivation 9 standard roles (primary, secondary, tertiary, neutral, neutralVariant, success, error, warning, info) derived perceptually in OKLCH space
Tonal palette generation Material 3-style tone steps via material_color_utilities, with asymmetric neutral step arrays
Contrast validation APCA 0.0.98G + WCAG 2.x simultaneous checking with tone suggestions
Export system JSON (structured) and TXT (token-style, Figma-friendly) with configurable inclusion flags
Gamut-safe by design Every derived color is verified in-gamut via round-trip OKLCH→RGB8→OKLCH validation
Null-safe, sealed errors Exhaustive exception hierarchy; no stringly-typed failures

Quickstart #

import 'package:huevora/huevora.dart';

void main() {
  final engine = ColorEngine();

  // Derive a complete branded palette from one hex color.
  final palette = engine.deriveCorePalette('#4A90E2');

  // Generate tonal palettes for every role.
  final tonals = engine.generateTonalPalettes(palette);

  // Check contrast.
  final contrast = ContrastEngine().check(
    foreground: palette.primary,
    background: engine.fromHex('#FFFFFF'),
  );
  print('APCA Lc: ${contrast.apcaLc}, WCAG: ${contrast.wcagRatio}:1');

  // Export to JSON.
  final json = ExportEngine().toJson(palette, tonals);
  print(json);
}

Installation #

dependencies:
  huevora: ^1.0.2+1
dart pub add huevora

API Overview #

ColorEngine #

final engine = ColorEngine();

// Derive from primary hex
final palette = engine.deriveCorePalette('#4A90E2', DerivationConfig(
  semanticBrandingWeight: 0.25,
  customColors: [(name: 'accent', hex: '#FF6B35')],
));

// Or validate a fully-specified palette
final validated = engine.validateCorePalette(CorePaletteInput(...));

// Tonal generation
final tonals = engine.generateTonalPalettes(palette);

ContrastEngine #

final result = ContrastEngine().check(
  foreground: palette.primary,
  background: engine.fromHex('#FFFFFF'),
  tonalResult: tonals,
  fgRole: ColorRole.primary,
);

print(result.advice);
print(result.suggestedFgTones); // tone alternatives from the palette

ExportEngine #

final export = ExportEngine();

// JSON with full metadata
final json = export.toJson(palette, tonals);

// Hex-only, core-only
final minimal = export.toJson(
  palette,
  tonals,
  ExportConfig.hexOnly(),
);

// Plain text tokens
final text = export.toText(palette, tonals);

// Write to disk
await export.writeToFile(json, './palette.json');


Color Derivation Logic #

Role Derivation
primary Input seed color
secondary Analogous (+30° hue offset, 65% chroma)
tertiary Complementary (+180° hue, 70% chroma)
neutral Primary hue, chroma clamped to [0.018, 0.10]
neutralVariant Primary hue, chroma clamped to [0.045, 0.10]
success Base hue 145°, pulled 25% toward primary hue
error Base hue 25°, pulled 25% toward primary hue
warning Base hue 75°, pulled 25% toward primary hue
info Base hue 240°, pulled 25% toward primary hue

Tone Step Arrays #

Role type Steps
Standard (chromatic) 0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 95, 98, 99, 100
Neutral 0, 4, 5, 6, 10, 12, 15, 17, 20, 22, 24, 25, 30, 35, 40, 50, 60, 70, 80, 87, 90, 92, 94, 95, 96, 98, 99, 100

Neutral roles use denser steps at dark and light extremes for precise elevation overlay and surface tint control. #

Contrast Standards #

Standard Metric Thresholds
APCA Signed Lc (lightness contrast) ≥90 fluent text, ≥75 body text, ≥60 large text, ≥45 UI components
WCAG 2.x Contrast ratio ≥7.0 AAA, ≥4.5 AA, ≥3.0 AA Large, <3.0 fail

APCA is polarity-sensitive (dark-on-light ≠ light-on-dark in |Lc|). WCAG 2.x is order-independent.


Error Handling #

All failures are typed via a sealed HuevoraException hierarchy:

try {
  final color = engine.fromHex('#ZZZZZZ');
} on InvalidHexException catch (e) {
  print('Bad input: ${e.input}');
}

try {
  GamutGuard.assertInSrgb(color);
} on OutOfGamutException catch (e) {
  print('Use ${e.clampedHex} instead of ${e.sourceHex}');
}

Dependencies #

Package Version Purpose
prism ^2.1.0 OKLCH/OKLab/RGB8 conversion, gamut clipping
material_color_utilities ^0.13.0 HCT tonal palette generation

License #

MIT


Contributing #

Issues and PRs welcome. All changes must pass the full test suite (dart test) and maintain backward compatibility of public API types.

0
likes
140
points
0
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A production-grade color engine for Dart. Derive complete design-system palettes from a single hex color, generate Material-style tonal palettes, validate contrast via APCA and WCAG 2.x, and export to JSON or plain text.

Repository (GitHub)
View/report issues
Contributing

Topics

#color #palette #contrast #accessibility #export

License

MIT (license)

Dependencies

material_color_utilities, meta, prism

More

Packages that depend on huevora