{
  "$schema": "https://ui.byronwade.com/r/contract.schema.json",
  "platform": {
    "id": "design-contracts",
    "version": "1.0.0",
    "mcpTools": [
      "get_contract",
      "resolve_token",
      "validate_ui",
      "list_primitives",
      "get_recipe",
      "apply_prefs"
    ],
    "pricingModel": "open-source",
    "priceMonthlyUsd": 0,
    "contractJsonKeys": [
      "$schema",
      "platform",
      "id",
      "name",
      "version",
      "priceMonthlyUsd",
      "mcp",
      "urls",
      "aesthetic",
      "mandate",
      "tokens",
      "banned",
      "consistencyBans",
      "primitives",
      "recipes",
      "prefs"
    ],
    "kit": "consistency"
  },
  "id": "vellum",
  "name": "Vellum",
  "version": "0.1.0",
  "priceMonthlyUsd": 0,
  "mcp": {
    "slug": "vellum",
    "tools": [
      "get_contract",
      "resolve_token",
      "validate_ui",
      "list_primitives",
      "get_recipe",
      "apply_prefs"
    ]
  },
  "urls": {
    "home": "https://ui.byronwade.com/vellum",
    "design": "https://ui.byronwade.com/vellum/design.md",
    "agents": "https://ui.byronwade.com/vellum/agents.md",
    "contract": "https://ui.byronwade.com/r/vellum.contract.json",
    "install": "https://ui.byronwade.com/vellum/install",
    "schema": "https://ui.byronwade.com/r/contract.schema.json"
  },
  "aesthetic": "Mist reading lanes, measured prose, typeset-first help surfaces.",
  "status": "preview",
  "mandate": {
    "purpose": "Keep application UI consistent across the product. Creativity is content + composition — never new tokens, shadows, or twin components. Law book + skills + CI gates are required; contract MCP is optional.",
    "beforeUi": [
      "Load this contract's design.md + agents.md and obey must / mustNot",
      "Open the matching {id}-* skill before composing product wholes",
      "Resolve colors/radii/depths from the closed kit only (MCP resolve_token optional)",
      "Compose only approved primitives — never fork Button/Card/shell twins",
      "Pick a task recipe when the surface matches (list, detail, agent-rail, …)"
    ],
    "beforeDone": [
      "Run npm run validate (check:design · platform · contrast) before claiming done",
      "Optional: run MCP validate_ui on snippets when tool-wired",
      "Own empty, loading, and error on resource surfaces",
      "Selected rows/items use bg-brand/10 — not a new border color",
      "Icons only from @/lib/icons (Phosphor) — never lucide-react",
      "Depth only via edge / depth-* — never Tailwind shadow-*"
    ],
    "must": [
      "OKLCH semantic tokens only (bg-background, text-foreground, bg-brand, …)",
      "One accent → --brand (selected = bg-brand/10)",
      "Closed radii: control rounded-lg · pill rounded-full · input rounded-lg · panel rounded-2xl · shell rounded-3xl",
      "data-surface for density (application | marketing | mobile | desktop)",
      "Object-bound AI with outcome-then-trace disclosure",
      "typeset presets for markdown/HTML — no per-tag class soup",
      "Same machine filenames + recipe ids on every design contract",
      "Reuse existing primitives/recipes before inventing new components"
    ],
    "mustNot": [
      "Invent hex / rgb / hsl / arbitrary color utilities",
      "Use Tailwind shadow-* (use edge / depth-*)",
      "Import lucide-react or @phosphor-icons/react directly",
      "Add a second brand accent or status-as-brand",
      "Ship font-bold on display/section headings",
      "Invent twin components or bespoke app shells",
      "Fork MCP tools / filenames / JSON keys for one contract only",
      "Demo-only happy paths without empty/loading/error",
      "Skip CI gates because an MCP tool was called"
    ]
  },
  "tokens": {
    "colorRoles": [
      "background",
      "foreground",
      "card",
      "popover",
      "primary",
      "secondary",
      "muted",
      "accent",
      "destructive",
      "warning",
      "success",
      "brand",
      "brand-muted",
      "border",
      "input",
      "ring",
      "dock",
      "dock-muted",
      "sidebar"
    ],
    "radii": [
      "rounded-lg",
      "rounded-2xl",
      "rounded-3xl",
      "rounded-full"
    ],
    "radiusIntents": {
      "control": "rounded-lg",
      "pill": "rounded-full",
      "input": "rounded-lg",
      "panel": "rounded-2xl",
      "shell": "rounded-3xl"
    },
    "depths": [
      "edge",
      "depth-none",
      "depth-soft",
      "depth-raised"
    ],
    "depthIntents": [
      "depth-none",
      "depth-soft",
      "depth-raised",
      "depth-100",
      "depth-300",
      "depth-400",
      "depth-600"
    ],
    "surfaces": [
      "application",
      "marketing",
      "mobile",
      "desktop"
    ],
    "activityRoles": [
      "thinking",
      "search",
      "read",
      "edit"
    ],
    "provenanceRoles": [
      "user",
      "assistant",
      "tool",
      "source",
      "app",
      "action"
    ],
    "typesetPresets": [
      "docs",
      "chat",
      "reading",
      "compact"
    ]
  },
  "banned": [
    "raw-hex-color",
    "arbitrary-color-utility",
    "non-oklch-color",
    "tailwind-shadow",
    "dvh-viewport",
    "font-bold-display",
    "scroll-choreography",
    "overlay-stickers-on-media",
    "pure-white",
    "pure-black",
    "bright-neon-accent",
    "cream-terracotta-cliche",
    "second-accent",
    "influence-brand-labels",
    "floating-chatbot",
    "nested-demo-scrollports",
    "inset-hero-media",
    "low-contrast-on-dock",
    "foreground-opacity-cheat",
    "direct-lucide-import",
    "direct-phosphor-import",
    "arbitrary-px-height",
    "arbitrary-px-type",
    "arbitrary-px-padding"
  ],
  "consistencyBans": [
    "hex-color",
    "rgb-hsl-literal",
    "tailwind-shadow",
    "font-bold-display",
    "lucide-import",
    "phosphor-direct-import",
    "arbitrary-color-utility",
    "second-accent"
  ],
  "primitives": [
    "button",
    "input",
    "textarea",
    "select",
    "checkbox",
    "switch",
    "table",
    "card",
    "dialog",
    "sheet",
    "tabs",
    "tooltip",
    "dropdown-menu",
    "sonner",
    "separator",
    "badge"
  ],
  "recipes": [
    {
      "id": "list-resource",
      "intent": "Scanable index of domain objects with filter + row actions.",
      "surface": "application",
      "must": [
        "stable row height",
        "mono metadata",
        "owns empty + loading + error",
        "selected = bg-brand/10"
      ],
      "never": [
        "marketing cards for rows",
        "raw hex",
        "shadow-*"
      ]
    },
    {
      "id": "edit-record",
      "intent": "Form to create/update one object with clear save path.",
      "surface": "application",
      "must": [
        "labels on every field",
        "validation inline",
        "h-8/h-9 controls",
        "rounded-lg inputs"
      ],
      "never": [
        "hero CTA height on every button",
        "serif body in forms"
      ]
    },
    {
      "id": "object-detail",
      "intent": "One product object with meta, actions, related lists.",
      "surface": "application",
      "must": [
        "title → description → meta",
        "edge panels",
        "object-bound AI"
      ],
      "never": [
        "detached promo chips",
        "second accent color"
      ]
    },
    {
      "id": "agent-rail",
      "intent": "AI attached to an object — outcome first, trace disclosed.",
      "surface": "application",
      "must": [
        "data-provenance",
        "outcome-then-trace",
        "bg-activity-* for agent verbs only",
        "mono tool/model names"
      ],
      "never": [
        "activity colors as brand",
        "hidden errors"
      ]
    },
    {
      "id": "settings-form",
      "intent": "Workspace or user preferences in calm chrome.",
      "surface": "application",
      "must": [
        "grouped sections",
        "quiet destructive",
        "focus rings"
      ],
      "never": [
        "theater tone for settings",
        "dense mono walls of copy"
      ]
    },
    {
      "id": "empty-recovery",
      "intent": "Empty/error states that teach the next action.",
      "surface": "application",
      "must": [
        "role=alert on errors",
        "one clear CTA",
        "no shame copy"
      ],
      "never": [
        "illustration zoo",
        "multiple competing CTAs"
      ]
    }
  ],
  "prefs": {
    "defaults": {
      "brand": "teal",
      "radius": "compact",
      "paper": "warm"
    },
    "brand": [
      {
        "id": "teal",
        "label": "Ink teal",
        "brand": "oklch(0.42 0.09 200)",
        "brandFg": "oklch(0.97 0.01 85)",
        "brandMuted": "oklch(0.93 0.03 200)",
        "accent": "oklch(0.93 0.02 200)"
      },
      {
        "id": "slate",
        "label": "Slate",
        "brand": "oklch(0.42 0.08 250)",
        "brandFg": "oklch(0.97 0.01 85)",
        "brandMuted": "oklch(0.93 0.03 250)",
        "accent": "oklch(0.93 0.02 250)"
      },
      {
        "id": "moss",
        "label": "Moss",
        "brand": "oklch(0.42 0.08 155)",
        "brandFg": "oklch(0.97 0.01 85)",
        "brandMuted": "oklch(0.93 0.03 155)",
        "accent": "oklch(0.93 0.02 155)"
      },
      {
        "id": "wine",
        "label": "Wine",
        "brand": "oklch(0.42 0.09 15)",
        "brandFg": "oklch(0.97 0.01 85)",
        "brandMuted": "oklch(0.93 0.03 15)",
        "accent": "oklch(0.93 0.02 15)"
      }
    ],
    "radius": [
      {
        "id": "compact",
        "label": "Compact",
        "value": "0.375rem"
      },
      {
        "id": "default",
        "label": "Default",
        "value": "0.5rem"
      },
      {
        "id": "soft",
        "label": "Soft",
        "value": "0.75rem"
      }
    ],
    "paper": [
      {
        "id": "warm",
        "label": "Warm paper",
        "background": "oklch(0.965 0.01 72)",
        "foreground": "oklch(0.28 0.02 55)",
        "card": "oklch(0.98 0.008 72)"
      },
      {
        "id": "cool",
        "label": "Cool paper",
        "background": "oklch(0.96 0.01 230)",
        "foreground": "oklch(0.28 0.02 240)",
        "card": "oklch(0.98 0.008 230)"
      },
      {
        "id": "night",
        "label": "Night",
        "background": "oklch(0.22 0.016 50)",
        "foreground": "oklch(0.94 0.01 75)",
        "card": "oklch(0.27 0.016 50)"
      }
    ],
    "notPrefs": [
      "Freeform hex / OKLCH color pickers",
      "Second brand accent",
      "Layout builders or preferred-layout marketplaces",
      "Animation catalogs as user settings",
      "Per-component theme overrides"
    ],
    "applyTool": "apply_prefs"
  },
  "generatedAt": "2026-08-06T15:54:03.698Z"
}
