Spatial & Luminous Design
Depth, light, and material systems that elevate interfaces from flat to three-dimensional. These techniques separate premium products from generic ones.
Purpose
- Provide a consistent 5-layer spatial model for z-axis depth
- Define luminosity techniques with specific CSS values
- Give production-ready glassmorphism across three tiers
- Reference material surfaces as design tokens
- Guide atmospheric color and mesh gradient usage
1. Spatial Depth System (5-Layer Model)
Every element belongs to exactly one layer. Elements never skip layers.
| Layer |
Z-Index Range |
Parallax Speed |
Purpose |
CSS Techniques |
| Background |
0 |
0.3× scroll |
Environment, atmosphere |
Fixed or slow-scroll gradient, ambient tint |
| Ground |
1–10 |
1× scroll (normal) |
Content foundation |
Cards, surfaces, main content |
| Floating |
11–100 |
1.05–1.1× scroll |
Active elements |
Dropdowns, tooltips, selections |
| Overlay |
101–1000 |
Fixed |
Focused attention |
Modals, lightboxes, drawers |
| Foreground |
1001+ |
Fixed |
Persistent UI |
Navigation, FAB, toasts |
Layer rules:
- Each layer has a consistent shadow depth token (e.g.,
--shadow-ground, --shadow-floating)
- Parallax ratios create natural depth perception — heavier layers move slower
- Background layer anchors the atmosphere; changing it shifts the entire page mood
Shadow depth tokens:
:root {
--shadow-ground: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.08);
--shadow-floating: 0 4px 16px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.08);
--shadow-overlay: 0 20px 60px rgba(0,0,0,0.20), 0 4px 16px rgba(0,0,0,0.12);
--shadow-foreground: 0 8px 32px rgba(0,0,0,0.24);
}
2. Luminosity Techniques
Ambient glow (behind focal elements):
.focal-element {
box-shadow: 0 0 60px 20px rgba(120, 80, 255, 0.20);
/* spread: 20–60px | blur: 40–100px | opacity: 15–30% */
/* color: element's dominant hue */
}
Backlit text (dark backgrounds):
.hero-heading {
text-shadow: 0 0 40px rgba(120, 80, 255, 0.30);
/* Creates ethereal, premium feel — use sparingly */
}
Neon effect (3-layer technique):
.neon {
box-shadow:
0 0 7px #7850ff, /* tight glow */
0 0 20px #7850ff, /* medium spread */
0 0 60px rgba(120,80,255,0.3); /* ambient wash */
}
Rim lighting (overhead light source suggestion):
.dark-card {
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10);
/* Simulates light hitting the top edge */
}
Brightness hierarchy rule:
The brightest element = highest attention priority. Use filter: brightness() or direct color lightness to control visual hierarchy intentionally.
3. Glassmorphism (3 Tiers)
| Tier |
Background |
Blur |
Border |
Use Case |
| Subtle |
rgba(255,255,255, 0.05–0.10) |
backdrop-filter: blur(8px) |
1px rgba(255,255,255, 0.10) |
Floating cards, secondary panels |
| Medium |
rgba(255,255,255, 0.15–0.25) |
backdrop-filter: blur(16px) |
1px rgba(255,255,255, 0.20) |
Navigation, toolbars, active panels |
| Immersive |
rgba(255,255,255, 0.30–0.40) |
backdrop-filter: blur(24px) |
1px rgba(255,255,255, 0.30) |
Modal backgrounds, hero overlays |
Implementation pattern:
.glass-medium {
background: rgba(255, 255, 255, 0.18);
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px); /* Safari */
border: 1px solid rgba(255, 255, 255, 0.20);
border-radius: var(--radius-lg);
}
Mandatory rules:
- MUST maintain 4.5:1 text contrast ratio over the blurred background — test on varied backgrounds
- Always add border for edge definition (without it, elements float directionlessly)
- Light source direction must match the elevation system
- Dark glassmorphism: swap white rgba for dark rgba values — do not just invert, redesign
4. Material Reference Library
| Material |
CSS Implementation |
Token Name |
| Glass |
backdrop-filter: blur(Xpx); background: rgba(R,G,B, 0.1–0.3) |
--surface-glass |
| Metal |
background: linear-gradient(135deg, hsl(0,0%,22%), hsl(0,0%,18%)); box-shadow: inset 0 1px 0 rgba(255,255,255,0.15) |
--surface-metal |
| Paper |
background: var(--color-surface) + noise overlay pseudo-element at 0.5–1.5% opacity |
--surface-paper |
| Fabric |
background: repeating-linear-gradient(0deg, transparent, transparent 1px, rgba(0,0,0,0.02) 1px, rgba(0,0,0,0.02) 2px) |
--surface-fabric |
| Liquid |
Multi-point radial gradients + morphing SVG shapes + slow transform animation (20–40s cycle) |
--surface-liquid |
Noise texture (Paper material):
.paper::after {
content: '';
position: absolute;
inset: 0;
background-image: url("data:image/svg+xml,..."); /* SVG noise */
opacity: 0.015; /* MAX 1.5% — above this reads as dirty, not refined */
pointer-events: none;
}
5. Atmospheric Color
Ambient tint:
Full-page overlay at 2–5% opacity of brand primary. Creates environmental cohesion and brand presence without competing with content.
body::before {
content: '';
position: fixed;
inset: 0;
background: var(--color-brand-primary);
opacity: 0.03;
pointer-events: none;
z-index: 0;
}
Content-responsive tinting:
Extract dominant color from hero image via canvas getImageData(), apply as page ambient tint. Technique used by Apple Music, Spotify.
Color temperature depth (spatial use):
- Warm colors (red, orange, yellow) → advance toward viewer
- Cool colors (blue, purple, teal) → recede from viewer
- Use intentionally to reinforce z-axis depth, not just for decoration
Chromatic shadows (not pure black/gray):
/* Instead of: box-shadow: 0 4px 16px rgba(0,0,0,0.2) */
/* Use shadow tinted toward complementary of light source: */
.card {
box-shadow: 0 4px 16px rgba(80, 40, 120, 0.25); /* purple-tinted for warm light */
}
Time-aware theming (optional, delightful):
- After 6pm: subtle warm shift (hue rotate +5deg, saturation +3%)
- Morning: cool shift (hue rotate -3deg, brightness +2%)
- Implement via CSS custom property update on schedule or user preference
6. Mesh Gradient Patterns
CSS implementation:
.mesh-bg {
background:
radial-gradient(ellipse at 20% 20%, rgba(120,80,255,0.4) 0%, transparent 50%),
radial-gradient(ellipse at 80% 20%, rgba(255,80,120,0.3) 0%, transparent 50%),
radial-gradient(ellipse at 50% 80%, rgba(80,200,255,0.3) 0%, transparent 50%),
radial-gradient(ellipse at 80% 80%, rgba(255,200,80,0.2) 0%, transparent 50%);
}
Construction rules:
- Place gradient points at grid intersections (3×3 or 4×4 grid)
- 4–6 color stops per point
- Saturation delta between adjacent stops: 3–5% (subtle variation, not jarring)
Animated mesh:
@keyframes mesh-drift {
0%, 100% { transform: translate(0, 0); }
33% { transform: translate(-20px, 10px); }
66% { transform: translate(10px, -20px); }
}
.mesh-point {
animation: mesh-drift 30s ease-in-out infinite;
will-change: transform; /* GPU acceleration */
}
- Animation cycle: 20–40s (longer = more atmospheric, less distracting)
- Always set
will-change: transform on animated gradient containers
Stripe's approach: WebGL noise functions via fragment shaders for GPU-rendered organic gradients with minimal CPU cost. Use for high-performance, complex mesh needs.
Anti-Patterns
| Anti-Pattern |
Why It Fails |
| Heavy blur killing text readability |
Always verify contrast OVER the blurred background, not against a solid |
| Frosted glass without border |
Edges disappear; elements float without spatial context |
| Shadows inconsistent with light source |
Elements casting shadows in different directions feel physically wrong |
| Flat single-tone backgrounds |
Misses the depth and atmosphere that elevates premium products |
| Noise texture above 2% opacity |
Reads as gritty and industrial, not refined premium |
| Gradients with > 20% saturation jumps between stops |
Jarring, not luminous |
| Black (#000) in shadows |
Feels heavy and dead — use tinted dark values instead |
| Glassmorphism on glassmorphism |
Stacked blur layers collapse depth, create visual noise |
| Same ambient glow color everywhere |
Loses intentionality; glow should reflect the element's own hue |
Validation Checklist
1---2name: spatial-luminous-design3description: Spatial depth systems, luminosity techniques, glassmorphism tiers, material surface reference (glass, metal, paper, fabric), atmospheric color, and animated mesh gradients — the vocabulary for premium three-dimensional UI. Use proactively when assigning z-axis layers and shadow depth tokens to interface elements, implementing glassmorphism at the correct tier, applying luminosity effects (ambient glow, neon, rim lighting), choosing material surfaces as design tokens, or building atmospheric color and animated mesh gradients.4---56# Spatial & Luminous Design78Depth, light, and material systems that elevate interfaces from flat to three-dimensional. These techniques separate premium products from generic ones.910## Purpose1112- Provide a consistent 5-layer spatial model for z-axis depth13- Define luminosity techniques with specific CSS values14- Give production-ready glassmorphism across three tiers15- Reference material surfaces as design tokens16- Guide atmospheric color and mesh gradient usage1718---1920## 1. Spatial Depth System (5-Layer Model)2122Every element belongs to exactly one layer. Elements never skip layers.2324| Layer | Z-Index Range | Parallax Speed | Purpose | CSS Techniques |25|-------|--------------|----------------|---------|----------------|26| Background | 0 | 0.3× scroll | Environment, atmosphere | Fixed or slow-scroll gradient, ambient tint |27| Ground | 1–10 | 1× scroll (normal) | Content foundation | Cards, surfaces, main content |28| Floating | 11–100 | 1.05–1.1× scroll | Active elements | Dropdowns, tooltips, selections |29| Overlay | 101–1000 | Fixed | Focused attention | Modals, lightboxes, drawers |30| Foreground | 1001+ | Fixed | Persistent UI | Navigation, FAB, toasts |3132**Layer rules:**33- Each layer has a consistent shadow depth token (e.g., `--shadow-ground`, `--shadow-floating`)34- Parallax ratios create natural depth perception — heavier layers move slower35- Background layer anchors the atmosphere; changing it shifts the entire page mood3637**Shadow depth tokens:**38```css39:root {40 --shadow-ground: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.08);41 --shadow-floating: 0 4px 16px rgba(0,0,0,0.12), 0 2px 4px rgba(0,0,0,0.08);42 --shadow-overlay: 0 20px 60px rgba(0,0,0,0.20), 0 4px 16px rgba(0,0,0,0.12);43 --shadow-foreground: 0 8px 32px rgba(0,0,0,0.24);44}45```4647---4849## 2. Luminosity Techniques5051**Ambient glow** (behind focal elements):52```css53.focal-element {54 box-shadow: 0 0 60px 20px rgba(120, 80, 255, 0.20);55 /* spread: 20–60px | blur: 40–100px | opacity: 15–30% */56 /* color: element's dominant hue */57}58```5960**Backlit text** (dark backgrounds):61```css62.hero-heading {63 text-shadow: 0 0 40px rgba(120, 80, 255, 0.30);64 /* Creates ethereal, premium feel — use sparingly */65}66```6768**Neon effect (3-layer technique):**69```css70.neon {71 box-shadow:72 0 0 7px #7850ff, /* tight glow */73 0 0 20px #7850ff, /* medium spread */74 0 0 60px rgba(120,80,255,0.3); /* ambient wash */75}76```7778**Rim lighting** (overhead light source suggestion):79```css80.dark-card {81 box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10);82 /* Simulates light hitting the top edge */83}84```8586**Brightness hierarchy rule:**87The brightest element = highest attention priority. Use `filter: brightness()` or direct color lightness to control visual hierarchy intentionally.8889---9091## 3. Glassmorphism (3 Tiers)9293| Tier | Background | Blur | Border | Use Case |94|------|-----------|------|--------|----------|95| Subtle | rgba(255,255,255, 0.05–0.10) | backdrop-filter: blur(8px) | 1px rgba(255,255,255, 0.10) | Floating cards, secondary panels |96| Medium | rgba(255,255,255, 0.15–0.25) | backdrop-filter: blur(16px) | 1px rgba(255,255,255, 0.20) | Navigation, toolbars, active panels |97| Immersive | rgba(255,255,255, 0.30–0.40) | backdrop-filter: blur(24px) | 1px rgba(255,255,255, 0.30) | Modal backgrounds, hero overlays |9899**Implementation pattern:**100```css101.glass-medium {102 background: rgba(255, 255, 255, 0.18);103 backdrop-filter: blur(16px);104 -webkit-backdrop-filter: blur(16px); /* Safari */105 border: 1px solid rgba(255, 255, 255, 0.20);106 border-radius: var(--radius-lg);107}108```109110**Mandatory rules:**111- MUST maintain 4.5:1 text contrast ratio over the blurred background — test on varied backgrounds112- Always add border for edge definition (without it, elements float directionlessly)113- Light source direction must match the elevation system114- Dark glassmorphism: swap white rgba for dark rgba values — do not just invert, redesign115116---117118## 4. Material Reference Library119120| Material | CSS Implementation | Token Name |121|----------|-------------------|------------|122| Glass | `backdrop-filter: blur(Xpx); background: rgba(R,G,B, 0.1–0.3)` | `--surface-glass` |123| Metal | `background: linear-gradient(135deg, hsl(0,0%,22%), hsl(0,0%,18%)); box-shadow: inset 0 1px 0 rgba(255,255,255,0.15)` | `--surface-metal` |124| Paper | `background: var(--color-surface)` + noise overlay pseudo-element at 0.5–1.5% opacity | `--surface-paper` |125| Fabric | `background: repeating-linear-gradient(0deg, transparent, transparent 1px, rgba(0,0,0,0.02) 1px, rgba(0,0,0,0.02) 2px)` | `--surface-fabric` |126| Liquid | Multi-point radial gradients + morphing SVG shapes + slow transform animation (20–40s cycle) | `--surface-liquid` |127128**Noise texture (Paper material):**129```css130.paper::after {131 content: '';132 position: absolute;133 inset: 0;134 background-image: url("data:image/svg+xml,..."); /* SVG noise */135 opacity: 0.015; /* MAX 1.5% — above this reads as dirty, not refined */136 pointer-events: none;137}138```139140---141142## 5. Atmospheric Color143144**Ambient tint:**145Full-page overlay at 2–5% opacity of brand primary. Creates environmental cohesion and brand presence without competing with content.146```css147body::before {148 content: '';149 position: fixed;150 inset: 0;151 background: var(--color-brand-primary);152 opacity: 0.03;153 pointer-events: none;154 z-index: 0;155}156```157158**Content-responsive tinting:**159Extract dominant color from hero image via canvas `getImageData()`, apply as page ambient tint. Technique used by Apple Music, Spotify.160161**Color temperature depth (spatial use):**162- Warm colors (red, orange, yellow) → advance toward viewer163- Cool colors (blue, purple, teal) → recede from viewer164- Use intentionally to reinforce z-axis depth, not just for decoration165166**Chromatic shadows (not pure black/gray):**167```css168/* Instead of: box-shadow: 0 4px 16px rgba(0,0,0,0.2) */169/* Use shadow tinted toward complementary of light source: */170.card {171 box-shadow: 0 4px 16px rgba(80, 40, 120, 0.25); /* purple-tinted for warm light */172}173```174175**Time-aware theming (optional, delightful):**176- After 6pm: subtle warm shift (hue rotate +5deg, saturation +3%)177- Morning: cool shift (hue rotate -3deg, brightness +2%)178- Implement via CSS custom property update on schedule or user preference179180---181182## 6. Mesh Gradient Patterns183184**CSS implementation:**185```css186.mesh-bg {187 background:188 radial-gradient(ellipse at 20% 20%, rgba(120,80,255,0.4) 0%, transparent 50%),189 radial-gradient(ellipse at 80% 20%, rgba(255,80,120,0.3) 0%, transparent 50%),190 radial-gradient(ellipse at 50% 80%, rgba(80,200,255,0.3) 0%, transparent 50%),191 radial-gradient(ellipse at 80% 80%, rgba(255,200,80,0.2) 0%, transparent 50%);192}193```194195**Construction rules:**196- Place gradient points at grid intersections (3×3 or 4×4 grid)197- 4–6 color stops per point198- Saturation delta between adjacent stops: 3–5% (subtle variation, not jarring)199200**Animated mesh:**201```css202@keyframes mesh-drift {203 0%, 100% { transform: translate(0, 0); }204 33% { transform: translate(-20px, 10px); }205 66% { transform: translate(10px, -20px); }206}207.mesh-point {208 animation: mesh-drift 30s ease-in-out infinite;209 will-change: transform; /* GPU acceleration */210}211```212- Animation cycle: 20–40s (longer = more atmospheric, less distracting)213- Always set `will-change: transform` on animated gradient containers214215**Stripe's approach:** WebGL noise functions via fragment shaders for GPU-rendered organic gradients with minimal CPU cost. Use for high-performance, complex mesh needs.216217---218219## Anti-Patterns220221| Anti-Pattern | Why It Fails |222|---|---|223| Heavy blur killing text readability | Always verify contrast OVER the blurred background, not against a solid |224| Frosted glass without border | Edges disappear; elements float without spatial context |225| Shadows inconsistent with light source | Elements casting shadows in different directions feel physically wrong |226| Flat single-tone backgrounds | Misses the depth and atmosphere that elevates premium products |227| Noise texture above 2% opacity | Reads as gritty and industrial, not refined premium |228| Gradients with > 20% saturation jumps between stops | Jarring, not luminous |229| Black (#000) in shadows | Feels heavy and dead — use tinted dark values instead |230| Glassmorphism on glassmorphism | Stacked blur layers collapse depth, create visual noise |231| Same ambient glow color everywhere | Loses intentionality; glow should reflect the element's own hue |232233---234235## Validation Checklist236237- [ ] Every element assigned to correct spatial layer (no z-index guessing)238- [ ] Shadow tokens consistent with elevation level239- [ ] Glassmorphism tier matches context (subtle/medium/immersive)240- [ ] 4.5:1 text contrast verified over glass surfaces on varied backgrounds241- [ ] Borders present on all glass surfaces for edge definition242- [ ] Ambient glow color derives from element's dominant hue243- [ ] Chromatic shadows used instead of pure rgba(0,0,0)244- [ ] Noise texture at or below 1.5% opacity245- [ ] Mesh gradient animation cycle 20–40s with will-change: transform246- [ ] prefers-reduced-motion stops mesh gradient animation