tailwindcss

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Tailwind CSS Development Skill

Tailwind CSS 开发技能

File Organization: This skill uses split structure. See
references/
for advanced patterns.
文件组织:本技能采用拆分结构,高级模式请查看
references/
目录。

1. Overview

1. 概述

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
本技能提供Tailwind CSS专业能力,以实用优先的CSS为JARVIS AI助手界面设置样式,打造一致且可维护的HUD设计。
风险等级:低 - 样式框架,安全面极小
主要用例:
  • 全息UI面板样式设计
  • 响应式HUD布局
  • 过渡动画工具类
  • 自定义JARVIS主题配置

2. Core Responsibilities

2. 核心职责

2.1 Fundamental Principles

2.1 基本原则

  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
  1. 优先TDD:在实现样式前编写组件测试
  2. 性能感知:优化CSS输出大小与渲染性能
  3. 实用优先:通过工具类组合样式,当模式重复时提取组件
  4. 设计系统:在配置中定义JARVIS调色板与间距规则
  5. 响应式设计:采用移动优先的断点工具类
  6. 默认深色模式:HUD始终使用深色主题
  7. 可访问性:保持足够的对比度

3. Implementation Workflow (TDD)

3. 实现工作流(TDD)

3.1 TDD Process for Styled Components

3.1 样式组件的TDD流程

Follow this workflow for every styled component:
为每个样式组件遵循以下工作流:

Step 1: Write Failing Test First

步骤1:先编写失败的测试

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')
  })
})
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

步骤2:实现最小代码以通过测试

vue
<!-- components/HUDPanel.vue -->
<template>
  <div
    data-testid="hud-panel"
    class="bg-jarvis-bg-panel/80 border border-jarvis-primary/30 backdrop-blur-sm rounded-lg p-4"
  >
    <div
      data-testid="panel-grid"
      class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
    >
      <slot />
    </div>
    <span
      data-testid="status-indicator"
      :class="statusClasses"
    />
    <button class="focus:ring-2 focus:outline-none focus:ring-jarvis-primary">
      Action
    </button>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'

const props = defineProps<{
  title?: string
  status?: 'active' | 'warning' | 'error' | 'inactive'
}>()

const statusClasses = computed(() => ({
  'bg-jarvis-primary animate-pulse': props.status === 'active',
  'bg-jarvis-warning': props.status === 'warning',
  'bg-jarvis-danger': props.status === 'error',
  'bg-gray-500': props.status === 'inactive'
}))
</script>
vue
<!-- components/HUDPanel.vue -->
<template>
  <div
    data-testid="hud-panel"
    class="bg-jarvis-bg-panel/80 border border-jarvis-primary/30 backdrop-blur-sm rounded-lg p-4"
  >
    <div
      data-testid="panel-grid"
      class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
    >
      <slot />
    </div>
    <span
      data-testid="status-indicator"
      :class="statusClasses"
    />
    <button class="focus:ring-2 focus:outline-none focus:ring-jarvis-primary">
      Action
    </button>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'

const props = defineProps<{
  title?: string
  status?: 'active' | 'warning' | 'error' | 'inactive'
}>()

const statusClasses = computed(() => ({
  'bg-jarvis-primary animate-pulse': props.status === 'active',
  'bg-jarvis-warning': props.status === 'warning',
  'bg-jarvis-danger': props.status === 'error',
  'bg-gray-500': props.status === 'inactive'
}))
</script>

Step 3: Refactor if Needed

步骤3:如有需要进行重构

Extract repeated patterns to @apply directives:
css
/* assets/css/components.css */
@layer components {
  .hud-panel {
    @apply bg-jarvis-bg-panel/80 border border-jarvis-primary/30 backdrop-blur-sm rounded-lg p-4;
  }

  .hud-grid {
    @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4;
  }
}
将重复模式提取到@apply指令中:
css
/* assets/css/components.css */
@layer components {
  .hud-panel {
    @apply bg-jarvis-bg-panel/80 border border-jarvis-primary/30 backdrop-blur-sm rounded-lg p-4;
  }

  .hud-grid {
    @apply grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4;
  }
}

Step 4: Run Full Verification

步骤4:运行完整验证

bash
undefined
bash
undefined

Run all style-related tests

Run all style-related tests

npm run test -- --grep "HUDPanel"
npm run test -- --grep "HUDPanel"

Check for unused CSS

Check for unused CSS

npx tailwindcss --content './components/**/*.vue' --output /dev/null
npx tailwindcss --content './components/**/*.vue' --output /dev/null

