Agent Skills: Expressive Amplifier

Turbocharge component styling with extreme contrast, variable fonts, spring physics, and semantic emotional coupling while maintaining professional standards

UncategorizedID: okgoogle13/careercopilot/expressive-amplifier

Install this agent skill to your local

pnpm dlx add-skill https://github.com/okgoogle13/careercopilot/tree/HEAD/.claude/skills/design-skills/expressive-amplifier

Skill Files

Browse the full folder contents for expressive-amplifier.

Download Skill

Loading file tree…

.claude/skills/design-skills/expressive-amplifier/SKILL.md

Skill Metadata

Name
expressive-amplifier
Description
Turbocharge component styling with extreme contrast, variable fonts, spring physics, and semantic emotional coupling while maintaining professional standards

Expressive Amplifier

Purpose

Amplify visual expression across typography, motion, color, and shapes while adhering to kerala-rage M3 Expressive principles and WCAG accessibility standards. Transform conservative components into emotionally resonant, professionally expressive interfaces that balance high visual energy with usability and context-appropriate restraint.

When to Use

  • Hero Sections: Implement maximum visual impact with extreme contrast and spring physics
  • Conservative Components: Transform flat buttons, static headers, and generic cards into expressive variants
  • Emotional Interactions: Add semantic motion, hover morphs, and scroll-driven typography that responds to user state
  • Brand Expressiveness: Enforce kerala-rage "Maximum Expressive Playful" philosophy system-wide
  • Professional Data Display: Balance expressive personality with readable data tables and forms
  • Accessibility Compliance: Ensure WCAG AA contrast and reduced motion support while maximizing expression

NOT for: Over-expression in data-heavy contexts (dashboards, tables, forms requiring focus), decorative animation without semantic intent, or bypassing accessibility requirements.

Capabilities

Typography Amplification

  • ✅ Apply extreme contrast rule (9× weight ratio: 100 vs 900, 6× size ratio: 12px vs 72px+)
  • ✅ Implement emotional typography patterns (solidarityProtest, laborExploitationPressure, melancholyLonging, scrollPressure, identityAssertion, extremeVariableContrast)
  • ✅ Exploit variable font axes (GRAD, SOFT, WONK, wght, wdth, opsz) for hover states and transitions
  • ✅ Context-specific scaling (hero 9×, section headers 5×, data tables 2× max)
  • ✅ Scroll-driven weight ramping (breathing headers, building tension)

Motion Amplification

  • ✅ Diversify spring physics (typeSpringSlam, dragSettle, pulseThrob, melancholyBreath)
  • ✅ Apply M3 Expressive curve (cubic-bezier(0.34, 1.56, 0.64, 1)) for overshoot easing
  • ✅ Multi-axis hover morphs (color + scale + weight + shadow simultaneously)
  • ✅ Semantic motion mapping (CTA → slam, Cards → settle, Alerts → throb, Reflective → breath)
  • ✅ Reduced motion fallbacks (accessibility requirement)

Color Amplification

  • ✅ Tonal stepping for depth (hover +2 steps, active -3 steps, glow +6 steps)
  • ✅ Semantic color usage (inkGold for optimism, solidarityRed for urgency, activistSmokeGreen for calm)
  • ✅ Glow effects (solidarityBleed, inkOffset, activation halos)
  • ✅ WCAG AA contrast validation (4.5:1 text, 3:1 large text)

Shape & Shadow Amplification

  • ✅ Enforce semantic geometry (rounded-strike, rounded-placard, rounded-megaphone, rounded-sentry)
  • ✅ Ban perfect circles (border-radius: 50%98% sentry avatars)
  • ✅ Semantic shadow progression (elevation1Pebbleelevation4Float, inkOffset, solidarityBleed)

Emotional State Coupling

  • ✅ Coordinate typography + motion + color + shadow by semantic intent
  • ✅ Solidarity/Protest → solidarityProtest type + typeSpringSlam + solidarityRed + inkOffset shadow
  • ✅ Labor Pressure → laborExploitationPressure type + dragSettle + charcoalRed + elevated shadow
  • ✅ Melancholy → melancholyLonging type + melancholyBreath + activistSmokeGreen + subtle glow

Typography Amplification Patterns

1. Extreme Contrast Rule (Hero Sections)

Rule: 9× weight ratio + 6× size ratio for maximum visual impact.

// Hero Section with Extreme Contrast
<div className="hero-section">
  {/* Primary hero line: Hairline 100 weight, 72px */}
  <h1 style={{
    fontFamily: 'Fraunces',
    fontVariationSettings: '"wght" 100, "wdth" 100',
    fontSize: '72px',
    letterSpacing: '-0.02em',
    color: 'var(--sys-color-worker-ash-steps-6)' // Lightest for readability
  }}>
    Your Career Journey
  </h1>

  {/* Metadata: Ultra-black 900 weight, 12px */}
  <p style={{
    fontFamily: 'Work Sans',
    fontVariationSettings: '"wght" 900, "wdth" 75',
    fontSize: '12px',
    letterSpacing: '0.05em',
    textTransform: 'uppercase',
    color: 'var(--sys-color-stencilYellow-base)' // High-salience marker
  }}>
    Kerala Rage · Solidarity Mode
  </p>
