skills/css-in-js-architect/SKILL.md
Architect scalable styling systems with Tailwind v4, CSS Modules, design tokens, dynamic theming, and container queries. Activate on: design tokens, theming system, Tailwind config, CSS architecture, container queries, dark mode. NOT for: component library creation (use design-system-creator), animation systems (use animation-system-architect).
npx skillsauth add curiositech/windags-skills css-in-js-architectInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build scalable, maintainable styling architectures with Tailwind v4, CSS Modules, design tokens, and modern CSS features like container queries and dynamic theming.
IF you need global utility classes + rapid prototyping:
@theme directiveIF you need component-scoped styles + CSS expertise:
IF you have mixed requirements:
Is this a multi-brand/white-label app?
├── YES → CSS custom properties with theme switching
│ ├── Static themes known at build? → @theme overrides
│ └── Dynamic themes from API? → Runtime CSS property updates
└── NO → Single theme
├── Need dark mode? → CSS custom properties with prefers-color-scheme
└── Single theme only → Hardcoded values in @theme acceptable
IF component layout depends on its container size:
@container queries with container-type: inline-sizeIF layout depends on device/viewport characteristics:
Symptoms: White flash before dark theme loads, theme "jumps" on page load Detection Rule: If you see a brief light background before dark mode applies, you have FOUC Diagnosis: Theme detection/application happens after initial render Fix:
<script>
// Inline script in <head> - runs before render
const theme = localStorage.getItem('theme') || 'system';
if (theme === 'dark' || (theme === 'system' && matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.setAttribute('data-theme', 'dark');
}
</script>
Symptoms: Some components don't respect theme changes, inconsistent colors across components
Detection Rule: If getComputedStyle shows different token values in different components, you have cascade issues
Diagnosis: CSS specificity or custom property inheritance broken
Fix: Ensure tokens defined at :root level, avoid overriding custom properties in component scopes
Symptoms: Console warnings about hydration mismatches, flickering on client-side hydration
Detection Rule: If React dev tools shows hydration warnings with theme-dependent content, you have mismatches
Diagnosis: Server renders default theme, client renders user's saved theme
Fix: Use suppressHydrationWarning on theme-dependent elements or defer theme application until after hydration
Symptoms: Container queries not triggering, unexpected breakpoint behavior
Detection Rule: If container queries work in isolation but fail when nested, you have cascade issues
Diagnosis: Missing container-type or conflicting container contexts
Fix: Explicitly set container-type: inline-size on every container query parent
Symptoms: Large CSS bundles, unused Tailwind utilities in production Detection Rule: If bundle analysis shows >100KB CSS or unused class warnings, you have bloat Diagnosis: Missing or incorrect PurgeCSS/content configuration Fix: Configure Tailwind v4 content detection properly, use CSS Modules for one-off styles
Scenario: E-commerce app needs light/dark modes with brand customization
Step 1: Define token structure
/* tokens.css */
:root {
/* Brand tokens - consistent across themes */
--brand-primary: oklch(0.55 0.18 250);
--brand-secondary: oklch(0.45 0.12 180);
/* Semantic tokens - theme-dependent */
--surface-primary: oklch(0.99 0 0);
--surface-raised: oklch(0.96 0 0);
--text-primary: oklch(0.15 0 0);
--text-secondary: oklch(0.40 0 0);
--border-subtle: oklch(0.88 0 0);
}
[data-theme='dark'] {
--surface-primary: oklch(0.13 0.01 260);
--surface-raised: oklch(0.18 0.01 260);
--text-primary: oklch(0.93 0 0);
--text-secondary: oklch(0.70 0 0);
--border-subtle: oklch(0.25 0.01 260);
}
Decision Point Hit: Need both utilities and component styles Expert Catches: Using OKLCH for perceptual uniformity, semantic naming separates brand from surface colors Novice Misses: Would use RGB/hex values, mix semantic and brand tokens
Step 2: Configure Tailwind v4
/* app.css */
@import 'tailwindcss';
@theme {
--color-surface-primary: var(--surface-primary);
--color-surface-raised: var(--surface-raised);
--color-text-primary: var(--text-primary);
--color-text-secondary: var(--text-secondary);
--color-brand-primary: var(--brand-primary);
}
Decision Point Hit: Utility classes for layout, CSS Modules for complex styling Expert Catches: Referencing CSS custom properties in @theme, maintaining single source of truth Novice Misses: Would duplicate token values in @theme instead of referencing
Step 3: Component implementation
// ProductCard.tsx
import styles from './ProductCard.module.css';
export function ProductCard({ product }) {
return (
<article className={styles.container}>
<div className="bg-surface-raised p-4 rounded-lg border border-border-subtle">
<img className={styles.image} src={product.image} />
<div className="space-y-2">
<h3 className="text-text-primary font-semibold">{product.name}</h3>
<p className="text-text-secondary">{product.description}</p>
<button className="bg-brand-primary text-white px-4 py-2 rounded">
Add to Cart
</button>
</div>
</div>
</article>
);
}
Result: Theme switching works instantly, no runtime CSS generation, fully responsive with container queries
prefers-color-scheme when no explicit preference setDo NOT use this skill for:
design-system-creator instead (handles API design, versioning, documentation)animation-system-architect instead (motion design, performance optimization)responsive-layout-master instead (complex grid arrangements, breakpoint strategy)Delegate to other skills when:
design-system-creatoranimation-system-architectresponsive-layout-masterdata-ai
license: Apache-2.0 NOT for unrelated tasks outside this domain.
development
Use when designing caching strategies (cache-aside, write-through, write-behind), implementing distributed locks, building rate limiters, leaderboards, real-time streams (XADD/consumer groups), pub/sub, or tuning eviction policies. Triggers: thundering-herd on cache miss, dogpile on key expiry, Redlock vs SET-NX-PX choice, sliding-window rate limiter, hot-key on a single cluster slot, big-key blowup, MULTI/EXEC across slots, KEYS in production. NOT for Redis Cluster operations/admin (different domain), embedded KV (SQLite, leveldb), in-process LRU caches, or Memcached.
tools
Drawing the `'use client'` boundary correctly in React Server Components apps (Next.js App Router, RSC frameworks) — leaf-pushing, slot composition, serialization rules, and environment poisoning prevention. Grounded in react.dev and Next.js 16 docs.
development
Use when designing rate limiting for an API, choosing between token bucket / sliding window / leaky bucket / fixed window, implementing it in Redis, deciding edge (Cloudflare/Upstash) vs origin enforcement, sizing per-user vs per-IP vs per-endpoint quotas, returning the right 429 response with Retry-After, or fixing the boundary-burst bug in fixed-window limiters. Triggers: 429 too many requests, INCR + EXPIRE, ZADD + ZREMRANGEBYSCORE + ZCARD, X-RateLimit-Remaining header, Cloudflare WAF rate limiting rules, Upstash @upstash/ratelimit, leaky bucket shaping vs policing, distributed rate limiter consistency. NOT for DDoS mitigation specifically (different scale), CAPTCHA / bot management, full WAF design, or per-user quota billing.