Mastors
Playground
Mastors v0.1 Stable

Style is the
expression of intent.

Mastors is an Intent-Based Styling Framework — declare what a UI element is and Mastors resolves how it looks: accessible, responsive, theme-aware, and zero-runtime.

$ pnpm add @mastors/api @mastors/core @mastors/schemas
Zero-Runtime
CSS compiled at build time
WCAG 2.2
Auto a11y enforcement
Token-Native
Design token–driven
Framework Agnostic
React, Vue, Svelte

Installation

Mastors is a pnpm workspace monorepo. Install the packages you need.

Full install

bash
pnpm add @mastors/api @mastors/core @mastors/compiler \
        @mastors/schemas @mastors/tokens @mastors/types @mastors/utils

Minimal install (API + core only)

bash
pnpm add @mastors/api @mastors/core @mastors/schemas @mastors/tokens @mastors/types

Framework adapters

bash
# React
pnpm add @mastors/adapter-react

# Vue 3
pnpm add @mastors/adapter-vue

# Svelte
pnpm add @mastors/adapter-svelte

Build plugins

bash
pnpm add -D @mastors/plugin-vite      # Vite
pnpm add -D @mastors/plugin-webpack   # webpack

Quick Start

Get from zero to a fully-styled, accessible component in five steps.

1
Create mastors.config.ts

Define your schema and custom vocabulary at the project root.

mastors.config.ts
import { defineSchema } from "@mastors/schemas";
        
        export default defineSchema({
          tokens: "./tokens/global.json",  // optional — uses built-in tokens by default
          vocabulary: {
            // Extend the built-in vocabulary with project-specific intents
            "card.promo.featured": {
              spacing: { x: "token.space.6", y: "token.space.5" },
              shadow: "token.shadow.elevated",
              radius: "token.radius.xl",
              color: {
                background: "token.color.primary.50",
                border: "token.color.primary.200",
              },
              a11y: { role: "article", contrast: "AA" },
            },
          },
        });
2
Add the Vite plugin
vite.config.ts
import { defineConfig } from "vite";
          import { mastorsPlugin } from "@mastors/plugin-vite";
          import schema from "./mastors.config";
          
          export default defineConfig({
            plugins: [
              mastorsPlugin({
                config: { schema, a11yMode: "warn" },
                a11yManifest: true,   // emit mastors-a11y.json at build
              }),
            ],
          });
3
Import the virtual CSS module
main.ts
import "virtual:mastors";  // inject compiled CSS (zero-runtime)
          import { configure } from "@mastors/api";
          import schema from "./mastors.config";
          
          configure({ schema, a11yMode: "warn" });
4
Declare intent
Card.tsx
import { intent } from "@mastors/api";
          
          const card = intent("card.elevated.interactive");
          // Mastors auto-resolves:
          //   ✓ Elevation shadow from token.shadow.elevated
          //   ✓ WCAG AA focus ring (ring.primary)
          //   ✓ Hover lift interaction
          //   ✓ prefers-reduced-motion guard
          //   ✓ Theme-aware background & border colors
5
Render with a framework adapter
React
import { Mastors } from "@mastors/adapter-react";
          
          export function Card({ title, body }) {
            return (
              <Mastors.div intent="card.elevated.interactive">
                <Mastors.h2 intent="heading.section">{title}</Mastors.h2>
                <Mastors.p intent="body.readable">{body}</Mastors.p>
                <Mastors.button intent="button.primary.cta">Get Started</Mastors.button>
              </Mastors.div>
            );
          }

Architecture

Mastors is organized as a five-layer pipeline. All resolution happens at build time — the browser receives plain atomic CSS with zero JavaScript in the styling critical path.

LAYER 1
@mastors/api
Intent Declaration API — intent() · semantics() · compose() · configure()
LAYER 2
@mastors/core
Semantic Resolver — token mapping · context inference · plugin hooks · resolver cache
LAYER 3
@mastors/core (runtime)
Adaptive Runtime — responsive optimizer · theme scaler · motion orchestrator
LAYER 4
@mastors/accessibility
WCAG 2.2 Guard — contrast enforcement · ARIA automation · motion sensitivity guard
LAYER 5
@mastors/compiler
Output Compiler — zero-runtime atomic CSS · class deduplication · token injection · a11y manifest
OUTPUT

Intent Declaration API

The @mastors/api package exposes four functions forming the public developer interface.

typescript
import { intent, semantics, compose, configure, intentClass } from "@mastors/api";

// ── configure() — initialize once at app entry ──
configure({ schema: mySchema, a11yMode: "warn" });

// ── intent() — parse an intent ID into a descriptor ──
const card = intent("card.elevated.interactive");
// Returns: IntentDescriptor { id, segments, context, __mastors: true }

