Getting Started {CDN usage}

Use this design system in any project by adding these tags to your HTML

<!-- CSS — add to <head> -->
<link rel="stylesheet" href="https://starter-project-ds.netlify.app/css/reset.css">
<link rel="stylesheet" href="https://starter-project-ds.netlify.app/css/tokens.css">
<link rel="stylesheet" href="https://starter-project-ds.netlify.app/css/components.css">

<!-- JS — add before </body> -->
<script src="https://starter-project-ds.netlify.app/js/main.js"></script>

<!-- Icons — individual SVG (fixed at 24px) -->
<img src="https://starter-project-ds.netlify.app/icons/heart.svg" alt="heart">

<!-- Icons — SVG sprite (any size via width/height) -->
<!-- main.js auto-injects the sprite, so use local #id refs -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
     stroke="currentColor" stroke-width="2">
  <use href="#heart"></use>
</svg>

<!-- Change width/height to render at any size (16, 20, 24, 32, 40, 48) -->
<svg width="16" height="16" viewBox="0 0 24 24" ...>...</svg>
<svg width="32" height="32" viewBox="0 0 24 24" ...>...</svg>
<svg width="48" height="48" viewBox="0 0 24 24" ...>...</svg>

A full starter template is available at /starter/index.html.

DS

Color Tokens {tokens.css}

Design system color variables — adapts to light and dark mode

Background — Default
Default--bg-default
Default Hover--bg-default-hover
Secondary--bg-secondary
Secondary Hover--bg-secondary-hover
Tertiary--bg-default-tertiary
Tertiary Hover--bg-default-tertiary-hover
Background — Neutral
Default--bg-neutral
Hover--bg-neutral-hover
Secondary--bg-neutral-secondary
Secondary Hover--bg-neutral-secondary-hover
Tertiary--bg-neutral-tertiary
Tertiary Hover--bg-neutral-tertiary-hover
Background — Brand
Default--bg-brand
Hover--bg-brand-hover
Secondary--bg-brand-secondary
Secondary Hover--bg-brand-secondary-hover
Tertiary--bg-brand-tertiary
Tertiary Hover--bg-brand-tertiary-hover
Background — Positive
Default--bg-positive
Hover--bg-positive-hover
Secondary--bg-positive-secondary
Secondary Hover--bg-positive-secondary-hover
Tertiary--bg-positive-tertiary
Tertiary Hover--bg-positive-tertiary-hover
Background — Warning
Default--bg-warning
Hover--bg-warning-hover
Secondary--bg-warning-secondary
Secondary Hover--bg-warning-secondary-hover
Tertiary--bg-warning-tertiary
Tertiary Hover--bg-warning-tertiary-hover
Background — Danger
Default--bg-danger
Hover--bg-danger-hover
Secondary--bg-danger-secondary
Secondary Hover--bg-danger-secondary-hover
Tertiary--bg-danger-tertiary
Tertiary Hover--bg-danger-tertiary-hover
Background — Disabled & Utilities
Disabled--bg-disabled
Scrim--bg-scrim
Blanket--bg-blanket
Overlay--bg-overlay
Measurement--bg-measurement
Text — Default
Default--text-default
Secondary--text-secondary
Tertiary--text-tertiary
Text — Neutral
Default--text-neutral
Secondary--text-neutral-secondary
Tertiary--text-neutral-tertiary
On Neutral--text-on-neutral
On Neutral 2nd--text-on-neutral-secondary
On Neutral 3rd--text-on-neutral-tertiary
Text — Brand
Default--text-brand
Secondary--text-brand-secondary
Tertiary--text-brand-tertiary
On Brand--text-on-brand
On Brand 2nd--text-on-brand-secondary
On Brand 3rd--text-on-brand-tertiary
Text — Positive / Warning / Danger
Positive--text-positive
Positive 2nd--text-positive-secondary
Warning--text-warning
Warning 2nd--text-warning-secondary
Danger--text-danger
Danger 2nd--text-danger-secondary
Text — Disabled & Utilities
Disabled--text-disabled
On Disabled--text-on-disabled
On Overlay--text-on-overlay
Border — Default / Neutral / Brand
Default--border-default
Default 2nd--border-default-secondary
Default 3rd--border-default-tertiary
Neutral--border-neutral
Brand--border-brand
Disabled--border-disabled
Border — Positive / Warning / Danger
Positive--border-positive
Positive 2nd--border-positive-secondary
Warning--border-warning
Warning 2nd--border-warning-secondary
Danger--border-danger
Danger 2nd--border-danger-secondary
Icon
Default--icon-default
Secondary--icon-secondary
Tertiary--icon-tertiary
Brand--icon-brand
Positive--icon-positive
Danger--icon-danger

