# Echo UI > A neo-skeuomorphic React component library you install into your own source tree with `npx echo-ui-cli`. Molded caps in recessed wells, emissive readouts, real press travel. Motion (GSAP) and sound (zero-dep WebAudio synth) are first-class token families alongside color and type. > IMPORTANT: The Base UI package is `@base-ui/react` (per-component imports, e.g. `@base-ui/react/dialog`), NOT `@base-ui-components/react` (the old name). Training data may be stale. ## Accessibility Accessibility is part of the grammar, not a review step. Echo guarantees WCAG 2.2 AA, and these are the parts a consumer can still get wrong: - Every control needs a name. `Switch`, `Checkbox`, `Slider`, `Segmented`, `Select`, `RadioGroup` and `Progress` take `aria-label` (or `aria-labelledby` pointing at visible text); `Field`, `Textarea` and `OtpField` take a visible `label`. Without one they do not compile. - An icon-only `HardwareButton` (`iconOnly`) needs `aria-label`: it has no text to read. - Forms: put the help text in `description` and the problem in `error`, both on the field. They are linked to the input and set `aria-invalid` for you. Never signal an error with colour or a red border alone. - Announcements: mount `` once and call `toast()` from `useToast()`. A message rendered into the page when it happens is usually never announced. - Sign-in: `Field` with `autoComplete` (`email`, `current-password`), and `OtpField` for a one-time code — it allows pasting, which people rely on. - State is never colour alone: Echo has one accent, and its components already carry state in shape and words. Do not add a red for danger; use `AlertDialog`, which asks before anything destructive. - Do not remove a focus ring, shrink a target below 24×24px, or set `aria-hidden` on something focusable. ## Components - [Modal](https://echo-ui.com/e/modal.json): Base UI Dialog (focus trap, Esc, scroll-lock, a11y) skinned as an Echo device panel. motion.summon enter, GSAP exit that completes before unmount, sound.transition on open. - [Menu](https://echo-ui.com/e/menu.json): Base UI Menu (typeahead, roving focus, submenu timing, checkbox/radio items) skinned as an Echo floating panel — the Select's molded cap trigger and the same lit dot for what is on. sound.transition on open, sound.select on item commit. Exports ContextMenu for the right-click case. - [Sheet](https://echo-ui.com/e/sheet.json): A molded chassis panel that slides in from an edge — the console side panel and the mobile nav. Built on Base UI's Drawer, so it carries swipe-to-dismiss and a backdrop that tracks the swipe. sound.transition on open. - [AlertDialog](https://echo-ui.com/e/alert-dialog.json): A destructive confirm. Modal covers the structure; this is the semantics — role=alertdialog, a required description, and no dismissal by clicking away. sound.caution on open, sound.error on a destructive confirm. Severity is the deep end of the accent ramp, never an imported red. - [SizeProvider](https://echo-ui.com/e/size.json): One size scale for everything with a height: sm, md and lg are the control heights, so a button, a field and a select of the same size line up in a row. - [Scope](https://echo-ui.com/e/scope.json): A part of the page with its own accent or softer molding, derived by the theme engine. - [HardwareButton](https://echo-ui.com/e/hardware-button.json): The molded tactile button: a cap in a recessed well with real press travel + sound. primary/neutral/ghost, sm/md/lg, icon slots, icon-only, loading, engraved. Built on semantic vars + useTactile. - [Popover](https://echo-ui.com/e/popover.json): Base UI Popover (anchoring, focus, dismiss, a11y) skinned as an Echo panel. useGsapPresence summon-in / GSAP exit before unmount; sound.select on open. - [Tooltip](https://echo-ui.com/e/tooltip.json): Base UI Tooltip (hover/focus, delay, a11y) skinned as a compact molded chip. Same useGsapPresence bridge as Modal/Popover. - [Select](https://echo-ui.com/e/select.json): Base UI Select (typeahead, keyboard, a11y) skinned as an Echo dropdown — a molded cap trigger and a floating panel with a lit dot on the selected option. CSS fade/scale; sound.select on change. - [Command](https://echo-ui.com/e/command.json): The command palette as a dot-matrix readout — the query line is the LcdChip's recessed screen well with an emissive caret and a scanline wash. Base UI Autocomplete for the input and listbox semantics, Base UI Dialog for the frame. Cmd/Ctrl+K by default; matches hidden keywords as well as labels. - [Tabs](https://echo-ui.com/e/tabs.json): Base UI Tabs (roving focus, arrow-key nav, a11y) marked with the library's one "you are here": a 2px lit rail slides under the open tab, over a hairline baseline. Labels stay on the chassis. sound.select on change. Compound API. - [Accordion](https://echo-ui.com/e/accordion.json): Base UI Accordion (keyboard, a11y, height measurement) skinned as molded device panels that expand. Click sound on toggle; height animates via CSS. Compound API. - [Switch](https://echo-ui.com/e/switch.json): Base UI Switch (role=switch, keyboard, a11y) with a hardware-toggle skin — a molded thumb sliding in a recessed track — and a click sound on toggle. - [Checkbox](https://echo-ui.com/e/checkbox.json): Base UI Checkbox (keyboard, indeterminate, a11y) with a molded box skin that fills accent and shows a check when set. Select sound on change. - [Slider](https://echo-ui.com/e/slider.json): Base UI Slider (keyboard, drag, track-press, a11y) with a recessed rail + molded knob and a scrubbing tick sound on each step. - [Segmented](https://echo-ui.com/e/segmented.json): A hardware segmented selector — molded uppercase segments in a recessed well, the active one on the lit primary cap. A radiogroup value selector (roving focus, arrow-key select, select sound), distinct from Tabs which switches content panels. - [Field](https://echo-ui.com/e/field.json): A text input sunk into a recessed well. The inner edge lights in the accent on focus; a mono eyebrow label and an optional machine (mono) value voice. - [DateField](https://echo-ui.com/e/date-field.json): A date typed into wheels, day, month and year in the order the locale writes them, each a row of small flaps that turn over to the value. Field's recessed well, on the same size scale; the value is an ISO date. - [Calendar](https://echo-ui.com/e/calendar.json): A month on a device screen: the days are its lit segments, the chosen day lit with the one lit accent and today on a lit rail. A grid with one Tab stop and the calendar keys; the value is an ISO date. - [DatePicker](https://echo-ui.com/e/date-picker.json): A DateField with a calendar key in its well: type the date, or choose it on a Calendar that opens under the field. The value is an ISO date. - [FileUpload](https://echo-ui.com/e/file-upload.json): A recessed tray you press to choose files or drop them on; its inner edge lights while files are over it. Each file becomes a row with a Progress strip while your handler uploads it, and a key to cancel, retry or remove it. - [Textarea](https://echo-ui.com/e/textarea.json): Field's recessed well, multi-line and autosizing. The height is measured from the browser's own layout rather than counted from newlines, so it stays right when lines wrap and when the container resizes. - [Badge](https://echo-ui.com/e/badge.json): A small molded/LCD status label: neutral, accent, lcd, outline. Static; composes var(--echo-*). - [Kbd](https://echo-ui.com/e/kbd.json): A molded keycap for keyboard hints. Uses the element; composes var(--echo-*). - [Divider](https://echo-ui.com/e/divider.json): A panel seam — a hairline with a faint light lip. Horizontal or vertical; role=separator. - [StatTile](https://echo-ui.com/e/stat-tile.json): A recessed LCD readout: a glowing value over a machine label in a dark well. Static; composes var(--echo-*). - [Chart](https://echo-ui.com/e/chart.json): StatTile's dot-matrix language applied to a series: a column per sample, cells lit from the bottom, in the recessed screen well LcdChip and Progress use. Quantises to whole cells by construction — a readout, not a charting library. - [AppShell](https://echo-ui.com/e/app-shell.json): The app frame: a molded chassis rail, a sticky sidebar, and the content between them. Slots, not props. Ships the skip link by construction and derives the sidebar's sticky offset from the rail's height. - [Panel](https://echo-ui.com/e/panel.json): The two halves of the device material law as a container: raised molded plastic (things you touch) or a recessed dark screen (things you read). - [Progress](https://echo-ui.com/e/progress.json): A discrete LED cell meter in a recessed strip — filled cells are lit accent LEDs with a bloom. Steppy by construction; role=progressbar. - [Loader](https://echo-ui.com/e/loader.json): Three accent LEDs breathing in sequence — the device thinking. role=status; reduced motion holds the dots steady. - [StatusDot](https://echo-ui.com/e/status-dot.json): A tiny LED — lit accent with a bloom, or dead plastic gray. Decorative (aria-hidden) unless given a label. - [Toast](https://echo-ui.com/e/toast.json): A raised glass notification slab with a status LED — lit accent when active. Presentational (role=status); queueing stays in the consumer. - [StatusIsland](https://echo-ui.com/e/status-island.json): Background work in a floating pill that blooms open for detail. - [Receipt](https://echo-ui.com/e/receipt.json): A summary that feeds out of a slot a line at a time, on paper you tear off. - [Ticket](https://echo-ui.com/e/ticket.json): A paper pass whose stub tears off along its perforation. - [NowPlaying](https://echo-ui.com/e/now-playing.json): A small player: a screen, a strip to scrub, the transport keys. - [LcdChip](https://echo-ui.com/e/lcd-chip.json): An inline recessed LCD readout — a glowing accent value beside a machine label, sunk into a dark well. The chip form of StatTile. - [SegmentDisplay](https://echo-ui.com/e/segment-display.json): A seven-segment readout whose dark segments stay faintly visible, with dim padding zeros. - [DateTile](https://echo-ui.com/e/date-tile.json): A desk calendar's page: weekday and month engraved, the day lit on a screen. - [Annunciator](https://echo-ui.com/e/annunciator.json): Fixed marks on a screen's glass that light when what they name is happening. - [LedKey](https://echo-ui.com/e/led-key.json): A molded pill key with an indicator LED that breathes while lit. The latching sibling of HardwareButton — for a key whose own state is part of the answer. - [EngravedPlate](https://echo-ui.com/e/engraved-plate.json): A paper-coloured metal plate with text cut into it and rivets at the edges — the one non-emissive readout. For a fact fixed to the device, where LcdChip is for a live value. - [Textures](https://echo-ui.com/e/textures.json): The grain law as composable overlays: Dither, Noise, Halftone, Scanlines, plus GrainField and Textured. Inline SVG tiles, no asset files; decorative and pointer-events-free. - [ShaderField](https://echo-ui.com/e/shader-field.json): The live brand field — a WebGL domain-warped fbm gradient sampled from the accent ramp, blooming toward the cursor. Reduced motion draws one static frame; no WebGL falls back to a CSS gradient. - [RadioGroup](https://echo-ui.com/e/radio-group.json): One choice from a small set, as molded selector caps with a pip that lights accent when chosen. Base UI owns roving focus and arrow-key selection. - [OTP field](https://echo-ui.com/e/otp-field.json): The one-time code a sign-in asks for, as a row of lit digit windows. Built on Base UI's OTP Field: paste fills the row, arrow keys and Backspace walk it, and autocomplete="one-time-code" lets a phone offer the code. - [NumberField](https://echo-ui.com/e/number-field.json): A machined readout between two molded step caps, with the label doubling as a drag-to-scrub handle. Base UI owns typing, arrow keys, step sizes, and clamping. - [Avatar](https://echo-ui.com/e/avatar.json): A person or device as a molded disc — image in a well, or initials engraved into the plastic when there is no image or it fails to load. - [Tag](https://echo-ui.com/e/tag.json): A label the user applied, optionally removable. Badge reports what the system knows; Tag is a small plate that can be peeled off. - [CountBadge](https://echo-ui.com/e/count-badge.json): A number worth noticing — the lit sibling of Badge. Disappears at zero, caps its face at max while still announcing the true count. - [Skeleton](https://echo-ui.com/e/skeleton.json): The shape of content that has not arrived: a recess with a slow sheen. aria-hidden by default; one label announces the wait for the whole region. - [Banner](https://echo-ui.com/e/banner.json): A persistent inline message strip for a condition that is still true. Severity by luminance and a tone pip, not by hues the seed does not own. - [EmptyState](https://echo-ui.com/e/empty-state.json): Nothing here, and what to do about it — a quiet recess with the way forward built into the API. - [Creature](https://echo-ui.com/e/creature.json): A companion that reports what's happening: Echo, or your own, as a vector or in dots. - [Perch](https://echo-ui.com/e/perch.json): A creature on a card's top edge, sitting or peeking. - [Table](https://echo-ui.com/e/table.json): Rows of data in a recessed screen well. Real table semantics, a required caption, tabular figures for numbers, and a scroll region that keyboard users can reach. Given columns and rows, it sorts, selects, filters and windows them. - [DescriptionList](https://echo-ui.com/e/description-list.json): Things and their values, on the page or on a screen. - [ShortcutMap](https://echo-ui.com/e/shortcut-map.json): A keyboard of Kbd caps over the list of shortcuts, lighting each one's keys. - [WidgetGrid](https://echo-ui.com/e/widget-grid.json): Widgets at fixed footprints that people arrange, by drag or by key. - [Breadcrumb](https://echo-ui.com/e/breadcrumb.json): Where you are in the hierarchy, as an engraved trail. Labelled nav around an ordered list; the current page is text with aria-current, not a link. - [Pagination](https://echo-ui.com/e/pagination.json): Molded number caps with the current page lit. The window never elides a single page and never changes width as you page through. - [Steps](https://echo-ui.com/e/steps.json): How far through a sequence you are, as LED stations on a wire. aria-current on the current station; the done state reaches screen readers as words, not colour. - [Card](https://echo-ui.com/e/card.json): A Panel with an anatomy: media, header, body and footer, spaced by size; the whole card can be one link or button. - [Item](https://echo-ui.com/e/item.json): The row every list is made of: media, title, description, trailing content, and actions behind it that a swipe or Tab reveals. - [Stack & Grid](https://echo-ui.com/e/layout.json): The two layouts a screen is made of, with gaps on the space scale. - [Collapsible](https://echo-ui.com/e/collapsible.json): One disclosure on its own: a ruled row with a chevron that opens a panel. - [ScrollArea](https://echo-ui.com/e/scroll-area.json): A region that scrolls inside itself, with a groove and a molded thumb, and shade where the content continues. - [Link](https://echo-ui.com/e/link.json): Inline text that goes somewhere: readable words with the accent as the underline. - [Toggle](https://echo-ui.com/e/toggle.json): The quiet key of a toolbar: on is the cap held down in its well. ToggleGroup puts several in one well. - [Toolbar](https://echo-ui.com/e/toolbar.json): Several caps sharing one long well: ButtonGroup, and Toolbar with one tab stop and arrow keys. - [RangeSlider](https://echo-ui.com/e/range-slider.json): Two knobs on one rail for a span, with Slider's weight. - [Knob](https://echo-ui.com/e/knob.json): A molded rotary cap with detents, a lit scale and every slider key. - [Tuner](https://echo-ui.com/e/tuner.json): A number tuned like a radio: a scale slides under a lit needle and a segment reading follows. - [Keypad](https://echo-ui.com/e/keypad.json): A payment terminal's keys: an amount, a PIN or a code entered on HardwareButton caps. - [FilterTray](https://echo-ui.com/e/filter-tray.json): Filter pads in one well that fold into the action when applied. - [WeekStrip](https://echo-ui.com/e/week-strip.json): A week of days to tap through, today on a lit rail, busy days with a pip. - [SwitchBank](https://echo-ui.com/e/switch-bank.json): A table of Switches for settings that come in a grid, a Checkbox per column. - [JogWheel](https://echo-ui.com/e/jog-wheel.json): A knob with no ends: slow for a step, spin for a long way. - [QuickTile](https://echo-ui.com/e/quick-tile.json): A quick-settings tile: a big key that lights when the thing is on. - [FillSlider](https://echo-ui.com/e/fill-slider.json): A tall tube that fills with lit plastic as you push it up. - [PatchBay](https://echo-ui.com/e/patch-bay.json): Sockets on two sides and cables between: a Select per source is the control. - [Meter](https://echo-ui.com/e/meter.json): A measurement in a known range: a tube of lit plastic that settles to its level. - [LevelMeter](https://echo-ui.com/e/level-meter.json): A live level as LED cells with real ballistics and a held peak. - [Combobox](https://echo-ui.com/e/combobox.json): A Select you can type into; multiple keeps choices as tags; creatable adds what you typed. - [TagsInput](https://echo-ui.com/e/tags-input.json): Free-form tags typed into Field's well: Enter or a comma adds, Backspace removes. - [Fieldset](https://echo-ui.com/e/fieldset.json): A named group of fields with a legend. - [CheckboxGroup](https://echo-ui.com/e/checkbox-group.json): A named set of checkboxes sharing one value, with an optional parent. - [Form](https://echo-ui.com/e/form.json): A form that fails well: a summary of what to fix, each a link to its field. - [HoldButton](https://echo-ui.com/e/hold-button.json): Confirm by holding: the cap fills while pressed and drains if let go. - [ChoiceCards](https://echo-ui.com/e/choice-cards.json): Options that need more than a word, as cards; the chosen one lights its edge. - [SideNav](https://echo-ui.com/e/side-nav.json): The navigation down the side of an app, with one lit rail that travels to where you are. - [TabBar](https://echo-ui.com/e/tab-bar.json): A phone app's bottom navigation: a floating molded dock whose cap travels to the place you're on. - [NotificationCenter](https://echo-ui.com/e/notification-center.json): A bell with the unread count, opening an inbox of notifications. - [PullToRefresh](https://echo-ui.com/e/pull-to-refresh.json): A list you pull down to reload: a rubber band, a key that clicks at the detent, and a real Refresh button beside the gesture. - [Console screen](https://echo-ui.com/e/console.json): A device dashboard as a front panel: AppShell, six StatTile readouts, an LED level matrix, a takes Table and Pagination. Proves density and data at scale. - [Chat screen](https://echo-ui.com/e/chat.json): One conversation as a front panel: Avatar + StatusDot header, a message log, a Loader typing indicator, and a Textarea composer with one lit Send cap. Proves the material language survives running text. - [Morph](https://echo-ui.com/e/morph.json): Wrap your own HardwareButtons and render any state: when the buttons change, the old ones flow into the new. The base for DoneButton, ConfirmButton and ActionFan. - [DoneButton](https://echo-ui.com/e/done-button.json): "Mark as done" divides into a lit "Done" and an "Undo". - [ConfirmButton](https://echo-ui.com/e/confirm-button.json): A destructive action that asks for its second press where the hand already is. - [ActionFan](https://echo-ui.com/e/action-fan.json): One action opens into its choices; the × folds them back. - [SaveButton](https://echo-ui.com/e/save-button.json): The button becomes its own progress, then its own answer: Save narrows into a busy cap while your save runs, widens into a lit Saved, and flows back. - [Timer](https://echo-ui.com/e/timer.json): A timer that is one button. - [Stopwatch](https://echo-ui.com/e/stopwatch.json): Start becomes the running time (lit) and a Lap button beside it; each lap is a drop that leaves Lap and lands in the lap count. - [VoiceNote](https://echo-ui.com/e/voice-note.json): Record a voice note in one button. - [AddToBag](https://echo-ui.com/e/add-to-bag.json): Press it and a drop buds out of the button and lands in the count beside it, which swells and goes up — the eye follows the thing you added to where it went. - [useBudOff](https://echo-ui.com/e/bud-off.json): A drop of the primary plastic buds out of one element, flies to another and is swallowed by it, which swells as it lands — so the eye follows cause to effect. - [PullCord](https://echo-ui.com/e/pull-cord.json): A switch you pull. - [useRoll](https://echo-ui.com/e/roll.json): A readout that rolls to a new value instead of swapping it: each digit steps through the ones in between, all together, fast when it's far and slowest on the last step. - [SplitFlap](https://echo-ui.com/e/split-flap.json): A readout that turns over like a departures board: each character flips through the ones between where it is and where it's going, flap by flap — fast when it's far, slowest on the last one — and each flap ticks. - [LightSource](https://echo-ui.com/e/light-source.json): Your pointer becomes the light the caps inside it are lit by: each HardwareButton's shine turns toward it and its shadow falls away from it, the nearest most. - [Magnetic](https://echo-ui.com/e/magnetic.json): The HardwareButtons inside it feel your hand before you touch them: each leans toward the pointer and comes up a little, the nearest most, and springs home when you move away. - [ThrowStack](https://echo-ui.com/e/throw-stack.json): A stack of cards you can throw: drag the top one and flick it, and it keeps the speed you gave it, spins from where you held it (grabbed low, it swings the other way), flies off and tucks back in underneath. - [Ripple](https://echo-ui.com/e/ripple.json): A surface of dots that answers a press like water: a wave runs out from where you pressed, and pressing longer presses deeper and sends a bigger one. - [Theme Engine](https://echo-ui.com/e/theme.json): createEchoTheme(seed) — OKLCH derivation turning a ~6-value seed into the full semantic-role set, with dual { css, values } output and WCAG-AA contrast guardrails. The token foundation every Echo component depends on. - [Sound Engine](https://echo-ui.com/e/sound.json): SoundProvider + zero-dep WebAudio SynthBackend. Sound tokens are serializable synth recipes; lazy AudioContext, persisted mute, per-play jitter, blur guard, and reduced-motion coupling. - [Motion Tokens](https://echo-ui.com/e/motion.json): GSAP motion tokens (duration + ease as serializable data), each with an optional reduced-motion collapse variant. Glass moves smooth; pixels move steppy. - [useTactile](https://echo-ui.com/e/use-tactile.json): The fusion primitive: binds motion (GSAP) + sound per interaction phase, with pointer/keyboard parity and prefers-reduced-motion collapse. Accepts token names or raw GSAP vars / sound recipes as an escape hatch. The same entry holds the physics the components are built on: springs, cap presses, the typing well, the liquid cap, and the morph engine (MorphSurface, morphFeels) that divides one cap into several. - [useGsapPresence](https://echo-ui.com/e/use-gsap-presence.json): The GSAP-exit bridge (implemented once, reused by every Base UI wrapper): controls open state + actionsRef so the exit animation completes before Base UI unmounts. Runs the enter on mount. ## Tokens - Color roles: --echo-surface, --echo-cap, --echo-cap-highlight, --echo-cap-shadow, --echo-well, --echo-accent, --echo-accent-highlight, --echo-accent-pressed, --echo-accent-glow, --echo-accent-ink, --echo-primary-cap-top, --echo-primary-cap-mid, --echo-primary-cap-base, --echo-primary-cap-ink, --echo-pour-top, --echo-pour-mid, --echo-pour-base, --echo-accent-fill-top, --echo-accent-fill-base, --echo-lcd, --echo-lcd-glow, --echo-text, --echo-text-dim, --echo-seam - Sound: tap, press, release, select, transition, notify, caution, error, celebrate - Motion: press, pop, summon, breath, settle, glitch, flood, drain, lift, follow, travel, squash, rebound, light, boot, bloom, island - Springs (`springs.`, for createSpring): track, smooth, snappy, bouncy - Morph feels (`morphFeels.`): cell, mercury, cut - CSS durations: --echo-duration-glitch, --echo-duration-press, --echo-duration-tick, --echo-duration-swap, --echo-duration-glide, --echo-duration-sweep, --echo-duration-pop, --echo-duration-flood - CSS eases: --echo-ease-glitch, --echo-ease-press, --echo-ease-tick, --echo-ease-swap, --echo-ease-glide, --echo-ease-sweep, --echo-ease-pop, --echo-ease-flood - Shadows (for a part of your own; never write a box-shadow by hand): --echo-shadow-well (Set into the body: a field, a tray, the bed a cap sits in); --echo-shadow-well-screen (The glass of a screen or a readout); --echo-shadow-well-deep (A deep bezel: a large screen, a keypad's window); --echo-shadow-groove (A track cut into the body, for progress and levels); --echo-shadow-edge (Light catching the top edge of a small raised part); --echo-shadow-hairline (The lit lip under a divider); --echo-shadow-chip (A small raised part: a badge, a count); --echo-shadow-key (A low key standing on its seam); --echo-shadow-cap (A molded cap at rest); --echo-shadow-cap-lit (The lit cap, the one place the hardware turns accent); --echo-shadow-panel (A panel resting on the body); --echo-shadow-lifted (A panel lifted off the body, the way a card rises under the pointer); --echo-shadow-chassis (The device's own body); --echo-shadow-tooltip (A tooltip, the lowest thing that floats); --echo-shadow-popover (A popover or a small popup); --echo-shadow-toast (An announcement floating over the page); --echo-shadow-modal (A dialog, the highest thing that floats); --echo-shadow-ring (Keyboard focus around a raised part: a gap in the body's colour, then the accent's ink (the glow, on a dark device)); --echo-shadow-ring-inset (Keyboard focus inside a well, where a ring outside would sit on the rim); --echo-shadow-glow (The glow of something lit: the current tab, the page you're on) ## Setup Set the project up once with `npx echo-ui-cli init`. It installs `echo-ui-core` (and `echo-ui-cli` as a dev dependency), writes `echo.json`, `echo-lock.json` and `echo-theme.css`, adds a marked Echo block to CLAUDE.md or AGENTS.md, a check hook to .claude/settings.json and three skills (building with Echo; Design Eye, which reads a moodboard into a style the project can wear; and Style Fit, which picks the style it wears), and prints the lines to paste. It never edits your source code, and `add` refuses to run before it. ```sh npx echo-ui-cli init ``` Components render with no colour until the theme is on the page. `init` writes `echo-theme.css` into the Echo folder — import it once from your global CSS or your root layout (or call `createEchoTheme().css` from `echo-ui-core/theme` to build it at runtime). Give the page the device's ground (`body { background: var(--echo-well); color: var(--echo-text); font-family: var(--echo-font-sans); }`), dark or light as the chassis makes it, and wrap the app in `SoundProvider` from `echo-ui-core/sound` — without it every component is silent. It starts muted until the person turns sound on, and remembers their choice; `defaultMuted={false}` starts with sound. Put `` from `echo-ui-core/check` once in the root layout: in development it says in the console what's still missing, and in production it renders nothing. Echo components are client components. In the Next.js App Router, a file that passes them a function (`onSave`, `onSubmit`, `onClick`) must start with `"use client"`. ## Install ```sh npx echo-ui-cli add ``` Echo is a REGISTRY, not an npm component package. Components are installed with `npx echo-ui-cli add ` and then live in the consumer's own source tree, importing each other by relative path inside one Echo folder. Never suggest `npm install` for a component. The one npm package is `echo-ui-core`, the grammar they all import (theme, sound, motion, tactile, presence). Cross-component dependencies resolve automatically. Consume only Layer-3 semantic vars (`var(--echo-*)`) in your own CSS; theme by passing a seed to `createEchoTheme`. ## Conformance Every component is tested against WCAG 2.2 AA: axe, keyboard, focus-visible, forced-colors, target-size, reflow — and each item's `/e/` record carries the same block. Not covered: screen-reader: not yet verified by a person.