Presets
Custom
The parts that build every BCS screen
100+ components from resources/, rendered with the platform's own Tailwind tokens, Alpine behaviour and Blade markup. The pages below put them together into real screens. Switch on Inspect components (or press I) and hover anything to see which component it is and which file it lives in.
Design tokens
Colour, type, radius and elevation are defined once in the @theme block of css/app.css. Components use the semantic names, so changing a token restyles every screen.
Controls: button, input and select share one height at each size
Toggles: one size, 36 by 20, knob 16
Progress: sm 4px, md 8px
Badges: md 22px, sm 18px
Icon chips: 28, 32, 40
Avatars: 24, 32, 40, 64, 80
Radius and padding: control 8, card 12, card padding 20 and 16
Type
Sign in to BCS display 28/34, auth and onboarding headings only
1,284 kpi 28/32
Live Dashboard heading 20/28
Business hours title 16/22
Configure and manage all communication channels. body 14/20
Savanna Dental Care, today at a glance small 13/18
Average handle time micro 11/16
rounded-md
rounded-lg
rounded-xl shadow-sm
shadow-lg
shadow-xl
rounded-full
sm, dense rows
md, lists
lg, stat cards
initials
Page header & banners
The header at the top of each page, and the banners that mark a demo or managed-account session. The frame itself (shell, sidebar and footer) is on the App frame page.
Channel Management
Configure and manage all communication channels
Demo
Renders only when the signed-in agent or business account isDemo(). It spans the whole window above the frame: in the app it is fixed top-0 and pads the body by 40px. Here it is shown in place.
Managed account
Shown while session('admin_managing_business') is set. <x-layout.shell> renders it at the top of the content column, beside the sidebar. Exit returns the administrator to the admin panel.
Buttons & actions
One canonical button component, the onboarding wizard's Back and Continue included, plus the task-specific controls used in the console and the admin tables.
Variants and sizes
With icons and loading: click Continue
Icon-only: md and sm, square, always with an aria-label
Today <x-ui.button> takes variant primary, secondary or danger and size sm or md; other attributes merge onto the <button>. Ghost, success, lg and icon-only are kit patterns, written as plain buttons with the same classes until they become props. Icons go in the slot. The onboarding wizard's Back and Continue are this component: Back keeps its leading arrow because it navigates, Continue has no arrow, and while a step saves Continue is disabled and reads "Saving…" with a spinner. Never append an arrow to an action's label.
Inputs
Fields for typing, from the standard labelled input to the floating-label adaptive input, plus the special-purpose fields used in onboarding, scheduling and widget setup.
Focus a field to see the ring. Every text field in the kit is a .bcs-input: the adaptive, icon, search and textarea fields too, so focus is always the action colour and never the frame colour. Size it with h-control-* and text-*; don't add border, shadow or focus utilities, which would cancel its states.
Enter the full number with country code, like +254 712 345 678.
Enter a full email address, like amina@savannadental.co.ke.
Enter verification code
We sent a 6-digit code to amina@savannadental.co.ke. It expires in 10 minutes.
That code is incorrect. Check the latest email and try again.
Code verified. Your contact details are confirmed.
Didn't get the code? Resend code in 00:45
Resend, while the countdown runs
Didn't get the code? Resend code in 00:45
Resend, once it ends
Didn't get the code?
Keyboard
- 0 to 9 fills the cell and moves on. Other keys are ignored.
- Backspace clears the cell, or steps back and clears the one before.
- ← → Home End move between cells.
- Pasting the code, or the phone's one-time-code autofill, fills all six.
Active, empty
Typing
Error
That code is incorrect. Check the latest email and try again.
Verified
Code verified.
Disabled, while a new code is sent
Grouped 3 + 3
Type or paste 482913 to see it verify; any other six digits show the error state. Classes live in the auth block of bcs-kit.css: .bcs-otp (add .is-error, .is-success or .is-disabled), .bcs-otp-slot, .bcs-otp-cell, .bcs-otp-caret and .bcs-otp-sep. Give each cell placeholder=" " so empty and filled cells style themselves. Behaviour comes from Alpine.data('bcsOtp') in assets/js/bcs-kit.js (in the app, resources/js/app.js); its options are listed there.
The main accent color used for the widget header, buttons and links
| Day | Open | Operating Hours |
|---|---|---|
|
-
Closed
|
Selection controls
Switches, radios, checkboxes and chips for turning settings on and off and for picking one option from several.
| Permission | View | Create | Edit | Delete |
|---|---|---|---|---|
Calls | ||||
| Call history | ||||
| Call recordings | ||||
Support tickets | ||||
| Tickets | ||||
Bug found in the source: app.js checks e.target.classList.contains('filter-chip'), so clicking the icon inside a chip does nothing. This showcase uses e.target.closest('.filter-chip') instead.
Dropdowns & menus
Selects for form values, which open one clean list 6px under the field, plus the Alpine menus and popovers that open over tables and builders and close when you click outside them.
Large, 44px: sign-in and onboarding forms
Behaviour comes from Alpine.data('bcsListbox') in assets/js/bcs-kit.js (in the app, resources/js/app.js). Without JavaScript, keep the native <select> the component renders today: the global select rule gives it the same chevron, and .bcs-select gives it the same border and focus ring.
Add menu, with descriptions
Row actions, kebab trigger
Main menu
Account menu, with a header
Behaviour comes from Alpine.data('bcsMenu') in assets/js/bcs-kit.js (in the app, resources/js/app.js). The source uses fa-hand-wave for Greeting, which is not in Font Awesome 6.4 Free and renders blank; this showcase uses fa-hand.
Grace Achieng
Tabs
A canonical tab component in two styles, the segmented control for switching a view or a value, plus the tab strips built inline in the agent console and the older script-driven tabs.
Business name, logo, contact details and the industry your AI assistant is tuned for.
Opening times per weekday, holidays and exceptions, and what happens to calls after hours.
Who can sign in to this business account and what each person is allowed to do.
Platform name, support email and the default time zone for new accounts (Africa/Nairobi).
The number customers see when the platform calls them on a business's behalf: +254 20 765 4321.
Per-minute call rates in KES, invoice dates and the payment method on file.
Filled: view switch, md 36 (default)
Filled with icons, sm 32
Subtle: form choice, full width (.is-block), radios inside
Subtle, sm 32: preview setting
The active option is marked with ARIA, not a class: aria-pressed="true" on buttons in a role="group", aria-selected="true" on role="tab" buttons in a role="tablist", or a checked radio inside each label.bcs-seg-item in a form. Used for the calendar view (Appointments), the appointment channel and Sign in as (subtle), the profile and list-page switches, the email preview width and the app frame's sidebar role.
Link tabs with href and active, plus iconColor
No activity yet
No engagements yet
No notifications yet
Bug found in the source: module-profile calls showTab(key, 'profile-tab-area'), but that id belongs to the panes wrapper and the buttons sit outside it. The panels switch but the underline never moves. Passing the outer profile-tabs id, as this demo does, fixes it.
Savanna Dental Care
2nd floor, Lenana Place, Ngong Road, Kilimani, Nairobi
+254 709 100 200
#00388 Refund for cancelled visit, in progress
#00342 Insurance form missing, resolved
Dental cleaningKES 3,500
Check-up and X-rayKES 2,500
Teeth whiteningKES 12,000
Today, Tue 6 Oct
- 15:00Call back Joseph Kariuki
- 16:30Check-up for Mercy Atieno
Opening hours and holidays
Insurance we accept
Rescheduling and cancellation policy
Cards
Each kind of card has one job: card is a generic container, stat-card the dashboard KPI tile, the KPI strip the headline figures of one record, and config-card a feature tile. The others are purpose-built blocks from the console and builders.
Business hours
When calls reach your agents instead of voicemail.
Fetch knowledge from your website
Pull hours, services and contact details from your site into the AI's knowledge.
1,284
12%vs last period
23
4%vs last period
14
Live
$8,420
Invoiced on 1 October
Open (.is-open): beside the profile header's actions, when the card is 900px or wider
Savanna Dental Care
Dental clinic, Westlands, Nairobi
- 24
- 3
- < 2 h
- 4.7 / 5
Boxed: one row from 560px of card width, 2 by 2 below that
- 1.8K
- 98%
- 4.9 / 5
- < 15 min
- 1.8K
- 98%
- 4.9 / 5
- < 15 min
Stat card or KPI strip? A stat card is a dashboard tile: each figure stands alone, with its own icon chip and a trend or live line, read across a grid. A KPI strip describes one record: up to four figures inside that record's card, without icons or trends. Don't mix the two in one row. The strip is a <dl>: each item is a <div> with the label (dt) first in the source and the value shown above it. Used in the Profile header and profile card.
48
handled today
3
in queue
Last call 2 min ago
31
conversations
1:05
first reply
2 visitors on the pricing page
—
not connected
Call recording
Keep calls for quality reviews and disputes.
1,204
recordings this month
Phone numbers
Numbers routed to this business.
3
active numbers
Call queue
4 agents available
3 waiting
Longest 2:14
Chat queue
2 agents available
1 waiting
Longest 0:48
Email queue
Handled by AI first
9 unread
Oldest 3h
List views & data display
Ways of showing records: the grouped list view, console queue rows, the data table with pagination, and compact label/value and metric displays.
Wanjiru Kamau
Rescheduled Thursday cleaning
Daniel Otieno
Plumbing slot tomorrow
+254 733 908 112
Abandoned after 3:40
Order #10482
Grace Achieng
Samuel Kiprono
4:02Upland Motors, warranty claim
Grace Achieng
1:47Re: invoice for September
Peter Njoroge
0:31Do you deliver to Nakuru?
Ticket #00391
2hWidget not loading on checkout page
Today, Tue 6 Oct
Thu 8 Oct
Fri 9 Oct
| User | Role | Status | Last active | Actions | |
|---|---|---|---|---|---|
| Brian Mwangi | RoleAgent | Status | Last active2 min ago | Actions | |
| Faith Wambui | RoleAgent | Status | Last activeNever | Actions | |
| Amina Wafula | RoleBusiness | Status | Last activeYesterday | Actions | |
| Kevin Ochieng | RoleAgent | Status | Last active3 days ago | Actions |
Empty: the kit empty state in one full-width row under the headers
| User | Role | Status | Last active | Actions |
|---|---|---|---|---|
|
No users match these filters Try another role or status, or clear the search. |
||||
Select with the row checkboxes, the header checkbox (all rows; it shows a dash when only some are selected), a click on the row, or Space on a focused row; Up and Down move between rows. The behaviour is x-data="bcsRowSelect(ids, selected)" from assets/js/bcs-kit.js. The look is .bcs-list (columns and card layout; .bcs-list--actions places the row actions) plus .bcs-table-row. The row's checkbox is its selection state, so rows carry no aria-selected: that is only valid inside role="grid", which would promise cell-by-cell arrow keys. Today <x-ui.data-table> renders a plain table that scrolls sideways on a phone; the markup here is what it should render, so the kit has one table system.
Company
Savanna Dental Care
Account ID
BA-10482
Plan
Premium, monthly
Member since
14 Feb 2025
Calls
412
Chats
268
Emails
91
Tickets
37
CSAT
4.7 / 5
AHT
5:48
1,284
Calls
642
Chats
5:48
Avg handle
92%
Resolved
4.7
CSAT
Badges, avatars & status
Small signals for state. The badge component holds the one mapping from a record's status to a colour, so views pass the status instead of choosing colours themselves.
Variants
Dot, small and uppercase
Status map: the status passed in, and the badge it produces
sm
md, online
lg, offline
md
md, online
one word
lg, with src
Colours here are computed with the same crc32(name) % 8 rule as the Blade component.
xs, 24
sm, 32
md, 40
lg, 64
xl, 80
Businesses get the tile; people keep the round avatar
Savanna Dental Care
Amina Hassan
The tile only changes the avatar's corners, so colour, initials and the photo all come from <x-ui.avatar>. It's unlayered in bcs-kit.css on purpose: it has to beat the avatar's rounded-full. Seen on the Profile header and job post and review rows, and in the List page's job posts.
Sizes: default 32px, and .is-sm 24px for dense rows
Support Tickets
3Live
LiveFeedback & overlays
How the platform confirms, warns and interrupts: dialogs and drawers, toasts, the loading overlay, empty states and inline messages.
Add User
Delete number
#00391
Widget not loading on checkout page
The chat bubble doesn't appear on our checkout page since yesterday. It still works on the home page.
Thanks Grace. Could you tell us which checkout plugin you're using? We'll check whether it blocks third-party scripts.
Probably the CSP header on their checkout subdomain. Asked engineering to confirm.
No appointments this week
Appointments booked by agents or the AI receptionist show up here.
No tickets match these filters
Try another status or priority, or clear the search.
Queue is empty
New calls and chats show up here the moment they arrive.
Say which case it is: "nothing yet" tells people where rows come from, "no matches" tells them to change the filters. The classes are .bcs-empty, .bcs-empty-icon, .bcs-empty-title, .bcs-empty-desc and .bcs-empty-actions in bcs-kit.css; .is-compact trims the padding for side panels. The list page's empty rows use the same classes: List empty state.
These credentials do not match our records.
Progress, steps & timelines
Bars for amounts, and step indicators for sequences: engagement flows, onboarding and activity history.
Colour rule for every progress and score bar: primary by default (in progress or neutral), success when complete or on target, danger when failing, over a limit or critical. No other colours. The component's default colour is a raw blue, so always pass color.
Account created
Completed
14 Feb 2025
Phone number connected
+254 709 100 200
Train the AI receptionist
In Progress
6 of 10 core facts added
Go live
Pending
Vertical, in the brand pane
Compact, above the form on phones
Set up your business: Business
Step footer: Back and Continue
Step 2 of 5
Business
Name, address and logo
Click Continue and Back to move through the steps. These are the pieces of the Onboarding wizard: its brand pane shows the vertical list while the card is 760px or wider and the compact band below that. Steps are numbered because they really are a sequence. The current step carries aria-current="step" and done steps read "(done)" to screen readers; the compact bar is decorative, since its line names the step.