Communitygithub.com

Adamparishspok/skills

Consolidate several apps or prototypes onto one shared component library without flattening their looks. Covers finding duplicated local components (buttons, selects, fields, modals, pagers, toasts), making shared components token-sized so each suite or app sets its own measurements, mapping variant names, deciding what stays app-specific, and the tailwind-merge traps that silently break custom tokens. Use when several apps each grew their own Btn/Select/Modal, when a design system's components "don't fit" a second product, or when retheming a family of apps. Triggers on: shared component library, design system consolidation, duplicate components, retheme, suite of apps, shadcn retokened, token-driven components, cn tailwind-merge custom tokens, variant mapping.

What is skills?

skills is a Claude Code agent skill that consolidate several apps or prototypes onto one shared component library without flattening their looks. Covers finding duplicated local components (buttons, selects, fields, modals, pagers, toasts), making shared components token-sized so each suite or app sets its own measurements, mapping variant names, deciding what stays app-specific, and the tailwind-merge traps that silently break custom tokens. Use when several apps each grew their own Btn/Select/Modal, when a design system's components "don't fit" a second product, or when retheming a family of apps. Triggers on: shared component library, design system consolidation, duplicate components, retheme, suite of apps, shadcn retokened, token-driven components, cn tailwind-merge custom tokens, variant mapping.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Adamparishspok/skills/tree/HEAD/skills/multi-app-design-system

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation


name: multi-app-design-system description: Consolidate several apps or prototypes onto one shared component library without flattening their looks. Covers finding duplicated local components (buttons, selects, fields, modals, pagers, toasts), making shared components token-sized so each suite or app sets its own measurements, mapping variant names, deciding what stays app-specific, and the tailwind-merge traps that silently break custom tokens. Use when several apps each grew their own Btn/Select/Modal, when a design system's components "don't fit" a second product, or when retheming a family of apps. Triggers on: shared component library, design system consolidation, duplicate components, retheme, suite of apps, shadcn retokened, token-driven components, cn tailwind-merge custom tokens, variant mapping. license: MIT

Many apps, one system

The usual failure: a kit is built for app A, app B's buttons are 4px taller and 2px rounder, so B forks the button "just this once". Five apps later there are six buttons, eight selects and three modals, all doing the same job.

Make the shared component token-sized: it carries behaviour, markup and states, and each theme supplies measurements. Then consolidate app by app.

Token-sized components

Read every measurement that differs between apps from a theme token:

@theme {
  --spacing-btn-sm: 1.75rem;  --spacing-btn-px-sm: 0.625rem;
  --spacing-btn-md: 2.25rem;  --spacing-btn-px-md: 0.875rem;
  --spacing-field: 2.125rem;  /* input / select height */
  --text-label: 0.8125rem;
}
md: "h-btn-md px-btn-px-md text-sm",
icon: "size-btn-md",

Then:

  • A suite overrides the tokens once in its theme, and every app in it gets its own measured control.
  • Radius, fills and shadows are already tokens (rounded-field, bg-accent, --shadow-card).
  • Paint fills as colour plus a decorative class, for example bg-accent accent-fill. A theme that only defines the decoration (a sheen) then never renders a transparent button.

See references/button.tsx.

Consolidation pass, per app

  1. Inventory local copies. Grep each app for export function (Btn|Button|IconBtn|Select|Field|Input|Modal|Dialog|Sheet|Badge|Empty|Pager|Toast|Stat|Status|Spinner). Count call sites.

  2. Replace and delete where the shared one matches after theming. Map variant names explicitly and write the mapping down:

    Local nameShared variant
    primary, navyaccent
    secondaryoutline
    quiet, softsubtle
    danger (solid)danger-solid
  3. Keep app-specific pieces app-specific:

    • domain widgets, charts and app chrome;
    • controls whose shape is the brand (iOS slabs, Carbon flat controls, 48px pill CTAs);
    • controls with behaviour the shared one lacks (tri-state checkbox, removable chips, an "Any" reset item, multi-select filters).

    A thin wrapper is fine when it adds one thing. Note why in a comment.

  4. Retire native <select>s and menu-based selects for one Select.

    • Radix Select reserves "" as "no value": use a sentinel like "all" and map it back.
    • Forward aria-labelledby and aria-describedby.
    • Walkthrough scripts that call selectOption() must click the combobox, then the option.
  5. Verify each app against its own screenshots (see visual-regression-pass). Real diffs are usually intended: sizes, sheen, press scale.

