← Back to work

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.

Reading mode
12 min read

specs

Role Principal Product Designer (IC)
Company Civitatis (travel tech)
Scope Token architecture, component design, Odisea Playground
Tools Figma, Claude Code, Tailwind
Year 2023–2026
30+ Production components
3 Platforms: web, iOS, Android
5 Product teams using the system

hero-visual

ODISEA DESIGN SYSTEM
Odisea Design System
# odisea-hero-visual · animated · 21:9

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.

01

Opaque token names

Names like sys-color-surface-container-highest required a lookup table. Designers avoided tokens altogether.

02

Massive duplication

Hundreds of tokens mapped to the same values, more tokens than design decisions.

03

Incomplete components

~15 components, most incomplete or out of sync with production code. Teams built one-offs instead.

04

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).

Before
sys-color-surface-container-highest sys-color-on-surface-variant sys-typescale-body-medium-size
After
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-diagram
Before Reference blue-500, gray-100 System sys-color-surface-container… Component button-bg-primary After Primitives blue-500, gray-100 Semantics bg-secondary, text-muted
Before Reference blue-500, gray-100 System sys-color-surface-container… Component button-bg-primary After Primitives blue-500, gray-100 Semantics bg-secondary, text-muted

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.

# foundation-typography

Typography

A type scale from text-xs to text-5xl, mapped to Tailwind's defaults. Two families: display and body.

# foundation-spacing

Spacing

space-1 through space-16, mirroring Tailwind's naming exactly, no semantic layer needed.

# foundation-radius

Border radius

rounded-sm to rounded-full, with semantic radius tokens mapped to specific UI contexts.

# foundation-colors

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

01

Skills

Markdown files teaching AI the system's conventions: brand guidelines, token usage, Figma API patterns.

02

Rules

Typography, spacing, and color constraints the AI reads before every action.

03

Playbooks

Step-by-step procedures: creating a component, setting up variants, binding tokens, structuring auto-layout.

04

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.

# ai-workflow-diagram
AI task design component Governance 01 Skills knows the system 02 Rules what's allowed 03 Playbooks how to do it Validation gate 04 · check token binding naming · a11y Production component fail retry with rule feedback
AI task design component Governance 01 Skills knows the system 02 Rules what's allowed 03 Playbooks how to do it Validation gate 04 · check token binding naming · a11y Production component fail retry with rule feedback

components

Components in production

Shipped across web, iOS and Android, built on the token architecture and foundations above.

# odisea-components.mp4
Forms · Button · Alert · Tag/Pill/Badge · Price · Accordion · Card

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.

01

Live preview

Components render as the AI edits them — no reload, no context switch. The designer sees changes the moment they’re written.

02

Point-and-tweak

Click any element to anchor the next request to it. “Give this button more padding” means exactly that button.

03

Saved designs

Name, tag, and search designs. Attach Jira URLs, export self-contained HTML, re-import later. ~380 designs and counting.

04

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.

90% Token reduction
46% Variant reduction through consolidation
300% Faster component creation with AI
15+ Developers consuming the system
6 Products live (web + app)
5 Designers shipping with Playground

contact

Great systems start
with great conversations.