Skip to content
portalbits
Home Docs GitHub(opens in a new tab)

Guides

Get startedFoundationsMotion

Components

All components

Buttons

ButtonIconButton

Inputs

InputSelectTextareaSlider

Selection

CheckboxToggleToggleGroupSwitchRadioGroup

Identity

AvatarBadge

Overlays

DialogPopoverTooltipDropdownMenuAlertDialog

Disclosure

TabsAccordion

Cards

AppCardArticleCardFeatureCard

Content

CarouselSectionHeaderEmptyStateAlertProgressSeparatorRowListRow

Chrome

PortalShellSidebarNavMobileNavTopBarAuthFrameColorSelectorFloatingNav

Start with the essentials.

The small decisions that hold the library together.

DOM-derived

A restrained palette

Soft neutrals leave room for a very particular green.

Action green#19e783--portal-green
Ink#181818--portal-ink
White surface#ffffff--portal-surface
Quiet canvas#f8faff--portal-canvas
Soft border#edeff3--portal-border

Source muted text is #9da3ac. This kit uses #686e78 for small text on light surfaces to improve contrast. Input, Select, Checkbox, and Switch edges use #878e98 instead of the source #edeff3 so each control is visible at 3:1; dividers keep #edeff3. Dark preview is an adaptation. It is not inspired by a measured dark theme.

Quietly expressive type

Regular weight, close tracking, and a clear hierarchy.

Section headingA world of possibilities32/40 · 500
Compact headingSmall details. Big difference.24/32 · 500
Body largeEverything you need, right where it belongs.16/24 · 400
NavigationFind your next favorite.15/22 · 400
Body / controlDiscover something new today.14/20 · 400
SupportingA quieter layer of information.13/18 · 400

The measured family is Roobert. This gallery bundles Inter under the SIL Open Font License as a predictable fallback. Supply licensed Roobert through --portal-font for closer typography.

Space, shape, depth

Room to breathe. Just enough elevation.

4px
8px
12px
16px
24px
32px
100px pill radius16px surface radius
--portal-shadow-control:
  0 6px 10px -4px rgb(0 0 0 / 12%),
  0 0 0 1px rgb(0 0 0 / 5%);

--portal-duration: 300ms;
--portal-ease: cubic-bezier(.215,.61,.355,1);

Evidence, not guesswork

What was measured, and where the library makes a deliberate choice.

PatternEvidenceLibrary treatment
ButtonsComputed 32/40/48px heights; 100px radius; dual shadowSource-derived sizes and variants
TypographyRoobert; 13–32px sampled scale; −1% trackingInter fallback; configurable family
Card surfaces16px corners; 16/24px spacing; layered shadowPreserved; neutral poster assets
ChromeSidebar, top controls, compact header and bottom navigation observedReusable composition; 767px breakpoint is an adaptation
Motion300ms easing on sampled controls and list opacitySource timing; overlay movement adapted
Dark / accessibilityFull dark styles and all focus states unverifiedOptional dark preview and contrast improvements labeled