// ── intentClass() — resolve directly to className string ──
const cls = intentClass("button.primary.cta");
// → "m-padding-left-abc m-background-color-def m-intent-button-primary-cta"

// ── semantics() — add intents to the active schema at runtime ──
semantics({
  "data.badge.negative": {
    color: { foreground: "token.color.error.700" },
  },
});

// ── compose() — merge multiple intents (last wins on conflicts) ──
const heroCard = compose("card.elevated", "card.elevated.interactive");

Semantic Resolver

@mastors/core houses the SemanticResolver class — the engine that maps intent identifiers to typed style maps via the schema vocabulary. Results are automatically cached per intent ID + context.

typescript
import { SemanticResolver } from "@mastors/core";
import { defaultSchema } from "@mastors/schemas";

const resolver = new SemanticResolver(defaultSchema);

// Step 1 — Parse intent string into a typed descriptor
const descriptor = resolver.describe("card.elevated.interactive");
// { id: "card.elevated.interactive", segments: { category, variant, modifier }, ... }

// Step 2 — Resolve descriptor into a full style map
const styleMap = resolver.resolve(descriptor);
// {
//   base: StyleRule[]           → CSS property/value pairs with token refs
//   variants: StyleRule[][]     → responsive / state variants
//   a11yHints: A11yHint[]       → WCAG requirements and ARIA suggestions
//   animationRules: AnimationRule[] → transitions with motion guard
// }

// Useful methods
resolver.clearCache();           // clear cached results (call when schema changes)
resolver.setSchema(newSchema);   // swap schema (also clears cache)

Specificity walk

When looking up a vocabulary entry, the resolver walks from most-specific to least-specific:

card.elevated.interactive card.elevated card fallback (empty map)

Built-in Vocabulary

Mastors ships 19 production-ready intents covering the most common UI patterns — all with automatic token resolution, WCAG 2.2 compliance, and interaction semantics.

Cards

Intent Shadow Interaction WCAG
card.base AA
card.elevated token.shadow.elevated AA
card.elevated.interactive token.shadow.elevated hover:lift · focus:ring · active:press AA
Schema definition
"card.elevated.interactive": {
  spacing: { x: "token.space.4", y: "token.space.3" },
  shadow: "token.shadow.elevated",
  radius: "token.radius.lg",
  color: {
    background: "token.color.neutral.0",
  },
  interaction: { hover: "lift", focus: "ring.primary", active: "press" },
  motion: "transition.natural",
  a11y: { role: "article", contrast: "AA" },
}

Buttons

Intent Background Interaction WCAG
button.primary color.primary.600 hover:darken · focus:ring AA
button.primary.cta color.primary.600 hover:darken · focus:ring AAA
button.secondary color.neutral.100 hover:lighten · focus:ring AA
button.destructive color.error.500 hover:darken · focus:ring.error AA

Typography

Intent Size token Weight Line height
heading.hero token.text.5xl bold tight (1.25)
heading.section token.text.3xl bold tight (1.25)
heading.subsection token.text.xl semibold snug (1.375)
body.readable token.text.base normal relaxed (1.625)
body.readable.longform token.text.lg normal loose (2)

Alerts & Feedback

Intent Background ARIA role WCAG
alert.info color.primary.50 status AA
alert.success color.success.100 status AA
alert.warning color.warning.100 alert AA
alert.destructive color.error.100 alert AA
toast.success.transient color.neutral.800 status AA

Navigation

Intent Surface Shadow ARIA landmark
nav.primary color.neutral.0 navigation
nav.primary.sticky color.neutral.0 token.shadow.base navigation

Forms

Intent Border Focus ARIA role
form.field color.neutral.300 ring.primary group
form.destructive.confirm color.error.500 dialog

Layout

Intent Description
container.max.centered Max-width centered layout wrapper with horizontal padding
grid.autofill.dense Auto-fill CSS grid with dense packing algorithm

Adding custom intents

Extend the built-in vocabulary in your mastors.config.ts. Custom intents follow the same schema shape as built-in ones:

typescript
defineSchema({
  vocabulary: {
    "dashboard.stat.positive": {
      spacing: { x: "token.space.4", y: "token.space.3" },
      radius: "token.radius.lg",
      color: {
        background: "token.color.success.100",
        foreground: "token.color.success.700",
        border: "token.color.success.500",
      },
      a11y: { contrast: "AA" },
    },
    "dashboard.stat.negative": {
      spacing: { x: "token.space.4", y: "token.space.3" },
      radius: "token.radius.lg",
      color: {
        background: "token.color.error.100",
        foreground: "token.color.error.700",
      },
      a11y: { contrast: "AA" },
    },
  },
});

