--- name: audit-style description: Audit and refactor CSS to comply with Game Loopers design system and BEM methodology --- # 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 (`.astro` files with ` ``` **AFTER (BEM Compliant)**: ```html

Title

Description

``` ### Example 2: Nested Selectors → Flat BEM **BEFORE (Violation)**: ```css .card .header .title { font-size: 20px; } .card.active { border-color: blue; } .card .footer button { padding: 12px 24px; } ``` **AFTER (BEM Compliant)**: ```css .card__title { font-size: var(--text-xl); } .card--active { border-color: var(--primary); } .card__footer-button { padding: var(--spacing-sm) var(--spacing-lg); } ``` ```html

Title

``` ### Example 3: Hardcoded Values → Design Tokens **BEFORE (Violations)**: ```css .product-card { background: #ffffff; color: #333333; border: 1px solid #e0e0e0; padding: 16px 24px; margin-bottom: 32px; border-radius: 8px; font-size: 16px; line-height: 1.5; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .product-card__title { color: #000000; font-size: 24px; font-weight: 600; margin-bottom: 8px; } .product-card__description { color: #666666; font-size: 14px; line-height: 1.6; } .product-card:hover { box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } ``` **AFTER (Design Token Compliant)**: ```css .product-card { background: var(--card); color: var(--card-foreground); border: 1px solid var(--border); padding: var(--spacing-md) var(--spacing-lg); margin-bottom: var(--spacing-xl); border-radius: var(--radius-lg); font-size: var(--text-base); line-height: var(--leading-normal); box-shadow: var(--shadow-sm); } .product-card__title { color: var(--foreground); font-size: var(--text-2xl); font-weight: var(--font-weight-semibold); margin-bottom: var(--spacing-sm); } .product-card__description { color: var(--muted-foreground); font-size: var(--text-sm); line-height: var(--leading-relaxed); } .product-card:hover { box-shadow: var(--shadow-md); } ``` --- ## Component-Specific Patterns ### Button Component Pattern ```css /* Base button block */ .button { display: inline-flex; align-items: center; justify-content: center; padding: var(--spacing-sm) var(--spacing-lg); border-radius: var(--radius-md); font-size: var(--text-base); font-weight: var(--font-weight-medium); transition: background-color 150ms; } /* Variant modifiers */ .button--primary { background-color: var(--primary); color: var(--primary-foreground); } .button--secondary { background-color: var(--secondary); color: var(--secondary-foreground); } .button--destructive { background-color: var(--destructive); color: var(--destructive-foreground); } /* Size modifiers */ .button--sm { padding: var(--spacing-xs) var(--spacing-md); font-size: var(--text-sm); } .button--lg { padding: var(--spacing-md) var(--spacing-xl); font-size: var(--text-lg); } /* Elements */ .button__icon { margin-right: var(--spacing-xs); } .button__text { } /* States */ .button:hover { opacity: 0.9; } .button:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; } .button:disabled { opacity: 0.5; pointer-events: none; } ``` ### Modal Component Pattern ```css .modal-overlay { position: fixed; inset: 0; background: rgb(0 0 0 / 0.5); display: flex; align-items: center; justify-content: center; padding: var(--spacing-lg); z-index: 50; } .modal-content { background: var(--card); border-radius: var(--radius-xl); box-shadow: var(--shadow-xl); max-width: 32rem; width: 100%; max-height: 90vh; overflow-y: auto; } .modal-header { display: flex; justify-content: space-between; align-items: center; padding: var(--spacing-lg); border-bottom: 1px solid var(--border); } .modal-title { font-size: var(--text-xl); font-weight: var(--font-weight-semibold); color: var(--foreground); } .modal-close { padding: var(--spacing-xs); color: var(--muted-foreground); } .modal-close:hover { color: var(--foreground); } .modal-body { padding: var(--spacing-lg); } ``` --- ## Accessibility Compliance All CSS must support accessibility standards: ### Focus States ```css /* All interactive elements MUST have visible focus indicators */ .button:focus-visible, .browse-tags__tag:focus-visible, .navigation__link:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; } ``` ### Color Contrast - Body text: 4.5:1 minimum contrast ratio - Large text: 3:1 minimum contrast ratio - UI components: 3:1 against adjacent colors **All semantic color tokens meet WCAG 2.1 Level AA standards.** ### Screen Reader Compatibility ```css /* Hidden but accessible to screen readers */ .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border-width: 0; } /* Decorative elements should be hidden from screen readers via aria-hidden="true" */ /* No CSS-only hiding for interactive elements */ ``` --- ## File Organization CSS files must follow this structure: ``` src/ ├── styles/ │ └── global.css # Global styles, shared .browse-* classes ├── components/ │ ├── Button.astro #