Skip to content

Design System

Zach Gollwitzer edited this page Apr 18, 2025 · 2 revisions

This page is a WIP.

Below, you can find all of the latest design tokens that we use. This file should be treated as the source of truth. If you see mismatches in the codebase, it is likely a mistake. We aim to match this file 1:1 in our codebase.

All these tokens should be defined in a single file here:

https://github.com/maybe-finance/maybe/blob/main/app/assets/tailwind/maybe-design-system.css

Conventions

In the Maybe app, we define everything centrally. We do NOT use dark:custom-style throughout the views, but instead, define our functional "tokens" with all the necessary themes:

// Functional "utility" class (this is what we use in our views)
@utility text-primary {
  @apply text-gray-900; // Primitive Tailwind class

  @variant theme-dark {
   @apply text-white; // Primitive Tailwind class
  }
}

Then, throughout the codebase, we attempt to exclusively use these Tailwind functional utility classes so we automatically get the benefit of dark/light mode without duplicate effort:

Correct:

<p class="text-primary">This works in both dark / light mode automatically</p>

Incorrect usage

<p class="text-gray-900 dark:text-white">INCORRECT USAGE</p>

Component conventions

Tokens for "components" (i.e. buttons, checkbox, tooltip, switch, etc.) should generally NOT be defined in our global CSS file. Instead, they should be referenced and encapsulated in a partial that represents that component.

NOTE: The current codebase does not yet reflect this and has scattered usage of classes like btn btn--primary throughout. We plan to migrate towards ViewComponent in the future and will be extracting these usages into a centralized component.

Form conventions

The majority of our forms are styled through a custom Form Builder, which is invoked via styled_form_with helper:

<%= styled_form_with model: @some_model do |f| %>
  <%# All form elements are automatically styled %>
<% end %>

All styles should be consolidated here unless the form is a "one-off" form_with not utilizing these global builder styles.

Design tokens

  • Usage Class - this represents the "functional token" that we use throughout the views
  • Light - the primitive Tailwind class this token is an alias to
  • Dark - the primitive Tailwind class this token is an alias to

Background tokens

Usage Class Light Dark
bg-surface bg-gray-50 bg-black
bg-surface-hover bg-gray-100 bg-gray-800
bg-surface-inset bg-gray-100 bg-gray-900
bg-surface-inset-hover bg-gray-200 bg-gray-800
bg-container bg-white bg-gray-900
bg-container-hover bg-gray-50 bg-gray-800
bg-container-inset bg-gray-50 bg-gray-800
bg-container-inset-hover bg-gray-100 bg-gray-700
bg-inverse bg-gray-800 bg-white
bg-inverse-hover bg-gray-700 bg-gray-100
bg-overlay bg-gray-100/50 bg-black/90
chat-bg-default bg-gray-100 bg-gray-900
tab-bg-group bg-gray-50 bg-black/70
tab-item-active bg-white bg-gray-700
tab-item-hover bg-gray-200 bg-gray-800
menu-item-item-active bg-white bg-gray-800
menu-item-item-hover bg-gray-100 bg-gray-800

Foreground tokens

Usage Class Light Dark
fg-primary text-gray-900 text-white
fg-primary-variant text-gray-800 text-gray-50
fg-secondary text-gray-50 text-gray-700
fg-secondary-variant text-gray-100 text-gray-600
fg-gray text-gray-500 text-gray-400
fg-subdued text-gray-400 text-gray-500
fg-contrast text-gray-400 text-gray-500
fg-inverse text-white text-gray-900
text-primary text-gray-900 text-white
text-secondary text-gray-500 text-gray-400
text-subdued text-gray-400 text-gray-600
text-link text-blue-600 text-blue-500

Semantic tokens

Usage Class Light Dark
success text-green-600 text-green-500
warning text-yellow-600 text-yellow-400
destructive text-red-600 text-red-400

Border tokens

Usage Class Light Dark
border-primary border-black/30 border-white/40
border-secondary border-black/20 border-white/30
border-tertiary border-black/10 border-white/20
border-subdued border-black/5 border-white/10
border-solid border-black border-white
border-destructive border-red-500 border-red-400

Utility tokens

Usage Class Light Dark
progress-ring-fill fill-gray-200 fill-gray-700
shadow shadow shadow

Component tokens

Buttons

Usage Class Light Dark
button-bg-primary bg-gray-900 bg-white
button-bg-primary-hover bg-gray-800 bg-gray-50
button-bg-secondary bg-gray-50 bg-gray-700
button-bg-secondary-hover bg-gray-100 bg-gray-600
button-bg-ghost-hover bg-gray-50 bg-gray-800
button-bg-outline-hover bg-gray-100 bg-gray-700
button-bg-disabled bg-gray-50 bg-gray-700
button-bg-destructive bg-red-500 bg-red-400
button-bg-destructive-hover bg-red-600 bg-red-500

Inputs

Usage Class Light Dark
input-bg-default bg-white bg-black/70
input-bg-variant bg-white bg-gray-900
input-bg-disabled bg-gray-50 bg-black/50
input-border-default border-black/10 border-white/20
input-border-hover border-black/20 border-white/30
input-border-focus border-black border-white

Switches

Usage Class Light Dark
switch-bg-default bg-gray-100 bg-gray-700
switch-bg-hover bg-gray-200 bg-gray-800
switch-bg-active bg-green-600 bg-green-500
switch-bg-active-hover bg-green-700 bg-green-600
switch-bg-disabled bg-gray-100 bg-gray-800
switch-indicator-fill bg-white bg-gray-500
switch-indicator-fill-active bg-white bg-gray-500
switch-indicator-fill-disabled bg-gray-50 bg-gray-700

Checkboxes

Usage Class Light Dark
checkbox-bg-default bg-white bg-gray-800
checkbox-bg-active bg-gray-900 bg-white
checkbox-bg-disabled bg-gray-50 bg-gray-900
checkbox-border border-black/20 border-white/30
checkbox-border-disabled border-black/10 border-white/20

Tooltips

Usage Class Light Dark
tooltip-bg-on-chart bg-white bg-gray-800
tooltip-bg-default bg-gray-700 bg-gray-800