Design System · Components

Components

Assembled, reusable units — the pieces a screen is actually built from. Every component here is a composition of elements and objects. Each section shows the component as it ships — live, working markup, never a screenshot — alongside the named pieces it's made of.

Elements vs. components

Elements are the indivisible atoms (a chip, a star, a quote, a button); objects are small clusters of those (a field row, a byline, a dropdown). This page holds components: the larger assemblies they snap into. The review card is the canonical example — a card shell wrapping six elements, so changing an element changes every component that uses it. Reach for an existing component first; compose a new one only when none bends to fit.

01

Header & navigation

The black header that anchors every screen: brand lockup, the primary module tabs, and a standalone Request Intake action held to the right. Locations is the default tab; Request Intake is present everywhere but never a peer of the sections.

Header ink-900 bg at --size-header · tabs brand underline on aria-current="page" · Request intake = a real .km-btn--ondark, right-aligned, persistent — never a styled tab.

Built from these elements. A fixed shell: brand mark, a row of tab links, and one on-dark action — the only chrome shared by every page. The whole strip speaks the on-dark token family (foundations); the mark is the system Krown K on a brand tile.

02

Review card

The Reviews-tab work unit: one Google review with a single reply action. Pure composition — a .km-card.km-card--accent with the --m-reviews spine, wrapping six elements. The profile link is icon-only so words never compete with the review; Draft reply is the one black primary per card.

Krown Streetsville
#214·Mississauga, ON
RealEstate·Jun 10, 2026·1:39 PM
Great service — they did every part, very nice to deal with.

.km-review — composition over .km-card. The card shell + --m-reviews spine are the only component-level parts; everything inside is an element.

Built from these elements — six, top to bottom. Edit any one in the element kit and it updates here.

  • Shop description — shop name (UI title) + #id · city dotline, in the shop-name font, not mono.
  • Stars — monochrome .km-stars; the score reads from the count of filled stars, never gold.
  • Reviewer byline — author · date · time dotline.
  • Quote — someone else's words, .km-quote, opening with the filled quote glyph as a quiet ornament.
  • Icon link — platform glyph + external ↗, no label, so the action recedes behind the review text.
  • Button — primary — the one real action per card.
03

Location card

The browsable unit for a single location: name as the only title, address + ID as metadata, one status chip, the K·G·A·B coverage row, and a footer. Public platform links live here; admin links live on the detail page only.

Montréal — Plateau
4521 Boul. Saint-Laurent, QC
LOC-0421
Published
Updated 2h ago Open details →

.km-loc — name is the single title; address + ID are metadata; one status chip top-right; coverage row reads K·G·A·B at a glance.

Built from these elements. A bordered card shell wrapping the location's identity, status, coverage, and footer — shop description, status pill, platform indicators, and an inline link.

04

Panel & card

The workhorse container every other component extends. Surface, hairline border, radius-md, optional 4px module spine. A header holds a title and at most one trailing control or count.

Panel with header
12 items
Optional module accent as a 4px left spine. Header holds a title and at most one trailing control or count.

.km-card · .km-card--accent with --accent for module context. Border only — never a resting shadow.

Built from these elements. The base container — almost everything else on this page is a card with something inside it: border & surface, a module accent, a plain chip as the count.

05

Detail / field-row card

A card filled with field rows — the atom of every detail page. A 160px mono-caps label pairs with a value that can hold text, a chip, or links, divided by hairlines.

Location ID
LOC-0421
Status
Published
Krown.com
Apple Business
Manual desk task

.km-field — mono caps label + value, hairline divider between. Values hold chips, links, or text.

Built from these elements. Stacks of field rows inside a card make up every detail surface.

06

Confirmation card

The “here's what I understood” receipt the system shows before doing anything. Brand left-border, mono-caps keys, a primary proceed and a quiet edit. Honest about manual work up front.

Here's what I understood
LocationLaval — Centre · LOC-0388
ChangeHours: closed Mondays; Saturday until 18:00
TargetsKrown.com · Google Business
Manual Apple & Bing desk task

.km-confirm — brand left-border, mono caps keys, primary “proceed” + quiet “edit”. Nothing publishes until confirm.

