Under active development — things may change.

Fluid Design System

Every block in the library shares a design system that handles spacing, typography, and responsive behavior. This page explains how it works, why it is built this way, and how to customize it.

You do not need to read this page to use blocks — everything works out of the box. But if you want to adjust the spacing, understand why blocks look consistent together, or customize the system for your project, this is where to look.

Why Fluid?

Traditional responsive design relies on breakpoints — fixed screen widths where values change abruptly. A section might use one amount of padding on mobile, a larger amount on tablet, and an even larger amount on desktop. This creates two problems.

Consistency is hard to maintain. When every block defines its own responsive spacing, blocks built at different times end up with slightly different values. Stack five of them on a page and the vertical rhythm feels uneven — someone has to go through each block and manually align the spacing. That work gets repeated on every project.

The transitions are not smooth. At one screen width the spacing is one value; one pixel wider and it jumps to a completely different value. On the growing range of screen sizes that fall between traditional breakpoints, the design just defaults to whatever the smaller breakpoint dictates.

How Fluid Design Solves This

Instead of jumping between fixed values at breakpoints, fluid design scales spacing and font sizes smoothly as the screen gets wider or narrower. A section that needs 32 pixels of padding on a small phone and 72 pixels on a large desktop gets every proportional value in between — automatically. No jumps, no manual overrides.

This is done with a CSS function called clamp() that calculates the right value for any screen width:

CSS
1/* Spacing that scales from 32px (at 360px screen width) to 72px (at 1440px screen width) */
2--space-l-2xl: clamp(2rem, 1.3376rem + 3.231vw, 4.5rem);

You do not need to write or understand these values. They are pre-generated and stored in a CSS file (tokens.css) that you copy into your project once during setup. Blocks reference these values through readable names like my-section or gap-stack — you never interact with the math directly.

The key benefit: every block that uses the same spacing token gets exactly the same spacing at every screen size. Stack a hero, a features section, and a CTA on a page — the rhythm between them is consistent because they all draw from the same scale.

Breakpoints are still used for structural layout changes — like stacking a two-column grid into a single column on small screens. But spacing and font sizes are always fluid. You never need to write responsive spacing overrides for individual blocks.

How the System Is Organized

The fluid design system has three layers, each building on the one before it. You do not need to work with all three directly — most of the time, the React components (Layer 3) handle everything.

Layer 1: CSS Tokens

The foundation is a set of CSS variables in tokens.css, generated using Utopia. These define two scales: a type scale for font sizes and a space scale for padding, margins, and gaps. Every value is a clamp() function tuned to a 360px–1440px screen width range.

On top of the raw scale values, a set of semantic tokens gives meaningful names to common design decisions:

CSS
1:root {
2  --fluid-section: var(--space-l-2xl);          /* section vertical spacing */
3  --fluid-component-gap: var(--space-s-m);      /* gap between items in a component */
4  --fluid-surface-padding: var(--space-m-l);    /* padding inside cards and surfaces */
5  --fluid-inline-padding: var(--space-s-l);     /* horizontal page margins */
6  --surface-radius: 1.5rem;                     /* border radius for cards */
7}

When you use --fluid-section, you are saying "this is the standard vertical spacing between page sections." The actual pixel value depends on the screen size, but the design intent is always clear.

Layer 2: Tailwind Utility Classes

The CSS tokens work but are verbose to use inline. The second layer provides short, readable Tailwind class names that map directly to the tokens:

ClassWhat it does
my-sectionVertical margin between sections
gap-stackGap between stacked items
p-surfacePadding inside a card or surface
px-inlineHorizontal page margins

One class handles every screen size. No responsive prefixes needed for spacing.

Layer 3: React Components

The third layer is a set of React components that apply the right classes for common layout patterns. These are what blocks actually use.

FluidSection wraps each block in a <section> tag with a max-width container.

FluidGrid provides a 12-column CSS grid inside the section. It accepts props for vertical spacing and optional background color. When a background is set, it automatically adds padding and rounded corners to create a visually distinct surface.

SectionHeader handles the common pattern of an eyebrow label, title, description, and optional buttons below. It supports left and center alignment.

Every block in the library follows the same structure:

TSX
1<FluidSection>
2  <FluidGrid marginY={...} bgColor={...}>
3    <div className="col-span-12">
4      <SectionHeader eyebrow={...} title={...} description={...} align={...}>
5        {/* buttons, etc. */}
6      </SectionHeader>
7    </div>
8    {/* block content */}
9  </FluidGrid>
10</FluidSection>

Additional components — FluidStack, FluidCluster, FluidContainer, FluidSubGrid, FluidSurface — handle vertical stacking, horizontal wrapping, width constraints, nested grids, and card surfaces. Each one is a thin wrapper over the fluid utility classes.

Design Controls in the Payload Admin

Every block includes a Design section in the Payload admin panel with three controls that content editors can use without touching code:

