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-mastertools
Building resilient distributed systems with circuit breakers, retries with full-jitter exponential backoff, retry budgets (per-request 3-attempt + per-client 10% ratio per Google SRE), deadline propagation, and the cascading-failure math (4 layers × 3 retries = 64x amplification). Grounded in Resilience4j, Microsoft Cloud Patterns, AWS Architecture Blog (Marc Brooker), and Google SRE Book.
testing
Designing HTTP cache headers that work correctly across browsers, CDNs, and shared proxies — `Cache-Control` directives per RFC 9111, `stale-while-revalidate` and `stale-if-error` per RFC 5861, the Vary header for varying responses, and surrogate keys for tag-based purging. Grounded in IETF RFCs and Cloudflare/Fastly docs.
development
Use when designing or fixing a Content Security Policy on a real site, choosing between nonce-based and hash-based CSP, adding strict-dynamic, debugging "Refused to execute inline script" errors, deploying CSP in report-only mode first, configuring report-to / report-uri, or auditing an existing policy for unsafe-inline / unsafe-eval / wildcards. Triggers: "CSP blocks legitimate inline script", strict-dynamic, nonce-{RANDOM}, sha256-{HASH}, object-src none, base-uri none, frame-ancestors, Trusted Types, X-Content-Security-Policy obsolete, report-only vs enforced. NOT for general HTTP security headers (HSTS, COOP/COEP), Trusted Types deep dive, CORS configuration, or building a WAF.
tools
Choosing and operating an HTTP API versioning strategy that doesn't break clients — Stripe's date-based pinned versions, the Deprecation/Sunset header pair (RFC 9745 + RFC 8594), URI vs header vs media-type approaches, and the version-transformer pattern. Grounded in Stripe's published architecture and IETF RFCs.