Case Study · Soberlink Identity

A unified component library for identity & account experiences.

A token-driven design system powering authentication, account management, and verification flows across Soberlink's identity platform — built with accessibility, theming, and developer ergonomics as first-class concerns.

Components
11 shipped
Color Tokens
66
A11y Coverage
WCAG AA
Bundle Size
~24kb gz

Color Tokens

Six semantic ramps (gray, blue, red, yellow, green, plus white/black) with 11 stops each. Tokens are exposed as CSS custom properties on :root, then aliased into role tokens (--link, --surface-color, --text-1) so themes can be swapped without touching components.

Full Palette · Hover any swatch for the token name
Gray
Blue · Brand
Red · Error
Yellow · Warning
Green · Success

Typography

Adelle Sans (loaded via Typekit) as the brand sans, with a system fallback stack. Six heading tiers, two body sizes, plus caption and large-paragraph utilities.

Type Scale
heading-1 Stay accountable. 48 / 64 · 700
heading-2 Stay accountable. 36 / 48 · 700
heading-3 Stay accountable. 24 / 32 · 700
heading-4 Stay accountable. 20 / 24 · 700
heading-5 Stay accountable. 16 / 24 · 600
heading-6 Stay accountable. 14 / 24 · 600 · UPPER
body-1 Real-time alcohol monitoring designed for connection, not surveillance. 16 / 150% · 400
body-2 Real-time alcohol monitoring designed for connection, not surveillance. 14 / 17 · 400
caption Real-time alcohol monitoring designed for connection. 12 / 16 · 400

Buttons

One .component-button base, four modifier classes (primary, secondary, borderless, is-loader) and icon helpers. Every state — hover, focus-visible, active, disabled, loading — is defined explicitly.

Variants & States
<button class="component-button primary">Primary</button>
<button class="component-button secondary">Secondary</button>
<button class="component-button borderless">Borderless</button>
<button class="component-button" disabled>Disabled</button>
<button class="component-button is-loader loading">Loading</button>
<button class="component-button icon-left google">Continue with Google</button>

Text Inputs

Text inputs use a data-status attribute (error, valid, readonly) to drive border color, helper text color, and focus ring — keeping markup declarative and state changes a one-attribute swap.

Validation States
We'll never share your email.
Looks good.
Please enter a valid email address.
This value is locked.
<div class="component-text-input" data-status="error">
  <label for="email">Email address</label>
  <input id="email" type="email" value="not-an-email" />
  <span class="helper-text">Please enter a valid email address.</span>
</div>

Password Field

Includes a show/hide visibility toggle and a popover that lists requirements with live success states as the user types.

Interactive · Try typing

Your password must include:

  • At least 8 characters
  • One uppercase letter
  • One number
  • One special character
Click the eye icon to reveal your password.

Select

Native <select> styled with the same status system as inputs — appearance is stripped and a custom chevron is layered in via background-image.

Default · Valid · Error
Used for scheduling reminders.
Country verified.

Checkbox

Custom checkbox with a brand-colored fill and SVG checkmark on :checked. Supports the same data-status="error" validation state.

States
You must accept to continue.

Toggle Switch

Used for binary settings where the change applies immediately (no save button needed). Pure CSS animation on the thumb.

Interactive
Email notifications
SMS notifications
Two-factor authentication

Alerts

Five severities — info, success, warning, error, lockout — each pulling from the matching color ramp's 0/10/50 stops for background, border, and text. Icons are background-image based to keep markup clean.

All Variants
Verification email sent. Check your inbox.
Your password was updated successfully.
Your session will expire in 2 minutes.
Incorrect email or password. Please try again.
Too many attempts. Try again in 10 minutes.

Verification Code

Six-digit input for SMS / email one-time codes. Auto-advances on input and supports paste-fill.

Try pasting a 6-digit code
We sent a code to your phone ending in 4321.

Tooltip

Help-text trigger paired with a positioned tooltip. The trigger uses the tooltip-hover-trigger styling; the tooltip itself is absolutely positioned with a rotated-square tail.

Hover the help icon
Why do we need this? We use your phone number only to send verification codes. We'll never share or sell it.