AI Chat

The AI-chat workspace template — Stage 5 opener, and the successor to the retired ChatWorkspace dashboard (/chat/workspace/ now redirects here). Primitives live on the Chat page; the frame is the App Shell. Pure composition: LB.Shell frame · LB.ConvList in the sidebar (auto Pinned + date-grouped buckets) · .lb-thread capped at 48rem (~768px at the default root size) · the Composer Dock docked at the bottom · ContextBudgetBar in the topbar · optional artifacts rail. The AI engine is yours — wire the composer/thread events to your provider. Consumed here: App Shell · Chat primitives · Composer Dock · Popover · Banner · Avatar · Segmented · Progress.

a11y (built in): a clip-hidden .lb-shell__skip link leads the frame and lands on <main tabindex="-1">; the sidebar toggle is a disclosure (aria-expanded + aria-controls, Ctrl/Cmd+B) and the drag handle is a focusable role=separator resized with ←/→. Below 768px the sidebar becomes a real modal — role=dialog + aria-modal + focus trap + scroll-lock, Esc closes it and focus returns to the toggle. Streaming bubbles carry aria-busy="true" so the thread's role=log stays quiet until the reply lands, and every icon-only action carries an aria-label.

Usage: Load three scripts in order — js/lb.js, js/components/lb-chat.js, js/components/lb-shell.js — and every piece auto-inits from its data attribute (data-lb-shell, data-lb-thread, data-lb-composer, data-lb-conv-list, data-lb-context-budget-bar). The wiring you own: populate the sidebar via listEl._lbConvList.setConvs([…]) + setActive(id), handle lb-composer-submit / lb-composer-stop by streaming your model's reply into thread._lbThread.appendBubble({…}) + appendText(), and report tokens with budgetEl._lbContextBudgetBar.setBudget({used, total}). Sidebar collapse/width persists in localStorage under data-lb-shell-key — give the workspace its own key per app.

Conventions baked in: assistant messages render flat/document-style (bubble shapes signal casual messaging — only the user side keeps the tinted bubble; this is our bubble default already); focus does not jump when a stream completes; per-response thumbs-up / thumbs-down buttons in the bubble footer.


The workspace

Everything wired: collapse the sidebar (Ctrl/Cmd+B, drag-resize enabled), pick conversations, open the model tray in the dock, watch the context bar. The artifacts rail is the shell's aside slot — transient by convention, shown here open.

Skip to conversation
letbe chat
Why is the sky blue?
Conversation started · today
You2 min ago
Why is the sky blue?
Assistant1 min ago

The sky looks blue because sunlight scatters as it passes through the atmosphere — shorter blue wavelengths scatter far more than the longer red ones, so blue light reaches your eyes from every direction.

At sunrise and sunset the light crosses far more air, the blue is scattered away before it reaches you, and the reds and oranges are what remain.

A new model is rolling out — responses may take a little longer while we scale up.
Model
Effort
Artifact
sky-scattering.svg
preview

Composition notes

This page is assembly only — every part is an existing component: LB.Shell (collapse/peek/resize/drawer), LB.ConvList (pinned + date buckets, search, kebab actions — consumer owns the data via setConvs()), .lb-thread + .lb-bubble (flat assistant default, --user tinted, branching + streaming built in), the .lb-dock module with its Popover tray, and ContextBudgetBar. Replaces the ChatWorkspace dashboard chrome — the chat primitives are unchanged. On a real page the shell is the body's only child at 100dvh.