ANTIGRAVITY LABJP
Articles/AI Tools
AI Tools/2026-03-27Advanced

Design Judgment in Code: Beyond AI-Generated UI — Practical Techniques for Embedding Intent into Types, Tokens, and Conditionals

Master the comprehensive techniques for embedding human design judgment into code. From TypeScript's type system for expressing UI intent, through strategic design token architecture, to semantic conditional branching and component API patterns. Learn how to inject judgment into AI-generated code and build design systems that reason like humans.

ai-tools14ui-design2design-system2typescript26tailwind2component-apiadvanced20

Premium Article

Our previous piece identified the core problem: AI-generated UI feels artificial because it lacks intentional reasoning baked into every decision. This deep dive translates that insight into systematic, implementable techniques—a complete framework for embedding human judgment into production code.

Field Notes: What the Docs Don't Tell You About Embedding AI Into Production UI

Before we dive into the philosophy, I want to share a few things I learned the painful way. Since 2014 I've shipped a portfolio of wallpaper and ambient apps (50M+ cumulative downloads, AdMob revenue as the primary income channel), and I've used Antigravity and other AI code generators to iterate on UI. The decisions below aren't theoretical — each came from a measurable hit to revenue or retention.

1. "Nice-looking UI" isn't always compatible with AdMob revenue

Ask Antigravity for "a clean home screen" and it returns something that looks polished. But in production AB tests on my wallpaper app, the AI-generated template-style layouts dropped AdMob banner viewability and pulled eCPM down by about 23%. The boundary between ad and product UI is something the model has no signal about — you have to encode that judgment in tokens and types, or revenue bleeds quietly.

Concrete tweaks I now insist on:

  • Always insert at least a spacing.md (16px) gap between banner ads and product chrome — never let AI compress it
  • Keep the safe area between status bar and banner top at spacing.lg (24px) or more. AI output tends to crunch this to 8px
  • Never show a banner on the very first screen after splash — App Store reviewers rejected my apps twice for this. First launch starts ad-free, period

2. WCAG 2.5.5's 44px rule earns its keep even in a wallpaper app

I used to assume "if all the user does is browse wallpapers, button size can favor aesthetics." Then I raised the "Download" button from 36px to 44px in two apps and D1 retention jumped from 41.2% to 47.8%. Users with less stable touch (my own mother is in this cohort) were mis-tapping back to the home screen far more often than I'd expected.

Locking size: 'md' at 44px isn't accessibility compliance for its own sake — it's an economic decision visible in the funnel. Every time AI-generated UI shrinks a tap target, retention pays the bill.

3. oklch shipped fine in theory; on real devices it hid a landmine

oklch is beautiful on paper. But when I rolled it out to pre-2024 Android devices running my Capacitor-based hybrid app (WebView), a non-trivial slice of devices silently ignored color: oklch(...). No Crashlytics crash — just colorless UI — followed by a steady drizzle of one-star reviews.

In production I now guard with @supports (color: oklch(0 0 0)) and ship RGB hardcoded fallbacks for unsupported devices. If you're starting an oklch-first project, add a Tailwind plugin that emits dual values at build time.

4. Make Antigravity explain "why" — review time drops 3x

When I require Antigravity's main agent to leave an inline comment for every className concatenation and conditional branch ("why this value?"), per-file review time drops from 8–10 minutes to roughly 3. Typos and type errors I fix myself; design-judgment calls I approve or reject just by reading the comments.

The prompt suffix I now reuse on every UI generation task:

For every className concatenation and conditional branch in your output,
add an inline comment on the adjacent line explaining "why this value."
ARIA attributes must be applied conditionally based on the state value,
and the reasoning for each must be recorded the same way.

Without this instruction the model emits "code that runs" but no judgment, and the cost compounds: weeks later I'd find myself archaeologically reconstructing decisions I should never have lost.

5. The 8-step checklist I actually use when changing design tokens