Built from these elements. A brand-accented card of key/value rows, capped with the safety actions — status pill, primary + quiet buttons.

07

Intake conversation

The conversational front door — bubbles + a persistent composer with a mic. The rep speaks plainly; the system replies with a plain receipt. Voice produces an editable transcript, never an auto-submitted action.

New hours for the Laval shop — they're closed Mondays now, and open till 6 on Saturdays.
Design Manager
Here's what I understood. Review it and I'll get it ready — nothing is published until you confirm.

.km-bubbles + .km-composer — user = ink-900 right, system = brand tint left. The mic owns the composer's bottom-right corner.

Built from these elements. A bubble thread above a composer; the confirmation card (above) slots in as the system's structured reply.

08

Processing checklist

The live “what's happening now” after a request is confirmed. Marks pair color + glyph — done ✓, active ●, manual !, queued ○ — never color alone. Reads as operational history, never a developer log.

Processing request
Updated Krown.com content done
Syncing Google Business Profile now
Apple & Bing — added to desk tasks manual
French review (Quebec) queued

.km-check — done ✓ · active ● · manual ! · queued ○. Color + glyph, never color alone.

Built from these elements. A card holding status-marked rows — each mark maps to a system status color from the token layer.

09

Activity feed

The durable “what happened” — one chronological stream across modules, every row attributed to a person. Module-tinted initial, plain-language line, who/how subtext, mono relative time.

Recent activity
L
Laval — Centre hours updated on Krown.com & Google.
by Mark · via Request Intake
2h
T
FR review approved for Plateau service page.
2 strings · Quebec French
5h
Apple Business desk task created for Laval.
awaiting manual completion
1d

.km-feed — module-tinted initial, plain-language line, who/how subtext, mono relative time. Operational history, not logs.

Built from these elements. A card of feed rows, each carrying a module-tinted initial and its author.

10

Empty & warning states

Empty isn't broken — it's an invitation. Warnings are honest and specific; blocked states say what to do next, in plain language. Each leads with a word, never just a colour.

No locations match “rimouqi”
  Check the spelling, or clear the search to see all 142 locations.
Apple & Bing are manual for now. This change was added to your desk tasks — complete it in their portals, then mark it done here.
Google sync didn't complete. The profile may be disconnected. Re-link Google, then retry — nothing on Krown.com was affected.
This is a preview environment. No content is written to live websites or platforms.

Empty dashed border, surface-2, title + one-line guidance + a recovery action. Banners manual (amber) · block (red, with next step) · info (neutral).

Built from these elements. An empty-state well plus three banner tones — each pairs an icon with a worded message and, where useful, a recovery action.

11

Dense table

Locations at scale — sticky mono headers, hover rows, and the platform tiles compacted so a hundred locations scan as one column of K·G·A·B.

LocationIDCoverageStatusUpdated
Montréal — PlateauLOC-0421
Published2h
Laval — CentreLOC-0388
Sync failed1d
Krown StreetsvilleLOC-0214
Published3d
Krown BarrhavenLOC-0177
Desk task5d

.km-table — sticky surface-2 mono headers, hairline row dividers, hover wash. Platform tiles compact to 20px inside the table so density never costs the K·G·A·B read.

12

Segmented control

The sliding pill — one thumb glides between options on the same recipe as the tab marker (--dur-page / --ease-in-out), so every sliding-marker in the system moves as one gesture.

.km-seg — surface-3 well, surface thumb with shadow-sm. The --ink variant (black thumb, white selected label) is the view-toggle voice: Table | Cards. Retired the harder-edged .km-toggle — every 2–4-option choice is a seg. Selection SLIDES, press DIPS: choosing is never a press. Click an option: the thumb glides, it never blinks.

13

Shared surface morph

A card grows into its detail surface and visibly stays the SAME object — the boundary travels the whole way on --dur-grow, the slowest deliberate move in the system. Content only renders at its own scale; the just-viewed card carries the lift when you return.

Krown Streetsville
#214 · Mississauga, ON
Krown Laval — Centre
#388 · Laval, QC
Krown Sainte-Foy
#356 · Québec, QC

growFrom / shrinkTo from $lib/motion/morph · rides --dur-grow / --ease-in-out · detail content fades in after the surface is 55% there; on the way back, content fades over the first third and the small display only appears once the surface lands. The phantom-hover guard mutes stray hover until the pointer actually moves.

