一键导入
stylesheet-conventions
// Stylesheet organization, design token usage, light/dark mode, and CSS conventions for Spectrum Hub. Use when adding global styles, creating block CSS, or structuring new stylesheet files.
// Stylesheet organization, design token usage, light/dark mode, and CSS conventions for Spectrum Hub. Use when adding global styles, creating block CSS, or structuring new stylesheet files.
Scaffold and implement a new EDS block for Spectrum Hub. Use when adding a new block — covers file structure, the init(el) function contract, template injection, CSS conventions, and when to use templates vs per-page authoring vs fragments.
Implement WCAG 2.2 compliant interfaces with mobile accessibility, inclusive design patterns, and assistive technology support. Use when auditing accessibility, implementing ARIA patterns, building for screen readers, or ensuring inclusive user experiences.
Create conventional commit messages following best conventions. Use when committing code changes, writing commit messages, or formatting git history. Follows conventional commits specification.
| name | stylesheet-conventions |
| description | Stylesheet organization, design token usage, light/dark mode, and CSS conventions for Spectrum Hub. Use when adding global styles, creating block CSS, or structuring new stylesheet files. |
Use this skill when writing CSS for any part of Spectrum Hub — global styles, block stylesheets, or shared component styles.
create-new-blockThese two skills cover complementary halves of the same task:
| Skill | Owns |
|---|---|
create-new-block | File structure, init(el) contract, how loadBlock resolves and loads the CSS file, template injection, block authoring conventions (div soup, object syntax, BEM class names) |
stylesheet-conventions (this file) | What goes inside the CSS file — tokens, light/dark mode, layer cascade, nesting, media queries, shared stylesheets |
When creating a new block, use both. Start with create-new-block to set up the files and wire the JS. Then use this skill to write the block's CSS correctly.
Spectrum Hub uses a layered stylesheet approach inspired by ITCSS. Styles are separated by responsibility so that more specific rules always override more general ones without specificity hacks.
| File | Purpose |
|---|---|
styles/styles.css | Fonts, design tokens (CSS custom properties), base element styles, layout objects, utilities, and the spectrum-edge layer |
blocks/<name>/<name>.css | Styles scoped to a single block — loaded as a module only when that block appears on the page |
global-blocks.css (aspirational) | Shared component styles used across multiple blocks (e.g. card patterns, list items) — avoids loading redundant stylesheets per block |
styles.css — anything that applies site-wide: tokens, element resets, typography scale, utility classes, grid variables. Do not add block-specific styles here..block-name { }. Loaded automatically by loadBlock unless the block is in the components array in scripts.js.global-blocks.css — styles for UI patterns shared by multiple blocks. Prefer this over duplicating styles across block stylesheets.All tokens are defined as CSS custom properties in styles/styles.css under :root. They are generated from the Spectrum 2 token library — do not edit the generated section.
--s2-gray-25 --s2-gray-50 --s2-gray-75 --s2-gray-100
--s2-gray-200 --s2-gray-300 --s2-gray-400 --s2-gray-500
--s2-gray-600 --s2-gray-700 --s2-gray-800 --s2-gray-900
--s2-gray-1000
--s2-blue-100 through --s2-blue-1200
Other color scales follow the same pattern: --s2-red-*, --s2-orange-*, --s2-yellow-*, --s2-green-*, --s2-seafoam-*, --s2-cyan-*, --s2-pink-*.
--s2-spacing-50 (2px) --s2-spacing-75 (4px)
--s2-spacing-100 (8px) --s2-spacing-200 (12px)
--s2-spacing-300 (16px) --s2-spacing-400 (24px)
--s2-spacing-500 (32px) --s2-spacing-600 (40px)
--s2-spacing-700 (48px) --s2-spacing-800 (64px)
--s2-spacing-900 (80px) --s2-spacing-1000 (96px)
--s2-corner-radius-75 (3px) --s2-corner-radius-100 (4px)
--s2-corner-radius-200 (5px) --s2-corner-radius-300 (6px)
--s2-corner-radius-400 (7px) --s2-corner-radius-500 (8px)
--s2-corner-radius-600 (9px) --s2-corner-radius-700 (10px)
--s2-corner-radius-800 (16px)
--s2-body-size-xxs (11px) --s2-body-size-xs (12px)
--s2-body-size-s (14px) --s2-body-size-m (16px)
--s2-body-size-l (18px) --s2-body-size-xl (20px)
--s2-body-size-xxl (22px) --s2-body-size-xxxl (25px)
--s2-body-font-weight: 400
--s2-body-line-height: 1.5
--s2-heading-size-xs (18px) --s2-heading-size-s (20px)
--s2-heading-size-m (22px) --s2-heading-size-l (28px)
--s2-heading-size-xl (36px) --s2-heading-size-xxl (45px)
--s2-heading-size-xxxl (58px) --s2-heading-size-xxxxl (73px)
--s2-heading-font-weight: 800
--s2-heading-line-height: 1.3
--s2-font-family: 'Adobe Clean', adobe-clean, 'Trebuchet MS', sans-serif
--s2-font-display-family: 'Adobe Clean Display', adobe-clean-display, sans-serif
--se-grid-container-width (83.4% up to 1500px at 1800px+)
--se-grid-column-width (container / 12)
--se-grid-gutter-width (8.3%)
--sh-nav-height (80px)
--se-body-background-color --se-body-color
--se-component-m-height (32px)
--se-corner-radius-50 (1px)
--se-adobe-corporate-color (rgb(235 16 0))
Color tokens use the CSS light-dark() function — each token resolves automatically based on the user's color-scheme preference. No JavaScript class toggling is needed.
:root {
color-scheme: light dark; /* enables light-dark() resolution */
}
/* Each token already handles both modes: */
--s2-gray-25: light-dark(rgb(255 255 255), rgb(17 17 17));
--s2-blue-900: light-dark(rgb(59 99 251), rgb(86 129 255));
Always use tokens rather than hardcoded colors. Tokens adapt to the user's mode automatically. To force a specific scheme on a section or component:
.my-block--dark {
color-scheme: dark;
}
.my-block--light {
color-scheme: light;
}
The utility classes .dark-scheme and .light-scheme are available globally for one-off overrides.
spectrum-edge CSS layerGlobal element styles in styles.css are wrapped in @layer spectrum-edge. This gives block stylesheets implicit priority — unlayered styles always beat layered ones, so blocks never need !important to override base styles.
/* styles.css */
@layer spectrum-edge {
html.spectrum-edge {
h1 { font-size: var(--s2-heading-size-xxl); }
p { margin: calc(1em * var(--s2-body-margin-multiplier)) 0; }
}
}
/* blocks/hero/hero.css — wins without !important */
.hero h1 { font-size: var(--s2-heading-size-xxxxl); }
These are defined in styles.css and available everywhere:
| Class | Purpose |
|---|---|
.visually-hidden | Hides content visually but keeps it accessible (clip-path: inset(50%)) |
.dark-scheme | Forces dark color scheme on an element |
.light-scheme | Forces light color scheme on an element |
.heading-size-* | Applies heading scale without changing element semantics |
.my-block { ... }..my-block__element, .my-block--modifier.rgb(from <token> r g b / <alpha>) for alpha variants of token colors:&:hover {
background-color: rgb(from var(--s2-gray-500) r g b / 15%);
}
@media queries with width >= syntax (not min-width):@media (width >= 800px) {
.my-block { display: flex; }
}
prefers-reduced-motion for any transitions or animations:@media (prefers-reduced-motion: reduce) {
.my-block { transition: none; }
}