tailwind-merge traps (cn())

tailwind-merge only knows Tailwind's built-in scale. Custom tokens break it in three silent ways:

  • Unknown spacing tokens. cn("h-btn-md", "h-10") keeps both, because it doesn't know h-btn-md is a height, and stylesheet order picks the winner. A caller's h-10 lost to the token and a 40px button rendered at 36px. Register tokens: extendTailwindMerge({ extend: { theme: { spacing: ["btn-sm","btn-md","field", …] } } }).
  • Unknown text sizes. cn("text-meta", "text-ink") treats text-meta as a colour and drops it. Register sizes: theme: { text: ["meta","micro","label"] }.
  • Custom shadows and colours. text-14 beside text-t3, or arbitrary shadow-[var(--x)] beside a named shadow: the same problem. When a codebase has a closed custom scale everywhere, use plain clsx there.

See references/cn.ts.

Focus and validation

  • An aria-invalid:ring-* style outranks focus-visible:ring-* and hides the focus ring on a focused invalid field. Write aria-invalid:not-focus-visible:ring-….
  • Bare <button>s inside forms submit them. If the shared Button doesn't default type="button", every converted non-submit call site must set it.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

Adamparishspok/skills

Make a website, web app or online store ready for AI agents. Scan it with Cloudflare's Agent Readiness checks, decide which checks apply to this kind of site, ship the discovery files and headers in priority order, and add the AI-first basics the scanner does not score (server-rendered content, JSON-LD, llms.txt). Covers robots.txt AI rules, Content Signals, sitemap, Markdown for Agents (Accept text/markdown), Link headers, API catalog, OAuth discovery, auth.md, MCP server card, A2A agent card, agent skills index, WebMCP, and commerce protocols (ACP, UCP, AP2, MPP, x402). Use when making a site AI-ready, agent-ready or AI-first, or fixing an isitagentready.com or Cloudflare Agent Readiness report. Triggers on: AI ready, agent ready, AI-first, agent readiness, isitagentready, AI Crawl Control, Markdown for Agents, text/markdown, llms.txt, GPTBot, ClaudeBot, AI crawlers, Content-Signal, ai-train, api-catalog, .well-known, oauth-protected-resource, auth.md, MCP server card, agent card, agent skills, WebMCP, a...

Adamparishspok/skills

Install a complete, lean favicon set on any website or web app — the five files modern browsers, iOS and Android actually use, one block of head markup added once in the root layout, and a check that every file resolves. Covers finding the public folder per framework, generating the set from one SVG (or from a RealFaviconGenerator package), dark-mode SVG icons, maskable manifest icons, cache busting and verification. Use when adding, replacing or auditing a favicon, app icon, apple-touch-icon or web manifest. Triggers on: favicon, favicon.ico, favicon.svg, apple-touch-icon, site.webmanifest, manifest.json, app icon, PWA icon, maskable icon, tab icon, RealFaviconGenerator.

Adamparishspok/skills

Give an interface one shared tempo and a small vocabulary of hover and state micro-interactions: duration tiers (tap/pop/hover/card/layout) for CSS and Motion, swap hand-offs, rows whose highlight grows in, trailing arrows, chevron nudges, card lifts without translate, scroll-edge fades, and icon/label swaps for copy and toggle buttons. Use when animations feel inconsistent, durations are scattered magic numbers, hovers only change colour, or a product feels flat or unfinished. Triggers on: animation duration, transition timing, hover state, micro-interaction, polish, copy button feedback, menu icon to close, back arrow, card hover, scroll fade, motion tokens, Framer Motion durations.

Adamparishspok/skills

Build or migrate a UI's neutral palette (grounds, surfaces, lines, ink/text) as an OKLCH formula driven by a few inputs instead of dozens of hand-picked hex values, with light and dark themes, per-step ladder overrides, a fit script that reproduces existing colours, and a browser contrast audit. Use when creating a theme, adding dark mode, retinting a product, auditing text contrast, or consolidating several apps' palettes. Triggers on: palette, neutrals, grey ramp, dark mode, theme tokens, oklch, retint, hue, contrast audit, design tokens, Tailwind @theme colours.

Related Skills