Foundations

Colors, mesh gradients, patterns, typography, and motion — the building blocks of the design system.

For Claude / LLM Reference

Reference this file when building UI. Call sections by name: "refer to foundations Colors" or "use the Mesh Gradients section".

Sections

  • 1.1 Colors — brand, charcoal, bone scales
  • 1.2 Mesh Gradients — blob backgrounds + noise
  • 1.3 Patterns — grid tiles + mask utilities
  • 1.4 Typography — text-display, text-headline, etc.
  • 1.5 Motion — transitions, animations, easing, GSAP scroll

Quick Reference

  • Page bg: bg-bone-200
  • Primary text: text-charcoal-900
  • Brand color: bg-orange-600
  • Grid pattern: bg-grid-pattern
  • Hero text: text-display
  • Body text: text-body

Key Files

  • tailwind.config.js — colors
  • assets/css/main.css — utilities
  • assets/images/grid-pattern*.svg

1.1 Colors

LLM Usage Guide:

  • Backgrounds: Use bg-bone-200 for page, bg-white for cards, bg-charcoal-900 for dark sections
  • Text: Use text-charcoal-900 on light, text-white on dark, text-orange-600 for accents
  • Opacity: Add /50 suffix for secondary text (e.g., text-charcoal-900/50 )
  • Buttons: Primary = bg-orange-600 text-white , hover = hover:bg-orange-700

Brand (Orange)

Subset of Tailwind orange. Use orange-600 as primary brand color.

orange-50

#fff7ed

orange-100

#ffedd5

orange-600

#ea580c

orange-700

#c2410c

Gradient Colors

Custom colors for mesh gradients. Available as Tailwind classes: bg-gradient-light , bg-gradient-mid , etc.

gradient-light

#f6b896

gradient-mid

#f08851

gradient-base

#ea580c

gradient-dark

#d34e0e

Charcoal

Dark neutral scale. Use for text and dark UI elements. Available as Tailwind classes: bg-charcoal-900 , text-charcoal-700 , etc.

charcoal-900

#2A2827

charcoal-800

#343231

charcoal-700

#46433F

charcoal-600

#58554F

charcoal-500

#6B6860

charcoal-400

#7E7B72

charcoal-300

#918E85

Bone

