Semantic Colors
Raw token values like --color-primary-600 are implementation details. Semantic aliases give your components meaning-based names that survive theme switches.
The Pattern
Import a theme's tokens, then create semantic aliases in :root:
@import "@syncupsuite/themes/swiss-international/tokens.css";
:root {
--app-background: var(--color-neutral-50);
--app-text: var(--color-neutral-900);
--app-text-muted: var(--color-neutral-600);
--app-border: var(--color-neutral-200);
--app-accent: var(--color-primary-600);
--app-accent-hover: var(--color-primary-700);
--app-success: var(--color-semantic-success);
--app-warning: var(--color-semantic-warning);
--app-error: var(--color-semantic-error);
}Your components reference --app-accent, not --color-primary-600. When you switch from Swiss International to Art Deco, only the token import changes — your components stay the same.
With Tailwind v4
Register semantic aliases in the @theme block so Tailwind generates utility classes:
@import "tailwindcss";
@import "@syncupsuite/themes/swiss-international/tokens.css";
:root {
--app-bg: var(--color-neutral-50);
--app-fg: var(--color-neutral-900);
--app-accent: var(--color-primary-600);
}
@theme {
--color-app-bg: var(--app-bg);
--color-app-fg: var(--app-fg);
--color-app-accent: var(--app-accent);
}Use in markup:
<div class="bg-app-bg text-app-fg">
<a class="text-app-accent hover:underline">Link</a>
</div>Theme Switching
Scope token imports to support multiple themes:
@import "@syncupsuite/themes/swiss-international/tokens.css";
[data-theme="nihon-traditional"] {
@import "@syncupsuite/themes/nihon-traditional/tokens.css";
}Or load dynamically:
async function loadTheme(slug: string) {
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = `/@syncupsuite/themes/${slug}/tokens.css`;
document.head.appendChild(link);
document.documentElement.dataset.theme = slug;
}Dark Mode
Tokens are theme-scoped, not mode-scoped. Create a second set of semantic aliases for dark mode:
@media (prefers-color-scheme: dark) {
:root {
--app-background: var(--color-neutral-900);
--app-text: var(--color-neutral-50);
--app-text-muted: var(--color-neutral-400);
--app-border: var(--color-neutral-700);
}
}Platform Convention
SyncupSuite platform projects use the su-* namespace:
:root {
--su-background: var(--color-neutral-50);
--su-text-primary: var(--color-neutral-900);
--su-text-secondary: var(--color-neutral-600);
--su-border: var(--color-neutral-200);
--su-accent: var(--color-primary-600);
}The su-* prefix is reserved for SyncupSuite platform properties. Your project can use any namespace.