A template that looks good in the first screenshot is easy. A template that still looks good after you’ve replaced half the content is hard. That’s the difference a design system makes.
This post walks through the decisions behind RicoFast’s design system — what we chose, what we rejected, and why.
Type — two fonts, one job each
Most SaaS templates pick a single sans-serif and call it a day. We use two fonts, and they have strictly separated roles:
| Font | Role | Where |
|---|---|---|
| Instrument Serif | Display | Hero titles, section headlines, page H1s — .font-brand class only |
| Inter | Everything else | Body, navigation, labels, buttons, captions |
Instrument Serif is the personality. It does the editorial work — it’s what gives the template that “thought went into this” feel without being precious about it. Inter is the work font, optimized for screens at small sizes, where almost all the actual reading happens.
The rule is enforced in global.css:
@theme {
--font-brand: "Instrument Serif", Georgia, serif;
--font-sans: "Inter", system-ui, sans-serif;
}
.font-brand {
font-family: var(--font-brand);
font-weight: 400;
}
Note the weight is always 400. Instrument Serif at heavy weights gets clumsy. Restraint here matters.
Color — one accent, one canvas
The full palette has thirty-plus tokens, but the soul of it is three colors:
--color-primary: #2d6dc3; /* the blue. links, headings, CTA */
--color-accent: #fad13b; /* the gold. badges, highlights — sparingly */
--color-bg-primary: #fdfaf5; /* the canvas. warm white, not pure white */
The canvas is the most important and the most opinionated. A warm #fdfaf5 (instead of pure #ffffff) is what makes the template feel like a designed product rather than a generic startup landing page. It costs you nothing technically and gains you a real visual identity.
Dark mode flips the canvas to #0b1220 — a deep navy, not black. Pure black against a warm-white site feels jarring; this navy is the same hue family as the primary blue, which makes the transition feel intentional.
Spacing — base 4, exponentially nothing
Everything is a multiple of 4px. Specifically:
4, 8, 12, 16, 24, 32, 40, 48, 64, 80, 96, 128
Sections use vertical padding of py-16 md:py-24 (64px / 96px). Cards use p-6 (24px) for compact or p-10 (40px) for spacious. The page max-width is 1200px, inner content 800px.
These numbers aren’t arbitrary — they form a coherent rhythm that lets sections breathe without anyone having to consciously notice the spacing.
Borders — dashed, primary-tinted
Most templates default to solid 1px neutral borders. We default to dashed, especially for section dividers:
<div class="w-full border-b border-dashed border-neutral-200"></div>
Why dashed? It’s a quieter divider. Solid borders shout I am separating two things; dashed borders whisper it. On a content-dense SaaS page where you might have 8-12 sections, that whisper is the difference between a site that breathes and one that feels like a form.
For cards we use a primary/10 tint — 1px solid rgba(45, 109, 195, 0.1) — so even the borders carry a hint of brand color.
Motion — subtle, purposeful, never decorative
Two animation systems coexist:
- AOS (Animate On Scroll) —
data-aos="fade-up-sm"for scroll reveals. Always withdata-aos-once="true"so it doesn’t replay every time the element re-enters the viewport. - motion.js — reserved for orchestrated entrances (the Hero text stagger via
AnimatedText), and for anything that needs a timeline.
The rules in docs/DESIGN.md:
- Duration 200–600ms for interactions, 400–800ms for scroll reveals
- Honor
prefers-reduced-motion - Prefer
transformandopacityover layout properties - Every animation should communicate something — entrance, state change, feedback
No animation just for the sake of “this section needs movement.”
Why all of this matters
A design system is a series of small constraints that, taken together, make a template look intentional. When you fork RicoFast and replace the Hero copy, swap the primary color, and add three new sections, the system holds: your version still looks coherent because the underlying decisions about type pairing, spacing rhythm, and motion vocabulary are doing the heavy lifting.
You don’t have to be a designer to ship a designed product. You just have to not break the system.
The full reference lives at docs/DESIGN.md. Read it once before your first major change — it’s the cheat sheet for everything in the template.