Components

The @layers/ui vocabulary, rendered stock, with the house rules that bind each component. Coverage is exhaustive and build-enforced: if a component is not on this page, it is not installed.

Account Identity

The one way to attribute a connected social account: avatar, platform badge, and username in a single row. Account selectors, post footers, anywhere a post or metric names its account.

Add Card

The dashed add tile that leads a grid: plus glyph, optional label and hint. Click to add, or drop files straight onto it when it is wired as an upload target.

Agent Badge

The mono uppercase chip that attributes work to an agent or area: task rows, chat attributions, deliverable cards. The color is the area accent, so a glance says which agent acted.

Alert

Inline callouts that stay in the flow of a page or panel: notices, warnings, degraded states. Not for confirmations (AlertDialog) or transient feedback.

Alert Dialog

A blocking confirmation before a destructive or irreversible action: deleting a post, disconnecting an account, discarding an edit, approving a spend change. The user must explicitly cancel or confirm. If the surface asks a question and the answer commits something, it is this — not a Dialog wearing two buttons.

App Identity

The Ads counterpart to AccountIdentity: rounded app icon, store badge, and app name in a row. An ad target is an iOS or Android app, and every surface that names one renders it this way.

Attachment

File and image attachments in chat composers, message threads, and upload lists. The chat ruling requires Attachment instead of Item or a custom card.

Attention Bar

The app shell's takeover bar: the product has stopped and one action restores it (a walled workspace, ghost mode, a credit balance under the cheapest generation). Never for a notice that can be ignored; that is Alert, in the flow of a page.

Audio Meter

A single-bar volume meter for a playing audio element: a Web Audio AnalyserNode merges both channels into one peak level.

Avatar

A person or account identity mark: profile pictures in account rows, message authors, member lists. Groups overlap with AvatarGroup and truncate with AvatarGroupCount.

Badge

Short status markers inline with other content: post state, platform tags, counts. One or two words, read at a glance.

Border Beam

A light that travels the border of the one control a surface is trying to hand the user — the "this is the thing to press" signal for a primary CTA that would otherwise read as static content. Owned, not installed: colors come from the brand palette and reduced motion removes the beam.

Brand Logo

The Layers L-mark inside its dark squircle box: the app rail home link, the FullscreenModal header, any surface that signs itself as Layers.

Breadcrumb

A page title on a route-navigated app (MMA) when the screen is one level inside a list screen, such as one connection inside Connections. The parent is a link; the current page is the last item. In the product app, stacked canvas sheets are the breadcrumb, so this is not used there.

Button

Any click action: submits, confirmations, toolbar controls. Text-only or icon-only; the label says exactly what happens.

Button Group

Related controls fused into one segmented row with flush inner corners: prev/next pairs, split buttons, a count beside its action.

Calendar

Picking dates from a month grid (react-day-picker): a single day, multiple days, or a range. Usually rendered inside a Popover; for date plus time use DateTimePicker.

Canvas

The app canvas column: the bg-secondary work surface that fills the space beside the chat pane and hosts the stacking CanvasSheets.

Canvas Sheet

The stacking panel system inside the canvas column: every area page is a base sheet, and detail views stack on top of it. Overlays in the app are stacked CanvasSheets, not modals.

Card

Grouped content that stands on its own: settings sections, digests, summaries. The default surface for a standalone block with an optional header and footer.

Catalog Card

A MediaCard specialization for picker grids: a square thumbnail with a title and optional description in the footer. Used where the user chooses an item, like product catalogs.

Chart

The composable foundation every new Strata chart builds on: ChartContainer scopes a config that maps series keys to CSS variables, and the tooltip/legend pieces render themed. Recharts stays unwrapped; you compose its primitives directly.

Chat

The chat stream vocabulary: MessageScroller keeps the conversation pinned to the live edge, and Marker divides the stream with separators like day markers. Row content (message bubbles) is owned by the consuming surface.

Chat Pane

The universal Elle chat layout: one frame (header, optional banner, the scrollable stream on the shared readable measure, working status bar over the composer) across /chats, the area companions, onboarding, and Cora. Surfaces supply the stream entries, header, and footer; the engine behind them is the surface’s concern.

Checkbox

Independent on/off choices in a form, or multi-select in a list. Each checkbox stands alone; for one-of-many use RadioGroup.

Code block

Showing a copyable snippet — install steps, API examples, generated prompts. One block, one snippet.

Combobox

A searchable pick list (Base UI): filter as you type, then choose. Short fixed lists use Select instead; multi-select with removable chips uses the ComboboxChips family.

Command

A searchable action or navigation list (cmdk): command palettes and pickers that filter their items as you type. CommandDialog wraps the palette form.

Command Inline

Embedded command search inside Dialog content: the same cmdk anatomy in a bordered rounded-md shell that sits flush within a dialog.