Typography {tokens.css}

Font styles from the design system

Title Hero 72px / Bold / 1.2
Title Page 48px / Bold / 1.2
Subtitle 32px / Regular / 1.2
Heading 24px / Semi Bold / 1.2
Subheading 20px / Regular / 1.2
Body Base — The quick brown fox jumps over the lazy dog 16px / Regular / 1.4
Body Strong — The quick brown fox jumps over the lazy dog 16px / Semi Bold / 1.4
Body Emphasis — The quick brown fox jumps over the lazy dog 16px / Italic / 1.4
Body Link — The quick brown fox jumps over the lazy dog 16px / Regular / 1.4 / Underline
Body Small — The quick brown fox jumps over the lazy dog 14px / Regular / 1.4
Body Small Strong — The quick brown fox jumps over the lazy dog 14px / Semi Bold / 1.4
Body Code — const greeting = "Hello, world!"; 16px / Roboto Mono / 1.3
Single Line / Body Base 16px / Regular / 1.0
Single Line / Body Small Strong 14px / Semi Bold / 1.0

Spacing {tokens.css}

Consistent spacing scale used across all components

--space-050
2px
--space-100
4px
--space-150
6px
--space-200
8px
--space-300
12px
--space-400
16px
--space-600
24px
--space-800
32px
--space-1200
48px
--space-1600
64px
--space-2400
96px
--space-4000
160px

Border Radius {tokens.css}

Corner rounding values for components

0none
--radius-1004px
--radius-2008px
--radius-40016px
--radius-full9999px

Stroke {tokens.css}

Border and outline widths

--stroke-border1px
--stroke-focus-ring2px

Drop Shadows {tokens.css}

Elevation levels for layered surfaces

100 --shadow-100
200 --shadow-200
300 --shadow-300
400 --shadow-400
500 --shadow-500
600 --shadow-600

Inner Shadows {tokens.css}

Inset depth effects for recessed surfaces

100 --inner-shadow-100
200 --inner-shadow-200
300 --inner-shadow-300
400 --inner-shadow-400
500 --inner-shadow-500
600 --inner-shadow-600

Blur Effects {tokens.css}

Background and layer blur for overlays and glass surfaces

Abc
No blurreference
Abc
--blur-overlaybackdrop-filter: blur(4px)
Abc
--blur-layerfilter: blur(4px)
Abc
--blur-glassbackdrop-filter: blur(4px)

Hero Sections {.ds-hero}

Full-width hero banners with various content layouts

Title

Subtitle

Panel Sections {.ds-panel}

Content panels with image and text combinations

.ds-panel — image left, content right

Heading

Subheading

Body text for your whole article or post. We'll put in some lorem ipsum to show how a filled-out page might look.

Excepteur efficient emerging, minim veniam anim aute carefully curated Ginza conversation exquisite perfect nostrud nisi intricate Content.

.ds-panel — content left, image right (reversed order)

Heading

Subheading

Body text for your whole article or post. We'll put in some lorem ipsum to show how a filled-out page might look.

Excepteur efficient emerging, minim veniam anim aute carefully curated Ginza conversation exquisite perfect nostrud nisi intricate Content.

.ds-panel-double — two images side by side

Card Grid Sections {.ds-card-grid}

Grid layouts for pricing, features, content, and more

.ds-card-grid + .pricing-card — pricing tier layout

Basic

$ 10 / mo
  • List item
  • List item
  • List item
  • List item
  • List item

Pro

$ 50 / mo
  • List item
  • List item
  • List item
  • List item
  • List item

Enterprise

$ 100 / mo
  • List item
  • List item
  • List item
  • List item
  • List item

.ds-card-grid + .card-icon — icon feature cards

Heading

Subheading

Title

