---
description: Tailwind CSS and theme token standards for Liquid and theme styles. Static classes only, semantic tokens from _styles/02_base/02.02_colors.css, content sources in _styles/main.css.
globs:
  - "**/*.liquid"
  - "_styles/**/*.css"
alwaysApply: false
---
# Tailwind CSS Development Rules

Apply when editing Liquid templates or theme CSS that use Tailwind classes or theme tokens. Use semantic tokens (surface, subtle, emphasis, accent, text-primary, border-secondary) from this project's `@theme`; see `_styles/02_base/02.02_colors.css`.

> **Source vs build output:** Edit CSS in `_styles/` (entrypoint `_styles/main.css`). The CLI compiles it into `assets/style.css` on every save and in CI, so `assets/style.css` is a **generated artifact** — never edit it directly, your changes will be overwritten. See `project-overview.mdc` (Build Outputs vs Source).

## Core Principles

### 1. Static Class Generation
**CRITICAL**: Never combine Tailwind classes with Liquid variables or dynamic values.

**Why this matters:**
- Tailwind CSS scans unparsed files during build time to generate CSS
- Liquid parsing happens on Shopify servers, not during local builds
- Tailwind cannot see the final rendered HTML with dynamic values
- This means dynamic classes like `duration-{{ animation_duration }}` will NOT work

**❌ Bad Examples:**
```liquid
<!-- These will NOT work - Tailwind can't see the dynamic values -->
<div class="duration-{{ animation_duration }}">
<div class="w-{{ width }}">
<div class="text-{{ color }}">
<div class="bg-{{ background_color }}">
```

**✅ Good Examples:**
```liquid
<!-- Use static Tailwind classes -->
<div class="duration-300">
<div class="w-full">
<div class="text-blue-600">
<div class="bg-gray-100">

<!-- Or use conditional classes -->
<div class="{% if show_animation %}duration-300{% else %}duration-0{% endif %}">
<div class="{% if size == 'sm' %}w-1/2{% else %}w-full{% endif %}">
```

### 2. Conditional Class Application
Use conditional statements to apply different static classes:

```liquid
<!-- ✅ Good: Conditional static classes -->
<div class="{% if expanded %}bg-blue-100{% else %}bg-gray-50{% endif %}">
<div class="{% if size == 'sm' %}text-sm{% else %}text-base{% endif %}">
<div class="{% if show_animation %}transition-all duration-300{% else %}transition-none{% endif %}">
```

### 3. Custom CSS for Dynamic Values
For truly dynamic values, use custom CSS classes:

```liquid
<!-- ✅ Good: Custom CSS for dynamic values -->
<style>
  .duration-custom { transition-duration: var(--custom-duration); }
  .width-custom { width: var(--custom-width); }
</style>

<div class="duration-custom" style="--custom-duration: {{ animation_duration }}ms">
<div class="width-custom" style="--custom-width: {{ width }}%">
```

## Class Organization

### 1. Logical Grouping
Group related classes together in a logical order:

```liquid
<!-- ✅ Good: Logical grouping -->
<div class="
  flex items-center justify-between
  p-4 m-2
  bg-white border border-gray-200 rounded-lg
  hover:bg-gray-50 focus:ring-2 focus:ring-blue-500
  transition-colors duration-200
">
```

### 2. Responsive Design
Use responsive prefixes consistently:

```liquid
<!-- ✅ Good: Responsive design -->
<div class="
  w-full md:w-1/2 lg:w-1/3
  text-sm md:text-base lg:text-lg
  p-2 md:p-4 lg:p-6
">
```

### 3. State Classes
Group state-based classes together:

```liquid
<!-- ✅ Good: State classes grouped -->
<button class="
  px-4 py-2 rounded
  bg-blue-600 text-white
  hover:bg-blue-700 focus:bg-blue-700
  focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2
  disabled:opacity-50 disabled:cursor-not-allowed
  transition-colors duration-200
">
```

## Performance Best Practices

### 1. Content Source Configuration
Tailwind v4 content sources are in `_styles/main.css`. All template and asset paths are scanned for class names:

```css
/* _styles/main.css */
@import "tailwindcss" source(none);
@plugin "@tailwindcss/typography";
@source "../assets/*.js";
@source "../assets/!(style).css";
@source "../layout/*.liquid";
@source "../blocks/*.liquid";
@source "../sections/*.liquid";
@source "../snippets/*.liquid";
@source "../templates/*.liquid";
```

