Canvas Design System
Main Site Tokens

Components

Reusable UI building blocks. Live interactive demos with the PHP code you need to implement them.

Buttons

Three main variants: Primary (gradient CTA), Secondary (outlined), and Ghost (minimal). All use 10px radius and semibold weight.

Primary Button

Red gradient, white text. Used for main CTAs.

<?= ws_button('Default', ['variant' => 'primary']) ?>
<?= ws_button('With Icon', ['variant' => 'primary', 'icon' => 'add']) ?>

Secondary Button

Cream background, navy border, navy text. For secondary actions.

<?= ws_button('Secondary', ['variant' => 'secondary']) ?>
<?= ws_button('Settings', ['variant' => 'secondary', 'icon' => 'settings']) ?>

Ghost Button

Transparent background, subtle border. For less prominent actions.

<?= ws_button('Ghost', ['variant' => 'ghost']) ?>
<?= ws_button('Cancel', ['variant' => 'ghost', 'icon' => 'close']) ?>

Danger Button

<?= ws_button('Delete', ['variant' => 'danger']) ?>

States

Size Modifiers

SizeCode
Small'size' => 'sm'
Medium (default)'size' => 'md'
Large'size' => 'lg'

Cards

Cards are the primary content container. Use ws_card() for simple cards or ws_card_start() / ws_card_end() for complex content.

Basic Card

This is a basic card with simple text content.
<?= ws_card('This is a basic card with simple text content.') ?>

Card with Title

A card description that provides useful information.
<?= ws_card('Description text.', ['title' => 'Card Title']) ?>

Custom Card Content

W
Team Workshop
Design Sprint · 45 min

A collaborative exercise for rapid ideation and prototyping.

Ideation 45 min
<?php ws_card_start(); ?>
    <!-- Custom card content -->
<?php ws_card_end(); ?>

Inputs

All inputs use 12px radius, consistent padding, and a focus ring in the app's accent color.

<?= ws_input('field', ['label' => 'Label', 'placeholder' => 'Enter text...']) ?>
<?= ws_input('q', ['label' => 'Search', 'type' => 'search', 'icon' => 'search']) ?>

Badges

Category, status, and duration badges for labeling content.

Variants

Default Success Warning Danger Info
<?= ws_badge('Success', ['variant' => 'success']) ?>
<?= ws_badge('Warning', ['variant' => 'warning']) ?>

With Icons

Active Pending Error

Duration Badge

15 min 30 min 1 hour 1h 30m
<?= ws_duration('30 min') ?>
<?= ws_duration('1h 30m') ?>

Alerts

Contextual feedback messages for user actions.

<?= ws_alert('Message text.', ['variant' => 'success']) ?>
<?= ws_alert('Warning text.', ['variant' => 'warning']) ?>

Avatars

User images with initials fallback.

BB
JD
AS
<?= ws_avatar('Bill Bulman', ['size' => 'sm']) ?>
<?= ws_avatar('Jane Doe', ['size' => 'md']) ?>
<?= ws_avatar('Alex Smith', ['size' => 'lg']) ?>

Select

Dropdown select fields styled consistently with inputs.

expand_more
<?= ws_select('category', [
    '' => 'Select...',
    'ideation' => 'Ideation',
    'strategy' => 'Strategy',
], ['label' => 'Category']) ?>

Modals

Five size presets. Below 600px, modals convert to bottom sheets.

SizeMax WidthUse Case
Small360pxConfirmations, simple actions
Default500pxStandard forms, details
Large640pxComplex forms, settings
XL800pxMulti-step flows
Full100vw - 48pxImage viewers, rich editors
phone_iphone Mobile behavior (below 600px): Modals convert to bottom sheets with full width, rounded top corners (20px), and a drag indicator bar.

Empty States

Placeholder content when data is not available.

No items found

Get started by creating your first item.

<?= ws_empty_state('No items found', [
    'icon' => 'inbox',
    'description' => 'Get started by creating your first item.',
    'action' => ws_button('Create Item', ['variant' => 'primary', 'icon' => 'add']),
]) ?>

Tabs

Navigation tabs for switching between views.

<?= ws_tabs([
    ['label' => 'Exercises', 'active' => true],
    ['label' => 'Icebreakers'],
    ['label' => 'Workshops'],
]) ?>

Progress

Visual progress indicators.

Getting Started
In Progress
Complete
<?= ws_progress(60, ['label' => 'In Progress']) ?>

Accordion

Expandable content sections.

<?= ws_accordion([
    ['title' => 'Question?', 'content' => 'Answer text.'],
    ['title' => 'Another?', 'content' => 'More details.'],
]) ?>

Tooltip

Contextual information on hover.

data-tooltip="This is a helpful tooltip" data-tooltip-position="top"
<?= ws_tooltip('Hover over me', ['text' => 'This is a helpful tooltip']) ?>

Breadcrumb

Navigation breadcrumbs for wayfinding.

<?= ws_breadcrumb([
    ['label' => 'Home', 'href' => '/'],
    ['label' => 'Library', 'href' => '/library'],
    ['label' => 'Current Page'],
]) ?>

Skeleton

Loading placeholders that indicate content is being loaded.

<?= ws_skeleton(['type' => 'card']) ?>

Stats

Numeric statistics with labels.

2,847 Exercises
156 Workshops
12k+ Facilitators
4.8 Rating
<?= ws_stats([
    ['value' => '2,847', 'label' => 'Exercises'],
    ['value' => '156', 'label' => 'Workshops'],
]) ?>