Game Loopers CSS BEM Audit & Refactor Skill
Skill Name
css-bem-auditor
Purpose
Audit, normalize, and refactor CSS across the Game Loopers application to comply with the project's BEM (Block–Element–Modifier) methodology and design system, ensuring maintainability, consistency, and scalability.
This skill identifies non-compliant selectors, design token violations, naming collisions, overly-specific rules, and architectural inconsistencies, then proposes or applies BEM-aligned fixes specific to Game Loopers.
Critical: This project uses strict BEM with NO utility-first CSS (no Tailwind, no inline utilities). All styles must use component-scoped CSS with BEM naming.
Scope
This skill operates on:
- Astro component styles (
.astrofiles with<style>blocks) - SolidJS component stylesheets (
.tsxfiles with co-located.cssfiles) - Global stylesheets (
/src/styles/global.css) - Component-specific CSS files (e.g.,
product-files-form.css)
It does not redesign UI or change visual intent unless explicitly requested.
Design System Reference
Game Loopers has a comprehensive design system defined in DESIGN_SYSTEM.md (co-located in this directory). All CSS must comply with:
Color System (CSS Custom Properties)
Semantic Colors:
--primary /* Black in light mode */
--primary-foreground /* White text on primary */
--secondary /* Light gray */
--secondary-foreground
--destructive /* Red for errors/delete */
--destructive-foreground
--accent /* Highlights, hover states */
--accent-foreground
--background /* Page background */
--foreground /* Primary text */
--card /* Card backgrounds */
--card-foreground
--muted /* Low emphasis backgrounds */
--muted-foreground /* Secondary text */
--border /* Default borders */
--input /* Input borders */
--ring /* Focus ring color */
Status Colors:
--color-success /* Green - confirmations */
--color-success-foreground
--color-warning /* Yellow - cautions */
--color-warning-foreground
--color-error /* Red - failures */
--color-error-foreground
--color-info /* Blue - notifications */
--color-info-foreground
Typography Scale
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
--text-3xl: 1.875rem; /* 30px */
--text-4xl: 2.25rem; /* 36px */
--text-5xl: 3rem; /* 48px */
--font-weight-normal: 400;
--font-weight-medium: 500;
--font-weight-semibold: 600;
--font-weight-bold: 700;
--leading-tight: 1.25;
--leading-snug: 1.375;
--leading-normal: 1.5;
--leading-relaxed: 1.625;
Spacing Scale (8px Grid)
--spacing-xs: 0.25rem; /* 4px */
--spacing-sm: 0.5rem; /* 8px */
--spacing-md: 1rem; /* 16px */
--spacing-lg: 1.5rem; /* 24px */
--spacing-xl: 2rem; /* 32px */
--spacing-2xl: 3rem; /* 48px */
--spacing-3xl: 4rem; /* 64px */
--spacing-4xl: 6rem; /* 96px */
--gap-xs: 0.25rem;
--gap-sm: 0.5rem;
--gap-md: 1rem;
--gap-lg: 1.5rem;
--gap-xl: 2rem;
--gap-2xl: 3rem;
Border Radius
--radius-sm: 0.125rem; /* 2px */
--radius-md: 0.375rem; /* 6px */
--radius-lg: 0.5rem; /* 8px */
--radius-xl: 0.75rem; /* 12px */
--radius-2xl: 1rem; /* 16px */
--radius-full: 9999px; /* Fully rounded */
Shadows
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
BEM Rules Enforced
Naming Convention
.block {}
.block__element {}
.block--modifier {}
.block__element--modifier {}
Block Naming:
- Lowercase only
- Hyphens for word separation (e.g.,
.product-card,.browse-cta) - Describes component purpose
Element Naming:
- Double underscore (
__) separates block from element - Lowercase with hyphens (e.g.,
.button__text,.card__header)
Modifier Naming:
- Double hyphen (
--) separates block/element from modifier - Lowercase with hyphens (e.g.,
.button--primary,.card--elevated)
Existing BEM Blocks (Reference)
Core Components:
.button(Button.astro).card(Card.astro).page-header(PageHeader.astro).navigation(Navigation.astro).browse-cta(BrowseCTA.astro)
Browse Components (global.css):
.browse-search.browse-tags.browse-grid.browse-card.browse-empty.browse-pagination
Product Components:
.product-chat.add-to-cart.add-to-cart-modal.product-documents-form.document-list.product-contributors.price-breakdown.status-editor.status-badge.revenue-preview.royalty-breakdown.product-files-form.product-royalty-breakdown.product-status-editor.product-embeddable-toggle.product-embedded-products
Document Components:
.document-chat
Interactive Components:
.confirm-dialog.modal-overlay,.modal-content,.modal-header,.modal-body
Prohibited Patterns
❌ Strictly Forbidden:
/* NO Tailwind-style utilities */
.flex { display: flex; }
.text-center { text-align: center; }
.mt-4 { margin-top: 1rem; }
/* NO chained selectors (breaks BEM) */
.card .title { }
.button .icon { }
/* NO tag-qualified classes */
div.card { }
a.button { }
/* NO ID selectors */
#header { }
/* NO deep nesting beyond 2 levels */
.card__header__title__icon { } /* Too deep */
/* NO generic state classes without block context */
.is-active { } /* Use .button--active instead */
.has-error { } /* Use .input--error instead */
/* NO hardcoded colors/sizes (use design tokens) */
.card {
color: #333; /* ❌ Use var(--foreground) */
padding: 24px; /* ❌ Use var(--spacing-lg) */
border-radius: 8px; /* ❌ Use var(--radius-lg) */
}
Allowed Patterns
✅ Correct Usage:
/* Flat class selectors with design tokens */
.card {
background-color: var(--card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: var(--spacing-3xl);
}
/* Explicit block ownership */
.card__title {
font-size: var(--text-xl);
font-weight: var(--font-weight-semibold);
color: var(--card-foreground);
}
/* Boolean and value modifiers */
.button--primary { }
.button--lg { }
.card--elevated { }
/* Pseudo-states on BEM classes */
.button:hover { }
.button:focus-visible { }
.button:disabled { }
/* Global page utilities (limited exceptions) */
.page { }
.page__container { }
/* Third-party libraries (unmodifiable) */
.tiptap { }
.astro-* { }
Audit Process
1. Inventory Phase
- Extract all class selectors from
.astroand.cssfiles - Map class usage across templates (Astro pages, SolidJS islands)
- Identify design token violations (hardcoded colors, spacing, typography)
- Detect duplicates and collisions
- Find orphaned selectors (defined but not used)
2. Classification Phase
Each selector is categorized as:
- Block (component root)
- Element (component part)
- Modifier (component variation)
- Global Utility (allowed:
.page,.page__container) - Third-party (allowed:
.tiptap,.astro-*) - Invalid (Tailwind-style utilities, non-BEM patterns)
3. Violation Detection
Naming Violations:
- Incorrect separator usage (
_instead of__,-instead of--) - CamelCase or snake_case naming
- Too-deep element nesting (
.block__element__subelement)
Design Token Violations:
- Hardcoded colors instead of
var(--primary), `var(--muted-f