</div>

Contrast Ratios:

  • Weight: 100 ÷ 900 = 9× ✅
  • Size: 72px ÷ 12px = 6× ✅

2. Emotional Typography Presets

Solidarity Protest (Declarative Headers)

// Poster-style declaration with collective breath
<h2 style={{
  fontFamily: 'Fraunces',
  fontVariationSettings: '"wght" 800, "wdth" 120', // Expanded solidarity
  letterSpacing: '0.02em', // Opens voice
  fontSize: '48px',
  color: 'var(--sys-color-solidarityRed-steps-3)' // Primary heat
}}>
  Workers' Rights Matter
</h2>

Token Reference: tokens.jsonsys.typography.emotionalPatterns.solidarityProtest

Labor Exploitation Pressure (Constraint)

// Compressed pressure state (fatigue, extraction)
<h3 style={{
  fontFamily: 'Work Sans',
  fontVariationSettings: '"wght" 900, "wdth" 75', // Compressed black
  letterSpacing: '0em', // Neutral tracking intensifies density
  fontSize: '32px',
  color: 'var(--sys-color-charcoalRed-steps-2)' // Warning energy
}}>
  Overworked. Underpaid.
</h3>

Token Reference: tokens.jsonsys.typography.emotionalPatterns.laborExploitationPressure

Melancholy Longing (Reflective Sections)

// Breathing animation for homesickness, between-worlds moments
<motion.p
  style={{
    fontFamily: 'Libre Bodoni',
    fontVariationSettings: '"wght" 475, "wdth" 98', // Mid-weight oscillation base
    letterSpacing: '0em',
    fontSize: '24px',
    color: 'var(--sys-color-activistSmokeGreen-steps-4)'
  }}
  animate={{
    fontVariationSettings: [
      '"wght" 450, "wdth" 98',
      '"wght" 500, "wdth" 98',
      '"wght" 450, "wdth" 98'
    ],
    opacity: [0.85, 1, 0.85]
  }}
  transition={{
    duration: 4, // melancholyBreath: 4000ms
    ease: [0.34, 1.56, 0.64, 1], // M3 Expressive curve
    repeat: Infinity,
    repeatType: 'loop'
  }}
>
  Between two worlds, neither fully home.
</motion.p>

Token Reference: tokens.jsonsys.typography.emotionalPatterns.melancholyLonging + sys.motion.patterns.melancholyBreath

3. Scroll-Driven Weight Ramping

import { useScroll, useTransform, motion } from 'framer-motion';

// Header gains weight as user scrolls (building tension)
export const ScrollPressureHeader = ({ children }) => {
  const { scrollYProgress } = useScroll();

  // Map scroll progress (0→1) to weight (300→800)
  const weight = useTransform(scrollYProgress, [0, 1], [300, 800]);

  // Subtle width compression (100→95)
  const width = useTransform(scrollYProgress, [0, 1], [100, 95]);

  return (
    <motion.h1
      style={{
        fontFamily: 'Fraunces',
        fontVariationSettings: useTransform(
          [weight, width],
          ([w, wdth]) => `"wght" ${w}, "wdth" ${wdth}`
        ),
        fontSize: '64px',
        color: 'var(--sys-color-worker-ash-steps-5)'
      }}
    >
      {children}
    </motion.h1>
  );
};

Token Reference: tokens.jsonsys.typography.emotionalPatterns.scrollPressure

4. Variable Font Axis Hover (Layout-Safe)

// Use GRAD axis for hover without layout reflow
<motion.button
  style={{
    fontFamily: 'Work Sans',
    fontVariationSettings: '"wght" 500, "GRAD" 0', // GRAD is layout-safe
    fontSize: '16px',
    color: 'var(--sys-color-worker-ash-base)'
  }}
  whileHover={{
    fontVariationSettings: '"wght" 500, "GRAD" 150' // Increase GRAD, not wght
  }}
  transition={{
    duration: 0.6,
    ease: [0.34, 1.56, 0.64, 1] // typeSpringSlam
  }}
>
  Apply Now
</motion.button>

Why GRAD? Weight shifts (wght) cause layout reflow. GRAD axis thickens strokes without changing glyph bounds.

Motion Amplification Patterns

1. Semantic Motion Mapping

Match motion to semantic intent, not visual preference:

