Instatic Design Tokens and CSS Modules Conventions: A Complete Developer Guide
Instatic enforces a strict, token-driven styling system where every visual property is defined as a CSS custom property in src/styles/globals.css and referenced exclusively via CSS Modules, with automated tests blocking hard-coded values and Tailwind usage.
The CoreBunch/Instatic repository implements a rigorous design tokens and CSS modules conventions architecture to ensure visual consistency across its admin interface. Every color, spacing value, and typographic scale is abstracted into reusable CSS custom properties, while component styles are isolated through adjacent CSS Modules. This approach guarantees a themable, maintainable UI that prevents accidental style drift through automated enforcement.
Design Token Architecture in Instatic
Centralized Token Definitions in globals.css
All design tokens reside in src/styles/globals.css, serving as the single source of truth for the entire application. Adding a new token requires appending a --your-token definition to this file, which can then be accessed via var(--your-token) throughout the codebase. This centralization ensures that brand colors, spacing scales, and radius values remain synchronized across all admin components.
Token Categories and Naming Patterns
Instatic organizes tokens by functional purpose rather than arbitrary values. Color tokens follow semantic grouping—--bg-surface, --border-default, --text-bright, and --overlay-10—with opacity variants using numeric suffixes (e.g., --accent-1 and --accent-1-10 for 10% opacity). Radius tokens differentiate contexts explicitly: --editor-radius-sm, --editor-radius, --panel-radius, and --input-radius each serve specific UI regions. Spacing tokens range from --space-4xs to --space-12xl, while typography tokens span --text-xs through --text-xl.
Fluid Spacing and Typography Scales
Unlike static pixel values, Instatic's spacing and typography tokens use clamp() functions to create fluid, viewport-adaptive scales. This eliminates the need for media query breakpoints while maintaining readable proportions across device sizes. The fluid system applies consistently from --space-4xs (minimal gaps) to --space-12xl (major layout sections).
CSS Modules Conventions and File Organization
Adjacent Module Pattern
Components located in src/admin/, src/admin/pages/site/, and src/ui/ directories must co-locate styles using the [ComponentName].module.css naming convention. For example, src/ui/components/Button/Button.module.css contains all Button-specific styles, while src/ui/components/Card/Card.module.css houses card layouts. This adjacency pattern keeps styles discoverable and scoped to their respective components.
camelCase Class Naming
Class selectors within modules use camelCase (e.g., .primaryButton, .cardContainer) rather than kebab-case or BEM methodology. This convention aligns with JavaScript object property access patterns when importing style objects into React components. The CSS Modules build step automatically scopes these classes to prevent global namespace pollution.
Strict Enforcement: No Raw Values or Tailwind
Automated Token Policy Testing
The repository includes src/__tests__/architecture/css-token-policy.test.ts, which fails any build containing raw hex codes, rgb/hsl values, or pixel literals in CSS Modules. This architectural test enforces 100% token adoption—every visual value must reference a custom property via var(--*). Direct literals such as color: #ff0000 or margin: 16px trigger immediate test failures.
Tailwind Prohibition
Instatic explicitly forbids Tailwind CSS utilities and dependencies. The test suite includes noTailwindUtilities.test.ts and no-tailwind-deps.test.ts to prevent utility-class imports or Tailwind-related package dependencies. All styling must occur through CSS Modules referencing design tokens, ensuring the admin UI remains free from utility-class sprawl and specificity conflicts.
Specificity and !important Rules
The codebase bans !important declarations except in two designated exceptions: globals.css for reduced-motion accessibility handling and Button.module.css for specificity reset requirements. This restriction prevents brittle style overrides and maintains the cascade's predictability.
Implementation Examples
Adding a Color Token and Using It in a Component
First, define the token in the global stylesheet:
/* src/styles/globals.css – add the token */
:root {
--brand-primary: #4a90e2;
--brand-primary-10: rgba(74,144,226,0.1);
}
Then reference it in a CSS Module:
/* src/ui/components/Alert/Alert.module.css – reference the token */
.alert {
background-color: var(--brand-primary-10);
border: 1px solid var(--brand-primary);
color: var(--text-bright);
border-radius: var(--editor-radius);
padding: var(--space-m);
}
Using Fluid Spacing in Layout Components
/* src/ui/components/Stack/Stack.module.css */
.stack {
display: flex;
flex-direction: column;
gap: var(--space-s); /* fluid spacing – no hard-coded pixels */
}
Referencing Radius Tokens in Cards
/* src/ui/components/Card/Card.module.css */
.card {
background: var(--bg-surface);
border-radius: var(--panel-radius); /* 12 px radius – shared token */
box-shadow: 0 2px 4px var(--overlay-10);
}
Summary
- All design tokens are centralized in
src/styles/globals.cssas CSS custom properties, categorized by semantic purpose (surface, border, text, accent) - CSS Modules must use adjacent file naming (
Component.module.css) and reside in approved directories (src/admin/,src/ui/) - Automated tests in
src/__tests__/architecture/block hard-coded values (css-token-policy.test.ts) and Tailwind usage (noTailwindUtilities.test.ts) - Token references must use
var(--*)syntax exclusively; no raw hex, rgb, or pixel values are permitted - Class names follow camelCase conventions within modules, and
!importantis banned except inglobals.cssandButton.module.css
Frequently Asked Questions
Where are design tokens defined in Instatic?
All design tokens are defined as CSS custom properties in src/styles/globals.css. This centralized approach ensures that colors, spacing, typography, and radius values remain consistent across the admin interface and can be updated from a single location, as documented in docs/reference/design-tokens.md.
How does Instatic prevent hard-coded CSS values?
The repository uses src/__tests__/architecture/css-token-policy.test.ts to scan CSS Modules for raw hex codes, rgb values, and pixel literals. Any module containing hard-coded values fails the test suite, enforcing the requirement that all visual properties reference tokens via var() notation.
Why does Instatic ban Tailwind CSS?
Instatic prohibits Tailwind utilities and dependencies through noTailwindUtilities.test.ts and no-tailwind-deps.test.ts to maintain strict visual consistency and prevent utility-class sprawl. The architecture requires explicit token references through CSS Modules instead of utility composition, ensuring design system adherence.
What naming convention should CSS Module class names follow?
Class names within CSS Modules use camelCase (e.g., .buttonPrimary, .cardHeader) rather than kebab-case or BEM. This convention aligns with JavaScript object property access patterns when importing styles into React components, and is enforced by the project's style guide in docs/design.md.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →