Skip to content

Components ​

Every piece used in the Scopecraft examples. Fictitious data.

Buttons ​

Send to clientPreview as clientBuild scope+ New opportunity

Status chips and delta chips ​

+12% vs last quarter1 change requestClarifyFrom approved scopeFollow up

Segmented choice ​

Entire productOnboarding only
YesNo

Tabs ​

OverviewDiscoveryScopeSimilar projectsEstimatePricing

Search and inputs ​

Odalys Brandt$23,500

KPI card ​

Win rate
64%
+6 pts, last 12 proposals

Progress bars ​


Action list row ​

H
Hazelgrove Clinics3 questions need your answer
Clarify$31,000  Answer 3

Question card ​

Engineering supportWill your team provide implementation support?
YesNo
Why it is askedHandoff depth was not discussed.
Effect on scopeYes adds about 12 h.

Toast ​

✓ Proposal sent to Odalys Brandt

App shell ​

ScopecraftBrackenhall Studio
Workspace
Dashboard
Opportunities8
Proposals1

Alerts ​

Saved. Your scope was synced to the proposal.
Check this. 2 questions are still unanswered.
Could not send. The client email bounced. Edit address
Tip. Press ⌘K to search anything.

Badges and counters ​

Inbox 12Review 3DraftApprovedPendingOverdue Online Offline

Checkboxes, radios and switches ​

Select, range and textarea ​

Input with validation ​

Client email
Enter a full email address.
Budget
Within the approved range.

Accordion ​

What is included?

Design, build and two review rounds.

What is excluded?

Hosting, content writing and paid tools.

How are changes handled?

Each change request is priced before work starts.

‹123…9›

Table ​

ProjectOwnerValueStatus
Hazelgrove ClinicsMara$23,500Won
Brightline StudioEli$12,800Pending
Northwind LabsMara$48,000Draft
Send proposal?

Odalys Brandt will get a link to the scope and price. You can still edit afterwards.

CancelSend

Tooltip and popover ​

Win rateWon proposals divided by sent proposals, last 12.ConfidenceHow sure the estimate is, from similar projects.

Avatars and stack ​

MEHMEH+4

Stepper ​

1 Discovery2 Scope3 Estimate4 Pricing5 Send

Empty state and skeleton ​

No proposals yetCreate your first one from an opportunity.+ New proposal

Full interactive component catalog ​

All 43 families render with Bootstrap 6.0.0-alpha.1 (pinned) inside a scoped .sc-bs6-root shell with Scopecraft tokens. Local previews, usage, markup and keyboard notes are unchanged. Extended variants.

scopecraft / UI library

Every component, in context.

43 families · Live previews · Usage · Markup · Keyboard notes

Buttons

Primary is for one leading action per surface. Secondary is for peer actions. Destructive uses semantic red, never the brand gradient.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-actions"><button class="l-btn l-primary" @click="showToast('Primary action selected')">Primary action</button><button class="l-btn l-secondary" @click="showToast('Secondary action selected')">Secondary</button><button class="l-btn l-quiet" @click="showToast('Quiet action selected')">Quiet</button><button class="l-btn l-danger" @click="openNative('modal',$event)">Delete...</button><button class="l-btn l-secondary" disabled>Disabled</button></div>

Button group

Button group chooses one mode; the adjacent dropdown holds secondary actions.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-actions"><div class="l-segment" aria-label="Display mode"><button v-for="item in ['Design','Code','Preview']" :key="item" :aria-pressed="choice===item" :class="{'is-active':choice===item}" @click="choice=item">{{ item }}</button></div></div>

Pagination

Lustro foundation ↗

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-actions"><a href="/lustro">Lustro foundation ↗</a><nav class="l-pages" aria-label="Example pages"><button @click="page=Math.max(1,page-1)" :disabled="page===1">Previous</button><span>Page {{page}} / 3</span><button @click="page=Math.min(3,page+1)" :disabled="page===3">Next</button></nav></div>

Alerts

Alerts occupy the page and stay until dismissed. Notifications need a clear source, severity and next action. Do not use color alone to explain the state.

Saved

Your changes are up to date.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><div v-if="alertOpen" class="l-alert l-alert-warn" role="alert"><div><strong>Needs attention</strong><p>Two checks are waiting for a review.</p></div><button class="l-icon-btn" aria-label="Dismiss notification" @click="alertOpen=false">×</button></div><button v-else class="l-btn l-secondary" @click="alertOpen=true">Show notification again</button><div class="l-alert l-alert-success"><div><strong>Saved</strong><p>Your changes are up to date.</p></div></div></div>

Toasts

A toast confirms a short-lived result; it must never be the only place for an error that needs fixing. Trigger several in quick succession: each one stays visible independently until dismissed or its six-second timer ends. Color, a label and a message communicate the variant together.

For production, keep independent IDs and timers so a new arrival never overwrites an earlier one. Render the stack in a portal above app content, cap its height and let it scroll on small screens. Keep errors that need user action inline too; the toast is only a short announcement. Respect reduced-motion when animating entry and exit.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-actions"><button class="l-btn l-primary" @click="showToast('Changes saved', 'success')">Show toast</button><button class="l-btn l-secondary" @click="showToast('Secondary action queued', 'info')">Show secondary toast</button><button class="l-btn l-secondary" @click="showToast('Review before continuing', 'warn')">Show warning</button><button class="l-btn l-secondary" @click="showToast('Could not save changes', 'error')">Show error</button></div>
<div class="l-toast-stack" aria-label="Toast notifications"><div v-for="item in toasts" :key="item.id" class="l-toast" :class="'l-toast-' + item.type" :role="item.type === 'error' ? 'alert' : 'status'"><span class="l-dot" :class="'l-dot-' + item.type" aria-hidden="true"></span><span class="l-toast-copy"><strong>{{ { success: 'Success', info: 'Info', warn: 'Warning', error: 'Error' }[item.type] }}</strong><span>{{ item.message }}</span></span><button class="l-icon-btn" :aria-label="'Dismiss ' + item.type + ' toast: ' + item.message" @click="dismissToast(item.id)">×</button></div></div>
<p>For production, keep independent IDs and timers so a new arrival never overwrites an earlier one. Render the stack in a portal above app content, cap its height and let it scroll on small screens. Keep errors that need user action inline too; the toast is only a short announcement. Respect reduced-motion when animating entry and exit.</p>

Badge

DraftReadyRunningBlocked

Use a short label with text, not a color alone. The grouped demo below includes four states.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-actions"><span class="l-badge">Draft</span><span class="l-badge l-badge-success">Ready</span><span class="l-badge l-badge-warn">Running</span><span class="l-badge l-badge-error">Blocked</span></div>
<p>Use a short label with text, not a color alone. The grouped demo below includes four states.</p>

Progress

Progress has a value and a max; use an indeterminate loader only when no useful estimate exists.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><label class="l-field-label" for="sample-progress">Upload progress · 68%</label><progress id="sample-progress" max="100" value="68">68%</progress></div>
<p>Progress has a value and a max; use an indeterminate loader only when no useful estimate exists.</p>

Spinners/Loaders

Name the loading region for assistive technology.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><span class="l-spinner" role="status" aria-label="Loading"></span></div>
<p>Name the loading region for assistive technology.</p>

Placeholders

Loading summary...

Skeletons reserve space while content loads; do not leave them in a permanent empty state.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><div class="l-skeleton" aria-hidden="true"></div><p>Loading summary...</p></div>
<p>Skeletons reserve space while content loads; do not leave them in a permanent empty state.</p>

Card

Use a compact summary with a clear title, metadata and the next action; keep card links and nested buttons separate.

PROJECT · REPO A

Review changes

The latest request is waiting for your review.

Needs review
TASK · 024

Ready to ship

Checks completed. The next step is a merge.

