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.
71
66%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
Optimize this skill with Tessl
npx tessl skill review --optimize ./skills/optics-context/SKILL.mdApply the Optics design system for consistent, token-based styling in Rails applications.
assets/tokens.jsonSearch for components in this order:
skills/optics-context/assets/components.json
app/assets/stylesheets for existing classesAlways use CSS custom properties from assets/tokens.json:
var(--op-color-primary), var(--op-color-background)var(--op-space-small), var(--op-space-medium), var(--op-space-large)var(--op-font-size-base), var(--op-line-height-normal)var(--op-radius-small), var(--op-border-width)var(--op-shadow-small), var(--op-shadow-medium)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
Block, Element, Modifier naming:
.block {
} /* Component base */
.block__element {
} /* Part of component */
.block--modifier {
} /* Variant of component */
.block__element--modifier {
} /* Variant of element */Nest modifiers and elements:
.card {
/* Base styles */
&.card--padded {
/* Modifier */
}
.card__header {
/* Element */
}
}File organization:
app/assets/stylesheets/components/{component-name}.cssapp/assets/stylesheets/components/overrides/{component-name}.cssapplication.scssComponent structure:
Example - Card component:
.card {
position: relative;
border-radius: var(--op-radius-medium);
background-color: var(--op-color-background);
box-shadow: var(--op-shadow-small);
/* Modifiers */
&.card--padded {
padding: var(--op-space-medium);
}
&.card--elevated {
box-shadow: var(--op-shadow-large);
}
/* Elements */
.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-size-base);
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-size-large);
}
&.btn--small {
padding: var(--op-space-xsmall) var(--op-space-small);
font-size: var(--op-font-size-small);
}
&.btn--disabled,
&:disabled {
opacity: 0.5;
cursor: not-allowed;
pointer-events: none;
}
}
.btn.btn--primary {
background-color: var(--op-color-primary);
color: var(--op-color-on-primary);
&:hover {
background-color: var(--op-color-primary-hover);
}
}
.btn.btn--secondary {
background-color: var(--op-color-secondary);
color: var(--op-color-on-secondary);
&:hover {
background-color: var(--op-color-secondary-hover);
}
}
.btn.btn--outline {
background-color: transparent;
border-color: var(--op-color-border);
color: var(--op-color-text);
&:hover {
background-color: var(--op-color-background-hover);
}
}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):
--{project-prefix}-{category}-{name}--ya-color-brand-accent for "Your App" projectToken categories:
--op-color-{name} or --{prefix}-color-{name}--op-space-{size} or --{prefix}-space-{size}--op-font-{property}-{value}--op-radius-{size}, --op-border-{property}--op-shadow-{size}Discovery workflow:
assets/components.json for existing componentapp/assets/stylesheets for project stylesToken workflow:
assets/tokens.json for appropriate tokenvar(--op-category-name)Component workflow:
components/ or components/overrides/application.scssSee assets/components.json for available Optics components and assets/tokens.json for all design tokens.
097ad6b
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.