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 opacitytext-{color}/{opacity}- Text with opacityborder-{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-destructivebg-background,bg-card,bg-muted,bg-accent,bg-primaryborder-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-primaryinstead oftext-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