Verify build size

Verify build size

npm run build && ls -lh .output/public/_nuxt/*.css
undefined
npm run build && ls -lh .output/public/_nuxt/*.css
undefined

4. Performance Patterns

4. 性能模式

4.1 Purge Optimization

4.1 清除优化

javascript
// tailwind.config.js
// Good: Specific content paths
export default {
  content: [
    './components/**/*.{vue,js,ts}',
    './layouts/**/*.vue',
    './pages/**/*.vue',
    './composables/**/*.ts'
  ]
}

// Bad: Too broad, includes unused files
export default {
  content: ['./src/**/*']  // Includes tests, stories, etc.
}
javascript
// tailwind.config.js
// Good: Specific content paths
export default {
  content: [
    './components/**/*.{vue,js,ts}',
    './layouts/**/*.vue',
    './pages/**/*.vue',
    './composables/**/*.ts'
  ]
}

// Bad: Too broad, includes unused files
export default {
  content: ['./src/**/*']  // Includes tests, stories, etc.
}

4.2 JIT Mode Efficiency

4.2 JIT模式效率

javascript
// Good: Let JIT generate only used utilities
export default {
  mode: 'jit',  // Default in v3+
  theme: {
    extend: {
      // Only extend what you need
      colors: {
        jarvis: {
          primary: '#00ff41',
          secondary: '#0891b2'
        }
      }
    }
  }
}

// Bad: Defining unused variants
export default {
  variants: {
    extend: {
      backgroundColor: ['active', 'group-hover', 'disabled']  // May not use all
    }
  }
}
javascript
// Good: Let JIT generate only used utilities
export default {
  mode: 'jit',  // Default in v3+
  theme: {
    extend: {
      // Only extend what you need
      colors: {
        jarvis: {
          primary: '#00ff41',
          secondary: '#0891b2'
        }
      }
    }
  }
}

// Bad: Defining unused variants
export default {
  variants: {
    extend: {
      backgroundColor: ['active', 'group-hover', 'disabled']  // May not use all
    }
  }
}

4.3 @apply Extraction Strategy

4.3 @apply提取策略

vue
<!-- Good: Extract when pattern repeats 3+ times -->
<style>
@layer components {
  .btn-jarvis {
    @apply px-4 py-2 rounded font-medium transition-all duration-200
           focus:outline-none focus:ring-2 focus:ring-offset-2;
  }
}
</style>

<!-- Bad: @apply for single-use styles -->
<style>
.my-unique-element {
  @apply p-4 m-2 text-white;  /* Just use utilities in template */
}
</style>
vue
<!-- Good: Extract when pattern repeats 3+ times -->
<style>
@layer components {
  .btn-jarvis {
    @apply px-4 py-2 rounded font-medium transition-all duration-200
           focus:outline-none focus:ring-2 focus:ring-offset-2;
  }
}
</style>

<!-- Bad: @apply for single-use styles -->
<style>
.my-unique-element {
  @apply p-4 m-2 text-white;  /* Just use utilities in template */
}
</style>

4.4 Responsive Breakpoints Efficiency

4.4 响应式断点效率

vue
<!-- Good: Mobile-first, minimal breakpoints -->
<div class="p-2 md:p-4 lg:p-6">
  <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4">
</div>

<!-- Bad: Redundant breakpoint definitions -->
<div class="p-2 sm:p-2 md:p-4 lg:p-4 xl:p-6">
  <div class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2">
</div>
vue
<!-- Good: Mobile-first, minimal breakpoints -->
<div class="p-2 md:p-4 lg:p-6">
  <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-4">
</div>

<!-- Bad: Redundant breakpoint definitions -->
<div class="p-2 sm:p-2 md:p-4 lg:p-4 xl:p-6">
  <div class="grid grid-cols-1 sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2">
</div>

4.5 Dark Mode Efficiency

4.5 深色模式效率

javascript
// Good: Single dark mode strategy (JARVIS is always dark)
export default {
  darkMode: 'class',  // Use 'class' for explicit control
  theme: {
    extend: {
      colors: {
        jarvis: {
          bg: {
            dark: '#0a0a0f',  // Define dark colors directly
            panel: '#111827'
          }
        }
      }
    }
  }
}