Ready

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-grid"><article class="l-card"><span class="l-eyebrow">PROJECT · REPO A</span><h3>Review changes</h3><p>The latest request is waiting for your review.</p><div class="l-card-foot"><span class="l-badge l-badge-warn">Needs review</span><button class="l-btn l-secondary" @click="showToast('Card action selected')">Open</button></div></article><article class="l-card"><span class="l-eyebrow">TASK · 024</span><h3>Ready to ship</h3><p>Checks completed. The next step is a merge.</p><div class="l-card-foot"><span class="l-badge l-badge-success">Ready</span><button class="l-btn l-secondary" @click="showToast('Card action selected')">Details</button></div></article></div>

Accordion

Use the shared color, type and spacing tokens.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><div v-for="item in ['Tokens','Behavior','Accessibility']" :key="item" class="l-accordion"><button :aria-expanded="accordion===item" @click="accordion=accordion===item?'':item">{{item}} <span>{{accordion===item?'−':'+'}}</span></button><p v-if="accordion===item">{{item==='Tokens'?'Use the shared color, type and spacing tokens.':item==='Behavior'?'Keep transitions short and tied to a state change.':'Use labels, visible focus and reduced-motion fallbacks.'}}</p></div></div>

List group

  • 01 · Surface tokensDocs
  • 02 · Component statesReady

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><ul class="l-list"><li><span>01 · Surface tokens</span><span class="l-badge">Docs</span></li><li><span>02 · Component states</span><span class="l-badge l-badge-success">Ready</span></li></ul></div>

Tables

ComponentStatusOwner
ButtonsReadyDesign
NotificationsReviewProduct
GraphsExampleMotion
No results

Try a different search or clear your filters.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><div class="l-table-scroll"><table class="l-table"><thead><tr><th scope="col">Component</th><th scope="col">Status</th><th scope="col">Owner</th></tr></thead><tbody><tr><td>Buttons</td><td><span class="l-badge l-badge-success">Ready</span></td><td>Design</td></tr><tr><td>Notifications</td><td><span class="l-badge l-badge-warn">Review</span></td><td>Product</td></tr><tr><td>Graphs</td><td><span class="l-badge">Example</span></td><td>Motion</td></tr></tbody></table></div><div class="l-empty"><strong>No results</strong><p>Try a different search or clear your filters.</p><button class="l-btn l-secondary" @click="search=''">Clear filters</button></div></div>

Forms

Use descriptive labels, not only placeholders.
Density

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-form"><label class="l-field-label" for="sample-search">Search components</label><input id="sample-search" type="search" v-model="search" placeholder="Search by name"><small>{{search?`Searching for “${search}”`:'Use descriptive labels, not only placeholders.'}}</small><label class="l-field-label" for="sample-select">Category</label><select id="sample-select"><option>All components</option><option>Actions</option><option>Feedback</option><option>Content</option></select><label class="l-field-label" for="sample-notes">Notes</label><textarea id="sample-notes" rows="2" placeholder="Optional notes"></textarea><label class="l-check"><input type="checkbox" checked> Send updates</label><fieldset><legend>Density</legend><label class="l-check"><input type="radio" name="density" checked> Comfortable</label><label class="l-check"><input type="radio" name="density"> Compact</label></fieldset><label class="l-switch"><input type="checkbox" checked><span aria-hidden="true"></span> Enable notifications</label></div>

Tooltips

Optional help appears on hover and keyboard focus. Required instructions stay visible.

Changes apply to this workspace.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><span class="kit-tooltip"><button class="l-btn l-secondary" aria-describedby="kit-tip">Focus or hover for help</button><span id="kit-tip" role="tooltip">Changes apply to this workspace.</span></span></div>

Popovers

The adjacent disclosure stays open for longer text.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-actions"><details class="l-dropdown"><summary>More information</summary><div class="l-menu l-popover">This content stays visible until you close the panel.</div></details></div>

Close button

Use an accessible name and a hit area large enough to tap. The toast is an illustration, not a destructive action.