Token edits ripple far. Skipping steps causes color regressions in shipped apps. The pipeline I now run on every token PR:

  1. Propose the change via the Figma Tokens plugin → designer review
  2. Export tokens.json and review the PR diff
  3. Update tailwind.config.ts through a generation script (no hand-edits)
  4. Run all Storybook stories through Chromatic for visual regression
  5. Eyeball on iOS simulators (iPhone SE / iPhone 15 Pro Max) and an Android emulator (Pixel 3a)
  6. Verify @supports fallback on a legacy WebView device
  7. Compare side-by-side with live AdMob test ads for viewability
  8. Roll out via AB test, minimum 5,000 sessions before full rollout

The one time I skipped two steps to ship faster, I got 17 one-star reviews on launch day citing invisible buttons. Tokens carry judgment — the rollout procedure has to carry just as much care.


The Philosophy of Design Tokens as Brand Judgment

Design tokens are more than numeric values. They are the bridge between brand philosophy and code implementation. Every token you define is a design judgment frozen in place.

Oklab and oklch: Perceptual Color in Code

Most projects define colors in RGB or HSL. But human color perception doesn't work in RGB space. Enter oklch (Oklab cylindrical): a color space designed to match how humans actually perceive color differences.

// Traditional RGB: no perceptual relationship
export const colors = {
  primary: '#4f46e5',      // Purple
  primaryDark: '#3730a3',  // Darker purple (but how much darker, perceptually?)
  primaryLight: '#818cf8', // Lighter purple (how light, really?)
};
 
// oklch: perceptually uniform
export const colors = {
  // oklch(lightness saturation hue)
  primary: 'oklch(0.55 0.2 260)',      // L=0.55 (mid-brightness)
  primaryDark: 'oklch(0.40 0.2 260)',  // L=0.40 (15% darker, visually consistent)
  primaryLight: 'oklch(0.70 0.15 260)', // L=0.70 (15% lighter, visually consistent)
 
  // Semantic colors: judgment embedded in naming
  success: 'oklch(0.58 0.15 142)',     // Green: intention is "confirmation"
  warning: 'oklch(0.68 0.15 65)',      // Yellow: intention is "caution"
  error: 'oklch(0.55 0.2 25)',         // Red: intention is "stop, be careful"
 
  // Neutral surfaces: warmth judgment
  surface: 'oklch(0.98 0.002 0)',      // Nearly white (with slight warmth)
  'surface-alt': 'oklch(0.94 0.002 0)',
};

Why oklch matters:

  1. Perceptual uniformity: A change from L=0.50 to L=0.55 looks the same anywhere on the lightness scale. In RGB, this isn't true.
  2. Scalability: To create a lighter variant, just increase lightness and slightly reduce saturation. No guesswork.
  3. Brand precision: oklch is based on CIELAB, the standard in print and color science. Your designer's color intuitions translate directly.

Spacing Scales Grounded in Human Cognition

Fibonacci spacing isn't arbitrary aesthetics—it's grounded in how humans perceive visual rhythm.

export const spacing = {
  // Fibonacci: 1, 1, 2, 3, 5, 8, 13, 21, 34 ...
  // This ratio appears in nature and human proportions.
  // The eye finds these intervals naturally pleasing.
 
  'xs': '0.25rem',   // 4px  - Tight (icon spacing, text decoration)
  'sm': '0.5rem',    // 8px  - Snug (related elements: label + icon)
  'md': '1rem',      // 16px - Default (component internals)
  'lg': '1.5rem',    // 24px - Breathing room (section boundaries)
  'xl': '2.5rem',    // 40px - Major separation (feature sections)
  'xxl': '4rem',     // 64px - Page-level margins
 
  // Touch-specific
  'touch-target': '2.75rem', // 44px minimum (WCAG 2.5.5)
};
 
