--- name: vois-tokens description: Rules and patterns for building UI with shadcn/ui, Tailwind v4 or StyleX, and Motion against a Vois design token set. Use when building components, pages, or any UI that should conform to the workspace design system. Covers spacing, typography, color tokens, component architecture, animation, accessibility, and modern CSS/StyleX patterns. version: 1.13.0 --- # Vois Tokens Skill (Rules & Values Edition) > Full version & updates: https://github.com/ommakes/Skills/blob/main/vois-tokens/SKILL.md — the full version adds a live per-edit checker hook (`scripts/`) for Claude Code, Cursor, and Codex, and a "Reviewing Existing UI" workflow for auditing code diffs. Both are code-editing features with no Figma equivalent, so this edition presents the design rules and token values as an adoptable reference implementation instead. Vois's Figma plugin syncs these tokens into your file as real variables if you want to adopt the system rather than just read about it. You are building UI for a design system that uses **shadcn/ui**, **Tailwind v4 or StyleX**, and **Motion**. This skill defines the rules, constraints, and patterns to follow. Deviation produces inconsistent, unmaintainable UI. Determine which styling engine the project uses (check `package.json` for `tailwindcss` vs `@stylexjs/stylex`, or ask) before applying the Tailwind- or StyleX-specific sections below — everything else applies either way. ## Taste dials If your workspace defines **VARIANCE** (layout asymmetry), **MOTION** (animation richness), and **DENSITY** (information per screen) as 1–10 dials, use them to tune choices you'd otherwise make by default: DENSITY biases spacing toward the tighter or looser end of the scale below; MOTION biases how much animation to add (low = essential feedback only, high = richer entrance/transition choreography); VARIANCE biases layout symmetry (low = symmetric grids, high = asymmetry welcome — also gates the centered-hero anti-slop rule below). **Dials never override hard rules.** Animations stay under the 300/500ms caps and honor `prefers-reduced-motion` even at MOTION 10; contrast, touch targets, and the 4/8 spacing scale hold even at DENSITY 10. Dials choose *within* the allowed range, never widen it. If no dials are defined, assume mid defaults (5/4/5). ## Before You Write Anything 1. Check the component manifest. If a component exists for what you need, use it — don't build a new one. 2. Check the token tables in the relevant section below (spacing, type scale, color, elevation, icon size, breakpoints). If a token exists, use it — don't hardcode. 3. If neither exists, flag it — don't invent values or components. ## Topic Index | Topic | Rule prefix | |---|---| | Spacing | `[DS-SPACING]` | | Typography | `[DS-TYPOGRAPHY]` | | Color | `[DS-COLOR]` | | Components (variants, modals, accordions) | `[DS-COMPONENT]` `[DS-MODAL]` | | Surfaces (radius, alignment, shadows, motion polish) | `[DS-SURFACE]` | | Elevation | `[DS-ELEVATION]` | | Iconography | `[DS-ICON]` | | Layout & responsive | `[DS-LAYOUT]` `[DS-RESPONSIVE]` | | Tailwind v4 | `[DS-TAILWIND]` | | StyleX (alternative to Tailwind) | `[DS-STYLEX]` | | Animation | `[DS-ANIMATION]` | | Accessibility | `[DS-A11Y]` | | CSS architecture | `[DS-CSS]` | | Anti-slop (generic "AI-looking" defaults) | `[DS-SLOP]` | --- ## Pre-Submit Checklist Run this before calling anything done. **Spacing** - [ ] All spacing values divisible by 4 or 8 `[DS-SPACING-001]` - [ ] No arbitrary spacing values `[DS-SPACING-003]` - [ ] Consistent at all tested breakpoints `[DS-SPACING-004]` **Typography** - [ ] No more than 3 text styles in any component `[DS-TYPOGRAPHY-001]` - [ ] Heading levels sequential, none skipped `[DS-TYPOGRAPHY-002]` - [ ] Numeric data uses monospace with `tabular-nums` `[DS-TYPOGRAPHY-003]` - [ ] Headings have `text-wrap: balance` `[DS-TYPOGRAPHY-006]` - [ ] Body copy has `text-wrap: pretty` `[DS-TYPOGRAPHY-007]` - [ ] Text containers have `max-width: 65ch` `[DS-TYPOGRAPHY-008]` - [ ] Ellipsis is `…` not `...` `[DS-TYPOGRAPHY-009]` - [ ] Quotes are curly, not straight `[DS-TYPOGRAPHY-010]` **Color** - [ ] No hardcoded hex values `[DS-COLOR-001]` - [ ] No raw Tailwind palette classes where tokens exist `[DS-COLOR-002]` - [ ] Both light and dark mode verified manually `[DS-COLOR-007]` - [ ] Color is not the only signal for error/success/warning `[DS-COLOR-003]` - [ ] Decorative icons have `aria-hidden="true"` `[DS-COLOR-005]` **Components** - [ ] Checked component manifest before building anything new `[DS-COMPONENT-001]` - [ ] Variants used semantically, not just defaulted `[DS-COMPONENT-006]` - [ ] cva used for variant logic `[DS-COMPONENT-002]` - [ ] Modals use `inert` on background content `[DS-MODAL-001]` - [ ] Modals have `overscroll-behavior: contain` `[DS-MODAL-002]` - [ ] `scrollbar-gutter: stable` on `html` `[DS-MODAL-003]` **Surfaces** - [ ] Nested rounded elements use concentric radius (`outer = inner + padding`) `[DS-SURFACE-001]` - [ ] Icons/buttons optically aligned, not just geometrically centered `[DS-SURFACE-003]` - [ ] Shadows used instead of borders for depth (not for dividers) `[DS-SURFACE-007]` - [ ] Image outlines are pure black/white at 0.1 opacity, never tinted `[DS-SURFACE-010]` - [ ] Enter animations split into chunks and staggered, not one big container `[DS-SURFACE-011]` - [ ] Exit animations are subtler/shorter than enters `[DS-SURFACE-013]` - [ ] Icon state transitions use scale 0.25→1, opacity, blur — not visibility toggling `[DS-SURFACE-014]` **Animation** - [ ] UI animations under 300ms (large elements under 500ms) `[DS-ANIMATION-001]` `[DS-ANIMATION-002]` - [ ] No keyboard-triggered animations `[DS-ANIMATION-003]` - [ ] `transform-origin` set to trigger point, not center `[DS-ANIMATION-006]` - [ ] No animations from `scale(0)` `[DS-ANIMATION-005]` - [ ] `prefers-reduced-motion` handled `[DS-ANIMATION-004]` - [ ] No `transition: all` `[DS-TAILWIND-005]` - [ ] Hover effects guarded on touch devices `[DS-ANIMATION-007]` - [ ] `will-change` only when stutter is actually observed, only on transform/opacity/filter `[DS-ANIMATION-009]` **Accessibility** - [ ] All interactive elements have `:focus-visible` styles `[DS-A11Y-002]` - [ ] No `outline: none` without a replacement `[DS-A11Y-003]` - [ ] Touch targets minimum 44×44px `[DS-A11Y-001]` - [ ] Contrast passes WCAG AA `[DS-A11Y-004]` - [ ] No `div`/`span` as interactive elements without ARIA `[DS-A11Y-005]` - [ ] All images have `alt` `[DS-A11Y-010]` - [ ] `
`/`` used for radio/checkbox groups `[DS-A11Y-016]` - [ ] `