Skip to content

Gradient Overlays & Fade Masks

Status: Canonical Applies to: Hero sections, demo containers, background graphics, card surfaces


Purpose

Gradient overlays create depth, direct attention, and blend content into surfaces without hard edges. They serve three roles in SageOx:

  1. Surface glow -- subtle radial warmth at the top of a container
  2. Content mask -- fade background graphics so foreground text remains legible
  3. Atmospheric depth -- darken or lighten zones to create visual weight

Every gradient must have a functional purpose. Decoration without function violates the Tufte principle.


Pattern Catalog

1. Container Surface Glow

A radial gradient ::before pseudo-element that adds subtle warmth to the top of a demo or feature container.

.container::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 70% 40% at 50% 0%,
    rgba(74, 95, 61, 0.06) 0%,
    transparent 60%
  );
  pointer-events: none;
}
Property Value Notes
Shape Ellipse, 70% wide × 40% tall Wide and shallow, anchored to top center
Color rgba(74, 95, 61, 0.06) Sage-tinted, 6% opacity
Fade Transparent at 60% Subtle; should not be consciously noticed
Position inset: 0 overlay Covers full container
Interaction pointer-events: none Never blocks clicks

When to use: Demo containers, feature cards, any elevated surface that benefits from a gentle "lit from above" feeling.

2. Top-to-Bottom Surface Fade

A linear gradient from accent surface color to transparent, applied as a background layer on the container.

/* Tailwind equivalent */
.overlay {
  background: linear-gradient(
    to bottom,
    var(--ox-accent-surface),
    transparent
  );
}
Property Value Token
Direction Top to bottom --
Start color sage-50 / rgba(122,143,120,0.15) dark --ox-accent-surface
End color transparent --
Position Absolute, inset: 0 --
Interaction pointer-events: none --

When to use: Cards or sections where the top edge should feel brighter/warmer than the bottom. Pairs well with the container surface glow for layered depth.

3. Background Graphic Mask

A radial CSS mask that fades a background animation or graphic so it doesn't compete with foreground text.

.graphic-container {
  mask-image: radial-gradient(
    ellipse 55% 65% at 68% 50%,
    black 30%,
    transparent 75%
  );
  -webkit-mask-image: radial-gradient(
    ellipse 55% 65% at 68% 50%,
    black 30%,
    transparent 75%
  );
}
Property Value Notes
Shape Ellipse, 55% wide × 65% tall Taller than wide; suits side-panel graphics
Center 68% from left, 50% from top Off-center toward the graphic's focal area
Solid zone black 30% Full visibility in the center
Fade zone transparent 75% Smooth fade to invisible
Opacity 0.78 on the container Further softens the graphic

When to use: Hero sections with animated backgrounds (e.g., network graphs, particle systems) that must coexist with a text block on the opposite side.

Adjust the center point based on where the text block sits. The mask should protect the text zone, not the graphic.

4. Atmospheric Darkening

A linear gradient that deepens one side of a section to create visual weight and improve text contrast.

.atmosphere {
  background: linear-gradient(
    to right,
    var(--ox-surface-1) 0%,
    var(--ox-surface-1) 20%,
    transparent 55%
  );
  opacity: 0.4;
}
Property Value Token
Direction to right (text side → graphic side) --
Solid zone 0-20% --ox-surface-1
Fade zone 20-55% Gradual transition
Opacity 0.4 Subtle; adds gravitas without blocking

When to use: Desktop hero layouts with text on one side and a graphic on the other. Hidden on mobile (hidden lg:block).


Composition Rules

Layering Order (Bottom to Top)

When multiple overlays coexist on a single container:

1. Container background (solid color)
2. Background graphic / animation (masked)
3. Atmospheric darkening
4. Surface glow (::before)
5. Foreground content

Stacking Limits

  • Maximum 2 gradient overlays per container
  • Surface glow + one additional mask is the typical maximum
  • If you need three overlays, reconsider the design

Opacity Budget

Total combined overlay opacity should not exceed ~0.15 in the text-readable zone. Overlays that are individually subtle can compound into muddiness.


Dark Mode Behavior

Pattern Light Mode Dark Mode
Surface glow rgba(74,95,61,0.06) Same value; subtle enough to work on dark surfaces
Top-to-bottom fade --ox-accent-surface (sage-50) --ox-accent-surface (rgba(122,143,120,0.15))
Background mask No change No change (mask is colorless)
Atmospheric darkening --ox-surface-1 at 0.4 --ox-surface-1 at 0.4 (auto-adapts via token)

The surface glow uses a hardcoded rgba value rather than a token because its 6% opacity works across both themes. If the sage palette shifts, update this value.


Anti-Patterns

Pattern Why It Fails
Gradient as decoration Violates Tufte; every gradient must serve a function
Visible gradient edge Hard stops draw the eye; always fade to transparent
Gradient over text Reduces legibility; mask the background, not the foreground
Multiple competing gradients Creates visual mud; limit to 2 per container
Animated gradient shift Distracting; gradients should be static
Gradient to communicate state Use semantic colors for state; gradients are spatial, not semantic

Accessibility

  • Gradient overlays must not reduce text contrast below WCAG AA (4.5:1 body, 3:1 large)
  • Background graphics behind masks must have sufficient contrast at their most-visible point (the mask center)
  • pointer-events: none is required on all overlay layers
  • Overlays are decorative; no ARIA attributes needed