CSS Pro Max
This skill consolidates production-grade guidance for CSS and UI work on the modern web. It covers layout and responsive strategy, spacing and whitespace rhythm, design-system terminology, motion, typography, visual-detail polish, accessibility baselines, foundation CSS architecture, token systems, color systems, and z-axis layering rules. The guidance is opinionated: when there is a preferred default, it is stated.
Each concept has exactly one canonical reference. Other references link to it rather than restating it — open the canonical file when you need to change or cite a rule.
When to use
Apply this skill for any task that touches CSS, markup that implies CSS responsibilities, or the look-and-feel quality of a product:
- Writing CSS for a component, page, or design system.
- Choosing padding, gaps, section rhythm, gutters, or spacing scale steps.
- Choosing a layout strategy: intrinsic sizing, flex, grid, container queries, media queries, or viewport units.
- Naming components, tokens, or layers inside a design system.
- Designing animations, transitions, scroll-linked motion, or
@keyframes. - Configuring typography (font stack, kerning, line-height, text-wrap, fluid type, Japanese-specific features).
- Polishing interactive UI: border radius, shadows, icon animation, staggered enters, tabular numerals.
- Auditing a UI for accessibility.
- Deciding
pxvsrem, physical vs logical properties, shorthand vs longhand, viewport vs container units.
When not to use
Skip this skill for pure backend logic, database schema work, API design decoupled from UI, non-visual scripts, or infrastructure and DevOps work.
Decision rule: if the change affects how a feature looks, feels, moves, or is interacted with, open this skill.
Core principles
- CSS is a suggestion, not a command. Let the engine handle what it does well (intrinsic sizing, wrapping, auto-fit grids) before reaching for queries or fixed values.
- Keep an intrinsic baseline. Responsive work starts with contracting/expanding behavior and flexibility; queries are escalation tools, not the default.
- Use the escalation order. Static → intrinsic → container query → media query. Do not jump to media queries before exhausting intrinsic layout.
- Prefer logical properties where the layout primitive is logical. Flex and grid already think in inline/block axes; match them. Stay physical where the spec is physical (transforms, backgrounds, media queries).
- Name by responsibility, never by appearance. A
<button>is aButton, an<a>is aLink, even if it looks like a button. Structure, behaviour, and HTML element dictate the name. - Motion must earn its place. Classify each animation as functional or decorative. When in doubt, remove it. The fastest animation is no animation.
- Write defensively. Assume text doubles in length, images fail to load, content is edited by a CMS, and users scale fonts. Build for the 80% that breaks in production.
- Accessibility is not optional. Contrast, focus visibility, touch-target size, keyboard order,
prefers-reduced-motion, and screen-reader labels are hard requirements, not nice-to-haves. - Progressive enhancement over hard gates. Ship modern features (View Transitions,
text-wrap: pretty,text-box-trim,word-break: auto-phrase,field-sizing) when they degrade gracefully; avoid features that silently break layout where unsupported. - Details compound into quality. Concentric radii, optical alignment, layered shadows, tabular numerals, staggered enters, and a
40×40minimum hit area add up to what "feels polished".
Decision flow — which reference should I open?
| Task | Open |
|---|---|
| Picking between intrinsic, container query, media query, or viewport units | responsive |
Computing a fluid clamp() or a breakpoint from calc() |
responsive |
| Naming a component, wrapper, navigation, menu, template, pattern, or theme | terminology |
| Deciding whether an animation is needed at all, or choosing easing/duration | animations |
Implementing prefers-reduced-motion branches in CSS |
animations |
Writing @keyframes (naming, scope, API-style custom properties, global vs local) |
keyframes |
| Setting up a font stack, text-wrap, kerning, measure, or fluid type (especially Japanese) | typography |
| Applying polish details: radii, shadows, staggered enters, icon cross-fade, tabular numerals | visual-details |
Verifying contrast, focus visibility, hit area, prefers-reduced-motion policy, ARIA, or keyboard operability |
accessibility |
| Defining global stack order for overlays, dialogs, and fixed surfaces | z-index |
| Designing reset policy, cascade layers, and low-specificity base | foundation |
| Designing token naming, scales, and API-style custom-property contracts | tokens |
| Building palette scales, text hierarchy color rules, and dark-mode color ladders | color |
Spacing scale, gap vs margin, grid vs flex for rhythm, gutters, responsive steps, negative margins |
spacing |
Loading directives (MANDATORY / Do NOT Load)
Use this section to avoid both under-loading and over-loading references.
Responsive symptoms
- MANDATORY - READ responsive.md when layout breaks by container width, query thresholds are unclear, or
clamp()math needs recalculation. - Do NOT Load animations.md first for layout collapse issues; motion tuning does not fix structural width/flow bugs.
Typography symptoms
- MANDATORY - READ typography.md when text is hard to read, line breaks are awkward, or Japanese/English mixed text looks uneven.
- Do NOT Load visual-details.md first for readability issues; shadows/radii cannot recover poor text rhythm.
Motion symptoms
- MANDATORY - READ animations.md when interaction feedback feels slow, distracting, or accessibility complaints mention motion sickness.
- Do NOT Load keyframes.md first unless
@keyframesdesign itself is the problem; many issues are solved by timing/easing policy.
Layering symptoms
- MANDATORY - READ z-index.md when headers/modals/toasts overlap incorrectly, or fixes start introducing large
z-indexnumbers. - Do NOT Load responsive.md first for pure stacking-order conflicts; width logic does not solve z-axis governance.
Foundation symptoms
- MANDATORY - READ foundation.md when global CSS precedence, reset side effects, or third-party style collisions appear.
- Do NOT Load visual-details.md first for cascade-order bugs; polish details do not fix layer architecture.
Token symptoms
- MANDATORY - READ tokens.md when naming scales drift, literals spread, or component APIs expose inconsistent custom properties.
- Do NOT Load terminology.md first for token-contract issues; naming vocabulary is not token governance.
Color-system symptoms
- MANDATORY - READ color.md when text hierarchy is unclear, palettes are ad hoc, or dark mode appears visually unstable.
- Do NOT Load typography.md first for palette-architecture issues; type rhythm does not replace color-system design.
Spacing symptoms
- MANDATORY - READ spacing.md when section rhythm is inconsistent, magic-number
marginspreads,gapvsmarginchoice is unclear, gutters ignore narrow viewports, or negative margins compensate for parent padding. - Do NOT Load spacing.md first when the issue is purely container-query threshold math with no whitespace policy change (open responsive.md first).
Reference map
| File | Responsibility | Canonical topics |
|---|---|---|
| responsive.md | Layout escalation | intrinsic → container → media, vw/vh ban, cqi, calc() breakpoints, fluid clamp() |
| typography.md | Readability and type | font stack, text-wrap, Japanese features, line-height, measure (45ch–75ch), font-variant-numeric, fluid type |
| animations.md | Motion strategy | easing/duration, transition-property: all ban, will-change, interruption, prefers-reduced-motion implementation |
| keyframes.md | @keyframes patterns |
dashed-ident naming, global vs local, API-style custom properties, paused + both scroll reveal |
| visual-details.md | Craft polish | concentric radii, optical alignment, layered shadows, staggered enters, exits, icon cross-fade, font smoothing, tabular numerals, image outlines, first-paint suppression |
| accessibility.md | A11y baseline | contrast, focus visibility, hit area, reduced-motion policy, keyboard, ARIA, hidden semantics, cursor: pointer |
| terminology.md | Naming contract and architecture | Element, Section, Container, Inner, Outer, layout primitive vocabulary, architecture terms (Composition / Utility / Block / Exception) |
| z-index.md | Z-axis layering governance | absolute vs relative layering, stack tokens, calc(infinity), stacking-context checks, top-layer usage |
| foundation.md | Base CSS architecture | reset scope, @layer order, low-specificity :where(), third-party CSS layering, a11y-safe base |
| tokens.md | Design-token contracts | naming grammar, family scales, global vs component aliasing, motion/depth token sets |
| color.md | Color-system strategy | HSL/OKLCH usage, palette scales, hierarchy by color+weight, dark-mode ladders, non-color redundancy |
| spacing.md | Whitespace rhythm | 8/4 base, scale steps, gap first, Grid for 2D rhythm, gutters vs gaps, responsive steps, negative-margin policy |
Global pre-delivery checklist
Run this before shipping. Each group points at its canonical reference; open that file for the full rule set and detailed checklists.
Responsive → responsive.md
- Escalation order honored (static → intrinsic → container → media).
- No
vworvh; logical viewport units chosen intentionally. - Container queries use
container: --name / inline-size. - Range syntax with
calc()thresholds; novar()inside@media/@containerconditions. -
width: 100%/height: 100%justified;min-width: 0guards present where needed. - Fluid
clamp()retains aremminimum.
Terminology → terminology.md
- Canonical vocabulary used (
Inner,Outer,Gutter,Gap,Navigation,Menu,Pattern,Component,Template,Theme). -
Containerreserved for the CSScontainerfeature. -
ButtonvsLinkfollows the HTML element, not appearance.
Typography → typography.md
- Body
line-height ≥ 1.5; headings between1.1and1.3. - Headings use
text-wrap: balance; Japanese body avoidstext-wrap: pretty. - Japanese headings apply
palt/vpal;font-kerningfollows the:lang(en)/:lang(ja)rule. - Prose is bounded to
45ch–75ch. - Numeric UI uses
font-variant-numeric: tabular-nums. - Fluid type keeps a
remfloor.
Animation → animations.md
- Every animation is classified as functional or decorative.
- Functional durations ≤
300ms; large surfaces ≤500ms. -
transition-property: allis never used. -
will-changeis scoped and temporary. -
prefers-reduced-motionbranches match the tier policy (policy in accessibility.md).
Keyframes → keyframes.md
-
@keyframesnames are dashed idents. - Globals live in
base/keyframes.css; component-local follow--{component}--{animation}. - Scroll-linked reveals use
animation-fill-mode: both+animation-play-state: paused.
Visual details → visual-details.md
- Nested rounded elements satisfy
outer-radius = inner-radius + padding. - Shadows are layered (top / contact / ambient) with dark-mode variants.
- Lists and menus use staggered enters (~`100
ms step, total ≤300` ms). - Every enter has a matching exit (
60–80%duration, reversed easing). - Icon swaps cross-fade with opacity / scale / blur.
- Live numerals use tabular numerals.
- Images on pale surfaces carry a
0.1-alpha inner outline. - Animations do not run on first paint.
Accessibility → accessibility.md
- Contrast
≥ 4.5:1body /≥ 3:1large, in both themes. - Every interactive element has a visible focus ring via
:focus-visible. - Hit area
≥ 40×40web (44×44pt iOS /48×48dp Android). - Reduced-motion honored per tier.
- Keyboard reachable in source order; no traps.
- Color is never the sole channel for error / success / warning / chart series.
- ARIA: native elements preferred; icon-only controls carry accessible names.
- Hidden strategy (
display: none/visibility: hidden/.visually-hidden/aria-hidden) chosen deliberately.
Z-index → z-index.md
- Global absolute layers are tokenized and centrally managed.
- Component-local layering uses relative rules (
0/1) unless exception is justified. - No large magic-number
z-indexvalues are introduced. - Stacking-context prerequisites are verified before numeric changes.
Foundation → foundation.md
- Layer order is explicit and stable (
reset→tokens→base→components→utilities→overrides). - Base selectors stay low-specificity (
:where()where appropriate). - Reset strategy preserves useful UA defaults and focus visibility.
- Third-party CSS precedence is controlled by layers, not selector inflation.
Tokens → tokens.md
- Token names follow one grammar and family taxonomy.
- Component aliases map to global tokens; deep alias chains are avoided.
- New literals are justified; reusable values are tokenized.
- Motion/depth/z-axis token families stay aligned with their canonical references.
Color system → color.md
- Palette groups have shade scales instead of single ad hoc values.
- Text hierarchy uses color plus weight, not size alone.
- Colored backgrounds use context-aware foreground choices.
- Dark mode uses dedicated ladders; color is not the sole communication channel.
Spacing → spacing.md
- Rhythm uses the canonical scale; 8-based layout, 4 only for micro internals.
- Narrow and wide viewports use appropriate gutter/step choices, not one fixed literal everywhere.
- Sibling/cell spacing uses
gapon Flex/Grid where possible; Grid for 2D rhythm, Flex for single-axis stacks. -
GutterandGapare not conflated (terminology.md). - No habitual negative margins to undo parent padding; full-bleed uses layout structure.
Anti-patterns with why
- NEVER jump straight to media queries for component-level breakage, because it locks components to viewport assumptions and increases regression risk when placement changes.
- NEVER use
transition-property: all, because unrelated properties animate unintentionally and create avoidable paint/layout work. - NEVER name by appearance (
PrimaryButtonLikeLink), because semantics drift and the same component becomes unmaintainable across contexts. - NEVER ship decorative high-frequency motion by default, because repeated exposure adds interaction friction and raises reduced-motion accessibility risk.
- NEVER treat typography as visual garnish, because readability defects cannot be compensated later by spacing, color, or motion polish.
- NEVER use chained child
marginfor rhythmic lists when a Flex/Grid parent could owngap, because collapsing, wrapping, and last-item hacks multiply. - NEVER use negative margins routinely to cancel parent
padding, because structure becomes opaque andoverflowclipping breaks layouts silently.
Fallback mini-playbook
Use this when quality drops late in implementation and you need a deterministic recovery path.
Responsive fallback
- Revert to intrinsic layout first (
wrap,minmax,max-inline-size) and remove non-essential queries. - Re-introduce one named container query at a time with explicit
calc()thresholds. - If still unstable, temporarily freeze to a safe single-column variant and re-expand after thresholds are recalculated.
Typography fallback
- Restore body baseline (
line-height >= 1.5, measure around45ch-75ch,remfloor in fluid type). - Disable aggressive features (
text-wrap: prettyon Japanese body, over-tight kerning) and validate readability first. - Re-apply advanced features (
palt/vpal,auto-phrase) only where they improve headings without harming body text.
Animation fallback
- Keep only functional motion (feedback/state continuity); remove decorative enters first.
- Cap duration (
<= 300mscommon UI,<= 500mslarge surfaces) and switch to strong ease-out/ease-in-out curves. - If instability remains, reduce to opacity-only transitions and enforce reduced-motion branches before reintroducing transform effects.