@adea-ai/ui 0.119.0 → 0.120.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,7 +18,7 @@ import { type VariantProps } from '#lib/variants';
18
18
  * `asChild` primitive, which has no Solid equivalent that preserves props.
19
19
  */
20
20
  export declare const buttonVariants: (props?: ({
21
- variant?: "link" | "default" | "destructive" | "success" | "outline" | "secondary" | "subtle" | "ghost" | null | undefined;
21
+ variant?: "link" | "default" | "destructive" | "success" | "toolbar" | "outline" | "secondary" | "subtle" | "ghost" | null | undefined;
22
22
  size?: "2xs" | "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "icon-2xs" | "icon-xs" | "icon-sm" | "icon-md" | "icon-lg" | "icon-xl" | "icon-2xl" | null | undefined;
23
23
  touchTarget?: "comfortable" | null | undefined;
24
24
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
@@ -1 +1 @@
1
- {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/button/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC9E,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/E,OAAO,EAAwC,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAGvF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc;;;;8EAmD1B,CAAA;AAED,KAAK,kBAAkB,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAA;AAE7D,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,gBAAgB,CAC7E,CAAC,EACD,kBAAkB,GAAG;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CACF,CAAA;AAED,wBAAgB,MAAM,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,kCAwBhF"}
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/button/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC9E,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,UAAU,CAAA;AAC/E,OAAO,EAAwC,KAAK,YAAY,EAAE,MAAM,eAAe,CAAA;AAGvF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc;;;;8EA0D1B,CAAA;AAED,KAAK,kBAAkB,GAAG,YAAY,CAAC,OAAO,cAAc,CAAC,CAAA;AAE7D,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,IAAI,gBAAgB,CAC7E,CAAC,EACD,kBAAkB,GAAG;IACnB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CACF,CAAA;AAED,wBAAgB,MAAM,CAAC,CAAC,SAAS,cAAc,GAAG,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,kCAwBhF"}
@@ -32,6 +32,13 @@ var buttonVariants = cva(`${controlInteractive} inline-flex shrink-0 items-cente
32
32
  outline: "border border-border bg-transparent text-foreground hover:bg-surface-hover hover:border-input",
33
33
  /** No chrome until hover. The default for toolbar and row actions. */
34
34
  ghost: "text-foreground hover:bg-surface-hover",
35
+ /**
36
+ * A ghost that opens something: a sheet, menu or popover trigger in a
37
+ * toolbar. While its surface is open it holds the menubar's pressed
38
+ * rung, so the open control never reads identical to its closed
39
+ * neighbours.
40
+ */
41
+ toolbar: "text-foreground hover:bg-surface-hover data-[expanded]:bg-surface-active",
35
42
  /** A tinted primary, for a secondary action inside a primary flow. */
36
43
  subtle: "bg-primary-subtle text-primary hover:bg-primary-subtle/80",
37
44
  success: "bg-success text-success-foreground hover:bg-success/90",
@@ -1 +1 @@
1
- {"version":3,"file":"button.js","names":["Polymorphic","PolymorphicProps","ComponentProps","splitProps","ValidComponent","cva","controlInteractive","controlSize","VariantProps","cn","buttonVariants","variants","variant","default","secondary","destructive","outline","ghost","subtle","success","link","size","xs","sm","md","lg","xl","touchTarget","comfortable","defaultVariants","ButtonVariantProps","ButtonProps","T","class","Button","props","local","rest","_$createComponent","_$mergeProps","as","type","_$createComponent","_$mergeProps"],"sources":["../../../../src/components/ui/button/button.tsx"],"sourcesContent":["import { Polymorphic, type PolymorphicProps } from '@kobalte/core/polymorphic'\nimport { type ComponentProps, splitProps, type ValidComponent } from 'solid-js'\nimport { cva, controlInteractive, controlSize, type VariantProps } from '#lib/variants'\nimport { cn } from '#lib/utils'\n\n/**\n * Button.\n *\n * One appearance ladder shared by every pressable thing in the system: a\n * button, a toolbar control, a dialog action, and a menu row all draw from the\n * same tokens, so a row of them cannot drift apart.\n *\n * The variants answer \"what is this for\", never \"what colour is it\". A caller\n * that wants a red button writes `variant=\"destructive\"`; the red lives here.\n * That is also what lets the design-system linter tell a caller which variant\n * to use instead of only which class was wrong.\n *\n * Polymorphic: pass `as=\"a\"` (or any component) and the button becomes it\n * while keeping the same styling contract. This replaces the React-era\n * `asChild` primitive, which has no Solid equivalent that preserves props.\n */\nexport const buttonVariants = cva(\n `${controlInteractive} inline-flex shrink-0 items-center justify-center rounded-md font-medium whitespace-nowrap select-none [&_svg]:pointer-events-none [&_svg]:shrink-0`,\n {\n variants: {\n variant: {\n /** The one primary action in a view. */\n default: 'bg-primary text-primary-foreground hover:bg-primary-hover',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-surface-hover',\n /** For the action that destroys something. Never the default. */\n destructive:\n 'bg-destructive-action text-destructive-action-foreground hover:bg-destructive-action/90 focus-visible:ring-destructive-subtle',\n /** A bordered button for a surface that already has a fill. */\n outline:\n 'border border-border bg-transparent text-foreground hover:bg-surface-hover hover:border-input',\n /** No chrome until hover. The default for toolbar and row actions. */\n ghost: 'text-foreground hover:bg-surface-hover',\n /** A tinted primary, for a secondary action inside a primary flow. */\n subtle: 'bg-primary-subtle text-primary hover:bg-primary-subtle/80',\n success: 'bg-success text-success-foreground hover:bg-success/90',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n '2xs': `${controlSize['2xs']} [&_svg]:size-3`,\n xs: `${controlSize.xs} [&_svg]:size-3.5`,\n sm: `${controlSize.sm} [&_svg]:size-3.5`,\n md: `${controlSize.md} [&_svg]:size-4`,\n lg: `${controlSize.lg} [&_svg]:size-4`,\n xl: `${controlSize.xl} [&_svg]:size-5`,\n '2xl': `${controlSize['2xl']} [&_svg]:size-6`,\n /* Square, for an icon with no label. The accessible name then has to\n come from `aria-label` or a visually hidden label — an icon-only\n button with neither is the accessibility finding the Storybook lane\n catches on every story. */\n 'icon-2xs': 'size-control-2xs p-0 [&_svg]:size-3',\n 'icon-xs': 'size-control-xs p-0 [&_svg]:size-3.5',\n 'icon-sm': 'size-control-sm p-0 [&_svg]:size-3.5',\n 'icon-md': 'size-control-md p-0 [&_svg]:size-4',\n 'icon-lg': 'size-control-lg p-0 [&_svg]:size-4',\n 'icon-xl': 'size-control-xl p-0 [&_svg]:size-5',\n 'icon-2xl': 'size-control-2xl p-0 [&_svg]:size-6',\n },\n /** Opt in to a stable touch target on devices with any coarse pointer. */\n touchTarget: {\n comfortable: 'touch-target-comfortable',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n },\n }\n)\n\ntype ButtonVariantProps = VariantProps<typeof buttonVariants>\n\nexport type ButtonProps<T extends ValidComponent = 'button'> = PolymorphicProps<\n T,\n ButtonVariantProps & {\n class?: string\n }\n>\n\nexport function Button<T extends ValidComponent = 'button'>(props: ButtonProps<T>) {\n const [local, rest] = splitProps(props as ButtonProps, [\n 'variant',\n 'size',\n 'touchTarget',\n 'class',\n ])\n\n return (\n <Polymorphic\n as=\"button\"\n type=\"button\"\n data-slot=\"button\"\n class={cn(\n buttonVariants({\n variant: local.variant,\n size: local.size,\n touchTarget: local.touchTarget,\n }),\n local.class\n )}\n {...(rest as ComponentProps<'button'>)}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqBA,IAAaU,iBAAiBL,IAC5B,GAAGC,mBAAkB,sJACrB;CACEK,UAAU;EACRC,SAAS;;GAEPC,SAAS;GACTC,WAAW;;GAEXC,aACE;;GAEFC,SACE;;GAEFC,OAAO;;GAEPC,QAAQ;GACRC,SAAS;GACTC,MAAM;EACR;EACAC,MAAM;GACJ,OAAO,GAAGd,YAAY,OAAM;GAC5Be,IAAI,GAAGf,YAAYe,GAAE;GACrBC,IAAI,GAAGhB,YAAYgB,GAAE;GACrBC,IAAI,GAAGjB,YAAYiB,GAAE;GACrBC,IAAI,GAAGlB,YAAYkB,GAAE;GACrBC,IAAI,GAAGnB,YAAYmB,GAAE;GACrB,OAAO,GAAGnB,YAAY,OAAM;GAK5B,YAAY;GACZ,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,YAAY;EACd;;EAEAoB,aAAa,EACXC,aAAa,2BACf;CACF;CACAC,iBAAiB;EACfjB,SAAS;EACTS,MAAM;CACR;AACF,CACF;AAWA,SAAgBa,OAA4CC,OAAuB;CACjF,MAAM,CAACC,OAAOC,QAAQlC,WAAWgC,OAAsB;EACrD;EACA;EACA;EACA;CAAO,CACR;CAED,OAAAG,gBACGtC,aAAWuC,WAAA;EACVC,IAAE;EACFC,MAAI;EAAA,aAAA;EAAA,KAAA,WAAA;GAAA,OAEGhC,GACLC,eAAe;IACbE,SAASwB,MAAMxB;IACfS,MAAMe,MAAMf;IACZM,aAAaS,MAAMT;GACrB,CAAC,GACDS,MAAMH,KACR;EAAC;CAAA,GACII,IAAgC,CAAA;AAG3C"}
1
+ {"version":3,"file":"button.js","names":["Polymorphic","PolymorphicProps","ComponentProps","splitProps","ValidComponent","cva","controlInteractive","controlSize","VariantProps","cn","buttonVariants","variants","variant","default","secondary","destructive","outline","ghost","toolbar","subtle","success","link","size","xs","sm","md","lg","xl","touchTarget","comfortable","defaultVariants","ButtonVariantProps","ButtonProps","T","class","Button","props","local","rest","_$createComponent","_$mergeProps","as","type","_$createComponent","_$mergeProps"],"sources":["../../../../src/components/ui/button/button.tsx"],"sourcesContent":["import { Polymorphic, type PolymorphicProps } from '@kobalte/core/polymorphic'\nimport { type ComponentProps, splitProps, type ValidComponent } from 'solid-js'\nimport { cva, controlInteractive, controlSize, type VariantProps } from '#lib/variants'\nimport { cn } from '#lib/utils'\n\n/**\n * Button.\n *\n * One appearance ladder shared by every pressable thing in the system: a\n * button, a toolbar control, a dialog action, and a menu row all draw from the\n * same tokens, so a row of them cannot drift apart.\n *\n * The variants answer \"what is this for\", never \"what colour is it\". A caller\n * that wants a red button writes `variant=\"destructive\"`; the red lives here.\n * That is also what lets the design-system linter tell a caller which variant\n * to use instead of only which class was wrong.\n *\n * Polymorphic: pass `as=\"a\"` (or any component) and the button becomes it\n * while keeping the same styling contract. This replaces the React-era\n * `asChild` primitive, which has no Solid equivalent that preserves props.\n */\nexport const buttonVariants = cva(\n `${controlInteractive} inline-flex shrink-0 items-center justify-center rounded-md font-medium whitespace-nowrap select-none [&_svg]:pointer-events-none [&_svg]:shrink-0`,\n {\n variants: {\n variant: {\n /** The one primary action in a view. */\n default: 'bg-primary text-primary-foreground hover:bg-primary-hover',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-surface-hover',\n /** For the action that destroys something. Never the default. */\n destructive:\n 'bg-destructive-action text-destructive-action-foreground hover:bg-destructive-action/90 focus-visible:ring-destructive-subtle',\n /** A bordered button for a surface that already has a fill. */\n outline:\n 'border border-border bg-transparent text-foreground hover:bg-surface-hover hover:border-input',\n /** No chrome until hover. The default for toolbar and row actions. */\n ghost: 'text-foreground hover:bg-surface-hover',\n /**\n * A ghost that opens something: a sheet, menu or popover trigger in a\n * toolbar. While its surface is open it holds the menubar's pressed\n * rung, so the open control never reads identical to its closed\n * neighbours.\n */\n toolbar: 'text-foreground hover:bg-surface-hover data-[expanded]:bg-surface-active',\n /** A tinted primary, for a secondary action inside a primary flow. */\n subtle: 'bg-primary-subtle text-primary hover:bg-primary-subtle/80',\n success: 'bg-success text-success-foreground hover:bg-success/90',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n '2xs': `${controlSize['2xs']} [&_svg]:size-3`,\n xs: `${controlSize.xs} [&_svg]:size-3.5`,\n sm: `${controlSize.sm} [&_svg]:size-3.5`,\n md: `${controlSize.md} [&_svg]:size-4`,\n lg: `${controlSize.lg} [&_svg]:size-4`,\n xl: `${controlSize.xl} [&_svg]:size-5`,\n '2xl': `${controlSize['2xl']} [&_svg]:size-6`,\n /* Square, for an icon with no label. The accessible name then has to\n come from `aria-label` or a visually hidden label — an icon-only\n button with neither is the accessibility finding the Storybook lane\n catches on every story. */\n 'icon-2xs': 'size-control-2xs p-0 [&_svg]:size-3',\n 'icon-xs': 'size-control-xs p-0 [&_svg]:size-3.5',\n 'icon-sm': 'size-control-sm p-0 [&_svg]:size-3.5',\n 'icon-md': 'size-control-md p-0 [&_svg]:size-4',\n 'icon-lg': 'size-control-lg p-0 [&_svg]:size-4',\n 'icon-xl': 'size-control-xl p-0 [&_svg]:size-5',\n 'icon-2xl': 'size-control-2xl p-0 [&_svg]:size-6',\n },\n /** Opt in to a stable touch target on devices with any coarse pointer. */\n touchTarget: {\n comfortable: 'touch-target-comfortable',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'md',\n },\n }\n)\n\ntype ButtonVariantProps = VariantProps<typeof buttonVariants>\n\nexport type ButtonProps<T extends ValidComponent = 'button'> = PolymorphicProps<\n T,\n ButtonVariantProps & {\n class?: string\n }\n>\n\nexport function Button<T extends ValidComponent = 'button'>(props: ButtonProps<T>) {\n const [local, rest] = splitProps(props as ButtonProps, [\n 'variant',\n 'size',\n 'touchTarget',\n 'class',\n ])\n\n return (\n <Polymorphic\n as=\"button\"\n type=\"button\"\n data-slot=\"button\"\n class={cn(\n buttonVariants({\n variant: local.variant,\n size: local.size,\n touchTarget: local.touchTarget,\n }),\n local.class\n )}\n {...(rest as ComponentProps<'button'>)}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAqBA,IAAaU,iBAAiBL,IAC5B,GAAGC,mBAAkB,sJACrB;CACEK,UAAU;EACRC,SAAS;;GAEPC,SAAS;GACTC,WAAW;;GAEXC,aACE;;GAEFC,SACE;;GAEFC,OAAO;;;;;;;GAOPC,SAAS;;GAETC,QAAQ;GACRC,SAAS;GACTC,MAAM;EACR;EACAC,MAAM;GACJ,OAAO,GAAGf,YAAY,OAAM;GAC5BgB,IAAI,GAAGhB,YAAYgB,GAAE;GACrBC,IAAI,GAAGjB,YAAYiB,GAAE;GACrBC,IAAI,GAAGlB,YAAYkB,GAAE;GACrBC,IAAI,GAAGnB,YAAYmB,GAAE;GACrBC,IAAI,GAAGpB,YAAYoB,GAAE;GACrB,OAAO,GAAGpB,YAAY,OAAM;GAK5B,YAAY;GACZ,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,WAAW;GACX,YAAY;EACd;;EAEAqB,aAAa,EACXC,aAAa,2BACf;CACF;CACAC,iBAAiB;EACflB,SAAS;EACTU,MAAM;CACR;AACF,CACF;AAWA,SAAgBa,OAA4CC,OAAuB;CACjF,MAAM,CAACC,OAAOC,QAAQnC,WAAWiC,OAAsB;EACrD;EACA;EACA;EACA;CAAO,CACR;CAED,OAAAG,gBACGvC,aAAWwC,WAAA;EACVC,IAAE;EACFC,MAAI;EAAA,aAAA;EAAA,KAAA,WAAA;GAAA,OAEGjC,GACLC,eAAe;IACbE,SAASyB,MAAMzB;IACfU,MAAMe,MAAMf;IACZM,aAAaS,MAAMT;GACrB,CAAC,GACDS,MAAMH,KACR;EAAC;CAAA,GACII,IAAgC,CAAA;AAG3C"}
@@ -147,6 +147,12 @@ export type ThemeVariant = {
147
147
  chart: readonly string[];
148
148
  provenance: ThemeProvenance;
149
149
  };
150
+ /**
151
+ * A variant's `--primary-subtle`: the tint over `var(--primary)` at the strength its
152
+ * catalogue record measures (`primarySubtleAlpha`). A variant that is not in the
153
+ * catalogue has nothing to measure, and gets its appearance's ceiling.
154
+ */
155
+ export declare function primarySubtleFor(theme: Pick<ThemeVariant, 'id' | 'appearance'>): string;
150
156
  /** The catalogue, in catalogue order. */
151
157
  export declare const builtinThemes: readonly ThemeVariant[];
152
158
  export declare function themeById(id: string): ThemeVariant | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/lib/themes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/lib/themes.ts"],"names":[],"mappings":"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"}
@@ -127,6 +127,15 @@ function toVariant(theme) {
127
127
  }
128
128
  };
129
129
  }
130
+ /**
131
+ * A variant's `--primary-subtle`: the tint over `var(--primary)` at the strength its
132
+ * catalogue record measures (`primarySubtleAlpha`). A variant that is not in the
133
+ * catalogue has nothing to measure, and gets its appearance's ceiling.
134
+ */
135
+ function primarySubtleFor(theme) {
136
+ const record = getTheme(theme.id);
137
+ return record ? primarySubtleCss(record) : primarySubtleCss(theme.appearance);
138
+ }
130
139
  /** The catalogue, in catalogue order. */
131
140
  var builtinThemes = Object.freeze(themes.map(toVariant));
132
141
  function themeById(id) {
@@ -276,7 +285,6 @@ function accentVariables(accentId, appearance, pair = {
276
285
  "--primary": roles.primary,
277
286
  "--primary-foreground": roles.primaryForeground,
278
287
  "--primary-hover": roles.primaryHover,
279
- "--primary-subtle": roles.primarySubtle,
280
288
  "--ring": roles.ring
281
289
  };
282
290
  }
@@ -302,7 +310,7 @@ function themeCssVariables(theme) {
302
310
  "--primary": c.primary,
303
311
  "--primary-foreground": c.primaryForeground,
304
312
  "--primary-hover": primaryHover(c.primary, theme.appearance),
305
- "--primary-subtle": primarySubtleCss(theme.appearance),
313
+ "--primary-subtle": primarySubtleFor(theme),
306
314
  "--secondary": c.secondary,
307
315
  "--secondary-foreground": c.secondaryForeground,
308
316
  "--muted": c.muted,
@@ -411,6 +419,6 @@ function validateThemeRegistry(themes$1 = builtinThemes) {
411
419
  var defaultLightThemeId = "adea-light";
412
420
  var defaultDarkThemeId = "adea-dark";
413
421
  //#endregion
414
- export { accentVariables, appearancePreviewThemes, builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, isThemeAccentId, resolveAccentPreset, themeAccentsFor, themeById, themeCssVariables, themeFamilies, themeRecordById, themeRecords, themesForAppearance, validateTheme, validateThemeRegistry, withAccent };
422
+ export { accentVariables, appearancePreviewThemes, builtinThemes, contrastRatio, defaultDarkThemeId, defaultLightThemeId, isThemeAccentId, primarySubtleFor, resolveAccentPreset, themeAccentsFor, themeById, themeCssVariables, themeFamilies, themeRecordById, themeRecords, themesForAppearance, validateTheme, validateThemeRegistry, withAccent };
415
423
 
416
424
  //# sourceMappingURL=themes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"themes.js","names":["catalogue","themes"],"sources":["../../src/lib/themes.ts"],"sourcesContent":["/**\n * The theme registry, now a bridge.\n *\n * The catalogue itself lives in `@adea-ai/themes`. This module is what is left in\n * the design system: the translation between the catalogue's **canonical** role\n * names and the **shadcn** vocabulary every component here is written against, plus\n * the handful of custom properties this system declares that are presentations of\n * data the catalogue already holds — the `--terminal-*` ramp, the `--editor-*` ramp,\n * and `--chrome`.\n *\n * ## Why it is a bridge and not a copy\n *\n * This file used to hold thirteen themes as hand-written hex literal tables, with its\n * own contrast validator, its own terminal and editor palettes, and its own\n * provenance records. That is a lot of surface to maintain for one consumer of a\n * palette, and it meant every product that wanted the same themes — Adea, Cortana —\n * either imported this package or wrote its own. The catalogue moved out so that\n * there is one answer to \"what is Catppuccin Mocha\", and this file is the part that\n * genuinely belongs to the design system.\n *\n * It is deliberately thin. If you are looking for a colour, it is not here: see\n * `@adea-ai/themes`, whose README explains how the values are produced and whose\n * `NOTICE` records where every palette came from.\n *\n * ## The mapping, and the entry that is not a rename\n *\n * {@link ROLE_FOR} maps canonical roles onto this system's variable vocabulary. One\n * entry will trip a reader: the catalogue's `accent` becomes this system's\n * `primary`, because in the shadcn vocabulary `--primary` is the action colour — the\n * fill of a primary button, the thing a focus ring is drawn in — while `--accent` is\n * a low-contrast hover wash. The catalogue's `accent` is the former, so it goes to\n * `--primary`, and `--accent` is filled from `surfaceHover`, which is what shadcn\n * components actually use it for.\n */\n\nimport {\n ACCENTS,\n accentForeground,\n accentRoles,\n chartSeries,\n getAccent,\n getTheme,\n hasTheme,\n shadcnDestructiveProjection,\n statusForeground,\n tint,\n primaryHover,\n primarySubtleCss,\n syntaxRoles,\n themes as catalogue,\n themesByAppearance,\n themeAccentPresets,\n validateCatalogue,\n type AccentPreset,\n type AdeaTheme,\n type AdeaThemeRecord,\n type ContrastFinding,\n} from '@adea-ai/themes'\nimport { isThemeAccentId } from './theme-accents'\n\nexport { isThemeAccentId } from './theme-accents'\n\nexport type ThemeAppearance = 'light' | 'dark'\n\n/**\n * The surface and text roles, in shadcn's vocabulary.\n *\n * Named to match the components below, which is why they differ from the\n * catalogue's: these are this system's variable names, and renaming them would mean\n * touching every component in the library for no gain.\n */\nexport type ThemeColors = {\n background: string\n foreground: string\n card: string\n cardForeground: string\n popover: string\n popoverForeground: string\n primary: string\n primaryForeground: string\n secondary: string\n secondaryForeground: string\n muted: string\n mutedForeground: string\n accent: string\n accentForeground: string\n destructive: string\n destructiveForeground: string\n destructiveSubtle: string\n /** Contrast-safe solid-action presentation, derived from the canonical error role. */\n destructiveAction: string\n destructiveActionForeground: string\n success: string\n successForeground: string\n successSubtle: string\n warning: string\n warningForeground: string\n warningSubtle: string\n info: string\n infoForeground: string\n infoSubtle: string\n border: string\n input: string\n ring: string\n sidebar: string\n sidebarForeground: string\n sidebarAccent: string\n sidebarBorder: string\n}\n\n/** The sixteen ANSI colours a terminal needs, plus its cursor and selection. */\nexport type ThemeTerminalPalette = {\n background: string\n foreground: string\n cursor: string\n selection: string\n black: string\n red: string\n green: string\n yellow: string\n blue: string\n magenta: string\n cyan: string\n white: string\n brightBlack: string\n brightRed: string\n brightGreen: string\n brightYellow: string\n brightBlue: string\n brightMagenta: string\n brightCyan: string\n brightWhite: string\n}\n\n/** The syntax roles a code view needs. */\nexport type ThemeEditorPalette = {\n keyword: string\n string: string\n number: string\n comment: string\n function: string\n variable: string\n type: string\n tag: string\n attribute: string\n operator: string\n heading: string\n link: string\n diffAdd: string\n diffDelete: string\n diffHunk: string\n searchMatch: string\n}\n\n/** Where a palette came from, and the terms it is used under. */\nexport type ThemeProvenance = {\n /** The project or person the palette belongs to. */\n source: string\n url: string\n /** An SPDX identifier. Every palette in this catalogue is permissive. */\n license: string\n}\n\nexport type ThemeVariant = {\n /** The `data-theme` value and the id a preference stores. */\n id: string\n /** Groups the variants that came from one project. */\n family: string\n familyLabel: string\n label: string\n appearance: ThemeAppearance\n /** One line, shown in a picker. */\n description: string\n colors: ThemeColors\n terminal: ThemeTerminalPalette\n editor: ThemeEditorPalette\n /** The categorical series, in order. */\n chart: readonly string[]\n provenance: ThemeProvenance\n}\n\n/**\n * Canonical role → this system's `ThemeColors` key.\n *\n * Read by {@link toVariant}. The two derived destructive-action presentation values\n * are intentionally excluded; the shared Themes adapter owns their color math.\n */\ntype ThemeRole = Exclude<keyof ThemeColors, 'destructiveAction' | 'destructiveActionForeground'>\n\nconst ROLE_FOR: Readonly<Record<ThemeRole, keyof AdeaThemeRecord['colors']>> = {\n background: 'background',\n foreground: 'text',\n card: 'surface',\n cardForeground: 'text',\n popover: 'surfaceElevated',\n popoverForeground: 'text',\n // Not a rename — see this module's header.\n primary: 'accent',\n primaryForeground: 'accentForeground',\n // shadcn's `secondary` and `muted` are both the first surface rung used as a fill.\n secondary: 'surface',\n secondaryForeground: 'text',\n muted: 'surface',\n mutedForeground: 'textMuted',\n // shadcn's `accent` is a hover wash, which is exactly `surfaceHover`.\n accent: 'surfaceHover',\n accentForeground: 'text',\n destructive: 'error',\n // Overwritten below from the measured pairing; nominal here so the table is total.\n destructiveForeground: 'error',\n destructiveSubtle: 'error',\n success: 'success',\n successForeground: 'success',\n successSubtle: 'success',\n warning: 'warning',\n warningForeground: 'warning',\n warningSubtle: 'warning',\n info: 'info',\n infoForeground: 'info',\n infoSubtle: 'info',\n border: 'border',\n input: 'border',\n ring: 'accent',\n sidebar: 'surface',\n sidebarForeground: 'text',\n sidebarAccent: 'surfaceHover',\n sidebarBorder: 'border',\n}\n\n/** Builds the design system's view of one catalogue entry. */\nfunction toVariant(theme: AdeaThemeRecord): ThemeVariant {\n const colors = {} as ThemeColors\n for (const key of Object.keys(ROLE_FOR) as ThemeRole[]) {\n colors[key] = theme.colors[ROLE_FOR[key]]\n }\n // Keep the semantic foreground paired with the canonical error role. Filled\n // destructive actions use the distinct projection below so their /90 hover state\n // remains readable without changing icons, borders, or tinted status surfaces.\n colors.destructiveForeground = statusForeground(theme, 'error')\n colors.destructiveSubtle = tint(theme.colors.error, theme.colors.background)\n const destructiveAction = shadcnDestructiveProjection(theme)\n colors.destructiveAction = destructiveAction.fill\n colors.destructiveActionForeground = destructiveAction.foreground\n colors.successForeground = statusForeground(theme, 'success')\n colors.successSubtle = tint(theme.colors.success, theme.colors.background)\n colors.warningForeground = statusForeground(theme, 'warning')\n colors.warningSubtle = tint(theme.colors.warning, theme.colors.background)\n colors.infoForeground = statusForeground(theme, 'info')\n colors.infoSubtle = tint(theme.colors.info, theme.colors.background)\n\n const syntax = syntaxRoles(theme)\n\n return {\n id: theme.id,\n family: theme.family,\n familyLabel: theme.familyLabel,\n label: theme.label,\n appearance: theme.appearance,\n description: theme.description,\n colors,\n terminal: {\n // The embedded terminal uses the theme's own canvas rather than a palette of its\n // own. The ANSI colours came from the palette that produced the canvas, so they\n // were chosen against it; a terminal on a different background would be the one\n // surface in the application not lit by the active theme.\n background: theme.colors.background,\n foreground: theme.colors.foreground,\n cursor: theme.cursor,\n selection: theme.selection,\n ...theme.ansi,\n },\n editor: {\n keyword: syntax.keyword,\n string: syntax.string,\n number: syntax.number,\n comment: syntax.comment,\n function: syntax.function,\n variable: syntax.variable,\n type: syntax.type,\n tag: syntax.tag,\n attribute: syntax.attribute,\n operator: syntax.operator,\n heading: syntax.heading,\n link: syntax.link,\n diffAdd: syntax.diffAdd,\n diffDelete: syntax.diffDelete,\n diffHunk: syntax.diffHunk,\n searchMatch: syntax.searchMatch,\n },\n chart: chartSeries(theme),\n provenance: {\n source: theme.provenance.project,\n url: theme.provenance.url,\n license: theme.provenance.license,\n },\n }\n}\n\n/** The catalogue, in catalogue order. */\nexport const builtinThemes: readonly ThemeVariant[] = Object.freeze(catalogue.map(toVariant))\n\nexport function themeById(id: string): ThemeVariant | undefined {\n if (!hasTheme(id)) return undefined\n return builtinThemes.find((theme) => theme.id === id)\n}\n\n/** The variants of one appearance, which is what a picker for that mode shows. */\nexport function themesForAppearance(appearance: ThemeAppearance): readonly ThemeVariant[] {\n const ids = new Set(themesByAppearance(appearance).map((theme) => theme.id))\n return builtinThemes.filter((theme) => ids.has(theme.id))\n}\n\n/** The families in the catalogue, in catalogue order. */\nexport function themeFamilies(): { family: string; label: string; themes: ThemeVariant[] }[] {\n const families = new Map<string, { family: string; label: string; themes: ThemeVariant[] }>()\n for (const theme of builtinThemes) {\n const entry = families.get(theme.family) ?? {\n family: theme.family,\n label: theme.familyLabel,\n themes: [],\n }\n entry.themes.push(theme)\n families.set(theme.family, entry)\n }\n return [...families.values()]\n}\n\n/** The accent presets, in the order a picker should show them. */\nexport const accents = ACCENTS\n\n/**\n * The canonical catalogue records, in catalogue order.\n *\n * {@link builtinThemes} is this system's projection of the catalogue onto the\n * shadcn vocabulary, which is what a document is painted with. A *preview* of a\n * theme — the miniatures `AppearanceEditor` and `ThemeMiniature` draw — reads the\n * catalogue's own roles instead (`surfaceActive`, `borderMuted`, `textSubtle`…),\n * several of which the projection folds together. These are those records, so a\n * consumer hands the editor exactly what it takes rather than reconstructing it\n * from the projection.\n */\nexport const themeRecords: readonly AdeaThemeRecord[] = catalogue\n\nexport function themeRecordById(id: string): AdeaThemeRecord | undefined {\n return getTheme(id)\n}\n\n/** A light/dark theme pair by id, with the defaults standing in for an unknown id. */\nfunction recordPair(lightThemeId: string, darkThemeId: string) {\n const light = getTheme(lightThemeId) ?? getTheme(defaultLightThemeId)!\n const dark = getTheme(darkThemeId) ?? getTheme(defaultDarkThemeId)!\n return { light, dark }\n}\n\n/**\n * The accents the selected light/dark pair carries — offered beside the presets.\n *\n * Computed per pair rather than per theme because a theme accent is a *pair* of\n * values, like a preset: a slot is offered only when both themes can offer it.\n */\nexport function themeAccentsFor(\n lightThemeId: string,\n darkThemeId: string\n): readonly AccentPreset[] {\n const { light, dark } = recordPair(lightThemeId, darkThemeId)\n return themeAccentPresets(light, dark)\n}\n\n/**\n * An accent id resolved against a theme pair: a preset, a theme accent the pair\n * offers, or `undefined` for `theme`, an unknown id, or a slot this pair cannot\n * offer — each of which means \"use the theme's own primary\".\n *\n * Theme accent ids are role-shaped (`ansi-blue`), so a stored one survives a theme\n * switch and resolves to the new theme's blue; when the new pair cannot offer the\n * slot it resolves to nothing, the same fallback a stale preset id gets.\n */\nexport function resolveAccentPreset(\n accentId: string,\n light: AdeaTheme,\n dark: AdeaTheme\n): AccentPreset | undefined {\n if (accentId === 'theme') return undefined\n const preset = getAccent(accentId)\n if (preset) return preset\n if (!isThemeAccentId(accentId)) return undefined\n return themeAccentPresets(light, dark).find((option) => option.id === accentId)\n}\n\n/**\n * A theme with an accent laid over it, in the catalogue's own shape.\n *\n * The accent replaces `accent` and its measured label, which is all an accent\n * changes about a theme; `undefined` returns the theme untouched. This is the\n * overlay a host needs for `AppearanceEditor`'s `lightTheme`/`darkTheme`.\n */\nexport function withAccent<T extends AdeaTheme>(theme: T, accent: AccentPreset | undefined): T {\n if (!accent) return theme\n const value = theme.appearance === 'dark' ? accent.dark : accent.light\n return {\n ...theme,\n colors: { ...theme.colors, accent: value, accentForeground: accentForeground(value) },\n }\n}\n\n/**\n * The two preview themes an appearance selection resolves to, accent applied.\n *\n * The adapter between a stored selection and `AppearanceEditor`: it takes ids —\n * what a preference holds — and returns the canonical records the editor's\n * `lightTheme` and `darkTheme` props take, so a host does not map roles by hand.\n * Unknown ids fall back to the defaults and an accent the pair cannot offer falls\n * back to the theme's own, exactly as `ThemeProvider` resolves them.\n */\nexport function appearancePreviewThemes(selection: {\n lightThemeId: string\n darkThemeId: string\n accent: string\n}): { lightTheme: AdeaThemeRecord; darkTheme: AdeaThemeRecord } {\n const { light, dark } = recordPair(selection.lightThemeId, selection.darkThemeId)\n const accent = resolveAccentPreset(selection.accent, light, dark)\n return { lightTheme: withAccent(light, accent), darkTheme: withAccent(dark, accent) }\n}\n\n/**\n * The properties an accent selection overrides, as CSS custom properties.\n *\n * ## Why this exists rather than relying on the `[data-accent]` blocks\n *\n * `theme.css` carries a `[data-accent='…']` block per preset, and those blocks are\n * correct — but they are unreachable at runtime. `ThemeProvider` writes a theme's\n * whole role set onto `<html>` as *inline* custom properties, and an inline\n * declaration outranks any stylesheet selector regardless of specificity. The\n * attribute was set, the rules existed, the values were right, and every one of the\n * seven accents rendered as the same blue.\n *\n * The blocks are kept, because they are what styles the window between the document\n * arriving and the provider mounting — which is the whole reason `themeScript`\n * exists. But the authoritative value has to be applied by the same code that\n * applies the theme, from the same source, or the two can drift again. So both the\n * provider and the CSS generator call `accentRoles` out of `@adea-ai/themes`, and\n * `tests/appearance-axes.test.ts` asserts the two agree value for value.\n *\n * A theme accent (`ansi-blue`) has no block: its value depends on the theme pair,\n * so it is resolved against `pair` — the selection's light and dark theme ids —\n * and only ever applied here. Without a pair it resolves against the defaults.\n *\n * Returns `undefined` for `theme` — the variant's own primary — for an id the\n * catalogue does not have, and for a theme accent the pair does not offer, so a\n * stale stored preference falls back to the theme rather than blanking the primary.\n */\nexport function accentVariables(\n accentId: string,\n appearance: ThemeAppearance,\n pair: { lightThemeId: string; darkThemeId: string } = {\n lightThemeId: defaultLightThemeId,\n darkThemeId: defaultDarkThemeId,\n }\n): Record<string, string> | undefined {\n if (accentId === 'theme') return undefined\n const { light, dark } = recordPair(pair.lightThemeId, pair.darkThemeId)\n const preset = resolveAccentPreset(accentId, light, dark)\n if (!preset) return undefined\n\n const roles = accentRoles(preset, appearance)\n return {\n '--primary': roles.primary,\n '--primary-foreground': roles.primaryForeground,\n '--primary-hover': roles.primaryHover,\n '--primary-subtle': roles.primarySubtle,\n '--ring': roles.ring,\n }\n}\n\n/**\n * The roles a variant sets, as CSS custom properties.\n *\n * The one place that knows the mapping from a theme's roles to this system's variable\n * names. A provider applies this; nothing else repeats it. The `--terminal-*` and\n * `--editor-*` ramps are presentations of the catalogue's ANSI and syntax data rather\n * than separate roles, which is why they are built here and not in the catalogue.\n */\nexport function themeCssVariables(theme: ThemeVariant): Record<string, string> {\n const c = theme.colors\n const t = theme.terminal\n const e = theme.editor\n return {\n '--background': c.background,\n '--foreground': c.foreground,\n '--card': c.card,\n '--card-foreground': c.cardForeground,\n '--popover': c.popover,\n '--popover-foreground': c.popoverForeground,\n '--primary': c.primary,\n '--primary-foreground': c.primaryForeground,\n /*\n * The two tokens derived from the primary, and they are here rather than left to\n * `theme.css` because they must follow `--primary` — which this function writes\n * for *any* theme in the catalogue, not just the two defaults `theme.css` carries.\n *\n * `--primary-hover` is a resolved colour, not a `color-mix()`: a uniform hover\n * step cannot be expressed as a mix (see `primaryHover`). Left out, a theme switch\n * would keep the previous theme's hover on the new theme's primary.\n *\n * `--primary-subtle` is a mix over `--primary`, so it would follow on its own —\n * it is written anyway so the pair is applied together and neither is left to\n * depend on which stylesheet happened to load.\n */\n '--primary-hover': primaryHover(c.primary, theme.appearance),\n '--primary-subtle': primarySubtleCss(theme.appearance),\n '--secondary': c.secondary,\n '--secondary-foreground': c.secondaryForeground,\n '--muted': c.muted,\n '--muted-foreground': c.mutedForeground,\n '--accent': c.accent,\n '--accent-foreground': c.accentForeground,\n '--destructive': c.destructive,\n '--destructive-foreground': c.destructiveForeground,\n '--destructive-subtle': c.destructiveSubtle,\n '--destructive-action': c.destructiveAction,\n '--destructive-action-foreground': c.destructiveActionForeground,\n '--success': c.success,\n '--success-foreground': c.successForeground,\n '--success-subtle': c.successSubtle,\n '--warning': c.warning,\n '--warning-foreground': c.warningForeground,\n '--warning-subtle': c.warningSubtle,\n '--info': c.info,\n '--info-foreground': c.infoForeground,\n '--info-subtle': c.infoSubtle,\n '--border': c.border,\n '--input': c.input,\n '--ring': c.ring,\n '--sidebar': c.sidebar,\n '--sidebar-foreground': c.sidebarForeground,\n '--sidebar-accent': c.sidebarAccent,\n '--sidebar-border': c.sidebarBorder,\n '--sidebar-primary': c.primary,\n '--sidebar-primary-foreground': c.primaryForeground,\n '--sidebar-ring': c.ring,\n '--sidebar-muted-foreground': c.mutedForeground,\n '--surface-sunken': c.muted,\n '--surface-hover': c.accent,\n '--surface-active': c.border,\n '--chrome': c.background,\n '--terminal-background': t.background,\n '--terminal-foreground': t.foreground,\n '--terminal-cursor': t.cursor,\n '--terminal-selection': t.selection,\n '--terminal-ansi-black': t.black,\n '--terminal-ansi-red': t.red,\n '--terminal-ansi-green': t.green,\n '--terminal-ansi-yellow': t.yellow,\n '--terminal-ansi-blue': t.blue,\n '--terminal-ansi-magenta': t.magenta,\n '--terminal-ansi-cyan': t.cyan,\n '--terminal-ansi-white': t.white,\n '--terminal-ansi-bright-black': t.brightBlack,\n '--terminal-ansi-bright-red': t.brightRed,\n '--terminal-ansi-bright-green': t.brightGreen,\n '--terminal-ansi-bright-yellow': t.brightYellow,\n '--terminal-ansi-bright-blue': t.brightBlue,\n '--terminal-ansi-bright-magenta': t.brightMagenta,\n '--terminal-ansi-bright-cyan': t.brightCyan,\n '--terminal-ansi-bright-white': t.brightWhite,\n '--editor-keyword': e.keyword,\n '--editor-string': e.string,\n '--editor-number': e.number,\n '--editor-comment': e.comment,\n '--editor-function': e.function,\n '--editor-variable': e.variable,\n '--editor-type': e.type,\n '--editor-tag': e.tag,\n '--editor-attribute': e.attribute,\n '--editor-operator': e.operator,\n '--editor-heading': e.heading,\n '--editor-link': e.link,\n '--editor-diff-add': e.diffAdd,\n '--editor-diff-delete': e.diffDelete,\n '--editor-diff-hunk': e.diffHunk,\n '--editor-search-match': e.searchMatch,\n '--chart-1': theme.chart[0] ?? c.primary,\n '--chart-2': theme.chart[1] ?? c.info,\n '--chart-3': theme.chart[2] ?? c.success,\n '--chart-4': theme.chart[3] ?? c.warning,\n '--chart-5': theme.chart[4] ?? c.destructive,\n '--chart-6': theme.chart[5] ?? c.mutedForeground,\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Validation\n *\n * Delegated. The floors are the catalogue's, because they are what makes the\n * catalogue able to hold other people's palettes at all, and a second set of floors\n * here would be a second answer to the same question — and the one that drifts.\n * ------------------------------------------------------------------------- */\n\nexport type ThemeFinding = {\n themeId: string\n role: string\n message: string\n}\n\nfunction toFinding(finding: ContrastFinding): ThemeFinding {\n return { themeId: finding.themeId, role: finding.role, message: finding.message }\n}\n\n/** Validates one variant. The floors, and the reasoning behind them, live in the catalogue. */\nexport function validateTheme(theme: ThemeVariant): ThemeFinding[] {\n const record = catalogue.find((entry) => entry.id === theme.id)\n if (!record) {\n return [{ themeId: theme.id, role: 'id', message: `${theme.id} is not in the catalogue` }]\n }\n return validateCatalogue([record]).map(toFinding)\n}\n\n/** Validates the whole registry, including the catalogue-level invariants. */\nexport function validateThemeRegistry(\n themes: readonly ThemeVariant[] = builtinThemes\n): ThemeFinding[] {\n const records = themes\n .map((theme) => catalogue.find((entry) => entry.id === theme.id))\n .filter((record): record is AdeaThemeRecord => !!record)\n\n const orphaned = themes\n .filter((theme) => !hasTheme(theme.id))\n .map((theme) => ({\n themeId: theme.id,\n role: 'id',\n message: `${theme.id} is in the registry but not in the catalogue`,\n }))\n\n return [...orphaned, ...validateCatalogue(records).map(toFinding)]\n}\n\nexport const defaultLightThemeId = 'adea-light'\nexport const defaultDarkThemeId = 'adea-dark'\n\n/** Re-exported so a consumer measuring a colour does not need a second import. */\nexport { contrastRatio } from '@adea-ai/themes'\n"],"mappings":"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"}
1
+ {"version":3,"file":"themes.js","names":["catalogue","themes"],"sources":["../../src/lib/themes.ts"],"sourcesContent":["/**\n * The theme registry, now a bridge.\n *\n * The catalogue itself lives in `@adea-ai/themes`. This module is what is left in\n * the design system: the translation between the catalogue's **canonical** role\n * names and the **shadcn** vocabulary every component here is written against, plus\n * the handful of custom properties this system declares that are presentations of\n * data the catalogue already holds — the `--terminal-*` ramp, the `--editor-*` ramp,\n * and `--chrome`.\n *\n * ## Why it is a bridge and not a copy\n *\n * This file used to hold thirteen themes as hand-written hex literal tables, with its\n * own contrast validator, its own terminal and editor palettes, and its own\n * provenance records. That is a lot of surface to maintain for one consumer of a\n * palette, and it meant every product that wanted the same themes — Adea, Cortana —\n * either imported this package or wrote its own. The catalogue moved out so that\n * there is one answer to \"what is Catppuccin Mocha\", and this file is the part that\n * genuinely belongs to the design system.\n *\n * It is deliberately thin. If you are looking for a colour, it is not here: see\n * `@adea-ai/themes`, whose README explains how the values are produced and whose\n * `NOTICE` records where every palette came from.\n *\n * ## The mapping, and the entry that is not a rename\n *\n * {@link ROLE_FOR} maps canonical roles onto this system's variable vocabulary. One\n * entry will trip a reader: the catalogue's `accent` becomes this system's\n * `primary`, because in the shadcn vocabulary `--primary` is the action colour — the\n * fill of a primary button, the thing a focus ring is drawn in — while `--accent` is\n * a low-contrast hover wash. The catalogue's `accent` is the former, so it goes to\n * `--primary`, and `--accent` is filled from `surfaceHover`, which is what shadcn\n * components actually use it for.\n */\n\nimport {\n ACCENTS,\n accentForeground,\n accentRoles,\n chartSeries,\n getAccent,\n getTheme,\n hasTheme,\n shadcnDestructiveProjection,\n statusForeground,\n tint,\n primaryHover,\n primarySubtleCss,\n syntaxRoles,\n themes as catalogue,\n themesByAppearance,\n themeAccentPresets,\n validateCatalogue,\n type AccentPreset,\n type AdeaTheme,\n type AdeaThemeRecord,\n type ContrastFinding,\n} from '@adea-ai/themes'\nimport { isThemeAccentId } from './theme-accents'\n\nexport { isThemeAccentId } from './theme-accents'\n\nexport type ThemeAppearance = 'light' | 'dark'\n\n/**\n * The surface and text roles, in shadcn's vocabulary.\n *\n * Named to match the components below, which is why they differ from the\n * catalogue's: these are this system's variable names, and renaming them would mean\n * touching every component in the library for no gain.\n */\nexport type ThemeColors = {\n background: string\n foreground: string\n card: string\n cardForeground: string\n popover: string\n popoverForeground: string\n primary: string\n primaryForeground: string\n secondary: string\n secondaryForeground: string\n muted: string\n mutedForeground: string\n accent: string\n accentForeground: string\n destructive: string\n destructiveForeground: string\n destructiveSubtle: string\n /** Contrast-safe solid-action presentation, derived from the canonical error role. */\n destructiveAction: string\n destructiveActionForeground: string\n success: string\n successForeground: string\n successSubtle: string\n warning: string\n warningForeground: string\n warningSubtle: string\n info: string\n infoForeground: string\n infoSubtle: string\n border: string\n input: string\n ring: string\n sidebar: string\n sidebarForeground: string\n sidebarAccent: string\n sidebarBorder: string\n}\n\n/** The sixteen ANSI colours a terminal needs, plus its cursor and selection. */\nexport type ThemeTerminalPalette = {\n background: string\n foreground: string\n cursor: string\n selection: string\n black: string\n red: string\n green: string\n yellow: string\n blue: string\n magenta: string\n cyan: string\n white: string\n brightBlack: string\n brightRed: string\n brightGreen: string\n brightYellow: string\n brightBlue: string\n brightMagenta: string\n brightCyan: string\n brightWhite: string\n}\n\n/** The syntax roles a code view needs. */\nexport type ThemeEditorPalette = {\n keyword: string\n string: string\n number: string\n comment: string\n function: string\n variable: string\n type: string\n tag: string\n attribute: string\n operator: string\n heading: string\n link: string\n diffAdd: string\n diffDelete: string\n diffHunk: string\n searchMatch: string\n}\n\n/** Where a palette came from, and the terms it is used under. */\nexport type ThemeProvenance = {\n /** The project or person the palette belongs to. */\n source: string\n url: string\n /** An SPDX identifier. Every palette in this catalogue is permissive. */\n license: string\n}\n\nexport type ThemeVariant = {\n /** The `data-theme` value and the id a preference stores. */\n id: string\n /** Groups the variants that came from one project. */\n family: string\n familyLabel: string\n label: string\n appearance: ThemeAppearance\n /** One line, shown in a picker. */\n description: string\n colors: ThemeColors\n terminal: ThemeTerminalPalette\n editor: ThemeEditorPalette\n /** The categorical series, in order. */\n chart: readonly string[]\n provenance: ThemeProvenance\n}\n\n/**\n * Canonical role → this system's `ThemeColors` key.\n *\n * Read by {@link toVariant}. The two derived destructive-action presentation values\n * are intentionally excluded; the shared Themes adapter owns their color math.\n */\ntype ThemeRole = Exclude<keyof ThemeColors, 'destructiveAction' | 'destructiveActionForeground'>\n\nconst ROLE_FOR: Readonly<Record<ThemeRole, keyof AdeaThemeRecord['colors']>> = {\n background: 'background',\n foreground: 'text',\n card: 'surface',\n cardForeground: 'text',\n popover: 'surfaceElevated',\n popoverForeground: 'text',\n // Not a rename — see this module's header.\n primary: 'accent',\n primaryForeground: 'accentForeground',\n // shadcn's `secondary` and `muted` are both the first surface rung used as a fill.\n secondary: 'surface',\n secondaryForeground: 'text',\n muted: 'surface',\n mutedForeground: 'textMuted',\n // shadcn's `accent` is a hover wash, which is exactly `surfaceHover`.\n accent: 'surfaceHover',\n accentForeground: 'text',\n destructive: 'error',\n // Overwritten below from the measured pairing; nominal here so the table is total.\n destructiveForeground: 'error',\n destructiveSubtle: 'error',\n success: 'success',\n successForeground: 'success',\n successSubtle: 'success',\n warning: 'warning',\n warningForeground: 'warning',\n warningSubtle: 'warning',\n info: 'info',\n infoForeground: 'info',\n infoSubtle: 'info',\n border: 'border',\n input: 'border',\n ring: 'accent',\n sidebar: 'surface',\n sidebarForeground: 'text',\n sidebarAccent: 'surfaceHover',\n sidebarBorder: 'border',\n}\n\n/** Builds the design system's view of one catalogue entry. */\nfunction toVariant(theme: AdeaThemeRecord): ThemeVariant {\n const colors = {} as ThemeColors\n for (const key of Object.keys(ROLE_FOR) as ThemeRole[]) {\n colors[key] = theme.colors[ROLE_FOR[key]]\n }\n // Keep the semantic foreground paired with the canonical error role. Filled\n // destructive actions use the distinct projection below so their /90 hover state\n // remains readable without changing icons, borders, or tinted status surfaces.\n colors.destructiveForeground = statusForeground(theme, 'error')\n colors.destructiveSubtle = tint(theme.colors.error, theme.colors.background)\n const destructiveAction = shadcnDestructiveProjection(theme)\n colors.destructiveAction = destructiveAction.fill\n colors.destructiveActionForeground = destructiveAction.foreground\n colors.successForeground = statusForeground(theme, 'success')\n colors.successSubtle = tint(theme.colors.success, theme.colors.background)\n colors.warningForeground = statusForeground(theme, 'warning')\n colors.warningSubtle = tint(theme.colors.warning, theme.colors.background)\n colors.infoForeground = statusForeground(theme, 'info')\n colors.infoSubtle = tint(theme.colors.info, theme.colors.background)\n\n const syntax = syntaxRoles(theme)\n\n return {\n id: theme.id,\n family: theme.family,\n familyLabel: theme.familyLabel,\n label: theme.label,\n appearance: theme.appearance,\n description: theme.description,\n colors,\n terminal: {\n // The embedded terminal uses the theme's own canvas rather than a palette of its\n // own. The ANSI colours came from the palette that produced the canvas, so they\n // were chosen against it; a terminal on a different background would be the one\n // surface in the application not lit by the active theme.\n background: theme.colors.background,\n foreground: theme.colors.foreground,\n cursor: theme.cursor,\n selection: theme.selection,\n ...theme.ansi,\n },\n editor: {\n keyword: syntax.keyword,\n string: syntax.string,\n number: syntax.number,\n comment: syntax.comment,\n function: syntax.function,\n variable: syntax.variable,\n type: syntax.type,\n tag: syntax.tag,\n attribute: syntax.attribute,\n operator: syntax.operator,\n heading: syntax.heading,\n link: syntax.link,\n diffAdd: syntax.diffAdd,\n diffDelete: syntax.diffDelete,\n diffHunk: syntax.diffHunk,\n searchMatch: syntax.searchMatch,\n },\n chart: chartSeries(theme),\n provenance: {\n source: theme.provenance.project,\n url: theme.provenance.url,\n license: theme.provenance.license,\n },\n }\n}\n\n/**\n * A variant's `--primary-subtle`: the tint over `var(--primary)` at the strength its\n * catalogue record measures (`primarySubtleAlpha`). A variant that is not in the\n * catalogue has nothing to measure, and gets its appearance's ceiling.\n */\nexport function primarySubtleFor(theme: Pick<ThemeVariant, 'id' | 'appearance'>): string {\n const record = getTheme(theme.id)\n return record ? primarySubtleCss(record) : primarySubtleCss(theme.appearance)\n}\n\n/** The catalogue, in catalogue order. */\nexport const builtinThemes: readonly ThemeVariant[] = Object.freeze(catalogue.map(toVariant))\n\nexport function themeById(id: string): ThemeVariant | undefined {\n if (!hasTheme(id)) return undefined\n return builtinThemes.find((theme) => theme.id === id)\n}\n\n/** The variants of one appearance, which is what a picker for that mode shows. */\nexport function themesForAppearance(appearance: ThemeAppearance): readonly ThemeVariant[] {\n const ids = new Set(themesByAppearance(appearance).map((theme) => theme.id))\n return builtinThemes.filter((theme) => ids.has(theme.id))\n}\n\n/** The families in the catalogue, in catalogue order. */\nexport function themeFamilies(): { family: string; label: string; themes: ThemeVariant[] }[] {\n const families = new Map<string, { family: string; label: string; themes: ThemeVariant[] }>()\n for (const theme of builtinThemes) {\n const entry = families.get(theme.family) ?? {\n family: theme.family,\n label: theme.familyLabel,\n themes: [],\n }\n entry.themes.push(theme)\n families.set(theme.family, entry)\n }\n return [...families.values()]\n}\n\n/** The accent presets, in the order a picker should show them. */\nexport const accents = ACCENTS\n\n/**\n * The canonical catalogue records, in catalogue order.\n *\n * {@link builtinThemes} is this system's projection of the catalogue onto the\n * shadcn vocabulary, which is what a document is painted with. A *preview* of a\n * theme — the miniatures `AppearanceEditor` and `ThemeMiniature` draw — reads the\n * catalogue's own roles instead (`surfaceActive`, `borderMuted`, `textSubtle`…),\n * several of which the projection folds together. These are those records, so a\n * consumer hands the editor exactly what it takes rather than reconstructing it\n * from the projection.\n */\nexport const themeRecords: readonly AdeaThemeRecord[] = catalogue\n\nexport function themeRecordById(id: string): AdeaThemeRecord | undefined {\n return getTheme(id)\n}\n\n/** A light/dark theme pair by id, with the defaults standing in for an unknown id. */\nfunction recordPair(lightThemeId: string, darkThemeId: string) {\n const light = getTheme(lightThemeId) ?? getTheme(defaultLightThemeId)!\n const dark = getTheme(darkThemeId) ?? getTheme(defaultDarkThemeId)!\n return { light, dark }\n}\n\n/**\n * The accents the selected light/dark pair carries — offered beside the presets.\n *\n * Computed per pair rather than per theme because a theme accent is a *pair* of\n * values, like a preset: a slot is offered only when both themes can offer it.\n */\nexport function themeAccentsFor(\n lightThemeId: string,\n darkThemeId: string\n): readonly AccentPreset[] {\n const { light, dark } = recordPair(lightThemeId, darkThemeId)\n return themeAccentPresets(light, dark)\n}\n\n/**\n * An accent id resolved against a theme pair: a preset, a theme accent the pair\n * offers, or `undefined` for `theme`, an unknown id, or a slot this pair cannot\n * offer — each of which means \"use the theme's own primary\".\n *\n * Theme accent ids are role-shaped (`ansi-blue`), so a stored one survives a theme\n * switch and resolves to the new theme's blue; when the new pair cannot offer the\n * slot it resolves to nothing, the same fallback a stale preset id gets.\n */\nexport function resolveAccentPreset(\n accentId: string,\n light: AdeaTheme,\n dark: AdeaTheme\n): AccentPreset | undefined {\n if (accentId === 'theme') return undefined\n const preset = getAccent(accentId)\n if (preset) return preset\n if (!isThemeAccentId(accentId)) return undefined\n return themeAccentPresets(light, dark).find((option) => option.id === accentId)\n}\n\n/**\n * A theme with an accent laid over it, in the catalogue's own shape.\n *\n * The accent replaces `accent` and its measured label, which is all an accent\n * changes about a theme; `undefined` returns the theme untouched. This is the\n * overlay a host needs for `AppearanceEditor`'s `lightTheme`/`darkTheme`.\n */\nexport function withAccent<T extends AdeaTheme>(theme: T, accent: AccentPreset | undefined): T {\n if (!accent) return theme\n const value = theme.appearance === 'dark' ? accent.dark : accent.light\n return {\n ...theme,\n colors: { ...theme.colors, accent: value, accentForeground: accentForeground(value) },\n }\n}\n\n/**\n * The two preview themes an appearance selection resolves to, accent applied.\n *\n * The adapter between a stored selection and `AppearanceEditor`: it takes ids —\n * what a preference holds — and returns the canonical records the editor's\n * `lightTheme` and `darkTheme` props take, so a host does not map roles by hand.\n * Unknown ids fall back to the defaults and an accent the pair cannot offer falls\n * back to the theme's own, exactly as `ThemeProvider` resolves them.\n */\nexport function appearancePreviewThemes(selection: {\n lightThemeId: string\n darkThemeId: string\n accent: string\n}): { lightTheme: AdeaThemeRecord; darkTheme: AdeaThemeRecord } {\n const { light, dark } = recordPair(selection.lightThemeId, selection.darkThemeId)\n const accent = resolveAccentPreset(selection.accent, light, dark)\n return { lightTheme: withAccent(light, accent), darkTheme: withAccent(dark, accent) }\n}\n\n/**\n * The properties an accent selection overrides, as CSS custom properties.\n *\n * ## Why this exists rather than relying on the `[data-accent]` blocks\n *\n * `theme.css` carries a `[data-accent='…']` block per preset, and those blocks are\n * correct — but they are unreachable at runtime. `ThemeProvider` writes a theme's\n * whole role set onto `<html>` as *inline* custom properties, and an inline\n * declaration outranks any stylesheet selector regardless of specificity. The\n * attribute was set, the rules existed, the values were right, and every one of the\n * seven accents rendered as the same blue.\n *\n * The blocks are kept, because they are what styles the window between the document\n * arriving and the provider mounting — which is the whole reason `themeScript`\n * exists. But the authoritative value has to be applied by the same code that\n * applies the theme, from the same source, or the two can drift again. So both the\n * provider and the CSS generator call `accentRoles` out of `@adea-ai/themes`, and\n * `tests/appearance-axes.test.ts` asserts the two agree value for value.\n *\n * A theme accent (`ansi-blue`) has no block: its value depends on the theme pair,\n * so it is resolved against `pair` — the selection's light and dark theme ids —\n * and only ever applied here. Without a pair it resolves against the defaults.\n *\n * Returns `undefined` for `theme` — the variant's own primary — for an id the\n * catalogue does not have, and for a theme accent the pair does not offer, so a\n * stale stored preference falls back to the theme rather than blanking the primary.\n */\nexport function accentVariables(\n accentId: string,\n appearance: ThemeAppearance,\n pair: { lightThemeId: string; darkThemeId: string } = {\n lightThemeId: defaultLightThemeId,\n darkThemeId: defaultDarkThemeId,\n }\n): Record<string, string> | undefined {\n if (accentId === 'theme') return undefined\n const { light, dark } = recordPair(pair.lightThemeId, pair.darkThemeId)\n const preset = resolveAccentPreset(accentId, light, dark)\n if (!preset) return undefined\n\n // `--primary-subtle` is deliberately not here. It is a `color-mix()` over\n // `var(--primary)`, so the theme's own declaration (`themeCssVariables`, or the\n // default block in `theme.css`) already follows the accent; and its strength is the\n // *theme's*, measured by `primarySubtleAlpha` to hold body text at 4.5:1 for every\n // accent the theme offers. Writing one here would replace that measured strength\n // with whatever this function was given, which is how an accent used to undo it.\n const roles = accentRoles(preset, appearance)\n return {\n '--primary': roles.primary,\n '--primary-foreground': roles.primaryForeground,\n '--primary-hover': roles.primaryHover,\n '--ring': roles.ring,\n }\n}\n\n/**\n * The roles a variant sets, as CSS custom properties.\n *\n * The one place that knows the mapping from a theme's roles to this system's variable\n * names. A provider applies this; nothing else repeats it. The `--terminal-*` and\n * `--editor-*` ramps are presentations of the catalogue's ANSI and syntax data rather\n * than separate roles, which is why they are built here and not in the catalogue.\n */\nexport function themeCssVariables(theme: ThemeVariant): Record<string, string> {\n const c = theme.colors\n const t = theme.terminal\n const e = theme.editor\n return {\n '--background': c.background,\n '--foreground': c.foreground,\n '--card': c.card,\n '--card-foreground': c.cardForeground,\n '--popover': c.popover,\n '--popover-foreground': c.popoverForeground,\n '--primary': c.primary,\n '--primary-foreground': c.primaryForeground,\n /*\n * The two tokens derived from the primary, and they are here rather than left to\n * `theme.css` because they must follow `--primary` — which this function writes\n * for *any* theme in the catalogue, not just the two defaults `theme.css` carries.\n *\n * `--primary-hover` is a resolved colour, not a `color-mix()`: a uniform hover\n * step cannot be expressed as a mix (see `primaryHover`). Left out, a theme switch\n * would keep the previous theme's hover on the new theme's primary.\n *\n * `--primary-subtle` is a mix over `--primary`, so it follows an accent on its\n * own, but its *strength* is per theme: `primarySubtleCss(record)` lowers the\n * appearance ceiling only as far as this theme needs for body text to clear 4.5:1\n * on the tint, over every surface, for every accent it offers. It has to be\n * written per theme for that reason — the appearance-wide value is not legible on\n * every palette.\n */\n '--primary-hover': primaryHover(c.primary, theme.appearance),\n '--primary-subtle': primarySubtleFor(theme),\n '--secondary': c.secondary,\n '--secondary-foreground': c.secondaryForeground,\n '--muted': c.muted,\n '--muted-foreground': c.mutedForeground,\n '--accent': c.accent,\n '--accent-foreground': c.accentForeground,\n '--destructive': c.destructive,\n '--destructive-foreground': c.destructiveForeground,\n '--destructive-subtle': c.destructiveSubtle,\n '--destructive-action': c.destructiveAction,\n '--destructive-action-foreground': c.destructiveActionForeground,\n '--success': c.success,\n '--success-foreground': c.successForeground,\n '--success-subtle': c.successSubtle,\n '--warning': c.warning,\n '--warning-foreground': c.warningForeground,\n '--warning-subtle': c.warningSubtle,\n '--info': c.info,\n '--info-foreground': c.infoForeground,\n '--info-subtle': c.infoSubtle,\n '--border': c.border,\n '--input': c.input,\n '--ring': c.ring,\n '--sidebar': c.sidebar,\n '--sidebar-foreground': c.sidebarForeground,\n '--sidebar-accent': c.sidebarAccent,\n '--sidebar-border': c.sidebarBorder,\n '--sidebar-primary': c.primary,\n '--sidebar-primary-foreground': c.primaryForeground,\n '--sidebar-ring': c.ring,\n '--sidebar-muted-foreground': c.mutedForeground,\n '--surface-sunken': c.muted,\n '--surface-hover': c.accent,\n '--surface-active': c.border,\n '--chrome': c.background,\n '--terminal-background': t.background,\n '--terminal-foreground': t.foreground,\n '--terminal-cursor': t.cursor,\n '--terminal-selection': t.selection,\n '--terminal-ansi-black': t.black,\n '--terminal-ansi-red': t.red,\n '--terminal-ansi-green': t.green,\n '--terminal-ansi-yellow': t.yellow,\n '--terminal-ansi-blue': t.blue,\n '--terminal-ansi-magenta': t.magenta,\n '--terminal-ansi-cyan': t.cyan,\n '--terminal-ansi-white': t.white,\n '--terminal-ansi-bright-black': t.brightBlack,\n '--terminal-ansi-bright-red': t.brightRed,\n '--terminal-ansi-bright-green': t.brightGreen,\n '--terminal-ansi-bright-yellow': t.brightYellow,\n '--terminal-ansi-bright-blue': t.brightBlue,\n '--terminal-ansi-bright-magenta': t.brightMagenta,\n '--terminal-ansi-bright-cyan': t.brightCyan,\n '--terminal-ansi-bright-white': t.brightWhite,\n '--editor-keyword': e.keyword,\n '--editor-string': e.string,\n '--editor-number': e.number,\n '--editor-comment': e.comment,\n '--editor-function': e.function,\n '--editor-variable': e.variable,\n '--editor-type': e.type,\n '--editor-tag': e.tag,\n '--editor-attribute': e.attribute,\n '--editor-operator': e.operator,\n '--editor-heading': e.heading,\n '--editor-link': e.link,\n '--editor-diff-add': e.diffAdd,\n '--editor-diff-delete': e.diffDelete,\n '--editor-diff-hunk': e.diffHunk,\n '--editor-search-match': e.searchMatch,\n '--chart-1': theme.chart[0] ?? c.primary,\n '--chart-2': theme.chart[1] ?? c.info,\n '--chart-3': theme.chart[2] ?? c.success,\n '--chart-4': theme.chart[3] ?? c.warning,\n '--chart-5': theme.chart[4] ?? c.destructive,\n '--chart-6': theme.chart[5] ?? c.mutedForeground,\n }\n}\n\n/* ---------------------------------------------------------------------------\n * Validation\n *\n * Delegated. The floors are the catalogue's, because they are what makes the\n * catalogue able to hold other people's palettes at all, and a second set of floors\n * here would be a second answer to the same question — and the one that drifts.\n * ------------------------------------------------------------------------- */\n\nexport type ThemeFinding = {\n themeId: string\n role: string\n message: string\n}\n\nfunction toFinding(finding: ContrastFinding): ThemeFinding {\n return { themeId: finding.themeId, role: finding.role, message: finding.message }\n}\n\n/** Validates one variant. The floors, and the reasoning behind them, live in the catalogue. */\nexport function validateTheme(theme: ThemeVariant): ThemeFinding[] {\n const record = catalogue.find((entry) => entry.id === theme.id)\n if (!record) {\n return [{ themeId: theme.id, role: 'id', message: `${theme.id} is not in the catalogue` }]\n }\n return validateCatalogue([record]).map(toFinding)\n}\n\n/** Validates the whole registry, including the catalogue-level invariants. */\nexport function validateThemeRegistry(\n themes: readonly ThemeVariant[] = builtinThemes\n): ThemeFinding[] {\n const records = themes\n .map((theme) => catalogue.find((entry) => entry.id === theme.id))\n .filter((record): record is AdeaThemeRecord => !!record)\n\n const orphaned = themes\n .filter((theme) => !hasTheme(theme.id))\n .map((theme) => ({\n themeId: theme.id,\n role: 'id',\n message: `${theme.id} is in the registry but not in the catalogue`,\n }))\n\n return [...orphaned, ...validateCatalogue(records).map(toFinding)]\n}\n\nexport const defaultLightThemeId = 'adea-light'\nexport const defaultDarkThemeId = 'adea-dark'\n\n/** Re-exported so a consumer measuring a colour does not need a second import. */\nexport { contrastRatio } from '@adea-ai/themes'\n"],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  "title": "Appearance Editor",
5
5
  "description": "",
6
6
  "dependencies": [
7
- "@adea-ai/themes@^0.9.7",
7
+ "@adea-ai/themes@^0.9.10",
8
8
  "@kobalte/core@^0.13.14",
9
9
  "lucide-solid@^1.51.0"
10
10
  ],
package/dist/r/lib.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "title": "Class-name and token helpers",
5
5
  "description": "The private helpers the components import: the class-name merge, the variant recipes, the token manifest and the theme bridge. Installed automatically as a peer of any component that needs it.",
6
6
  "dependencies": [
7
- "@adea-ai/themes@^0.9.7",
7
+ "@adea-ai/themes@^0.9.10",
8
8
  "class-variance-authority@^0.7.1",
9
9
  "cn@^0.4.0"
10
10
  ],
@@ -1993,7 +1993,7 @@
1993
1993
  "title": "Appearance Editor",
1994
1994
  "description": "",
1995
1995
  "dependencies": [
1996
- "@adea-ai/themes@^0.9.7",
1996
+ "@adea-ai/themes@^0.9.10",
1997
1997
  "@kobalte/core@^0.13.14",
1998
1998
  "lucide-solid@^1.51.0"
1999
1999
  ],
@@ -2462,7 +2462,7 @@
2462
2462
  "title": "Theming",
2463
2463
  "description": "",
2464
2464
  "dependencies": [
2465
- "@adea-ai/themes@^0.9.7",
2465
+ "@adea-ai/themes@^0.9.10",
2466
2466
  "@kobalte/core@^0.13.14",
2467
2467
  "lucide-solid@^1.51.0"
2468
2468
  ],
@@ -2577,7 +2577,7 @@
2577
2577
  "title": "Class-name and token helpers",
2578
2578
  "description": "The private helpers the components import: the class-name merge, the variant recipes, the token manifest and the theme bridge. Installed automatically as a peer of any component that needs it.",
2579
2579
  "dependencies": [
2580
- "@adea-ai/themes@^0.9.7",
2580
+ "@adea-ai/themes@^0.9.10",
2581
2581
  "class-variance-authority@^0.7.1",
2582
2582
  "cn@^0.4.0"
2583
2583
  ],
@@ -35,6 +35,13 @@ export const buttonVariants = cva(
35
35
  'border border-border bg-transparent text-foreground hover:bg-surface-hover hover:border-input',
36
36
  /** No chrome until hover. The default for toolbar and row actions. */
37
37
  ghost: 'text-foreground hover:bg-surface-hover',
38
+ /**
39
+ * A ghost that opens something: a sheet, menu or popover trigger in a
40
+ * toolbar. While its surface is open it holds the menubar's pressed
41
+ * rung, so the open control never reads identical to its closed
42
+ * neighbours.
43
+ */
44
+ toolbar: 'text-foreground hover:bg-surface-hover data-[expanded]:bg-surface-active',
38
45
  /** A tinted primary, for a secondary action inside a primary flow. */
39
46
  subtle: 'bg-primary-subtle text-primary hover:bg-primary-subtle/80',
40
47
  success: 'bg-success text-success-foreground hover:bg-success/90',
@@ -296,6 +296,16 @@ function toVariant(theme: AdeaThemeRecord): ThemeVariant {
296
296
  }
297
297
  }
298
298
 
299
+ /**
300
+ * A variant's `--primary-subtle`: the tint over `var(--primary)` at the strength its
301
+ * catalogue record measures (`primarySubtleAlpha`). A variant that is not in the
302
+ * catalogue has nothing to measure, and gets its appearance's ceiling.
303
+ */
304
+ export function primarySubtleFor(theme: Pick<ThemeVariant, 'id' | 'appearance'>): string {
305
+ const record = getTheme(theme.id)
306
+ return record ? primarySubtleCss(record) : primarySubtleCss(theme.appearance)
307
+ }
308
+
299
309
  /** The catalogue, in catalogue order. */
300
310
  export const builtinThemes: readonly ThemeVariant[] = Object.freeze(catalogue.map(toVariant))
301
311
 
@@ -462,12 +472,17 @@ export function accentVariables(
462
472
  const preset = resolveAccentPreset(accentId, light, dark)
463
473
  if (!preset) return undefined
464
474
 
475
+ // `--primary-subtle` is deliberately not here. It is a `color-mix()` over
476
+ // `var(--primary)`, so the theme's own declaration (`themeCssVariables`, or the
477
+ // default block in `theme.css`) already follows the accent; and its strength is the
478
+ // *theme's*, measured by `primarySubtleAlpha` to hold body text at 4.5:1 for every
479
+ // accent the theme offers. Writing one here would replace that measured strength
480
+ // with whatever this function was given, which is how an accent used to undo it.
465
481
  const roles = accentRoles(preset, appearance)
466
482
  return {
467
483
  '--primary': roles.primary,
468
484
  '--primary-foreground': roles.primaryForeground,
469
485
  '--primary-hover': roles.primaryHover,
470
- '--primary-subtle': roles.primarySubtle,
471
486
  '--ring': roles.ring,
472
487
  }
473
488
  }
@@ -502,12 +517,15 @@ export function themeCssVariables(theme: ThemeVariant): Record<string, string> {
502
517
  * step cannot be expressed as a mix (see `primaryHover`). Left out, a theme switch
503
518
  * would keep the previous theme's hover on the new theme's primary.
504
519
  *
505
- * `--primary-subtle` is a mix over `--primary`, so it would follow on its own —
506
- * it is written anyway so the pair is applied together and neither is left to
507
- * depend on which stylesheet happened to load.
520
+ * `--primary-subtle` is a mix over `--primary`, so it follows an accent on its
521
+ * own, but its *strength* is per theme: `primarySubtleCss(record)` lowers the
522
+ * appearance ceiling only as far as this theme needs for body text to clear 4.5:1
523
+ * on the tint, over every surface, for every accent it offers. It has to be
524
+ * written per theme for that reason — the appearance-wide value is not legible on
525
+ * every palette.
508
526
  */
509
527
  '--primary-hover': primaryHover(c.primary, theme.appearance),
510
- '--primary-subtle': primarySubtleCss(theme.appearance),
528
+ '--primary-subtle': primarySubtleFor(theme),
511
529
  '--secondary': c.secondary,
512
530
  '--secondary-foreground': c.secondaryForeground,
513
531
  '--muted': c.muted,
@@ -153,6 +153,11 @@
153
153
  * rule rather than a matching one — which is what they were not, before.
154
154
  */
155
155
  --primary-hover: oklch(0.4643 0.1668 301.69);
156
+ /*
157
+ * The selected-state tint. A share of `--primary`, so it follows an accent with
158
+ * no block of its own; the share is this theme's, measured by @adea-ai/themes so
159
+ * body text clears 4.5:1 on it over every surface, for every accent it offers.
160
+ */
156
161
  --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
157
162
  /* The window chrome, one step off the canvas. */
158
163
  --chrome: var(--surface);
@@ -283,6 +288,11 @@
283
288
  * rule rather than a matching one — which is what they were not, before.
284
289
  */
285
290
  --primary-hover: oklch(0.7823 0.1668 301.69);
291
+ /*
292
+ * The selected-state tint. A share of `--primary`, so it follows an accent with
293
+ * no block of its own; the share is this theme's, measured by @adea-ai/themes so
294
+ * body text clears 4.5:1 on it over every surface, for every accent it offers.
295
+ */
286
296
  --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
287
297
  /* The window chrome, one step off the canvas. */
288
298
  --chrome: var(--surface);
@@ -310,7 +320,13 @@
310
320
  * adea's six accent presets, as a selection rather than a constant. `data-accent` sits on
311
321
  * the same element as `dark` — in both applications that is `<html>` — and each
312
322
  * block overrides the roles an accent owns: the interactive primary, its label,
313
- * its hover rung, its tint and the focus ring.
323
+ * its hover rung and the focus ring.
324
+ *
325
+ * The tint, `--primary-subtle`, is not one of them. It is a share of `var(--primary)`
326
+ * declared on the same element, so it already follows the accent; and the share is
327
+ * the theme's own, measured by @adea-ai/themes so body text clears 4.5:1 on it. A
328
+ * block keyed only on the appearance could carry only the appearance-wide ceiling,
329
+ * which would undo that measurement for every theme that needs a lighter wash.
314
330
  *
315
331
  * The values are adea's accent presets, passed through the same two rules
316
332
  * `deriveAccentRoles` applies in the product:
@@ -330,14 +346,12 @@
330
346
  --primary: oklch(0.4907 0.2412 292.58);
331
347
  --primary-foreground: oklch(1 0 0);
332
348
  --primary-hover: oklch(0.4407 0.2412 292.58);
333
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
334
349
  --ring: oklch(0.4907 0.2412 292.58);
335
350
  }
336
351
  .dark[data-accent='violet'] {
337
352
  --primary: oklch(0.709 0.1592 293.54);
338
353
  --primary-foreground: oklch(0 0 0);
339
354
  --primary-hover: oklch(0.759 0.1592 293.54);
340
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
341
355
  --ring: oklch(0.709 0.1592 293.54);
342
356
  }
343
357
 
@@ -345,14 +359,12 @@
345
359
  --primary: oklch(0.5461 0.2152 262.88);
346
360
  --primary-foreground: oklch(1 0 0);
347
361
  --primary-hover: oklch(0.4961 0.2152 262.88);
348
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
349
362
  --ring: oklch(0.5461 0.2152 262.88);
350
363
  }
351
364
  .dark[data-accent='blue'] {
352
365
  --primary: oklch(0.7137 0.1434 254.62);
353
366
  --primary-foreground: oklch(0 0 0);
354
367
  --primary-hover: oklch(0.7637 0.1434 254.62);
355
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
356
368
  --ring: oklch(0.7137 0.1434 254.62);
357
369
  }
358
370
 
@@ -360,14 +372,12 @@
360
372
  --primary: oklch(0.5273 0.1371 150.07);
361
373
  --primary-foreground: oklch(1 0 0);
362
374
  --primary-hover: oklch(0.4773 0.1371 150.07);
363
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
364
375
  --ring: oklch(0.5273 0.1371 150.07);
365
376
  }
366
377
  .dark[data-accent='green'] {
367
378
  --primary: oklch(0.8003 0.1821 151.71);
368
379
  --primary-foreground: oklch(0 0 0);
369
380
  --primary-hover: oklch(0.8503 0.1363 151.71);
370
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
371
381
  --ring: oklch(0.8003 0.1821 151.71);
372
382
  }
373
383
 
@@ -375,14 +385,12 @@
375
385
  --primary: oklch(0.5553 0.1455 49);
376
386
  --primary-foreground: oklch(1 0 0);
377
387
  --primary-hover: oklch(0.5053 0.1455 49);
378
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
379
388
  --ring: oklch(0.5553 0.1455 49);
380
389
  }
381
390
  .dark[data-accent='amber'] {
382
391
  --primary: oklch(0.8369 0.1644 84.43);
383
392
  --primary-foreground: oklch(0 0 0);
384
393
  --primary-hover: oklch(0.8869 0.0991 84.43);
385
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
386
394
  --ring: oklch(0.8369 0.1644 84.43);
387
395
  }
388
396
 
@@ -390,14 +398,12 @@
390
398
  --primary: oklch(0.5198 0.0936 223.13);
391
399
  --primary-foreground: oklch(1 0 0);
392
400
  --primary-hover: oklch(0.4698 0.0936 223.13);
393
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
394
401
  --ring: oklch(0.5198 0.0936 223.13);
395
402
  }
396
403
  .dark[data-accent='cyan'] {
397
404
  --primary: oklch(0.7971 0.1339 211.53);
398
405
  --primary-foreground: oklch(0 0 0);
399
406
  --primary-hover: oklch(0.8471 0.102 211.53);
400
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
401
407
  --ring: oklch(0.7971 0.1339 211.53);
402
408
  }
403
409
 
@@ -405,14 +411,12 @@
405
411
  --primary: oklch(0.5246 0.199 3.96);
406
412
  --primary-foreground: oklch(1 0 0);
407
413
  --primary-hover: oklch(0.4746 0.199 3.96);
408
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
409
414
  --ring: oklch(0.5246 0.199 3.96);
410
415
  }
411
416
  .dark[data-accent='pink'] {
412
417
  --primary: oklch(0.7253 0.1752 349.76);
413
418
  --primary-foreground: oklch(0 0 0);
414
419
  --primary-hover: oklch(0.7753 0.1752 349.76);
415
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
416
420
  --ring: oklch(0.7253 0.1752 349.76);
417
421
  }
418
422
  /* @end generated accents */
@@ -4,7 +4,7 @@
4
4
  "title": "Theming",
5
5
  "description": "",
6
6
  "dependencies": [
7
- "@adea-ai/themes@^0.9.7",
7
+ "@adea-ai/themes@^0.9.10",
8
8
  "@kobalte/core@^0.13.14",
9
9
  "lucide-solid@^1.51.0"
10
10
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adea-ai/ui",
3
- "version": "0.119.0",
3
+ "version": "0.120.0",
4
4
  "description": "The Adea design system: Kobalte-backed Solid components, semantic OKLCH tokens, and the app-shell layout primitives shared by Adea and Cortana.",
5
5
  "keywords": [
6
6
  "adea",
@@ -129,7 +129,7 @@
129
129
  "check:packed-paste-model": "node scripts/check-packed-paste-model.mjs"
130
130
  },
131
131
  "dependencies": {
132
- "@adea-ai/themes": "^0.9.7",
132
+ "@adea-ai/themes": "^0.9.10",
133
133
  "@corvu/calendar": "^0.1.2",
134
134
  "@corvu/drawer": "^0.2.4",
135
135
  "@corvu/otp-field": "^0.1.4",
package/registry.json CHANGED
@@ -1993,7 +1993,7 @@
1993
1993
  "title": "Appearance Editor",
1994
1994
  "description": "",
1995
1995
  "dependencies": [
1996
- "@adea-ai/themes@^0.9.7",
1996
+ "@adea-ai/themes@^0.9.10",
1997
1997
  "@kobalte/core@^0.13.14",
1998
1998
  "lucide-solid@^1.51.0"
1999
1999
  ],
@@ -2462,7 +2462,7 @@
2462
2462
  "title": "Theming",
2463
2463
  "description": "",
2464
2464
  "dependencies": [
2465
- "@adea-ai/themes@^0.9.7",
2465
+ "@adea-ai/themes@^0.9.10",
2466
2466
  "@kobalte/core@^0.13.14",
2467
2467
  "lucide-solid@^1.51.0"
2468
2468
  ],
@@ -2577,7 +2577,7 @@
2577
2577
  "title": "Class-name and token helpers",
2578
2578
  "description": "The private helpers the components import: the class-name merge, the variant recipes, the token manifest and the theme bridge. Installed automatically as a peer of any component that needs it.",
2579
2579
  "dependencies": [
2580
- "@adea-ai/themes@^0.9.7",
2580
+ "@adea-ai/themes@^0.9.10",
2581
2581
  "class-variance-authority@^0.7.1",
2582
2582
  "cn@^0.4.0"
2583
2583
  ],
@@ -35,6 +35,13 @@ export const buttonVariants = cva(
35
35
  'border border-border bg-transparent text-foreground hover:bg-surface-hover hover:border-input',
36
36
  /** No chrome until hover. The default for toolbar and row actions. */
37
37
  ghost: 'text-foreground hover:bg-surface-hover',
38
+ /**
39
+ * A ghost that opens something: a sheet, menu or popover trigger in a
40
+ * toolbar. While its surface is open it holds the menubar's pressed
41
+ * rung, so the open control never reads identical to its closed
42
+ * neighbours.
43
+ */
44
+ toolbar: 'text-foreground hover:bg-surface-hover data-[expanded]:bg-surface-active',
38
45
  /** A tinted primary, for a secondary action inside a primary flow. */
39
46
  subtle: 'bg-primary-subtle text-primary hover:bg-primary-subtle/80',
40
47
  success: 'bg-success text-success-foreground hover:bg-success/90',
package/src/lib/themes.ts CHANGED
@@ -296,6 +296,16 @@ function toVariant(theme: AdeaThemeRecord): ThemeVariant {
296
296
  }
297
297
  }
298
298
 
299
+ /**
300
+ * A variant's `--primary-subtle`: the tint over `var(--primary)` at the strength its
301
+ * catalogue record measures (`primarySubtleAlpha`). A variant that is not in the
302
+ * catalogue has nothing to measure, and gets its appearance's ceiling.
303
+ */
304
+ export function primarySubtleFor(theme: Pick<ThemeVariant, 'id' | 'appearance'>): string {
305
+ const record = getTheme(theme.id)
306
+ return record ? primarySubtleCss(record) : primarySubtleCss(theme.appearance)
307
+ }
308
+
299
309
  /** The catalogue, in catalogue order. */
300
310
  export const builtinThemes: readonly ThemeVariant[] = Object.freeze(catalogue.map(toVariant))
301
311
 
@@ -462,12 +472,17 @@ export function accentVariables(
462
472
  const preset = resolveAccentPreset(accentId, light, dark)
463
473
  if (!preset) return undefined
464
474
 
475
+ // `--primary-subtle` is deliberately not here. It is a `color-mix()` over
476
+ // `var(--primary)`, so the theme's own declaration (`themeCssVariables`, or the
477
+ // default block in `theme.css`) already follows the accent; and its strength is the
478
+ // *theme's*, measured by `primarySubtleAlpha` to hold body text at 4.5:1 for every
479
+ // accent the theme offers. Writing one here would replace that measured strength
480
+ // with whatever this function was given, which is how an accent used to undo it.
465
481
  const roles = accentRoles(preset, appearance)
466
482
  return {
467
483
  '--primary': roles.primary,
468
484
  '--primary-foreground': roles.primaryForeground,
469
485
  '--primary-hover': roles.primaryHover,
470
- '--primary-subtle': roles.primarySubtle,
471
486
  '--ring': roles.ring,
472
487
  }
473
488
  }
@@ -502,12 +517,15 @@ export function themeCssVariables(theme: ThemeVariant): Record<string, string> {
502
517
  * step cannot be expressed as a mix (see `primaryHover`). Left out, a theme switch
503
518
  * would keep the previous theme's hover on the new theme's primary.
504
519
  *
505
- * `--primary-subtle` is a mix over `--primary`, so it would follow on its own —
506
- * it is written anyway so the pair is applied together and neither is left to
507
- * depend on which stylesheet happened to load.
520
+ * `--primary-subtle` is a mix over `--primary`, so it follows an accent on its
521
+ * own, but its *strength* is per theme: `primarySubtleCss(record)` lowers the
522
+ * appearance ceiling only as far as this theme needs for body text to clear 4.5:1
523
+ * on the tint, over every surface, for every accent it offers. It has to be
524
+ * written per theme for that reason — the appearance-wide value is not legible on
525
+ * every palette.
508
526
  */
509
527
  '--primary-hover': primaryHover(c.primary, theme.appearance),
510
- '--primary-subtle': primarySubtleCss(theme.appearance),
528
+ '--primary-subtle': primarySubtleFor(theme),
511
529
  '--secondary': c.secondary,
512
530
  '--secondary-foreground': c.secondaryForeground,
513
531
  '--muted': c.muted,
@@ -153,6 +153,11 @@
153
153
  * rule rather than a matching one — which is what they were not, before.
154
154
  */
155
155
  --primary-hover: oklch(0.4643 0.1668 301.69);
156
+ /*
157
+ * The selected-state tint. A share of `--primary`, so it follows an accent with
158
+ * no block of its own; the share is this theme's, measured by @adea-ai/themes so
159
+ * body text clears 4.5:1 on it over every surface, for every accent it offers.
160
+ */
156
161
  --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
157
162
  /* The window chrome, one step off the canvas. */
158
163
  --chrome: var(--surface);
@@ -283,6 +288,11 @@
283
288
  * rule rather than a matching one — which is what they were not, before.
284
289
  */
285
290
  --primary-hover: oklch(0.7823 0.1668 301.69);
291
+ /*
292
+ * The selected-state tint. A share of `--primary`, so it follows an accent with
293
+ * no block of its own; the share is this theme's, measured by @adea-ai/themes so
294
+ * body text clears 4.5:1 on it over every surface, for every accent it offers.
295
+ */
286
296
  --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
287
297
  /* The window chrome, one step off the canvas. */
288
298
  --chrome: var(--surface);
@@ -310,7 +320,13 @@
310
320
  * adea's six accent presets, as a selection rather than a constant. `data-accent` sits on
311
321
  * the same element as `dark` — in both applications that is `<html>` — and each
312
322
  * block overrides the roles an accent owns: the interactive primary, its label,
313
- * its hover rung, its tint and the focus ring.
323
+ * its hover rung and the focus ring.
324
+ *
325
+ * The tint, `--primary-subtle`, is not one of them. It is a share of `var(--primary)`
326
+ * declared on the same element, so it already follows the accent; and the share is
327
+ * the theme's own, measured by @adea-ai/themes so body text clears 4.5:1 on it. A
328
+ * block keyed only on the appearance could carry only the appearance-wide ceiling,
329
+ * which would undo that measurement for every theme that needs a lighter wash.
314
330
  *
315
331
  * The values are adea's accent presets, passed through the same two rules
316
332
  * `deriveAccentRoles` applies in the product:
@@ -330,14 +346,12 @@
330
346
  --primary: oklch(0.4907 0.2412 292.58);
331
347
  --primary-foreground: oklch(1 0 0);
332
348
  --primary-hover: oklch(0.4407 0.2412 292.58);
333
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
334
349
  --ring: oklch(0.4907 0.2412 292.58);
335
350
  }
336
351
  .dark[data-accent='violet'] {
337
352
  --primary: oklch(0.709 0.1592 293.54);
338
353
  --primary-foreground: oklch(0 0 0);
339
354
  --primary-hover: oklch(0.759 0.1592 293.54);
340
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
341
355
  --ring: oklch(0.709 0.1592 293.54);
342
356
  }
343
357
 
@@ -345,14 +359,12 @@
345
359
  --primary: oklch(0.5461 0.2152 262.88);
346
360
  --primary-foreground: oklch(1 0 0);
347
361
  --primary-hover: oklch(0.4961 0.2152 262.88);
348
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
349
362
  --ring: oklch(0.5461 0.2152 262.88);
350
363
  }
351
364
  .dark[data-accent='blue'] {
352
365
  --primary: oklch(0.7137 0.1434 254.62);
353
366
  --primary-foreground: oklch(0 0 0);
354
367
  --primary-hover: oklch(0.7637 0.1434 254.62);
355
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
356
368
  --ring: oklch(0.7137 0.1434 254.62);
357
369
  }
358
370
 
@@ -360,14 +372,12 @@
360
372
  --primary: oklch(0.5273 0.1371 150.07);
361
373
  --primary-foreground: oklch(1 0 0);
362
374
  --primary-hover: oklch(0.4773 0.1371 150.07);
363
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
364
375
  --ring: oklch(0.5273 0.1371 150.07);
365
376
  }
366
377
  .dark[data-accent='green'] {
367
378
  --primary: oklch(0.8003 0.1821 151.71);
368
379
  --primary-foreground: oklch(0 0 0);
369
380
  --primary-hover: oklch(0.8503 0.1363 151.71);
370
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
371
381
  --ring: oklch(0.8003 0.1821 151.71);
372
382
  }
373
383
 
@@ -375,14 +385,12 @@
375
385
  --primary: oklch(0.5553 0.1455 49);
376
386
  --primary-foreground: oklch(1 0 0);
377
387
  --primary-hover: oklch(0.5053 0.1455 49);
378
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
379
388
  --ring: oklch(0.5553 0.1455 49);
380
389
  }
381
390
  .dark[data-accent='amber'] {
382
391
  --primary: oklch(0.8369 0.1644 84.43);
383
392
  --primary-foreground: oklch(0 0 0);
384
393
  --primary-hover: oklch(0.8869 0.0991 84.43);
385
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
386
394
  --ring: oklch(0.8369 0.1644 84.43);
387
395
  }
388
396
 
@@ -390,14 +398,12 @@
390
398
  --primary: oklch(0.5198 0.0936 223.13);
391
399
  --primary-foreground: oklch(1 0 0);
392
400
  --primary-hover: oklch(0.4698 0.0936 223.13);
393
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
394
401
  --ring: oklch(0.5198 0.0936 223.13);
395
402
  }
396
403
  .dark[data-accent='cyan'] {
397
404
  --primary: oklch(0.7971 0.1339 211.53);
398
405
  --primary-foreground: oklch(0 0 0);
399
406
  --primary-hover: oklch(0.8471 0.102 211.53);
400
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
401
407
  --ring: oklch(0.7971 0.1339 211.53);
402
408
  }
403
409
 
@@ -405,14 +411,12 @@
405
411
  --primary: oklch(0.5246 0.199 3.96);
406
412
  --primary-foreground: oklch(1 0 0);
407
413
  --primary-hover: oklch(0.4746 0.199 3.96);
408
- --primary-subtle: color-mix(in oklch, var(--primary) 10%, transparent);
409
414
  --ring: oklch(0.5246 0.199 3.96);
410
415
  }
411
416
  .dark[data-accent='pink'] {
412
417
  --primary: oklch(0.7253 0.1752 349.76);
413
418
  --primary-foreground: oklch(0 0 0);
414
419
  --primary-hover: oklch(0.7753 0.1752 349.76);
415
- --primary-subtle: color-mix(in oklch, var(--primary) 16%, transparent);
416
420
  --ring: oklch(0.7253 0.1752 349.76);
417
421
  }
418
422
  /* @end generated accents */