Warm white scale. bone-200 (#F8F7F4) is the page background. Available as Tailwind classes: bg-bone-200 , bg-bone-300 , etc.

white

#FFFFFF

bone-50

#FCFCFB

bone-100

#FAFAF8

bone-200

#F8F7F4

bone-300

#F3F2EE

bone-400

#EEECEA

Text Colors

Three base colors with opacity variants. 100% for primary text, 50% for secondary. Use text-charcoal-900 , text-charcoal-900/50 , etc.

Dark Text (on light bg)

Primary text — 100%

Secondary text — 50%

text-charcoal-900 / text-charcoal-900/50

Light Text (on dark bg)

Primary text — 100%

Secondary text — 50%

text-white / text-white/50

Brand Text

Brand text — orange-600

Brand secondary — 50%

text-orange-600 / text-orange-600/50

1.2 Mesh Gradients

Blurred blob backgrounds with noise texture overlay. Base: #ea580c , blur: 160px . Each variation positions 3 blobs (light, mid, dark) differently.

LLM Usage Guide:

  • When to use: Footer backgrounds, hero sections, CTA banners, promotional areas
  • Implementation: Copy the blob HTML structure from examples below. No utility class — use inline styles
  • Noise overlay: Always add the SVG noise texture. Use Subtle (0.15) for most cases, Medium/Strong for blur overlays
  • Responsive: Blur values (160px footer, 60px small) may need adjustment on mobile
  • Colors: Use bg-gradient-light/mid/base/dark Tailwind classes for the blob colors

Blob Structure

Each mesh uses 3 blobs with these colors:

  • Light #f6b896 — width: 55%, height: 130%
  • Mid #f08851 — width: 60%, height: 120%
  • Dark #d34e0e — width: 70%, height: 140%

1. Default (Footer)

Mid: top-center, Dark: bottom-left, Light: bottom-right

2. Top Heavy

All blobs clustered at top edge

3. Bottom Heavy

All blobs clustered at bottom edge

4. Center Spread

Blobs radiating from center

Noise Texture Variants

SVG feTurbulence noise overlay. Use stronger variants on images with blur or orange mesh gradients.

Noise Filter Settings

Blend mode: mix-blend-overlay

  • Subtle — opacity 15%, baseFrequency 0.8, numOctaves 4 (footer default)
  • Medium — opacity 40%, baseFrequency 0.7, numOctaves 5 (blurred images)
  • Strong — opacity 55%, baseFrequency 0.6, numOctaves 6 (heavy blur/gradients)

1. Subtle (Default)

opacity: 0.15

2. Medium

opacity: 0.40

3. Strong

opacity: 0.55

Blurred Background Images

Full-bleed background images with heavy blur effect. Used for hero sections and feature backgrounds where the image provides atmosphere without distraction.

LLM Usage Guide:

  • When to use: Hero backgrounds, role pages, feature sections where image adds atmosphere
  • Blur amount: 40-50px for strong blur (image unrecognizable), 20-30px for softer blur
  • Scale: Always use scale(1.1) or scale-150 to prevent blur edge artifacts
  • Tint overlay: Optional bg-black/10 to darken, or colored overlay for brand feel
  • Noise: Always add noise overlay (Medium 0.40 opacity recommended for blurred images)
  • Text: Use white text with opacity variants for hierarchy

Blurred Image Structure

<div class="relative overflow-hidden">
  <!-- Background image with blur -->
  <div
    class="absolute inset-0 bg-cover bg-center scale-150"
    style="background-image: url('image.jpg'); filter: blur(50px);"
  ></div>

  <!-- Optional tint overlay -->
  <div class="absolute inset-0 bg-black/10"></div>

  <!-- Noise texture overlay (medium) -->
  <svg class="absolute inset-0 w-full h-full pointer-events-none opacity-[0.40] mix-blend-overlay z-[5]">
    <filter id="noise">
      <feTurbulence type="fractalNoise" baseFrequency="0.7" numOctaves="5" stitchTiles="stitch" />
    </filter>
    <rect width="100%" height="100%" filter="url(#noise)" />
  </svg>

  <!-- Content (needs relative z-10) -->
  <div class="relative z-10">...</div>
</div>

Portrait Image

Portrait with blur(50px)

Warm tones from skin/hair create ambient background

Landscape Image

Landscape with blur(50px)

Cool tones create calm, professional atmosphere

Blur Amount Comparison

blur(20px)

Soft — image recognizable

blur(30px)

Medium — shapes visible

blur(40px)

Strong — abstract colors

blur(50px)

Heavy — pure atmosphere

Combined Noise + Blur with Masks

Layer multiple masked effects on a single image to create distinct zones: clear areas, blurred areas, and noisy areas. Each effect layer has its own mask for precise control.

LLM Usage Guide:

  • Layer order: Base clear image → Blur layer with mask → Noise layer with mask
  • Independent masks: Each layer has its own mask-image for precise zone control
  • Blur layer: Wrap blurred img in a div, apply mask-image to the div (not the img)
  • Noise layer: Apply mask-image directly to the SVG element
  • Scale blur: Always use scale-110 or higher on blurred images to prevent edge artifacts

Combined Effects Layer Structure

<div class="relative overflow-hidden">
  <!-- 1. Base: Clear image -->
  <img class="absolute inset-0 w-full h-full object-cover" />

  <!-- 2. Blur layer: masked to specific area -->
  <div class="absolute inset-0" style="mask-image: radial-gradient(circle at center, transparent 25%, rgba(0,0,0,1) 60%);">
    <img class="w-full h-full object-cover blur-[12px] scale-110" />
  </div>

  <!-- 3. Noise layer: masked to different area -->
  <svg class="absolute inset-0 opacity-[0.45] mix-blend-overlay"
       style="mask-image: radial-gradient(circle at center, transparent 30%, rgba(0,0,0,1) 70%);">
    <filter id="noise">
      <feTurbulence type="fractalNoise" baseFrequency="0.7" numOctaves="5" stitchTiles="stitch" />
    </filter>
    <rect width="100%" height="100%" filter="url(#noise)" />
  </svg>
</div>
Clear base
Blurred middle

Clear → Blur → Noise (horizontal)

Left clear, middle blur, right noise

Clear base
Blurred edges

Clear center, Blur + Noise edges

Sharp focus center, diffuse edges

Clear base
Blurred bottom

Clear → Noise → Blur (vertical)

Top clear, middle noise, bottom blur

1.3 Patterns & Textures

Grid tile patterns with CSS mask gradients for fade effects. Two versions: Dark tiles (#EDECE8) for bone backgrounds, Light tiles (#FFFFFF) for dark/orange backgrounds.

LLM Usage Guide:

  • When to use: Section backgrounds, hero areas, anywhere subtle texture adds depth
  • Light backgrounds: class="bg-grid-pattern" (dark tiles)
  • Dark/orange backgrounds: class="bg-grid-pattern-light" (white tiles)
  • Change fade direction: Add mask modifier: class="bg-grid-pattern mask-to-bl"
  • Available masks: mask-to-tr/tl/br/bl/t/b/l/r , mask-fade-x/y , mask-radial-center/bl/br/tl/tr

CSS Utility Classes

Grid Pattern Classes

  • .bg-grid-pattern — dark tiles (for bone bg)
  • .bg-grid-pattern-light — light tiles (for dark/orange bg)

Mask Modifiers (combine with above)

  • .mask-to-tr .mask-to-tl .mask-to-br .mask-to-bl
  • .mask-to-t .mask-to-b .mask-to-l .mask-to-r
  • .mask-fade-x .mask-fade-y
  • .mask-radial-center .mask-radial-bl etc.

Usage: <div class="bg-grid-pattern mask-to-bl">...</div>

Dark Tiles (on Bone)

mask-to-tr (default)

mask-to-bl

mask-to-r

mask-radial-bl

Light Tiles (on Dark/Orange)

On Charcoal

On Charcoal

On Orange

On Orange

1.4 Typography

Semantic style classes independent of HTML tags. Font: Plus Jakarta Sans . Classes can be applied to any element and overridden with Tailwind utilities.

LLM Usage Guide:

  • Key principle: Visual style is separate from semantic HTML. A <h3> can use text-display , a <p> can use text-headline
  • Usage: Apply class to any element: <h2 class="text-title"> or <p class="text-body-lg">
  • Override: Use Tailwind utilities: <p class="text-body font-bold text-orange-600">
  • Responsive: Sizes scale automatically at md (768px) and lg (1024px) breakpoints
  • Fixed sizes: text-caption and text-overline don't scale (12px and 10px)

Typography Scale Reference

Class Base md (768px) lg (1024px) Weight Use Case
.text-display 44px 56px 72px 700 Hero headlines
.text-display-sm 38px 48px 60px 700 Secondary heroes
.text-headline 32px 40px 48px 700 Section titles
.text-headline-sm 28px 34px 40px 700 Subsection titles
.text-title 24px 28px 32px 600 Card titles, features
.text-title-sm 20px 24px 26px 600 Smaller card titles
.text-body-lg 18px 20px 20px 500 Lead paragraphs
.text-body 14px 16px 16px 500 Default body text
.text-body-sm 12px 14px 14px 500 Secondary text
.text-caption 12px 500 Metadata, footnotes
.text-overline 10px 700 Labels, uppercase

Visual Examples

Each style shown with its class. Resize browser to see responsive scaling.

.text-display

Text Display

44px → 56px → 72px · Bold · -0.05em tracking

.text-display-sm

Text Display Small

38px → 48px → 60px · Bold · -0.05em tracking

.text-headline

Text Headline

32px → 40px → 48px · Bold · -0.04em tracking

.text-headline-sm

Text Headline Small

28px → 34px → 40px · Bold · -0.04em tracking

.text-title

Text Title

24px → 28px → 32px · Semibold · -0.03em tracking

.text-title-sm

Text Title Small

20px → 24px → 26px · Semibold · -0.03em tracking

.text-body-lg

Lead paragraphs and important introductory text that needs more emphasis than standard body copy.

18px → 20px → 20px · Medium · -0.02em tracking

.text-body

Default body text for paragraphs, descriptions, and general content.

14px → 16px → 16px · Medium · -0.02em tracking · 50% opacity default

.text-body-sm

Secondary text, supporting information, and less prominent content.

12px → 14px → 14px · Medium · -0.01em tracking · 50% opacity default

.text-caption

Image captions, timestamps, metadata, footnotes.

12px fixed · Medium · 0 tracking

.text-overline

CATEGORY LABELS · SECTION MARKERS · BADGES

10px fixed · Bold · 0.1em tracking · UPPERCASE

On Dark Backgrounds

.text-headline

Dark Section Title

Body text on dark backgrounds uses white with opacity for hierarchy.

.text-headline

Brand Section Title

Same principle applies on brand orange backgrounds.

Override with Tailwind

Customizing Typography Classes

Base classes set size, weight, line-height, and tracking. Override any property with Tailwind utilities.

text-title font-normal

Title with normal weight

text-body font-bold

Body with bold weight

text-headline text-orange-600

Headline in brand color

text-body opacity-100

Body with full opacity

1.5 Motion

Animation and transition patterns for interactions and reveals. Motion should feel purposeful and smooth , never distracting or excessive.

LLM Usage Guide:

  • Duration tokens: fast (150ms), normal (300ms), slow (500ms), slower (700ms)
  • Easing: Use ease-out for entrances, ease-in for exits, ease-in-out for in-place changes
  • Entrance Animations: Use animate-entrance + animate-entrance-delay-[1-5] for staggered page load reveals
  • Blur Reveal: For hero sections with dramatic blur transitions (700ms)
  • Card Expand: For accordions, expandable content (500ms)
  • Link Underline: Animated underlines on hover (300ms)
  • Pulse Dot: Use animate-pulse-dot for status indicators

Duration Scale

fast

150ms

Micro-interactions, hovers

normal

300ms

Standard transitions

slow

500ms

Card expand, state changes

slower

700ms

Blur reveal, dramatic effects

Easing Curves

ease-out

cubic-bezier(0.16, 1, 0.3, 1)

Elements entering — fast start, gentle stop

ease-in

cubic-bezier(0.7, 0, 0.84, 0)

Elements exiting — gentle start, fast end

ease-in-out

cubic-bezier(0.65, 0, 0.35, 1)

In-place state changes

Motion Patterns

Interactive examples. Hover or click to see the animation.

Blur Reveal

Hover to reveal

Duration: 700ms (slower)

Use: Hero sections, dramatic reveals

blur-md → blur-0
transition-all duration-700 ease-out

Card Expand

Expandable Card

Additional content that appears when expanded. Great for accordions and FAQs.

Duration: 500ms (slow)

Use: Accordions, expandable content

max-h-0 → max-h-[value]
transition-all duration-500 ease-out

Link Underline

Duration: 300ms (normal)

Use: Navigation links, inline links

width: 0 → 100%
after:w-0 hover:after:w-full

Stagger Animation

Duration: 300ms + stagger delay

Use: List items, grid reveals

transition-delay: 0, 75, 150, 225ms
Sequential reveal effect

Text Reveal (TBC)

To be confirmed

Duration: TBD

Use: Text animations, typewriter effects

Placeholder for future text reveal animation pattern.

Entrance Animations

Staggered fade-in + slide-up animations for page load reveals. Apply to hero sections, feature grids, or any content that should animate in when the page loads. Respects prefers-reduced-motion .

Entrance Animation Classes

Class Duration Delay Use Case
.animate-entrance 600ms 0ms Base animation (20px slide)
.animate-entrance-sm 500ms 0ms Subtle animation (12px slide)
.animate-entrance-delay-1 100ms Second element in sequence
.animate-entrance-delay-2 200ms Third element in sequence
.animate-entrance-delay-3 300ms Fourth element in sequence
.animate-entrance-delay-4 400ms Fifth element in sequence
.animate-entrance-delay-5 500ms Sixth element in sequence
.animate-entrance-delay-sm-[1-5] 75ms increments Tighter sequences (grids)

Live Demo — Click "Replay" to see the animation

OVERLINE TAG

Hero Headline Text

Supporting description text that provides more context about the headline above.

Staggered Entrance Animation Example

<!-- Hero section with staggered entrance -->
<div class="animate-entrance">
  <span class="text-overline">TAG</span>
</div>

<h1 class="animate-entrance animate-entrance-delay-1">
  Headline Text
</h1>

<p class="animate-entrance animate-entrance-delay-2">
  Description text...
</p>

<div class="animate-entrance animate-entrance-delay-3">
  <button class="btn-primary">CTA</button>
</div>

Usage Tips

  • Hero sections: Use 100ms delays (delay-1 through delay-4) for clear visual hierarchy
  • Feature grids: Use 75ms delays (delay-sm-1 through delay-sm-5) for tighter card reveals
  • Combine with animate-entrance-sm: For subtle reveals on secondary content
  • Accessibility: Animations automatically disabled for users with prefers-reduced-motion
  • Pulse indicator: Use animate-pulse-dot for status dots (replaces inline keyframes)

Additional Patterns

Focus Ring

Duration: 150ms (fast)

Use: Form inputs, interactive elements

focus:ring-2 focus:ring-orange-600
focus:ring-offset-2

Tailwind Transition Classes

Duration Classes

  • duration-150 — fast (150ms)
  • duration-300 — normal (300ms)
  • duration-500 — slow (500ms)
  • duration-700 — slower (700ms)

Property Classes

  • transition-all — all properties
  • transition-colors — color only
  • transition-opacity — opacity only
  • transition-transform — transform only

Usage: <button class="transition-transform duration-150 active:scale-95">

GSAP Scroll Animations

Scroll-triggered and scroll-linked animations powered by GSAP ScrollTrigger. Use for elements that should animate when scrolling into view, or animations that follow scroll position.

LLM Usage Guide:

  • Basic usage: Add data-scroll-animate="preset" to any element
  • Scroll-linked (scrub): Add data-scroll-scrub="1" to link animation progress to scroll position
  • Stagger groups: Wrap elements in parent with data-scroll-stagger="0.1"
  • Custom timing: Use data-scroll-start and data-scroll-end to control trigger points

Animation Presets

Preset Effect Best For
fade-up Fade in + move up 40px General content reveals, text blocks
scale-up Scale 0.7→1 + move up 80px Cards, hero elements, featured content
fade-in Simple opacity fade Images, backgrounds, subtle reveals
slide-left Slide in from right Side panels, alternating content
slide-right Slide in from left Side panels, alternating content
scale-in Scale 0.8→1 (no movement) Icons, badges, centered elements
rotate-in Rotate -10°→0° + move up Playful reveals, featured items

Data Attribute Options

Attribute Default Description
data-scroll-animate Animation preset name (required)
data-scroll-scrub false Link to scroll position (true, false, or smoothing number)
data-scroll-start "top 85%" When animation starts (element viewport)
data-scroll-end "top 20%" When animation ends (element viewport)
data-scroll-duration 1 Duration in seconds (non-scrub only)
data-scroll-delay 0 Delay in seconds (non-scrub only)
data-scroll-ease "power3.out" GSAP easing function
data-scroll-markers false Show debug markers (development only)

Interactive Demo

Scroll down within this container to see the animations. Each card uses a different preset.

fade-up

Fades in while moving up 40px

scale-up (with scrub)

Scales and moves with scroll position

slide-left

Slides in from the right

slide-right

Slides in from the left

Staggered group (0.15s delay):

Item 1

Item 2

Item 3

Basic Usage Examples

<!-- Simple fade up animation -->
<div data-scroll-animate="fade-up">
  Content fades in when scrolled into view
</div>

<!-- Scale animation linked to scroll position -->
<div data-scroll-animate="scale-up"
     data-scroll-scrub="1"
     data-scroll-start="top bottom"
     data-scroll-end="top 40%">
  Card scales as you scroll
</div>

<!-- Staggered animation group -->
<div data-scroll-stagger="0.1">
  <div data-scroll-animate="fade-up">Item 1</div>
  <div data-scroll-animate="fade-up">Item 2</div>
  <div data-scroll-animate="fade-up">Item 3</div>
</div>

<!-- Custom timing and easing -->
<div data-scroll-animate="slide-left"
     data-scroll-duration="1.5"
     data-scroll-delay="0.2"
     data-scroll-ease="elastic.out(1, 0.5)">
  Custom animation timing
</div>

Key Files

  • assets/js/scroll-animations.js — Scroll animation module (presets, initialization)
  • _includes/head.html — GSAP CDN includes

CDN: GSAP 3.12 + ScrollTrigger loaded from jsdelivr.net