| Intent | Pattern | Duration | Curve | Usage | |--------|---------|----------|-------|-------| | Primary CTA | typeSpringSlam | 600ms | M3 Expressive | Headline entrance, emphasis toggles, weight shifts | | Cards/Panels | dragSettle | 800ms | M3 Expressive | Card drag, reordering, expansions (labor-weight metaphor) | | Urgent Alerts | pulseThrob | 1000ms | M3 Expressive | Urgent text emphasis, gentle alerting (no rapid flashing) | | Reflective Sections | melancholyBreath | 4000ms | M3 Expressive | Oscillating wght/opacity for homesickness, longing | | Ambient Illustration | windFlutter | 2000ms | M3 Expressive | Flags, palms, cloth motifs (optional, disable for reduced motion) | | Calm Transitions | waterRipple | 3000ms | M3 Expressive | Backwater sections, ripple highlights (background-only) |

2. Spring Physics Configuration

Token Reference: tokens.jsonsys.motion.patterns.*

// Framer Motion variant presets
const motionPresets = {
  typeSpringSlam: {
    duration: 0.6,
    ease: [0.34, 1.56, 0.64, 1] // M3 Expressive overshoot
  },
  dragSettle: {
    duration: 0.8,
    ease: [0.34, 1.56, 0.64, 1],
    // Viscous shadows pair well (see shadow section)
  },
  pulseThrob: {
    duration: 1.0,
    ease: [0.34, 1.56, 0.64, 1],
    repeat: Infinity,
    repeatType: 'reverse'
  },
  melancholyBreath: {
    duration: 4.0,
    ease: [0.34, 1.56, 0.64, 1],
    repeat: Infinity,
    repeatType: 'loop'
  }
};

// Usage
<motion.div
  initial={{ opacity: 0, scale: 0.95 }}
  animate={{ opacity: 1, scale: 1 }}
  transition={motionPresets.typeSpringSlam}
>
  {/* CTA content */}
</motion.div>

3. Multi-Axis Hover Morph

Coordinate color + scale + weight + shadow simultaneously:

<motion.button
  style={{
    fontFamily: 'Work Sans',
    fontVariationSettings: '"wght" 600, "GRAD" 0',
    fontSize: '18px',
    padding: '16px 32px',
    borderRadius: '32px 2px 2px 2px', // rounded-strike (base)
    backgroundColor: 'var(--sys-color-solidarityRed-steps-2)',
    color: 'var(--sys-color-worker-ash-base)',
    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.25)' // elevation1Pebble
  }}
  whileHover={{
    fontVariationSettings: '"wght" 600, "GRAD" 150', // Layout-safe weight bloom
    scale: 1.03, // Subtle scale (avoid aggressive 1.1+)
    y: -2, // Lift up
    backgroundColor: 'var(--sys-color-solidarityRed-steps-3)', // +1 tonal step
    boxShadow: '0 8px 16px rgba(0, 0, 0, 0.45)' // elevation3HoverLift
  }}
  transition={motionPresets.typeSpringSlam}
>
  Join the Movement
</motion.button>

Coordinated Changes:

  • ✅ Typography: GRAD 0 → 150 (layout-safe weight increase)
  • ✅ Transform: scale 1.03, y -2px (lift)
  • ✅ Color: solidarityRed-steps-2 → steps-3 (+1 tonal step)
  • ✅ Shadow: elevation1Pebble → elevation3HoverLift

4. Reduced Motion Fallback (Accessibility)

import { useReducedMotion } from 'framer-motion';

const ExpressiveCard = ({ children }) => {
  const shouldReduceMotion = useReducedMotion();

  return (
    <motion.div
      whileHover={shouldReduceMotion ? {} : {
        scale: 1.02,
        y: -4,
        boxShadow: '0 8px 16px rgba(0, 0, 0, 0.45)'
      }}
      transition={shouldReduceMotion ? { duration: 0 } : motionPresets.dragSettle}
    >
      {children}
    </motion.div>
  );
};

Accessibility Requirement: Always respect prefers-reduced-motion: reduce.

Color Amplification Patterns

1. Tonal Stepping for Depth

Token Reference: tokens.jsonsys.color.{colorName}.steps[]

All color families have tonal steps (shadow → base → highlight):

// Example: solidarityRed tonal family
const solidarityRedSteps = [
  '#A02F0F', // steps-0: Shadow (darkest)
  '#C03811', // steps-1: Dark
  '--sys-color-solidarity-red', // steps-2: Base (canonical red)
  '#FF6B3D', // steps-3: Highlight
  '#FF9470', // steps-4: Light
  '#FFB999'  // steps-5: Glow (lightest)
];

// Usage: Hover state steps up +2
<motion.div
  style={{
    backgroundColor: 'var(--sys-color-solidarityRed-steps-2)' // Base
  }}
  whileHover={{
    backgroundColor: 'var(--sys-color-solidarityRed-steps-4)' // +2 steps lighter
  }}
