Reef's theme system provides a consistent design language through StyleX CSS variables. The theme defines colors, sizing, and component-specific details that can be customized to match your brand while maintaining visual harmony across all components.
The theme system is built on three main variable groups exported from @228-co/reef/themes/theme.stylex:
themeColors - Color palettes for each status type with 13 depth levels
themeSizing - Responsive font sizes and spacing using CSS clamp()
themeDetails - Component-specific tokens for padding, borders, and animations
Each color category includes 13 shades ranging from 0 (lightest) to 1000 (darkest). Colors are defined using stylex.defineVars which creates CSS custom properties that can be overridden at runtime.
| Category | Source Palette | Use Case |
|---|---|---|
danger | Red (Hagoromo) | Error states, destructive actions, and warnings requiring attention |
warning | Yellow (Hagoromo) | Caution states, pending actions, and non-critical alerts |
info | Blue (Hagoromo) | Informational content, tips, and neutral highlights |
success | Green (Hagoromo) | Positive actions, confirmations, and completed states |
primary | Lampblack / White (dark mode) | Primary brand color for main actions and emphasis |
secondary | ShrimpShell (Chinese) | Secondary brand color for alternative actions |
background | FishBelly / CeremonialBlack (dark mode) | Page and container backgrounds |
neutral | ShrimpShell (Chinese) | Neutral elements without semantic meaning |
Each color category has 13 levels: 0, 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950, 1000. Lower numbers are lighter, higher numbers are darker:
Depth 1
Depth 2
Depth 3
Depth 4
Depth 5
Depth 6
Depth 7
Depth 8
Depth 9
// Accessing theme colors
import { themeColors } from "@228-co/reef/themes/theme.stylex";
const styles = stylex.create({
error: {
color: themeColors.danger500,
backgroundColor: themeColors.danger100,
},
success: {
color: themeColors.success700,
borderColor: themeColors.success300,
},
});The theme automatically supports dark mode through CSS media queries. Colors that adapt to dark mode use the DARK constant:
export const DARK = "@media (prefers-color-scheme: dark)";
// Colors with dark mode variants
primary500: { default: Lampblack[500], [DARK]: White[500] },
background100: { default: FishBelly[100], [DARK]: CeremonialBlack[100] },
// Colors without dark mode variants remain consistent
danger500: { default: Red[500] },The sizing system uses CSS clamp() for fluid responsive values that scale smoothly between viewport sizes. This eliminates the need for breakpoints in most cases.
While sizing can be fully customized, Reef includes two presets designed for common use cases:
text-page - Optimized for content-heavy pages like blogs, documentation, and landing pages with larger, more readable typography
app-page - Designed for web applications with denser UI, smaller fonts, and tighter spacing for information-rich interfaces
The sizing tokens are based on
font0 - Smallest text (captions, labels)
font1 - Body text
font2 - Large body / small headings
font3 - Headings
font4 - Large headings
font5 - Display text
spaceXS - Extra small spacing
spaceS - Small spacing
spaceM - Medium spacing
spaceL - Large spacing
// Using sizing tokens
import { themeSizing } from "@228-co/reef/themes/theme.stylex";
const styles = stylex.create({
card: {
padding: themeSizing.spaceM,
gap: themeSizing.spaceS,
fontSize: themeSizing.font1,
},
heading: {
fontSize: themeSizing.font3,
marginBottom: themeSizing.spaceL,
},
});Component-specific tokens provide granular control over individual UI elements. These tokens often reference themeSizing values for consistency.
containerPadding - Internal padding for containers
containerBaseBorderRadius - Base border radius for container elements
containerBorderWidth - Border width for container outlines
buttonBorderWidth - Border width for buttons
buttonPaddingInline - Horizontal padding for buttons
buttonBorderRadius - Border radius for button corners
buttonIconSize - Size for icons inside buttons
buttonIconMargin - Margin around button icons
tooltipPaddingInline - Horizontal padding for tooltips
tooltipPaddingBlock - Vertical padding for tooltips
tooltipBorderRadius - Border radius for tooltip corners
popoverPaddingInline - Horizontal padding for popovers
popoverPaddingBlock - Vertical padding for popovers
popoverBorderRadius - Border radius for popover corners
animationLoadingTime - Duration for loading animations (200ms)
animationFadeTime - Duration for fade transitions (300ms)
iconPrimaryColor - Primary color for icons (adapts to dark mode)
iconSecondaryColor - Secondary color for two-tone icons
// Using detail tokens
import { themeDetails } from "@228-co/reef/themes/theme.stylex";
const styles = stylex.create({
customContainer: {
padding: themeDetails.containerPadding,
borderRadius: themeDetails.containerBaseBorderRadius,
borderWidth: themeDetails.containerBorderWidth,
},
customButton: {
paddingInline: themeDetails.buttonPaddingInline,
borderRadius: themeDetails.buttonBorderRadius,
transitionDuration: themeDetails.animationFadeTime,
},
});import {
themeColors,
themeSizing,
themeDetails,
DARK,
} from "@228-co/reef/themes/theme.stylex";const styles = stylex.create({
card: {
padding: themeSizing.spaceM,
backgroundColor: themeColors.background100,
borderRadius: themeDetails.containerBaseBorderRadius,
borderWidth: themeDetails.containerBorderWidth,
borderStyle: "solid",
borderColor: themeColors.neutral300,
},
errorState: {
color: themeColors.danger600,
backgroundColor: themeColors.danger100,
},
});When creating custom components, use the DARK media query constant for dark mode support:
import { DARK } from "@228-co/reef/themes/theme.stylex";
const styles = stylex.create({
customElement: {
backgroundColor: {
default: "#ffffff",
[DARK]: "#1a1a1a",
},
boxShadow: {
default: "0 2px 4px rgba(0,0,0,0.1)",
[DARK]: "0 2px 4px rgba(0,0,0,0.4)",
},
},
});Reef uses curated color palettes from different sources to create visually harmonious themes:
Hagoromo - Red, Yellow, Blue, Green, White palettes for semantic colors
Chinese Traditional - Lampblack, CeremonialBlack, FishBelly, ShrimpShell for primary/background/neutral tones
Use theme tokens over raw values - Reference themeColors and themeSizing instead of hardcoded values
Match depth to visual hierarchy - Use lower depth numbers (100-400) for backgrounds, higher (600-900) for text and borders
Test dark mode appearance - Colors with [DARK] variants automatically adapt, but verify your custom styles work in both modes
Leverage responsive sizing - The clamp() values in themeSizing provide smooth scaling without breakpoints
Use semantic color names - Choose colors by meaning (danger, success) rather than by color name (red, green)