mirror of
https://gitea.tendokyu.moe/Kayori/Medusa.net.git
synced 2026-09-27 01:00:40 +03:00
71 lines
2.9 KiB
TypeScript
71 lines
2.9 KiB
TypeScript
/**
|
|
* Derives the app's full Material 3 color palette from a single seed color
|
|
* using Google's own color-science library, so tailwind.config.ts and the
|
|
* generated `md-*` Tailwind utilities always agree with each other.
|
|
*
|
|
* Uses the "Tonal Spot" scheme variant (low-to-medium colorfulness, the
|
|
* default Material You look on Android) at standard contrast.
|
|
*/
|
|
import {
|
|
Hct,
|
|
SchemeTonalSpot,
|
|
MaterialDynamicColors,
|
|
argbFromHex,
|
|
hexFromArgb,
|
|
type DynamicScheme,
|
|
} from '@material/material-color-utilities';
|
|
import type { ColorTokens } from 'tailwind-material-3';
|
|
|
|
export const SEED_COLOR = '#D81B7A';
|
|
|
|
const dynamicColors = new MaterialDynamicColors();
|
|
const seed = Hct.fromInt(argbFromHex(SEED_COLOR));
|
|
const lightScheme = new SchemeTonalSpot(seed, false, 0);
|
|
const darkScheme = new SchemeTonalSpot(seed, true, 0);
|
|
|
|
type DynamicColorLike = { getArgb(scheme: DynamicScheme): number };
|
|
|
|
const role = (pick: (colors: MaterialDynamicColors) => DynamicColorLike) => ({
|
|
light: hexFromArgb(pick(dynamicColors).getArgb(lightScheme)),
|
|
dark: hexFromArgb(pick(dynamicColors).getArgb(darkScheme)),
|
|
});
|
|
|
|
export const colorTokens: ColorTokens = {
|
|
primary: role((c) => c.primary()),
|
|
onPrimary: role((c) => c.onPrimary()),
|
|
primaryContainer: role((c) => c.primaryContainer()),
|
|
onPrimaryContainer: role((c) => c.onPrimaryContainer()),
|
|
inversePrimary: role((c) => c.inversePrimary()),
|
|
secondary: role((c) => c.secondary()),
|
|
onSecondary: role((c) => c.onSecondary()),
|
|
secondaryContainer: role((c) => c.secondaryContainer()),
|
|
onSecondaryContainer: role((c) => c.onSecondaryContainer()),
|
|
tertiary: role((c) => c.tertiary()),
|
|
onTertiary: role((c) => c.onTertiary()),
|
|
tertiaryContainer: role((c) => c.tertiaryContainer()),
|
|
onTertiaryContainer: role((c) => c.onTertiaryContainer()),
|
|
error: role((c) => c.error()),
|
|
onError: role((c) => c.onError()),
|
|
errorContainer: role((c) => c.errorContainer()),
|
|
onErrorContainer: role((c) => c.onErrorContainer()),
|
|
background: role((c) => c.background()),
|
|
onBackground: role((c) => c.onBackground()),
|
|
surface: role((c) => c.surface()),
|
|
onSurface: role((c) => c.onSurface()),
|
|
surfaceVariant: role((c) => c.surfaceVariant()),
|
|
onSurfaceVariant: role((c) => c.onSurfaceVariant()),
|
|
surfaceDim: role((c) => c.surfaceDim()),
|
|
surfaceBright: role((c) => c.surfaceBright()),
|
|
surfaceContainerLowest: role((c) => c.surfaceContainerLowest()),
|
|
surfaceContainerLow: role((c) => c.surfaceContainerLow()),
|
|
surfaceContainer: role((c) => c.surfaceContainer()),
|
|
surfaceContainerHigh: role((c) => c.surfaceContainerHigh()),
|
|
surfaceContainerHighest: role((c) => c.surfaceContainerHighest()),
|
|
inverseSurface: role((c) => c.inverseSurface()),
|
|
inverseOnSurface: role((c) => c.inverseOnSurface()),
|
|
outline: role((c) => c.outline()),
|
|
outlineVariant: role((c) => c.outlineVariant()),
|
|
shadow: role((c) => c.shadow()),
|
|
scrim: role((c) => c.scrim()),
|
|
};
|