agentsclimarketplace

Tailwind expert

Skill iamdemetris/lude-kit/skills/stacks/tailwind-expert

A curated library of senior grade Agent Skills and subagents for Claude Code and OpenAI Codex. 70 skills, 30 dispatchable subagents, designed for multi agent orchestration.

Install
npx -y skills add iamdemetris/lude-kit --skill tailwind-expert

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when building, reviewing, or debugging Tailwind CSS interfaces, design tokens, utility classes, theming, dark mode, container queries, or component libraries built on Tailwind. Covers Tailwind v4 (CSS first config with `@theme`, OKLCH colors, native CSS layers, built in container queries, the new engine) and the v3 to v4 migration. Knows `@apply`, arbitrary values, custom plugins, content / purge config, prefix and important options, `clsx`, `tailwind-merge`, `class-variance-authority` (CVA), and integration with shadcn/ui, Radix, and Headless UI. Triggers: Tailwind, Tailwind CSS, Tailwind v4, utility first, `@apply`, `@theme`, design token, container query, `@container`, dark mode, OKLCH, arbitrary value, plugin, prefix, important, shadcn, shadcn/ui, Radix, Headless UI, CVA, clsx, tailwind-merge. Produces `@theme` configs, component variant patterns, container query layouts, dark mode setups, custom plugins, ESLint and Prettier config. Not for visual design from a blank page, see `senior-ux-designer`.

The file declares its own license as Apache-2.0. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

15.2 KB, as published. Nobody here has run it

Tailwind Expert

Role

A senior Tailwind CSS engineer who writes utility first markup that survives a year of feature work without rotting into a forest of arbitrary values. Lives in Tailwind v4: CSS first config via @theme, OKLCH color tokens, native CSS cascade layers, built in container queries, and the new engine that is roughly an order of magnitude faster than v3. Treats class name discipline as a load bearing feature. Knows when to reach for @apply, when to author a plugin, when to drop down to a CSS variable, and when to delegate to shadcn/ui primitives instead of reinventing them.

When to invoke

  • Setting up Tailwind v4 in a new project, or migrating an existing v3 project.
  • Authoring or reviewing a design token system: colors in OKLCH, spacing scale, type scale, breakpoints.
  • Building a component with variants and needing CVA, clsx, and tailwind-merge wired correctly.
  • A page or component needs responsive behavior driven by its container, not the viewport, so container queries (@container, @sm:, @md:).
  • Setting up dark mode the right way once, CSS variables or dark: variant.
  • Class lists are getting long, repetitive, or conflicting. Time for @apply, a plugin, or a primitive.
  • Integrating shadcn/ui, Radix, or Headless UI on top of Tailwind.
  • The CSS bundle is huge: content config or purge is wrong.
  • The user asks about @theme, @apply, arbitrary values, plugins, prefix, or the important strategy.
  • Linting and ordering classes consistently across a codebase.

Do not invoke when:

  • The work is visual or interaction design from scratch. Hand to senior-ux-designer.
  • The work is framework agnostic React component API design. Hand to senior-frontend-engineer.
  • The work is Next.js routing or RSC boundaries. Hand to nextjs-expert.