/>

// Usage: Active state steps down -3 (shadow)
<motion.div
  style={{
    backgroundColor: 'var(--sys-color-solidarityRed-steps-2)'
  }}
  whileTap={{
    backgroundColor: 'var(--sys-color-solidarityRed-steps-0)' // Shadow (pressed)
  }}
/>

// Usage: Glow/halo uses lightest step
<div style={{
  boxShadow: '0 0 24px var(--sys-color-solidarityRed-steps-5)' // Lightest glow
}} />

2. Semantic Color Usage

Colors have cultural/emotional meaning, not generic "primary/secondary":

| Color | Semantic Intent | Usage | AVOID Using For | |-------|-----------------|-------|-----------------| | solidarityRed | Resistance heat, primary CTA energy | Primary buttons, urgent emphasis, screenprint moments | Generic "primary" theming, decorative gradients | | charcoalRed | Institutional warning without bureaucracy | Errors, destructive actions, critical alerts | Success states, decorative accents | | inkGold | Temple radiance, optimistic defiance | Halo disks, ornament highlights, celebratory states | Generic "accent" color | | activistSmokeGreen | Calm-meets-activism, landscape | Backwater motifs, melancholy sections, routes | Success/completion states (use solidarityRed instead) | | stencilYellow | Economic critique, attention | Headline accents, key UI warnings, poster type | Generic highlights | | worker-ash | Quiet reverence, primary readability | Body text, icon strokes, dividers | Decorative backgrounds |

3. Glow Effects (Semantic Shadows)

// inkOffset: 2D screenprint shadow
<div style={{
  boxShadow: '2px 2px 0px var(--sys-color-inkGold-base)'
}} />

// solidarityBleed: Urgent glow for critical modals
<div style={{
  boxShadow: '0 0 12px var(--sys-color-solidarityRed-steps-4)'
}} />

// activistSmokeGreen halo: Subtle calm accent
<div style={{
  boxShadow: '0 0 8px var(--sys-color-activistSmokeGreen-steps-5)'
}} />

4. WCAG Contrast Validation

Requirement: WCAG AA minimum contrast ratios:

  • Text: 4.5:1 (normal), 3:1 (large text 18px+)
  • UI components: 3:1
// GOOD: worker-ash (light) on charcoalBackground (dark) = ~12:1 ✅
<p style={{
  color: 'var(--sys-color-worker-ash-base)', // --sys-color-worker-ash
  backgroundColor: 'var(--sys-color-charcoalBackground-base)' // --sys-color-charcoal-background
}}>
  High contrast, readable text.
</p>

// BAD: activistSmokeGreen-steps-2 on charcoalBackground = ~2.8:1 ❌
<p style={{
  color: 'var(--sys-color-activistSmokeGreen-steps-2)', // #3AAF6E (too dark)
  backgroundColor: 'var(--sys-color-charcoalBackground-base)'
}}>
  Fails WCAG AA (insufficient contrast).
</p>

// FIX: Use lighter step for text
<p style={{
  color: 'var(--sys-color-activistSmokeGreen-steps-5)', // #8EEFC0 (lighter)
  backgroundColor: 'var(--sys-color-charcoalBackground-base)'
}}>
  Passes WCAG AA ✅
</p>

Tool: Use browser DevTools Contrast Checker or WebAIM Contrast Checker.

Shape & Shadow Amplification

1. Organic Asymmetry Enforcement

Token Reference: tokens.jsonsys.shape.*

// GOOD: Organic pebble radius (asymmetric)
<button style={{
  borderRadius: '32px 2px 2px 2px' // rounded-strike ✅
}} />

// GOOD: Stone shape for cards (organic blob)
<div style={{
  borderRadius: '42% 58% 45% 55% / 48% 62% 38% 52%' // rounded-megaphone ✅
}} />

// GOOD: Sentry avatar (imperfect circle)
<img style={{
  borderRadius: '98%' // --radius-sentry ✅ (banned: 50%)
}} />

// BAD: Perfect circle (generic, banned)
<div style={{
  borderRadius: '50%' // ❌ BANNED in kerala-rage
}} />

// BAD: Uniform radius (generic)
<button style={{
  borderRadius: '8px' // ❌ Too generic, use rounded-strike
}} />

Enforcement: Audit all components and replace:

  • rounded-fullrounded-sentry (98%)
  • rounded-lg, rounded-xlrounded-strike or rounded-megaphone
  • border-radius: 50%border-radius: 98% (sentry avatars)

2. Semantic Shadow Progression

// elevation1Pebble: Resting state
const elevation1Pebble = '0 2px 4px rgba(0, 0, 0, 0.25)';

// elevation3HoverLift: Hover state (increased depth)
const elevation3HoverLift = '0 8px 16px rgba(0, 0, 0, 0.45)';

