| name | optics-context |
| description | Use the Optics design framework for styling applications. Apply Optics classes for layout, spacing, typography, colors, and components. Use when working on CSS, styling views, or implementing design system guidelines. |
| metadata | {"triggers":"slim, css, frontend, design-system, optics"} |
Optics Design Framework
Apply the Optics design system for consistent, token-based styling in Rails applications.
Core Principles
- Use tokens, not hard-coded values - All colors, spacing, typography from
assets/tokens.json
- Follow BEM structure - Block, Element, Modifier naming conventions
- Check existing components first - Reuse before creating new
- Progressive enhancement - Start with semantic HTML, layer styles
Finding Optics Classes
Search for components in this order:
- Check Optics components -
skills/optics-context/assets/components.json
- Find appropriate component, modifiers, and attributes
- Modify using BEM if needed
- Search project styles - Look in
app/assets/stylesheets for existing classes
- Create new component - Only if nothing exists (see "Creating Components" below)
Using Optics Tokens
Always use CSS custom properties from assets/tokens.json:
- Colors:
var(--op-color-primary-base), var(--op-color-background)
- Spacing:
var(--op-space-small), var(--op-space-medium), var(--op-space-large)
- Typography:
var(--op-font-medium), var(--op-line-height-base)
- Borders:
var(--op-radius-small), var(--op-border-width)
- Shadows:
var(--op-shadow-small), var(--op-shadow-medium)
Detecting Violations
Never use hard-coded values:
❌ Colors: #fff, #000, rgb(...), rgba(...), hsl(...), color names like white, black ❌ Spacing: Bare px, rem, em values in padding, margin, gap ❌ Shadows: box-shadow: 0 1px 3px rgba(...) ❌ Borders: border: 1px solid #ddd ❌ Gradients: linear-gradient(...) with literal colors
Common token mistakes:
❌ var(--op_color_primary_base) - Wrong separator (underscore instead of hyphen) ❌ var(--color-primary-base) - Missing --op- prefix ❌ var(--op-primary-color-base) - Wrong segment order
✅ var(--op-color-primary-base) - Correct format
Fix violations by replacing with tokens from assets/tokens.json
BEM Structure
Block, Element, Modifier naming:
.block {
}
.block__element {
}
.block--modifier {
}
.block__element--modifier {
}
Nest modifiers and elements:
.card {
&.card--padded {
}
.card__header {
}
}
Creating Components
File organization:
- Create CSS file:
app/assets/stylesheets/components/{component-name}.css
- Or override:
app/assets/stylesheets/components/overrides/{component-name}.css
- Import in
application.scss
Component structure:
- Define base block with semantic name
- Add nested elements (parts of component)
- Add modifiers (variants)
- Use only Optics tokens
- One component per file unless tightly coupled
Example - Card component:
.card {
position: relative;
border-radius: var(--op-radius-medium);
background-color: var(--op-color-background);
box-shadow: var(--op-shadow-small);
&.card--padded {
padding: var(--op-space-medium);
}
&.card--elevated {
box-shadow: var(--op-shadow-large);
}
.card__header {
padding: var(--op-space-medium);
border-bottom: var(--op-border-width) solid var(--op-color-border);
border-start-start-radius: var(--op-radius-medium);
border-start-end-radius: var(--op-radius-medium);
}
.card__body {
padding: var(--op-space-medium);
}
.card__footer {
padding: var(--op-space-medium);
border-top: var(--op-border-width) solid var(--op-color-border);
border-end-start-radius: var(--op-radius-medium);
border-end-end-radius: var(--op-radius-medium);
}
}
Example - Button component:
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
padding: var(--op-space-small) var(--op-space-medium);
font-size: var(--op-font-medium);
font-weight: var(--op-font-weight-medium);
border-radius: var(--op-radius-small);
border: var(--op-border-width) solid transparent;
cursor: pointer;
transition: all 0.2s ease;
&:hover {
opacity: 0.9;
}
&.btn--large {
padding: var(--op-space-medium) var(--op-space-large);
font-size: var(--op-font-large);
}
&.btn--small {
padding: var(--op-space-x-small) var(--op-space-small);
font-size: var(--op-font-small);
}
&.btn--disabled,
&:disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
}
&.btn--primary {
background-color: var(--op-color-primary-base);
color: var(--op-color-primary-on-base);
&:hover {
background-color: var(--op-color-primary-plus-two);
color: var(--op-color-primary-on-plus-two);
}
}
&.btn--secondary {
background-color: var(--op-color-neutral-base);
color: var(--op-color-neutral-on-base);
&:hover {
background-color: var(--op-color-neutral-plus-two);
color: var(--op-color-neutral-on-plus-two);
}
}
&.btn--outline {
background-color: transparent;
border-color: var(--op-color-border);
color: var(--op-color-neutral-on-plus-max);
&:hover {
border-color: var(--op-color-primary-base);
}
}
Creating Custom Tokens
First ensure there isn't an existing token that fits your need When tokens are missing, create component-specific ones:
Project-specific tokens (preferred for custom needs):
- Use namespace prefix:
--{project-prefix}-{category}-{name}
- Example:
--ya-color-brand-accent for "Your App" project
- Keeps project tokens separate from core Optics
Token categories:
- Color:
--op-color-{name} or --{prefix}-color-{name}
- Spacing:
--op-space-{size} or --{prefix}-space-{size}
- Typography:
--op-font-{property}-{value}
- Border:
--op-radius-{size}, --op-border-{property}
- Shadow:
--op-shadow-{size}
Quick Reference
Discovery workflow:
- Check
assets/components.json for existing component
- Search
app/assets/stylesheets for project styles
- Create new component with Optics tokens
Token workflow:
- Check
assets/tokens.json for appropriate token
- Use token in CSS:
var(--op-category-name)
- Create custom token if needed (use project prefix)
Component workflow:
- Create CSS file in
components/ or components/overrides/
- Define block with base styles
- Add nested elements and modifiers
- Use only Optics tokens (no hard-coded values)
- Import in
application.scss
See assets/components.json for available Optics components and assets/tokens.json for all design tokens.