Theme

Radius

Two-channel corner rounding for controls and surfacesView source →

Kookie UI rounds corners on two independent channels. Controls and marks — buttons, inputs, checkboxes, badges, switches — scale aggressively with the theme and can become pills. Surfaces — cards, dialogs, popovers, menus, tables — damp as the theme grows and never go pill.

The gap between the channels is the point. Round controls read as touchable; restrained surfaces read as architectural. Widening the theme widens that contrast instead of inflating everything at once.

The radius infrastructure (5-step scale, factor system) is from Radix Themes, but Kookie UI uses custom radius values and adds the surface channel.

Installation

shell
npm install @kushagradhawan/kookie-ui

Usage

Set radius on the Theme component to control corner rounding across the app. Both channels move together from this one prop.

tsx
import { Theme } from '@kushagradhawan/kookie-ui';
 
<Theme radius="medium"><YourApp /></Theme>

Channels

Controls And Marks

--radius-* drives anything a person clicks, types into, or toggles. These opt into --radius-full, so at radius="full" a Button becomes a pill.

css
var(--radius-1)  /* 6px */
var(--radius-2)  /* 8px */
var(--radius-3)  /* 10px */
var(--radius-4)  /* 12px */
 
var(--radius-5)  /* 16px */
var(--radius-6)  /* 20px */
var(--radius-7)  /* 24px */
var(--radius-8)  /* 28px */
 
var(--radius-9)  /* 32px */
var(--radius-10) /* 40px */
var(--radius-11) /* 48px */
var(--radius-12) /* 56px */

Used by Button, IconButton, TextField, TextArea, Select trigger, Checkbox, Radio, Switch, Slider, Progress, Badge, Kbd, SegmentedControl, Tabs, Avatar, menu items, and the item shells of CheckboxCards and RadioCards.

CheckboxCards and RadioCards are the one place where the two channels disagree with the markup. Their items are built on Card, but they are selection controls that happen to be card-shaped — a row of choices, each one a large target — so they override --base-card-border-radius back onto the control channel and stay round alongside the rest of the form.

Surfaces

--radius-surface-* drives panels that hold content. Same base ramp, damped factor, no pill.

css
var(--radius-surface-1)  /* 6px */
var(--radius-surface-2)  /* 8px */
var(--radius-surface-3)  /* 10px */
var(--radius-surface-4)  /* 12px */
 
var(--radius-surface-5)  /* 16px */
var(--radius-surface-6)  /* 20px */
var(--radius-surface-7)  /* 24px */
var(--radius-surface-8)  /* 28px */
 
var(--radius-surface-9)  /* 32px */
var(--radius-surface-10) /* 40px */
var(--radius-surface-11) /* 48px */
var(--radius-surface-12) /* 56px */

Used by Card, Dialog, AlertDialog, Popover, HoverCard, Tooltip, DropdownMenu, ContextMenu, Combobox, Select content, Sidebar content, Table, Callout, Accordion, Chatbar, and inset Shell panes. Toolbar and Inset follow Card automatically.

Sheet is exempt — it sets border-radius: 0 regardless of theme. A menu's content damps while the rows inside it stay on the control channel, which is the contrast the split exists for.

Factors

Each theme sets both factors. The surface factor is capped at 1, which is what keeps panels calm at the top of the scale.

css
[data-radius='none']   { --radius-factor: 0;    --radius-surface-factor: 0;    }
[data-radius='small']  { --radius-factor: 0.75; --radius-surface-factor: 0.5;  }
[data-radius='medium'] { --radius-factor: 1;    --radius-surface-factor: 0.75; }
[data-radius='large']  { --radius-factor: 1.5;  --radius-surface-factor: 0.9;  }
[data-radius='full']   { --radius-factor: 2;    --radius-surface-factor: 1;    }

A surface at full is exactly as round as a surface at medium. Controls keep climbing past it.

Mark Ceiling

Marks are small and do not grow with the theme, so the radius ramp can outrun the box. Checkbox is the one case where it did: at full its corner reached half its own box and the mark rendered as a perfect circle — visually identical to Radio, which is border-radius: 100%. That collapses the distinction between choosing many and choosing one.

Checkbox now clamps its corner to 40% of its own box:

css
--checkbox-radius-ratio-max: 0.4;
--checkbox-radius-max: calc(var(--checkbox-size) * var(--checkbox-radius-ratio-max));
--checkbox-border-radius: min(
  calc(var(--radius-1) * var(--spacing-multiplier-medium)),
  var(--checkbox-radius-max)
);

The ceiling only binds at the top of the scale. none through medium are unchanged at every size, large moves by 0.35px at size 2 alone, and full drops from a circle to a clearly square mark.

Switch and Radio are deliberately exempt — a pill and a circle are their correct shapes at every theme.

Scale

None

Sharp corners on both channels. Geometric, technical interfaces.

tsx
<Theme radius="none"><YourApp /></Theme>

Small

Tight rounding. Controls at 0.75x, surfaces at 0.5x.

tsx
<Theme radius="small"><YourApp /></Theme>

Medium

Standard rounding and the default. Controls at 1x, surfaces at 0.75x.

tsx
<Theme radius="medium"><YourApp /></Theme>

Large

Prominent controls against steady surfaces. Controls at 1.5x, surfaces at 0.9x.

tsx
<Theme radius="large"><YourApp /></Theme>

Full

Pill-shaped controls inside near-square panels — the widest contrast the system offers. Controls at 2x plus pill, surfaces capped at 1x.

tsx
<Theme radius="full"><YourApp /></Theme>

Overrides

Components that accept a radius prop re-declare both factors for their subtree, so an override keeps the control/surface relationship intact.

tsx
<Theme radius="medium">
  <Button radius="full">Pill button</Button>
  <Accordion.Root radius="small">...</Accordion.Root>
</Theme>

To reach for a channel directly in custom CSS, pick the one that matches what you are drawing:

css
.my-panel {
  border-radius: var(--radius-surface-4);
}
 
.my-control {
  border-radius: max(var(--radius-2), var(--radius-full));
}

Credits

The radius infrastructure (5-step scale system and factor-based multiplier approach) is from Radix Themes by WorkOS. Kookie UI's radius values and the surface channel are custom.

© 2026 Kushagra Dhawan. Licensed under MIT. GitHub.

Theme

Accent color

Gray color

Appearance

Radius

Scaling

Panel background