How I built a trilingual design system in one evening
LAUSANNE, Switzerland —
One night, one backported module, three brands. Here’s the story.
The starting point
April 22nd, 6 PM. I receive a screenshot — a tidy folder with 25 HTML pages (colors, buttons, cards, forms…) alongside a 468-line colors_and_type.css, 52 self-hosted .woff2 fonts and a SKILL.md manifest for AI agents.
It’s the ACiD Studio design system, extracted from production code. A brand playbook for the designers, developers and AIs that work on the project.
A technical file, not a showcase. Question: what if we put it online?
The bet
A public design system is a serious signal. Stripe, Vercel, Shopify publish theirs — because it’s part of their sales pitch. “See, we have a real system, not a copy-pasted theme.”
For a one-person agency with a CHF 2,999 entry ticket, showing acidstudio.ch/design-system/ flips the perception immediately: “they’re structured like a real company.”
Constraint: ship it in one evening, without breaking the homepage, without bloating the site, in the three languages (FR / EN / ES) of the site.
The architecture
Phase 1 — Static publishing
Instead of a separate subdomain or dedicated repo, I copied the design system folder straight into frontend/public/design-system/. Astro automatically serves public/ at root → acidstudio.ch/design-system/buttons.html works without config.
Win: zero DNS, zero SSL, zero extra deployment pipeline.
Phase 2 — Astro landing page
An Astro page src/pages/design-system.astro that:
- Reuses the site Layout (navbar + footer unchanged)
- Displays a giant “CODE & BOLDNESS” hero in the brand typography
- Shows the 25 previews in a grid, each in a scaled 50% iframe
- Closes with a dark CTA featuring the site’s signature acid radial orb
No static screenshots, no image build — the original HTML previews are loaded as-is, just miniaturized. A change in any preview appears automatically in the grid.
Phase 3 — Internationalization
Three versions: /design-system/ (FR), /en/design-system/ (EN), /es/design-system/ (ES).
Pattern used — the same as the project’s BlogListing.astro:
- A shared
DesignSystemPage.astrocomponent with alangprop - Three 10-line wrappers in
src/pages/,src/pages/en/,src/pages/es/ - All strings translated via a
labelsobject keyed by language
Translated hero: CODE & AUDACE (FR) / CODE & BOLDNESS (EN) / CODE & AUDACIA (ES).
The small technical hells
The unreadable TOC
First render: black background, white Outfit text, 14px, weight 600. On macOS Retina, letters appear blurry and distorted — an anti-aliasing halo creates a bizarre script effect.
Diagnosis: Outfit (display font) is optimized for large sizes. At 14px, it’s less readable than Inter (UI font) with the same weight.
Fix: font swap + text-rendering: optimizeLegibility + generous letter-spacing (0.02em) + horizontal padding bumped to 22px.
Clashing CSS tokens
The project uses shadcn/ui which defines --color-accent in HSL. My component also used --color-accent, but with the acid value #c8f135. Silent conflict — shadcn won.
Fix: module-specific namespace. All my tokens become --ds-* with chained fallbacks:
background: var(--ds-accent, var(--acid, #c8f135));
Three fallback levels: project override, native ACiD token, hardcoded value. The project can override at any level without touching the component.
The backport — from one-shot to reusable module
When a feature deserves to live in 2+ projects, it moves out into acid-starter — the template repo that centralizes all reusable modules.
I created modules/design-system/v1.0.0 with:
- The shared
DesignSystemPage.astrocomponent - The three Astro wrappers
[lang]/design-system.astro - A
design-system.config.jsonwith every configurable field - A README covering install and configuration
Configurable: brand name, accent text (AUDACE vs BOLDNESS vs AUDACIA), active languages (FR-only or trilingual), CTA hrefs, preview list, logo.
Generic by design: zero hardcoded colors, everything flows through CSS variables. The accent becomes amber for a restaurant, magenta for a therapy brand, acid for the mother agency — automatically.
The outcome
In 4 hours:
acidstudio.ch/design-system/→ trilingual, 25 components, stats, commercial CTAdesign-systemv1.0.0 module inacid-starter- Deployments on two client projects tuned to their brand:
alaclasse-restaurant.ch/design-system/(gold + Playfair/Cormorant) andmagnetismetherapeutique.ch/design-system/(violet + DM Serif/Raleway in dark theme)
Commercial deliverable: every future ACiD Studio client gets their public design system to share. Not “like Stripe’s”. Theirs, with their colors and vocabulary.
Takeaways
- Publishing a technical showcase remains the cheapest marketing tool for an agency: the work is already done, you just need to package it.
- Leveraging existing project conventions (
BlogListing.astropattern, CSS tokens, import aliases) saved me 50% of the time. The fewer decisions, the faster I code. - The moment a one-shot becomes reusable is precise — if 2+ projects will want it, head to
acid-starterfrom v1.0.
The ACiD Studio design system is here: acidstudio.ch/en/design-system.
If you’re starting a web project and want your own, get in touch.