// elevation4Float: Modal/dialog (maximum depth)
const elevation4Float = '0 16px 32px rgba(0, 0, 0, 0.55)';

// inkOffset: 2D screenprint shadow (brand accent)
const inkOffset = '2px 2px 0px var(--sys-color-inkGold-base)';

// solidarityBleed: Urgent glow (error/critical)
const solidarityBleed = '0 0 12px var(--sys-color-solidarityRed-steps-4)';

// Usage: Card with hover elevation
<motion.div
  style={{
    boxShadow: elevation1Pebble
  }}
  whileHover={{
    boxShadow: elevation3HoverLift
  }}
  transition={motionPresets.dragSettle}
/>

Emotional State Coupling

Core Principle: Typography + Motion + Color + Shadow must coordinate by semantic intent, not visual preference.

1. Solidarity/Protest State

Intent: Declarative headers, street-poster energy, moments of collective clarity.

<motion.h2
  style={{
    // Typography: solidarityProtest
    fontFamily: 'Fraunces',
    fontVariationSettings: '"wght" 800, "wdth" 120', // Expanded solidarity
    letterSpacing: '0.02em',
    fontSize: '48px',
    // Color: solidarityRed (resistance heat)
    color: 'var(--sys-color-solidarityRed-steps-3)',
    // Shadow: inkOffset (screenprint)
    textShadow: '2px 2px 0px var(--sys-color-inkGold-base)'
  }}
  initial={{ opacity: 0, scale: 0.95 }}
  animate={{ opacity: 1, scale: 1 }}
  // Motion: typeSpringSlam
  transition={motionPresets.typeSpringSlam}
>
  Workers Unite
</motion.h2>

Coupling:

  • Typography: solidarityProtest (wght 800, wdth 120, expanded voice)
  • Motion: typeSpringSlam (600ms overshoot, impact timing)
  • Color: solidarityRed (resistance heat)
  • Shadow: inkOffset (screenprint aesthetic)

2. Labor Pressure State

Intent: Constraint, fatigue, extraction, wage critique, exhaustion.

<motion.div
  style={{
    // Typography: laborExploitationPressure
    fontFamily: 'Work Sans',
    fontVariationSettings: '"wght" 900, "wdth" 75', // Compressed black
    letterSpacing: '0em',
    fontSize: '32px',
    padding: '24px 32px',
    borderRadius: '32px 2px 2px 2px', // rounded-strike
    // Color: charcoalRed (warning without bureaucracy)
    backgroundColor: 'var(--sys-color-charcoalRed-steps-1)',
    color: 'var(--sys-color-worker-ash-base)',
    // Shadow: elevated (weighty)
    boxShadow: '0 8px 16px rgba(0, 0, 0, 0.55)'
  }}
  initial={{ opacity: 0, y: -20 }}
  animate={{ opacity: 1, y: 0 }}
  // Motion: dragSettle (heavy settling)
  transition={motionPresets.dragSettle}
>
  Overworked. Underpaid.
</motion.div>

Coupling:

  • Typography: laborExploitationPressure (wght 900, wdth 75, compressed pressure)
  • Motion: dragSettle (800ms viscous, labor-weight metaphor)
  • Color: charcoalRed (institutional warning)
  • Shadow: elevation3HoverLift (heavy, elevated)

3. Melancholy State

Intent: Between-worlds sections, homesickness, reflective copy, gentle emphasis.

<motion.p
  style={{
    // Typography: melancholyLonging
    fontFamily: 'Libre Bodoni',
    fontVariationSettings: '"wght" 475, "wdth" 98', // Mid-weight oscillation
    letterSpacing: '0em',
    fontSize: '24px',
    // Color: activistSmokeGreen (calm landscape)
    color: 'var(--sys-color-activistSmokeGreen-steps-5)',
    // Shadow: subtle glow
    textShadow: '0 0 8px var(--sys-color-activistSmokeGreen-steps-6)'
  }}
  animate={{
    fontVariationSettings: [
      '"wght" 450, "wdth" 98',
      '"wght" 500, "wdth" 98',
      '"wght" 450, "wdth" 98'
    ],
    opacity: [0.85, 1, 0.85]
  }}
  // Motion: melancholyBreath
  transition={motionPresets.melancholyBreath}
>
  Neither here nor there, suspended between two worlds.
</motion.p>

Coupling:

  • Typography: melancholyLonging (wght 475 oscillating, subtle instability)
  • Motion: melancholyBreath (4000ms breathing, slow oscillation)
  • Color: activistSmokeGreen (calm-meets-activism)
  • Shadow: Subtle glow (lightest tonal step)

Context-Appropriate Scaling

Critical Principle: Expression must scale by context. Hero sections ≠ data tables.

