Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
49fba84
feat: add semantic CSS tokens from design system
Myestery Oct 16, 2025
3936626
refactor: replace hex colors with semantic tokens in selection toolbox
Myestery Oct 16, 2025
233f1eb
refactor: replace hex colors with semantic tokens in widget components
Myestery Oct 16, 2025
b9da142
refactor: replace dark-theme classes with semantic tokens in graph co…
Myestery Oct 16, 2025
1e93d84
refactor: replace dark-theme classes with semantic tokens in input co…
Myestery Oct 16, 2025
1e8a6cd
refactor: replace dark-theme classes with semantic tokens in UI compo…
Myestery Oct 16, 2025
81d5dc7
refactor: replace dark-theme classes with semantic tokens in layout c…
Myestery Oct 16, 2025
325cfaf
refactor: replace dark-theme classes with semantic tokens in asset co…
Myestery Oct 16, 2025
4eec033
refactor: replace dark-theme classes with semantic tokens in widget e…
Myestery Oct 16, 2025
25c9860
refactor: replace dark-theme classes with semantic tokens in manager …
Myestery Oct 16, 2025
6650b29
refactor: replace dark-theme classes with semantic tokens in dialog a…
Myestery Oct 16, 2025
333cf02
refactor: replace dark-theme classes with semantic tokens in story files
Myestery Oct 16, 2025
354b69a
feat: add ESLint rules to enforce semantic token usage
Myestery Oct 16, 2025
a405934
refactor: remove redundant test for normal styling in BypassButton co…
Myestery Oct 16, 2025
fdafd0a
Merge remote-tracking branch 'origin/main' into css-token-standardiza…
Myestery Oct 17, 2025
6f744e7
fix(tests): update class names in NodeConflictDialogContent tests to …
Myestery Oct 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,12 @@ export default defineConfig([
'no-console': ['error', { allow: ['warn', 'error'] }],
'tailwindcss/no-custom-classname': 'off', // TODO: fix
'vue/no-v-html': 'off',
// Enforce dark-theme: instead of dark: prefix
'vue/no-restricted-class': ['error', '/^dark:/'],
// Enforce semantic CSS tokens:
'vue/no-restricted-class': [
'error',
'/^dark:/',
'/^(bg|text|border|fill|stroke)-\\[#/'
],
'vue/multi-word-component-names': 'off', // TODO: fix
'vue/no-template-shadow': 'off', // TODO: fix
'vue/match-component-import-name': 'error',
Expand Down
225 changes: 225 additions & 0 deletions packages/design-system/src/css/style.css
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think with a lot of this we're getting too granular.
For example: --text-blue and --accent-blue and --button-surface-blue having tokens.

What we'd want is just something like --warning: var(--color-ochre-700); --warning-surface: var(--color-stone-300);, not multiple warning/success/etc for each aspect of each context. We want fewer theme tokens that are more versatile (so that users who want to customize don't have to define 200 separate colors).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would that be changed by designers or coders?

Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,81 @@
--text-secondary: var(--color-stone-100);
--text-primary: var(--color-charcoal-700);
--input-surface: rgba(0, 0, 0, 0.15);

/* Semantic tokens from tokens.csv - Light Mode */
--text-contrast: var(--color-pure-white);
--text-danger-error: var(--color-danger-200);
--text-warning: var(--color-warning-200);
--text-success: var(--color-success-200);
--text-blue: var(--color-blue-100);
--text-highlight: var(--color-blue-selection);
--accent-secondary: var(--color-stone-100);
--accent-contrast: var(--color-pure-white);
--accent-danger-error: var(--color-danger-200);
--accent-warning: var(--color-warning-200);
--accent-success: var(--color-success-200);
--accent-blue: var(--color-blue-100);
--accent-white: var(--color-pure-white);
--button-surface: var(--color-gray-100);
--button-surface-hovered: var(--color-gray-300);
--button-surface-danger: var(--color-danger-200);
--button-surface-blue: var(--color-blue-200);
--button-surface-contrast: var(--color-pure-black);
--button-bkg-secondary: var(--color-gray-400);
--button-bkg-info: var(--color-slate-100);
--button-icon: var(--color-stone-200);
--button-icon-disabled: var(--color-alpha-gray-500-50);
--interface-canvas-background: var(--color-gray-400);
--interface-icon: var(--color-slate-100);
--interface-panel-component-surface-hovered: var(--color-gray-200);
--interface-panel-component-surface-selected: var(--color-gray-400);
--interface-panel-card-surface: var(--color-gray-100);
--interface-panel-card-surface-hover: var(--color-gray-200);
--interface-panel-job-progress-primary: var(--color-blue-400);
--interface-panel-job-progress-secondary: var(--color-blue-selection);
--interface-menu-surface: var(--color-pure-white);
--interface-menu-stroke: var(--color-gray-400);
--interface-menu-keybind-surface-blue: var(--color-blue-400);
--interface-workflow-tab-surface: var(--color-gray-300);
--interface-workflow-tab-surface-active: var(--color-interface-panel-surface);
--interface-workflow-tab-surface-hovered: var(--color-gray-100);
--interface-workflow-tab-stroke: var(--color-gray-500);
--interface-workflow-tab-button-highlight: var(--color-gray-400);
--node-surface: var(--color-pure-white);
--node-component-hovered: var(--color-gray-300);
--node-component-selected: var(--color-gray-500);
--node-component-highlighted: var(--color-stone-100);
--node-ring-hover: var(--color-alpha-gray-500-50);
--node-bypass-surface: color-mix(in srgb, #ceaac9 60%, transparent);
--node-seed-control-surface: var(--color-alpha-gray-500-50);
--node-seed-control-icon: var(--color-blue-100);
--node-button-filled-primary-border: var(--color-sand-100);
--node-button-filled-primary-bkg-hover: var(--color-pure-white);
--node-button-filled-primary-bkg-selected: var(--color-pure-white);
--node-button-filled-primary-border-hover: var(--color-sand-100);
--node-button-filled-info-border-hover: var(--color-slate-300);
--node-button-outline-primary-border: var(--color-sand-300);
--node-button-outline-secondary-border: var(--color-sand-100);
--node-button-outline-secondary-border-hover: var(--color-sand-300);
--node-note-default-surface: var(--color-sand-100);
--node-note-scrollbar-track: var(--color-alpha-gray-500-50);
--node-note-text-primary: var(--color-charcoal-700);
--modal-background: var(--color-gray-200);
--modal-button-surface: var(--color-ivory-100);
--modal-button-surface-hovered: var(--color-gray-400);
--modal-contrast-surface: var(--color-charcoal-500);
--modal-panel-surface: var(--color-ivory-100);
--modal-panel-component-surface-hovered: var(--color-gray-200);
--modal-panel-component-surface-selected: var(--color-gray-300);
--modal-card-surface: var(--color-ivory-100);
--modal-card-surface-hovered: var(--color-gray-400);
--modal-card-button-surface: var(--color-gray-300);
--modal-card-button-surface-hovered: var(--color-gray-500);
--modal-card-tag-surface: color-mix(in srgb, var(--color-gray-400) 40%, transparent);
--modal-card-stroke-highlight: var(--accent-primary);
--modal-menu-surface: var(--color-pure-white);
--tooltip-background: var(--color-pure-white);
--tooltip-border: var(--color-sand-100);
}

.dark-theme {
Expand Down Expand Up @@ -246,6 +321,81 @@
--text-secondary: var(--color-slate-100);
--text-primary: var(--color-pure-white);
--input-surface: rgba(130, 130, 130, 0.1);

/* Semantic tokens from tokens.csv - Dark Mode */
--text-contrast: var(--color-pure-black);
--text-danger-error: var(--color-danger-100);
--text-warning: var(--color-warning-100);
--text-success: var(--color-success-100);
--text-blue: var(--color-blue-100);
--text-highlight: var(--color-blue-selection);
--accent-secondary: var(--color-slate-100);
--accent-contrast: var(--color-charcoal-700);
--accent-danger-error: var(--color-danger-100);
--accent-warning: var(--color-warning-100);
--accent-success: var(--color-success-100);
--accent-blue: var(--color-blue-100);
--accent-white: var(--color-pure-white);
--button-surface: var(--color-charcoal-500);
--button-surface-hovered: var(--color-charcoal-300);
--button-surface-danger: var(--color-danger-100);
--button-surface-blue: var(--color-blue-100);
--button-surface-contrast: var(--color-pure-white);
--button-bkg-secondary: var(--color-pure-black);
--button-bkg-info: var(--color-slate-300);
--button-icon: var(--color-gray-800);
--button-icon-disabled: var(--color-alpha-stone-100-20);
--interface-canvas-background: var(--color-pure-black);
--interface-icon: var(--color-slate-100);
--interface-panel-component-surface-hovered: var(--color-charcoal-600);
--interface-panel-component-surface-selected: var(--color-charcoal-400);
--interface-panel-card-surface: var(--color-charcoal-600);
--interface-panel-card-surface-hover: var(--color-charcoal-400);
--interface-panel-job-progress-primary: var(--color-blue-300);
--interface-panel-job-progress-secondary: var(--color-blue-selection);
--interface-menu-surface: var(--color-charcoal-800);
--interface-menu-stroke: var(--color-stone-200);
--interface-menu-keybind-surface-blue: var(--color-blue-300);
--interface-workflow-tab-surface: var(--color-charcoal-800);
--interface-workflow-tab-surface-active: var(--color-charcoal-400);
--interface-workflow-tab-surface-hovered: var(--color-charcoal-600);
--interface-workflow-tab-stroke: var(--color-charcoal-400);
--interface-workflow-tab-button-highlight: var(--color-charcoal-200);
--node-surface: var(--color-charcoal-800);
--node-component-hovered: var(--color-charcoal-400);
--node-component-selected: var(--color-charcoal-200);
--node-component-highlighted: var(--color-slate-100);
--node-ring-hover: color-mix(in srgb, var(--color-gray-500) 20%, transparent);
--node-bypass-surface: color-mix(in srgb, #6a246a 60%, transparent);
--node-seed-control-surface: var(--color-blue-selection);
--node-seed-control-icon: var(--color-blue-100);
--node-button-filled-primary-border: var(--color-charcoal-600);
--node-button-filled-primary-bkg-hover: var(--color-charcoal-600);
--node-button-filled-primary-bkg-selected: var(--color-charcoal-600);
--node-button-filled-primary-border-hover: var(--color-slate-300);
--node-button-filled-info-border-hover: var(--color-slate-100);
--node-button-outline-primary-border: var(--color-slate-100);
--node-button-outline-secondary-border: var(--color-stone-100);
--node-button-outline-secondary-border-hover: var(--color-pure-white);
--node-note-default-surface: var(--color-sand-200);
--node-note-scrollbar-track: var(--color-alpha-stone-100-20);
--node-note-text-primary: var(--color-charcoal-700);
--modal-background: var(--color-charcoal-800);
--modal-button-surface: var(--color-charcoal-400);
--modal-button-surface-hovered: var(--color-charcoal-300);
--modal-contrast-surface: var(--color-ivory-100);
--modal-panel-surface: var(--color-charcoal-600);
--modal-panel-component-surface-hovered: var(--color-charcoal-400);
--modal-panel-component-surface-selected: var(--color-charcoal-300);
--modal-card-surface: var(--color-charcoal-600);
--modal-card-surface-hovered: var(--color-charcoal-400);
--modal-card-button-surface: var(--color-charcoal-300);
--modal-card-button-surface-hovered: var(--color-charcoal-200);
--modal-card-tag-surface: color-mix(in srgb, var(--color-gray-400) 40%, transparent);
--modal-card-stroke-highlight: var(--accent-primary);
--modal-menu-surface: var(--color-charcoal-400);
--tooltip-background: var(--color-charcoal-800);
--tooltip-border: var(--color-slate-300);
}

@theme inline {
Expand Down Expand Up @@ -303,6 +453,81 @@
--color-text-secondary: var(--text-secondary);
--color-text-primary: var(--text-primary);
--color-input-surface: var(--input-surface);

/* Tailwind mappings for new semantic tokens */
--color-text-contrast: var(--text-contrast);
--color-text-danger-error: var(--text-danger-error);
--color-text-warning: var(--text-warning);
--color-text-success: var(--text-success);
--color-text-blue: var(--text-blue);
--color-text-highlight: var(--text-highlight);
--color-accent-secondary: var(--accent-secondary);
--color-accent-contrast: var(--accent-contrast);
--color-accent-danger-error: var(--accent-danger-error);
--color-accent-warning: var(--accent-warning);
--color-accent-success: var(--accent-success);
--color-accent-blue: var(--accent-blue);
--color-accent-white: var(--accent-white);
--color-button-surface: var(--button-surface);
--color-button-surface-hovered: var(--button-surface-hovered);
--color-button-surface-danger: var(--button-surface-danger);
--color-button-surface-blue: var(--button-surface-blue);
--color-button-surface-contrast: var(--button-surface-contrast);
--color-button-bkg-secondary: var(--button-bkg-secondary);
--color-button-bkg-info: var(--button-bkg-info);
--color-button-icon: var(--button-icon);
--color-button-icon-disabled: var(--button-icon-disabled);
--color-interface-canvas-background: var(--interface-canvas-background);
--color-interface-icon: var(--interface-icon);
--color-interface-panel-component-surface-hovered: var(--interface-panel-component-surface-hovered);
--color-interface-panel-component-surface-selected: var(--interface-panel-component-surface-selected);
--color-interface-panel-card-surface: var(--interface-panel-card-surface);
--color-interface-panel-card-surface-hover: var(--interface-panel-card-surface-hover);
--color-interface-panel-job-progress-primary: var(--interface-panel-job-progress-primary);
--color-interface-panel-job-progress-secondary: var(--interface-panel-job-progress-secondary);
--color-interface-menu-surface: var(--interface-menu-surface);
--color-interface-menu-stroke: var(--interface-menu-stroke);
--color-interface-menu-keybind-surface-blue: var(--interface-menu-keybind-surface-blue);
--color-interface-workflow-tab-surface: var(--interface-workflow-tab-surface);
--color-interface-workflow-tab-surface-active: var(--interface-workflow-tab-surface-active);
--color-interface-workflow-tab-surface-hovered: var(--interface-workflow-tab-surface-hovered);
--color-interface-workflow-tab-stroke: var(--interface-workflow-tab-stroke);
--color-interface-workflow-tab-button-highlight: var(--interface-workflow-tab-button-highlight);
--color-node-surface: var(--node-surface);
--color-node-component-hovered: var(--node-component-hovered);
--color-node-component-selected: var(--node-component-selected);
--color-node-component-highlighted: var(--node-component-highlighted);
--color-node-ring-hover: var(--node-ring-hover);
--color-node-bypass-surface: var(--node-bypass-surface);
--color-node-seed-control-surface: var(--node-seed-control-surface);
--color-node-seed-control-icon: var(--node-seed-control-icon);
--color-node-button-filled-primary-border: var(--node-button-filled-primary-border);
--color-node-button-filled-primary-bkg-hover: var(--node-button-filled-primary-bkg-hover);
--color-node-button-filled-primary-bkg-selected: var(--node-button-filled-primary-bkg-selected);
--color-node-button-filled-primary-border-hover: var(--node-button-filled-primary-border-hover);
--color-node-button-filled-info-border-hover: var(--node-button-filled-info-border-hover);
--color-node-button-outline-primary-border: var(--node-button-outline-primary-border);
--color-node-button-outline-secondary-border: var(--node-button-outline-secondary-border);
--color-node-button-outline-secondary-border-hover: var(--node-button-outline-secondary-border-hover);
--color-node-note-default-surface: var(--node-note-default-surface);
--color-node-note-scrollbar-track: var(--node-note-scrollbar-track);
--color-node-note-text-primary: var(--node-note-text-primary);
--color-modal-background: var(--modal-background);
--color-modal-button-surface: var(--modal-button-surface);
--color-modal-button-surface-hovered: var(--modal-button-surface-hovered);
--color-modal-contrast-surface: var(--modal-contrast-surface);
--color-modal-panel-surface: var(--modal-panel-surface);
--color-modal-panel-component-surface-hovered: var(--modal-panel-component-surface-hovered);
--color-modal-panel-component-surface-selected: var(--modal-panel-component-surface-selected);
--color-modal-card-surface: var(--modal-card-surface);
--color-modal-card-surface-hovered: var(--modal-card-surface-hovered);
--color-modal-card-button-surface: var(--modal-card-button-surface);
--color-modal-card-button-surface-hovered: var(--modal-card-button-surface-hovered);
--color-modal-card-tag-surface: var(--modal-card-tag-surface);
--color-modal-card-stroke-highlight: var(--modal-card-stroke-highlight);
--color-modal-menu-surface: var(--modal-menu-surface);
--color-tooltip-background: var(--tooltip-background);
--color-tooltip-border: var(--tooltip-border);
}

@custom-variant dark-theme {
Expand Down
6 changes: 3 additions & 3 deletions src/components/bottomPanel/tabs/shortcuts/ShortcutsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
class="flex flex-col"
>
<h3
class="subcategory-title mb-4 text-xs font-bold tracking-wide text-surface-600 uppercase dark-theme:text-surface-400"
class="subcategory-title mb-4 text-xs font-bold tracking-wide text-text-secondary uppercase"
>
{{ getSubcategoryTitle(subcategory) }}
</h3>
Expand All @@ -16,7 +16,7 @@
<div
v-for="command in subcategoryCommands"
:key="command.id"
class="shortcut-item flex items-center justify-between rounded py-2 transition-colors duration-200 hover:bg-surface-100 dark-theme:hover:bg-surface-700"
class="shortcut-item flex items-center justify-between rounded py-2 transition-colors duration-200 hover:bg-interface-panel-component-surface-hovered"
>
<div class="shortcut-info grow pr-4">
<div class="shortcut-name text-sm font-medium">
Expand All @@ -32,7 +32,7 @@
<span
v-for="key in command.keybinding!.combo.getKeySequences()"
:key="key"
class="key-badge min-w-6 rounded border bg-surface-200 px-2 py-1 text-center font-mono text-xs dark-theme:bg-surface-600"
class="key-badge min-w-6 rounded border bg-interface-menu-keybind-surface-default px-2 py-1 text-center font-mono text-xs"
>
{{ formatKey(key) }}
</span>
Expand Down
4 changes: 2 additions & 2 deletions src/components/button/IconGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { cn } from '@/utils/tailwindUtil'
const iconGroupClasses = cn(
'flex justify-center items-center shrink-0',
'outline-hidden border-none p-0 rounded-lg',
'bg-white dark-theme:bg-zinc-700',
'text-neutral-950 dark-theme:text-white',
'bg-button-surface',
'text-text-primary',
'transition-all duration-200',
'cursor-pointer'
)
Expand Down
6 changes: 3 additions & 3 deletions src/components/button/MoreButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ const pt = computed(() => ({
content: {
class: cn(
'mt-1 rounded-lg',
'bg-white dark-theme:bg-zinc-800',
'text-neutral dark-theme:text-white',
'bg-interface-menu-surface',
'text-text-primary',
'shadow-lg',
'border border-zinc-200 dark-theme:border-zinc-700'
'border border-interface-menu-stroke'
)
}
}))
Expand Down
8 changes: 4 additions & 4 deletions src/components/card/CardContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ const containerClasses = computed(() => {
// Variant styles
const variantClasses = {
default: cn(
hasBackground && 'bg-white dark-theme:bg-zinc-800',
hasBorder && 'border border-zinc-200 dark-theme:border-zinc-700',
hasBackground && 'bg-interface-panel-card-surface',
hasBorder && 'border border-interface-stroke',
hasShadow && 'shadow-sm',
hasCursor && 'cursor-pointer'
),
Expand All @@ -57,9 +57,9 @@ const containerClasses = computed(() => {
'p-2 transition-colors duration-200'
),
outline: cn(
hasBorder && 'border-2 border-zinc-300 dark-theme:border-zinc-600',
hasBorder && 'border-2 border-interface-stroke',
hasCursor && 'cursor-pointer',
'hover:border-zinc-400 dark-theme:hover:border-zinc-500 transition-colors'
'hover:border-interface-panel-component-surface-hovered transition-colors'
)
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/card/CardDescription.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="line-clamp-2 h-7 text-xs text-zinc-500 dark-theme:text-zinc-400">
<div class="line-clamp-2 h-7 text-xs text-text-secondary">
<slot></slot>
</div>
</template>
Expand Down
2 changes: 1 addition & 1 deletion src/components/chip/SquareChip.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const baseClasses =

const variantStyles = {
dark: 'bg-zinc-500/40 text-white/90',
light: 'backdrop-blur-[2px] bg-white/50 text-zinc-900 dark-theme:text-white'
light: 'backdrop-blur-[2px] bg-white/50 text-text-primary'
}

const chipClasses = computed(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/FormImageUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div class="flex items-center gap-2">
<div
class="preview-box flex h-16 w-16 items-center justify-center rounded border p-2"
:class="{ 'bg-gray-100 dark-theme:bg-gray-800': !modelValue }"
:class="{ 'bg-button-surface': !modelValue }"
>
<img
v-if="modelValue"
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/LazyImage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/>
<div
v-if="hasError"
class="absolute inset-0 flex items-center justify-center bg-surface-50 text-muted dark-theme:bg-surface-800"
class="absolute inset-0 flex items-center justify-center bg-interface-panel-surface text-muted"
>
<img
src="/assets/images/default-template.png"
Expand Down
Loading
Loading