Framework Adapters

Mastors provides first-class adapter packages for React, Vue 3, and Svelte — each exposing the idiomatic API for that framework.

React

React / TSX
import { useIntent, Mastors } from "@mastors/adapter-react";

// Hook — resolves to a className string
function Card({ title, body }) {
  const className = useIntent("card.elevated.interactive");
  return <div className={className}>{title}</div>;
}

// Component namespace — declarative intent prop
<Mastors.div intent="card.elevated.interactive">
  <Mastors.h2 intent="heading.section">Title</Mastors.h2>
  <Mastors.p  intent="body.readable">Body text</Mastors.p>
  <Mastors.button intent="button.primary.cta">Get Started</Mastors.button>
</Mastors.div>

Vue 3

Vue 3 / SFC
// main.ts — register globally
import { MastorsPlugin } from "@mastors/adapter-vue";
app.use(MastorsPlugin);

// Component.vue
<script setup>
import { useIntent } from "@mastors/adapter-vue";
const cardClass = useIntent("card.elevated.interactive");
</script>

<template>
  <!-- Composable -->
  <div :class="cardClass">...</div>

  <!-- Directive (requires MastorsPlugin) -->
  <div v-intent="'button.primary.cta'">...</div>
</template>

Svelte

Svelte
import { resolveIntent, intentAction } from "@mastors/adapter-svelte";

// Class binding (resolved at import time)
const cardClass = resolveIntent("card.elevated.interactive");

// Action (reactive, updates on prop change)
<div use:intentAction={"card.elevated.interactive"}>...</div>

// Class shorthand
<div class={resolveIntent("button.primary.cta")}>...</div>

Build Plugins

Mastors scans source files for intent("...") calls and compiles atomic CSS at build time via Vite or webpack plugins.

Vite Plugin

vite.config.ts
import { mastorsPlugin } from "@mastors/plugin-vite";

export default defineConfig({
  plugins: [
    mastorsPlugin({
      config: {
        schema,
        a11yMode: "warn",       // "warn" | "enforce" | "report" | "off"
        outputFormat: "atomic", // "atomic" | "css-modules" | "css-vars"
      },
      include: ["ts", "tsx", "vue", "svelte"],  // file extensions to scan
      a11yManifest: true,   // emit mastors-a11y.json at build
    }),
  ],
});

webpack Plugin

webpack.config.js
const { MastorsWebpackPlugin } = require("@mastors/plugin-webpack");

module.exports = {
  plugins: [
    new MastorsWebpackPlugin({
      config: { schema, a11yMode: "warn" },
      filename: "mastors.css",  // output CSS filename in dist
    }),
  ],
};

Configuration

Full MastorsConfig type reference:

typescript
type MastorsConfig = {
  schema: MastorsSchema;           // required — your project schema

  a11yMode?:
    | "warn"       // console.warn on violations (default, dev-friendly)
    | "enforce"    // throws on error-severity violations (use in CI)
    | "report"     // silently collect — call guard.generateManifest()
    | "off";       // disable accessibility guard entirely

  outputFormat?:
    | "atomic"     // deduplicated atomic CSS classes (default)
    | "css-modules" // scoped CSS module per intent
    | "css-vars";  // CSS custom property declarations only

  themes?: string[];           // theme names to generate variants for
  defaultTheme?: string;       // active theme at build time
};

VocabularyEntry schema shape

typescript
type VocabularyEntry = {
  spacing?:    { x?: TokenPath; y?: TokenPath };
  radius?:     TokenPath;
  shadow?:     TokenPath;
  color?: {
    background?: TokenPath;
    foreground?: TokenPath;
    border?:     TokenPath;
  };
  typography?: {
    size?:       TokenPath;
    weight?:     TokenPath;
    lineHeight?: TokenPath;
  };
  interaction?: {
    hover?:  "lift" | "darken" | "lighten" | "highlight";
    focus?:  "ring.primary" | "ring.error" | "ring.success";
    active?: "press" | "bounce";
  };
  motion?: "transition.natural" | "animate.slide-up.spring";
  a11y?: {
    role?:     string;          // ARIA role suggestion
    contrast?: "AA" | "AAA";   // WCAG contrast level to enforce
  };
};

Design Tokens

Mastors uses a dot-notation token path system. Every token path maps to a CSS custom property at compile time:

