# Liveblocks Design System

## What this is

A design system reconstructed from a single detailed specification document (`uploads/Design System-Liveblocks.md`) rather than from live Figma or codebase access. That source document is itself a reverse-engineered, template-structured audit of Liveblocks' real marketing site and embeddable collaboration component library — it uses **"Continuum"** as an internal placeholder product name and invented people/companies for illustrative copy, and tags every value with a confidence marker (**[M]** measured, **[D]** derived for parity, **[A]** assumed/authored). This design system un-anonymizes that document back to **Liveblocks** for naming and copy, while keeping every measured token (color, spacing, radius, shadow, motion, type) exactly as specified — those are the real signature of the system, not the placeholder name.

**Source:** `uploads/Design System-Liveblocks.md` (34k words, versioned "Rev 7" against an internal `docs/TEMPLATE.md`). No Figma link, codebase, or logo file was attached — this system was built from that document alone. If a Figma file, repo, or logo becomes available, re-run against it and reconcile.

## The two surfaces

Liveblocks reads as **two accent families on one shared architecture**, and they're never meant to merge:

- **Marketing/docs** — the persuasive site selling the product. True-black canvas, violet accent, Inter type, generous `rem`-based spacing, one hero entrance animation, a signature self-timing use-case carousel and dot-matrix world map.
- **Product** (the embeddable Comments/Multiplayer/Notifications/Presence/AI Copilots component library that customers drop into their own apps) — dense, **light by default with a supported dark mode**, `#1177ff` accent, inherits the host application's typography (sets no font-family of its own), `em`-relative spacing that shrinks with host font-size, almost no decorative motion. White text is preserved on filled accent and destructive controls.

There is no separate "app" tier: the component library **is** the product. It has no sidebar, top bar, or page chrome of its own — it mounts inside a customer's existing UI.

## The signature idea

Every tint in both accent families is **computed at runtime via `color-mix()`**, not hand-picked. Six root inputs (background, foreground, accent, accent-foreground, destructive, destructive-foreground) plus a per-family contrast dial generate the entire palette. There is no authored 50→900 ramp anywhere — see `tokens/colors.css`. Customization runs through the **official `--lb-*` namespace** (color, spacing, radius, contrast, motion, elevation — e.g. `--lb-accent`, `--lb-radius`, `--lb-spacing`) — that is now the canonical name for every token in the public surface; the old unprefixed names (`--accent`, `--radius`, …) remain as aliases so existing component source keeps resolving, but `--lb-*` is what integrators should read and set.

## Index