// Bad: Light/dark variants when app is always dark
<div class="bg-white dark:bg-gray-900">  // Unnecessary light styles
javascript
// Good: Single dark mode strategy (JARVIS is always dark)
export default {
  darkMode: 'class',  // Use 'class' for explicit control
  theme: {
    extend: {
      colors: {
        jarvis: {
          bg: {
            dark: '#0a0a0f',  // Define dark colors directly
            panel: '#111827'
          }
        }
      }
    }
  }
}

// Bad: Light/dark variants when app is always dark
<div class="bg-white dark:bg-gray-900">  // Unnecessary light styles

4.6 Animation Performance

4.6 动画性能

javascript
// Good: GPU-accelerated properties
export default {
  theme: {
    extend: {
      keyframes: {
        glow: {
          '0%, 100%': { opacity: '0.5' },  // opacity is GPU-accelerated
          '50%': { opacity: '1' }
        }
      }
    }
  }
}

// Bad: Layout-triggering properties
keyframes: {
  resize: {
    '0%': { width: '100px' },  // Triggers layout recalc
    '100%': { width: '200px' }
  }
}
javascript
// Good: GPU-accelerated properties
export default {
  theme: {
    extend: {
      keyframes: {
        glow: {
          '0%, 100%': { opacity: '0.5' },  // opacity is GPU-accelerated
          '50%': { opacity: '1' }
        }
      }
    }
  }
}

// Bad: Layout-triggering properties
keyframes: {
  resize: {
    '0%': { width: '100px' },  // Triggers layout recalc
    '100%': { width: '200px' }
  }
}

5. Technology Stack & Versions

5. 技术栈与版本

5.1 Recommended Versions

5.1 推荐版本

PackageVersionNotes
tailwindcss^3.4.0Latest with JIT mode
@nuxtjs/tailwindcss^6.0.0Nuxt integration
tailwindcss-animate^1.0.0Animation utilities
版本说明
tailwindcss^3.4.0最新版本,支持JIT模式
@nuxtjs/tailwindcss^6.0.0Nuxt集成插件
tailwindcss-animate^1.0.0动画工具类

5.2 Configuration

5.2 配置示例

javascript
// tailwind.config.js
export default {
  content: [
    './components/**/*.{vue,js,ts}',
    './layouts/**/*.vue',
    './pages/**/*.vue',
    './composables/**/*.ts',
    './plugins/**/*.ts'
  ],
  darkMode: 'class',
  theme: {
    extend: {
      colors: {
        jarvis: {
          primary: '#00ff41',
          secondary: '#0891b2',
          warning: '#f59e0b',
          danger: '#ef4444',
          bg: {
            dark: '#0a0a0f',
            panel: '#111827'
          }
        }
      },
      fontFamily: {
        mono: ['JetBrains Mono', 'monospace'],
        display: ['Orbitron', 'sans-serif']
      },
      animation: {
        'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
        'scan': 'scan 2s linear infinite',
        'glow': 'glow 2s ease-in-out infinite alternate'
      },
      keyframes: {
        scan: {
          '0%': { transform: 'translateY(-100%)' },
          '100%': { transform: 'translateY(100%)' }
        },
        glow: {
          '0%': { boxShadow: '0 0 5px #00ff41' },
          '100%': { boxShadow: '0 0 20px #00ff41' }
        }
      }
    }
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('tailwindcss-animate')
  ]
}
javascript
// tailwind.config.js
export default {
  content: [
    './components/**/*.{vue,js,ts}',
    './layouts/**/*.vue',
    './pages/**/*.vue',
    './composables/**/*.ts',
    './plugins/**/*.ts'
  ],
  darkMode: 'class',
  theme: {
    extend: {
      colors: {
        jarvis: {
          primary: '#00ff41',
          secondary: '#0891b2',
          warning: '#f59e0b',
          danger: '#ef4444',
          bg: {
            dark: '#0a0a0f',
            panel: '#111827'
          }
        }
      },
      fontFamily: {
        mono: ['JetBrains Mono', 'monospace'],
        display: ['Orbitron', 'sans-serif']
      },
      animation: {
        'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
        'scan': 'scan 2s linear infinite',
        'glow': 'glow 2s ease-in-out infinite alternate'
      },
      keyframes: {
        scan: {
          '0%': { transform: 'translateY(-100%)' },
          '100%': { transform: 'translateY(100%)' }
        },
        glow: {
          '0%': { boxShadow: '0 0 5px #00ff41' },
          '100%': { boxShadow: '0 0 20px #00ff41' }
        }
      }
    }
  },
  plugins: [
    require('@tailwindcss/forms'),
    require('tailwindcss-animate')
  ]
}