token.space.4 --mastors-space-4: 1rem
Spacing (4pt base)
token.space.1
0.25rem
token.space.2
0.5rem
token.space.4
1rem
token.space.6
1.5rem
token.space.8
2rem
token.space.12
3rem
Semantic Colors
token.color.primary.50
#eff6ff
token.color.primary.600
#2563eb
token.color.success.500
#22c55e
token.color.warning.500
#eab308
token.color.error.500
#ef4444
token.color.neutral.0
#ffffff
Border Radius
token.radius.sm
0.125rem
token.radius.md
0.375rem
token.radius.lg
0.5rem
token.radius.xl
0.75rem
token.radius.full
9999px
Elevation (Shadows)
token.shadow.sm
0 1px 2px …
token.shadow.base
0 1px 3px …
token.shadow.md
0 4px 6px …
token.shadow.elevated
0 10px 15px …
token.shadow.xl
0 25px 50px …

Token Registry API

typescript
import { TokenRegistry, defaultTokens } from "@mastors/tokens";

const registry = new TokenRegistry(defaultTokens);

registry.resolve("token.space.4");               // → "1rem"
registry.resolveToVar("token.shadow.elevated");  // → { cssVar: "--mastors-shadow-elevated", fallback: "..." }
registry.generateCssVars(":root");               // → ":root { --mastors-space-4: 1rem; ... }"

// Extend with overrides (immutable — returns new registry)
const custom = registry.extend({
  token: { space: { "4": "0.875rem" } }          // override one value
});

Accessibility Guard

The @mastors/accessibility package wraps every resolved intent with automatic WCAG 2.2 compliance checking — contrast ratios, focus rings, ARIA hints, and motion sensitivity.

Contrast Enforcement
Checks every foreground/background pair against AA (4.5:1) or AAA (7:1) thresholds automatically.
Focus Ring Generation
Auto-generates 2px visible focus rings for all interactive intents meeting WCAG 2.4.7.
ARIA Recommendations
Suggests required ARIA attributes and landmark roles for every semantic intent type.
Motion Sensitivity
Wraps all transitions in @media (prefers-reduced-motion: reduce) automatically.

Guard modes

Mode Behavior When to use
warn console.warn on violations Default — development
enforce Throws on error-severity violations CI/CD pipelines
report Silently collects all violations Audits / manifests
off Disables guard entirely Performance-critical builds
typescript
import { AccessibilityGuard, contrastRatio, meetsContrastRequirement } from "@mastors/accessibility";

// Utility functions
contrastRatio("#3b82f6", "#ffffff");              // → 3.94
meetsContrastRequirement("#000000", "#ffffff", "AA");  // → true

// Guard instance
const guard = new AccessibilityGuard("enforce", tokenRegistry);
guard.check(intentId, styleMap);                  // throws if error-severity violations exist

// Generate a full compliance manifest
const manifest = guard.generateManifest(totalIntents);
// { totalIntents, passCount, failCount, violations: A11yViolation[] }

Package Reference

Mastors is a pnpm monorepo with fully tree-shakeable packages.

Package Description Key exports
@mastors/api Public Intent Declaration API intent · configure · semantics · compose
@mastors/core Semantic Resolver Engine SemanticResolver · defaultResolver
@mastors/schemas Built-in semantic vocabulary defineSchema · defaultSchema · builtinVocabulary
@mastors/tokens Design token registry TokenRegistry · defaultTokens · defaultRegistry
@mastors/compiler Zero-runtime CSS output compiler MastorsCompiler
@mastors/accessibility WCAG 2.2 guard layer AccessibilityGuard · contrastRatio · generateFocusRing
@mastors/types Shared TypeScript definitions All core types (tree-shakeable)
@mastors/utils Shared utility functions camelToKebab · tokenPathToCssVar · deepMerge
@mastors/adapter-react React adapter useIntent · Mastors.*
@mastors/adapter-vue Vue 3 adapter useIntent · MastorsPlugin · v-intent
@mastors/adapter-svelte Svelte adapter resolveIntent · intentAction
@mastors/plugin-vite Vite build plugin mastorsPlugin
@mastors/plugin-webpack webpack build plugin MastorsWebpackPlugin

Roadmap

Mastors is actively developed. Here's what's shipped and what's coming.

Phase 1 — Foundation ✓ Shipped Q3–Q4 2025
Core intent() API · SemanticResolver v0.1 · Vite plugin · Interactive Playground
Phase 2 — Engine In Progress Q1–Q2 2026
Zero-runtime compiler · WCAG 2.2 Guard · Animation intents · VSCode extension with intent autocomplete
Phase 3 — AI Integration Planned Q3–Q4 2026
AI cleanup layer (mastors ai-normalize) · Figma plugin · Vue & Svelte adapters · Mastors Studio beta
Phase 4 — Ecosystem Future 2027+
Component marketplace · Mastors Cloud · Enterprise compiler · Angular adapter · MCP server for LLMs

Try it in the Playground

Type any intent identifier and see live CSS output, token references, WCAG hints, and a rendered preview.

Open Mastors Playground