ControlWhat it doesOptions
SpacingHow much vertical space above and below the blockCompact, Comfortable (default), Spacious
BackgroundSection background colorDefault (transparent), Muted, Card, Primary, Accent
AlignmentText alignment for the section headerLeft, Center (default)

Spacing maps to different vertical margin values — all still fluid, just at different scales. "Compact" pulls blocks closer together, "spacious" gives them more breathing room.

Background applies a background color using your project's color theme. Choosing "Primary" automatically switches the text to a contrasting color. See Theming for details on how backgrounds work with your color scheme.

Alignment controls whether the section header text is left-aligned or centered.

These controls are added to every block config automatically through shared helper functions, so all blocks get the same design options with no extra setup.

Customizing the System

The entire system inherits from the CSS tokens in tokens.css. To adjust spacing globally, override the semantic tokens in your globals.css:

CSS
1:root {
2  --fluid-section: var(--space-2xl);        /* tighter section spacing */
3  --fluid-surface-padding: var(--space-s);  /* smaller card padding */
4  --surface-radius: 1rem;                   /* less rounded surfaces */
5}

One change propagates through every utility class, every React component, and every block on the page. See Customization for more ways to adapt blocks to your project.

To change the underlying scale — different screen width range, different size ratio — regenerate the tokens using the Utopia calculator and replace the values in tokens.css.


Reference

The tables below list every token, utility class, and component in the system. Use them as a lookup when building or customizing blocks — you do not need to memorize any of this.

Type Scale Tokens

TokenMin (360px)Max (1440px)Usage
--step--211.11px11.52pxFine print
--step--113.33px14.40pxSmall text
--step-016.00px18.00pxBody text
--step-119.20px22.50pxH5
--step-223.04px28.13pxH4
--step-327.65px35.16pxH3
--step-433.18px43.95pxH2
--step-539.81px54.93pxH1
--step-647.78px68.66pxHero/display

Space Scale Tokens

TokenMin → MaxUsage
--space-2xs8px → 9pxTight gaps
--space-xs12px → 14pxSmall gaps
--space-s16px → 18pxComponent-level gaps
--space-m24px → 27pxMedium spacing
--space-l32px → 36pxSection-level gaps
--space-xl48px → 54pxLarge section spacing
--space-2xl64px → 72pxHero spacing
--space-3xl96px → 108pxMajor sections

Semantic Tokens

TokenValuePurpose
--fluid-section--space-l-2xlStandard section vertical spacing
--fluid-section-sm--space-s-lCompact section spacing
--fluid-section-lg--space-3xl-4xlLarge section spacing
--fluid-section-xl--space-4xl-5xlExtra-large section spacing
--fluid-component-gap--space-s-mGap between items within a component
--fluid-surface-padding--space-m-lPadding inside card/surface containers
--fluid-inline-padding--space-s-lHorizontal page margins
--surface-radius1.5remBorder radius for surfaces/cards

Utility Classes

Section Spacing

ClassPurpose
py-sectionStandard section vertical padding
my-sectionStandard section vertical margin
my-section-smCompact section margin
my-section-lgLarge section margin
my-section-xlExtra-large section margin

Component Gaps

ClassPurpose
gap-section-itemsGap between major items in a section
gap-section-innerGap between sub-items within a section
gap-stack-sm / gap-stack / gap-stack-lgVertical flex gap variants
gap-cluster-sm / gap-cluster / gap-cluster-lgHorizontal flex gap variants

Surface Padding

ClassPurpose
p-surface-smCompact surface padding
p-surfaceStandard surface padding
p-surface-lgLarge surface padding

Inline Padding

ClassPurpose
px-inline-smNarrow horizontal margins
px-inlineStandard horizontal page margins
bleed-inlineNegative margins to break out of container

Layout Components

ComponentPurposeKey Props
FluidSectionOutermost wrapper — <section> + containerclassName, bgClassName
FluidGrid12-column CSS grid with spacing and optional backgroundmarginY (sm/lg/xl), bgColor, columnGap
FluidSubGridCSS subgrid for nested grid layoutsclassName
FluidContainerWidth-constrained containermaxWidth (narrow/wide/full)
FluidStackVertical flex layoutgap (sm/md/lg)
FluidClusterHorizontal flex layout (wrapping)gap (sm/md/lg)
FluidSurfaceCard/surface with radius and paddingpadding (sm/md/lg)

Typography Components

ComponentPurpose
SectionHeaderComposite: eyebrow + title + description + children slot
SectionTitleStandalone section title
SectionDescriptionStandalone description text
EyebrowSmall label above a title

Admin Design Fields

FieldOptionsDefaultPurpose
spacingPresetcompact, comfortable, spaciouscomfortableControls FluidGrid vertical margin
backgroundThemedefault, muted, card, primary, accentdefaultSets section background color
contentAlignmentstart, centercenterControls text alignment