6. Implementation Patterns

6. 实现模式

6.1 HUD Panel Component

6.1 HUD面板组件

vue
<template>
  <div class="
    relative
    bg-jarvis-bg-panel/80
    border border-jarvis-primary/30
    rounded-lg
    p-4
    backdrop-blur-sm
    shadow-lg shadow-jarvis-primary/10
  ">
    <!-- Scanline overlay -->
    <div class="
      absolute inset-0
      bg-gradient-to-b from-transparent via-jarvis-primary/5 to-transparent
      animate-scan
      pointer-events-none
    " />

    <!-- Content -->
    <div class="relative z-10">
      <h3 class="
        font-display
        text-jarvis-primary
        text-lg
        uppercase
        tracking-wider
        mb-2
      ">
        {{ title }}
      </h3>
      <slot />
    </div>
  </div>
</template>
vue
<template>
  <div class="
    relative
    bg-jarvis-bg-panel/80
    border border-jarvis-primary/30
    rounded-lg
    p-4
    backdrop-blur-sm
    shadow-lg shadow-jarvis-primary/10
  ">
    <!-- Scanline overlay -->
    <div class="
      absolute inset-0
      bg-gradient-to-b from-transparent via-jarvis-primary/5 to-transparent
      animate-scan
      pointer-events-none
    " />

    <!-- Content -->
    <div class="relative z-10">
      <h3 class="
        font-display
        text-jarvis-primary
        text-lg
        uppercase
        tracking-wider
        mb-2
      ">
        {{ title }}
      </h3>
      <slot />
    </div>
  </div>
</template>

6.2 Status Indicator

6.2 状态指示器

vue
<template>
  <div class="flex items-center gap-2">
    <span :class="[
      'w-2 h-2 rounded-full',
      {
        'bg-jarvis-primary animate-pulse': status === 'active',
        'bg-jarvis-warning': status === 'warning',
        'bg-jarvis-danger animate-ping': status === 'error',
        'bg-gray-500': status === 'inactive'
      }
    ]" />
    <span class="text-sm text-gray-300">{{ label }}</span>
  </div>
</template>
vue
<template>
  <div class="flex items-center gap-2">
    <span :class="[
      'w-2 h-2 rounded-full',
      {
        'bg-jarvis-primary animate-pulse': status === 'active',
        'bg-jarvis-warning': status === 'warning',
        'bg-jarvis-danger animate-ping': status === 'error',
        'bg-gray-500': status === 'inactive'
      }
    ]" />
    <span class="text-sm text-gray-300">{{ label }}</span>
  </div>
</template>

6.3 Button Variants

6.3 按钮变体

vue
<template>
  <button :class="[
    'px-4 py-2 rounded font-medium transition-all duration-200',
    'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-jarvis-bg-dark',
    {
      'bg-jarvis-primary text-black hover:bg-jarvis-primary/90 focus:ring-jarvis-primary':
        variant === 'primary',
      'bg-transparent border border-jarvis-secondary text-jarvis-secondary hover:bg-jarvis-secondary/10 focus:ring-jarvis-secondary':
        variant === 'secondary',
      'bg-jarvis-danger text-white hover:bg-jarvis-danger/90 focus:ring-jarvis-danger':
        variant === 'danger'
    }
  ]">
    <slot />
  </button>
</template>
vue
<template>
  <button :class="[
    'px-4 py-2 rounded font-medium transition-all duration-200',
    'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-jarvis-bg-dark',
    {
      'bg-jarvis-primary text-black hover:bg-jarvis-primary/90 focus:ring-jarvis-primary':
        variant === 'primary',
      'bg-transparent border border-jarvis-secondary text-jarvis-secondary hover:bg-jarvis-secondary/10 focus:ring-jarvis-secondary':
        variant === 'secondary',
      'bg-jarvis-danger text-white hover:bg-jarvis-danger/90 focus:ring-jarvis-danger':
        variant === 'danger'
    }
  ]">
    <slot />
  </button>
</template>

7. Quality Standards

7. 质量标准

7.1 Accessibility

7.1 可访问性

vue
<!-- Good - Sufficient contrast -->
<span class="text-jarvis-primary"><!-- #00ff41 on dark bg --></span>

<!-- Good - Focus visible -->
<button class="focus:ring-2 focus:ring-jarvis-primary focus:outline-none">

<!-- Good - Screen reader text -->
<span class="sr-only">Status: Active</span>
vue
<!-- Good - Sufficient contrast -->
<span class="text-jarvis-primary"><!-- #00ff41 on dark bg --></span>