Composer

The "message Elle" input: one auto-growing textarea that renders as a pill on a single line and expands to a rounded multi-line form the moment the text stops fitting. Enter sends; Shift+Enter adds a newline.

Connection Card

The compact tile for one connectable data source in a directory of them. Built to render by the hundred: mark, status, name, one muted line.

Connection Panel

The one surface for a single connection: what it gives you, what you currently have, and the one thing you can do about it. Opened from a ConnectionCard in the directory, connected or not.

Connection Request Card

A living, inline request to connect a signal provider. The same card remains in place as a connection moves from available through working, ready, failed, or skipped.

Content Card

The generated-post card: 9:16 media rendered through MediaPlayer with the two-cell ContentCardFooter (account and schedule) beneath, wrapped in the gradient hover glow.

Content Card Footer

The footer under every generation card: one pill per destination, each pairing an account with the time IT goes out. ContentCard, ContentRenderer, and ContentPlaceholder all share it.

Content Placeholder

The processing and failed states of a content container: a placeholder that holds the grid cell while a generation runs, then hands off to ContentCard when media lands.

Content Renderer

A near duplicate of ContentCard whose post fields accept null (media_urls, media_type, hook). Reach for it only when your data really is nullable; otherwise use ContentCard.

Data Table

Every tabular area list: accounts, live posts, invoices. One component owns the sticky header, sorting, skeleton loading, row click, selection, and infinite scroll.

Date Time Picker

Picking a date and a time together, like scheduling a post: a calendar popover, a time input, and an optional clear button in one row.

Decision Dock

The formal tier of the two-tier decision system: a quiet strip pinned above the composer that walks the user through everything the system is blocked on, one decision at a time. Consent moments (tool approvals, plan spend gates) and structured questions (setup wizards, data collection) alike. Never for the conversation’s own casual next beat (that is DecisionPills), and never for approving a document (artifact consent happens on the canvas).

Decision Pills

The decision bar above the composer when the agent needs an answer: exactly one filled recommendation, with any alternatives as subordinate outline buttons.

Decomposition Bar

One quantity split into named parts that sum to it — a residual pool broken into reasons, a spend total broken by channel. Reach for it when the reading is "these are all of the same whole", never for progress toward a target.

Destructive Action Card

One action that tears something down, isolated in its own card with the consequence spelled out and a confirmation behind it: disconnect an integration, remove a listing, delete a project. Sits last on a settings surface, below the facts it acts on.

Dialog

A centered modal for focused content and small forms: renaming a post, editing settings, picking options. Blocking yes/no confirmations use AlertDialog instead.

Dot Field Loader

The working state of a surface that is loading or generating content — the Brand bento asset folders and the content generation cards. A muted dot matrix with a soft band of lit dots sweeping top to bottom: a scanner moving over work in progress, not a glow blob.

Dropdown Menu

A list of actions behind one trigger: row actions on a table, the overflow menu on a card, account switching. Menus hold actions; picking a value for a form field is a Select or Combobox.

Elle Avatar

Elle wherever she speaks: chat message rows, session headers, SMS mockups. A static black and white Elle mark inside a circle.

Empty State

The zero-items state of a surface, list, or grid: no posts scheduled yet, no accounts connected. Says what belongs here and gives one way to fill it.

Field

The layout family for every form: consistent label, description, and error placement around any control. FieldSet and FieldGroup space whole sections; Field spaces one control.

Filter Menu

A toolbar filter over SEVERAL values at once: account types, statuses, platforms. One value only? Use Select. A control strip that changes a mode rather than narrowing a list? That is not a filter.

Form

React-hook-form bindings for validated forms: settings panes, dialogs, anything with rules and error messages. The Field family handles layout; Form wires state, ids, and aria attributes.

Fullscreen Dialog

The fullscreen builder-overlay chrome: real Dialog semantics (portal, backdrop, Esc, focus trap) on a fixed fullscreen frame with the ElleMark header, a round close button, and an optional fixed footer action bar. Used by the slideshow builders and reference pickers.

Fullscreen Media Preview

The 9:16 media lightbox inside fullscreen editors and detail sheets: the current slide on a letterboxed canvas with a thumbnail rail, arrow-key and click-to-advance navigation, and an optional per-slide delete.

Fullscreen Modal

A full-viewport takeover for creative builders and editors: work that needs the whole screen, not a panel. Portals to document.body with a sticky BrandLogo header, Escape handling, and body scroll lock.

Grid

An equal-column arrangement of same-shaped cards inside a sheet or card: paired charts, a side-by-side of two panels. Part of the Elle generative-UI catalog, so agents and developers compose the same primitive.

Hashtag Textarea

Writing captions with hashtag autocomplete: typing # opens a suggestion list filtered from a keyword list, built on Textarea plus Popover and Command.

