Examples
Landing page demos
Two complete landing pages built entirely with Luster UI components — no extra libraries.
Luster UI
Editorial-first Web Components design system. 20 components, dark/light mode, any brand color — works in React, Vue, Angular and plain HTML.
npm install @luster-ui/ui
Quick start
import { defineCustomElements } from '@yvstudio/luster-ui/loader';
defineCustomElements();
<script type="module"
src="https://unpkg.com/@yvstudio/luster-ui/dist/luster/luster.esm.js">
</script>
Badge
Inline status indicator. Supports dot prefix for minimal presence.
<luster-badge variant="default">Default</luster-badge>
<luster-badge variant="success">Success</luster-badge>
<luster-badge variant="warning">Warning</luster-badge>
<luster-badge variant="error">Error</luster-badge>
<luster-badge variant="beta">Beta</luster-badge>
<luster-badge variant="live">Live</luster-badge>
<luster-badge variant="success" dot>Active</luster-badge>
<luster-badge variant="warning" dot>Pending</luster-badge>
<luster-badge variant="error" dot>Offline</luster-badge>
| Prop | Type | Description | Default |
|---|---|---|---|
| variant | 'default' | 'primary' | 'success' | 'warning' | 'error' | 'beta' | 'live' | Color scheme | 'default' |
| dot | boolean | Shows colored dot prefix | false |
| size | 'sm' | 'md' | Badge size | 'md' |
Input
Text field with label, helper text and error state. Fully accessible.
<luster-input
label="Email"
placeholder="you@example.com"
type="email"
></luster-input>
<luster-input
label="Password"
type="password"
helper-text="At least 8 characters"
></luster-input>
<luster-input
label="Username"
error
error-message="Username is already taken"
></luster-input>
| Prop | Type | Description | Default |
|---|---|---|---|
| label | string | Field label | '' |
| placeholder | string | Placeholder text | '' |
| type | string | Native input type | 'text' |
| value | string | Field value | '' |
| error | boolean | Error state | false |
| error-message | string | Error text below field | '' |
| helper-text | string | Helper text below field | '' |
| disabled | boolean | Disabled state | false |
Checkbox
Controlled checkbox with indeterminate state support.
<luster-checkbox label="Accept terms"></luster-checkbox>
<luster-checkbox label="Pre-selected" checked></luster-checkbox>
<luster-checkbox label="Partial" indeterminate></luster-checkbox>
<luster-checkbox label="Disabled" disabled></luster-checkbox>
| Prop | Type | Description | Default |
|---|---|---|---|
| label | string | Checkbox label | '' |
| checked | boolean | Checked state | false |
| indeterminate | boolean | Partial/indeterminate state | false |
| disabled | boolean | Disabled state | false |
| value | string | Form value | '' |
Toggle
On/off switch for settings and preference controls.
<luster-toggle label="Notifications"></luster-toggle>
<luster-toggle label="Dark mode" checked></luster-toggle>
<luster-toggle label="Disabled" disabled></luster-toggle>
| Prop | Type | Description | Default |
|---|---|---|---|
| label | string | Toggle label | '' |
| checked | boolean | On state | false |
| disabled | boolean | Disabled state | false |
Feedback
Alert
Contextual messages for feedback, errors and status updates.
<luster-alert
variant="info"
heading="Information"
message="Your account is currently under review."
dismissible
></luster-alert>
<luster-alert
variant="success"
heading="Published!"
message="Your article is now live."
dismissible
></luster-alert>
<luster-alert
variant="error"
heading="Failed to save"
message="Something went wrong. Please try again."
dismissible
></luster-alert>
| Prop | Type | Description | Default |
|---|---|---|---|
| variant | 'info' | 'success' | 'warning' | 'error' | Alert type | 'info' |
| heading | string | Bold title | '' |
| message | string | Body text | '' |
| dismissible | boolean | Shows close button | true |
| timestamp | string | Optional time label | '' |
Modal
Dialog overlay with confirm / cancel actions. Controlled via the open prop.
<luster-button variant="primary" id="openBtn">Open modal</luster-button>
<luster-modal
id="myModal"
heading="Delete article"
subtitle="This action cannot be undone."
confirm-label="Delete"
cancel-label="Cancel"
></luster-modal>
<script>
document.getElementById('openBtn').addEventListener('click', () => {
document.getElementById('myModal').open = true;
});
</script>
| Prop | Type | Description | Default |
|---|---|---|---|
| open | boolean | Controls visibility | false |
| heading | string | Dialog title | '' |
| subtitle | string | Body / description | '' |
| confirm-label | string | Confirm button text | 'Proceed' |
| cancel-label | string | Cancel button text | 'Cancel' |
| size | 'sm' | 'md' | 'lg' | Dialog width | 'md' |
Accordion
Collapsible panel. Accepts any slot content and an optional badge.
Luster UI works in React, Vue, Angular, Svelte and plain HTML — no wrappers required.
Override --dc-primary, --dc-primary-dim and --dc-on-primary. All derived tokens update via color-mix().
<luster-accordion
heading="What frameworks are supported?"
subtitle="Compatibility"
>
<p>Works in React, Vue, Angular, Svelte and plain HTML.</p>
</luster-accordion>
<luster-accordion
heading="How does theming work?"
badge="3 tokens"
badge-variant="primary"
expanded
>
<p>Override 3 CSS custom properties.</p>
</luster-accordion>
| Prop | Type | Description | Default |
|---|---|---|---|
| heading | string | Panel title | '' |
| subtitle | string | Secondary label | '' |
| badge | string | Badge text | '' |
| badge-variant | 'primary' | 'default' | 'success' | 'beta' | Badge color | 'default' |
| expanded | boolean | Open by default | false |
Cards
Card
General-purpose container with 4 surface styles. Accepts any slot content.
Default
Elevated
Glass
Feature
<luster-card variant="default">
<p>Default card</p>
</luster-card>
<luster-card variant="elevated">
<p>Elevated — shadow lift</p>
</luster-card>
<luster-card variant="glass">
<p>Glass — blur backdrop</p>
</luster-card>
| Prop | Type | Description | Default |
|---|---|---|---|
| variant | 'default' | 'elevated' | 'glass' | 'feature' | Surface style | 'default' |
| padding | 'sm' | 'md' | 'lg' | 'none' | Inner padding | 'md' |
| hoverable | boolean | Hover lift effect | false |
Article Card
Editorial content card with category, author, date and featured layout.
<luster-article-card
category="Design Systems"
heading="Building accessible color palettes"
excerpt="A practical guide to creating color tokens."
date="Apr 2026"
author="Yasmim Vieira"
author-role="Design Engineer"
></luster-article-card>
<!-- Featured variant -->
<luster-article-card
category="Web Components"
heading="Why Web Components for design systems"
excerpt="Framework-agnostic and future-proof."
featured
></luster-article-card>
| Prop | Type | Description | Default |
|---|---|---|---|
| category | string | Topic label | '' |
| heading | string | Article title | '' |
| excerpt | string | Short description | '' |
| date | string | Publication date | '' |
| author | string | Author name | '' |
| author-role | string | Author role/title | '' |
| image-url | string | Cover image URL | '' |
| featured | boolean | Hero / featured layout | false |
Profile Card
Author / user card with stats and a call-to-action button.
<luster-profile-card
name="Yasmim Vieira"
role="Design Engineer"
stat1-value="48"
stat1-label="Articles"
stat2-value="12.4k"
stat2-label="Readers"
cta-label="View Portfolio"
></luster-profile-card>
| Prop | Type | Description | Default |
|---|---|---|---|
| name | string | Display name | '' |
| role | string | Job title / role | '' |
| avatar | string | Avatar image URL | '' |
| stat1-value | string | First stat number | '' |
| stat1-label | string | First stat label | '' |
| stat2-value | string | Second stat number | '' |
| stat2-label | string | Second stat label | '' |
| cta-label | string | CTA button text | 'View Portfolio' |
Stat Card
Dashboard metric card with status, user count and optional toggle.
<luster-stat-card
heading="Analytics Engine"
description="Real-time event processing"
version="v3.1"
status="active"
users="8.2k"
has-toggle
toggle-on
></luster-stat-card>
<luster-stat-card
heading="Search Index"
status="beta"
users="430"
has-toggle
></luster-stat-card>
| Prop | Type | Description | Default |
|---|---|---|---|
| heading | string | Card title | '' |
| description | string | Short description | '' |
| version | string | Version string | '' |
| status | 'active' | 'beta' | 'deprecated' | Status badge | 'active' |
| users | string | User count label | '' |
| has-toggle | boolean | Shows toggle control | false |
| toggle-on | boolean | Toggle initial state | false |
Feature Quote
Pull quote for testimonials and editorial highlights.
<luster-feature-quote
quote="Design systems are about the relationships between components."
author="Yasmim Vieira"
role="Design Engineer"
></luster-feature-quote>
<!-- Large variant -->
<luster-feature-quote
variant="large"
quote="Good design is obvious. Great design is transparent."
author="Joe Sparano"
role="Designer"
></luster-feature-quote>
| Prop | Type | Description | Default |
|---|---|---|---|
| quote | string | Quote text | '' |
| author | string | Author name | '' |
| role | string | Author role / title | '' |
| variant | 'default' | 'large' | 'inline' | Layout variant | 'default' |
Tabs
Tabbed navigation with named slot panels. Tab definitions are passed as JSON.
<luster-tabs
tabs='[{"id":"overview","label":"Overview"},{"id":"api","label":"API Reference"}]'
active="overview"
>
<div slot="tab-overview">Overview content</div>
<div slot="tab-api">API Reference content</div>
</luster-tabs>
| Prop | Type | Description | Default |
|---|---|---|---|
| tabs | JSON string: [{id, label}] | Tab definitions | '' |
| active | string | Active tab id | '' |
Data
Resource Table
Data table for resources with score bars, status badges and row actions.
<luster-resource-table
section-label="System Components"
rows='[
{"name":"Design Tokens","category":"Foundations","score":98,"status":"active"},
{"name":"Button System","category":"Components","score":87,"status":"active"},
{"name":"Legacy Forms","category":"Deprecated","score":34,"status":"deprecated"}
]'
></luster-resource-table>
Activity Item
Feed row for activity logs and file change notifications. Two layout variants.
<!-- Activity variant -->
<luster-activity-item
label="Updated design tokens"
description="Changed primary color"
time="2 min ago"
variant="activity"
icon="edit"
></luster-activity-item>
<!-- File variant -->
<luster-activity-item
label="design-tokens.json"
description="Updated 14 tokens"
time="5 min ago"
variant="file"
file-size="4.2 KB"
downloadable
></luster-activity-item>
| Prop | Type | Description | Default |
|---|---|---|---|
| label | string | Primary text | '' |
| description | string | Secondary text | '' |
| time | string | Relative timestamp | '' |
| variant | 'activity' | 'file' | Item type | 'activity' |
| icon | string | Icon name (activity variant) | 'edit' |
| file-size | string | File size label (file variant) | '' |
| downloadable | boolean | Shows download button | false |
Layout
Hero
Full-width section header with animated glows and optional parallax image.
<luster-hero
heading="Editorial stories, beautifully organized"
subtitle="Discover and explore content from the world's best writers."
section="EXPLORE"
></luster-hero>
<!-- With image + parallax -->
<luster-hero
heading="Your headline here"
subtitle="Supporting text."
section="HOME"
image-url="https://example.com/cover.jpg"
parallax
></luster-hero>
| Prop | Type | Description | Default |
|---|---|---|---|
| heading | string | Main headline | '' |
| subtitle | string | Supporting text | '' |
| section | string | Eyebrow label (uppercase) | '' |
| image-url | string | Background image | '' |
| parallax | boolean | Parallax scroll effect | false |
Color Swatch
Visual token reference for design system documentation and palette display.
<luster-color-swatch
color="#a3a6ff"
name="Primary"
hex="#a3a6ff"
></luster-color-swatch>
| Prop | Type | Description | Default |
|---|---|---|---|
| color | string | CSS color (hex, rgb, var) | '#a3a6ff' |
| name | string | Token display name | '' |
| hex | string | Hex value shown below swatch | '' |
| size | 'sm' | 'md' | 'lg' | Swatch size | 'md' |
Theming
Any-color theming
Override three CSS custom properties to fully rebrand all components. All derived tokens — hover tints, shadows, focus rings, gradients — cascade automatically via color-mix().
:root {
--dc-primary: #f97316; /* your brand color */
--dc-primary-dim: #ea580c; /* darker shade */
--dc-on-primary: #ffffff; /* text/icon on primary */
}
/* Emerald */
:root { --dc-primary: #10b981; --dc-primary-dim: #059669; --dc-on-primary: #ffffff; }
/* Rose */
:root { --dc-primary: #f43f5e; --dc-primary-dim: #e11d48; --dc-on-primary: #ffffff; }
/* Gold (dark text — amber is light) */
:root { --dc-primary: #f59e0b; --dc-primary-dim: #d97706; --dc-on-primary: #1c1200; }
/* Sky blue */
:root { --dc-primary: #0ea5e9; --dc-primary-dim: #0284c7; --dc-on-primary: #ffffff; }
// Switch to light
document.documentElement.setAttribute('data-theme', 'light');
// Switch to dark
document.documentElement.setAttribute('data-theme', 'dark');
// Persist preference
localStorage.setItem('theme', 'light');
// Auto — let OS handle it (no JS needed)
// @media (prefers-color-scheme: light) is already active