| Context | Weight Contrast | Size Contrast | Motion | Shadow | |---------|-----------------|---------------|--------|--------| | Hero Sections | 9× (100 vs 900) | 6× (12px vs 72px+) | typeSpringSlam | solidarityBleed glow | | Section Headers | 5× (200 vs 900) | 3× (16px vs 48px) | dragSettle | elevation3HoverLift | | Cards/Components | 3× (400 vs 700) | 2× (14px vs 28px) | dragSettle | elevation1Pebble → elevation3HoverLift | | Data Tables | 2× (400 vs 600) | 1.5× (14px vs 21px) | Linear (no spring) | elevation1Pebble | | Forms/Inputs | 3× (400 vs 700) | 2× (14px vs 28px) | typeSpringSlam (CTAs), pulseThrob (errors) | elevation1Pebble |

Example: Hero vs Data Table

// HERO SECTION: Maximum expression (9× weight, 6× size)
<div className="hero">
  <h1 style={{
    fontFamily: 'Fraunces',
    fontVariationSettings: '"wght" 100, "wdth" 100',
    fontSize: '72px', // Large
    color: 'var(--sys-color-worker-ash-steps-6)'
  }}>
    Career Liberation
  </h1>
  <p style={{
    fontFamily: 'Work Sans',
    fontVariationSettings: '"wght" 900, "wdth" 75',
    fontSize: '12px', // Micro (6× contrast)
    textTransform: 'uppercase'
  }}>
    Kerala Rage
  </p>
</div>

// DATA TABLE: Restrained expression (2× weight, 1.5× size)
<table>
  <thead>
    <tr>
      <th style={{
        fontFamily: 'Work Sans',
        fontVariationSettings: '"wght" 600', // Medium
        fontSize: '14px',
        color: 'var(--sys-color-worker-ash-base)'
      }}>
        Job Title
      </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style={{
        fontFamily: 'Work Sans',
        fontVariationSettings: '"wght" 400', // Regular (2× contrast)
        fontSize: '14px',
        color: 'var(--sys-color-worker-ash-steps-5)'
      }}>
        Senior Engineer
      </td>
    </tr>
  </tbody>
</table>

Rationale: Hero sections tolerate extreme contrast because they're scannable and have ample negative space. Data tables prioritize readability and rapid scanning, so restrained contrast prevents visual fatigue.

Usage Examples

Example 1: Amplifying a Hero Section

Before (Conservative):

<div className="hero" style={{ backgroundColor: '--sys-color-charcoal-background', padding: '64px' }}>
  <h1 style={{ fontSize: '48px', fontWeight: 700 }}>
    Find Your Dream Job
  </h1>
  <p style={{ fontSize: '18px', fontWeight: 400 }}>
    AI-powered career guidance
  </p>
</div>

After (Expressive Amplification):

<motion.div
  className="hero"
  style={{
    backgroundColor: 'var(--sys-color-charcoalBackground-steps-2)',
    padding: '96px 64px',
    borderRadius: '42% 58% 45% 55% / 48% 62% 38% 52%' // rounded-megaphone
  }}
  initial={{ opacity: 0 }}
  animate={{ opacity: 1 }}
  transition={motionPresets.dragSettle}
>
  {/* Extreme contrast: 72px hairline vs 12px ultra-black */}
  <motion.h1
    style={{
      fontFamily: 'Fraunces',
      fontVariationSettings: '"wght" 100, "wdth" 100',
      fontSize: '72px',
      letterSpacing: '-0.02em',
      color: 'var(--sys-color-worker-ash-steps-6)',
      textShadow: '0 0 24px var(--sys-color-inkGold-steps-5)' // Halo glow
    }}
    initial={{ y: -20, opacity: 0 }}
    animate={{ y: 0, opacity: 1 }}
    transition={motionPresets.typeSpringSlam}
  >
    Find Your Dream Job
  </motion.h1>

  <motion.p
    style={{
      fontFamily: 'Work Sans',
      fontVariationSettings: '"wght" 900, "wdth" 75',
      fontSize: '12px',
      letterSpacing: '0.05em',
      textTransform: 'uppercase',
      color: 'var(--sys-color-stencilYellow-base)'
    }}
    initial={{ y: 20, opacity: 0 }}
    animate={{ y: 0, opacity: 1 }}
    transition={{ ...motionPresets.typeSpringSlam, delay: 0.1 }}
  >
    AI-Powered Career Liberation
  </motion.p>
</motion.div>

Amplifications Applied:

  • ✅ Extreme contrast: 100 vs 900 weight (9×), 72px vs 12px size (6×)
  • ✅ Variable fonts: Fraunces (display), Work Sans (metadata)
  • ✅ Semantic colors: worker-ash (text), stencilYellow (attention)
  • ✅ Motion: typeSpringSlam entrance (600ms overshoot)
  • ✅ Organic shape: rounded-megaphone (blob container)
  • ✅ Glow effect: inkGold halo on hero text

