Files
rspade_system/docs/skills/scss/SKILL.md
root 1b46c5270c Add skills documentation and misc updates
Add form value persistence across cache revalidation re-renders

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-29 04:38:06 +00:00

252 lines
5.3 KiB
Markdown
Executable File

---
name: scss
description: SCSS styling architecture in RSX including component scoping, BEM naming, responsive breakpoints, and variables. Use when writing SCSS files, styling components, working with responsive design, or troubleshooting CSS conflicts.
---
# RSX SCSS Architecture
## Component-First Philosophy
Every styled element is a component with scoped SCSS. No CSS spaghetti - no generic classes like `.page-header` scattered across files.
**Pattern vs Unique Decision**:
- If you're copy-pasting markup, extract a component
- Reusable structures → shared component with slots
- One-off structures → page-specific component
---
## Directory Rules
| Location | Purpose | Scoping |
|----------|---------|---------|
| `rsx/app/` | Feature components | Must wrap in component class |
| `rsx/theme/components/` | Shared components | Must wrap in component class |
| `rsx/theme/` (outside components/) | Primitives, variables, Bootstrap overrides | Global |
| `rsx/lib/` | Non-visual utilities | No styles |
---
## Component Scoping (Required)
SCSS in `rsx/app/` and `rsx/theme/components/` **must** wrap in a single component class:
```scss
// dashboard_index_action.scss
.Dashboard_Index_Action {
padding: 2rem;
.card {
margin-bottom: 1rem;
}
.stats-grid {
display: grid;
gap: 1rem;
}
}
```
- Wrapper class matches JS class or Blade `@rsx_id`
- Filename must match associated `.js` or `.blade.php` file
- Components auto-render with `class="Component_Name"` on root
---
## BEM Child Classes
Child classes use exact PascalCase component name as prefix:
```scss
.DataGrid_Kanban {
&__loading { /* .DataGrid_Kanban__loading */ }
&__board { /* .DataGrid_Kanban__board */ }
&__column { /* .DataGrid_Kanban__column */ }
}
```
```html
<!-- Correct -->
<div class="DataGrid_Kanban__loading">
<!-- WRONG - kebab-case doesn't match compiled CSS -->
<div class="datagrid-kanban__loading"> <!-- No styles! -->
```
**No kebab-case** in component BEM classes.
---
## Variables
Define in `rsx/theme/variables.scss`. **Check this file before writing new SCSS.**
In bundles, variables.scss must be included before directory includes:
```php
'include' => [
'rsx/theme/variables.scss', // First
'rsx/theme', // Then directories
'rsx/app/frontend',
],
```
Variables can be declared outside the wrapper for sharing:
```scss
// frontend_spa_layout.scss
$sidebar-width: 215px;
$header-height: 57px;
.Frontend_Spa_Layout {
.sidebar { width: $sidebar-width; }
}
```
---
## Variables-Only Files
Files with only `$var: value;` declarations (no selectors) are valid without wrapper:
```scss
// _variables.scss
$primary-color: #0d6efd;
$border-radius: 0.375rem;
```
---
## Supplemental SCSS Files
Split large SCSS by breakpoint or feature:
```
frontend_spa_layout.scss # Primary (required)
frontend_spa_layout_mobile.scss # Supplemental
frontend_spa_layout_print.scss # Supplemental
```
Supplemental files use the **same wrapper class** as primary:
```scss
// frontend_spa_layout_mobile.scss
.Frontend_Spa_Layout {
@media (max-width: 768px) {
.sidebar { width: 100%; }
}
}
```
---
## Responsive Breakpoints
RSX replaces Bootstrap breakpoints. **Bootstrap's `.col-md-6`, `.d-lg-none` do NOT work.**
### Tier 1 (Simple)
| Name | Range |
|------|-------|
| `mobile` | 0-1023px |
| `desktop` | 1024px+ |
### Tier 2 (Granular)
| Name | Range |
|------|-------|
| `phone` | 0-799px |
| `tablet` | 800-1023px |
| `desktop-sm` | 1024-1199px |
| `desktop-md` | 1200-1639px |
| `desktop-lg` | 1640-2199px |
| `desktop-xl` | 2200px+ |
### SCSS Mixins
```scss
.Component {
padding: 2rem;
@include mobile {
padding: 1rem;
}
@include phone {
padding: 0.5rem;
}
@include desktop-xl {
max-width: 1800px;
}
}
```
### Utility Classes
```html
<div class="col-mobile-12 col-desktop-6">...</div>
<div class="d-mobile-none">Hidden on mobile</div>
<div class="mobile-only">Only visible on mobile</div>
<div class="hide-tablet">Hidden on tablet only</div>
```
### JavaScript Detection
```javascript
if (Responsive.is_mobile()) {
// Mobile behavior
}
if (Responsive.is_desktop_xl()) {
// Extra large desktop
}
```
---
## Slot-Based Composition
Use slots to separate structure from content:
```jqhtml
<Define:Datagrid_Card>
<div class="card">
<div class="card-header"><%= content('toolbar') %></div>
<div class="card-body"><%= content('body') %></div>
</div>
</Define:Datagrid_Card>
<!-- Usage -->
<Datagrid_Card>
<Slot:toolbar><button>Add</button></Slot:toolbar>
<Slot:body><My_Datagrid /></Slot:body>
</Datagrid_Card>
```
Component owns layout/styling; pages provide content via slots.
---
## What Remains Shared (Unscoped)
Only primitives should be unscoped:
- Buttons (`.btn-primary`, `.btn-secondary`)
- Spacing utilities (`.mb-3`, `.p-2`)
- Typography (`.text-muted`, `.fw-bold`)
- Bootstrap overrides
Everything else → component-scoped SCSS.
---
## No Exemptions
There are **no exemptions** to scoping rules for files in `rsx/app/` or `rsx/theme/components/`. If a file can't be associated with a component, it likely belongs in:
- `rsx/theme/base/` for global utilities
- A dedicated partial imported via `@use`
## More Information
Details: `php artisan rsx:man scss`, `php artisan rsx:man responsive`