Back
Standalone v1.6.0

vois-tokens

Enforces Vois design system rules when building UI with shadcn/ui, Tailwind v4, and Motion.

Rules and patterns for building UI with shadcn/ui, Tailwind v4, 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 patterns.

  • UI to build or review

    Describe the component, page, or pattern you're working on. Include any existing code if you have it.

  • Rule-compliant UI code

    Code that applies Vois spacing, typography, color tokens, component architecture, animation, and accessibility rules. Every deviation from the system is flagged rather than guessed.

  • Rule usage log

    A vois_record_rule_usage call listing every rule ID applied, with violated or ambiguous rules flagged for system improvement.

Load the vois-tokens skill. I'm building [describe the component or page] and need it to conform to the Vois design system.

Skills that call into or pair with this one. Click a node to open it. Expand the reference files node to browse them on GitHub.

Get this skill

Download the SKILL.md file and install it in Claude or Cursor.

  1. Download the SKILL.md file using the button above.
  2. Open claude.ai and go to Settings.
  3. Select Skills from the sidebar.
  4. Click Add skill and upload the SKILL.md file.
  5. Give the skill a name and save. Claude loads it automatically when relevant.

Skills installed in Claude persist across conversations. Claude reads the skill when the trigger conditions match your message.

Vois Tokens Skill

You are building UI for a design system that uses shadcn/ui, Tailwind v4, and Motion. This skill defines the rules, constraints, and patterns you must follow. Deviation from these rules produces inconsistent, unmaintainable UI.

This SKILL.md is the entry point. Detailed rules for each topic live in references/ — read only the file(s) relevant to what you’re building, not all of them every time.

Automated checks: a deterministic detector (scripts/detect.mjs) covers the mechanically-verifiable subset of the Pre-Submit Checklist below and can run as a per-edit hook in Claude Code, Cursor, or Codex. See references/hooks.md for setup and which rules are covered.


Before You Write Anything

  1. Check the component manifest. If a component exists for what you need, use it. Do not build a new one.
  2. Check the token reference. If a token exists for the value you need, use it. Do not hardcode anything.
  3. If neither exists, flag it — don’t invent values or components.
  4. After completing any UI work, call vois_record_rule_usage with the rule IDs you applied. This feeds the self-improving design system. If you violated a rule or found a rule unclear, include it with violated: true or ambiguous: true.

Reference Files

Read the file(s) that match what you’re building. Each file is self-contained — you don’t need to read the others to use one.

FileRead this when you’re working on…Rule prefix
references/spacing.mdAny padding, margin, or gap value[DS-SPACING]
references/typography.mdHeadings, body text, type scale, fonts, copy punctuation[DS-TYPOGRAPHY]
references/color.mdColor tokens, OKLCH, dark mode, light-dark()[DS-COLOR]
references/components.mdComponent variants, cva, modals/dialogs, accordions[DS-COMPONENT] [DS-MODAL]
references/surfaces.mdBorder radius, optical alignment, shadows vs. borders, image outlines, enter/exit choreography, icon transitions[DS-SURFACE]
references/layout-and-responsive.mdViewport height units, content-visibility, breakpoints[DS-LAYOUT] [DS-RESPONSIVE]
references/tailwind-v4.mdTailwind v3→v4 migration, container queries, arbitrary values[DS-TAILWIND]
references/animation.mdTiming, easing, reduced motion, Motion library usage[DS-ANIMATION]
references/accessibility.mdTouch targets, focus states, contrast, semantic HTML[DS-A11Y]
references/css-architecture.md@theme setup, selector specificity, media queries[DS-CSS]
references/hooks.mdSetting up the automated per-edit checker, managing ignores[DS-HOOKS]

Scoped loading: if you only need one or two rules (e.g. vois-router sent you here for a single component decision), read only the matching reference file plus this SKILL.md. You don’t need the full set for a scoped task.


Pre-Submit Checklist

Run this regardless of which reference files you read — it’s the universal gate 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 set 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 44x44px [DS-A11Y-001]
  • Contrast passes WCAG AA [DS-A11Y-004]
  • No div or span as interactive elements without ARIA [DS-A11Y-005]
  • All images have alt [DS-A11Y-010]
  • <fieldset> and <legend> used for radio/checkbox groups [DS-A11Y-016]
  • <br> not used for spacing [DS-A11Y-012]
  • <ul>/<ol> used for lists, not stacked divs [DS-A11Y-011]
  • loading="lazy" on below-the-fold images [DS-A11Y-013]

Layout

  • Using svh/lvh/dvh not vh for viewport-height layouts [DS-LAYOUT-001]
  • Long pages use content-visibility: auto on off-screen sections [DS-LAYOUT-002]
  • Tested at sm, md, lg breakpoints [DS-RESPONSIVE-002]
  • No padding-bottom/margin-top used to space siblings — use gap on parent [DS-LAYOUT-COMP-001]
  • No wrapper divs that serve no layout purpose [DS-LAYOUT-COMP-002]
  • min-width: 0 on flex children containing text or overflow-prone content [DS-LAYOUT-COMP-003]
  • Images with set dimensions have object-fit [DS-LAYOUT-COMP-006]
  • aspect-ratio used instead of padding-top percentage hack [DS-LAYOUT-COMP-005]