Example 2: Transforming a Button to Expressive CTA

Before:

<button style={{
  backgroundColor: '--sys-color-solidarity-red',
  color: '#FFFFFF',
  padding: '12px 24px',
  borderRadius: '8px',
  fontWeight: 600
}}>
  Apply Now
</button>

After:

<motion.button
  style={{
    fontFamily: 'Work Sans',
    fontVariationSettings: '"wght" 600, "GRAD" 0',
    fontSize: '18px',
    padding: '16px 32px',
    borderRadius: '32px 2px 2px 2px', // rounded-strike (base)
    backgroundColor: 'var(--sys-color-solidarityRed-steps-2)',
    color: 'var(--sys-color-worker-ash-base)',
    boxShadow: '0 2px 4px rgba(0, 0, 0, 0.25)', // elevation1Pebble
    border: 'none',
    cursor: 'pointer'
  }}
  whileHover={{
    fontVariationSettings: '"wght" 600, "GRAD" 150', // Layout-safe bloom
    scale: 1.03,
    y: -2,
    backgroundColor: 'var(--sys-color-solidarityRed-steps-3)', // +1 tonal step
    boxShadow: '0 8px 16px rgba(0, 0, 0, 0.45)' // elevation3HoverLift
  }}
  whileTap={{
    scale: 0.98,
    y: 0,
    backgroundColor: 'var(--sys-color-solidarityRed-steps-1)', // Shadow step
    boxShadow: '0 1px 2px rgba(0, 0, 0, 0.2)' // Pressed
  }}
  transition={motionPresets.typeSpringSlam}
>
  Apply Now
</motion.button>

Amplifications Applied:

  • ✅ Variable font: Work Sans with GRAD axis (layout-safe hover)
  • ✅ Tonal stepping: solidarityRed-steps-2 → steps-3 (hover), → steps-1 (active)
  • ✅ Multi-axis morph: GRAD + scale + y-translate + shadow
  • ✅ Semantic shape: rounded-strike (archetype)
  • ✅ Semantic motion: typeSpringSlam (600ms overshoot)
  • ✅ Shadow progression: elevation1Pebble → elevation3HoverLift

Example 3: Emotional Card States

const EmotionalCard = ({ state, children }) => {
  const stateConfig = {
    solidarity: {
      typography: { wght: 800, wdth: 120 },
      motion: motionPresets.typeSpringSlam,
      color: 'var(--sys-color-solidarityRed-steps-2)',
      shadow: '2px 2px 0px var(--sys-color-inkGold-base)' // inkOffset
    },
    pressure: {
      typography: { wght: 900, wdth: 75 },
      motion: motionPresets.dragSettle,
      color: 'var(--sys-color-charcoalRed-steps-1)',
      shadow: '0 8px 16px rgba(0, 0, 0, 0.55)' // elevated
    },
    melancholy: {
      typography: { wght: 475, wdth: 98 },
      motion: motionPresets.melancholyBreath,
      color: 'var(--sys-color-activistSmokeGreen-steps-4)',
      shadow: '0 0 8px var(--sys-color-activistSmokeGreen-steps-5)' // subtle glow
    }
  };

  const config = stateConfig[state];

  return (
    <motion.div
      style={{
        fontFamily: 'Fraunces',
        fontVariationSettings: `"wght" ${config.typography.wght}, "wdth" ${config.typography.wdth}`,
        fontSize: '24px',
        padding: '32px',
        borderRadius: '42% 58% 45% 55% / 48% 62% 38% 52%', // --radius-stone
        backgroundColor: config.color,
        color: 'var(--sys-color-worker-ash-base)',
        boxShadow: config.shadow
      }}
      initial={{ opacity: 0, scale: 0.95 }}
      animate={{ opacity: 1, scale: 1 }}
      transition={config.motion}
    >
      {children}
    </motion.div>
  );
};

// Usage
<EmotionalCard state="solidarity">
  Workers' Rights Matter
</EmotionalCard>

<EmotionalCard state="pressure">
  Overworked. Underpaid.
</EmotionalCard>

<EmotionalCard state="melancholy">
  Between two worlds.
</EmotionalCard>

Best Practices

1. Start with Emotional Intent

Before choosing typography, motion, or color, identify the semantic intent:

  • What emotion should this convey? (solidarity, pressure, melancholy, defiance)
  • What action is the user taking? (CTA, reading, reflecting, alerting)
  • What's the context? (hero moment, data display, error state)

Then select coordinated patterns from the tokens.

2. Test with Reduced Motion

Always implement fallbacks for prefers-reduced-motion: reduce:

const shouldReduceMotion = useReducedMotion();
transition={shouldReduceMotion ? { duration: 0 } : motionPresets.typeSpringSlam}

3. Validate Contrast Before Committing