14

Reorderable widgets

Drag the handle: the row follows the pointer 1:1, neighbours give way on a quick decelerate, and release lands on the rare-overshoot settle. For dashboard widgets, kanban columns, priority lists.

Replies needed
widget
Platform coverage
widget
Translation queue
widget
Recent activity
widget

createSnapDrag from $lib/motion/snap.svelte · direct index targeting (fast multi-slot drags land in one move) · window-level listeners so release ALWAYS lands · settle rides --dur-slow / --ease-settle.

15

Loading states

Calm and confident: layered skeletons with a soft sweep that stops when content lands, cards arriving on the stagger cascade, numbers rolling after. Never an endless pulse.

Montréal — Plateau
0
profile views
Laval — Centre
0
profile views
Québec — Sainte-Foy
0
profile views

.km-skeleton + km-rise on --stagger steps (capped at 6) · figures roll in on the value-roll behaviour once content lands.

16

AI generation

Generating never shows a plain spinner: a soft brand-tone border sweep, a streaming text shimmer, a pulsing caret, and the button label morphing Generate → Thinking → Regenerate. Brand tones only.

Review response · Krown Streetsville

“Great service — they did every part, very nice to deal with.” ★★★★★

.km-ai--thinking border sweep · .km-ai-shimmer streaming text · .km-ai-caret pulse — for response drafting, insight cards, translation suggestions across every AI-assisted surface.

17

Completion celebration

A tiny, contained reward on completion: the check draws itself, the badge settles in on the rare-overshoot curve, a soft tint halo breathes out once. Never confetti.

For approved · published · completed — moments worth a half-second of delight.

CheckDraw component · km-draw + km-badge-pop + km-halo on --dur-morph / --ease-settle.

18

Promotion log

How a component earns its way into this page. New work stages on a proposed-components surface, gets triaged against the locked system, and only then promotes into the core — nothing lands here unreviewed.

The governance pattern. Screenshots from the in-progress app are treated as a request, not a spec. Every one runs the same four-step loop on the staging surface: read the screen (separate what the rep needs from decorative chrome), rebuild from the kit (card, row, chip, tile, button — new parts only as a last resort), flag edge cases (when the system has no rule, name the gap and propose the rule), and promote to core (once agreed, the rule lands in the registry, the stylesheets and this documentation). The gate for anything new: “is this really not a card / row / chip / tile?” — extend an existing component with a modifier before inventing one, and no raw hex or px: a new value becomes a proposed token, never an inline number.

The Reviews module is the worked example. The Reviews tab was triaged on the staging surface and promoted to core on June 11, 2026 with all ten edge cases resolved — the reserved --m-reviews accent activated as the card spine, the metric hero, the filter facets, the monochrome stars, the quote block, the review card composition, and the custom dropdown. The page-local copies were then deleted: this documentation consumes those primitives from core, so the docs can never drift from the shipped system.

Edge caseResolution — promoted to core, Jun 11, 2026
Hero workload metric
.km-metric-hero
One hero figure per view; prominence from scale, not colour. The number leads at title size with a .km-subtext label before it; a green meter fills with work done; the total recedes to a mono caption.
Star rating + star glyphs
.km-stars · star / star-fill
Literal stars, monochrome — filled (ink) = the score, hollow (border-grey) = the remainder. Keeps the “icons never carry their own colour” house rule; gold/amber was rejected.
Filter facet
.km-facet
The system’s first true filter pattern: a selectable chip borrowing the toggle’s selection language — active = ink fill, control height to line up with buttons and inputs, count doubling as a live tally.
Review card + quote block
.km-review · .km-quote
Assembled from card + shop description + stars + byline dotline + quote + platform tile. Mostly composition; .km-quote is the one genuinely new primitive, opening with the new quote glyph in muted ink.
Reviews module accent
--m-reviews
Already reserved in the token layer — the case simply activates it as the card left-spine. No new token needed; the foundation anticipated Reviews.
Platform tile as profile link
icon-only link
Was “Open profile”. Now icon-only — the Google glyph (identity) plus the external ↗ glyph (leaves the app), no words, deep-linking to this exact review on the shop’s Google listing.
Dropdown menu (custom)
.km-dropdown
Native select can’t style its list or stop the OS popup overlapping the field. Custom listbox opens below on the overlay recipe; hover = neutral, selection = brand — they never read alike.
Select / dropdown caret
.km-select
Existed but handed its arrow to the OS. Fixed in core: native appearance reset, the system caret-down-fill painted in ink-500; the Clear button moved from quiet to secondary.
Subtext type role
.km-subtext
The system had the size but no named secondary-text role, so captions were hand-styled each time. Added Small · regular · ink-500 as the one treatment for any quiet caption or metric label.
Header action button
.km-btn--ondark
“Request intake” was a fake button — a .km-tab with inline styles and a raw hex bolted on. Promoted to a real on-dark button variant with the --ondark-* token family; .km-tab hardened with nowrap.

