Skip to main content

Semantic Derivation

Play+ Semantic Derivation Guide​

Overview​

Semantic tokens are the heart of Play+'s theming model. They allow you to build visually rich and brand-flexible UI experiences by mapping global raw values to meaningful roles. This document explains how semantic tokens are derived, when to use them, when to avoid them, and how the Play+ theming engine operates.


🧱 Token Architecture Summary​

TierToken TypeOwnershipUsage ScopeOverridable?Example
1Global TokensPlay+ CoreRaw values (e.g., colors, spacing)❌ (Do not override)--global-color-pink-500
2Semantic TokensUser/ThemeDesign roles (e.g., primary text)βœ… Theme-specific--color-brand-primary
3Component TokensAdvanced UsageComponent-specific overridesβœ… Scoped--component-button-padding-vertical

🧠 How the Engine Runs​

The Play+ Theming Engine loads when your application initializes or when a theme is switched at runtime. Here's how it operates:

  1. Loads the base CSS (_base.css) to get the global and default semantic tokens.
  2. Loads theme.map.json from the current brand/theme directory.
  3. Applies mappings of semantic tokens β†’ new global tokens.
  4. Applies derived states (e.g., hover, active, focus, dark variants) based on naming rules.
  5. Injects final token map into :root and watches for hot-swappable updates.

This engine ensures the entire application theme is controlled via one lightweight JSON map, making live previews and runtime updates seamless.


🎨 What Gets a Semantic Token (and What Doesn’t)​

CategoryNeeds Semantic Token?Reason
Brand Colorsβœ…Changes between themes; context-aware.
Text Colorsβœ…Needs adaptive contrast.
Backgroundsβœ…May shift in dark/light themes.
Typography (Fonts)βœ…Brands may change body/heading fonts.
Motion Patterns❌Shared Play+ motion language; not brand-specific.
Shadow/Elevation❌Generally consistent across brands.
Radius⚠️ (Partial)Use semantic token if branding requires it.
Icon Sizes❌Functional sizes; unlikely to vary.
Accessibility Tokensβœ…Used by accessibility-aware components.

πŸ“ Token File Responsibilities​

PathPurpose
styles/core/_base.cssContains all global (raw value) tokens and defines the CSS variables for semantic tokens with their base fallback values
styles/themes/acme/theme.map.jsonMaps semantic tokens to new global values for a specific brand. The engine falls back to styles/themes/default/theme.map.json if no theme is loaded.

⚠️ Never edit _base.css directly to theme your app. Instead, override semantic tokens via theme.map.json.


βœ… Default Semantic Token List​

This list comes from _base.css and serves as the baseline for all themes:

Colors​

  • --color-brand-primary
  • --color-brand-secondary
  • --color-brand-primary-hover
  • --color-text-primary
  • --color-text-secondary
  • --color-text-disabled
  • --color-text-on-brand
  • --color-surface-interactive-default
  • --color-surface-disabled
  • --color-border-default
  • --color-border-focus

Typography​

  • --font-family-display
  • --font-family-heading
  • --font-body-1, --font-body-2
  • --font-heading-h1, --font-heading-h2

Motion​

  • --motion-pattern-fade
  • --motion-pattern-slide
  • --motion-pattern-pop

Layout & Spacing​

  • --layout-max-width
  • --layout-gutter-default

Accessibility​

  • --accessibility-focus-ring-color
  • --accessibility-focus-ring-style

Iconography​

  • --icon-size-md
  • --icon-color-default

Content​

  • --content-line-measure

Glassmorphism​

  • --glass-backdrop-blur
  • --glass-background-color

🧩 Example Derivation Map (Default Theme)​

Semantic TokenMapped Global Token
--color-brand-primary--global-color-pink-500
--color-brand-primary-hover--global-color-pink-700
--color-brand-secondary--global-color-purple-500
--color-text-primary--global-color-gray-700
--color-text-secondary--global-color-gray-600
--color-text-disabled--global-color-gray-400
--color-text-on-brand--global-color-white
--color-surface-interactive-default--global-color-pink-500
--color-surface-disabled--global-color-gray-200
--color-border-default--global-color-gray-300
--color-border-focus--global-color-pink-500
--font-family-display--global-font-family-display
--font-family-heading--global-font-family-heading
--font-family-body--global-font-family-body
--motion-pattern-fade--global-motion-duration-swift + easing
--layout-gutter-default--global-spacing-4
--icon-color-default--color-text-secondary
--glass-backdrop-blur--global-glassmorphic-blur

πŸ“ Naming Convention Guidelines​

TypePrefixExample
Colorcolor-color-surface-disabled
Typographyfont-font-heading-h1
Radiusradius-radius-md
Motionmotion-pattern-motion-pattern-slide
Layoutlayout-layout-gutter-default
Iconicon-icon-color-on-brand
Contentcontent-content-line-measure
Accessibilityaccessibility-accessibility-focus-ring-width

πŸ“¦ Best Practices​

  • Never use global tokens directly in components.
  • Derive all design decisions through semantic tokens.
  • Only use component-level tokens for scoped overrides or design exceptions.
  • Document all brand themes via theme.map.json.
  • Use fallback defaults to ensure graceful degradation.

πŸ”„ Theme Switching​

Play+ supports runtime theming:

import { playTheme } from 'playplus-core';
playTheme.load('acme'); // Switch to Acme theme

🧠 Final Note​

Semantic tokens are what make Play+ adaptable, accessible, and maintainable at scale. They are not an extra layer β€” they are the design language.

"Let your brand breathe β€” one token at a time."