readableStopOn function
Escolhe, dentro de swatch, o stop com contraste ≥ minRatio sobre
background — para usar uma cor de marca/semântica como elemento de UI
(borda, ícone, texto de acento) sobre uma superfície, garantindo ≥ 3:1
(COLOR_ACCESSIBILITY_RULES §5). Em fundo claro varre preferindo stops
escuros; em fundo escuro, stops claros. Cai no stop de maior contraste se
nenhum atingir o alvo (torna a falha visível em teste, sem sumir).
Implementation
Color readableStopOn(
ColorSwatch<int> swatch,
Color background, {
double minRatio = 3.0,
}) {
final bool darkBg = Hct.fromInt(background.toARGB32()).tone < 50;
const List<int> onDark = <int>[
300,
400,
200,
500,
100,
600,
700,
800,
900,
50,
];
const List<int> onLight = <int>[
700,
600,
800,
500,
900,
400,
300,
200,
100,
50,
];
final List<int> order = darkBg ? onDark : onLight;
Color best = swatch[order.first] ?? swatch;
double bestRatio = contrastRatio(best, background);
for (final int stop in order) {
final Color? candidate = swatch[stop];
if (candidate == null) continue;
final double ratio = contrastRatio(candidate, background);
if (ratio >= minRatio) return candidate;
if (ratio > bestRatio) {
best = candidate;
bestRatio = ratio;
}
}
return best;
}