Token imports: `01_theme/01_primitives.css`, `02_base/02.01_sizes.css`, `02_base/02.02_colors.css`, `02_base/02.03_typography.css`. Any file that uses Tailwind classes must be covered by these `@source` paths so classes are not purged.

### 2. Avoid Arbitrary Values
Prefer predefined Tailwind classes over arbitrary values:

```liquid
<!-- ❌ Bad: Arbitrary values -->
<div class="w-[123px] h-[456px]">

<!-- ✅ Good: Predefined classes -->
<div class="w-32 h-40">
```

### 3. Use CSS Custom Properties
For dynamic values, use CSS custom properties defined in `_styles/main.css` and imported token files (`01_primitives.css`, `02.02_colors.css`, etc.).

## Color System (Theme Tokens)

### 1. Primitives and semantic tokens
- **Primitives**: `_styles/01_theme/01_primitives.css` — raw colors (e.g. `--color-dune-50`, `--color-abbey-950`).
- **Semantic tokens**: `_styles/02_base/02.02_colors.css` — background, text, border tokens used by Tailwind utilities.

### 2. Semantic token names (this project)
Background: `--background-color-surface`, `--background-color-subtle`, `--background-color-emphasis`, `--background-color-accent`.  
Text: `--text-color-primary`, `--text-color-secondary`, `--text-color-on-accent`, `--text-color-on-accent-sec`.  
Border: `--border-color-primary`, `--border-color-secondary`, `--border-color-on-accent`, `--border-color-on-accent-sec`.

Tailwind generates classes from these (e.g. `bg-surface`, `bg-subtle`, `text-primary`, `text-on-accent`, `border-primary`, `border-secondary`). Gradients: `--background-image-gradient-surface`, `-subtle`, `-emphasis`, `-contrast`.

### 3. Using theme colors in Liquid
Prefer semantic utility classes; use arbitrary values only when no token exists:

```liquid
<!-- Prefer: semantic classes from @theme -->
<div class="bg-surface text-primary border border-secondary">
<div class="bg-subtle text-secondary">
<div class="bg-accent text-on-accent">
<div class="border-primary">

<!-- Optional: arbitrary value from a token -->
<div class="bg-[hsl(var(--background-color-emphasis))]">
```

### 4. Color schemas (@utility)
Sections can switch palette via `@utility` classes: `color-schema-primary`, `color-schema-secondary`, `color-schema-muted`, `color-schema-accent-1`, `color-schema-accent-2`, `color-schema-accent-3`, `color-schema-contrast`. Apply to a wrapper (e.g. section root) so children inherit semantic tokens. See `_styles/02_base/02.02_colors.css`.

## Design-Focused Accessibility

### 1. Contextual Focus States
Use design-appropriate focus indicators instead of generic rings:

```liquid
<!-- ✅ Good: Input with border focus -->
<input class="
  border border-secondary
  focus:border-primary focus:outline-none
  transition-colors duration-200
">

<!-- ✅ Good: Summary with background focus -->
<summary class="
  bg-white hover:bg-emphasis
  focus:bg-emphasis focus:outline-none
  transition-colors duration-200
">

<!-- ✅ Good: Button with ring focus (appropriate for buttons) -->
<button class="
  bg-subtle text-on-accent
  hover:bg-subtle/90
  focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2
  transition-colors duration-200
">
```

### 2. Focus State Guidelines
Choose focus indicators based on component context:

- **Inputs/Form Fields**: Use `focus:border-primary` when parent has `border-secondary`
- **Summary Elements**: Use `focus:bg-emphasis` for subtle background change
- **Buttons**: Use `focus:ring-2 focus:ring-primary` for clear button focus
- **Links**: Use `focus:underline` or `focus:text-primary` for text-based focus
- **Cards/Containers**: Use `focus:border-primary` or `focus:shadow-lg`

### 3. Reduced Motion
Respect user preferences using the theme's custom properties:

```css
/* _styles/main.css */
@media (prefers-reduced-motion: reduce) {
  .transition-all {
    transition: none !important;
  }
}
```

### 4. High Contrast
Support high contrast mode:

```css
/* _styles/main.css */
@media (prefers-contrast: high) {
  .border-gray-200 {
    border-color: #000000 !important;
  }
}
```

## Component Patterns

### 1. Atomic Components
Use consistent patterns for atomic components:

