一键导入
enterprise-css-patterns-library
Comprehensive enterprise CSS architecture patterns for large-scale applications with design systems, governance, and team workflows
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Comprehensive enterprise CSS architecture patterns for large-scale applications with design systems, governance, and team workflows
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | Enterprise CSS Patterns Library |
| description | Comprehensive enterprise CSS architecture patterns for large-scale applications with design systems, governance, and team workflows |
| category | enterprise |
| version | 1.0.0 |
| keywords | ["enterprise","css-architecture","design-system","itcss","atomic-design","monorepo","governance","bem","versioning","migration","performance","storybook"] |
A comprehensive collection of production-ready CSS patterns and architectures for enterprise-scale applications. This skill covers design systems, governance frameworks, component libraries, team workflows, and migration strategies.
Description: A scalable and maintainable CSS architecture based on specificity levels, from generic to explicit.
Architecture Layers:
/**
* ITCSS Architecture Implementation
* @description 7-layer inverted triangle CSS architecture
* @version 3.0.0
* @governance Design System Council approved
* @accessibility WCAG 2.1 AA compliant
*/
// Layer 1: Settings – Global variables, config switches
@import 'settings/colors';
@import 'settings/typography';
@import 'settings/breakpoints';
@import 'settings/spacing';
// Layer 2: Tools – Mixins and functions (no output)
@import 'tools/mixins';
@import 'tools/functions';
@import 'tools/placeholders';
// Layer 3: Generic – Ground-zero styles (resets, normalize)
@import 'generic/reset';
@import 'generic/normalize';
@import 'generic/box-sizing';
// Layer 4: Elements – Unclassed HTML elements (type selectors)
@import 'elements/headings';
@import 'elements/links';
@import 'elements/forms';
@import 'elements/tables';
// Layer 5: Objects – Cosmetic-free design patterns (layout)
@import 'objects/container';
@import 'objects/grid';
@import 'objects/media';
@import 'objects/list-bare';
// Layer 6: Components – Complete UI components (specific)
@import 'components/buttons';
@import 'components/cards';
@import 'components/modals';
@import 'components/navigation';
// Layer 7: Utilities – Helper classes with !important (highest specificity)
@import 'utilities/spacing';
@import 'utilities/typography';
@import 'utilities/visibility';
@import 'utilities/colors';
TypeScript Configuration Interface:
/**
* ITCSS Configuration
* @interface ITCSSConfig
* @description Configuration for ITCSS architecture setup
*/
interface ITCSSConfig {
/** Base path for SCSS files */
basePath: string;
/** Layers to include in build */
layers: {
settings: boolean;
tools: boolean;
generic: boolean;
elements: boolean;
objects: boolean;
components: boolean;
utilities: boolean;
};
/** Output configuration */
output: {
/** Generate sourcemaps */
sourcemaps: boolean;
/** Minify output */
minify: boolean;
/** Output file path */
outputPath: string;
};
/** Performance budgets */
budgets: {
maxSize: number; // in KB
maxSpecificity: number;
};
}
/**
* Initialize ITCSS architecture
* @param config - ITCSS configuration
* @returns Build result with metrics
*/
function initializeITCSS(config: ITCSSConfig): Promise<BuildResult> {
// Implementation
}
Design Tokens:
/**
* ITCSS Settings Layer - Design Tokens
* @description Foundation design tokens for the entire system
*/
// settings/_colors.scss
:root {
// Primitive tokens
--color-blue-100: #e3f2fd;
--color-blue-500: #2196f3;
--color-blue-900: #0d47a1;
// Semantic tokens
--color-primary: var(--color-blue-500);
--color-primary-hover: var(--color-blue-600);
--color-surface: #ffffff;
--color-text: #1f2937;
}
// settings/_spacing.scss
:root {
--spacing-unit: 8px;
--spacing-xs: calc(var(--spacing-unit) * 0.5); // 4px
--spacing-sm: calc(var(--spacing-unit) * 1); // 8px
--spacing-md: calc(var(--spacing-unit) * 2); // 16px
--spacing-lg: calc(var(--spacing-unit) * 3); // 24px
--spacing-xl: calc(var(--spacing-unit) * 4); // 32px
}
Accessibility Notes:
Performance Metrics:
Description: Block Element Modifier methodology adapted for large teams and complex applications.
Enterprise BEM Pattern:
/**
* BEM Enterprise Naming Convention
* @description Standardized BEM implementation for large teams
* @pattern [namespace-]block__element--modifier
* @version 2.0.0
* @accessibility WCAG 2.1 AA compliant
*/
// Namespace configuration
$namespace: 'ds-'; // Design system prefix for isolation
/**
* Component: Card
* @component Card
* @category UI Components
* @version 2.1.0
* @status stable
* @designer Jane Doe
* @developer John Smith
* @last-modified 2024-01-15
* @accessibility
* - Keyboard navigable
* - Screen reader friendly
* - ARIA labels included
*/
.#{$namespace}card {
// CSS Custom Properties API
--card-background: var(--color-surface);
--card-padding: var(--spacing-md);
--card-border-radius: var(--radius-md);
--card-shadow: var(--shadow-sm);
--card-transition: var(--transition-default);
// Base block styles
background: var(--card-background);
padding: var(--card-padding);
border-radius: var(--card-border-radius);
box-shadow: var(--card-shadow);
transition: var(--card-transition);
/**
* Element: Card header container
* @requires .ds-card__title
* @optional .ds-card__actions
*/
&__header {
display: flex;
align-items: center;
justify-content: space-between;
padding-block-end: var(--spacing-sm);
border-block-end: 1px solid var(--color-border);
}
/**
* Element: Card title
* @typography heading-3
* @color text-primary
*/
&__title {
font-size: var(--font-size-lg);
font-weight: var(--font-weight-semibold);
color: var(--color-text-primary);
margin: 0;
}
/**
* Element: Card actions container
* @layout horizontal flex
*/
&__actions {
display: flex;
gap: var(--spacing-xs);
}
/**
* Element: Card body content
* @layout flex-column
*/
&__body {
padding-block: var(--spacing-md);
}
/**
* Element: Card footer
* @layout flex horizontal
*/
&__footer {
display: flex;
justify-content: flex-end;
gap: var(--spacing-sm);
padding-block-start: var(--spacing-sm);
border-block-start: 1px solid var(--color-border);
}
// ===== Modifier: Visual Variants =====
/**
* Modifier: Elevated card with enhanced shadow
* @shadow level-2
*/
&--elevated {
--card-shadow: var(--shadow-md);
&:hover {
--card-shadow: var(--shadow-lg);
}
}
/**
* Modifier: Interactive clickable card
* @interaction hover, focus, active
* @cursor pointer
*/
&--interactive {
cursor: pointer;
&:hover {
--card-background: var(--color-surface-hover);
}
&:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
&:active {
transform: translateY(1px);
}
}
/**
* Modifier: Outlined card variant
* @border 1px solid
*/
&--outlined {
--card-shadow: none;
border: 1px solid var(--color-border);
}
// ===== Modifier: Size Variants =====
/**
* Modifier: Compact card with reduced padding
* @padding sm
*/
&--compact {
--card-padding: var(--spacing-sm);
}
/**
* Modifier: Large card with increased padding
* @padding lg
*/
&--large {
--card-padding: var(--spacing-lg);
}
// ===== State Modifiers =====
/**
* State: Loading state
* @state loading
*/
&--loading {
position: relative;
pointer-events: none;
&::after {
content: '';
position: absolute;
inset: 0;
background: rgba(255, 255, 255, 0.8);
display: flex;
align-items: center;
justify-content: center;
}
}
/**
* State: Error state
* @state error
* @color error
*/
&--error {
border-inline-start: 4px solid var(--color-error);
}
}
TypeScript Interface:
/**
* BEM Component Configuration
* @interface BEMComponent
* @description Type-safe BEM component configuration
*/
interface BEMComponent {
/** Block name */
block: string;
/** Namespace prefix */
namespace?: string;
/** Elements within the block */
elements: {
name: string;
required: boolean;
description: string;
}[];
/** Available modifiers */
modifiers: {
name: string;
type: 'visual' | 'size' | 'state';
values?: string[];
description: string;
}[];
/** Component metadata */
metadata: {
version: string;
status: 'stable' | 'beta' | 'deprecated';
accessibility: string[];
};
}
/**
* Generate BEM class name
* @param block - Block name
* @param element - Optional element name
* @param modifier - Optional modifier name
* @param namespace - Optional namespace prefix
* @returns Complete BEM class name
*/
function bem(
block: string,
element?: string,
modifier?: string,
namespace: string = 'ds-'
): string {
let className = `${namespace}${block}`;
if (element) className += `__${element}`;
if (modifier) className += `--${modifier}`;
return className;
}
// Usage example
const cardClass = bem('card', 'header', 'elevated'); // 'ds-card__header--elevated'
Accessibility Guidelines:
<article class="ds-card"> instead of <div>role="region" for cards with headingstabindex="0" and keyboard handlersDescription: Hierarchical component system from atoms to pages for systematic UI construction.
Atomic Design Implementation:
/**
* Atomic Design System Structure
* @description 5-level component hierarchy
* @pattern Atoms → Molecules → Organisms → Templates → Pages
* @version 3.0.0
*/
// ===== ATOMS: Basic building blocks =====
// atoms/_button.scss
/**
* Atom: Button
* @description Fundamental clickable element
* @category Atoms
* @accessibility
* - Keyboard accessible (Enter/Space)
* - Focus visible
* - ARIA label support
*/
.a-button {
--button-background: var(--color-primary);
--button-color: var(--color-primary-contrast);
--button-padding: var(--spacing-sm) var(--spacing-md);
--button-border-radius: var(--radius-md);
--button-font-size: var(--font-size-base);
--button-font-weight: var(--font-weight-medium);
--button-transition: all 0.2s ease;
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--spacing-xs);
padding: var(--button-padding);
background: var(--button-background);
color: var(--button-color);
border: none;
border-radius: var(--button-border-radius);
font-size: var(--button-font-size);
font-weight: var(--button-font-weight);
font-family: inherit;
line-height: 1;
text-decoration: none;
cursor: pointer;
user-select: none;
transition: var(--button-transition);
// Focus state
&:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
// Hover state
&:hover:not(:disabled) {
filter: brightness(1.1);
}
// Active state
&:active:not(:disabled) {
transform: translateY(1px);
}
// Disabled state
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
// atoms/_input.scss
/**
* Atom: Input
* @description Text input field
* @category Atoms
*/
.a-input {
--input-background: var(--color-surface);
--input-border: 1px solid var(--color-border);
--input-padding: var(--spacing-sm) var(--spacing-md);
--input-border-radius: var(--radius-md);
--input-font-size: var(--font-size-base);
width: 100%;
padding: var(--input-padding);
background: var(--input-background);
border: var(--input-border);
border-radius: var(--input-border-radius);
font-size: var(--input-font-size);
font-family: inherit;
transition: border-color 0.2s ease;
&:focus {
outline: none;
border-color: var(--color-primary);
}
&::placeholder {
color: var(--color-text-tertiary);
}
&:disabled {
background: var(--color-surface-disabled);
cursor: not-allowed;
}
}
// ===== MOLECULES: Simple component groups =====
// molecules/_form-field.scss
/**
* Molecule: Form Field
* @description Input with label and error message
* @category Molecules
* @composition
* - .a-label (Atom)
* - .a-input (Atom)
* - .a-error-message (Atom)
*/
.m-form-field {
display: flex;
flex-direction: column;
gap: var(--spacing-xs);
&__label {
@extend .a-label;
font-weight: var(--font-weight-medium);
color: var(--color-text-primary);
}
&__input {
@extend .a-input;
}
&__hint {
font-size: var(--font-size-sm);
color: var(--color-text-tertiary);
}
&__error {
font-size: var(--font-size-sm);
color: var(--color-error);
display: none;
}
// Error state
&--error {
.m-form-field__input {
border-color: var(--color-error);
}
.m-form-field__error {
display: block;
}
}
}
// molecules/_search-box.scss
/**
* Molecule: Search Box
* @description Input with search icon and clear button
* @category Molecules
* @composition
* - .a-input (Atom)
* - .a-button (Atom)
* - .a-icon (Atom)
*/
.m-search-box {
position: relative;
display: flex;
align-items: center;
&__icon {
position: absolute;
left: var(--spacing-sm);
color: var(--color-text-tertiary);
pointer-events: none;
}
&__input {
@extend .a-input;
padding-inline-start: calc(var(--spacing-md) + 24px);
padding-inline-end: calc(var(--spacing-md) + 24px);
}
&__clear {
@extend .a-button;
position: absolute;
right: var(--spacing-xs);
padding: var(--spacing-xs);
background: transparent;
color: var(--color-text-tertiary);
&:hover {
color: var(--color-text-primary);
}
}
}
// ===== ORGANISMS: Complex UI components =====
// organisms/_header.scss
/**
* Organism: Site Header
* @description Main navigation header
* @category Organisms
* @composition
* - .m-logo (Molecule)
* - .m-navigation (Molecule)
* - .m-search-box (Molecule)
* - .m-user-menu (Molecule)
*/
.o-header {
--header-height: 64px;
--header-background: var(--color-surface);
--header-border: 1px solid var(--color-border);
position: sticky;
top: 0;
z-index: 100;
height: var(--header-height);
background: var(--header-background);
border-block-end: var(--header-border);
&__container {
display: flex;
align-items: center;
justify-content: space-between;
height: 100%;
padding-inline: var(--spacing-lg);
max-width: var(--container-max-width);
margin-inline: auto;
}
&__brand {
display: flex;
align-items: center;
gap: var(--spacing-md);
}
&__nav {
flex: 1;
display: flex;
justify-content: center;
}
&__actions {
display: flex;
align-items: center;
gap: var(--spacing-sm);
}
}
// organisms/_data-table.scss
/**
* Organism: Data Table
* @description Complex table with sorting, filtering, pagination
* @category Organisms
* @composition
* - .m-table-header (Molecule)
* - .m-table-row (Molecule)
* - .m-pagination (Molecule)
*/
.o-data-table {
--table-border: 1px solid var(--color-border);
--table-header-background: var(--color-surface-secondary);
width: 100%;
border: var(--table-border);
border-radius: var(--radius-lg);
overflow: hidden;
&__header {
background: var(--table-header-background);
font-weight: var(--font-weight-semibold);
}
&__body {
// Table body styles
}
&__footer {
display: flex;
justify-content: space-between;
align-items: center;
padding: var(--spacing-md);
border-block-start: var(--table-border);
}
}
TypeScript Atomic Design Interface:
/**
* Atomic Design Component Registry
* @description Type-safe component registry for atomic design
*/
interface AtomicDesignRegistry {
atoms: {
button: ComponentDefinition;
input: ComponentDefinition;
label: ComponentDefinition;
icon: ComponentDefinition;
};
molecules: {
formField: ComponentDefinition;
searchBox: ComponentDefinition;
card: ComponentDefinition;
};
organisms: {
header: ComponentDefinition;
dataTable: ComponentDefinition;
sidebar: ComponentDefinition;
};
templates: {
dashboardLayout: TemplateDefinition;
authLayout: TemplateDefinition;
};
}
interface ComponentDefinition {
name: string;
category: 'atom' | 'molecule' | 'organism';
dependencies: string[];
props: Record<string, PropDefinition>;
variants: string[];
accessibility: AccessibilityRequirements;
}
interface PropDefinition {
type: 'string' | 'number' | 'boolean';
required: boolean;
default?: any;
description: string;
}
interface AccessibilityRequirements {
role?: string;
ariaLabels: string[];
keyboardNavigation: boolean;
wcagLevel: 'A' | 'AA' | 'AAA';
}
Composition Guidelines:
Description: Complete enterprise design system structure with tokens, components, and patterns.
/**
* Enterprise Design System Structure
* @description Complete design system architecture
* @version 3.0.0
* @governance Design System Council
* @performance Budget: 250KB uncompressed, 50KB gzipped
*/
// ===== LAYER 1: Design Tokens =====
// Primary source of truth for all design decisions
@import 'tokens/colors';
@import 'tokens/typography';
@import 'tokens/spacing';
@import 'tokens/shadows';
@import 'tokens/animations';
@import 'tokens/breakpoints';
@import 'tokens/z-index';
// ===== LAYER 2: Foundation =====
// Core utilities and helpers
@import 'foundation/reset';
@import 'foundation/mixins';
@import 'foundation/functions';
@import 'foundation/grid';
@import 'foundation/breakpoints';
// ===== LAYER 3: Component Layer =====
// Reusable UI components organized by category
@import 'components/core/*'; // Core: buttons, inputs, labels
@import 'components/layout/*'; // Layout: container, grid, stack
@import 'components/navigation/*'; // Navigation: navbar, tabs, breadcrumbs
@import 'components/data/*'; // Data: tables, lists, cards
@import 'components/feedback/*'; // Feedback: alerts, toasts, modals
// ===== LAYER 4: Pattern Layer =====
// Complex UI patterns combining components
@import 'patterns/forms/*';
@import 'patterns/cards/*';
@import 'patterns/modals/*';
@import 'patterns/workflows/*';
@import 'patterns/dashboards/*';
// ===== LAYER 5: Theme Layer =====
// Brand-specific customizations
@import 'themes/default';
@import 'themes/dark';
@import 'themes/high-contrast';
@import 'themes/brand-a';
@import 'themes/brand-b';
3-Tier Token System:
/**
* Multi-Tier Design Token Architecture
* @description Enterprise-grade token system for maximum flexibility
* @governance Token changes require Design System Council approval
* @versioning Tokens follow semantic versioning
*/
// ===== TIER 1: Primitive Tokens (Raw Values) =====
/**
* Primitive Color Tokens
* @description Base color palette - never use directly in components
* @tier 1
*/
$primitive-colors: (
// Blue scale
'blue-100': #e3f2fd,
'blue-200': #bbdefb,
'blue-300': #90caf9,
'blue-400': #64b5f6,
'blue-500': #2196f3,
'blue-600': #1e88e5,
'blue-700': #1976d2,
'blue-800': #1565c0,
'blue-900': #0d47a1,
// Gray scale
'gray-100': #f5f5f5,
'gray-200': #eeeeee,
'gray-300': #e0e0e0,
'gray-400': #bdbdbd,
'gray-500': #9e9e9e,
'gray-600': #757575,
'gray-700': #616161,
'gray-800': #424242,
'gray-900': #212121,
// Semantic colors
'green-500': #4caf50,
'green-600': #43a047,
'amber-500': #ffc107,
'amber-600': #ffb300,
'red-500': #f44336,
'red-600': #e53935
);
// ===== TIER 2: Semantic Tokens (Meaning) =====
/**
* Semantic Color Tokens
* @description Purpose-driven tokens mapped from primitives
* @tier 2
* @usage Use these in tier-3 component tokens
*/
$semantic-colors: (
// Primary brand color
'primary': map-get($primitive-colors, 'blue-600'),
'primary-hover': map-get($primitive-colors, 'blue-700'),
'primary-active': map-get($primitive-colors, 'blue-800'),
'primary-light': map-get($primitive-colors, 'blue-100'),
// Secondary brand color
'secondary': map-get($primitive-colors, 'gray-700'),
'secondary-hover': map-get($primitive-colors, 'gray-800'),
// Feedback colors
'success': map-get($primitive-colors, 'green-600'),
'success-light': map-get($primitive-colors, 'green-100'),
'warning': map-get($primitive-colors, 'amber-600'),
'warning-light': map-get($primitive-colors, 'amber-100'),
'error': map-get($primitive-colors, 'red-600'),
'error-light': map-get($primitive-colors, 'red-100'),
'info': map-get($primitive-colors, 'blue-500'),
'info-light': map-get($primitive-colors, 'blue-100'),
// Neutral colors
'text-primary': map-get($primitive-colors, 'gray-900'),
'text-secondary': map-get($primitive-colors, 'gray-700'),
'text-tertiary': map-get($primitive-colors, 'gray-500'),
'text-disabled': map-get($primitive-colors, 'gray-400'),
// Surface colors
'surface': #ffffff,
'surface-secondary': map-get($primitive-colors, 'gray-100'),
'surface-tertiary': map-get($primitive-colors, 'gray-200'),
// Border colors
'border': map-get($primitive-colors, 'gray-300'),
'border-strong': map-get($primitive-colors, 'gray-400')
);
// ===== TIER 3: Component Tokens (Specific Use) =====
/**
* Component-Specific Tokens
* @description Granular tokens for individual components
* @tier 3
* @usage Use these directly in component styles
*/
$component-tokens: (
// Button tokens
'button-primary-bg': map-get($semantic-colors, 'primary'),
'button-primary-text': #ffffff,
'button-primary-hover-bg': map-get($semantic-colors, 'primary-hover'),
'button-secondary-bg': map-get($semantic-colors, 'secondary'),
'button-secondary-text': #ffffff,
'button-padding-sm': 8px 12px,
'button-padding-md': 12px 16px,
'button-padding-lg': 16px 24px,
// Card tokens
'card-background': map-get($semantic-colors, 'surface'),
'card-border': 1px solid map-get($semantic-colors, 'border'),
'card-shadow': 0 2px 4px rgba(0, 0, 0, 0.1),
'card-shadow-hover': 0 4px 8px rgba(0, 0, 0, 0.15),
'card-padding': 16px,
'card-border-radius': 8px,
// Input tokens
'input-bg': map-get($semantic-colors, 'surface'),
'input-border': 1px solid map-get($semantic-colors, 'border'),
'input-border-focus': 2px solid map-get($semantic-colors, 'primary'),
'input-text': map-get($semantic-colors, 'text-primary'),
'input-placeholder': map-get($semantic-colors, 'text-tertiary'),
'input-padding': 8px 12px,
'input-border-radius': 4px
);
/**
* Token Validation Function
* @description Ensures token exists and provides helpful error
* @param {Map} $token-map - Token map to search
* @param {String} $key - Token key
* @returns {Any} Token value
* @throws Error if token not found
*/
@function validate-token($token-map, $key) {
@if not map-has-key($token-map, $key) {
@error "Token '#{$key}' not found in token map. Available tokens: #{map-keys($token-map)}";
}
@return map-get($token-map, $key);
}
/**
* Get Component Token
* @description Safe token retrieval with validation
* @param {String} $key - Component token key
* @returns {Any} Token value
*/
@function token($key) {
@return validate-token($component-tokens, $key);
}
// Usage example
.button {
background: token('button-primary-bg');
color: token('button-primary-text');
padding: token('button-padding-md');
}
CSS Custom Properties Export:
/**
* Export Tokens as CSS Custom Properties
* @description Make tokens available at runtime for dynamic theming
*/
:root {
// Tier 1: Primitive tokens
@each $name, $value in $primitive-colors {
--color-#{$name}: #{$value};
}
// Tier 2: Semantic tokens
@each $name, $value in $semantic-colors {
--semantic-#{$name}: #{$value};
}
// Tier 3: Component tokens
@each $name, $value in $component-tokens {
--#{$name}: #{$value};
}
// Typography tokens
--font-family-primary: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
--font-family-mono: 'SF Mono', Monaco, 'Cascadia Code', monospace;
--font-size-xs: 0.75rem; // 12px
--font-size-sm: 0.875rem; // 14px
--font-size-base: 1rem; // 16px
--font-size-lg: 1.125rem; // 18px
--font-size-xl: 1.25rem; // 20px
--font-size-2xl: 1.5rem; // 24px
--font-size-3xl: 1.875rem; // 30px
--font-size-4xl: 2.25rem; // 36px
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
// Spacing tokens
--spacing-unit: 8px;
--spacing-xs: 4px;
--spacing-sm: 8px;
--spacing-md: 16px;
--spacing-lg: 24px;
--spacing-xl: 32px;
--spacing-2xl: 48px;
--spacing-3xl: 64px;
// Border radius tokens
--radius-none: 0;
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-xl: 16px;
--radius-full: 9999px;
// Shadow tokens
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
--shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
--shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1);
--shadow-xl: 0 20px 25px rgba(0, 0, 0, 0.15);
// Animation tokens
--transition-fast: 150ms ease;
--transition-default: 250ms ease;
--transition-slow: 350ms ease;
--ease-in: cubic-bezier(0.4, 0, 1, 1);
--ease-out: cubic-bezier(0, 0, 0.2, 1);
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
// Z-index tokens
--z-dropdown: 1000;
--z-sticky: 1020;
--z-fixed: 1030;
--z-modal-backdrop: 1040;
--z-modal: 1050;
--z-popover: 1060;
--z-tooltip: 1070;
}
TypeScript Token Interface:
/**
* Design Token Type Definitions
* @description Type-safe design token system
*/
/**
* Token Tier Enumeration
* @enum {number}
*/
enum TokenTier {
/** Raw values - never use directly */
Primitive = 1,
/** Purpose-driven tokens */
Semantic = 2,
/** Component-specific tokens */
Component = 3
}
/**
* Color Token Definition
* @interface ColorToken
*/
interface ColorToken {
name: string;
value: string;
tier: TokenTier;
/** Contrast ratio for accessibility */
contrastRatio?: number;
/** WCAG compliance level */
wcagLevel?: 'AA' | 'AAA';
}
/**
* Spacing Token Definition
* @interface SpacingToken
*/
interface SpacingToken {
name: string;
value: string;
/** Base unit multiplier */
multiplier: number;
}
/**
* Typography Token Definition
* @interface TypographyToken
*/
interface TypographyToken {
fontSize: string;
lineHeight: string;
fontWeight: number;
letterSpacing?: string;
}
/**
* Complete Token Registry
* @interface DesignTokenRegistry
*/
interface DesignTokenRegistry {
colors: {
primitive: Map<string, ColorToken>;
semantic: Map<string, ColorToken>;
component: Map<string, ColorToken>;
};
spacing: Map<string, SpacingToken>;
typography: Map<string, TypographyToken>;
shadows: Map<string, string>;
radii: Map<string, string>;
zIndex: Map<string, number>;
}
/**
* Token Manager Class
* @class TokenManager
* @description Manages design tokens with validation and type safety
*/
class TokenManager {
private registry: DesignTokenRegistry;
/**
* Get color token
* @param name - Token name
* @param tier - Token tier (defaults to component)
* @returns Color value
* @throws Error if token not found
*/
getColor(name: string, tier: TokenTier = TokenTier.Component): string {
let tokenMap: Map<string, ColorToken>;
switch (tier) {
case TokenTier.Primitive:
tokenMap = this.registry.colors.primitive;
break;
case TokenTier.Semantic:
tokenMap = this.registry.colors.semantic;
break;
case TokenTier.Component:
tokenMap = this.registry.colors.component;
break;
}
const token = tokenMap.get(name);
if (!token) {
throw new Error(`Color token '${name}' not found in tier ${tier}`);
}
return token.value;
}
/**
* Validate token accessibility
* @param foreground - Foreground color token
* @param background - Background color token
* @returns WCAG compliance level or null if fails
*/
validateContrast(foreground: string, background: string): 'AA' | 'AAA' | null {
const ratio = this.calculateContrastRatio(foreground, background);
if (ratio >= 7) return 'AAA';
if (ratio >= 4.5) return 'AA';
return null;
}
private calculateContrastRatio(color1: string, color2: string): number {
// Implementation of WCAG contrast ratio calculation
// Returns ratio between 1 and 21
return 4.5; // Placeholder
}
}
Structure:
# CSS Governance Charter
Version: 2.0.0
Effective Date: 2024-01-01
Review Cycle: Quarterly
## 1. Governance Structure
### Design System Council
**Role:** Strategic oversight and major decision approval
**Members:**
- Chief Design Officer (Chair)
- Lead Frontend Architect
- UX Research Lead
- Accessibility Specialist
- Product Manager
**Responsibilities:**
- Approve architecture changes
- Set design system roadmap
- Resolve escalated decisions
- Budget allocation
**Meeting Schedule:** Monthly
### CSS Working Group
**Role:** Technical implementation and standards
**Members:**
- Senior Frontend Engineers (3-5)
- CSS Specialist
- Performance Engineer
- Quality Assurance Lead
**Responsibilities:**
- Review RFCs (Request for Comments)
- Define coding standards
- Approve new components
- Maintain documentation
**Meeting Schedule:** Weekly
### Component Owners
**Role:** Individual component maintenance
**Responsibilities:**
- Implement features
- Fix bugs
- Update documentation
- Review PRs for owned components
**Assignment:** Each component has 1 primary + 1 secondary owner
### Quality Assurance Team
**Role:** Testing and validation
**Responsibilities:**
- Visual regression testing
- Accessibility audits
- Performance testing
- Cross-browser validation
## 2. Decision Making Process
### RFC (Request for Comments) Process
**When to Create RFC:**
- New architecture patterns
- Breaking changes
- New major components
- Methodology changes
- Performance budget adjustments
**RFC Template:**
```markdown
# RFC: [Title]
**Date:** YYYY-MM-DD
**Author:** Name
**Status:** Draft | Review | Approved | Rejected
## Summary
Brief description (2-3 sentences)
## Motivation
Why is this needed?
## Detailed Design
Technical implementation details
## Drawbacks
Potential downsides and risks
## Alternatives
What other approaches were considered?
## Migration Plan
How to adopt this change?
## Performance Impact
Expected performance implications
Review Timeline:
Linting:
.stylelintrc.json in repository rootDocumentation:
Performance:
Accessibility:
Browser Support:
Tracked Metrics:
Quality Gates:
Required Checks (Automated):
Required Reviews:
Review Checklist:
## Architecture
- [ ] Follows established patterns
- [ ] Appropriate file location
- [ ] Correct naming conventions
## Code Quality
- [ ] No !important (except utilities)
- [ ] Uses design tokens
- [ ] Minimal nesting (max 3 levels)
- [ ] DRY principle followed
## Performance
- [ ] Efficient selectors
- [ ] No layout thrashing
- [ ] Critical CSS identified
## Documentation
- [ ] Component docs complete
- [ ] Usage examples provided
- [ ] Changelog updated
## Testing
- [ ] Visual regression passes
- [ ] Accessibility tested
- [ ] Cross-browser verified
Automated Enforcement:
Manual Review:
Violation Process:
New Team Members:
Ongoing Education:
Required Documentation:
Documentation Locations:
### Code Review Checklist
```scss
/**
* Enterprise CSS Code Review Checklist
* @description Comprehensive review criteria for CSS contributions
* @version 2.1.0
* @governance Mandatory for all CSS changes
*/
// ===== ARCHITECTURE COMPLIANCE =====
/**
* Architecture Review
* @checklist
* - [ ] Follows ITCSS/Atomic/established architecture
* - [ ] Correct layer placement (Settings/Tools/Components/etc)
* - [ ] File naming follows conventions
* - [ ] Appropriate directory structure
* - [ ] No cross-layer violations
*/
// ===== NAMING CONVENTIONS =====
/**
* Naming Standards
* @checklist
* - [ ] BEM methodology followed consistently
* - [ ] Namespace prefix used correctly
* - [ ] Class names are semantic and meaningful
* - [ ] No abbreviations (except standard: btn, nav)
* - [ ] Modifier naming is clear
*/
// ===== CODE QUALITY =====
/**
* Code Quality Standards
* @checklist
* - [ ] No !important (except in utility layer)
* - [ ] No magic numbers (all values use variables/tokens)
* - [ ] Mixins used appropriately
* - [ ] Functions used for calculations
* - [ ] DRY principle applied
* - [ ] Consistent code formatting
* - [ ] Logical properties used (margin-inline vs margin-left)
*/
// Example of quality issues:
// ❌ BAD
.card {
margin-left: 16px; // Magic number + physical property
color: #333 !important; // Unnecessary !important
.title {
.text {
.inner {
// Too much nesting
}
}
}
}
// ✅ GOOD
.card {
margin-inline-start: var(--spacing-md); // Token + logical property
color: var(--color-text-primary);
&__title {
// Single level nesting
}
}
// ===== PERFORMANCE =====
/**
* Performance Standards
* @checklist
* - [ ] Specificity kept low (max 0-3-0)
* - [ ] Nesting limited to 3 levels
* - [ ] Efficient selectors (avoid universal, descendant)
* - [ ] Critical CSS identified and extracted
* - [ ] No expensive properties (box-shadow on scroll)
* - [ ] Bundle size impact measured
* - [ ] No redundant selectors
*/
// Performance budget check
/**
* Bundle Size Impact
* @metric Current: 45KB | After Change: 47KB | Budget: 50KB
* @status ✅ Within budget
*/
// ===== DESIGN TOKENS =====
/**
* Design Token Usage
* @checklist
* - [ ] All colors use design tokens
* - [ ] All spacing uses spacing scale
* - [ ] Typography tokens applied
* - [ ] No hard-coded values
* - [ ] Semantic tokens preferred over primitive
* - [ ] Component tokens for specific use cases
*/
// ===== ACCESSIBILITY =====
/**
* Accessibility Requirements
* @checklist
* - [ ] Color contrast meets WCAG 2.1 AA (4.5:1 text, 3:1 UI)
* - [ ] Focus indicators visible and meet standards
* - [ ] Interactive elements have hover/focus/active states
* - [ ] No reliance on color alone for information
* - [ ] Text is resizable up to 200%
* - [ ] Reduced motion respected (@media prefers-reduced-motion)
* - [ ] High contrast mode supported
*/
// Example accessibility checks:
// ✅ GOOD - Contrast ratio: 7.2:1 (AAA)
.button {
background: var(--color-primary); // #0d47a1
color: #ffffff;
&:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
}
// ❌ BAD - Contrast ratio: 2.8:1 (Fails AA)
.button-bad {
background: #90caf9; // Too light
color: #ffffff;
&:focus {
outline: none; // Removes focus indicator
}
}
// ===== RESPONSIVE DESIGN =====
/**
* Responsive Requirements
* @checklist
* - [ ] Mobile-first approach
* - [ ] Breakpoints use design tokens
* - [ ] Container queries where appropriate
* - [ ] Flexible units (rem, em, %) over px
* - [ ] Tested on all required viewports
* - [ ] No horizontal scrolling
*/
// ===== BROWSER COMPATIBILITY =====
/**
* Browser Support
* @checklist
* - [ ] Tested in Chrome (last 2 versions)
* - [ ] Tested in Firefox (last 2 versions)
* - [ ] Tested in Safari (last 2 versions)
* - [ ] Tested in Edge (last 2 versions)
* - [ ] Autoprefixer applied
* - [ ] Fallbacks for unsupported features
*/
// ===== DOCUMENTATION =====
/**
* Documentation Requirements
* @checklist
* - [ ] Component purpose documented
* - [ ] Usage examples provided
* - [ ] Props/modifiers documented
* - [ ] Storybook story created
* - [ ] Accessibility notes included
* - [ ] Browser support listed
* - [ ] Changelog updated
*/
// ===== TESTING =====
/**
* Testing Requirements
* @checklist
* - [ ] Visual regression tests created/updated
* - [ ] Accessibility tests pass (axe-core)
* - [ ] Cross-browser testing completed
* - [ ] Responsive testing done
* - [ ] Performance testing conducted
* - [ ] Interactive states tested
*/
// ===== DESIGN SYSTEM ALIGNMENT =====
/**
* Design System Compliance
* @checklist
* - [ ] Uses design tokens exclusively
* - [ ] Follows spacing system
* - [ ] Typography scale applied correctly
* - [ ] Color palette compliance
* - [ ] Adheres to grid system
* - [ ] Consistent with existing patterns
*/
// ===== MIGRATION & DEPRECATION =====
/**
* Breaking Changes
* @checklist (if applicable)
* - [ ] Migration guide provided
* - [ ] Deprecation warnings added
* - [ ] Version bump appropriate (MAJOR for breaking)
* - [ ] Backward compatibility considered
* - [ ] Codemods provided for automation
* - [ ] Communication plan defined
*/
/**
* Enterprise Component Template
* @description Reusable component scaffold with full documentation
* @version 3.0.0
*/
/**
* Component Template Mixin
* @mixin component-template
* @param {String} $name - Component name
* @param {Map} $config - Component configuration
*/
@mixin component-template($name, $config: ()) {
/**
* Component: #{$name}
* @component #{$name}
* @category #{map-get($config, 'category')}
* @version #{map-get($config, 'version')}
* @status #{map-get($config, 'status')}
* @designer #{map-get($config, 'designer')}
* @developer #{map-get($config, 'developer')}
* @last-modified #{map-get($config, 'last-modified')}
* @accessibility #{map-get($config, 'accessibility')}
*/
.c-#{$name} {
// Component API using CSS Custom Properties
--#{$name}-background: var(--color-surface);
--#{$name}-color: var(--color-text);
--#{$name}-border: var(--border-default);
--#{$name}-padding: var(--spacing-md);
--#{$name}-border-radius: var(--radius-md);
--#{$name}-transition: var(--transition-default);
// Base styles using custom properties
background: var(--#{$name}-background);
color: var(--#{$name}-color);
border: var(--#{$name}-border);
padding: var(--#{$name}-padding);
border-radius: var(--#{$name}-border-radius);
transition: var(--#{$name}-transition);
// Allow component-specific styles
@content;
}
}
/**
* Enterprise Button Component
* @description Production-ready button with full variants
* @example
* <button class="c-button c-button--primary c-button--medium">
* Click me
* </button>
*/
@include component-template('button', (
'category': 'Core Components',
'version': '2.1.0',
'status': 'stable',
'designer': 'Jane Doe',
'developer': 'John Smith',
'last-modified': '2024-01-15',
'accessibility': 'WCAG 2.1 AA - Keyboard accessible, ARIA support'
)) {
// Core button structure
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--spacing-xs);
font-family: var(--font-family-primary);
font-weight: var(--font-weight-medium);
text-decoration: none;
cursor: pointer;
user-select: none;
white-space: nowrap;
// ===== Size Variants =====
&--small {
--button-padding: var(--spacing-xs) var(--spacing-sm);
--button-font-size: var(--font-size-sm);
--button-min-height: 32px;
}
&--medium {
--button-padding: var(--spacing-sm) var(--spacing-md);
--button-font-size: var(--font-size-base);
--button-min-height: 40px;
}
&--large {
--button-padding: var(--spacing-md) var(--spacing-lg);
--button-font-size: var(--font-size-lg);
--button-min-height: 48px;
}
// ===== Type Variants =====
&--primary {
--button-background: var(--color-primary);
--button-color: var(--color-primary-contrast);
&:hover:not(:disabled) {
--button-background: var(--color-primary-hover);
}
}
&--secondary {
--button-background: var(--color-secondary);
--button-color: var(--color-secondary-contrast);
&:hover:not(:disabled) {
--button-background: var(--color-secondary-hover);
}
}
&--outlined {
--button-background: transparent;
--button-color: var(--color-primary);
--button-border: 1px solid var(--color-primary);
&:hover:not(:disabled) {
--button-background: var(--color-primary-light);
}
}
&--text {
--button-background: transparent;
--button-color: var(--color-primary);
--button-border: none;
&:hover:not(:disabled) {
--button-background: var(--color-primary-light);
}
}
// ===== States =====
&:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
&:active:not(:disabled) {
transform: translateY(1px);
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
&--loading {
position: relative;
color: transparent;
&::after {
content: '';
position: absolute;
width: 16px;
height: 16px;
border: 2px solid currentColor;
border-radius: 50%;
border-top-color: transparent;
animation: button-spin 0.6s linear infinite;
}
}
}
@keyframes button-spin {
to { transform: rotate(360deg); }
}
TypeScript Component Interface:
/**
* Button Component Configuration
* @interface ButtonConfig
*/
interface ButtonConfig {
/** Button variant type */
variant: 'primary' | 'secondary' | 'outlined' | 'text';
/** Button size */
size: 'small' | 'medium' | 'large';
/** Disabled state */
disabled?: boolean;
/** Loading state */
loading?: boolean;
/** Full width button */
fullWidth?: boolean;
/** Icon position */
iconPosition?: 'left' | 'right';
}
/**
* Generate button class names
* @param config - Button configuration
* @returns Class name string
*/
function getButtonClasses(config: ButtonConfig): string {
const classes = ['c-button'];
classes.push(`c-button--${config.variant}`);
classes.push(`c-button--${config.size}`);
if (config.loading) classes.push('c-button--loading');
if (config.fullWidth) classes.push('c-button--full-width');
return classes.join(' ');
}
Description: Version management strategy for design system CSS following semver principles.
/**
* CSS Semantic Versioning Strategy
* @description Version management for design system CSS
* @pattern MAJOR.MINOR.PATCH
* @governance All version changes require approval
*/
// Current design system version
$design-system-version: '3.2.1';
/**
* Version Change Guidelines
*
* MAJOR (3.0.0 → 4.0.0) - Breaking Changes:
* - Removing CSS classes
* - Changing class naming structure (.btn → .c-button)
* - Modifying existing component API
* - Removing design tokens
* - Changing token values significantly
* - Breaking HTML structure requirements
*
* MINOR (3.1.0 → 3.2.0) - New Features:
* - Adding new components
* - Adding new utility classes
* - Adding new mixins/functions
* - Adding new design tokens
* - Adding new component variants
* - Backward-compatible enhancements
*
* PATCH (3.2.0 → 3.2.1) - Bug Fixes:
* - Fixing visual bugs
* - Performance improvements
* - Documentation updates
* - Accessibility fixes (non-breaking)
* - Browser compatibility fixes
*/
/**
* Deprecation Warning Mixin
* @mixin deprecate
* @param {String} $message - Deprecation message
* @param {String} $version-removed - Version when removal occurs
*/
@mixin deprecate($message, $version-removed) {
@warn "DEPRECATION WARNING: #{$message}. This will be removed in version #{$version-removed}. Current version: #{$design-system-version}";
}
/**
* Example: Deprecating Old Button Class
*/
.btn {
@include deprecate(
"Use .c-button instead of .btn",
"4.0.0"
);
// Temporary compatibility - extends new component
@extend .c-button;
}
/**
* Version-Specific Feature Flags
* @description Enable/disable features based on version
*/
$feature-flags: (
'css-custom-properties': true,
'container-queries': false,
'cascade-layers': false,
'logical-properties': true,
'has-selector': false
);
/**
* Check if feature is enabled
* @function feature-enabled
* @param {String} $feature - Feature name
* @returns {Boolean} Feature enabled status
*/
@function feature-enabled($feature) {
@return map-get($feature-flags, $feature) == true;
}
/**
* Conditional Feature Implementation
*/
@if feature-enabled('css-custom-properties') {
:root {
--spacing-unit: 8px;
--color-primary: #007bff;
}
.component {
padding: var(--spacing-unit);
color: var(--color-primary);
}
} @else {
// Fallback for browsers without custom property support
.component {
padding: 8px;
color: #007bff;
}
}
/**
* CSS Migration Utilities
* @description Tools for gradual migration between versions
*/
/**
* Compatibility Layer Mixin
* @mixin compatibility-mode
* @param {String} $from-version - Migrating from version
* @description Creates compatibility mappings for smooth migration
*/
@mixin compatibility-mode($from-version: '2.0') {
@if $from-version == '2.0' {
// Map v2.0 classes to v3.0 equivalents
.btn { @extend .c-button; }
.btn-primary { @extend .c-button--primary; }
.btn-secondary { @extend .c-button--secondary; }
.card { @extend .c-card; }
.card-header { @extend .c-card__header; }
.card-body { @extend .c-card__body; }
.modal { @extend .c-modal; }
.modal-content { @extend .c-modal__content; }
@warn "Running in compatibility mode for v2.0. Please migrate to v3.0 class names.";
}
}
/**
* Progressive Enhancement Helper
* @mixin progressive-enhancement
* @param {String} $feature - CSS feature to check
*/
@mixin progressive-enhancement($feature) {
@if $feature == 'grid' {
@supports (display: grid) {
@content;
}
}
@if $feature == 'custom-properties' {
@supports (--css: variables) {
@content;
}
}
@if $feature == 'container-queries' {
@supports (container-type: inline-size) {
@content;
}
}
}
// Usage example
.layout {
// Fallback: Flexbox layout
display: flex;
flex-wrap: wrap;
// Enhancement: Grid layout where supported
@include progressive-enhancement('grid') {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
}
TypeScript Migration Tools:
/**
* CSS Migration Manager
* @class MigrationManager
* @description Manages CSS version migrations
*/
class MigrationManager {
private currentVersion: string;
private targetVersion: string;
/**
* Create migration plan
* @param from - Current version
* @param to - Target version
* @returns Migration steps
*/
createMigrationPlan(from: string, to: string): MigrationStep[] {
const steps: MigrationStep[] = [];
// Determine migration type
const [fromMajor, fromMinor] = from.split('.').map(Number);
const [toMajor, toMinor] = to.split('.').map(Number);
if (toMajor > fromMajor) {
// Major version migration - breaking changes
steps.push({
type: 'breaking',
description: 'Update class names to new convention',
automated: true,
codemod: 'migrate-class-names.js'
});
steps.push({
type: 'breaking',
description: 'Update design token references',
automated: true,
codemod: 'migrate-tokens.js'
});
steps.push({
type: 'manual',
description: 'Review and test components',
automated: false
});
}
if (toMinor > fromMinor) {
// Minor version migration - additive changes
steps.push({
type: 'additive',
description: 'Opt-in to new features',
automated: false
});
}
return steps;
}
/**
* Generate migration report
* @param steps - Migration steps
* @returns Markdown report
*/
generateReport(steps: MigrationStep[]): string {
let report = `# Migration Plan: ${this.currentVersion} → ${this.targetVersion}\n\n`;
report += `## Summary\n`;
report += `- Total steps: ${steps.length}\n`;
report += `- Automated: ${steps.filter(s => s.automated).length}\n`;
report += `- Manual: ${steps.filter(s => !s.automated).length}\n\n`;
report += `## Steps\n\n`;
steps.forEach((step, index) => {
report += `### ${index + 1}. ${step.description}\n`;
report += `**Type:** ${step.type}\n`;
report += `**Automated:** ${step.automated ? 'Yes' : 'No'}\n`;
if (step.codemod) {
report += `**Codemod:** \`${step.codemod}\`\n`;
}
report += `\n`;
});
return report;
}
}
interface MigrationStep {
type: 'breaking' | 'additive' | 'manual';
description: string;
automated: boolean;
codemod?: string;
}
Description: CSS organization and sharing strategy for monorepo environments with multiple applications.
enterprise-monorepo/
├── packages/
│ ├── design-system/ # Shared design system package
│ │ ├── src/
│ │ │ ├── tokens/ # Design tokens
│ │ │ │ ├── colors.scss
│ │ │ │ ├── typography.scss
│ │ │ │ └── spacing.scss
│ │ │ ├── foundation/ # Base utilities
│ │ │ │ ├── reset.scss
│ │ │ │ ├── mixins.scss
│ │ │ │ └── grid.scss
│ │ │ ├── components/ # UI components
│ │ │ │ ├── button/
│ │ │ │ ├── card/
│ │ │ │ └── modal/
│ │ │ └── index.scss # Main entry point
│ │ ├── dist/ # Built CSS
│ │ │ ├── design-system.css
│ │ │ ├── design-system.min.css
│ │ │ └── tokens.json
│ │ ├── package.json
│ │ └── README.md
│ │
│ ├── shared-components/ # Shared React/Angular components
│ │ └── src/
│ │ └── styles/
│ │ └── component-overrides.scss
│ │
│ ├── app-customer-portal/ # Application 1
│ │ └── src/
│ │ └── styles/
│ │ ├── main.scss # Imports design system
│ │ ├── theme.scss # App-specific theme
│ │ └── overrides/ # Component customizations
│ │
│ ├── app-admin-dashboard/ # Application 2
│ │ └── src/
│ │ └── styles/
│ │ ├── main.scss
│ │ ├── theme.scss
│ │ └── overrides/
│ │
│ └── app-marketing-site/ # Application 3
│ └── src/
│ └── styles/
│ ├── main.scss
│ ├── theme.scss
│ └── overrides/
│
├── tools/
│ ├── build-css/ # Shared build scripts
│ └── css-linter/ # Linting configuration
│
└── package.json # Root package.json
/**
* Design System Main Entry Point
* packages/design-system/src/index.scss
* @description Central export for the design system
* @version 3.0.0
*/
// Design tokens (always imported first)
@import 'tokens/colors';
@import 'tokens/typography';
@import 'tokens/spacing';
@import 'tokens/shadows';
@import 'tokens/breakpoints';
// Foundation
@import 'foundation/reset';
@import 'foundation/mixins';
@import 'foundation/functions';
@import 'foundation/grid';
// Components (alphabetically)
@import 'components/button/button';
@import 'components/card/card';
@import 'components/input/input';
@import 'components/modal/modal';
@import 'components/table/table';
// Utilities
@import 'utilities/spacing';
@import 'utilities/typography';
@import 'utilities/visibility';
Package Configuration:
{
"name": "@company/design-system",
"version": "3.2.1",
"description": "Enterprise design system CSS",
"main": "dist/design-system.css",
"style": "dist/design-system.css",
"sass": "src/index.scss",
"files": [
"dist",
"src"
],
"exports": {
".": {
"style": "./dist/design-system.css",
"sass": "./src/index.scss",
"default": "./dist/design-system.css"
},
"./tokens": {
"sass": "./src/tokens/index.scss",
"json": "./dist/tokens.json"
},
"./components/*": {
"sass": "./src/components/*/index.scss"
}
},
"scripts": {
"build": "npm run build:css && npm run build:tokens",
"build:css": "sass src/index.scss dist/design-system.css --style=expanded",
"build:css:min": "sass src/index.scss dist/design-system.min.css --style=compressed",
"build:tokens": "node scripts/build-tokens.js",
"lint": "stylelint 'src/**/*.scss'",
"test": "npm run test:visual && npm run test:a11y",
"test:visual": "backstop test",
"test:a11y": "pa11y-ci"
},
"peerDependencies": {
"sass": "^1.69.0"
},
"devDependencies": {
"sass": "^1.69.0",
"stylelint": "^15.10.0",
"backstopjs": "^6.2.0",
"pa11y-ci": "^3.0.0"
}
}
/**
* Application Main Stylesheet
* packages/app-customer-portal/src/styles/main.scss
* @description Imports design system and applies customizations
*/
// ===== 1. Import Design System =====
@use '@company/design-system' as ds;
// ===== 2. Import Design System Tokens =====
@use '@company/design-system/tokens' as tokens;
// ===== 3. Application-Specific Theme =====
@import 'theme';
// ===== 4. Component Overrides =====
@import 'overrides/button';
@import 'overrides/card';
@import 'overrides/navigation';
// ===== 5. Custom Application Styles =====
@import 'layouts/dashboard';
@import 'layouts/auth';
@import 'pages/home';
@import 'pages/profile';
Application Theme Customization:
/**
* Application Theme
* packages/app-customer-portal/src/styles/theme.scss
* @description Brand-specific theme overrides
*/
:root {
// Override primary brand color
--color-primary: #1a73e8; // Google Blue
--color-primary-hover: #1557b0;
// App-specific colors
--color-app-header: #1f2937;
--color-app-sidebar: #111827;
// Custom spacing for this app
--app-header-height: 64px;
--app-sidebar-width: 280px;
}
// Apply theme to design system components
.c-button--primary {
// Automatically uses overridden --color-primary
}
/**
* Shared Webpack CSS Configuration
* tools/build-css/webpack.css.config.js
* @description Reusable CSS build configuration for all apps
*/
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const PostCSSPresetEnv = require('postcss-preset-env');
/**
* Create CSS build configuration
* @param {Object} options - Build options
* @returns {Object} Webpack configuration
*/
function createCSSConfig(options = {}) {
const isProduction = options.mode === 'production';
return {
module: {
rules: [
{
test: /\.(scss|sass)$/,
use: [
// Extract CSS to separate files
MiniCssExtractPlugin.loader,
// CSS loader with modules support
{
loader: 'css-loader',
options: {
sourceMap: !isProduction,
modules: {
auto: true,
localIdentName: isProduction
? '[hash:base64:8]'
: '[name]__[local]--[hash:base64:5]'
},
importLoaders: 2
}
},
// PostCSS processing
{
loader: 'postcss-loader',
options: {
sourceMap: !isProduction,
postcssOptions: {
plugins: [
// Modern CSS features
PostCSSPresetEnv({
stage: 3,
features: {
'nesting-rules': true,
'custom-properties': true,
'custom-media-queries': true,
'logical-properties-and-values': true
},
autoprefixer: {
grid: true
}
}),
// PurgeCSS for production
...(isProduction ? [
require('@fullhuman/postcss-purgecss')({
content: [
'./src/**/*.{html,ts,tsx,js,jsx}',
'./node_modules/@company/**/*.{html,ts,tsx,js,jsx}'
],
safelist: {
standard: [/^c-/, /^m-/, /^o-/, /^u-/], // BEM classes
deep: [/modal/, /tooltip/], // Dynamic classes
greedy: [/data-theme$/] // Attribute selectors
}
})
] : [])
]
}
}
},
// SASS compilation
{
loader: 'sass-loader',
options: {
sourceMap: !isProduction,
sassOptions: {
includePaths: [
'node_modules',
'../../node_modules'
],
precision: 5,
outputStyle: isProduction ? 'compressed' : 'expanded'
}
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: isProduction
? 'css/[name].[contenthash:8].css'
: 'css/[name].css',
chunkFilename: isProduction
? 'css/[name].[contenthash:8].chunk.css'
: 'css/[name].chunk.css'
})
],
optimization: {
minimizer: [
new CssMinimizerPlugin({
minimizerOptions: {
preset: [
'default',
{
discardComments: { removeAll: true },
normalizeWhitespace: true,
colormin: true,
minifyFontValues: true,
minifyGradients: true
}
]
}
})
]
}
};
}
module.exports = { createCSSConfig };
Usage in Application:
/**
* Application Webpack Config
* packages/app-customer-portal/webpack.config.js
*/
const { createCSSConfig } = require('../../tools/build-css/webpack.css.config');
const { merge } = require('webpack-merge');
module.exports = (env, argv) => {
const cssConfig = createCSSConfig({ mode: argv.mode });
return merge(cssConfig, {
// App-specific configuration
entry: './src/main.ts',
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].[contenthash].js'
}
});
};
# .github/workflows/css-pipeline.yml
# Enterprise CSS CI/CD Pipeline
name: CSS Pipeline
on:
pull_request:
paths:
- 'packages/design-system/**'
- 'packages/*/src/styles/**'
- '.github/workflows/css-pipeline.yml'
push:
branches:
- main
- develop
# Cancel in-progress runs for same PR
concurrency:
group: css-${{ github.ref }}
cancel-in-progress: true
jobs:
# ===== Job 1: Linting =====
lint:
name: CSS Linting
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Stylelint
run: npm run lint:css
- name: Check CSS formatting
run: npm run format:check:css
- name: Validate design tokens
run: npm run validate:tokens
# ===== Job 2: Testing =====
test:
name: CSS Testing
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build design system
run: npm run build --workspace=@company/design-system
- name: Visual regression testing
run: npm run test:visual
- name: Accessibility testing
run: npm run test:a11y:css
- name: Upload visual regression results
if: failure()
uses: actions/upload-artifact@v3
with:
name: visual-regression-diffs
path: backstop_data/bitmaps_test
# ===== Job 3: Build & Bundle Analysis =====
build:
name: Build & Analysis
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build design system
run: npm run build --workspace=@company/design-system
- name: Build applications
run: npm run build:apps
- name: Analyze CSS bundle size
run: npm run analyze:css
- name: Check performance budgets
run: npm run budget:check
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: css-bundles
path: |
packages/design-system/dist
packages/*/dist/css
- name: Comment bundle size on PR
if: github.event_name == 'pull_request'
uses: andresz1/size-limit-action@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
# ===== Job 4: Performance Testing =====
performance:
name: Performance Testing
runs-on: ubuntu-latest
needs: build
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Download build artifacts
uses: actions/download-artifact@v3
with:
name: css-bundles
path: dist
- name: Run Lighthouse CI
run: |
npm install -g @lhci/cli
lhci autorun
- name: Check CSS parse time
run: npm run test:css:parse-time
# ===== Job 5: Publish (main branch only) =====
publish:
name: Publish Design System
runs-on: ubuntu-latest
needs: [lint, test, build, performance]
if: github.ref == 'refs/heads/main'
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
registry-url: 'https://registry.npmjs.org'
- name: Install dependencies
run: npm ci
- name: Build design system
run: npm run build --workspace=@company/design-system
- name: Publish to npm
run: npm publish --workspace=@company/design-system --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: v${{ steps.package-version.outputs.version }}
release_name: Design System v${{ steps.package-version.outputs.version }}
body_path: CHANGELOG.md
/**
* Performance Budget Configuration
* .size-limit.json
* @description Enforce CSS bundle size limits
*/
[
{
"name": "Design System - Full Bundle",
"path": "packages/design-system/dist/design-system.css",
"limit": "250 KB",
"gzip": true
},
{
"name": "Design System - Minified",
"path": "packages/design-system/dist/design-system.min.css",
"limit": "50 KB",
"gzip": true
},
{
"name": "Critical CSS",
"path": "packages/design-system/dist/critical.css",
"limit": "14 KB",
"gzip": false
},
{
"name": "App - Customer Portal",
"path": "packages/app-customer-portal/dist/css/main.css",
"limit": "300 KB",
"gzip": true
},
{
"name": "App - Admin Dashboard",
"path": "packages/app-admin-dashboard/dist/css/main.css",
"limit": "280 KB",
"gzip": true
}
]
/**
* Storybook Main Configuration
* .storybook/main.js
* @description Complete Storybook setup for enterprise CSS documentation
*/
module.exports = {
// Story locations
stories: [
'../packages/design-system/src/**/*.stories.@(js|jsx|ts|tsx|mdx)',
'../packages/design-system/src/**/*.docs.mdx'
],
// Addons for enhanced functionality
addons: [
'@storybook/addon-essentials', // Essential tools
'@storybook/addon-a11y', // Accessibility testing
'@storybook/addon-design-tokens', // Design token visualization
'@storybook/addon-interactions', // Interaction testing
'storybook-addon-pseudo-states', // Hover/focus states
'storybook-css-modules-preset', // CSS Modules support
'storybook-dark-mode' // Dark mode toggle
],
// Framework configuration
framework: {
name: '@storybook/html-webpack5',
options: {}
},
// Feature flags
features: {
buildStoriesJson: true,
cssVariables: true,
modernInlineRender: true
},
// TypeScript configuration
typescript: {
check: true,
reactDocgen: 'react-docgen-typescript'
},
// Static directories
staticDirs: ['../public'],
// Webpack customization
webpackFinal: async (config) => {
// Add SCSS support
config.module.rules.push({
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
});
return config;
}
};
Storybook Preview Configuration:
/**
* Storybook Preview Configuration
* .storybook/preview.js
* @description Global decorators, parameters, and styles
*/
import '../packages/design-system/dist/design-system.css';
// Global parameters
export const parameters = {
// Actions configuration
actions: { argTypesRegex: '^on[A-Z].*' },
// Controls configuration
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/
},
expanded: true,
sort: 'requiredFirst'
},
// Viewport configuration
viewport: {
viewports: {
mobile: {
name: 'Mobile',
styles: { width: '375px', height: '667px' },
type: 'mobile'
},
tablet: {
name: 'Tablet',
styles: { width: '768px', height: '1024px' },
type: 'tablet'
},
desktop: {
name: 'Desktop',
styles: { width: '1440px', height: '900px' },
type: 'desktop'
},
wide: {
name: 'Wide Desktop',
styles: { width: '1920px', height: '1080px' },
type: 'desktop'
}
}
},
// Documentation configuration
docs: {
toc: {
title: 'Table of Contents',
headingSelector: 'h2, h3'
},
source: {
type: 'code',
language: 'html'
}
},
// Accessibility configuration
a11y: {
config: {
rules: [
{
id: 'color-contrast',
enabled: true
},
{
id: 'aria-required-attr',
enabled: true
}
]
}
},
// Design assets integration
design: {
type: 'figma',
allowFullscreen: true
}
};
// Global decorators
export const decorators = [
(Story) => {
return `
<div class="sb-container" style="padding: 2rem;">
${Story()}
</div>
`;
}
];
// Global types
export const globalTypes = {
theme: {
name: 'Theme',
description: 'Global theme for components',
defaultValue: 'light',
toolbar: {
icon: 'circlehollow',
items: [
{ value: 'light', title: 'Light', icon: 'sun' },
{ value: 'dark', title: 'Dark', icon: 'moon' },
{ value: 'high-contrast', title: 'High Contrast', icon: 'contrast' }
],
dynamicTitle: true
}
}
};
<!-- Button.stories.mdx -->
import { Meta, Story, Canvas, ArgsTable, Source, Description } from '@storybook/addon-docs';
import { Button } from './Button';
<Meta
title="Components/Core/Button"
component={Button}
parameters={{
design: {
type: 'figma',
url: 'https://www.figma.com/file/xxx/Design-System?node-id=123'
},
docs: {
description: {
component: 'The Button component is a fundamental UI element for triggering actions and events.'
}
}
}}
argTypes={{
variant: {
control: { type: 'select' },
options: ['primary', 'secondary', 'outlined', 'text'],
description: 'Button visual variant',
table: {
type: { summary: 'string' },
defaultValue: { summary: 'primary' }
}
},
size: {
control: { type: 'radio' },
options: ['small', 'medium', 'large'],
description: 'Button size',
table: {
type: { summary: 'string' },
defaultValue: { summary: 'medium' }
}
},
disabled: {
control: { type: 'boolean' },
description: 'Disabled state',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' }
}
},
loading: {
control: { type: 'boolean' },
description: 'Loading state with spinner',
table: {
type: { summary: 'boolean' },
defaultValue: { summary: 'false' }
}
}
}}
/>
# Button Component
The Button component provides a clickable interface element for user interactions.
## Design Principles
- **Clarity**: Clear visual hierarchy with distinct variants
- **Accessibility**: Fully keyboard navigable with screen reader support
- **Consistency**: Follows enterprise design system guidelines
- **Flexibility**: Multiple variants and sizes for different contexts
## Usage Guidelines
### When to Use
- **Primary actions**: Main call-to-action on pages or in dialogs
- **Secondary actions**: Supporting actions with lower emphasis
- **Form submissions**: Submit or cancel form data
- **Navigation triggers**: Open dialogs, panels, or navigate
### When NOT to Use
- **Navigation between pages**: Use Link component instead
- **Toggle states**: Use Switch or Checkbox components
- **Multiple selections**: Use Checkbox or Radio groups
---
## Examples
### Primary Button
The primary button is for the main action on a page or section.
<Canvas>
<Story name="Primary">
{`
<button class="c-button c-button--primary c-button--medium">
Primary Action
</button>
`}
</Story>
</Canvas>
### Secondary Button
Secondary buttons are for supporting actions with less emphasis.
<Canvas>
<Story name="Secondary">
{`
<button class="c-button c-button--secondary c-button--medium">
Secondary Action
</button>
`}
</Story>
</Canvas>
### Button Sizes
Buttons come in three sizes: small, medium, and large.
<Canvas>
<Story name="Sizes">
{`
<div style="display: flex; gap: 1rem; align-items: center;">
<button class="c-button c-button--primary c-button--small">
Small
</button>
<button class="c-button c-button--primary c-button--medium">
Medium
</button>
<button class="c-button c-button--primary c-button--large">
Large
</button>
</div>
`}
</Story>
</Canvas>
### Button with Icon
Buttons can include icons for better context.
<Canvas>
<Story name="With Icon">
{`
<button class="c-button c-button--primary c-button--medium">
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
<path d="M8 0l8 8-8 8-8-8 8-8z"/>
</svg>
<span>With Icon</span>
</button>
`}
</Story>
</Canvas>
### Loading State
Buttons show a loading spinner when an action is in progress.
<Canvas>
<Story name="Loading">
{`
<button class="c-button c-button--primary c-button--medium c-button--loading">
Loading...
</button>
`}
</Story>
</Canvas>
### Disabled State
Disabled buttons cannot be interacted with.
<Canvas>
<Story name="Disabled">
{`
<button class="c-button c-button--primary c-button--medium" disabled>
Disabled Button
</button>
`}
</Story>
</Canvas>
---
## CSS Implementation
<Source
language="scss"
dark
code={`
/**
* Button Component
* @component c-button
* @version 2.1.0
*/
.c-button {
// Base styles
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--spacing-xs);
padding: var(--button-padding);
background: var(--button-background);
color: var(--button-color);
border: var(--button-border, none);
border-radius: var(--button-border-radius);
font-size: var(--button-font-size);
font-weight: var(--font-weight-medium);
font-family: inherit;
line-height: 1;
text-decoration: none;
cursor: pointer;
user-select: none;
transition: all 0.2s ease;
// Variants
&--primary {
--button-background: var(--color-primary);
--button-color: var(--color-primary-contrast);
}
&--secondary {
--button-background: var(--color-secondary);
--button-color: var(--color-secondary-contrast);
}
// Sizes
&--small {
--button-padding: var(--spacing-xs) var(--spacing-sm);
--button-font-size: var(--font-size-sm);
}
&--medium {
--button-padding: var(--spacing-sm) var(--spacing-md);
--button-font-size: var(--font-size-base);
}
&--large {
--button-padding: var(--spacing-md) var(--spacing-lg);
--button-font-size: var(--font-size-lg);
}
// States
&:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
&:hover:not(:disabled) {
filter: brightness(1.1);
}
&:active:not(:disabled) {
transform: translateY(1px);
}
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
}
`}
/>
---
## Accessibility
### WCAG 2.1 AA Compliance
- ✅ **Color Contrast**: Meets 4.5:1 ratio for text
- ✅ **Keyboard Navigation**: Fully accessible via Tab and Enter/Space
- ✅ **Focus Indicators**: Visible 2px outline with 2px offset
- ✅ **Screen Reader**: Proper ARIA labels and states
### Keyboard Shortcuts
| Key | Action |
|-----|--------|
| Tab | Focus button |
| Enter | Activate button |
| Space | Activate button |
### ARIA Attributes
```html
<button
class="c-button c-button--primary"
aria-label="Submit form"
aria-disabled="false"
aria-busy="false">
Submit
</button>
| Browser | Version |
|---|---|
| Chrome | Last 2 |
| Firefox | Last 2 |
| Safari | Last 2 |
| Edge | Last 2 |
.btn to .c-buttonAngular Material components quick reference. Use when searching for Material component APIs, theming patterns, or CDK utilities.
Comprehensive patterns for BEM, OOCSS, SMACSS, ITCSS, and CUBE CSS with selection guides and implementation strategies
Comprehensive Leaflet patterns for custom markers, styled popups, controls, GeoJSON, clustering, and dark mode. Use when searching for Leaflet styling, marker customization, popup design, or interactive map features.
Comprehensive map styling patterns for Leaflet, Mapbox, and GIS visualizations. Use when searching for map theming, marker styling, popup designs, or choropleth patterns.
Comprehensive Mapbox GL JS patterns for custom styles, 3D visualization, animations, and data-driven maps. Use when searching for Mapbox styling, 3D buildings, heat maps, or advanced map visualizations.
PostCSS plugins reference - essential plugins, configuration, and optimization strategies