Ten edge cases · ten written rules · zero unreviewed landings. The staging surface is empty again — that is the steady state.

19

Component manifest

Every class in the system, registered. This table is generated from the component registry — the same data the audit reconciles against the stylesheets and real usage, so no class can exist invisibly.

SelectorTitleLayerFile
.kmProduct baseelementcomponents/base.css
.km-subtextSubtextelementcomponents/base.css
.km-headerApp headercomponentcomponents/header.css
.km-tabTop tabcomponentcomponents/header.css
.km-sidenavSide navcomponentcomponents/sidenav.css
.km-btnButtonelementcomponents/button.css
.km-linkLinkelementcomponents/button.css
.km-cardCard / panelcomponentcomponents/card.css
.km-locLocation cardcomponentcomponents/card.css
.km-fieldDetail field rowobjectcomponents/card.css
.km-chipStatus chipelementcomponents/chip.css
.km-platPlatform tileelementcomponents/chip.css
.km-assigneeAssignee pillobjectcomponents/chip.css
.km-labelField labelelementcomponents/form.css
.km-inputText inputelementcomponents/form.css
.km-textareaTextareaelementcomponents/form.css
.km-selectSelectelementcomponents/form.css
.km-hintField hintelementcomponents/form.css
.km-segSegmented controlelementcomponents/form.css
.km-composerVoice composercomponentcomponents/form.css
.km-bubbleIntake bubblecomponentcomponents/conversation.css
.km-confirmConfirmation cardcomponentcomponents/conversation.css
.km-checkProcessing checklistcomponentcomponents/conversation.css
.km-feedActivity feedcomponentcomponents/conversation.css
.km-emptyEmpty statecomponentcomponents/feedback.css
.km-bannerBannercomponentcomponents/feedback.css
.km-tableDense tablecomponentcomponents/table.css
.km-metric-heroHero workload metricobjectcomponents/reviews.css
.km-facetFilter facetobjectcomponents/reviews.css
.km-starsStar ratingelementcomponents/reviews.css
.km-quoteQuote blockelementcomponents/reviews.css
.km-dotlineDot-separated meta lineobjectcomponents/reviews.css
.km-reviewReview cardcomponentcomponents/reviews.css
.km-dropdownDropdown menuoverlaycomponents/dropdown.css
.km-glassGlass materialoverlaycomponents/glass.css
.km-liftCard lifteffectcomponents/motion-effects.css
.km-tilt3D tilteffectcomponents/motion-effects.css
.km-glowCursor-follow gloweffectcomponents/motion-effects.css
.km-meterMetereffectcomponents/motion-effects.css
.km-skeletonSkeletoneffectcomponents/motion-effects.css
.km-paletteCommand paletteeffectcomponents/motion-effects.css
.km-drawerParallax drawereffectcomponents/motion-effects.css
.km-checkdrawStatus celebrationeffectcomponents/motion-effects.css
.km-ic-spinIcon micro-motionseffectcomponents/motion-effects.css
.km-empty--ambientAmbient empty stateeffectcomponents/motion-effects.css
.km-aiAI generation motioneffectcomponents/motion-effects.css
.km-overlayOverlayoverlaycomponents/dialog.css
.km-dialogDialogoverlaycomponents/dialog.css

Krown Design Manager · Components · Compositions assembled from the element kit. No live CMS/platform write behavior is implied by this document.