Styling Templates

Style your templates with Tailwind utility classes and shadcn/ui’s beautiful design system.

Quick Start

export default function MyTemplate({ title, tw }) {
  return (
    <div style={tw('flex items-center justify-center w-full h-full bg-gradient-to-br from-blue-600 to-purple-700')}>
      <h1 style={tw('text-7xl font-bold text-white')}>
        {title}
      </h1>
    </div>
  );
}

The tw() Function

Every template receives a tw() function that converts Tailwind classes to inline styles compatible with Satori:

// Tailwind classes
tw('flex items-center justify-center p-8 bg-blue-500')

// Converts to inline styles:
{
  display: 'flex',
  alignItems: 'center',
  justifyContent: 'center',
  padding: '2rem',
  backgroundColor: '#3b82f6'
}

Basic Usage

export default function Banner({ title, subtitle, tw }) {
  return (
    <div style={tw('w-full h-full p-12 bg-gray-50')}>
      <h1 style={tw('text-6xl font-bold text-gray-900 mb-4')}>
        {title}
      </h1>
      <p style={tw('text-2xl text-gray-600')}>
        {subtitle}
      </p>
    </div>
  );
}

Combining with Custom Styles

Mix Tailwind classes with custom styles using the spread operator:

export default function CustomGradient({ title, tw }) {
  return (
    <div
      style={{
        ...tw('flex flex-col items-center justify-center w-full h-full p-20'),
        background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
      }}
    >
      <h1 style={tw('text-8xl font-bold text-white')}>{title}</h1>
    </div>
  );
}

shadcn/ui Design System

loopwind uses shadcn/ui’s design system by default, providing semantic color tokens for beautiful, consistent designs.

Default Color Palette

All templates automatically have access to these semantic colors defined in .loopwind/loopwind.json:

colors: {
  // Primary colors
  primary: '#18181b',           // Main brand color
  'primary-foreground': '#fafafa',

  // Secondary colors
  secondary: '#f4f4f5',         // Subtle accents
  'secondary-foreground': '#18181b',

  // Background
  background: '#ffffff',        // Page background
  foreground: '#09090b',        // Main text color

  // Muted
  muted: '#f4f4f5',            // Subtle backgrounds
  'muted-foreground': '#71717a', // Muted text

  // Accent
  accent: '#f4f4f5',           // Highlight color
  'accent-foreground': '#18181b',

  // Destructive
  destructive: '#ef4444',       // Error/danger states
  'destructive-foreground': '#fafafa',

  // UI Elements
  border: '#e4e4e7',           // Border color
  input: '#e4e4e7',            // Input borders
  ring: '#18181b',             // Focus rings
  card: '#ffffff',             // Card background
  'card-foreground': '#09090b',
}

Using Semantic Colors

export default function SemanticCard({ title, description, price, tw }) {
  return (
    <div style={tw('bg-card border border-border rounded-lg p-6')}>
      <h2 style={tw('text-card-foreground text-2xl font-bold mb-2')}>
        {title}
      </h2>
      <p style={tw('text-muted-foreground mb-4')}>
        {description}
      </p>
      <div style={tw('text-primary text-3xl font-bold')}>
        ${price}
      </div>
    </div>
  );
}

Opacity Modifiers

Use Tailwind’s slash syntax for opacity with any color:

export default function OpacityExample({ tw }) {
  return (
    <div style={tw('bg-primary/50')}>          {/* 50% opacity */}
      <p style={tw('text-muted-foreground/75')}> {/* 75% opacity */}
        Subtle text
      </p>
      <div style={tw('border border-border/30')}> {/* 30% opacity */}
        Faint border
      </div>
    </div>
  );
}

Supported syntax:

  • bg-{color}/{opacity} - Background with opacity
  • text-{color}/{opacity} - Text with opacity
  • border-{color}/{opacity} - Border with opacity

Text Hierarchy

// Primary text
tw('text-foreground')

// Secondary/muted text
tw('text-muted-foreground')

// Accent/brand text
tw('text-primary')

// Destructive/error text
tw('text-destructive')

Backgrounds

// Page background
tw('bg-background')

// Card/elevated surfaces
tw('bg-card')

// Subtle backgrounds
tw('bg-muted')

// Accent backgrounds
tw('bg-accent')

Supported Tailwind Classes

Layout

  • Display: flex, inline-flex, block, inline-block, hidden
  • Flex Direction: flex-row, flex-col, flex-row-reverse, flex-col-reverse
  • Justify: justify-start, justify-end, justify-center, justify-between, justify-around
  • Align: items-start, items-end, items-center, items-baseline, items-stretch

Spacing

  • Padding: p-{n}, px-{n}, py-{n}, pt-{n}, pb-{n}, pl-{n}, pr-{n}
  • Margin: m-{n}, mx-{n}, my-{n}, mt-{n}, mb-{n}, ml-{n}, mr-{n}
  • Gap: gap-{n}, gap-x-{n}, gap-y-{n}
  • Sizes: 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 56, 64

Examples:

tw('p-4')      // padding: 1rem
tw('px-8')     // paddingLeft: 2rem, paddingRight: 2rem
tw('m-6')      // margin: 1.5rem
tw('gap-4')    // gap: 1rem

Sizing

  • Width: w-{n}, w-full, w-screen, w-1/2, w-1/3, w-2/3
  • Height: h-{n}, h-full, h-screen

Examples:

tw('w-full')   // width: 100%
tw('h-64')     // height: 16rem
tw('w-1/2')    // width: 50%