```liquid
<!-- Button component pattern -->
<button class="
  inline-flex items-center justify-center
  px-4 py-2 rounded-md
  text-sm font-medium
  bg-subtle text-on-accent
  hover:bg-subtle/90 focus:bg-subtle/90
  focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2
  disabled:opacity-50 disabled:cursor-not-allowed
  transition-colors duration-200
  {{ class }}
">
  {{ content }}
</button>
```

### 2. Layout Components
Use consistent spacing and layout patterns:

```liquid
<!-- Container pattern -->
<div class="
  max-w-7xl mx-auto px-4 sm:px-6 lg:px-8
  {{ class }}
">
  {{ content }}
</div>
```

### 3. Form Components
Use consistent form styling:

```liquid
<!-- Input pattern -->
<input class="
  block w-full rounded-md
  border border-secondary
  focus:border-primary focus:outline-none
  disabled:bg-emphasis disabled:cursor-not-allowed
  transition-colors duration-200
  {{ class }}
">
```

## Common Patterns

### 1. Card Components
```liquid
<div class="
  bg-subtle border border-secondary rounded-lg shadow-sm
  hover:shadow-md transition-shadow duration-200
  {{ class }}
">
  {{ content }}
</div>
```

### 2. Navigation Items
```liquid
<a class="
  block px-3 py-2 rounded-md text-sm font-medium
  text-secondary hover:text-primary hover:bg-emphasis
  focus:outline-none focus:bg-emphasis
  transition-colors duration-200
  {{ class }}
">
  {{ content }}
</a>
```

### 3. Status Indicators
```liquid
<span class="
  inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium
  {{ status == 'success' ? 'bg-green-100 text-green-800' : '' }}
  {{ status == 'error' ? 'bg-red-100 text-red-800' : '' }}
  {{ status == 'warning' ? 'bg-yellow-100 text-yellow-800' : '' }}
  {{ status == 'info' ? 'bg-blue-100 text-blue-800' : '' }}
">
  {{ content }}
</span>
```

## Debugging Tips

### 1. Class Verification
Use browser dev tools to verify classes are applied correctly:

```javascript
// Check if classes are present
console.log(element.className);
```

### 2. Purge Verification
Ensure classes aren't being purged by checking the content sources in `_styles/main.css`:

```bash
# Check what classes are being purged
npx tailwindcss --content ./**/*.liquid --output ./temp.css
```

### 3. Dynamic Class Debugging
For conditional classes, add debugging:

```liquid
<!-- Debug conditional classes -->
<div class="
  {% if debug %}border-2 border-red-500{% endif %}
  {{ conditional_classes }}
">
  <!-- Add debug output -->
  {% if debug %}
    <div class="text-xs text-gray-500">
      Applied classes: {{ conditional_classes }}
    </div>
  {% endif %}
</div>
```

## Theme Integration

### 1. Tokens and custom properties
Use semantic classes (e.g. `bg-surface`, `text-primary`) so styles stay within the token system. For one-off values, use theme variables from `_styles/01_theme/01_primitives.css` and `_styles/02_base/02.02_colors.css`. Typography and sizes: `_styles/02_base/02.01_sizes.css`, `02.03_typography.css`.

### 2. Responsive breakpoints
Use Tailwind breakpoints (e.g. `md:`, `lg:`) consistently; theme may define `--breakpoint-*` in `@theme`.

### 3. Custom utilities
Add custom utilities in `_styles/` (e.g. in a layer file imported by `main.css`):

```css
/* _styles/main.css */
@layer utilities {
  .text-balance {
    text-wrap: balance;
  }
  
  .hide-scroll-bar {
    -ms-overflow-style: none;
    scrollbar-width: none;
  }
  
  .hide-scroll-bar::-webkit-scrollbar {
    display: none;
  }
}
```

## Compliance Checklist

Before committing any Tailwind CSS changes, ensure:

- [ ] No dynamic Tailwind classes with Liquid variables
- [ ] All conditional classes use static Tailwind values
- [ ] Contextual focus states used (not generic rings everywhere)
- [ ] Responsive design implemented correctly
- [ ] Performance optimizations applied
- [ ] Design-appropriate accessibility considerations addressed
- [ ] Classes are logically grouped and organized
- [ ] Custom CSS used for truly dynamic values
- [ ] Content sources in `_styles/main.css` include all template files
- [ ] No arbitrary values unless absolutely necessary
- [ ] Theme custom properties used when appropriate
- [ ] Custom utilities added to `_styles/main.css` when needed
- [ ] Semantic tokens used (surface, subtle, emphasis, accent, text-primary, border-secondary) from `_styles/02_base/02.02_colors.css`
- [ ] Focus states match component context and design