Heading

The one heading primitive. as picks the outline level for the document structure; variant picks a bundled visual preset from the type scale. The two axes are independent.

InfiniteLoader

The next-page indicator for an infinitely-scrolling list or grid: generations, research, the creative library, the catalog and content pickers. Render it under the list, guarded on the query's own isFetchingNextPage. For a first load (no rows yet) use skeletons shaped like what is coming, not this; for a full-panel load center a size-8 Spinner in the region.

Input

Single-line text entry in forms: names, links, handles.

Input Group

An input with something attached: a leading icon, a text prefix, an inline button. One bordered group instead of an input plus floating decorations.

Input OTP

Entering a verification code sent by email or SMS: one slot per character, with paste and autofill support (the input-otp library).

Label

Names a form control. Every Input, Textarea, Select trigger, Checkbox, Switch, and RadioGroupItem gets one.

List Row

The conversation and list row: a title with an optional badge, a two-line subtitle, and small agent chips. The chats list is the reference consumer.

Live Post Card

A posted piece of content with its live performance: 9:16 media beside a primary stat, a secondary stat list, and a platform/username/date footer. The card for Live Posts grids (social, UGC) and Elle’s generated post lists.

Live Post Detail

The live-post performance detail: a scrolling stats column (metrics grid, views bars, engagement area, audience breakdowns) beside a sticky 9:16 media preview. Purely presentational; every consumer passes ready data.

Markdown

Renders a markdown string (react-markdown plus GitHub-flavored markdown) with the house typography: headings, lists, tables, inline code, and links.

Media Card

The shared clickable media surface: a card with an optional footer and the standardized gradient hover glow. Use it anywhere media renders as a card (library assets, catalogs, products) so hovering media feels the same everywhere.

Media Player

The hover-to-play media preview behind every content card: a single image, a multi-image slideshow, or a muted looping video, revealed with a fade once loaded.

Meter List

Labeled progress rows — icon, label, "x of y", track, and an optional muted meta line. The repeated per-group meter a dashboard workstream panel needs.

Nav Tabs

Route-linked sub-navigation across an area’s pages (Social → Live Posts / Schedule / Accounts). For in-place view switching inside one surface, use Tabs instead.

Navigation Menu

Header navigation with dropdown panels: the marketing site header is the reference consumer. Triggers read as plain text links; panels morph between items in a shared popover viewport.

Pace Chart

Goal progress against an on-track reference: the measured series, a dashed pace line from baseline to target, and the target itself. The plan dashboard is the reference consumer.

Platform Icon

Inline brand marks for the platforms Layers touches: tiktok, instagram, meta (facebook is an alias), github, slack, appstore, googleplay, youtube, linkedin, apple, stripe, revenuecat. The badge inside AccountIdentity and AppIdentity, platform pickers, connect flows.

PlatformTile

A third-party provider’s mark on its own brand-colored tile, for surfaces where connections are browsed and chosen — the connections directory above all. For an inline identity mark inside a row, badge, or account line, use PlatformIcon instead: a colored chip is noise there.

Popover

Lightweight content anchored to a trigger: a small form, a date picker, an inline explainer. Blocking decisions go to Dialog or AlertDialog; plain labels are Tooltips.

Power List

The answer to "why would I do this" on any surface that puts a capability behind a setup step: a connection, a phone number to verify, an SDK to install. One sentence per thing the capability buys.

Progress

Determinate progress toward a known end: an upload, a batch of posts going out. For work of unknown duration use Spinner.

Property List

A read-only set of label/value facts about ONE subject: what a connection is bound to, what an API key’s prefix is, what a post scored. Use it wherever you were about to hand-roll a two-column <dl>.

QR Code

Handing a payload from a desktop screen to the phone in the user’s hand: phone verification (the sms: link that opens Messages prefilled), device pairing, a link that only makes sense on mobile. Always pair it with a plain button that does the same thing, for the people already on that phone.

Radio Group

Picking exactly one option from a short visible list: posting cadence, mode, audience. When the list gets long, use Select.

Rate Chart

A compact area chart for percentage rates over time inside a Card size sm, with a gradient fill under the line.

Save Bar

The commit row for an inline edit on a page: a table of checkboxes, a settings block, a picker. It sits directly under the thing it commits, right-aligned, and renders only while there are unsaved changes.

ScopeAvatar

The mark for something the user OWNS and switches between — a project, an organization. Its real icon when we hold one, otherwise its first letter on a brand pastel. Use PlatformTile for a third-party provider (that is a vendor’s brand, not the customer’s thing) and AccountIdentity for a social account.

ScopeSwitcher

Picking WHICH thing a surface acts on — which project the rail is in, which organization a billing dialog is reading. It is a scope control, not a form field: for choosing a VALUE inside a form, use Select (one of many) or RadioGroup (one of a few).