Typography

  • Font Size: text-xs, text-sm, text-base, text-lg, text-xl, text-2xl, text-3xl, text-4xl, text-5xl, text-6xl, text-7xl, text-8xl, text-9xl
  • Font Weight: font-thin, font-light, font-normal, font-medium, font-semibold, font-bold, font-extrabold, font-black
  • Text Align: text-left, text-center, text-right
  • Line Height: leading-none, leading-tight, leading-normal, leading-relaxed, leading-loose

Colors

All standard Tailwind colors plus shadcn semantic colors:

Standard colors:

  • text-{color}-{shade}, bg-{color}-{shade}, border-{color}-{shade}
  • Colors: red, blue, green, yellow, purple, pink, gray, indigo, teal, orange
  • Shades: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900

shadcn semantic colors:

  • text-foreground, text-primary, text-muted-foreground, text-destructive
  • bg-background, bg-card, bg-muted, bg-accent, bg-primary
  • border-border, border-input
tw('text-blue-500')        // Standard Tailwind color
tw('bg-purple-600')        // Standard Tailwind color
tw('text-primary')         // shadcn semantic color
tw('bg-card')              // shadcn semantic color

Position & Layout

  • Position: relative, absolute, fixed, sticky
  • Inset: inset-0, top-0, bottom-0, left-0, right-0
  • Z-Index: z-0, z-10, z-20, z-30, z-40, z-50

Borders

  • Border Width: border, border-{n}, border-t, border-b, border-l, border-r
  • Border Radius: rounded, rounded-sm, rounded-md, rounded-lg, rounded-xl, rounded-2xl, rounded-3xl, rounded-full
  • Border Color: border-{color}-{shade}, border-border, border-input

Effects

  • Shadow: shadow-sm, shadow, shadow-md, shadow-lg, shadow-xl, shadow-2xl
  • Opacity: opacity-0, opacity-25, opacity-50, opacity-75, opacity-100

Filters

  • Blur: blur-none, blur-sm, blur, blur-md, blur-lg, blur-xl
  • Brightness: brightness-0, brightness-50, brightness-100, brightness-150, brightness-200
  • Contrast: contrast-0, contrast-50, contrast-100, contrast-150, contrast-200

Gradients

Linear Gradients

// Gradient direction
tw('bg-gradient-to-r')      // left to right
tw('bg-gradient-to-br')     // top-left to bottom-right
tw('bg-gradient-to-t')      // bottom to top

// Gradient colors
tw('from-blue-500')         // Start color
tw('via-purple-500')        // Middle color
tw('to-pink-500')           // End color

// Complete gradient
tw('bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500')

Gradient Examples

export default function GradientCard({ title, tw }) {
  return (
    <div style={tw('w-full h-full bg-gradient-to-br from-cyan-500 to-blue-600 p-12')}>
      <h1 style={tw('text-white text-6xl font-bold')}>
        {title}
      </h1>
    </div>
  );
}

Custom Theme Colors

You can override the default shadcn colors or add your own custom colors in .loopwind/loopwind.json:

{
  "theme": {
    "colors": {
      "primary": "#3b82f6",
      "primary-foreground": "#ffffff",
      "accent": "#10b981",
      "brand": "#ff6b6b"
    }
  }
}

Then use these custom colors in your templates:

tw('text-brand')    // Uses your custom brand color
tw('bg-primary')    // Uses your custom primary color
tw('bg-accent')     // Uses your custom accent color

Auto-Detection from tailwind.config.js

loopwind automatically detects and loads your project’s Tailwind configuration:

your-project/
├── tailwind.config.js  ← Automatically detected
└── .loopwind/
    ├── loopwind.json
    └── templates/

This includes:

  • Custom colors
  • Custom spacing values
  • Custom fonts
  • Theme extensions
  • Custom utilities

Complete Example

export default function ModernCard({ 
  tw, 
  image,
  title, 
  description, 
  category,
  author,
  avatar 
}) {
  return (
    <div style={tw('w-full h-full bg-card')}>
      {/* Hero image */}
      <div style={tw('relative h-2/3')}>
        <img 
          src={image(hero)} 
          style={tw('w-full h-full object-cover')}
        />
        {/* Category badge */}
        <div style={tw('absolute top-4 left-4 bg-primary/90 backdrop-blur px-4 py-2 rounded-full')}>
          <span style={tw('text-sm font-semibold text-primary-foreground')}>
            {category}
          </span>
        </div>
      </div>
      
      {/* Content */}
      <div style={tw('h-1/3 p-8 flex flex-col justify-between')}>
        <div>
          <h2 style={tw('text-3xl font-bold text-foreground mb-2')}>
            {title}
          </h2>
          <p style={tw('text-muted-foreground line-clamp-2')}>
            {description}
          </p>
        </div>
        
        {/* Author */}
        <div style={tw('flex items-center gap-3')}>
          <img 
            src={image(avatar)} 
            style={tw('w-10 h-10 rounded-full border-2 border-border')}
          />
          <span style={tw('text-sm text-muted-foreground')}>
            {author}
          </span>
        </div>
      </div>
    </div>
  );
}

Why This Approach?

  • Semantic naming: text-primary instead of text-blue-600
  • Consistency: All templates use the same design language
  • Flexibility: Easy to customize entire theme
  • Accessibility: Pre-tested color contrasts
  • Modern: Same system as shadcn/ui components
  • Familiar: Standard Tailwind syntax

Next Steps