hero · design system
Odisea: from overengineered tokens to AI-powered design operations
I restructured a legacy token architecture, reducing it from three layers to two; I brought it 100% in line with Tailwind; I developed the rules that enable AI to generate production-quality Figma components; and then, together with a developer, I built the tool to generate code using our own components.
specs
hero-visual
context
A growing company, a fragmented design language
Civitatis grew into a multi-platform company: B2C, B2B, and internal operations, built by 5 product teams in parallel. The visual language hadn't kept pace, web, iOS, and Android drifted apart.
A system existed in Figma and Storybook, but as a static library: disconnected from code, opaque token names, no governance.
The design system wasn't broken, it was never designed to scale with the company.
context
Civitatis grew into a multi-platform company, 5 product teams shipping to web, iOS, and Android, but the design system stayed a static Figma library: disconnected from code, opaque tokens, no governance.
my-role
As Principal Product Designer IC, I restructured the token architecture, defined the AI rules for Figma-to-code generation, and designed Odisea Playground alongside the developer who built it.
the-problem
Over-engineered foundations, under-delivered components
The legacy system was built at the wrong abstraction level, harder to use than going without it.
Opaque token names
Names like sys-color-surface-container-highest required a lookup table. Designers avoided tokens altogether.
Massive duplication
Hundreds of tokens mapped to the same values, more tokens than design decisions.
Incomplete components
~15 components, most incomplete or out of sync with production code. Teams built one-offs instead.
No shared language
Figma didn't match CSS, which didn't match the documentation.
the-problem
The legacy token architecture was over-engineered: opaque sys-* names, hundreds of duplicated tokens, ~15 half-finished components, and no shared vocabulary between Figma and code.
vision
A design system that speaks the same language as code
The goal: a system lean enough to be learnable, structured enough to be automatable, and aligned with the stack so designers and developers communicate without translation.
- Tailwind alignment: one vocabulary for Figma and code.
- Two token layers: primitives and semantics, nothing more.
- AI-ready rules: constraints that let AI create production-quality components.
- Cross-platform: one system for web, iOS, and Android.
vision
Build a system lean enough to be learnable, structured enough to be automatable, and aligned 1:1 with Tailwind, one vocabulary for Figma, code, and AI, across web, iOS, and Android.
token-architecture
From three layers of abstraction to two
The legacy model had three layers: reference → system → component tokens. The sys-* layer added complexity without clarity, so I collapsed it to two: primitives (raw values) and semantics (design decisions).
sys-color-surface-container-highest sys-color-on-surface-variant sys-typescale-body-medium-size bg-secondary text-muted text-base The Tailwind decision
Matching token names to Tailwind utility classes eliminated an entire category of translation errors, rounded-lg in Figma is rounded-lg in code, and made the system natively legible to AI tools that already speak Tailwind.
token-architecture
I collapsed a three-layer token system (ref → sys → component) into two: primitives and semantics. sys-color-surface-container-highest became bg-secondary. Aligning tokens with Tailwind gave designers, developers, and AI tools one shared vocabulary.
foundations
Building the bedrock: typography, spacing, and systematic patterns
Every component inherits from a small set of constrained, purposeful scales.
Typography
A type scale from text-xs to text-5xl, mapped to Tailwind's defaults. Two families: display and body.
Spacing
space-1 through space-16, mirroring Tailwind's naming exactly, no semantic layer needed.
Border radius
rounded-sm to rounded-full, with semantic radius tokens mapped to specific UI contexts.
Colors
A curated palette of brand, feedback, and neutral tokens, each mapped to a semantic role.
Library architecture
I split the system into modular, scoped Figma libraries, each team consumes only what it needs.
Foundations
Tokens, scales, and base styles, the source of truth every library inherits from.
Icons
A unified icon set, versioned independently from components.
Components
Shared buttons, inputs, cards, and patterns used across all products.
B2C
Booking flows, search, and traveler-facing patterns.
B2B
Data tables, dashboards, and back-office patterns.
iOS
HIG-aligned controls and native patterns on Odisea tokens.
Android
Material-aligned components on Odisea foundations.
ai-workflow
Meta-design: I design the rules, AI executes within them
I designed the quality contract, tokens, rules, and validation gates, so AI can now build components that pass the same bar I used to enforce by hand.
Four layers
Skills
Markdown files teaching AI the system's conventions: brand guidelines, token usage, Figma API patterns.
Rules
Typography, spacing, and color constraints the AI reads before every action.
Playbooks
Step-by-step procedures: creating a component, setting up variants, binding tokens, structuring auto-layout.
Validation gates
Checkpoints the AI must pass: token binding, naming conventions, auto-layout structure, accessibility compliance.
ai-workflow
In 2025 I built a four-layer system, skills, rules, playbooks, and validation gates, that lets AI create production-quality Figma components within constraints I define. I designed the quality contract; AI executes within it.
how-it-works
The “bind immediately” philosophy
Every value is bound to a token at creation, never retrofitted. AI doesn't set fill: #1a1a1a, it sets fill: bg-primary from the start, eliminating an entire class of drift.
components
Components in production
Shipped across web, iOS and Android, built on the token architecture and foundations above.
components
30+ production components shipped across three platforms, built on the token architecture and foundations above.
playground
Vibe coding with production-valid output
Once the system existed, the next problem was obvious: designers still sketched in Figma, handed off specs, and waited for a developer to turn them into real UI. Every step introduced translation loss.
The insight was simple: what if you could iterate through conversation with an AI — but using our actual components? Not something that looks like our DS. Our code. The output would be production-valid from the first prompt, because there’s nothing to correct.
I don’t make mockups anymore. I make working prototypes — in production-ready code, from the first prompt.
That’s what I designed and built with one developer: Odisea Playground.
Live preview
Components render as the AI edits them — no reload, no context switch. The designer sees changes the moment they’re written.
Point-and-tweak
Click any element to anchor the next request to it. “Give this button more padding” means exactly that button.
Saved designs
Name, tag, and search designs. Attach Jira URLs, export self-contained HTML, re-import later. ~380 designs and counting.
Hard guardrails
A Claude Code hook enforces that the AI only touches Preview.tsx. Nothing outside the design boundary is in scope.
5 designers use it today. The frontend of Civitatis Pro — a full B2B product — is being built by a designer in Playground, without a front-end developer.
playground
I designed Odisea Playground: vibe coding but using our actual DS components, so the AI’s output is production-valid from the first prompt. 5 designers use it; the frontend of a full B2B product is being built in it without a front-end developer.
the-loop
From a week to a day — and back into the system
Before Playground, every A/B test needed a designer spec, a developer, and roadmap time — a week minimum. Now the designer builds the variant in Playground, exports the HTML Optimizely needs, and launches the same day. No dev, no roadmap dependency.
And when a Playground pattern earns its keep in production, the playground-to-ds skill promotes it into @civitatis/ds-ui as a reusable component — visual reference locked, API designed first, docs and Storybook included.
The flywheel: explore in Playground → validate with data → ship to the system 15+ developers use.
the-loop
A/B testing dropped from a week to a day — designer builds in Playground, exports to Optimizely, launches the same day. When a pattern proves itself, playground-to-ds promotes it into @civitatis/ds-ui. Explore → validate → ship.
results
Impact across the organization
From a system no one used to the foundation of 6 products and a tool that puts production code in designers’ hands — in 6 months, with 2 people.
contact