component-family-consistency
Component Family Consistency
Every interactive component in a product — buttons, inputs, selects, checkboxes, radio buttons, pills, badges, tags, calendars, date pickers, sliders, toggles — belongs to the same visual family. They share a common design DNA. A user should be able to look at any component and feel that it belongs to the same product as every other component.
When components are designed in isolation without shared tokens, the product feels assembled from parts rather than built as a whole.
The Shared DNA
Define these tokens once. Every component inherits from them.
Border-Radius
All interactive components use the same base radius token. Variations are derived, not invented.
--radius-base: 8px; /* buttons, inputs, selects */
--radius-sm: 4px; /* checkboxes, small badges */
--radius-lg: 12px; /* cards, modals, large panels */
--radius-full: 9999px; /* pills, tags, avatar chips */
A button and an input on the same form must have the same radius. A pill is always --radius-full. A badge is --radius-sm or --radius-full depending on brand tone — but consistent across all badges.
Border Style
Borders across all form components and containers should use a highly restricted set of tokens.
The 2-Step Rule: Limit border widths to at most two options (e.g., 1px and 4px, or 1px and 8px). Do not use an incremental scale like 1px, 2px, 3px, 4px.... A limited choice makes the hierarchy clear and the product feel intentional.
--border-width-thin: 1px; /* Default for inputs, cards, dividers */
--border-width-thick: 4px; /* Featured items, bold accents, active indicators */
--border-color: var(--color-border);
--border-color-focus: var(--color-primary);
--border-color-error: var(--color-error);
An input border and a select border are identical at rest. Focus state uses --border-color-focus everywhere. Error state uses --border-color-error everywhere.
Spacing and Height
Components at the same visual scale share height and internal padding.
/* Default (md) size */
--component-height-md: 40px;
--component-padding-x-md: 12px;
--component-padding-y-md: 8px;
/* Small */
--component-height-sm: 32px;
--component-padding-x-sm: 8px;
--component-padding-y-sm: 6px;
/* Large */
--component-height-lg: 48px;
--component-padding-x-lg: 16px;
--component-padding-y-lg: 10px;
A button and an input placed next to each other must be the same height. This is not cosmetic — mismatched heights break form layouts and signal disorder.
Shadow
Interactive components use a consistent shadow logic:
- At rest: no shadow, or
--shadow-xsfor floating components (select dropdown trigger) - On focus: focus ring via
outline, notbox-shadow(unless usingbox-shadowas the focus ring consistently) - Elevated (dropdowns, popovers opening from components):
--shadow-md
Colour Logic
The same colour roles apply uniformly across all components:
| State | Colour token |
|---|---|
| Rest border | --color-border |
| Focus border / ring | --color-primary |
| Error border | --color-error |
| Disabled | --color-text-secondary at reduced opacity |
| Selected / active fill | --color-primary |
| Hover background | --color-primary at 8–12% opacity |
Component Family Members
| Component | Shares radius | Shares height | Shares border | Shares colour logic |
|---|---|---|---|---|
| Button | ✓ | ✓ | — (filled) | ✓ |
| Input / textarea | ✓ | ✓ | ✓ | ✓ |
| Select | ✓ | ✓ | ✓ | ✓ |
| Checkbox | --radius-sm |
— | ✓ | ✓ |
| Radio | --radius-full |
— | ✓ | ✓ |
| Toggle / switch | --radius-full |
✓ | — | ✓ |
| Pill / tag | --radius-full |
✓ | ✓ optional | ✓ |
| Badge | --radius-sm or --radius-full |
— | — | ✓ |
| Date picker / calendar | --radius-base |
✓ | ✓ | ✓ |
| Slider | --radius-full (track + thumb) |
— | — | ✓ |
| Search input | ✓ | ✓ | ✓ | ✓ |
| Combobox | ✓ | ✓ | ✓ | ✓ |
Gradients in Components
If the brand uses gradients, apply them consistently:
- A gradient on a primary button should use the same gradient angle and stops as gradient usage elsewhere in the product
- Hover state: slightly shift the gradient lightness, not the hue
- Do not use gradients on some button variants and flat colour on others — pick one approach per variant and apply it universally
Review Checklist
- Do buttons and inputs on the same form share the same height?
- Do all bordered components use at most two border-width options (e.g., 1px and 4px)?
- Does focus state look identical across all focusable components?
- Does error state look identical across all components that can have errors?
- Are all radius values derived from the same base token — not set independently per component?
- Do pills and tags use
--radius-fullconsistently? - Is gradient usage (if any) consistent across all button variants?
- Could a new component be added to the library using only existing tokens?
More from dembrandt/dembrandt-skills
nielsen-usability-heuristics
UI design and review should apply Nielsen's 10 Usability Heuristics — the foundational principles for evaluating and improving usability. Use when auditing an interface, designing interaction flows, writing error messages, or reviewing any UI for usability issues.
45form-design
Forms have three layers of guidance: helper text below the input explains what to enter, placeholder shows the expected format, and validation confirms correctness. Real-time validation for complex inputs. Submit enables only when the form is valid. Use when designing or reviewing any form, input field, or data entry UI.
44color-mode-and-theme
Choose light, dark, or combined color mode deliberately based on brand tone and user context. Offer a theme selector only when user control genuinely matters — enterprise tools, data-heavy UIs, or extended-use applications. Use when defining the base color palette, designing a design system, or deciding whether to build dark mode support.
43generate-ui-from-brand
Pipeline skill — turns a URL or DESIGN.md into a concrete UI structure with decisions already made. Extracts live design tokens, normalizes them into a semantic system, applies UX principles, and outputs an actionable UI spec. Use when building UI for an existing brand from scratch, auditing a design system, or refactoring visual inconsistency.
42scroll-areas
Scroll areas inside a layout should be avoided wherever possible. When unavoidable, allow only one scroll axis at a time and always keep the user in control. Use when designing layouts, data tables, panels, or any component that might introduce an inner scroll container.
42micro-interactions
Micro-interactions are small, purposeful animations and responses that reward the user and make the interface feel alive — an animated icon, a satisfying toggle, a subtle reveal. Borrowed from the natural world, they add delight without distraction. Use when designing interactive components, success states, toggles, loaders, or any moment worth celebrating.
42