Christian CastillejoDesign Engineer
Case Study / 01

Nectar UI

I realized standard libraries assume too much styling. Nectar is my answer: a headless infrastructure powered by Tailwind v4 variables that allows logic to be shared while aesthetics remain fluid.

Core Stack
Tailwind v4
Radix UI
TypeScript
Framer Motion
Next.js 14
Key Metrics
15

Elements

<5kb

Bundle Size

The Process

Engineering narrative.

01

The Token Dilemma

Systematizing Intuition

Designers think in tokens (colors, spacing, radius), but developers often hardcode magic numbers. I wanted a system where the 'Theme' wasn't just a JavaScript object, but a native CSS API. Using Tailwind v4, I mapped semantic variables directly to the browser engine.

the-token-dilemma.ts
:root {
  /* Primitives (Source of Truth) */
  --p-vermilion-500: #E35028;
  --p-green-500:     #025A4E;
  
  /* Physics */
  --ease-spring: cubic-bezier(0.16, 1, 0.3, 1);
}

@theme {
  /* Semantic Mapping */
  --color-primary: var(--p-vermilion-500);
  --color-accent:  var(--p-green-500);

  /* Radius Engine */
  --radius-interaction: var(--radius-full); /* Pills */
  --radius-surface:     var(--radius-2xl);  /* Cards */
  
  /* Typography */
  --font-display: "Acorn", serif;
}
02

Headless Primitives

Accessibility as Architecture

Building accessible components like a 'ComboBox' or 'Dialog' from scratch is error-prone. Instead of reinventing the wheel, I built Nectar on top of Radix UI. This decouples the 'Behavior' (Focus traps, Keyboard nav, ARIA) from the 'Presentation'. My components are accessible by default, not as an afterthought.

Headless Primitives
03

Docs as Product

The Developer Experience

A system is only as good as its documentation. I built a dedicated documentation site that acts as a 'Laboratory'. It features interactive playgrounds, physics simulations for buttons, and a live token inspector. This shifts the mindset from 'reading docs' to 'exploring the system'.

Docs as Product
System Architecture

Atomic
Composition.

Nectar enforces a strict separation of concerns. Tokens define the physics, Primitives handle the logic, and Compounds allow for flexible composition without API bloat.

Design Tokens

CSS Variables

The visual DNA (Colors, Typo, Radius) defined in CSS.

Headless Core

Radix UI

Unstyled primitives managing state and ARIA.

Nectar UI

The Glue

Tailwind classes merging Tokens + Primitives.

Consumption

The Portfolio

Importing semantically typed components.

Configurationcodegen.ts
tailwind.config.ts (v4)
@import "tailwindcss";

@theme {
  --font-display: "Acorn", serif;
  --font-sans: "Geist", sans-serif;
  
  --ease-spring: cubic-bezier(0.16, 1, 0.3, 1);
}

By using the new CSS-first configuration, we expose the design system directly to the browser engine, enabling zero-runtime theme switching.

Interactive Lab

Tactile
Physics.

Test the 'Button' component. It's not just a color change; it includes an internal loading state handler and specific spring physics for the click interaction.

Properties
Inspection Mode
Button.usage.tsx
<Button
  variant="primary"
  size="default"
  isLoading={false}
  onClick={() => handleClick()}
>
  Click Me
</Button>
Strict Guidelines

Engineering
Manifesto.

Rules I imposed on myself to ensure this wasn't just another UI kit.

01

Colocation

Documentation lives next to the code. If I update the component, I update the docs immediately.

Maintainability
02

No Magic Numbers

Every padding, margin, or color must come from a Token. Hex codes are banned in component files.

Consistency
03

Polymorphism

Components support the 'asChild' prop (via Slot), allowing them to merge with other DOM elements seamlessly.

Flexibility
04

Zero CLS

Components enforce explicit dimensions to prevent layout shifts during hydration or loading states.

Performance
Retrospective

Engineering
Trade-offs.

Every project is a series of decisions. Here are the critical pivot points where I had to balance technical purity with business reality.

01

The cost of 'Too Much Dry'

I learned that early abstraction is the root of all evil. I had to duplicate some code initially to understand the common patterns before extracting them into the 'cn' utility and base variants.

Key Takeaway
02

Developer Experience is User Experience

If the API is hard to use, the UI will be buggy. Spending time on strong TypeScript definitions saved me hours of debugging in the consuming apps.

Key Takeaway