---
name: tailwindcss
description: Tailwind CSS utility-first styling for JARVIS UI components
model: sonnet
risk_level: LOW
version: 1.1.0
---
# Tailwind CSS Development Skill
> **File Organization**: This skill uses split structure. See `references/` for advanced patterns.
## 1. Overview
This skill provides Tailwind CSS expertise for styling the JARVIS AI Assistant interface with utility-first CSS, creating consistent and maintainable HUD designs.
**Risk Level**: LOW - Styling framework with minimal security surface
**Primary Use Cases**:
- Holographic UI panel styling
- Responsive HUD layouts
- Animation utilities for transitions
- Custom JARVIS theme configuration
## 2. Core Responsibilities
### 2.1 Fundamental Principles
1. **TDD First**: Write component tests before styling implementation
2. **Performance Aware**: Optimize CSS output size and rendering performance
3. **Utility-First**: Compose styles from utility classes, extract components when patterns repeat
4. **Design System**: Define JARVIS color palette and spacing in config
5. **Responsive Design**: Mobile-first with breakpoint utilities
6. **Dark Mode Default**: HUD is always dark-themed
7. **Accessibility**: Maintain sufficient contrast ratios
## 3. Implementation Workflow (TDD)
### 3.1 TDD Process for Styled Components
Follow this workflow for every styled component:
#### Step 1: Write Failing Test First
```typescript
// tests/components/HUDPanel.test.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import HUDPanel from '~/components/HUDPanel.vue'
describe('HUDPanel', () => {
it('renders with correct JARVIS theme classes', () => {
const wrapper = mount(HUDPanel, {
props: { title: 'System Status' }
})
const panel = wrapper.find('[data-testid="hud-panel"]')
expect(panel.classes()).toContain('bg-jarvis-bg-panel/80')
expect(panel.classes()).toContain('border-jarvis-primary/30')
expect(panel.classes()).toContain('backdrop-blur-sm')
})
it('applies responsive grid layout', () => {
const wrapper = mount(HUDPanel)
const grid = wrapper.find('[data-testid="panel-grid"]')
expect(grid.classes()).toContain('grid-cols-1')
expect(grid.classes()).toContain('md:grid-cols-2')
expect(grid.classes()).toContain('lg:grid-cols-3')
})
it('shows correct status indicator colors', async () => {
const wrapper = mount(HUDPanel, {
props: { status: 'active' }
})
const indicator = wrapper.find('[data-testid="status-indicator"]')
expect(indicator.classes()).toContain('bg-jarvis-primary')
expect(indicator.classes()).toContain('animate-pulse')
await wrapper.setProps({ status: 'error' })
expect(indicator.classes()).toContain('bg-jarvis-danger')
})
it('maintains accessibility focus styles', () => {
const wrapper = mount(HUDPanel)
const button = wrapper.find('button')
expect(button.classes()).toContain('focus:ring-2')
expect(button.classes()).toContain('focus:outline-none')
})
})
```
#### Step 2: Implement Minimum to Pass
```vue