← Back to work

hero · design system

Odisea: from overengineered tokens to AI-powered design operations

I rebuilt a legacy token architecture from three layers to two, aligned it 1:1 with Tailwind, built the rules that let AI produce production-quality Figma components — then built the tool that puts those components directly in designers' hands.

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.

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.

evolution

Three years, three phases

  • 2023: Research, Dan Mall courses, industry audits, governance models.
  • 2024: Manual creation, token architecture, foundations, and first components built by hand, setting the quality bar.
  • 2025–2026: AI pivot, everything I'd learned, encoded into skills, rules, and playbooks.

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.

adoption

Making adoption the easiest option

I started where inconsistency hurt most, booking flows and availability models. Early wins turned those teams into advocates who pulled the system into their own workflows.

Then I wrote the migration guides, contribution templates, and changelog that let teams adopt the system without me becoming a bottleneck. Five product teams now use it across web, iOS and Android; later teams onboarded through those guides and pairing sessions with early adopters.

adoption

I started where inconsistency hurt most, then wrote the migration guides, contribution templates, and changelog that let five product teams adopt the system across web, iOS and Android without me becoming a bottleneck.

foundations

Building the bedrock: typography, spacing, and systematic patterns

Every component inherits from a small set of constrained, purposeful scales.

The focus ring pattern

Accessibility was built in, not bolted on: one universal focus ring, same offset, color, and animation, shared by every interactive element. Keyboard accessibility came for free, and variant count dropped significantly.

# 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

In 2025 I stopped building every component by hand. Now AI creates production-quality Figma components, within constraints I define.

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-proof

From a week to a day — directly to Optimizely

Before Playground, an A/B test required a designer to spec it in Figma, a developer to implement it, roadmap prioritization, and at minimum a week of coordination before anything went live.

After: the designer builds the variant in Playground, exports the HTML Optimizely requires, and launches the test the same day.

One home page redesign. Built in Playground, exported, live in Optimizely the same day.

+4.9% Searches initiated
+10.38% CTR on re-engagement CTA

No dev involved. No roadmap dependency. Design decisions now have a direct path to data.

the-proof

A/B testing went from a week to a day: designer builds the variant in Playground, exports HTML to Optimizely, launches the same day. A home page redesign yielded +4.9% searches and +10.38% re-engagement CTR — no developer, no roadmap dependency.

the-loop

When a design proves itself, it becomes a component

Playground wasn’t just an exploration tool. It became a feeder for the design system itself.

When a pattern proved valuable — used repeatedly, validated in production — I built a workflow to promote it back into @civitatis/ds-ui as a reusable component. The playground-to-ds skill handles the translation end-to-end:

01

Visual reference locked

The agent reads the Playground design — the exact render, not a screenshot — and extracts every invariant: geometry, spacing, typography, colors, interactions.

02

API designed first

The component’s public interface is decided before any JSX is written. The design is the constraint; the API is the variable.

03

Full DS integration

The component gets a colocated .doc.mjs, a Storybook story, and passes odisea-lint before any PR is opened.

04

Designer review in Storybook

The designer reviews the promoted component in local Storybook before the PR is opened. No shortcuts on fidelity.

The flywheel: explore in Playground → validate with data → ship to the system 15+ developers use.

the-loop

When a Playground design proves itself in production, playground-to-ds promotes it into @civitatis/ds-ui — locking the visual reference, designing the API first, adding docs and Storybook coverage. The flywheel: explore → validate → ship to the system 15+ developers use.

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.

Fernando Giménez · Product · Brand ·  &