Skip to content

Design tokens

Every visual aspect of the platform — color, radius, focus rings, shadows, and common component states — is parameterized as a CSS custom property. The frontend SDK ships the tokens in styles/variables.css, plus Tailwind v4 compatibility utilities for the classes used by SDK components. Plugin frontends should reference tokens, never hex codes.

Why tokens

When a deployment overrides the platform's brand color (a lab might want a different primary), every plugin re-themes automatically — no per-plugin update needed. Hardcoded #4F46E5 in your plugin breaks that.

Tokens also make light/dark/density work universally. The dark theme just changes the variable values; a plugin that uses var(--bg-primary) flips correctly without code changes.

Setup

Frontend scaffolding is included by default with mint init (skipped when --no-frontend is passed). Manual setup:

css
/* frontend/src/style.css */
@import "tailwindcss";
@import "@morscherlab/mint-sdk/styles" layer(mint-sdk);

Token families

Brand

VariableMeaningDefault light
--color-primaryIndigo brand color#6366F1
--color-primary-hoverHover state#4F46E5
--color-primary-lightLight accent#93C5FD
--color-primary-softSoft tint for backgroundsrgba(99, 102, 241, 0.12)
--color-ctaOrange CTA#F97316
--color-cta-hoverCTA hover#EA580C
--mint-brandMINT brand mark color#7BD0B5

Use brand tokens for: links, primary buttons, focused inputs, the most-prominent action on a screen.

Semantic feedback

VariableUse
--mint-successSuccessful operations
--mint-errorErrors, destructive actions
--mint-warningWarnings, "needs review" states
--mint-infoInformational notices

Each ships variants: --mint-{name}-bg, --mint-{name}-border, --mint-{name}-text.

Surfaces

VariableUse
--bg-primaryThe main page background
--bg-secondaryCard / panel surface
--bg-tertiaryRecessed surface (e.g., inside a card)
--bg-cardCard surface alias
--bg-hoverHover background
--border-colorDefault 1px border color
--border-lightLow-contrast border

Text

VariableUse
--text-primaryMain text color
--text-secondaryLess-emphasized text (labels, captions)
--text-mutedEven more recessed (helper text)
--mint-text-inverseLegacy alias for text on dark backgrounds

Focus

VariableUse
--focus-ringFull box-shadow value for a solid focus ring
--focus-ring-offsetFull box-shadow value with an offset ring
--focus-ring-errorError focus ring
--focus-ring-softSofter translucent focus ring
--focus-ring-soft-errorSofter translucent error focus ring

Every interactive component honors these. Custom components should follow the same pattern.

Spacing and radius

Tailwind's standard scale (p-2, p-4, gap-3) works as usual. SDK-specific radius, shadow, form-height, and transition tokens are:

VariableUse
--radiusDefault radius (0.375rem)
--radius-sm, --radius-md, --radius-lgStandard radius scale
--shadow-sm, --shadow, --shadow-md, --shadow-lgElevation
--form-height-sm, --form-height-md, --form-height-lgInput/control heights
--mint-transitionShared component transition (150ms ease)

Motion

VariableUse
RuleUse
-----------
@media (prefers-reduced-motion: reduce)The SDK globally shortens animation and transition durations
--mint-transitionUse for simple custom hover/focus transitions

The SDK respects prefers-reduced-motion globally. Custom animations should either use the same media query or keep motion non-essential.

Tailwind utilities

Use the SDK compatibility utilities or Tailwind v4 arbitrary values in templates:

vue
<div class="bg-bg-secondary text-text-primary border border-border p-4 rounded-mint">
  <h2 class="text-text-primary font-semibold">Title</h2>
  <p class="text-text-secondary text-sm">Subtitle</p>
  <div class="bg-bg-hover p-3 rounded-mint-sm mt-2">Recessed content</div>
</div>
Utility prefixMaps to
bg-bg-secondary, bg-bg-hover, bg-bg-inputBackground tokens
text-text-primary, text-text-secondary, text-text-mutedText tokens
border-bordervar(--border-color)
bg-mint-{primary,cta,success,error,warning,info,danger}Brand / semantic backgrounds
text-mint-{success,error,warning,info}Semantic text
text-mint-primary, bg-mint-primary, border-mint-primaryBrand color
rounded-mint, rounded-mint-sm, rounded-mint-lgSDK radius utilities

For tokens without a named utility, use Tailwind's arbitrary value syntax:

vue
<p class="text-[var(--text-muted)] border-[color:var(--border-light)]">
  Helper text
</p>

Custom CSS

When utility classes aren't enough:

vue
<style scoped>
.my-card {
  background: var(--bg-secondary);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  transition: box-shadow var(--mint-transition);
}

.my-card:hover {
  box-shadow: var(--shadow-lg);
}

.my-card:focus-within {
  box-shadow: var(--focus-ring);
}
</style>

Don'ts

  • Don't hardcode hex codescolor: #4F46E5; won't re-theme. Use var(--color-primary) or the Tailwind utility.
  • Don't reach into the platform's frontend — your plugin is its own bundle and shouldn't import platform code. Tokens are the contract.
  • Don't reinvent semantic colors--mint-success already exists. A different green from yours will look out of place.
  • Don't bake in repeated transition values — use var(--mint-transition) or the SDK's components/utilities where possible.

Auditing your plugin

A quick check before merging plugin frontend changes:

bash
# Find any hardcoded hex codes in your plugin's Vue / CSS
grep -rE "#[0-9a-fA-F]{6}\b" src/ frontend/src/

Hits are usually candidates for var(--…) substitution.

Notes

  • Token names are stable across SDK minor versions. Major bumps may introduce new families or rename existing ones — check the changelog.
  • The platform may override variables in its own root stylesheet (packages/sdk-frontend/src/styles/variables.css is the master; the platform's frontend/src/style.css can :root { --color-primary: ...; } to re-skin).
  • Plugin Histoire stories should be reviewed in light, dark, AND white backgrounds — every story file declares them.
  • Theming — palette overrides, density, accessibility
  • Component Library — every component reads tokens
  • The token source: packages/sdk-frontend/src/styles/variables.css

MINT is open source. Made by the Morscher Lab.