diff --git a/src/uix/eidos/generated/base.css b/src/uix/eidos/generated/base.css index a6e1b8de8..76263901a 100644 --- a/src/uix/eidos/generated/base.css +++ b/src/uix/eidos/generated/base.css @@ -1605,22 +1605,30 @@ --button-transition-ease: var(--ease-default); --button-spinner-duration: 720ms; --button-disabled-opacity: 0.5; + --button-primary-track: var(--color-primary-track); --button-primary-element: var(--color-primary-element); + --button-primary-border: var(--color-primary-border); --button-primary-solid: var(--color-primary-solid); --button-primary-solid-hover: var(--color-primary-solid-hover); --button-primary-text: var(--color-primary-text); --button-primary-contrast: var(--color-primary-contrast); + --button-secondary-track: var(--color-secondary-track); --button-secondary-element: var(--color-secondary-element); + --button-secondary-border: var(--color-secondary-border); --button-secondary-solid: var(--color-secondary-solid); --button-secondary-solid-hover: var(--color-secondary-solid-hover); --button-secondary-text: var(--color-secondary-text); --button-secondary-contrast: var(--color-secondary-contrast); + --button-neutral-track: var(--color-neutral-track); --button-neutral-element: var(--color-neutral-element); + --button-neutral-border: var(--color-neutral-border); --button-neutral-solid: var(--color-neutral-solid); --button-neutral-solid-hover: var(--color-neutral-solid-hover); --button-neutral-text: var(--color-neutral-text); --button-neutral-contrast: var(--color-neutral-contrast); + --button-affirm-track: var(--color-affirm-track); --button-affirm-element: var(--color-affirm-element); + --button-affirm-border: var(--color-affirm-border); --button-affirm-solid: var(--color-affirm-solid); --button-affirm-solid-hover: var(--color-affirm-solid-hover); --button-affirm-text: var(--color-affirm-text); @@ -1632,12 +1640,16 @@ --button-fulfill-solid-hover: var(--color-fulfill-solid-hover); --button-fulfill-text: var(--color-fulfill-text); --button-fulfill-contrast: var(--color-fulfill-contrast); + --button-risk-track: var(--color-risk-track); --button-risk-element: var(--color-risk-element); + --button-risk-border: var(--color-risk-border); --button-risk-solid: var(--color-risk-solid); --button-risk-solid-hover: var(--color-risk-solid-hover); --button-risk-text: var(--color-risk-text); --button-risk-contrast: var(--color-risk-contrast); + --button-threat-track: var(--color-threat-track); --button-threat-element: var(--color-threat-element); + --button-threat-border: var(--color-threat-border); --button-threat-solid: var(--color-threat-solid); --button-threat-solid-hover: var(--color-threat-solid-hover); --button-threat-text: var(--color-threat-text); diff --git a/src/uix/eidos/lib/recipes/base.ts b/src/uix/eidos/lib/recipes/base.ts index 10d5a691c..bdae36c01 100644 --- a/src/uix/eidos/lib/recipes/base.ts +++ b/src/uix/eidos/lib/recipes/base.ts @@ -1512,23 +1512,34 @@ export const THEME_BASE_RECIPE_TOKENS = { 'transition-ease': 'var(--ease-default)', 'spinner-duration': '720ms', 'disabled-opacity': '0.5', - // Per-color palettes (8 system tokens) + // Per-color palettes — 7 slots per color, uniform across all 8: track / + // element / border / solid / solid-hover / text / contrast. soft + surface + // + outline variants read track/border, so every color must define them + // (was only fulfill/loss — the others rendered with no bg/border). + 'primary-track': 'var(--color-primary-track)', 'primary-element': 'var(--color-primary-element)', + 'primary-border': 'var(--color-primary-border)', 'primary-solid': 'var(--color-primary-solid)', 'primary-solid-hover': 'var(--color-primary-solid-hover)', 'primary-text': 'var(--color-primary-text)', 'primary-contrast': 'var(--color-primary-contrast)', + 'secondary-track': 'var(--color-secondary-track)', 'secondary-element': 'var(--color-secondary-element)', + 'secondary-border': 'var(--color-secondary-border)', 'secondary-solid': 'var(--color-secondary-solid)', 'secondary-solid-hover': 'var(--color-secondary-solid-hover)', 'secondary-text': 'var(--color-secondary-text)', 'secondary-contrast': 'var(--color-secondary-contrast)', + 'neutral-track': 'var(--color-neutral-track)', 'neutral-element': 'var(--color-neutral-element)', + 'neutral-border': 'var(--color-neutral-border)', 'neutral-solid': 'var(--color-neutral-solid)', 'neutral-solid-hover': 'var(--color-neutral-solid-hover)', 'neutral-text': 'var(--color-neutral-text)', 'neutral-contrast': 'var(--color-neutral-contrast)', + 'affirm-track': 'var(--color-affirm-track)', 'affirm-element': 'var(--color-affirm-element)', + 'affirm-border': 'var(--color-affirm-border)', 'affirm-solid': 'var(--color-affirm-solid)', 'affirm-solid-hover': 'var(--color-affirm-solid-hover)', 'affirm-text': 'var(--color-affirm-text)', @@ -1540,12 +1551,16 @@ export const THEME_BASE_RECIPE_TOKENS = { 'fulfill-solid-hover': 'var(--color-fulfill-solid-hover)', 'fulfill-text': 'var(--color-fulfill-text)', 'fulfill-contrast': 'var(--color-fulfill-contrast)', + 'risk-track': 'var(--color-risk-track)', 'risk-element': 'var(--color-risk-element)', + 'risk-border': 'var(--color-risk-border)', 'risk-solid': 'var(--color-risk-solid)', 'risk-solid-hover': 'var(--color-risk-solid-hover)', 'risk-text': 'var(--color-risk-text)', 'risk-contrast': 'var(--color-risk-contrast)', + 'threat-track': 'var(--color-threat-track)', 'threat-element': 'var(--color-threat-element)', + 'threat-border': 'var(--color-threat-border)', 'threat-solid': 'var(--color-threat-solid)', 'threat-solid-hover': 'var(--color-threat-solid-hover)', 'threat-text': 'var(--color-threat-text)', @@ -3227,7 +3242,8 @@ export const THEME_BASE_RECIPE_TOKENS = { // base theme (invisible against panels), so the track uses the same // visible-track mix as Progress: a light tint of content-primary on the // surface. Reads on white AND dark, and follows the theme. - 'track-bg': 'color-mix(in srgb, var(--color-content-primary) 12%, var(--color-surface-default))', + 'track-bg': + 'color-mix(in srgb, var(--color-content-primary) 12%, var(--color-surface-default))', 'range-bg': 'var(--color-primary-solid)', 'thumb-radius': 'var(--radius-full)', 'thumb-border-width': 'var(--border-width)', diff --git a/web/routes/uix/components/button/+page.svelte b/web/routes/uix/components/button/+page.svelte index 61f953e12..0b4fe5de8 100644 --- a/web/routes/uix/components/button/+page.svelte +++ b/web/routes/uix/components/button/+page.svelte @@ -30,7 +30,7 @@ x: Icon.X } as const; - type Tab = 'live' | 'api' | 'morfo' | 'sema' | 'recipe' | 'a11y'; + type Tab = 'live' | 'gallery' | 'api' | 'morfo' | 'sema' | 'recipe' | 'a11y'; let tab = $state('live'); const variants: ButtonVariant[] = ['solid', 'soft', 'surface', 'outline', 'ghost', 'plain']; @@ -40,6 +40,20 @@ const colors: Array<'primary' | 'secondary' | 'neutral'> = ['primary', 'secondary', 'neutral']; const types: Array<'button' | 'submit' | 'reset'> = ['button', 'submit', 'reset']; + // Gallery: all 8 color roles. Hierarchy (primary/secondary/neutral) rides the + // `color` prop; the evaluative palette (affirm/fulfill/risk/threat/loss) rides + // `intent`, which wins on data-color. + const gallery: Array<{ name: string; color?: 'primary' | 'secondary' | 'neutral'; intent: ButtonIntent }> = [ + { name: 'primary', color: 'primary', intent: 'neutral' }, + { name: 'secondary', color: 'secondary', intent: 'neutral' }, + { name: 'neutral', color: 'neutral', intent: 'neutral' }, + { name: 'affirm', intent: 'affirm' }, + { name: 'fulfill', intent: 'fulfill' }, + { name: 'risk', intent: 'risk' }, + { name: 'threat', intent: 'threat' }, + { name: 'loss', intent: 'loss' } + ]; + // ── Live state ──────────────────────────────────────────────────────── // Soma let intent = $state('neutral'); @@ -244,6 +258,9 @@
+ @@ -455,6 +472,32 @@ {/if} + {#if tab === 'gallery'} +
+

Variants × colors

+

+ Every eidos variant across all 8 color roles. + Hierarchy (primary / secondary / neutral) rides the + color prop; the evaluative palette (affirm / fulfill + / risk / threat / loss) rides intent, + which wins on data-color. +

+
+ {#each variants as v} +
+ {v} + {#each gallery as c} + + {/each} +
+ {/each} +
+
+ {/if} + {#if tab === 'api'}

API reference