skill · sumi · v0.6.1
CSS Architecture
Modern CSS architecture for any stack (plain CSS, SCSS, Tailwind v4, scoped Vue/Svelte styles, CSS Modules) — tokens as custom properties from DESIGN.md, cascade layers, naming, specificity, intrinsic and fluid layout, container queries, logical properties, modern selectors, dark mode and reduced motion. Use when writing or reviewing *.css, *.scss, style blocks, Tailwind classes or theme config, or when layout/responsiveness/theming is involved.
- Reference
- sumi
- skill
- css-architecture
- source
- plugins/sumi/skills/css-architecture/SKILL.md
CSS is a design system's runtime. Every visual value comes from a token; layout is intrinsic first and responsive second; specificity stays flat.
Tokens
- All colors, font families, type sizes, spacing, radii, shadows, z-indexes, durations and easings are CSS custom properties generated from
DESIGN.md. Hardcoded values in components are bugs. - Two layers: primitives (
--color-clay-600) and semantic roles (--color-surface,--color-text-muted,--color-accent). Components consume roles only, so themes and dark mode swap roles, not components. - Tailwind v4: tokens live in
@themein CSS; never sprinkle arbitrary values (text-[17px],bg-[#3a2f2a]) — add a token. - Shopify/WordPress: map merchant/editor settings to the same custom properties (
--section-padding-block) instead of inline styles.
Cascade and specificity
- Use
@layer reset, tokens, base, layout, components, utilities, overrides;to make order explicit. - Target specificity 0-1-0: one class per selector. No IDs, no
!important(except utilities layer by design), no qualifying (div.card). - Naming: follow the project. In plain CSS/SCSS without scoping, use BEM (
.card,.card__title,.card--featured) with max one level of nesting. In scoped/module/utility systems, no BEM needed. :where()to zero specificity in base styles;:is()to group;:has()for parent/state styling (keep the subject element narrow for performance).
Layout
- Intrinsic first: flexbox and grid with
minmax(),auto-fit,min(),clamp()remove most breakpoints. - Component-level responsiveness with container queries (
container-type: inline-size); viewport media queries for page-level layout only. - Mobile-first
min-widthqueries with a fixed breakpoint set from DESIGN.md (custom properties don't work inside media queries: use Sass variables,@custom-mediawith a build step, or Tailwind's--breakpoint-*theme keys), never ad-hoc pixel values. - Fluid type and spacing via
clamp()with a rem component so zoom still works. - Logical properties everywhere (
margin-inline,padding-block,inset-inline-start,text-align: start) — free RTL support. aspect-ratiofor media boxes;gapinstead of margins between siblings; avoid magic numbers.- Use
subgridto align card internals across a row.
Modern capabilities (use, with fallbacks where needed)
color-mix()and OKLCH for tints/shades and hover states derived from tokens.@starting-style+transition-behavior: allow-discretefor entry/exit of dialogs and popovers.- View Transitions API for page/state transitions as progressive enhancement.
- Scroll-driven animations only when they add meaning; always reduced-motion safe.
text-wrap: balancefor headings,text-wrap: prettyfor body.- Native nesting is fine; keep it one level deep.
Theming and preferences
- Dark mode swaps semantic roles under
[data-theme="dark"]and/orprefers-color-scheme. Never invert blindly; re-check contrast for every role pair. @media (prefers-reduced-motion: reduce)disables non-essential motion (keep opacity fades, drop transforms/parallax).- Respect
forced-colors: active: don't rely on backgrounds or shadows for meaning; use real borders/outlines. - Focus styles: visible
:focus-visibleoutline from a token (house rule: ≥ 2px, ≥ 3:1 contrast). Neveroutline: nonewithout a replacement.
SCSS specifics
- Module system only:
@use/@forward, never@import. Namespacedsass:math,sass:color. - SCSS for build-time helpers (mixins for breakpoints, functions for rem); runtime values stay custom properties.
- Partials organized by role (abstracts, base, layout, components, sections/pages). Stylelint with property ordering.
Slop tells
- Hardcoded hex colors, px font sizes and one-off spacing values; arbitrary Tailwind values.
z-index: 9999; stacking contexts created by accident;position: absoluteto fix layout problems.- Every element with the same radius and shadow regardless of role.
- Breakpoint soup instead of intrinsic layout; fixed heights on text containers.
- Duplicate declarations, unused selectors, deep nesting mirroring the DOM.
Done checklist
- No raw values outside the token definition files.
- Works from 320px to wide screens and at 200% zoom without horizontal scroll.
- Container queries for component responsiveness where the component is reused in different widths.
- Dark mode, reduced motion, forced colors and focus-visible verified.
- Stylelint/Prettier clean; no unused CSS shipped for the feature.