with one click
css-modules
Implements scoped CSS using CSS Modules with automatic class name generation, composition, and TypeScript support. Use when needing component-scoped styles, avoiding naming collisions, or migrating from global CSS.
Menu
Implements scoped CSS using CSS Modules with automatic class name generation, composition, and TypeScript support. Use when needing component-scoped styles, avoiding naming collisions, or migrating from global CSS.
Writes, edits, and creates dbt models following best practices. Use when user needs to create new dbt SQL models, update existing models, or convert raw SQL to dbt format. Handles staging, intermediate, and mart models with proper config blocks, CTEs, and documentation.
Apply Domain-Driven Design, Clean Architecture, CQRS, and command/query patterns to code reviews and feature design. Use when analyzing or designing code in Application, Service, Infrastructure, DataAccess, Validation, Domain, or Functions projects, or when addressing architectural concerns, layering, mapping, entities, value objects, repositories, or validators in the Rome Repair Order Service.
Analyzes and refactors code using Domain-Driven Design principles. Use when refactoring domain models, identifying DDD anti-patterns, improving domain clarity, or applying tactical/strategic DDD patterns.
Guide for DDD strategic design - analyzing domains through structured questioning, conducting stakeholder interviews (PM/domain experts/users), and producing Bounded Context analysis, Context Maps, and Ubiquitous Language. Use when user needs help understanding domain boundaries, planning domain interviews, or structuring DDD strategic artifacts.
Win competitive rounds: run a clean process, deliver value previews before asking, coordinate partners, and manage timelines. Use when you're trying to close a 'must win' deal against other funds.
End-to-end associate workflow with time-boxed gates: thesis -> sourcing -> meetings -> diligence -> memo, ending with either IC-ready memo or explicit kill decision. Use when you need to run the full pipeline for a sector or a specific deal.
| name | css-modules |
| description | Implements scoped CSS using CSS Modules with automatic class name generation, composition, and TypeScript support. Use when needing component-scoped styles, avoiding naming collisions, or migrating from global CSS. |
Locally scoped CSS by generating unique class names at build time.
CSS Modules work out of the box in Vite, Next.js, and Create React App.
Create module file:
/* Button.module.css */
.button {
padding: 12px 24px;
border-radius: 8px;
border: none;
cursor: pointer;
}
.primary {
background: #3b82f6;
color: white;
}
.secondary {
background: #e5e7eb;
color: #1f2937;
}
Import and use:
// Button.tsx
import styles from './Button.module.css';
interface ButtonProps {
variant?: 'primary' | 'secondary';
children: React.ReactNode;
}
export function Button({ variant = 'primary', children }: ButtonProps) {
return (
<button className={`${styles.button} ${styles[variant]}`}>
{children}
</button>
);
}
ComponentName.module.css # Component styles
page.module.css # Page styles
layout.module.css # Layout styles
Files without .module.css are treated as global CSS.
import styles from './Component.module.css';
// Single class
<div className={styles.container} />
// Multiple classes
<div className={`${styles.card} ${styles.elevated}`} />
// Conditional classes
<div className={`${styles.button} ${isActive ? styles.active : ''}`} />
// Dynamic class from variable
const variant = 'primary';
<div className={styles[variant]} />
// With clsx/classnames library
import clsx from 'clsx';
<div className={clsx(styles.button, {
[styles.active]: isActive,
[styles.disabled]: isDisabled,
})} />
CSS class names become JavaScript property names:
/* Valid patterns */
.button { } /* styles.button */
.primaryButton { } /* styles.primaryButton */
.primary-button { } /* styles['primary-button'] or styles.primaryButton (with camelCase) */
.Button { } /* styles.Button */
/* Avoid - invalid JS identifiers */
.123start { } /* Won't work */
.my class { } /* Won't work */
/* base.module.css */
.base {
padding: 16px;
border-radius: 8px;
font-family: system-ui;
}
.card {
composes: base;
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.panel {
composes: base;
background: #f3f4f6;
border: 1px solid #e5e7eb;
}
/* typography.module.css */
.heading {
font-weight: 700;
line-height: 1.2;
}
.body {
font-weight: 400;
line-height: 1.6;
}
/* Card.module.css */
.title {
composes: heading from './typography.module.css';
font-size: 1.5rem;
margin-bottom: 8px;
}
.description {
composes: body from './typography.module.css';
color: #6b7280;
}
.special {
composes: base highlight from './shared.module.css';
composes: bordered from './borders.module.css';
}
.button {
/* Compose from global CSS (like a reset or utility) */
composes: reset-button from global;
padding: 12px 24px;
}
/* Within a module file */
:global(.body-locked) {
overflow: hidden;
}
/* Mixed local and global */
.modal :global(.overlay) {
background: rgba(0,0,0,0.5);
}
/* Global block */
:global {
.utility-class {
display: flex;
}
.another-utility {
gap: 16px;
}
}
:local(.className) {
/* Explicitly local (default behavior) */
}
With PostCSS nesting or native CSS nesting:
.card {
padding: 16px;
.header {
display: flex;
justify-content: space-between;
}
.body {
margin-top: 12px;
}
&:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
&.highlighted {
border: 2px solid #3b82f6;
}
}
// css-modules.d.ts (in src/ or types/)
declare module '*.module.css' {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module '*.module.scss' {
const classes: { readonly [key: string]: string };
export default classes;
}
Generate type definitions from CSS files:
npm install -D typed-css-modules
npx tcm src
Generates .css.d.ts files:
// Button.module.css.d.ts
declare const styles: {
readonly button: string;
readonly primary: string;
readonly secondary: string;
};
export default styles;
Watch mode:
npx tcm src --watch
Options:
# CamelCase class names
npx tcm src --camelCase
# Named exports (for tree shaking)
npx tcm src --namedExports
# TypeScript 5 arbitrary extensions
npx tcm src --allowArbitraryExtensions
IDE support without generating files:
// tsconfig.json
{
"compilerOptions": {
"plugins": [
{ "name": "typescript-plugin-css-modules" }
]
}
}
Works out of the box. Custom configuration:
// vite.config.ts
import { defineConfig } from 'vite';
export default defineConfig({
css: {
modules: {
// Generate scoped class names
generateScopedName: '[name]__[local]___[hash:base64:5]',
// Export class names as camelCase
localsConvention: 'camelCase',
},
},
});
Works out of the box. No configuration needed.
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.module\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]--[hash:base64:5]',
},
},
},
],
},
],
},
};
/* Alert.module.css */
.alert {
padding: 12px 16px;
border-radius: 6px;
display: flex;
align-items: center;
gap: 8px;
}
.info {
composes: alert;
background: #dbeafe;
color: #1e40af;
}
.success {
composes: alert;
background: #dcfce7;
color: #166534;
}
.warning {
composes: alert;
background: #fef3c7;
color: #92400e;
}
.error {
composes: alert;
background: #fee2e2;
color: #991b1b;
}
import styles from './Alert.module.css';
type AlertVariant = 'info' | 'success' | 'warning' | 'error';
interface AlertProps {
variant: AlertVariant;
children: React.ReactNode;
}
export function Alert({ variant, children }: AlertProps) {
return <div className={styles[variant]}>{children}</div>;
}
.container {
padding: 16px;
}
.grid {
display: grid;
grid-template-columns: 1fr;
gap: 16px;
}
@media (min-width: 768px) {
.container {
padding: 24px;
}
.grid {
grid-template-columns: repeat(2, 1fr);
gap: 24px;
}
}
@media (min-width: 1024px) {
.grid {
grid-template-columns: repeat(3, 1fr);
}
}
.card {
background: var(--card-bg, white);
color: var(--card-text, #1f2937);
border: 1px solid var(--card-border, #e5e7eb);
border-radius: var(--radius-md, 8px);
padding: var(--spacing-4, 16px);
}
/* Dark theme override via parent */
:global(.dark) .card {
--card-bg: #1f2937;
--card-text: #f9fafb;
--card-border: #374151;
}
composes.submitButton not .btn1| Mistake | Fix |
|---|---|
Missing .module.css extension | Rename to *.module.css |
| Accessing undefined class | Check spelling, add TypeScript |
| composes after other rules | Move composes to top of rule |
| Circular composition | Restructure dependencies |
| Styling by element | Use class selectors instead |