Shapes
Shape is a subtle but powerful tool for communicating interactivity, hierarchy, and grouping. Tessera UI uses a constrained border radius scale that maps to specific component contexts.
Radius Scale
Section titled “Radius Scale”| Token | Value | Pixels | Shape Language |
|---|---|---|---|
--ts-radius-none | 0 | 0px | Sharp edges — data-dense UI, tables |
--ts-radius-sm | 0.375rem | 6px | Subtle rounding — badges, small elements, tooltips |
--ts-radius-md | 0.75rem | 12px | Default rounding — inputs, alerts |
--ts-radius-lg | 1rem | 16px | Spacious rounding — cards, panels |
--ts-radius-xl | 1.75rem | 28px | Prominent rounding — modals, large containers |
--ts-radius-full | 9999px | Pill / circle | Pill shapes — buttons, toggle tracks, pill badges |
Shape Families
Section titled “Shape Families”Shape families are semantic shape roles that group components by their visual purpose. Rather than assigning radii per-component, families ensure that related components share the same shape language.
| Family Token | Default Value | Components |
|---|---|---|
--ts-shape-interactive | radius-full (pill) | Buttons, toggles — pill-shaped by default |
--ts-shape-container | radius-lg (16px) | Cards, panels, form containers |
--ts-shape-overlay | radius-xl (28px) | Modals, drawers, dialogs |
--ts-shape-badge | radius-sm (6px) | Badges, tooltips, tags |
--ts-shape-pill | radius-full (9999px) | Toggle tracks, pill badges, progress bars |
Override a shape family to globally change all components in that group:
:root { /* Make all interactive elements rectangular instead of pill */ --ts-shape-interactive: var(--ts-radius-md);
/* Make all containers sharp */ --ts-shape-container: var(--ts-radius-sm);}Component Shape Defaults
Section titled “Component Shape Defaults”Each component uses a radius appropriate to its size and purpose:
| Component | Default Radius | Token |
|---|---|---|
| Button (base) | full (pill) | --ts-button-radius |
| Input (base) | md (12px) | --ts-input-radius |
| Card | lg (16px) | --ts-card-radius |
| Modal | xl (28px) | --ts-modal-radius |
| Alert | md (12px) | --ts-alert-radius |
| Badge | sm (6px) | --ts-badge-radius |
| Badge (pill) | full | Pill override |
| Tooltip | sm (6px) | --ts-tooltip-radius |
| Toggle track | full | Pill shape |
Size-Responsive Radius
Section titled “Size-Responsive Radius”Some components adjust their border radius based on size to maintain visual proportion:
- Small elements (
xs,sm) useradius-sm— tight rounding keeps them compact - Default elements (
md) useradius-md— balanced rounding for standard UI - Large elements (
lg,xl) useradius-lg— more generous rounding scales with the element
This prevents small elements from looking overly round and large elements from looking overly sharp.
Shape Consistency Rules
Section titled “Shape Consistency Rules”- Buttons are pill-shaped by default. The M3-inspired design uses
radius-fullfor all interactive elements like buttons and toggles. - Inputs use rectangular rounding. Inputs and selects use
radius-md(12px) for a clean, contained feel. - Container elements use generous rounding. Cards use
radius-lg(16px), modals useradius-xl(28px) for a soft, pillowy aesthetic. - Pill shapes for buttons and status indicators. Buttons, toggle tracks, pill badges, and progress indicators use
radius-full.
Customizing Shape
Section titled “Customizing Shape”Override component tokens to change the shape language for your application:
/* Sharp, modern aesthetic */ts-button { --ts-button-radius: var(--ts-radius-sm); }ts-card { --ts-card-radius: var(--ts-radius-sm); }ts-modal { --ts-modal-radius: var(--ts-radius-md); }
/* Rectangular buttons (override pill default) */ts-button { --ts-button-radius: var(--ts-radius-md); }ts-input { --ts-input-radius: var(--ts-radius-sm); }