// Documentation: embed the "why"
const RATIONALE = {
  xs: 'Visual tightness—elements are directly related (icon + label)',
  sm: 'Related elements with clear hierarchy (button + sublabel)',
  md: 'Standard spacing between distinct but connected ideas',
  lg: 'Clear visual separation for meaningful boundaries',
  xl: 'Major sections deserve breathing room',
  xxl: 'Viewport to content relationship—ensure margins frame the page',
};

Typography: Readability as Judgment

Font size doesn't exist in isolation. It's always paired with line-height—and that pairing is a design judgment about readability.

export const typography = {
  // Tuple: [font-size, { line-height, letter-spacing }]
 
  'xs': ['0.75rem', { lineHeight: '1.5', letterSpacing: '0.01em' }],
  // 12px with tight leading (1.5): compact, caption-level text
 
  'sm': ['0.875rem', { lineHeight: '1.5' }],
  // 14px with snug leading: supporting text
 
  'base': ['1rem', { lineHeight: '1.6' }],
  // 16px with generous leading (1.6): body text. Legibility is paramount here.
  // Line-height of 1.6 means line-length should be 45-75 characters for optimal reading.
 
  'lg': ['1.125rem', { lineHeight: '1.6' }],
  // 18px body: for accessibility-first designs, this is more inclusive
 
  'h3': ['1.375rem', { lineHeight: '1.5', letterSpacing: '-0.01em' }],
  // 22px heading: tighter line-height (1.5) because larger text
  // naturally has more whitespace between lines.
  // Negative letter-spacing pulls letters closer—visual weight increases.
 
  'h2': ['1.75rem', { lineHeight: '1.3', letterSpacing: '-0.01em' }],
  // 28px heading: even tighter line-height for visual impact
 
  'h1': ['2.25rem', { lineHeight: '1.2', letterSpacing: '-0.02em' }],
  // 36px hero: maximum visual impact. Line-height of 1.2 creates a cohesive block.
};
 
// Judgment documentation
const TYPOGRAPHY_RATIONALE = {
  'h1-line-height': `
    Headings larger than 28px benefit from tighter line-height.
    Large text has inherent whitespace; tightening line-height
    creates visual cohesion and emphasizes the heading's role.
  `,
  'body-line-height': `
    Body text needs 1.5–1.6 line-height for accessibility.
    Research shows this improves reading speed and comprehension,
    especially for users with dyslexia or low vision.
  `,
  'negative-letter-spacing': `
    Large headings get -0.01em to -0.02em letter-spacing.
    This pulls letters closer, creating visual weight and
    making the heading feel more substantial.
  `,
};

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
Real metrics from a 50M-download wallpaper app: how token-driven UI recovered AdMob eCPM by ~23% after AI-generated layouts dropped it
Why a 44px tap target lifted D1 retention from 41.2% to 47.8% — and how to bake this judgment into Button size tokens
Prompt template that cuts Antigravity code review time from 8–10 minutes to ~3 minutes, plus an 8-step design-token rollout checklist used in production
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

AI Tools2026-03-27
Why AI-Generated UI Feels Off — Beyond Surface-Level Design Quirks to the Core Problem of Missing Intent
The uncanny feeling when looking at AI-generated UI isn't just about gradients and emoji overuse. The real issue runs deeper: the absence of human judgment embedded in design decisions. Learn how type systems, design tokens, and conditional logic can carry intentionality.
AI Tools2026-03-26
Building a RAG Pipeline with Antigravity— Unlock Your Company's Knowledge with Vector Search and LLMs
A comprehensive guide to designing and implementing RAG (Retrieval-Augmented Generation) pipelines using Antigravity. Covers embedding generation, ChromaDB integration, hybrid search with reranking, prompt optimization, and production best practices.
AI Tools2026-06-24
When an Overnight Local Agent Crawls by Dawn — Keeping Ollama's Latency Flat by Working Backward from Context Length
Why each step of a long-running local agent gets heavier toward the end, how to measure it from Ollama's timing fields, and how a fixed num_ctx plus a rolling summary keep per-step latency flat.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →