git clone https://github.com/NeverSight/learn-skills.dev
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/agents-inc/skills/web-styling-scss-modules" ~/.claude/skills/neversight-learn-skills-dev-web-styling-scss-modules && rm -rf "$T"
data/skills-md/agents-inc/skills/web-styling-scss-modules/SKILL.mdStyling & Design System
Quick Guide: Two-tier token system (Core primitives -> Semantic tokens). Foreground/background color pairs. Components use semantic tokens only. SCSS Modules + CSS Cascade Layers. HSL format. Dark mode via
class with mixin. Data-attributes for state. Self-contained (no external dependencies)..dark
<critical_requirements>
CRITICAL: Before Using This Skill
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
, named constants)import type
(You MUST wrap ALL UI package component styles in
for proper cascade precedence)@layer components {}
(You MUST use semantic tokens ONLY in components - NEVER use core tokens directly)
(You MUST use HSL format for colors with CSS color functions - NO Sass color functions like darken/lighten)
(You MUST use data-attributes for state styling - NOT className toggling)
(You MUST use
for imports - @use
is deprecated and will be removed in Dart Sass 3.0.0)@import
</critical_requirements>
Auto-detection: UI components, styling patterns, design tokens, SCSS modules, CSS Cascade Layers, dark mode theming
When to use:
- Implementing design tokens and theming
- Building component styles with SCSS Modules
- Ensuring visual consistency across applications
- Working with colors, spacing, typography
- Implementing dark mode with class-based theming
- Setting up CSS Cascade Layers for predictable style precedence
Key patterns covered:
- Two-tier token system (Core -> Semantic)
- SCSS Module patterns with CSS Cascade Layers
- Color system (HSL format, semantic naming, foreground/background pairs)
- Spacing and typography systems
- Dark mode implementation (
class with mixin pattern).dark - Component structure and organization
When NOT to use:
- One-off prototypes without design system needs (use inline styles or basic CSS)
- External component libraries with their own theming (Material-UI, Chakra)
- Projects requiring comprehensive utility classes (use Tailwind CSS instead)
Detailed Resources:
- examples/core.md - Token system, HSL colors, cascade layers
- examples/tokens.md - Spacing and typography systems
- examples/theming.md - Dark mode implementation
- examples/patterns.md - Module structure, data-attributes, mixins, global styles, icons
- examples/cva.md - cva integration with SCSS Modules
- examples/advanced.md - :has(), :global(), nesting patterns
- examples/modules.md - Sass module system (@use and @forward)
- reference.md - Decision frameworks and anti-patterns
<philosophy>
Philosophy
The design system follows a self-contained, two-tier token architecture where core primitives (raw HSL values, base sizes) map to semantic tokens (purpose-driven names). Components consume only semantic tokens, enabling theme changes without component modifications.
Core Principles:
- Self-contained: No external dependencies (no Open Props, no Tailwind for tokens)
- Two-tier system: Core tokens provide raw values, semantic tokens provide meaning
- HSL-first: Use modern CSS color functions, not Sass color manipulation
- Layer-based: CSS Cascade Layers ensure predictable style precedence across monorepo
- Theme-agnostic components: Components use semantic tokens and adapt automatically to light/dark mode
<patterns>
Core Patterns
Pattern 1: Two-Tier Token System
The design system uses a two-tier token architecture: Tier 1 (Core tokens) provides raw values, Tier 2 (Semantic tokens) references core tokens with purpose-driven names.
Token Architecture
Location:
packages/ui/src/styles/design-tokens.scss
Tier 1: Core tokens - Raw HSL values, base sizes, primitives
--color-white: 0 0% 100%; --color-gray-900: 222 47% 11%; --color-red-500: 0 84% 60%; --space-unit: 0.2rem;
Tier 2: Semantic tokens - Reference core tokens with purpose-driven names
--color-background-base: var(--color-white); --color-text-default: var(--color-gray-500); --color-primary: var(--color-gray-900); --color-primary-foreground: var(--color-white); --color-destructive: var(--color-red-500);
Why this matters: Semantic tokens make purpose clear (what the token is for), theme changes only update token values (not component code), components remain theme-agnostic.
For complete implementation examples, see examples/core.md.
Pattern 2: HSL Color Format with CSS Color Functions
Store HSL values without the
hsl() wrapper in tokens, apply hsl() wrapper when using tokens, and use modern CSS color functions for transparency and color mixing.
Color Format Rules
- Store HSL values without
wrapper:hsl()--color-gray-900: 222 47% 11%; - Use
wrapper when applying:hsl()background-color: hsl(var(--color-primary)) - Use CSS color functions for derived colors:
- Transparency:
(append alpha to HSL components)hsl(var(--color-primary) / 0.5) - Color mixing:
color-mix(in srgb, hsl(var(--color-primary)), white 10%) - Channel manipulation:
(wrap origin inhsl(from hsl(var(--color-primary)) h s calc(l * 0.8))
first)hsl()
- Transparency:
- NEVER use Sass color functions: No
,darken()
,lighten()transparentize() - Always use semantic color tokens (not raw HSL in components)
Why HSL: HSL format eliminates Sass dependencies, CSS color functions work natively in browsers, semantic naming clarifies purpose (not just value), theme changes update token values without touching components.
For complete implementation examples, see examples/core.md.
Pattern 3: CSS Cascade Layers for Predictable Precedence
Use CSS Cascade Layers to control style precedence across the monorepo, ensuring UI package components have lower priority than app-specific overrides.
Layer Hierarchy (lowest -> highest priority)
- Browser resets and normalizations@layer reset
- Design system component styles (UI package)@layer components- Unlayered styles - App-specific overrides (highest priority)
Key Rules
- UI package components: Always wrap in
@layer components {} - App-specific styles: Never wrap in layers (unlayered = highest priority)
- Layer declaration: Import
first to declare layer orderlayers.scss
Why layers: Wrapping in
@layer components {} ensures app styles can override without specificity wars, loading order becomes irrelevant, predictable precedence across monorepo.
For complete implementation examples, see examples/core.md.
Pattern 4: Dark Mode with .dark
Class and Mixin
.darkImplement dark mode by adding
.dark class to root element, which overrides semantic tokens. Use mixin pattern for organization.
Key Principles
- Components remain theme-agnostic (no theme logic in component code)
- Semantic tokens provide indirection between theme and components
- Only override Tier 2 semantic tokens in
class, never Tier 1 core tokens.dark - Theme switching is instant (just CSS variable changes)
For complete implementation examples, see examples/theming.md.
Additional Patterns
The following patterns are documented with full examples in the examples/ folder:
- Pattern 5: SCSS Module Structure with Cascade Layers - examples/patterns.md
- Pattern 6: Spacing System with Semantic Tokens - examples/tokens.md
- Pattern 7: Typography System with REM-Based Sizing - examples/tokens.md
- Pattern 8: Data-Attributes for State Styling - examples/patterns.md
- Pattern 9: SCSS Mixins for Reusable Patterns - examples/patterns.md
- Pattern 10: Global Styles Organization - examples/patterns.md
- Pattern 11: Icon Styling - examples/patterns.md
- Pattern 12: cva Integration - examples/cva.md
- Pattern 13: Advanced CSS Features - examples/advanced.md
- Pattern 14: Sass Module System (@use and @forward) - examples/modules.md
<red_flags>
RED FLAGS
For complete anti-patterns and red flags, see reference.md.
High Priority Issues:
- Using core tokens directly in components (use semantic tokens)
- Component styles not wrapped in
@layer components {} - Using Sass color functions (
,darken()
)lighten() - Hardcoded color/spacing values
- Theme logic in components
- Using
instead of@import
(deprecated in Dart Sass 1.80.0, removed in 3.0.0)@use - Using
for division instead of/
(deprecated)math.div()
</red_flags>
<critical_reminders>
CRITICAL REMINDERS
All code must follow project conventions in CLAUDE.md
(You MUST wrap ALL UI package component styles in
for proper cascade precedence)@layer components {}
(You MUST use semantic tokens ONLY in components - NEVER use core tokens directly)
(You MUST use HSL format for colors with CSS color functions - NO Sass color functions like darken/lighten)
(You MUST use data-attributes for state styling - NOT className toggling)
(You MUST use
for imports - @use
is deprecated and will be removed in Dart Sass 3.0.0)@import
Failure to follow these rules will break theming, create cascade precedence issues, and violate design system conventions.
</critical_reminders>