<!-- Good - Focus visible -->
<button class="focus:ring-2 focus:ring-jarvis-primary focus:outline-none">

<!-- Good - Screen reader text -->
<span class="sr-only">Status: Active</span>

8. Common Mistakes & Anti-Patterns

8. 常见错误与反模式

8.1 Anti-Patterns

8.1 反模式

Avoid: Excessive Custom CSS

避免:过度自定义CSS

vue
<!-- Bad - Custom CSS when utilities exist -->
<style>
.custom-panel {
  padding: 1rem;
  border-radius: 0.5rem;
}
</style>

<!-- Good - Use utilities -->
<div class="p-4 rounded-lg">
vue
<!-- Bad - Custom CSS when utilities exist -->
<style>
.custom-panel {
  padding: 1rem;
  border-radius: 0.5rem;
}
</style>

<!-- Good - Use utilities -->
<div class="p-4 rounded-lg">

Avoid: Inconsistent Spacing

避免:不一致的间距

vue
<!-- Bad - Mixed spacing values -->
<div class="p-3 mt-5 mb-2">

<!-- Good - Consistent scale -->
<div class="p-4 my-4">
vue
<!-- Bad - Mixed spacing values -->
<div class="p-3 mt-5 mb-2">

<!-- Good - Consistent scale -->
<div class="p-4 my-4">

Avoid: Hardcoded Colors

避免:硬编码颜色

vue
<!-- Bad - Hardcoded hex -->
<div class="text-[#00ff41]">

<!-- Good - Theme color -->
<div class="text-jarvis-primary">
vue
<!-- Bad - Hardcoded hex -->
<div class="text-[#00ff41]">

<!-- Good - Theme color -->
<div class="text-jarvis-primary">

9. Pre-Implementation Checklist

9. 实施前检查清单

Phase 1: Before Writing Code

阶段1:编写代码前

  • Write component tests for expected class applications
  • Verify JARVIS theme colors are defined in config
  • Check content paths include all source files
  • Review existing components for reusable patterns
  • 编写组件测试,验证预期类的应用
  • 确认JARVIS主题颜色已在配置中定义
  • 检查内容路径包含所有源文件
  • 查看现有组件,寻找可复用模式

Phase 2: During Implementation

阶段2:实现过程中

  • Use utilities before custom CSS
  • Apply consistent spacing scale (4, 8, 12, 16...)
  • Include focus states for all interactive elements
  • Test responsive breakpoints at each size
  • Use theme colors, never hardcoded hex values
  • 优先使用工具类,再考虑自定义CSS
  • 应用一致的间距比例(4、8、12、16...)
  • 为所有交互元素添加焦点状态
  • 在每个尺寸下测试响应式断点
  • 使用主题颜色,绝不硬编码十六进制值

Phase 3: Before Committing

阶段3:提交前

  • All component tests pass:
    npm test
  • Build completes without CSS errors:
    npm run build
  • Check CSS bundle size hasn't grown unexpectedly
  • Verify no unused @apply extractions
  • Test accessibility with keyboard navigation
  • 所有组件测试通过:
    npm test
  • 构建完成,无CSS错误:
    npm run build
  • 检查CSS包大小未出现异常增长
  • 验证无未使用的@apply提取
  • 通过键盘导航测试可访问性

10. Summary

10. 总结

Tailwind CSS provides utility-first styling for JARVIS:
  1. TDD: Write tests for class applications before implementation
  2. Performance: Optimize content paths and use JIT mode
  3. Theme: Define JARVIS colors and fonts in config
  4. Utilities: Compose styles from utilities, extract patterns with @apply
  5. Accessibility: Maintain focus states and sufficient contrast
Remember: The JARVIS HUD has a distinct visual identity - maintain consistency with the theme configuration and test all styling with vitest.

References:
  • references/advanced-patterns.md
    - Complex layout patterns
Tailwind CSS为JARVIS提供实用优先的样式方案:
  1. TDD:在实现前编写类应用的测试
  2. 性能:优化内容路径,使用JIT模式
  3. 主题:在配置中定义JARVIS颜色与字体
  4. 工具类:通过工具类组合样式,用@apply提取重复模式
  5. 可访问性:保持焦点状态与足够的对比度
注意:JARVIS HUD具有独特的视觉标识 - 需与主题配置保持一致,并使用vitest测试所有样式。

参考:
  • references/advanced-patterns.md
    - 复杂布局模式