Close a dismissible panel

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-actions"><button class="l-close" aria-label="Close sample panel" @click="showToast('Sample panel closed')">×</button><span>Close a dismissible panel</span></div>

Collapse

For one block of secondary detail, prefer native disclosure. Accordion above coordinates several blocks.

Show delivery details

Open with Enter or Space without losing context.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><details class="l-collapse"><summary>Show delivery details</summary><p>Open with Enter or Space without losing context.</p></details></div>

Offcanvas

Drawer / sheet / offcanvas: contextual details beside the current view. Native modal behavior includes Escape and focus containment.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><button class="l-btn l-secondary" @click="openNative('sheet',$event)">Open side panel</button></div>

Scrollspy

Select a section to bring it into view; the active state is also exposed as text.

Inicio

Section inicio selected.

This is a section-selection preview, not automatic scroll tracking. Production scrollspy should use IntersectionObserver to update aria-current.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><nav class="l-spy-nav" aria-label="Example sections"><button v-for="item in ['Home','Details','Summary']" :key="item" :aria-current="menuSection===item?'location':undefined" @click="menuSection=item">{{item}}</button></nav><div class="l-card" aria-live="polite"><strong>{{menuSection}}</strong><p>Section {{menuSection.toLowerCase()}} selected.</p></div></div>
<p>This is a section-selection preview, not automatic scroll tracking. Production scrollspy should use IntersectionObserver to update aria-current.</p>

Notifications

A persistent inbox for events that need attention, distinct from short-lived toasts.

Notifications2 unread
  • Unread · Dana requested a project review4 minutes ago
  • Unread · Budget approved1 hour ago

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><div class="l-actions"><strong>Notifications</strong><span class="l-badge">{{notificationsRead?0:2}} unread</span><button class="l-btn l-secondary" @click="notificationsRead=!notificationsRead">{{notificationsRead?'Reset unread':'Mark all read'}}</button></div><ul class="l-list"><li><span>{{notificationsRead?'Read':'Unread'}} · Dana requested a project review</span><small>4 minutes ago</small></li><li><span>{{notificationsRead?'Read':'Unread'}} · Budget approved</span><small>1 hour ago</small></li></ul></div>

Attachment and file upload

Native file selection, filename and size. This preview never uploads a file.

No file selectedLocal selection only. Production: validate type and size on the server.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-form"><label>Attach a PDF or text file<input type="file" accept=".pdf,.txt" @change="selectFile"></label><span class="l-badge">{{pickedFile}}</span><small>Local selection only. Production: validate type and size on the server.</small></div>

Date picker

Use locale-aware native date input for a single date; see Calendar for richer scheduling.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-form"><label>Due date<input type="date" value="2026-10-15"></label><label>Date and time<input type="datetime-local"></label></div>

Choice card

A larger radio target for options with descriptions. Arrow keys move between native radios.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-grid"><label class="l-card"><input type="radio" name="delivery" checked> <strong>Weekly summary</strong><p>A weekly overview of your workspace.</p></label><label class="l-card"><input type="radio" name="delivery"> <strong>Daily summary</strong><p>Updates at the end of each day.</p></label></div>

Stepper

Show a finite workflow. Production steps must not bypass required validation.

  1. 1. Details
  2. 2. Review
  3. 3. Done

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><ol class="l-actions"><li v-for="(s,i) in ['Details','Review','Done']" :aria-current="step===i+1?'step':undefined" :class="{'l-badge':step===i+1}">{{i+1}}. {{s}}</li></ol><div class="l-actions"><button class="l-btn l-secondary" :disabled="step===1" @click="step--">Back</button><button class="l-btn l-secondary" :disabled="step===3" @click="step++">Continue</button></div></div>

Hover card

Optional rich context. Native disclosure also makes the information available without a mouse.

Dana Lee · Coach details
Dana Lee

Lead coach · 12 classes this month