Body text for whatever you'd like to say. Add main takeaway points, quotes, anecdotes, or even a very very short story.

Title

Body text for whatever you'd like to say. Add main takeaway points, quotes, anecdotes, or even a very very short story.

Title

Body text for whatever you'd like to say. Add main takeaway points, quotes, anecdotes, or even a very very short story.

.ds-card-grid + .card-content-list — image content list cards

Heading

Subheading

Title

Body text for whatever you'd like to say. Add main takeaway points, quotes, anecdotes, or even a very very short story.

Title

Body text for whatever you'd like to say. Add main takeaway points, quotes, anecdotes, or even a very very short story.

Page Sections {.ds-page-section}

Standalone page content blocks

.ds-page-section + .ds-accordion — accordion FAQ layout

Heading

Subheading

Title
Answer the frequently asked question in a simple sentence, a longish paragraph, or even in a list.
Title
Answer the frequently asked question in a simple sentence, a longish paragraph, or even in a list.
Title
Answer the frequently asked question in a simple sentence, a longish paragraph, or even in a list.

.ds-page-section + .form-newsletter — newsletter signup layout

Follow the latest trends

With our daily newsletter

Buttons {.btn}

Action buttons in various styles and sizes

.btn.btn-brand, .btn-neutral, .btn-subtle, .btn-danger

.btn.btn-sm — small size

.btn.disabled — disabled state

Icon Button {.btn-icon}

Icon-only buttons in brand, neutral, and subtle variants with two sizes

.btn-icon.btn-brand, .btn-icon.btn-neutral, .btn-icon.btn-subtle — medium

.btn-icon.btn-sm — small size

Avatars {.avatar}

User profile images and initials in various sizes and shapes

.avatar — circle (default, .avatar-md, .avatar-sm)

A
B
C

.avatar.avatar-square — square (default, .avatar-md, .avatar-sm)

A
B
C

.avatar-group — overlapping stack

A
B
C
D

Tags {.tag}

Labels and badges for categorization and status

.tag — primary with dismiss button

Brand Danger Positive Warning Neutral

.tag.secondary — secondary without dismiss

Brand Danger Positive Warning Neutral

Tag Toggle {.tag-toggle}

Toggleable tags for filtering — on state uses brand fill, off state uses tertiary

.tag-toggle-group — mix of .tag-toggle.on and .tag-toggle.off

Tabs {.ds-tabs}

Tabbed navigation for switching between content panels

Overview panel content. Switch tabs to see different content.

Features panel content with details about functionality.

Pricing panel content showing available plans.

Reviews panel content with user feedback.

Support panel content with help resources.

Tooltips {.tooltip}

Contextual information on hover

.tooltip.top

TitleBody text

.tooltip.bottom

TitleBody text

.tooltip.left

TitleBody text

.tooltip.right

TitleBody text

Notifications {.notification}

Feedback messages and alerts

.notification — default

Message sent

Your message has been delivered successfully.

.notification.alert — destructive/error

Error occurred

Something went wrong. Please try again.

Dialog {.dialog-overlay}

Modal overlay for focused content and actions

Dialog Heading

This is a dialog component with a scrim overlay. It can contain any content — forms, confirmations, or informational messages.

Blade {.blade-overlay}

Side panel fixed to the right edge with transparent scrim overlay

Blade Panel

This is a blade component — a side panel that slides in from the right edge of the viewport. The transparent scrim allows the underlying page content to remain visible while preventing interaction.

Blades are well suited for supplementary content that relates to the current view: detail panes, settings panels, filters, or contextual editing forms. They keep the user oriented within the page while surfacing additional information.

Like the modal, the blade uses a shared panel header with a title and dismiss button. The body scrolls independently when content overflows.

On mobile viewports, the blade expands to full screen — effectively identical to the modal's mobile behavior — providing a consistent experience across form factors.

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae. Morbi lacinia molestie dui. Praesent blandit dolor. Sed non quam. In vel mi sit amet augue congue elementum.

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec posuere vulputate arcu. Phasellus accumsan cursus velit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae.

Fusce sagittis, libero non molestie mollis, magna orci ullamcorper dolor, at vulputate neque nulla lacinia eros. Sed id ligula quis est convallis tempor. Curabitur lacinia pulvinar nibh. Nam a sapien.