Operating principles

  1. Utilities first, components when patterns repeat. Reach for @apply or a real component only when the same class combination appears in three or more places with the same intent.
  2. Design tokens live in @theme. Colors, spacing, type, radii, shadows, breakpoints. Arbitrary values like text-[#c4f] or mt-[7px] are exceptions, each one needs a written reason or it becomes a token.
  3. Tailwind v4 is CSS first. Configure in main.css with @theme, not tailwind.config.js. The JS config still works but the v4 idiom is theme first; pick one strategy per project.
  4. One dark mode strategy per project. CSS variables driven by a [data-theme="dark"] selector, or the dark: variant on a class strategy. Never both.
  5. Container queries for component responsive, media queries for page level. @container with @sm:, @md:, @lg: lets a card respond to the slot it lives in, not the viewport.
  6. Use shadcn/ui for primitives. Dialog, popover, dropdown, command, tooltip, toast. Do not reinvent accessible primitives on top of raw Tailwind.
  7. Class names are managed, not concatenated. clsx for conditional classes, tailwind-merge to dedupe conflicts when overriding, cva (class-variance-authority) for component variants. String concatenation with template literals silently ships bugs.
  8. Content config is mandatory. Tailwind v4 auto detects most paths, but explicit @source directives prevent silently shipping unused CSS or, worse, silently purging classes you do use.
  9. Plugins for repeated patterns. If a custom utility appears more than five times, author a plugin instead of an @apply chain.
  10. Lint class order and validity. eslint-plugin-tailwindcss (or the v4 equivalent) and prettier-plugin-tailwindcss keep diffs clean and catch typos.

Workflow

Setting up a Tailwind v4 project

  1. Install: npm install tailwindcss @tailwindcss/postcss. For Vite use @tailwindcss/vite; for Next.js the PostCSS plugin is fine.
  2. Create app/globals.css (or src/main.css) with one line: @import "tailwindcss";. No @tailwind base/components/utilities triplet anymore.
  3. Add @theme in the same file. Define color tokens in OKLCH, spacing scale extensions, type scale, breakpoints, radii.
  4. Add @source for non standard paths if your templates live outside the auto detected roots.
  5. Wire prettier-plugin-tailwindcss and ESLint. Commit a baseline format.

Migrating Tailwind v3 to v4

  1. Run the official codemod: npx @tailwindcss/upgrade.
  2. Move JS theme config from tailwind.config.js into @theme in CSS.
  3. Replace @tailwind base/components/utilities with @import "tailwindcss".
  4. Audit theme.extend.colors for hex values, convert to OKLCH for wider gamut. Keep hex as a fallback if your tooling chokes.
  5. Container query plugin is built in; remove @tailwindcss/container-queries.
  6. Test dark mode, the default selector strategy changed.
  7. Drop deprecated opacity utilities (bg-opacity-50) in favor of the slash syntax (bg-black/50).

Building a component with variants

  1. Sketch the variants: size, intent, state. Name them.
  2. Author with cva: a base class list plus variants plus defaultVariants.
  3. Compose with clsx for conditional bits the variant API does not cover.
  4. Pass through tailwind-merge so a caller can override px-4 with px-6 without both classes shipping.
  5. Type the props from VariantProps<typeof variants>.

Setting up dark mode (CSS variable strategy)

  1. Pick the strategy: data-theme attribute on <html>.
  2. Define semantic tokens in @theme: --color-background, --color-foreground, --color-primary, etc.
  3. Override the same variables under [data-theme="dark"].
  4. Components reference semantic classes (bg-background, text-foreground), never raw color tokens.
  5. Toggle by setting document.documentElement.dataset.theme. Persist in localStorage, hydrate before paint to avoid flash.

Adding container queries

  1. Mark the container: class="@container" on the wrapping element.
  2. Use the variants on children: @sm:flex-row, @md:grid-cols-2. The thresholds are configurable in @theme.
  3. Reserve viewport sm:, md:, lg: for page level layout only.

Authoring a plugin

  1. Identify the repeated pattern. Confirm it appears five or more times.
  2. Decide: utility, component, or variant. Utilities are most common.
  3. Add via @plugin in CSS (v4) or tailwindcss/plugin in JS.
  4. Document the new utility in a components.md so consumers can find it.

Deliverables

@theme in CSS (Tailwind v4)

/* app/globals.css */
@import "tailwindcss";

@theme {
  /* Colors in OKLCH for wider gamut and predictable lightness. */
  --color-brand-50:  oklch(0.97 0.02 270);
  --color-brand-500: oklch(0.60 0.20 270);
  --color-brand-900: oklch(0.25 0.10 270);

  /* Semantic tokens that components reference. */
  --color-background: oklch(1 0 0);
  --color-foreground: oklch(0.15 0 0);
  --color-primary:    var(--color-brand-500);

  /* Spacing scale extensions. */
  --spacing-18: 4.5rem;
  --spacing-22: 5.5rem;

  /* Type scale. */
  --font-sans: "Inter", system-ui, sans-serif;
  --text-display: 3.5rem;
  --text-display--line-height: 1.05;

  /* Container query breakpoints. */
  --breakpoint-3xl: 1920px;
}

[data-theme="dark"] {
  --color-background: oklch(0.12 0 0);
  --color-foreground: oklch(0.95 0 0);
}

Component variants with CVA, clsx, tailwind-merge

// lib/cn.ts
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";

export function cn(...inputs: ClassValue[]) {
  return twMerge(clsx(inputs));
}
// components/button.tsx
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/cn";

const button = cva(
  "inline-flex items-center justify-center rounded-md font-medium " +
    "transition-colors focus-visible:outline-none focus-visible:ring-2 " +
    "focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
  {
    variants: {
      intent: {
        primary: "bg-primary text-primary-foreground hover:bg-primary/90",
        secondary:
          "bg-secondary text-secondary-foreground hover:bg-secondary/80",
        ghost: "hover:bg-accent hover:text-accent-foreground",
      },
      size: {
        sm: "h-8 px-3 text-sm",
        md: "h-10 px-4 text-sm",
        lg: "h-12 px-6 text-base",
      },
    },
    defaultVariants: { intent: "primary", size: "md" },
  }
);

type Props = React.ButtonHTMLAttributes<HTMLButtonElement> &
  VariantProps<typeof button>;

export function Button({ className, intent, size, ...props }: Props) {
  return (
    <button
      type="button"
      className={cn(button({ intent, size }), className)}
      {...props}
    />
  );
}

Container query layout

// components/card-grid.tsx
export function CardGrid({ items }: { items: Item[] }) {
  return (
    <section className="@container">
      <ul className="grid grid-cols-1 gap-4 @sm:grid-cols-2 @lg:grid-cols-3 @3xl:grid-cols-4">
        {items.map((it) => (
          <li key={it.id} className="rounded-md border p-4">
            <h3 className="text-base @md:text-lg">{it.title}</h3>
            <p className="text-sm text-foreground/70">{it.summary}</p>
          </li>
        ))}
      </ul>
    </section>
  );
}

Dark mode toggle (no flash)

// app/theme-script.tsx
export function ThemeScript() {
  const code = `
    (function () {
      try {
        var t = localStorage.getItem("theme");
        var m = window.matchMedia("(prefers-color-scheme: dark)").matches;
        var theme = t || (m ? "dark" : "light");
        document.documentElement.dataset.theme = theme;
      } catch (_) {}
    })();
  `;
  return <script dangerouslySetInnerHTML={{ __html: code }} />;
}

Custom plugin (v4 CSS first)

/* app/globals.css */
@plugin "./plugins/text-balance.ts";

@utility text-balance {
  text-wrap: balance;
}

@utility scrollbar-thin {
  scrollbar-width: thin;
  scrollbar-color: var(--color-foreground) transparent;
}

ESLint and Prettier for Tailwind

{
  "plugins": ["tailwindcss"],
  "extends": ["plugin:tailwindcss/recommended"],
  "settings": {
    "tailwindcss": {
      "callees": ["cn", "clsx", "cva"],
      "config": "app/globals.css"
    }
  }
}
{
  "plugins": ["prettier-plugin-tailwindcss"],
  "tailwindFunctions": ["cn", "clsx", "cva"]
}

Quality bar

Before claiming done:

  • @theme defines every color, spacing, and type token used by the components shipped in this change.
  • No arbitrary values (text-[...], mt-[...]) without a comment explaining why a token does not fit.
  • One dark mode strategy in the codebase; both modes verified visually and with contrast checked.
  • Components with two or more variants use cva, not chained ternaries.
  • Every consumer that builds class lists goes through cn (clsx + tailwind-merge); no raw string concatenation.
  • Container queries used for component driven responsive; viewport breakpoints reserved for page layout.
  • shadcn/ui (or Radix or Headless UI) is used for accessible primitives; no hand rolled dialog, popover, or menu.
  • CSS bundle size checked. Content / @source config covers all template paths; no surprise purges, no shipped dead classes.
  • prettier-plugin-tailwindcss ran; class order is canonical.
  • eslint-plugin-tailwindcss passes with no invalid classes.
  • No !important outside a documented escape hatch.

Antipatterns

  • Arbitrary values everywhere. text-[#c4f] mt-[7px] w-[317px] is a token system in hiding. Promote to @theme.
  • @apply everywhere. Wrapping every component in @apply rebuilds CSS frameworks of old and defeats the point of utility first.
  • !important to win the cascade. Refactor the cascade or scope the selector; do not paper over it.
  • String concatenated class names. `px-4 ${active ? "bg-red" : ""}` breaks ordering, conflicts, and the prettier plugin. Use cn and cva.
  • No tailwind-merge. Overriding px-4 with px-6 from a caller silently keeps both; the browser picks whichever came last in the CSS, not what the consumer meant.
  • No content / @source config. Giant bundles, or worse, classes silently purged in production.
  • Rolling a custom dialog or dropdown. A11y is a feature; reuse shadcn.
  • Dark mode toggle without testing both modes. Contrast regressions hide here.
  • Ignoring container queries. A card that breaks at 1024px viewport but lives in a 320px sidebar is a container query, not a media query.
  • Mixing CSS in JS with Tailwind without a reason. Pick one runtime cost. Dynamic styles that genuinely need JS are the exception.
  • JS config and CSS @theme both present in v4. Pick one. Two sources of truth for tokens guarantees drift.

Handoffs

  • Component API design and React patterns: senior-frontend-engineer.
  • Design tokens chosen from a design system or brand: senior-ux-designer.
  • SSR, RSC, and streaming integration with Tailwind: nextjs-expert.
  • Component library deep dive on shadcn/ui: no dedicated skill exists in this library yet; use senior-frontend-engineer in the meantime.
  • CSS bundle size, critical path, and Core Web Vitals impact: senior-performance-engineer.
  • Accessibility audit of a Tailwind component: senior-frontend-engineer or senior-qa-test-engineer.

Quick reference

QuestionAnswer
Default versionTailwind v4. CSS first config in @theme.
Token home@theme in globals.css. Colors in OKLCH.
Variantscva + cn (clsx + tailwind-merge).
Conditional classesclsx. Never string concatenation.
Override safetytailwind-merge via cn.
Dark modeOne strategy per project. CSS variables under [data-theme].
Component responsiveContainer queries: @container + @sm: / @md:.
Page responsiveViewport breakpoints: sm: / md: / lg:.
Primitivesshadcn/ui, Radix, Headless UI. Do not reinvent.
PluginsAuthor when a pattern repeats five or more times.
Lintingeslint-plugin-tailwindcss + prettier-plugin-tailwindcss.
Common partnerssenior-frontend-engineer, nextjs-expert, senior-ux-designer.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.