Available

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><details><summary>Dana Lee · Coach details</summary><article class="l-card"><strong>Dana Lee</strong><p>Lead coach · 12 classes this month</p><span class="l-badge l-badge-success">Available</span></article></details></div>

Message

Keep sender and time with the content. Incoming, outgoing and system states have different roles.

Dana · 10:42

Ready for review.

You · 10:43

I will check the task list.

System · Review requested

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo"><article class="kit-bubble"><strong>Dana · 10:42</strong><p>Ready for review.</p></article><article class="kit-bubble outgoing"><strong>You · 10:43</strong><p>I will check the task list.</p></article><small>System · Review requested</small></div>

Range slider

For approximate numeric settings; always show the current value. Arrow keys adjust the native slider.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-form"><label>Volume<input type="range" min="0" max="100" v-model="volume"><output>{{volume}}%</output></label></div>

Input group

Combine a field with units or a related action while retaining a visible label.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-form"><label>Budget (USD)<div class="l-actions"><span>$</span><input type="number" min="0" value="1200"><button class="l-btn l-secondary" @click="showToast('Demo budget updated','success')">Apply</button></div></label></div>

Validation and field states

Validate after interaction, preserve entered values, and connect errors to the field.

Use a short unique name

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-form"><form @submit.prevent="formSent=true" novalidate><label>Project name<input v-model="formName" required :aria-invalid="formSent&&!formName.trim()" aria-describedby="kit-validation"></label><small id="kit-validation" role="status">{{formSent?(formName.trim()?'Demo saved':'Enter a project name'):'Use a short unique name'}}</small><label>Read-only reference<input value="PRJ-042" readonly></label><label>Disabled field<input value="Managed by workspace" disabled></label><button class="l-btn l-secondary" type="submit">Validate demo</button></form></div>

Error and retry

Explain the failure, keep context, and offer recovery. This retry is local simulation.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo" :role="failed?'alert':'status'"><strong>{{failed?'Could not load projects':'Demo projects loaded'}}</strong><p>{{failed?'Your previous changes are safe. Try again.':'Connection restored (simulation).'}}</p><button class="l-btn l-secondary" @click="failed=!failed">{{failed?'Try again':'Reset error'}}</button></div>

Empty state

Explain why there is no content and offer one useful next action.

No projects yet

Create a project to start tracking work.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-empty"><strong>No projects yet</strong><p>Create a project to start tracking work.</p><button class="l-btn l-secondary" @click="showToast('Demo project created','success')">Create demo project</button></div>

Select and suggestions

Use select for a fixed set. Datalist is browser-native suggestions, not a full custom combobox.

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-form"><label>Priority<select><option>Normal</option><option>High</option><option>Low</option></select></label><label>Owner suggestions<input list="kit-owners" placeholder="Type a name"></label><datalist id="kit-owners"><option value="Dana Lee"/><option value="Marcos Silva"/></datalist></div>

Checkbox, radio and switch

Choose many values with checkboxes, one with radios, and immediate on/off settings with a switch.

Plan

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-form"><label><input type="checkbox" checked> Email updates</label><label><input type="checkbox" disabled> Managed option (disabled)</label><fieldset><legend>Plan</legend><label><input type="radio" name="kit-plan" checked> Personal</label><label><input type="radio" name="kit-plan"> Team</label></fieldset><label class="l-switch"><input type="checkbox" role="switch" checked><span aria-hidden="true"></span> Automatic reminders</label></div>

Avatar

Initials fallback and text status. Noninteractive avatars do not need a tab stop.

DLMSAvailable

Keyboard: Tab to interactive controls. Enter activates buttons and links; Space toggles native choices. Disabled controls cannot be activated. Use Escape to close modal surfaces.

Copy implementation markup
<div class="l-demo l-actions"><span class="l-avatar" role="img" aria-label="Dana Lee">DL</span><span class="l-avatar" role="img" aria-label="Marcos Silva">MS</span><span>Available</span></div>

Archive project?

This is a local demo. No project is changed.

Project details

Dana Lee · Launch checklist