CSS

  • No #id selectors used for styling [DS-CSS-002]
  • Selectors no deeper than 2 levels without a class [DS-CSS-003]
  • Hand-authored @media queries use em not px [DS-CSS-007]

Quick Reference

SituationWhat to doFull detail
Need a componentCheck manifest firstreferences/components.md
Nesting rounded elementsouterRadius = innerRadius + paddingreferences/surfaces.md
Icon or button looks off-centerAlign optically, not geometricallyreferences/surfaces.md
Card/container needs depthLayered box-shadow, not a borderreferences/surfaces.md
Image needs a subtle edge1px outline, pure black/white at 0.1 opacityreferences/surfaces.md
Page or section enteringSplit into chunks, stagger ~100msreferences/surfaces.md
Icon swapping state (play/pause, like)scale 0.25→1 + opacity + blur, exact valuesreferences/surfaces.md
Need a color valueCheck token list firstreferences/color.md
Need a spacing valueRound to nearest 4 or 8references/spacing.md
Need a font sizeUse the type scalereferences/typography.md
Need full-screen heightsvh not vhreferences/layout-and-responsive.md
Text container widthmax-width: 65chreferences/typography.md
Two colors switching with themelight-dark()references/color.md
Animating accordion heightinterpolate-size: allow-keywordsreferences/components.md
Building a modalinert + overscroll-behavior + scrollbar-gutterreferences/components.md
Value doesn’t exist in tokensFlag it, don’t invent it
Animation feels offCheck transform-origin and slow it downreferences/animation.md
Hover on mobileGuard with @media (hover: hover) and (pointer: fine)references/animation.md
Unsure about contrastMeasure it. 4.5:1 minimum for normal textreferences/accessibility.md
Space between two adjacent elementsgap on the parent, not padding-bottom on the first childreferences/layout-and-responsive.md
Flex child text overflowing or not truncatingAdd min-width: 0 to the flex childreferences/layout-and-responsive.md
Fixed-size image looks stretchedAdd object-fit: cover or object-fit: containreferences/layout-and-responsive.md
16:9 or other ratio containeraspect-ratio: 16 / 9, not padding-top hackreferences/layout-and-responsive.md
Group of radio or checkbox inputsWrap in <fieldset> with <legend>references/accessibility.md
Date or time in content<time datetime="...">references/accessibility.md
Hand-authoring a media queryUse em not px for the breakpoint valuereferences/css-architecture.md
Selector getting hard to overrideYou’ve gone too deep — add a class insteadreferences/css-architecture.md
Done with UI workCall vois_record_rule_usage with rule IDs applied

Reviewing Existing UI

This section applies only when the task is reviewing, auditing, or polishing existing code against this design system — not when building something new from scratch. If you’re asked to “review this component,” “make this feel better,” or “audit this screen for design system alignment,” follow this output format.

Output Format

Present every change as a markdown table with Before and After columns, grouped under a heading per rule or category. Don’t list findings as loose “Before:” / “After:” prose lines outside a table — they’re harder to scan and easy to skim past.

  • Include every change made, not a representative subset.
  • One diff per row. Don’t bundle two unrelated changes into a single row.
  • Cite the specific file and property when it isn’t obvious from the snippet.
  • If a category was checked but nothing needed to change, omit that table entirely. Empty tables are noise, not reassurance.

Example

#### Concentric border radius `[DS-SURFACE-001]`
| Before | After |
| --- | --- |
| `rounded-xl` on card + `rounded-xl` on inner button (`p-2`) | `rounded-2xl` on card (`12 + 8`), `rounded-lg` on inner button |

#### Tabular numbers `[DS-TYPOGRAPHY-003]`
| Before | After |
| --- | --- |
| `<span>{count}</span>` on animated counter | `<span className="tabular-nums">{count}</span>` |

#### Scale on press `[DS-ANIMATION-008]`
| Before | After |
| --- | --- |
| `scale(0.9)` on button press | Raised to `scale(0.96)` — below `0.95` reads as exaggerated |

Review Checklist

Run this for any review/audit task, regardless of which reference files the underlying build touched:

  • Spacing divisible by 4 or 8, no arbitrary values
  • Color uses tokens, not hardcoded hex or raw Tailwind palette
  • Nested rounded elements use concentric radius
  • Icons/buttons optically aligned, not just geometrically centered
  • Shadows used instead of borders for depth (not dividers)
  • Component manifest checked before any custom-built equivalent
  • Modals have inert, overscroll-behavior: contain, scrollbar-gutter: stable
  • Enter animations split/staggered; exits are subtler and shorter
  • No transition: all; will-change only where stutter was actually observed
  • Touch targets at least 44×44px; focus-visible styles present
  • Headings use text-wrap: balance; body copy uses text-wrap: pretty
  • Dynamic numbers use tabular-nums

This checklist is deliberately a cross-section of the full pre-submit checklist above — it’s what’s most likely to be wrong in code that predates this design system, not an exhaustive re-walk of every rule. For a from-scratch build, use the full pre-submit checklist instead.