- `styles.css` — the single global-CSS entry point (import-only, per the compiler contract). Imports everything in `tokens/`.
- `tokens/` — `colors.css`, `typography.css`, `spacing.css`, `radius-shadow.css`, `motion.css`, `z-index.css`, `fonts.css` (Inter for marketing/docs — an open-license substitute for the official site's Suisse Int'l, which requires a separate commercial license this project doesn't hold; JetBrains Mono for code, self-hosted from uploaded files; the product UI loads no typeface of its own).
- `guidelines/` — foundation specimen cards (Colors, Type, Spacing, Motion, Brand groups) shown in the Design System tab.
- `components/` — reusable React primitives, grouped by concern:
  - `components/core/` — Button, IconButton, Link, Badge, Tag, Chip, Card
  - `components/avatar/` — Avatar, AvatarStack
  - `components/forms/` — Input, Textarea, Select, Checkbox, Radio, Switch
  - `components/feedback/` — Modal, Toast, ToastStack, Tooltip, Skeleton
  - `components/navigation/` — Tabs, Accordion, Dropdown, Sidebar (+ SidebarProvider, SidebarInset — persistent page-level "on this page" nav)
  - `components/code/` — CodeBlock
  - `components/product/` — ProductIcon, StatusIndicator, CommentThread (convenience wrapper over `comments/Thread`)
  - `components/comments/` — Comment, CommentPin, Thread, FloatingThread, Composer, FloatingComposer; `primitives/` — Timestamp, Reactions, Attachments, Mention, EmojiPicker; `commentUtils.js` — formatting/composer-state helpers
  - `components/notifications/` — InboxNotification, InboxNotificationList
  - `components/presence/` — Cursor, Cursors (`presenceUtils.js` computes bubble text color from the runtime cursor color)
  - `components/ai/` — AiChat, AiTool, ToolConfirmation, ToolInspector, AgentActivityItem
  - `components/history/` — HistoryVersionSummary, HistoryVersionSummaryList
  - `components/utils/` — Icon, FeatureIcon, LiveblocksUiConfig (+ `useLiveblocksUiConfig`, `LiveblocksPortal`)
  - `components/marketing/` — MarketingNav, MegaMenu, AnnouncementPill, HeroShell, LogoWall, StatBlock, FeatureGrid, BentoMosaic, AlternatingFeatureSection, Testimonial, CTABand, MarketingFooter, Wordmark, PricingPlans, PricingFAQ, DotMatrixMap, RealtimeNodeDiagram, RealtimeInfrastructureVisual, HeroStage, UseCaseCarousel, SpotlightButtonrdmark (text stand-in — no logo asset provided); signature visuals — **HeroStage** (scalable 1208×770 hero canvas, one `--hero-scale` knob), **UseCaseCarousel** (self-timing Document/Workflow/Sheet/Dashboard tablist whose active pill fill is its own progress timer), **RealtimeNodeDiagram** (draggable Presence/Broadcast/Storage/Feeds/Threads room with human + agent participants), **DotMatrixMap** (triangular-lattice world map with illuminated marker extrusions), **RealtimeInfrastructureVisual** (integrated room + map composition sharing one scaled canvas), **SpotlightButton** (pointer-tracking spotlight action for artwork overlays); `marketingUtils.js` — reduced-motion/scroll hooks, install-prompt clipboard helper
- `ui_kits/marketing/` — full homepage recreation (nav, hero, use-case carousel, bento mosaic, pricing, testimonial, footer).
- `ui_kits/docs/` — docs shell recreation (header, sidebar, TOC, content).
- `ui_kits/product-embed/` — a mock collaborative app demonstrating the embeddable component library in context (comments, presence, notifications).
- `SKILL.md` — portable skill file for using this system outside this product.

## Intentional additions (components not in the source's confirmed inventory)

The source document is explicit that **Input/Textarea/Select, Checkbox/Radio/Switch, Modal, and Toast were never observed** in either measured surface — they're authored in this pass using the system's established grammar (same border/radius/shadow/motion/focus rules) because ordinary product flows need them. They are flagged `[A]` throughout and should get a design review before shipping. Explicitly **excluded**, per the source's own scope: a full app shell, data table, command palette, and settings-row — these are out of scope until a real product surface needs them.

---

## Content fundamentals

**Voice:** second person for the reader ("you"), third person for the product. Sentence case everywhere, with exactly one exception — the small, positive-tracked, all-caps section eyebrow. No exclamation marks. No banned-word list was directly documented, but the measured copy consistently favors concrete mechanism over inflated claims — e.g. naming what a feature literally does rather than reaching for "seamlessly," "effortlessly," "unlock," or "supercharge." Treat those four as off-brand by inference.

**Claims, not category labels.** Headings state a position — "Multiplayer is an infrastructure problem" — never a bare noun like "Overview." CTA labels name the outcome: "Get started for free," "Read the docs," never bare "Submit" or "Learn more."

**Numbers over adjectives.** Stat blocks and the rolling odometer exist specifically to replace an adjective ("fast," "global") with a live number.

**Completeness as a value.** Every mega-menu row, docs card, and sidebar entry carries a one-line description — a bare link reads as incomplete. This is the single most consistent content rule in the source.

**Errors and empty states** name what happened (or what's missing) and give exactly one action — no apology, no filler.

**Sample copy patterns** (illustrative shapes, not sourced quotes — the source document uses invented placeholder people/companies and this system does not repeat them as if real):
> Hero: a claim about the problem, then what the product does about it — "X is an infrastructure problem" → "Add collaborative editing for humans and agents, without building infrastructure."
> Card: title as a noun phrase, description as one plain sentence — "Persistent shared data" / "Data and files are stored across sessions. No backend to manage."
> Error: state what happened, offer retry, no apology.

---

## Visual foundations

**Color** is derived, not enumerated (see "signature idea" above). Product default accent is `#1177ff` light / `#44aaff` dark, exposed as `--lb-accent`; marketing/docs accent is violet (`#8F71F1`, measured dark-only — light mode is a reconstructed, unverified mirror, `#7D5AEF`). White text (`--lb-accent-foreground` / `--lb-destructive-foreground: #fff`) is preserved on filled accent and destructive controls as the visual-fidelity default. Beyond the single functional product accent, each ready-made feature — **Comments, Multiplayer, Notifications, Presence, AI Copilots** — has its own marketing-side identity accent (`--family-comments`, `--family-multiplayer`, `--family-notifications`, `--family-presence`, `--family-ai-copilots`); these are `[A]` authored placeholders in one consistent oklch chroma/lightness, hue-only variation, pending a real brand file — they identify a feature on the marketing site, they do not change the embedded component's own color, which always defaults to `--lb-accent`. A fixed five-member categorical palette (amber, rose, blue, green, violet) exists only for the marketing use-case carousel and must never be reused as semantic/status color. Participant cursor/avatar color is an open channel supplied by the integrating application — never hashed or rotated inside the system itself. **Semantic status** is its own role namespace, separate from `--accent`/`--destructive`: `--semantic-destructive` (`#FF4455`, `[M]` measured), `--semantic-success` (`#1F9C6E`, `[A]` authored this pass, shares hue with the marketing mint but not measured against it), `--semantic-warning` (`#B45309`, `[A]` authored — the one state with a white-only foreground exception, confirmed against both its tinted and solid applications), and `--semantic-info` (aliases `--lb-accent-text-safe`, the accessible accent reading — not raw `--accent` — so status can diverge from the brand accent later without a palette change). `info` is never labeled "Info / accent"; it documents a distinct status role, not a synonym for the general accent token. See `components/core/SemanticStatesPanel.jsx`, the shared data-driven presentation used by the "Semantic states" guideline card.

**Type:** two families. The official Liveblocks website uses Suisse Int'l. This distributable design-system implementation uses **Inter** as an open-license (OFL) substitute for marketing and documentation, because Suisse Int'l requires a separate commercial license this project doesn't hold — `tokens/typography.css` sets `--font-sans` to `"Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`, so it resolves to the OS/browser's Inter (if installed) or a clean system stack, with no self-hosted binaries and no missing-asset warning. Consumers with an appropriate Suisse Int'l license may override `--font-sans` to restore it. Code uses **JetBrains Mono** (open license, self-hosted). The embeddable product UI sets **no font-family of its own** — it inherits the host application's typography by design; every product component in `components/` uses `fontFamily: 'inherit'`, never a forced sans stack. Three weights only across the marketing/docs family — 400 (body), 500 (default UI weight — buttons, labels, most component text), 600 (headings, emphasis). No 700 exists anywhere. Product type is `em`-relative (11 steps, `0.625em`–`1.75em`); marketing type is fixed `rem` (hero H1 `4rem`, down to caption `0.875rem`).

**Spacing:** two deliberately different disciplines. Product is `em`-relative (`--spacing: 1em`, multiples from `0.25` to `3.5`) so a component nested in smaller host text shrinks proportionally with zero overrides. Marketing is fixed `rem` (`--space-1` through `--space-16`, `0.25rem`–`8rem`). Section padding on marketing is generous: `6rem` desktop, `4.5rem` tablet, `3.5rem` mobile.

**Backgrounds:** marketing is a monolithic true-black canvas with no photography — only product screenshots (real UI, both themes, never auto-inverted) and one textured background PNG pinned bottom-right as atmosphere. No hand-drawn illustration, no repeating pattern beyond that one texture. Sections alternate two surface tones with no divider rule between them — segmentation is by fill, not by line. Product surfaces are flat and neutral, no imagery.

**Gradients/glows:** rare and meaningful, never decorative filler. The AI-toolbar halo (four rotating gradient layers) means "a model is working here" and appears nowhere else. A hero ambient wash retints with the active use-case category. A pointer-spotlight (small radial gradient following the cursor) *replaces* hover fill on buttons that sit over artwork.

**Motion:** confirms, never decorates. `100ms` default duration; only `background`, `color`, `opacity` transition — `all` is never used. Two named easings do the marketing work: `ease-out-cubic` (workhorse) and `ease-out-bounce` (the digit-rolling odometer only — reserve it, it reads as juvenile elsewhere). Scroll-triggered entrance motion fires once, on the hero, and nowhere else. All auto-advancing motion (carousel, marquee, odometer) stops permanently on first user interaction. `prefers-reduced-motion` disables all of the above; focus rings always survive — they're state, not motion.

**Hover/press:** surfaces step up one fill level; marketing has no hover fill at all, using the pointer-spotlight instead. Cards never scale or lift on hover — border and fill steps only; a drop-shadowed card is treated as a bug. Icon and label color always move together, never independently.

**Borders:** one weight, `1px`, always an inset shadow rather than a `border` property so it never affects box sizing. Weight is expressed through an alpha ladder (6%→16% dark, one 10% value light), not pixel width.

**Shadows:** every shadow is a three-layer stack (hairline ring + tight contact shadow + wide ambient shadow), reserved for things that genuinely float — menus, tooltips, cursors, modals. Cards at rest never get one.

**Corners:** `--radius: 0.5em` is one of exactly two public customization knobs. Cards/panels `12px`, bento tiles `16px`, hero media frame `20px`, inputs/small buttons `8px`, pills/badges fully round, code blocks `10px`. Avatars are always circles.

**Transparency/blur:** the nav bar uses `backdrop-filter: blur(12px) saturate(180%)` at 72% opacity while scrolling; alpha-based dividers and fills are used throughout marketing (a deliberate five-step divider scale, plus one opaque variant specifically so overlapping hairline borders in the bento grid never double-render darker).

**Imagery color vibe:** cool, dark, no grain — product screenshots rendered in light mode inside the dark hero stage, no warm tones, no photography of people beyond avatar/testimonial headshots.

---

## Iconography

Line icons on a 20px grid, 1.5px stroke, round caps/joins, `currentColor`. Default color is the decorative `foreground-moderate` step, deepening one step on hover — icon and any adjacent label color always move together. Inline text icons scale to 14px (`0.7×` the base grid). The marketing map-marker rail uses a distinct 16px grid at the same 1.5px stroke, because it sits at a smaller relative text size — a font-relative scale doing its job, not an inconsistency.

**No icon set/source was provided** — no codebase, sprite, or SVG export was attached, only the specification document. This system substitutes **Lucide** (CDN-loaded, MIT-licensed) as the closest open match to the documented grid/stroke/style, flagged here as a substitution to verify against the real icon set if one becomes available. No emoji use was documented; two fixed-pixel exceptions exist for an emoji-picker padding token, implying an emoji picker exists in the product surface, but its own visual spec was never captured.

**No logo was provided.** Every place a wordmark or mark would sit renders the plain text "Liveblocks" in the system's own type instead — do not draw or approximate a logo from memory. Provide a real logo file to replace these placeholders.

---

## Known gaps and what to verify

This system carries forward the source document's own gap list in full (see the source's §16 for the exhaustive version). The most consequential:

- **No logo/wordmark file, no icon set, no real screenshots or customer logos** were provided — every one of those slots is either omitted or a clearly-flagged placeholder.
- **Font substitution:** the official site uses Suisse Int'l, a commercially licensed family this project doesn't hold a license for. Inter is used instead as an open-license substitute for marketing/docs, via font stack only (no self-hosted binaries, nothing to upload). JetBrains Mono is self-hosted from uploaded files, open license.
- **Icon set:** substituted with Lucide (see Iconography above) — verify against the real product icon source if one exists.
- **Marketing light theme** is a reconstructed, unverified mirror of the measured dark theme — never observed on a real light-mode marketing surface.
- **Input/Textarea/Select, Checkbox/Radio/Switch, Modal, Toast** were never measured — authored this pass from the system's grammar; review before shipping.
- No z-index scale, code-syntax palette (beyond 5 roles), or docs mobile-sidebar behavior were measured — all authored/partial, see the relevant `.prompt.md`/card notes.
- **Per-feature accent hex values** (Comments/Multiplayer/Notifications/Presence/AI Copilots) were not found in any measured source — `--family-*` tokens in `tokens/colors.css` are `[A]` authored placeholders (one oklch chroma/lightness, hue varied) standing in until a real brand file confirms them.