Sheet {.sheet-overlay}

Full-screen overlay with fixed header, scrollable body, and optional footer

Sheet Title

This is a sheet component — a full-screen overlay that takes over the entire viewport. Like the modal, it uses a blanket background that blocks interaction with the content below.

Sheets are ideal for immersive tasks that benefit from maximum screen real estate: complex forms, multi-step workflows, document editing, or any experience that should feel like a dedicated view rather than a floating panel.

The sheet uses the same shared panel header and footer as the modal and blade. The body scrolls independently when content overflows, while the header and footer remain pinned.

On all viewport sizes, including mobile, the sheet fills the entire screen — making it consistent across breakpoints. This is the key difference from modals (centered with max-width) and blades (side-anchored with fixed width).

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

List Row {.list-row}

Flexible row component for lists, with optional icon, subtitle, right content, and chevron

.list-row-icon — Avatar variant (icon in 40px rounded box)

Recent Activity 3 new transactions
$1,240.00 +$80.00
Payment Method Visa ending in 4242
$0.00 No balance

.list-row-icon.icon-only — Icon variant (raw 24px icon, no box)

Profile Edit your personal info
Notifications Manage alert preferences

.list-row-icon.image — Image variant (40px rounded image)

Avatar
Sarah Connor Online
Avatar
John Doe Away

.list-row — no icon, header only

Privacy Policy
Terms of Service

.list-row — no icon, with right text

Subscription Monthly plan
$9.99/mo

Table {.ds-table, .ds-table-header, .ds-table-section}

Data table with rounded border, header rows, optional subtitles, and composable Table Header + Table Section wrappers

.ds-table + .align-right — transactions with right-aligned amounts

Transaction Date Amount
Coffee ShopVisa •4242 Apr 14, 20269:32 AM -$4.50Pending
Salary DepositDirect deposit Apr 12, 202612:00 AM +$3,200.00Completed
Electric BillAuto-pay Apr 10, 20266:00 AM -$87.30Completed

.ds-table-section > .ds-table-header + .ds-table — full Table Section with header

Team Members
All active and away members in your workspace
Name Role Status
Alice Martinalice@company.com DesignerProduct team Active
Bob Chenbob@company.com EngineerPlatform team Away
Carol Reyescarol@company.com Product ManagerGrowth team Active

Checkbox Field {.checkbox-field}

Checkbox input with label and optional description — supports checked, unchecked, indeterminate, and disabled states

.checkbox-group — checked, unchecked, indeterminate

.checkbox-field.disabled — disabled state

Radio Field {.radio-field}

Radio button with label and optional description — used in groups for single-select

.radio-group — default radio group

.radio-field.disabled — disabled state

Select Field {.select-field}

Dropdown select with label, description, and error states

.select-field — default

United States
Canada
United Kingdom
Germany
Japan

.select-field.error — with error message

Design
Engineering
Please select a category

.select-field — disabled

Switch Field {.switch-field}

Toggle switch with label and optional description

.switch-field — checked

.switch-field — unchecked

.switch-field.disabled — disabled

Search Input {.search-input}

Pill-shaped search field with icon

.search-input — default with placeholder

.search-input.disabled — disabled

.menu — with headings, icons, shortcuts, separator, danger item

Popover {.popover}

Floating picker for selecting from a list of options — replaces default OS pickers

.popover — default with selected, hover, and danger states

Selected
Default
Another option
Delete

.popover — minimal without icons

Option A
Option B
Option C

Icons {.icon-grid}

287 Feather icons available via SVG sprite sheet

