Skip to content
MocklyDocs

Build

Site theme

Your brand's colors, text styles, fonts, shadows, corners, spacing, and motion in one file, each a class.

A brand is a handful of decisions made once: its colors, its type, its font, how round its corners are, how deep its shadows, how much room it gives a section, and how things move. In Mockly they live in one file, components/site-theme.tsx. Each becomes a class the whole site uses, so changing one changes every page that uses it. The studio's Site Styles changes the same file without code.

components/site-theme.tsx
export const siteTheme = {  colors: {    brand: { 50: "#eef2ff", 600: "#4f46e5", 700: "#4338ca" },    ink: "oklch(0.21 0.04 262)",  },  text: {    "heading-1": { size: "5xl", weight: "bold", tracking: "tight" },    body: { size: "base", leading: "relaxed" },  },  fonts: { sans: "IBM Plex Sans, system-ui, sans-serif" },  shadows: { panel: "0 1px 2px rgb(15 23 42 / 0.05), 0 10px 30px -12px rgb(15 23 42 / 0.2)" },  radii: { card: "0.75rem" },  spacing: { section: "6rem" },  durations: { quick: "150ms" },  easings: { glide: "cubic-bezier(0.22, 1, 0.36, 1)" },  animations: {    "hero-in": {      keyframes: { from: { opacity: 0, translate: "0 1rem" } },      duration: "600ms",      easing: "glide",    },  },};
components/pricing-card.tsx
export function PricingCard({ plan, price }: { plan: string; price: string }) {  return (    <div class="rounded-card bg-white p-8 shadow-panel transition-shadow duration-quick ease-glide hover:shadow-lg">      <h3 class="text-heading-1 text-ink">{plan}</h3>      <p class="mt-4 text-body text-brand-600">{price}</p>    </div>  );}

Every part is optional, and the file is an ordinary component file otherwise: a page can import siteTheme like any constant. Without the file, a site's classes are Tailwind's own.

Colors#

A color is one value, such as ink, or shades of one, such as brand's 50 to 700. It works in every class that takes a color: bg-brand-600, text-ink, border-brand-200, ring-brand-600/20, hover:bg-brand-700.

  • A value is hex, "#4f46e5" or "#fff", or oklch, "oklch(0.47 0.19 262)": lightness from 0 to 1 (or 0% to 100%), chroma up to 0.5, and a hue in degrees.
  • Opacity goes in the class, bg-brand-600/50, not in the color.
  • Names are lowercase letters and digits, starting with a letter, with no dashes. Shades are whole numbers from 0 to 999.

Text styles#

A text style is one class, text-heading-1, for a font size and, if you like, a weight, a line height (leading), and letter spacing (tracking). Each is a step of Tailwind's scales:

FieldSteps
sizexs, sm, base, lg, xl, 2xl to 9xl
weightthin, extralight, light, normal, medium, semibold, bold, extrabold, black
leadingnone, tight, snug, normal, relaxed, loose
trackingtighter, tight, normal, wide, wider, widest

As in Tailwind, a class on the element beats that part of it: text-heading-1 font-normal isn't bold, and text-heading-1 max-md:text-3xl is smaller on a phone.

Fonts, shadows, corners, and spacing#

KeyA value isIts classes
fontsa font stack: names separated by commasfont-<name>
shadowsa box shadow, as CSS writes itshadow-<name>
radiia length, such as "0.75rem", or a percentagerounded-<name>, and rounded-t-<name> and the other sides
spacinga length, such as "6rem"wherever spacing goes: p-section, mt-section, -mt-section, gap-section, w-section, space-y-section
  • A font named sans replaces Tailwind's own, so it's every page's font. serif and mono replace theirs too. The font files themselves are the pages' fonts (see Images, fonts, and files); a theme font can't share its class with one, such as font-inter.
  • A shadow is up to 8 layers separated by commas, each two to four lengths, inset if it's inside, and a color.
  • Each takes variants like any class: md:p-section, hover:shadow-panel.

Motion#

KeyA value isIts classes
durationsa time, "150ms" or "0.6s"duration-<name> and delay-<name>, for transitions
easingsan easing, as CSS writes it: "ease-out", "cubic-bezier(…)", "steps(4)", or "linear(…)"ease-<name>
animationskeyframes and how they playanimate-<name>

An animation has keyframes, and a duration. It may have an easing, a delay, iterations (a number, or "infinite"), a direction, and a fill. Its duration and delay can be a theme duration's name, and its easing a theme easing's.

TSX
animations: {  breathe: {    keyframes: { "0%, 100%": { opacity: 1 }, "50%": { opacity: 0.6 } },    duration: "2s",    iterations: "infinite",  },},
  • A keyframe is at from, to, a percentage, or several, and sets what it changes, by CSS's name or JavaScript's (backgroundColor): opacity, transforms, filters, clip paths, colors, shadows, background position and size, letter spacing, stroke dashes, width, height, and insets.
  • Values are CSS's numbers, words, colors, and functions. Quotes, comments, semicolons, braces, url(), and var() aren't allowed, so a value can't reach beyond itself.
  • For people who ask for less motion, add motion-reduce:animate-none beside the class. An animation plays for everyone otherwise, as Tailwind's do. For motion that's already careful, use reveal and transitions; see Animations.

A name with a dash is written in quotes, as "hero-in" is above.

Names Mockly keeps#

A theme never changes a class Tailwind already has. Each name is lowercase letters and digits in parts joined by dashes, and Mockly refuses one that would:

  • name one of Tailwind's colors (indigo), or a word its classes use (a color named x would make border-x a color instead of a width);
  • start with a word Tailwind's classes of its kind use: rounded-t, p-x, shadow-lg, font-bold, ease-in, animate-spin;
  • start a text style's or a shadow's name with a theme color's (shadow-brand is the shadow's color);
  • be one of Tailwind's own animations (fade-in), or one of CSS's easings (ease).

When publishing, Mockly also asks UnoCSS itself whether the theme changes a class your code uses. Each problem is an error with its code (MK7001 to MK7005, MK7011, and MK7012), at the name; see Diagnostics.

In the studio#

Site Styles, 🎨 in the sidebar, shows the theme as cards: each color with its shades, each text style with its "Aa", each font, shadow, corner, and length drawn with its own value, and each animation with Play. Change a value, add one, or rename one with ✎: a rename changes every class in the site that uses it, as one change you can undo. Keyframes and new animations are the file's: Edit keyframes in the theme file opens it.

In Design mode, the style panel lists the theme's colors, text styles, corner radii, shadows, and spacing first among the choices for each.