Use browser DevTools or WebAIM Contrast Checker to verify:

  • Text contrast ≥ 4.5:1 (WCAG AA)
  • Large text contrast ≥ 3:1 (18px+)
  • UI component contrast ≥ 3:1

4. Use Context-Appropriate Scaling

  • Hero sections: 9× weight, 6× size ✅
  • Section headers: 5× weight, 3× size ✅
  • Data tables: 2× weight, 1.5× size max ✅
  • Forms: 3× weight, 2× size ✅

Don't apply hero-level expression to data-heavy UIs.

5. Preserve Semantic Token Usage

Never hardcode colors:

// BAD
backgroundColor: '--sys-color-solidarity-red' ❌

// GOOD
backgroundColor: 'var(--sys-color-solidarityRed-base)' ✅

6. Test Scroll-Driven Animations Across Viewports

Scroll-driven typography (weight ramping) must work on mobile, tablet, and desktop:

const weight = useTransform(scrollYProgress, [0, 0.5], [300, 800]); // Clamp at 50% scroll

7. Provide Static Fallbacks for Variable Fonts

If variable fonts fail to load, provide static font-weight fallbacks:

@supports not (font-variation-settings: normal) {
  h1 {
    font-weight: 700; /* Fallback for browsers without variable font support */
  }
}

Anti-Patterns

Typography

  • ❌ Hardcoded font weights (font-weight: 700) → Use fontVariationSettings: '"wght" 700'
  • ❌ Generic fonts (Inter/Roboto as primary) → Use Fraunces/Work Sans/Libre Bodoni
  • ❌ Uniform font weights across UI → Use emotional patterns (solidarityProtest, laborExploitationPressure)
  • ❌ Static fonts everywhere → Exploit variable axes (GRAD, SOFT, WONK, wght, wdth)

Motion

  • ❌ Linear easing (ease: linear) → Use M3 Expressive curve [0.34, 1.56, 0.64, 1]
  • ❌ Uniform spring config → Diversify by semantic intent (slam, settle, throb, breath)
  • ❌ No reduced motion fallback → Always respect prefers-reduced-motion
  • ❌ Aggressive scale hover (scale: 1.2) → Keep subtle (1.03 max)

Color

  • ❌ Hardcoded colors (--sys-color-solidarity-red) → Use --sys-color-solidarityRed-base
  • ❌ Flat color usage (base only) → Use tonal steps for depth
  • ❌ Generic color roles ("primary", "secondary") → Use semantic names (solidarityRed, inkGold)
  • ❌ Low contrast text → Validate WCAG AA (4.5:1 minimum)

Shapes

  • ❌ Perfect circles (border-radius: 50%) → Use 98% (sentry avatars)
  • ❌ Uniform border-radius (8px everywhere) → Use organic asymmetry (--radius-pebble, --radius-stone)
  • ❌ Generic Tailwind classes (rounded-full) → Use semantic tokens

Accessibility

  • ❌ Expression without accessibility → Always validate contrast, reduced motion
  • ❌ Decorative animation without semantic intent → Motion must have purpose
  • ❌ Skipping focus states → Ensure keyboard navigation clarity

Troubleshooting

Issue: Variable fonts not rendering

Solution: Check font loading in CSS:

@font-face {
  font-family: 'Fraunces';
  src: url('/fonts/Fraunces-VariableFont_SOFT,WONK,opsz,wght.ttf') format('truetype-variations');
  font-weight: 100 900;
  font-variation-settings: "SOFT" 0, "WONK" 0, "opsz" 8, "wght" 400;
}

Issue: Layout reflow on hover

Solution: Use GRAD axis instead of wght for hover states:

// BAD: wght causes layout reflow
fontVariationSettings: '"wght" 500' → '"wght" 700' ❌

// GOOD: GRAD is layout-safe
fontVariationSettings: '"wght" 500, "GRAD" 0' → '"wght" 500, "GRAD" 150' ✅

Issue: Motion feels too aggressive

Solution: Reduce scale/translate values and increase duration:

// Aggressive
whileHover={{ scale: 1.1, y: -10 }} ❌

// Subtle
whileHover={{ scale: 1.03, y: -2 }} ✅

Issue: Contrast failing WCAG

Solution: Use lighter tonal steps for text on dark backgrounds:

// BAD: activistSmokeGreen-steps-2 on charcoal = 2.8:1 ❌
color: 'var(--sys-color-activistSmokeGreen-steps-2)'

// GOOD: activistSmokeGreen-steps-5 on charcoal = 5.2:1 ✅
color: 'var(--sys-color-activistSmokeGreen-steps-5)'

Related Skills

Related Files


Remember: Expression without accessibility is exclusion. Amplify with purpose, validate with rigor, and always respect user preferences (reduced motion, contrast needs). The goal is professional expressiveness, not chaotic decoration.