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.
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 CardThe 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 BadgeThe 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.
AlertInline callouts that stay in the flow of a page or panel: notices, warnings, degraded states. Not for confirmations (AlertDialog) or transient feedback.
Alert DialogA blocking confirmation before a destructive or irreversible action: deleting a post, disconnecting an account, approving a spend change. The user must explicitly cancel or confirm.
App IdentityThe 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.
Audio MeterA single-bar volume meter for a playing audio element: a Web Audio AnalyserNode merges both channels into one peak level.
Audio SliderSelecting a fixed-length window of an audio track: the same visual as VideoTrimmer, but the selection only slides left or right. No resize handles.
AvatarA person or account identity mark: profile pictures in account rows, message authors, member lists. Groups overlap with AvatarGroup and truncate with AvatarGroupCount.
BadgeShort status markers inline with other content: post state, platform tags, counts. One or two words, read at a glance.
Brand LogoThe Layers L-mark inside its dark squircle box: the app rail home link, the FullscreenModal header, any surface that signs itself as Layers.
ButtonAny click action: submits, confirmations, toolbar controls. Text-only or icon-only; the label says exactly what happens.
Button GroupRelated controls fused into one segmented row with flush inner corners: prev/next pairs, split buttons, a count beside its action.
CalendarPicking 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.
CanvasThe app canvas column: the bg-secondary work surface that fills the space beside the chat pane and hosts the stacking CanvasSheets.
Canvas SheetThe 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.
CardGrouped content that stands on its own: settings sections, digests, summaries. The default surface for a standalone block with an optional header and footer.
Catalog CardA 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.
ChatThe chat vocabulary: MessageScroller keeps the conversation pinned to the live edge, Message and Bubble render each row, and Marker divides the stream with separators like day markers.
CheckboxIndependent on/off choices in a form, or multi-select in a list. Each checkbox stands alone; for one-of-many use RadioGroup.
ComboboxA 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.
CommandA searchable action or navigation list (cmdk): command palettes and pickers that filter their items as you type. CommandDialog wraps the palette form.
Command InlineEmbedded command search inside Dialog content: the same cmdk anatomy in a bordered rounded-md shell that sits flush within a dialog.
ComposerThe "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.
Content CardThe 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 FooterThe two-cell footer under every generation card: account identity on the left, schedule on the right. ContentCard, ContentRenderer, and ContentPlaceholder all share it.
Content PlaceholderThe processing and failed states of a content container: an animated placeholder that holds the grid cell while a generation runs, then hands off to ContentCard when media lands.
Content RendererA 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 TableEvery tabular area list: accounts, live posts, invoices. One component owns the sticky header, sorting, skeleton loading, row click, selection, and infinite scroll.
Date Time PickerPicking 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 PillsThe decision bar above the composer when the agent needs an answer: exactly one filled recommendation, with any alternatives as subordinate outline buttons.
DialogA centered modal for focused content and small forms: renaming a post, editing settings, picking options. Blocking yes/no confirmations use AlertDialog instead.
Dropdown MenuA 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.
Editable Text Radio GroupChoosing one text option while keeping every option editable in place: hook pickers and other pick-one-then-tweak lists.
Elle AvatarElle wherever she speaks: chat message rows, session headers, SMS mockups. A static black and white Elle mark inside a circle.
Empty StateThe zero-items state of a list or grid: no posts scheduled yet, no accounts connected. Says what belongs here and gives one way to fill it.
FieldThe layout family for every form: consistent label, description, and error placement around any control. FieldSet and FieldGroup space whole sections; Field spaces one control.
FormReact-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 ModalA 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.
GridAn equal-column grid with a tokened gap: StatCard rows, paired charts, any run of same-shaped cards. Part of the Elle generative-UI catalog, so agents and developers compose the same primitive.
Hashtag TextareaWriting captions with hashtag autocomplete: typing # opens a suggestion list filtered from a keyword list, built on Textarea plus Popover and Command.
HeadingThe 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.
InputSingle-line text entry in forms: names, links, handles.
Input GroupAn input with something attached: a leading icon, a text prefix, an inline button. One bordered group instead of an input plus floating decorations.
Input OTPEntering a verification code sent by email or SMS: one slot per character, with paste and autofill support (the input-otp library).
LabelNames a form control. Every Input, Textarea, Select trigger, Checkbox, Switch, and RadioGroupItem gets one.
List RowThe 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 DetailThe 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.
MarkdownRenders a markdown string (react-markdown plus GitHub-flavored markdown) with the house typography: headings, lists, tables, inline code, and links.
Media CardThe 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 PlayerThe 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.
Navigation MenuHeader 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.
Phone InputCollecting a phone number with a country picker: flag button opens a searchable country list (Command in a Popover), the input formats as you type.
Platform IconInline brand marks for the platforms Layers touches: tiktok, instagram, meta (facebook is an alias), github, appstore, googleplay, youtube, linkedin. The badge inside AccountIdentity and AppIdentity, platform pickers, connect flows.
PopoverLightweight 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.
ProgressDeterminate progress toward a known end: an upload, a batch of posts going out. For work of unknown duration use Spinner.
Radio GroupPicking exactly one option from a short visible list: posting cadence, mode, audience. When the list gets long, use Select.
Rate ChartA compact area chart for percentage rates over time inside a Card size sm, with a gradient fill under the line.
Section LabelThe house mono uppercase marker for section headings inside panels, tables, and lists.
SelectChoosing one option from a fixed list: platforms, accounts, filters. For searchable or free-form lists reach for Combobox instead.
SeparatorA hairline divider between adjacent content regions when spacing alone does not read as a boundary.
SheetYou do not. Stock Sheet ships with the shadcn preset but has zero direct consumers in the product; this page exists to state that ruling.
ShimmerText 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.
SkeletonPlaceholder blocks while real content loads. Mirror the shape of what will render so the layout does not jump when data arrives.
SliderPicking a numeric value, or a range with two thumbs, along a continuum: intensity, budget split.
SpinnerWork in progress with no known end point: agents running, a save in flight, a view loading. For determinate work use Progress.
Stat CardA single KPI with an icon, a formatted value, and an optional period-over-period delta. Rows of these open area dashboards and post detail sheets.
Suggestion PillsEqual-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.
SwitchA standing binary setting: auto-post, notifications. Use Checkbox when the choice is one of several fields submitted together.
TabsSwitching between peer views inside one surface: Live Posts and Schedule, Preview and Details. For route-linked navigation use NavTabs.
TextareaMulti-line text entry: briefs, captions, notes. It grows with its content instead of showing a resize handle.
ToggleA single pressed or unpressed control: bookmark, show captions. The state lives in the control itself; for a set acting together use ToggleGroup.
Toggle GroupA set of related toggles acting as one control: alignment, view density. For a single standalone control use Toggle.
TooltipA short label on hover or focus that names a control or explains a value: what an icon-only button does, what a metric counts.
Trend ChartA 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 HandleThe floating-pill seam between two resizable columns, like the chat/canvas divider. The handle is the visual; the hooks own the drag.
Video TrimmeriOS-style clip trimming: a filmstrip of thumbnails with draggable start and end handles, plus a slidable selection region.
Window SheetThe 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.