Install
$ agentstack add skill-syo-m-fable5-skills-css-modules ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
CSS Modules
Files & naming
- One module per component, colocated:
UserCard.tsx+UserCard.module.css. - Class names: camelCase (
primaryButton, notprimary-button) — enablesstyles.primaryButtonwithout bracket access. - Name by role, not appearance:
.errorMessagenot.redText. The module scope already namespaces — no BEM prefixes needed. - Import as
styles:import styles from './UserCard.module.css'.
Design tokens — single source of truth
- All colors, spacing, radii, shadows, typography, z-index live as CSS custom properties in
src/styles/tokens.css, defined on:root. - Component modules consume tokens only — the semantic/component tier where tiers exist (see
design-system), never primitives like--blue-600. A raw hex/px value for a themable property in a component module is a bug. - Spacing on a scale (
--space-1…--space-8); z-index from a fixed ladder (--z-dropdown,--z-modal,--z-toast) — neverz-index: 9999. - Theming (dark mode) by redefining tokens — components never branch on theme themselves. Default to
prefers-color-scheme; add[data-theme]only when a user-facing toggle is required, set pre-paint by a tiny inline script (CSP nonce applies — seefrontend-security) to avoid a wrong-theme flash.
Variants & state
- Variants via data attributes, not class string concatenation:
.button[data-variant='danger'] { background: var(--color-danger); }
- Boolean UI state the same way (
data-open,aria-expanded) — style off ARIA attributes when one exists:.menu[aria-expanded='true']. clsxhas exactly one job here: merging a consumer-passedclassNameprop with the base class. Enumerated variants and boolean state always go through data attributes, never conditional class lists; a component wanting 3+ conditional classes should be restructured into variants.
Layout & responsive
- Mobile-first: base styles, then
@media (min-width: …)upward. Breakpoints documented once intokens.csscomments (custom properties don't work in media queries — keep the canonical list there). - Prefer modern layout primitives: flex
gap/ grid over margin hacks;aspect-ratio; container queries for components that adapt to their container, media queries only for page-level layout. - Aspect-preserving media: give the box a defined
aspect-ratioand useobject-fit: contain/cover. Never size an image withmax-width/max-heightinside a flex item — the main-axis shrink sizes width independently of the height cap and stretches the image (a mixed-aspect-ratio thumbnail grid is where this bites). - Logical properties (
margin-inline,padding-block,inset-inline-start) over physical ones — free RTL support (the foundation thei18nskill builds on). - No fixed heights on text containers; min-height if needed.
Globals — the only allowed global CSS
src/styles/ contains exactly: tokens.css, reset.css, globals.css (base element styles: body, headings, links). Nothing else is global. No :global() in component modules except to target third-party library DOM you don't control — with a comment saying which library.
In Astro projects, the per-component styling primitive is the single-file scoped ` block instead of *.module.css — see astro`. The token/naming/variant rules here still apply.
Motion
- Animate
transformandopacityonly (compositor-friendly); never animatewidth/height/top/leftfor transitions. - Every significant animation (anything beyond a subtle hover/focus transition) respects
@media (prefers-reduced-motion: reduce)— same threshold as thea11yskill. - Durations/easings as tokens (
--duration-fast,--ease-out). - These are the invariants only — escalation (keyframes / WAAPI / animation libraries), View Transitions, entrance/exit animations, and scroll effects live in the
motionskill.
Enforcement
The token/var() and class-naming rules above are machine-enforced by Stylelint — see tooling for the exact rules and the shipped templates/stylelint.config.mjs.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Syo-M
- Source: Syo-M/fable5_skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.