activity
airplay
alert-circle
alert-octagon
alert-triangle
align-center
align-justify
align-left
align-right
anchor
aperture
archive
arrow-down-circle
arrow-down-left
arrow-down-right
arrow-down
arrow-left-circle
arrow-left
arrow-right-circle
arrow-right
arrow-up-circle
arrow-up-left
arrow-up-right
arrow-up
at-sign
award
bar-chart-2
bar-chart
battery-charging
battery
bell-off
bell
bluetooth
bold
book-open
book
bookmark
box
briefcase
calendar
camera-off
camera
cast
check-circle
check-square
check
chevron-down
chevron-left
chevron-right
chevron-up
chevrons-down
chevrons-left
chevrons-right
chevrons-up
chrome
circle
clipboard
clock
cloud-drizzle
cloud-lightning
cloud-off
cloud-rain
cloud-snow
cloud
code
codepen
codesandbox
coffee
columns
command
compass
copy
corner-down-left
corner-down-right
corner-left-down
corner-left-up
corner-right-down
corner-right-up
corner-up-left
corner-up-right
cpu
credit-card
crop
crosshair
database
delete
disc
divide-circle
divide-square
divide
dollar-sign
download-cloud
download
dribbble
droplet
edit-2
edit-3
edit
external-link
eye-off
eye
facebook
fast-forward
feather
figma
file-minus
file-plus
file-text
file
film
filter
flag
folder-minus
folder-plus
folder
framer
frown
gift
git-branch
git-commit
git-merge
git-pull-request
github
gitlab
globe
grid
hard-drive
hash
headphones
heart
help-circle
hexagon
home
image
inbox
info
instagram
italic
key
layers
layout
life-buoy
link-2
link
linkedin
list
loader
lock
log-in
log-out
mail
map-pin
map
maximize-2
maximize
meh
menu
message-circle
message-square
mic-off
mic
minimize-2
minimize
minus-circle
minus-square
minus
monitor
moon
more-horizontal
more-vertical
mouse-pointer
move
music
navigation-2
navigation
octagon
package
paperclip
pause-circle
pause
pen-tool
percent
phone-call
phone-forwarded
phone-incoming
phone-missed
phone-off
phone-outgoing
phone
pie-chart
play-circle
play
plus-circle
plus-square
plus
pocket
power
printer
radio
refresh-ccw
refresh-cw
repeat
rewind
rotate-ccw
rotate-cw
rss
save
scissors
search
send
server
settings
share-2
share
shield-off
shield
shopping-bag
shopping-cart
shuffle
sidebar
skip-back
skip-forward
slack
slash
sliders
smartphone
smile
speaker
square
star
stop-circle
sun
sunrise
sunset
table
tablet
tag
target
terminal
thermometer
thumbs-down
thumbs-up
toggle-left
toggle-right
tool
trash-2
trash
trello
trending-down
trending-up
triangle
truck
tv
twitch
twitter
type
umbrella
underline
unlock
upload-cloud
upload
user-check
user-minus
user-plus
user-x
user
users
video-off
video
voicemail
volume-1
volume-2
volume-x
volume
watch
wifi-off
wifi
wind
x-circle
x-octagon
x-square
x
youtube
zap-off
zap
zoom-in
zoom-out

Examples

Full-page compositions built entirely from shared design system components

Page Newsletter

Follow the latest trends

With our daily newsletter

Page Product

Wireless Headphones

New Arrival
$50

Premium wireless headphones with active noise cancellation and 30-hour battery life.

Midnight Black
Silver
Navy Blue
Standard
Compact

Answer the frequently asked question in a simple sentence, a longish paragraph, or even in a list.

Free shipping on orders over $50. Returns accepted within 30 days of purchase.

All products come with a 1-year limited warranty covering manufacturing defects.

Page Product Results

Wireless Speaker$45
Smart Watch$120
Running Shoes$89
Desk Lamp$35
Backpack$65
Sunglasses$55

AI Chatbot

Flippy chats
Chats
Analog Clock React app
Simple Design System
Figma variable planning
OKCLH token algorithm
Component naming advice
Hey Flippy! Write me a script for building an Analog Clock.
F

Sure. Here is a Typescript code block for your Analog Clock project. It is built using React, and uses the local time for London, England as standard. Let me know if you would like to make any refinements to the code.

import React, { useState, useEffect } from "react"; export default function AnalogClock({ updateInterval = 1000, secondHandColor = "red", minuteHandColor = "black", hourHandColor = "black", }) { const [time, setTime] = useState({ hours: 0, minutes: 0, seconds: 0 }); useEffect(() => { const updateClock = () => { const now = new Date(); setTime({ hours: now.getHours(), minutes: now.getMinutes(), seconds: now.getSeconds() }); }; updateClock(); const id = setInterval(updateClock, updateInterval); return () => clearInterval(id); }, [updateInterval]); }