Guide creating new CSS components following Tailwind + semantic component patterns with dark mode support and test coverage
/plugin marketplace add 2389-research/claude-plugins/plugin install css-development@2389-research-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Guides you through creating new CSS components following established patterns:
@applyThis is a sub-skill of css-development - typically invoked automatically via the main skill.
Use when:
This skill follows the patterns documented in the main css-development skill. Key patterns:
Semantic naming: .button-primary not .btn-blue
Tailwind composition: Use @apply to compose utilities
Dark mode: Include dark: variants by default
Composition first: Check if existing classes can be combined
Test coverage: Static CSS tests + component rendering tests
When this skill is invoked, create a TodoWrite checklist and work through it step-by-step.
First, announce that you're using this skill:
"I'm using the css-development:create-component skill to guide creating this new CSS component."
Use the TodoWrite tool to create this checklist:
Creating CSS Component:
- [ ] Survey existing components (read components.css)
- [ ] Check if composition solves it (can existing classes combine?)
- [ ] Identify component type (atom/molecule/organism if new class needed)
- [ ] Choose semantic name (follow existing naming patterns)
- [ ] Write component class (use @apply, include dark: variants)
- [ ] Create markup integration (show React/HTML usage)
- [ ] Write static CSS test (verify class exists)
- [ ] Write component rendering test (verify className application)
- [ ] Document component (add usage comment)
Action: Use the Read tool to read styles/components.css
Purpose: Understand what already exists to ensure consistency and identify reuse opportunities
What to look for:
Mark as in_progress before starting, mark as completed when done.
Action: Analyze if combining existing classes achieves the goal
Examples:
.button-primary + spacing utilities.card if it exists, add utility class if needed.badge + color utilitiesYAGNI principle: Only create a new class if composition doesn't work or creates excessive duplication in markup.
Decision:
Mark as completed when decision is made.
Action: Determine atomic design level (if creating new class)
Atoms - Basic building blocks:
.button, .input, .badge, .spinner, .linkMolecules - Composed components:
.card, .form-field, .empty-state, .alertOrganisms - Complex components:
.page-layout, .navigation, .session-card, .conversation-timelineWhy this matters: Helps scope complexity and dependencies
Mark as completed when type is identified.
Action: Choose a descriptive, semantic class name following existing patterns
Naming patterns from reference codebase:
.button-primary, .button-secondary, .button-danger.card-title, .card-description, .form-field.session-card, .marketing-hero, .dashboard-layout.session-card-active, .button-disabledAnti-patterns (avoid):
.btn-blue, .card-sm, .text-big.btn, .hdr, .desc.component, .item, .thingValidation: Name should clearly indicate purpose and fit existing patterns
Mark as completed when name is chosen.
Action: Create the CSS class in styles/components.css using Edit tool
Template:
/* [Component name] - [Brief description]
Usage: <[element] className="[class-name]">[content]</[element]> */
.[class-name] {
@apply [background-utilities] [dark-variants];
@apply [spacing-utilities];
@apply [typography-utilities];
@apply [transition-utilities];
}
Required elements:
dark: for colors/backgroundsExample:
/* Primary button - Main call-to-action button with hover lift effect
Usage: <button className="button-primary">Click me</button> */
.button-primary {
@apply bg-indigo-500 hover:bg-indigo-700 dark:bg-indigo-600 dark:hover:bg-indigo-800;
@apply px-6 py-3 rounded-lg font-medium text-white;
@apply transition-all duration-200 hover:-translate-y-0.5;
@apply focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2;
}
Use Edit tool to add to existing file (don't overwrite entire file)
Mark as completed when class is written to file.
Action: Document how to use the component in different frameworks
Show usage examples for:
Example documentation:
## Using the button-primary Component
**React:**
```tsx
const Button = ({ variant = 'primary', className = '', children, ...props }) => {
const classes = `button-${variant} ${className}`.trim();
return <button className={classes} {...props}>{children}</button>;
};
// Usage
<Button variant="primary">Click me</Button>
<Button variant="primary" className="w-full">Full width</Button>
Vanilla HTML:
<button class="button-primary">Click me</button>
<button class="button-primary custom-class">With custom class</button>
**Where to put this:** In project documentation, README, or as a comment in the component file
**Mark as completed** when markup examples are documented.
---
#### Step 7: Write Static CSS Test
**Action:** Add test to `styles/__tests__/components.test.ts` (or create if doesn't exist)
**Purpose:** Verify the CSS class exists in the components.css file
**Test pattern:**
```typescript
import { readFileSync } from 'fs';
import { describe, it, expect } from 'vitest';
describe('components.css', () => {
const content = readFileSync('styles/components.css', 'utf-8');
it('should have button-primary component class', () => {
expect(content).toContain('.button-primary');
});
it('should have button-primary dark mode variants', () => {
expect(content).toContain('dark:bg-indigo');
});
});
Key checks:
dark:)Run test:
npm test styles/__tests__/components.test.ts
# or
vitest styles/__tests__/components.test.ts
Expected: Test passes (green)
Mark as completed when test is written and passing.
Action: Add component rendering test (framework-specific)
Purpose: Verify className application works in actual components
React example:
import { render, screen } from '@testing-library/react';
import { describe, it, expect } from 'vitest';
import { Button } from '@/components/atoms/Button';
describe('Button component', () => {
it('applies button-primary class', () => {
render(<Button variant="primary">Click</Button>);
expect(screen.getByRole('button')).toHaveClass('button-primary');
});
it('accepts and applies custom className', () => {
render(<Button variant="primary" className="custom-class">Click</Button>);
const button = screen.getByRole('button');
expect(button).toHaveClass('button-primary', 'custom-class');
});
});
Key checks:
Run test:
npm test components/atoms/Button.test.tsx
# or
vitest components/atoms/Button.test.tsx
Expected: Test passes (green)
Mark as completed when test is written and passing.
Action: Ensure component has usage documentation
Documentation should include:
Additional documentation (optional but recommended):
Minimum requirement: CSS comment + markup examples exist
Mark as completed when documentation is verified.
When all checklist items are completed:
Run all tests to ensure everything passes:
npm test
Show summary of what was created:
Suggest next steps:
Example summary:
Created button-primary component!
Files created/modified:
- styles/components.css (added .button-primary)
- styles/__tests__/components.test.ts (added static CSS test)
- components/atoms/Button.test.tsx (added rendering test)
- components/atoms/Button.tsx (markup integration)
Next steps:
- Commit these changes: git add . && git commit -m "feat: add button-primary component"
- Use in your UI: <Button variant="primary">Click me</Button>
- Create variants if needed: button-secondary, button-danger, etc.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.