This repo defines a structured color system for web apps, based on a custom color palette:
- Strong neutrals for UI chrome and text
- Opinionated accents with a tech/cyber vibe
- Semantic tokens for app components (buttons, alerts, forms, shell)
The goal: use semantic tokens everywhere ($color-*, $btn-*, $alert-*) and keep raw hex values and fun names ($scrap-green, $robo-sludge, etc.) mostly inside colors.scss.
colors.scss– Single source of truth for:- Base palette
- Neutral scale
- Semantic design tokens
- Component-level aliases
- Optional CSS Custom Properties export
This README documents how to consume those tokens in your app.
In your main stylesheet:
@use 'colors' as *; // or a relative path, e.g. 'styles/colors';
@use 'colors' as c;
body {
background-color: c.$color-bg-body;
color: c.$color-text;
}
// The examples below assume as * for brevity.The system is split into:
- Base Palette – raw colors & neutrals
- Semantic Tokens – layout, text, brand, states, shell
- Component Aliases – buttons, forms, alerts, badges
- Optional CSS Custom Properties – :root { --color-… }
You should rarely need to touch the base palette once wired in.
Use these for page backgrounds, cards, and structure:
$color-bg-body– main app background$color-bg-surface– primary cards, sheets$color-bg-surface-alt– subtle panels / inset areas
Example:
body {
background-color: $color-bg-body;
color: $color-text;
}
.card {
background-color: $color-bg-surface;
border: 1px solid $color-border-subtle;
}
.card--inset {
background-color: $color-bg-surface-alt;
border: 1px solid $color-border-default;
}Text tokens maintain legible hierarchy:
$color-text– body text$color-text-strong– headings$color-text-muted– timestamps, hints$color-text-soft– labels, neutral statuses$color-text-inverse– text on dark backgrounds$color-text-link,$color-text-link-hover, $color-text-link-visited`
Example:
h1, h2, h3 {
color: $color-text-strong;
}
.meta {
color: $color-text-muted;
}
a {
color: $color-text-link;
text-decoration: none;
&:hover {
color: $color-text-link-hover;
}
}Accessibility note: Avoid using $scrap-green, $cyber-green, or $future-yellow as long-running text on white; they are used primarily as fills and backgrounds with dark text.
$color-primary– main brand color (scrap green)$color-primary-strong– dark, high-contrast variant (twilight)$color-primary-soft-bg/$color-primary-soft-border– subtle brand tints$color-on-primary– text on primary backgrounds
Primary button example:
.button--primary {
background-color: $btn-primary-bg;
color: $btn-primary-text;
border: 1px solid $btn-primary-border;
&:hover {
background-color: $btn-primary-bg-hover;
}
}Use the pre-defined button tokens instead of rolling your own colors:
- Primary:
$btn-primary-* - Secondary:
$btn-secondary-* - Ghost / Neutral:
$btn-ghost-* - Destructive:
$btn-danger-*
Example — Secondary Button
.button--secondary {
background-color: $btn-secondary-bg;
color: $btn-secondary-text;
border: 1px solid $btn-secondary-border;
&:hover {
background-color: $btn-secondary-bg-hover;
}
}Tokens for inputs, labels, and validation states:
- Backgrounds:
$input-bg,$input-disabled-bg - Borders:
$input-border,$input-border-hover,$input-border-focus,$input-border-error - Text:
$input-text,$input-placeholder,$input-label,$input-helper-text,$input-error-text
Example — Form Input
.input {
background-color: $input-bg;
border: 1px solid $input-border;
color: $input-text;
&::placeholder {
color: $input-placeholder;
}
&:hover {
border-color: $input-border-hover;
}
&:focus {
border-color: $input-border-focus;
outline: none;
}
&--error {
border-color: $input-border-error;
+ .input__message {
color: $input-error-text;
}
}
&--disabled {
background-color: $input-disabled-bg;
color: $input-disabled-text;
}
}Use the alert tokens for banners, inline alerts, and toasts:
- Success:
$alert-success-* - Error:
$alert-error-* - Warning:
$alert-warning-* - Info:
$alert-info-*
Example — Alerts
.alert {
border-radius: 4px;
padding: 0.75rem 1rem;
display: flex;
gap: 0.5rem;
align-items: flex-start;
&--success {
background-color: $alert-success-bg;
border: 1px solid $alert-success-border;
color: $alert-success-text;
}
&--error {
background-color: $alert-error-bg;
border: 1px solid $alert-error-border;
color: $alert-error-text;
}
&--warning {
background-color: $alert-warning-bg;
border: 1px solid $alert-warning-border;
color: $alert-warning-text;
}
&--info {
background-color: $alert-info-bg;
border: 1px solid $alert-info-border;
color: $alert-info-text;
}
}- Neutral:
$badge-neutral-* - Info:
$badge-info-* - Success:
$badge-success-* - Error:
$badge-error-* - Soft pink tag:
$badge-pill-soft-pink-*
Example — Badges
.badge {
display: inline-flex;
align-items: center;
border-radius: 999px;
padding: 0.125rem 0.5rem;
font-size: 0.75rem;
font-weight: 500;
&--neutral {
background-color: $badge-neutral-bg;
color: $badge-neutral-text;
}
&--info {
background-color: $badge-info-bg;
color: $badge-info-text;
}
&--success {
background-color: $badge-success-bg;
color: $badge-success-text;
}
&--error {
background-color: $badge-error-bg;
color: $badge-error-text;
}
&--pill-pink {
background-color: $badge-pill-soft-pink-bg;
color: $badge-pill-soft-pink-text;
}
}Tokens for top nav and sidebars:
$color-shell-bg,$color-shell-bg-alt$color-shell-border$color-shell-text,$color-shell-text-muted$color-shell-accent
Example — App Shell
.app-shell {
background-color: $color-shell-bg;
color: $color-shell-text;
}
.app-shell__nav-link {
color: $color-shell-text-muted;
&--active {
color: $color-shell-text;
border-bottom: 2px solid $color-shell-accent;
}
}colors.scss also exports a :root block with matching CSS variables (e.g. --color-bg-body, --color-primary, etc.).
Use them when:
- You have non-Sass environments (e.g. inline styles, JS-driven themes)
- You want runtime theming (dark mode, brand switching)
Example — Using CSS Variables
body {
background-color: var(--color-bg-body);
color: var(--color-text);
}
.button--primary {
background-color: var(--color-primary);
color: var(--color-on-primary);
}If you don’t need this, comment out the :root { … } block at the bottom of colors.scss.
Do:
- Use
$color-*and component aliases for all UI styling. - Keep actual hex values isolated to
colors.scss. - Use bright accent colors mostly as fills or backgrounds with dark text.
Don’t:
- Hardcode arbitrary hex values in components.
- Use
$future-yellowas paragraph text on white backgrounds. - Overuse raw brand colors where a semantic token exists.