Packs
A pack is a self-contained extension that adds capabilities or a visual identity to Vanilla Breeze. Packs come in three types:
Functional
Add JS behaviors and components. No theme tokens — they work with any theme. Examples: ui, effects, prototype.
Aesthetic
Pure visual themes — token overrides for colors, fonts, radii, easing. No JS, no new components. CSS-only.
Full
Theme + effects + components in one coherent package. A complete visual identity. Examples: retro, kawaii.
Mental Model
Vanilla Breeze core ships tokens, layouts, and web components. A pack extends this with:
Theme
Token overrides scoped to [data-theme~="name"]. Changes colors, fonts, radii, easing. Zero new CSS rules — just different values.
Effects
CSS and JS animations activated by data-* attributes. Add data-neon or data-flipboard to any element.
Components
Web components with pack-specific chrome. They consume core tokens automatically — switch theme and the component adapts.
All three layers are optional. A pack can ship just a theme, just effects, just components, or any combination.
Token Inheritance
This is the key insight: pack components consume the same tokens as core. When you switch from data-theme="retro" to data-theme="ocean", every pack component re-renders with ocean's colors, fonts, and spacing. No code changes needed.
Loading a Pack
CDN (static)
Load the full pack alongside core:
Granular Loading
Load only the parts you need:
Runtime Activation
Load a pack dynamically from JavaScript:
activateBundle injects a <link> for the CSS and import()s the JS. It returns a Promise that resolves when both are loaded.
Layer Architecture
Vanilla Breeze uses CSS @layer to manage cascade priority. Pack layers sit after core layers, ensuring pack styles always win over core defaults without specificity battles:
| Layer | Purpose | Owner |
|---|---|---|
tokens … utils |
Core Vanilla Breeze styles | Core |
bundle-theme |
Token overrides for [data-theme~="name"] |
Pack theme file |
bundle-effects |
CSS effects activated by data-* attributes |
Pack effects file |
bundle-components |
Web component styles (inside Shadow DOM) | Pack component files |
When no pack is loaded, the three bundle layers are empty declarations — zero cost.
Pack Anatomy
An aesthetic pack lives in src/packs/{name}/ and follows a strict file convention:
The build pipeline produces granular and combined outputs:
Theme File
The theme file overrides core tokens inside a @layer bundle-theme block, scoped by a [data-theme~="name"] selector:
Because it uses the ~= (word match) selector, users can combine themes: data-theme="retro dark".
Writing Effects
CSS Effects
CSS effects are data-* attribute selectors in the bundle-effects layer. They must:
- Scope custom properties to their own selector (no
:rootpollution) - Consume core tokens via
var(--color-primary)so they adapt to theme changes - Provide
prefers-reduced-motionand[data-motion-reduced]overrides - Include
@media printresets
JS Effects
JS effects use the registerEffect API. The pack registry provides a shared MutationObserver that auto-initializes effects on dynamically added elements:
| Property | Required | Description |
|---|---|---|
selector |
Yes | CSS selector to match (e.g. [data-flipboard]) |
init(el) |
Yes | Called when a matching element enters the DOM |
destroy(el) |
No | Called when a matching element is removed |
reducedMotionFallback(el) |
No | Called instead of init when motion is reduced |
Writing Components
Registration
Components use registerComponent for priority-based conflict resolution. Since customElements.define() is permanent, the registry uses first-wins semantics with priority tiebreaking:
Token Contract
Every pack component documents which tokens it consumes and which it exposes. This makes the dependency chain explicit and enables tooling:
Usage
Component Rules
- Shadow DOM required — isolates component styles from the page
::part()API — expose named parts for external styling- Consume tokens, not hard values — use
var(--color-primary)notoklch(70% 0.28 145) - Progressive enhancement — slot a native
<audio>for JS-off fallback - Static metadata — declare
bundle,contract,version, token arrays
Available Packs
Try the packs in the interactive explorer, or load them individually in your projects.
Functional Packs
Add capabilities beyond core. Work with any theme.
UI Pack
Theme picker and environment manager for broad theme switching UIs.
Type: functional
Effects Pack
Text effects, animated images, ticker counters, and star ratings.
Type: functional
Prototype Pack
Placeholder content for rapid prototyping and wireframing.
Type: functional
Extras
Standalone modules loaded separately: data-emoji, <emoji-picker>, extended emoji set.
Type: functional
Font Packs
Opt-in variable font bundles. One file per typographic role — no multi-weight loading.
Foundation Fonts
Inter (sans/UI), Literata (serif/editorial), Recursive (mono/code). Variable fonts with axis-aware tokens.
Type: font pack (~660KB Latin subset)
Display Fonts
Fraunces (WONK/SOFT axes), Cormorant (Garamond-lineage), Bodoni Moda (dramatic contrast). For editorial and marketing.
Type: font pack (~430KB Latin subset)
Expressive Fonts
Nabla (COLR v1 3D depth), Honk (inflatable neon), Kablammo (comic impact). For hero sections and creative contexts.
Type: font pack (~610KB)
Material Icons
Material Symbols Outlined variable icon font with attractor animations. Context-aware weight and optical size.
Type: icon pack (theme + effects + JS)
Full Packs
Theme + effects + components — a complete visual identity in one package.
Retro / CRT
Phosphor green, sharp corners, Cartridge font, CRT effects, split-flap board, audio player with oscilloscope.
Type: full (theme + effects + components)
Kawaii / Cute
Pastel pink/mint/lavender palette, pill shapes, bouncy motion, Cherry Bomb One display font, sparkle particles.
Type: full (theme + effects + components)
Memphis
Bold flat colour, geometric surface patterns (stripes, dots, zigzag, squiggle, confetti), hard drop shadows, Boogaloo + Outfit + Space Mono fonts.
Type: full (theme + effects)
Try Them
Pack Explorer
Interactive demo page — load and switch between all available packs live.
Next Steps
Pack Explorer
Try packs live in the interactive demo.
Principles
Understand the progressive enhancement philosophy.
Themes
Learn about the core token system that packs extend.