A living reference for the CrewThat design language. Everything flows from
tokens (color, type, space, radius) in design-tokens.css into
framework-free components (.c-*) in components.css,
wired by components.js. Build new surfaces from these and they stay on-brand automatically.
The ten semantic colors. Reference them as CSS variables — never hard-code hex.
<div style="background:var(--color-primary)"></div>
<div style="background:var(--color-accent)"></div>
<div style="background:var(--color-surface)"></div>
/* in CSS */
.btn { background: var(--color-primary); }
.card { background: var(--color-surface);
border: 1px solid var(--color-line);
color: var(--color-ink); }
A modular type scale (--text-xs → --text-6xl) and three families.
<h1 style="font-size:var(--text-4xl)">Heading</h1>
<p style="font-size:var(--text-base)">Body</p>
<span style="font-family:var(--font-display)">
BEBAS NEUE
</span>
<span style="font-family:var(--font-ui)">Inter</span>
<span style="font-family:var(--font-mono)">Mono</span>
A 4px base scale. Use for padding, margin, and gap to keep rhythm consistent.
.stack { gap: var(--space-4); }
.card { padding: var(--space-6); }
.hero { margin-bottom: var(--space-16); }
Variants, sizes, disabled, and loading states.
<button class="c-btn c-btn--primary">Primary</button>
<button class="c-btn c-btn--secondary">Secondary</button>
<button class="c-btn c-btn--ghost">Ghost</button>
<button class="c-btn c-btn--danger">Danger</button>
<button class="c-btn c-btn--primary c-btn--sm">Small</button>
<button class="c-btn c-btn--primary c-btn--lg">Large</button>
<button class="c-btn c-btn--primary" disabled>Disabled</button>
<button class="c-btn c-btn--primary is-loading">
<span class="c-spinner"></span> Saving…
</button>
Inputs, selects, textareas, and the error state.
<div class="c-field">
<label class="c-field__label">Crew name</label>
<input class="c-input" type="text">
</div>
<select class="c-select">…</select>
<textarea class="c-textarea"></textarea>
<div class="c-field c-field--error">
<label class="c-field__label">Email</label>
<input class="c-input" type="email">
<div class="c-field__error">
Enter a valid email address.
</div>
</div>
Status pills for catalog and roadmap items.
<span class="c-badge c-badge--live">LIVE</span>
<span class="c-badge c-badge--soon">COMING SOON</span>
<span class="c-badge c-badge--roadmap">ROADMAP</span>
<span class="c-badge c-badge--neutral">NEUTRAL</span>
<span class="c-badge c-badge--info">INFO</span>
<span class="c-badge c-badge--warn">WARN</span>
<span class="c-badge c-badge--error">ERROR</span>
Surface container — flat, elevated, or accent-topped.
The base surface. One-pixel line, soft radius, generous padding.
Adds a large drop shadow to lift content off the page.
A gold top-border to flag featured or premium content.
<div class="c-card">
<h3>Card</h3>
<p>The base surface.</p>
</div>
<div class="c-card c-card--elevated">…</div>
<div class="c-card c-card--accent">…</div>
For zero-data views — icon, title, message, and a clear action.
<div class="c-empty">
<div class="c-empty__icon">📭</div>
<div class="c-empty__title">
No punch-list items yet
</div>
<div class="c-empty__msg">
When the crew flags an issue…
</div>
<button class="c-btn c-btn--primary">
Add item
</button>
</div>
Shimmer placeholders for loading content.
<div class="c-skeleton" style="width:70%"></div>
<div class="c-skeleton" style="width:90%"></div>
<div class="c-skeleton" style="width:50%"></div>
Accessible tabs wired by components.js via data-tabs.
<div class="c-tabs" data-tabs>
<button class="c-tab" role="tab"
aria-controls="panel-1">Overview</button>
<button class="c-tab" role="tab"
aria-controls="panel-2">Inventory</button>
</div>
<div role="tabpanel" id="panel-1">…</div>
<div role="tabpanel" id="panel-2" hidden>…</div>
Collapsible sections — click a head to toggle.
<div class="c-accordion">
<div class="c-accordion__item">
<button class="c-accordion__head">
What is a pull chart?
</button>
<div class="c-accordion__body">…</div>
</div>
<div class="c-accordion__item">…</div>
</div>
Focus-trapped dialog. CTUI.modal() handles open, close, and Esc.
<button id="open">Open modal</button>
<div class="c-modal-backdrop" id="m">
<div class="c-modal">
<button class="c-modal__close">×</button>
<div class="c-modal__title">Example modal</div>
<p>Body…</p>
<button class="c-btn c-btn--primary"
data-close>Close</button>
</div>
</div>
<script>
const m = CTUI.modal('#m');
open.addEventListener('click', m.open);
</script>
Transient notifications via CTUI.toast(msg, kind).
CTUI.toast('Saved.', 'success');
CTUI.toast('Heads up.', 'warn');
CTUI.toast('Something failed.', 'error');
Body… Press Esc, click the backdrop, the × , or Close to dismiss. Focus is trapped while open.