diff --git a/.changeset/poster-label-ink.md b/.changeset/poster-label-ink.md
new file mode 100644
index 00000000..7b8ac947
--- /dev/null
+++ b/.changeset/poster-label-ink.md
@@ -0,0 +1,5 @@
+---
+"material-theme-builder": patch
+---
+
+Write each poster label in the M3 role it is paired with -- `primary` in `on-primary`, `on-primary` in `primary`, the surface family in `on-surface`, tones 80 and up in black and the rest in white -- as Material Theme Builder's poster does, instead of white in `mix-blend-mode: difference`.
diff --git a/src/Mtb.stories.helpers.tsx b/src/Mtb.stories.helpers.tsx
index 492571af..08954e4a 100644
--- a/src/Mtb.stories.helpers.tsx
+++ b/src/Mtb.stories.helpers.tsx
@@ -104,46 +104,52 @@ function TailwindCustomColors() {
return (
-
+
On MyCustomColor1 Container
-
+
On MyCustomColor2 Container
@@ -195,37 +201,37 @@ export function TailwindScheme() {
Primary
-
+
50
-
+
100
-
+
200
-
+
300
-
+
400
-
+
500
-
+
600
-
+
700
-
+
800
-
+
900
-
@@ -235,37 +241,37 @@ export function TailwindScheme() {
Secondary
-
+
50
-
+
100
-
+
200
-
+
300
-
+
400
-
+
500
-
+
600
-
+
700
-
+
800
-
+
900
-
@@ -275,37 +281,37 @@ export function TailwindScheme() {
Tertiary
-
+
50
-
+
100
-
+
200
-
+
300
-
+
400
-
+
500
-
+
600
-
+
700
-
+
800
-
+
900
-
@@ -315,37 +321,37 @@ export function TailwindScheme() {
Error
-
+
50
-
+
100
-
+
200
-
+
300
-
+
400
-
+
500
-
+
600
-
+
700
-
+
800
-
+
900
-
@@ -355,37 +361,37 @@ export function TailwindScheme() {
Neutral
-
+
50
-
+
100
-
+
200
-
+
300
-
+
400
-
+
500
-
+
600
-
+
700
-
+
800
-
+
900
-
@@ -395,37 +401,37 @@ export function TailwindScheme() {
Neutral Variant
-
+
50
-
+
100
-
+
200
-
+
300
-
+
400
-
+
500
-
+
600
-
+
700
-
+
800
-
+
900
-
@@ -435,37 +441,37 @@ export function TailwindScheme() {
myCustomColor1
-
+
50
-
+
100
-
+
200
-
+
300
-
+
400
-
+
500
-
+
600
-
+
700
-
+
800
-
+
900
-
@@ -475,37 +481,37 @@ export function TailwindScheme() {
myCustomColor2
-
+
50
-
+
100
-
+
200
-
+
300
-
+
400
-
+
500
-
+
600
-
+
700
-
+
800
-
+
900
-
diff --git a/src/Scheme.tsx b/src/Scheme.tsx
index 82b9d809..da8b6860 100644
--- a/src/Scheme.tsx
+++ b/src/Scheme.tsx
@@ -173,10 +173,82 @@ const twClasses = {
surfaceTint: "bg-surface-tint",
} satisfies Record
;
+/**
+ * The role each swatch's label is written in -- its M3 pair, the way the
+ * official app's poster does it: `primary` reads in `on-primary` and
+ * `on-primary` in `primary`; the surface family reads in `on-surface`, and
+ * the inks (`on-surface`, `outline`) in `surface`. `scrim` and `shadow` are
+ * black in both schemes, so their label is plain white, as in the app.
+ *
+ * The fixed accents are not on the app's poster; they follow the same pairing.
+ */
+const ink = {
+ primary: "onPrimary",
+ onPrimary: "primary",
+ primaryContainer: "onPrimaryContainer",
+ onPrimaryContainer: "primaryContainer",
+ secondary: "onSecondary",
+ onSecondary: "secondary",
+ secondaryContainer: "onSecondaryContainer",
+ onSecondaryContainer: "secondaryContainer",
+ tertiary: "onTertiary",
+ onTertiary: "tertiary",
+ tertiaryContainer: "onTertiaryContainer",
+ onTertiaryContainer: "tertiaryContainer",
+
+ error: "onError",
+ onError: "error",
+ errorContainer: "onErrorContainer",
+ onErrorContainer: "errorContainer",
+
+ primaryFixed: "onPrimaryFixed",
+ primaryFixedDim: "onPrimaryFixed",
+ onPrimaryFixed: "primaryFixed",
+ onPrimaryFixedVariant: "primaryFixed",
+ secondaryFixed: "onSecondaryFixed",
+ secondaryFixedDim: "onSecondaryFixed",
+ onSecondaryFixed: "secondaryFixed",
+ onSecondaryFixedVariant: "secondaryFixed",
+ tertiaryFixed: "onTertiaryFixed",
+ tertiaryFixedDim: "onTertiaryFixed",
+ onTertiaryFixed: "tertiaryFixed",
+ onTertiaryFixedVariant: "tertiaryFixed",
+
+ surfaceDim: "onSurface",
+ surface: "onSurface",
+ surfaceBright: "onSurface",
+ surfaceContainerLowest: "onSurface",
+ surfaceContainerLow: "onSurface",
+ surfaceContainer: "onSurface",
+ surfaceContainerHigh: "onSurface",
+ surfaceContainerHighest: "onSurface",
+ onSurface: "surface",
+ onSurfaceVariant: "surfaceVariant",
+ outline: "surface",
+ outlineVariant: "onSurface",
+
+ inverseSurface: "inverseOnSurface",
+ inverseOnSurface: "inverseSurface",
+ inversePrimary: "onSurface",
+ scrim: "white",
+ shadow: "white",
+
+ background: "onBackground",
+ onBackground: "background",
+ surfaceVariant: "onSurfaceVariant",
+ surfaceTint: "onPrimary",
+} satisfies Record;
+
+/** The CSS color a label is written in, from the role it is paired with. */
+function inkOf(role: TokenName | "white"): string {
+ return role === "white" ? "white" : `var(--md-sys-color-${kebabCase(role)})`;
+}
+
/**
* One color cell: the role as `title`, its human name as label, the color
* itself from `var(--md-sys-color-)` — or from the Tailwind utility when
- * under a `tw` `Scheme`.
+ * under a `tw` `Scheme`. The label is written in the role's pair (`ink`),
+ * always from the var: `tw` is about the `bg-*` utilities resolving.
*/
function Swatch({
role,
@@ -195,11 +267,11 @@ function Swatch({
{children ??
{startCase(role)}
}
@@ -235,8 +307,6 @@ function PosterStyle({ notext }: { notext?: boolean }) {
p {
font-family: sans-serif;
- color: white;
- mix-blend-mode: difference;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@@ -292,6 +362,34 @@ const themeStyles = {
},
} satisfies Record<"light" | "dark", CSSProperties>;
+/**
+ * One cell of a custom color's row: the `--md-sys-color-
` token as its
+ * color, its `label` written in the `ink` token -- its pair, as `ink` maps
+ * the standard roles.
+ */
+function CustomSwatch({
+ name,
+ ink,
+ label,
+}: {
+ name: string;
+ ink: string;
+ label: string;
+}) {
+ return (
+
+ );
+}
+
/**
* The four roles the current spec no longer lists, as an extra row under
* `on-surface` — `background`, `on-background`, `surface-variant` and
@@ -644,54 +742,30 @@ export function Scheme({
}
{customColors && customColors.length > 0 && (
- {customColors?.map((customColor) => (
-
-
-
- {upperFirst(customColor.name)}
-
-
-
-
- On {upperFirst(customColor.name)}
-
-
-
-
- {upperFirst(customColor.name)} Container
-
-
-
-
- On {upperFirst(customColor.name)} Container
-
-
-
- ))}
+ {customColors.map((customColor) => {
+ const name = kebabCase(customColor.name);
+ const label = upperFirst(customColor.name);
+ return (
+
+
+
+
+
+
+ );
+ })}
)}
@@ -753,6 +827,7 @@ export function Shades({
alignItems: "center",
justifyContent: "center",
backgroundColor: `var(--md-ref-palette-${isCustom ? kebabCase(name) : name}-${tone})`,
+ color: tone >= 80 ? "black" : "white",
}}
>
{tone}