Radius

Radius tokens set the corner shape of Nuton's surfaces, from square to pill. Use them for every border-radius; never type a pixel value.

  • Beta
  • Accessibility
  • Figma none local (remote 04-Radius)
  • packages/tokens/src/interim/radius-spacing.json

Beta because all ten radius tokens are interim (src/interim). The Nuton DS file has no local radius variables: screens bind the remote 04-Radius library (Q-02, TD-14), so the values here are the observed set. Stable needs a local Radius collection in Figma (D9 backlog, D20); the tokens then move into the Figma snapshot and leave src/interim.

Overview

Nuton is soft by default: pill buttons, round avatars and generously rounded fields and menus. Radius is a scale of ten steps; a component picks one step per part, and nested parts step down so corners stay concentric.

0 · 0px
4 · 4px
6 · 6px
8 · 8px
10 · 10px
12 · 12px
16 · 16px
20 · 20px
24 · 24px
full · 9999px
  • Pill and circle (radius-full): buttons, avatars, status dots, key icons. The default Button corner.
  • Large (radius-16 to radius-24): floating containers and large fields: menus, the command menu, 48px inputs, status modals and marketing cards.
  • Medium (radius-8 to radius-12): compact controls and items inside containers: small inputs, menu items, rounded buttons, textareas.
  • Small (radius-4, radius-6): tiny parts: keyboard keys, checkbox indicators, the password reveal button.
  • Square (radius-0): corners="sharp" on Button and Button group, and edges that meet another surface.

Tokens

Every radius token, generated from @nuton/tokens. All ten are interim: design values waiting for a home in the Nuton Figma file.

Radius tokens
PreviewTokenValueSource
--nu-radius-00pxInterim
--nu-radius-44pxInterim
--nu-radius-66pxInterim
--nu-radius-88pxInterim
--nu-radius-1010pxInterim
--nu-radius-1212pxInterim
--nu-radius-1616pxInterim
--nu-radius-2020pxInterim
--nu-radius-2424pxInterim
--nu-radius-full9999pxInterim

Values are the set observed on Nuton screens: the remote 04-Radius library, the teacher app's tokens and Figma screen usage (radius-20 and radius-24 come from screens only). radius-full is a large number rather than 50%, so a pill stays a pill at any width.

Usage

css
/* Load once: import '@nuton/tokens/tokens.css' */
.lesson-card {
  border-radius: var(--nu-radius-16);
}
.lesson-card__thumbnail {
  border-radius: var(--nu-radius-8); /* steps down inside the card */
}
.space-badge {
  border-radius: var(--nu-radius-full);
}

Both Tailwind outputs add Nuton's numeric keys next to Tailwind's own (rounded-lg and friends still exist). Use the numeric keys so every corner traces back to a token.

Choosing a radius

  • Use the component's radius. Components already set theirs. Only reach for a token when you build a new surface.
  • Nest by stepping down. An inner surface uses a smaller radius than its container, roughly the outer radius minus the padding between them: a menu at radius-16 holds items at radius-8.
  • Scale with size. Taller controls take larger radii: a 48px input uses radius-16, a 36px one radius-8.
  • One corner style per surface. Don't mix smooth, rounded and sharp buttons in one view.
  • Pills use radius-full. Never 50% or a large hand-typed number.

Radius by component

Radius tokens used by each component
ComponentPartToken
Buttoncorners="smooth" (default)radius-full
Buttoncorners="rounded"; small icon-onlyradius-10 · radius-8
Buttoncorners="sharp"radius-0
Button groupsmooth · rounded (2xs) · sharpradius-full · radius-8 (radius-6) · radius-0
Inputsize="lg" (default, 48px tall)radius-16
Inputsize="sm" (36px) and appearance="inline"radius-8
Password inputReveal buttonradius-6
TextareaBoxradius-12
Digit inputEach digit boxradius-10
Dropdown, Combobox, Command menuMenu containerradius-16
Dropdown, ComboboxItem sm · item lgradius-8 · radius-10
Command menuItemradius-10
Menu itemsCheckbox indicator · leading media and switchradius-4 · radius-full
KbdKey capradius-4
AvatarImage, initials, status badgesradius-full
Chart legend, key iconDot and icon frameradius-full

Read from packages/ui/src/components/*/*.css. Two parts don't use a token yet: the checkbox indicator's inner mark (a fixed 2.6px, --nu-checkbox-inner-radius) and anything with a radius not on this scale.

In use

Button corners

The corners prop on Button and Button group picks the radius. Smooth is the default and Nuton's look.

Fields

Input radius follows its size: radius-16 at the default 48px, radius-8 at 36px. Textarea uses radius-12.

Open the menu. The container uses radius-16 and its padding holds items at radius-8, so the hover fill sits concentric with the container's corner.

Pills and circles

AOTBCompleted lessons⌘K

Accessibility

Radius never carries meaning

Corner shape isn't a state or a message. Errors, selection and focus have their own colour, border, text and ARIA cues; a square corner never means “error” or “disabled”. Don't refer to controls by shape in copy (“press the round button”), because shape isn't available to everyone (WCAG 1.3.3).

Focus rings follow shape

Button, Input and Digit input draw focus as a box-shadow, so the ring takes the component's radius: a pill ring on a pill button, a radius-16 ring on a large input. Button group and Link button keep the browser outline (C10), which also follows border-radius in current browsers. The ring's contrast is the open issue, not its shape: the Figma focus effect measures about 1.1:1 against white (C5).

Forced colours and clipping

In Windows High Contrast, Button and Digit input switch to a 2px Highlight outline, which keeps the shape. Containers that clip (overflow: hidden on Input and Button group) cut off anything in their corners, so keep content inside the padding; on Button group this may clip an edge item's focus outline (C29).

You must: keep a non-shape cue for every state; check focus rings on new rounded surfaces aren't clipped by a parent with overflow: hidden.

Guidelines and related

Use radius tokens for

  • Every border-radius in product code and new components.
  • Nesting: a smaller step for each surface inside another.
  • Pills and circles, with radius-full.

Don't use radius for

  • Signalling state, priority or errors.
  • Overriding a component's own radius. Use its corners or size prop.
  • Values off the scale (7px, 50%). Ask the DS Owner to add a step in Figma instead.

Do and don't

Photosynthesis
DoStep the radius down when you nest. A radius-8 item inside a radius-16 container keeps the gap even around the corner.
Photosynthesis
Don'tDon't reuse the outer radius inside. Equal radii on nested surfaces leave a thick, uneven gap at each corner.
DoKeep one corner style in a view. Consistent corners read as one product.
Don'tDon't mix smooth, rounded and sharp. Mixed corners look like components from different products.
DoMark destructive actions with intent and a clear label. The error colour and the words “Delete space” carry the meaning, for everyone.
Don'tDon't use corner shape to signal danger. A sharp corner means nothing to a screen reader and little to anyone else.

Adding a radius

Radius is a design token, so new steps start in Figma (D20). Until the Nuton file has a local Radius collection, propose new values to the DS Owner; they're added to src/interim with the nuton.interim flag and reported on every token check.