Section Label

The house mono uppercase marker for section headings inside panels, tables, and lists.

Select

Choosing one option from a fixed list: platforms, accounts, filters. For searchable or free-form lists reach for Combobox instead.

Select List

Pick several, commit once: checkbox rows with a single Save. The generative-UI surface for keeping a subset of generated options (the hook picker); the DecisionDock doctrine applied to a selection instead of a wizard.

Separator

A hairline divider between adjacent content regions when spacing alone does not read as a boundary.

Shimmer

Text that represents live, streaming, or thinking work: a "Thinking" line in chat, a status label while an agent runs. The sweep says "in motion" without a spinner.

Signal Meter

A quantity already held, read as a gauge — how much of a project’s available signal Layers actually has. Never for work in flight.

SignalCard

A board of every outside source a project could be read from, present from the first second and dimmed until it is real. The onboarding canvas is the consumer: the board shows the shape of the whole relationship before the visitor has given anything.

SignalField

A backdrop for a surface that would otherwise be a flat empty plane and that has a run to report on. Dots scattered across the container are pulled home into the Layers mark as progress advances. The onboarding canvas is the consumer.

Skeleton

Placeholder blocks while real content loads. Mirror the shape of what will render so the layout does not jump when data arrives.

Slider

Picking a numeric value, or a range with two thumbs, along a continuum: intensity, budget split.

Spinner

Indeterminate loading with no known end point: a save in flight, a route resolving, a full-panel load. For the next page of an infinitely-scrolling list use InfiniteLoader, never a bare Spinner — it owns the centring and the padding. For determinate work use Progress. To signal an agent is live/working (not loading) use ThinkingOrb; for the streaming chat work-line use WorkingStatus.

Stat Card

The summary row that opens an area page, a dashboard, or a post detail sheet: a run of KPIs, each a label, a formatted value, and optionally what it was doing over a comparison window.

Sticky Section Header

The header for each section of a long scrolling list — a day of scheduled posts, a bucket of content. Title left, count right, sticky at the top of the scroll region so the reader always knows which section they are in.

Suggestion Pills

Equal-weight conversation starters above the composer: outlined pills that each send a ready-made message. No recommendation is being made; every option carries the same weight.

Switch

A standing binary setting: auto-post, notifications. Use Checkbox when the choice is one of several fields submitted together.

Tabs

Switching between peer views inside one surface: Live Posts and Schedule, Preview and Details. For route-linked navigation use NavTabs.

Tag input

Free-text entry that commits tokens into dismissible pills: geo country codes, ad keywords — any list a user types rather than picks. Not for choosing among known options (use Select or SuggestionPills).

Textarea

Multi-line text entry: briefs, captions, notes. It grows with its content instead of showing a resize handle.

ThinkingOrb

The glyph on a live agent line — Elle's working status, where a pulsing green dot used to sit. Each state is a distinct animation, so the orb says WHAT is happening (searching, composing, connecting) rather than merely that something is. It is a status indicator, not a loader: for indeterminate loading use Spinner, and for the next page of a list use InfiniteLoader.

Toggle

A single pressed or unpressed control: bookmark, show captions. The state lives in the control itself; for a set acting together use ToggleGroup.

Toggle Group

A set of related toggles acting as one control: alignment, view density. For a single standalone control use Toggle.

ToolbarFilterSelect

The standard toolbar filter: choosing one value from a fixed option list to narrow the surface below (status, platform, date range). It is Select pre-shaped for toolbars — flat trigger, 32px, every item in a SelectGroup — so toolbar call sites pass options instead of re-composing the anatomy.

Tooltip

A short label on hover or focus that names a control or explains a value: what an icon-only button does, what a metric counts.

Track List

A music picker with audio preview — trending tracks a user can hear before committing one to a reel. The catalog surface for the first-experiment music conversation; MediaCard only plays video.

Trend Chart

A compact bar chart for count metrics over time (views, likes) inside a Card size sm. The header shows the series total; hovering a bar swaps it for that point.

Vertical Resize Handle

The floating-pill seam between two resizable columns, like the chat/canvas divider. The handle is the visual; the hooks own the drag.

Window Sheet

The resizable inspector panel anchored to the right edge: post inspectors, editors, settings panels that live beside the page instead of over its center. Drag the left edge to resize.

Work Card

The in-feed record of one piece of work that was kicked off: what it is, how far it got at starting, and the way to check both. It resolves in place as evidence arrives and then stays, because the record is the point.

WorkingStatus

The streaming work-line shown over the chat composer while Elle is actively working: a small spinner, a shimmer label, and an elapsed-seconds counter. Not a loader (use Spinner) and not the live-agent glyph (use ThinkingOrb).