Component catalog · Visual Cast

← all explorations
Mode

SageOx component catalog · Visual Cast

Components for the /cast TV destination and the /join mobile flow — primitives, room compositions, and the actual page surfaces. Source lives in packages/cast-web/. This page is generated by scripts/build-static-catalog.ts from the React registry — not maintained by hand. Re-export to update.

25 components 9 categories Surface · Visual Cast Generated · 2026-05-17

Tier 3 · Surfaces

Real product pages, organized by area. Each entry's KB-conformance rating is a deliberate audit signal: partial and drifted surfaces are candidates for the KB-parity refactor epic. Screenshots arrive when the Playwright capture harness lands.

Visual Cast

The /cast TV destination (idle, welcome, live meeting, team wall, team pulse) and the /join mobile flow. Cast-themed surfaces — chrome flips with data-cast-theme, mode flips with data-mode.

Chrome: CastRoot (no TopBar) + RoomShell ribbon + presence/dock + cast-theme tokens (Workshop default, Tactile/Atelier/etc. via cookie)

Cast · Idle screenshot Target · KB v2 mockup

Cast · Idle

/cast/idle
? unknown

Resting state for a paired TV between meetings. Shows team identity, ambient room awareness, and the pairing code for casting a new session.

apps/web/app/cast/idle/page.tsx
Primary components
  • CastRoot packages/cast-web/src/CastRoot.tsx
  • RoomShell packages/cast-web/src/room/RoomShell.tsx
States
  • No team paired
  • Paired · ambient
  • Paired · about-to-cast (recent activity)
Design notes
  • Cast theme defaults to Workshop (dark navy + violet) but flips per cast-theme cookie.
  • Calm state — no motion except the live pulse dot on team activity. Per Rule 2 (three-layer motion).
Cast · Welcome screenshot Target · KB v2 mockup

Cast · Welcome

/cast/welcome
? unknown

First-load welcome / onboarding shell for a freshly paired TV.

apps/web/app/cast/welcome/page.tsx
Primary components
  • CastRoot packages/cast-web/src/CastRoot.tsx
States
  • First paint
  • Transition to /cast/idle
Cast · Live meeting (TV) screenshot Target · KB v2 mockup

Cast · Live meeting (TV)

/cast/meeting/[rec_id]
~ partial

The live meeting destination on a TV. Composes the room shell with the active participant strip, raised-hand queue, decision pulse, reactions overlay, and presentation rail when a participant is presenting.

apps/web/app/cast/meeting/[rec_id]/page.tsx
Primary components
  • RoomShell packages/cast-web/src/room/RoomShell.tsx
  • RoomParticipantsList packages/cast-web/src/room/RoomParticipantsList.tsx
  • QuickReactRow packages/cast-web/src/room/QuickReactRow.tsx
  • RoomPresentationControl packages/cast-web/src/room/RoomPresentationControl.tsx
  • PresenceDensityRow packages/cast-web/src/room/PresenceDensityRow.tsx
States
  • Calm — meeting in progress, low activity
  • Climax — multiple hands raised, AI nudging
  • Recording active — rec-strip pulsing in the corner
  • Presentation mode — a participant is presenting
  • No active participants (orphaned)
Variations
  • Theme: Workshop (default) / Tactile / Atelier / Homestead / Expedition
  • Mode: live / pulse / quiet (page-side framerate dial, ADR-040)
Design notes
  • One copper accent per view (active speaker indicator). Reactions overlay must dim under data-calm.
  • Frame rate is page-side: proxy.ts stamps x-cast-mode/x-cast-fps headers; CastRoot reads them.
Cast · Meeting join intermediate screenshot Target · KB v2 mockup

Cast · Meeting join intermediate

/cast/meeting/[rec_id]/join
? unknown

TV-side intermediate page showing the QR + short pairing code for participants to join the meeting from their phones. Used while the recording exists but participants are still arriving.

apps/web/app/cast/meeting/[rec_id]/join/page.tsx
States
  • Code visible · 0 participants joined
  • Code visible · participants arriving
  • Code expired/revoked
Design notes
  • QR is dark-on-light by default; flips with data-mode.
  • Short code is 4 chars, font is JetBrains Mono 800 at ~140px.
Cast · Team wall screenshot Target · KB v2 mockup

Cast · Team wall

/cast/team/[team_id]/wall
? unknown

Static team wall view for a paired TV — the social feed surface showing recent decisions, hand-raises, recordings, and ambient team presence. Read-only.

apps/web/app/cast/team/[team_id]/wall/page.tsx
Primary components
  • RoomShell packages/cast-web/src/room/RoomShell.tsx
  • RoomAttachmentsRow packages/cast-web/src/room/RoomAttachmentsRow.tsx
States
  • Active team · populated
  • Quiet team · sparse feed
  • No team data
Cast · Team pulse screenshot Target · KB v2 mockup

Cast · Team pulse

/cast/team/[team_id]/pulse
? unknown

Live team-presence visualization for a paired TV. Continuous murmur of who is around, who is speaking elsewhere, what is in motion — calmer than the wall, more alive than idle.

apps/web/app/cast/team/[team_id]/pulse/page.tsx
Primary components
  • PresenceDensityRow packages/cast-web/src/room/PresenceDensityRow.tsx
States
  • Quiet pulse
  • Live pulse · active speakers
Design notes
  • Pulse loop must stop after 3 cycles per Rule 2 (three-layer motion); restarts on actual signal.
Join · Mobile (public) screenshot Target · KB v2 mockup

Join · Mobile (public)

/join
~ partial

Public mobile entry for joining a cast session via a short code or shared link. Phone-shaped surface — identity card, status bar, hand-raise toggle, reaction quick-row.

apps/web/app/(public)/join/page.tsx
Primary components
  • PhoneStatusBar packages/cast-web/src/room/PhoneStatusBar.tsx
  • IdentityCard packages/cast-web/src/room/IdentityCard.tsx
  • RaiseHandToggle packages/cast-web/src/room/RaiseHandToggle.tsx
  • HandRaiseConfirmCard packages/cast-web/src/room/HandRaiseConfirmCard.tsx
  • QuickReactRow packages/cast-web/src/room/QuickReactRow.tsx
States
  • Code entry
  • Joining (resolving session)
  • In session · hand down · listening
  • In session · hand raised · queued
  • Reaction sent · confirmation pulse
  • Session ended · summary
Variations
  • Theme: Workshop (default) / Tactile — picks up the host TV cookie
  • Identity: known user vs anonymous (display-name only)
Design notes
  • Surface is iOS-status-bar-aware: PhoneStatusBar sticky-fixes above IdentityCard so the elapsed timer never scrolls off.
  • Hand-raise queue position is derived client-side from screen.raisedHands sorted by handRaisedAt.

Components

Reusable primitives that compose the surfaces above. Each shown in all variants and states.

Actions

Buttons and action triggers. One Copper CTA per view; hierarchy via variant + color.

RoomPresentationControl

TV-side controls for whatever participant is currently presenting — pause, advance, hand back. Visible only when presentation mode is active.

packages/cast-web/src/room/RoomPresentationControl.tsx
Active presentation
alice · slide 3 / 12

RecordingControls

Start/stop/pause recording from within the room. Sacred-tier — surfaces a pulsing red dot when armed; refuses to dismiss while recording is live.

packages/cast-web/src/room/RecordingControls.tsx
Armed · recording
recording · 12:04

QuickReactRow

Six-emoji quick-reaction row that participants tap from /join. Reactions float up to the TV via an SSE channel and overlay on the meeting canvas.

packages/cast-web/src/room/QuickReactRow.tsx
Six reactions
👍❤️🎉🤔😅🙌

RaiseHandToggle

Big hero toggle on /join. Hand down → calm sage; hand up → copper-bordered with queue-position readout. Hold-down for "I have a quick question" haptic distinction.

packages/cast-web/src/room/RaiseHandToggle.tsx
Hand down
Hand up

PlayAvatarButton

Avatar-on-its-own play button — used in compact contexts (room dock, attachment row) where a full RecordingControls is too much chrome.

packages/cast-web/src/room/PlayAvatarButton.tsx
Idle

Forms

Inputs, controls, validation. Composable with Label and form-state hooks.

IdleAvatarSelector

Avatar/initials picker shown during /join check-in for participants who don't have a profile photo. Six-tile picker that maps to deterministic avatar colors.

packages/cast-web/src/room/IdleAvatarSelector.tsx
Six tiles

Data display

Tables, lists, descriptions, and visualizations. Dense by default; semantic tokens.

RoomParticipantsList

Strip of participant avatars + names for the live TV meeting. Composes IdentityCard atoms; collapses density when ≥8 participants per PresenceDensityRow rules.

packages/cast-web/src/room/RoomParticipantsList.tsx
Five participants
AC
ac
BR
br
CH
ch
DM
dm
ER
er

PresenceDensityRow

Adaptive presence strip. Renders full avatars under ≤7 participants; collapses to density dots + overflow count above. The visual register of "the room is alive."

packages/cast-web/src/room/PresenceDensityRow.tsx
Collapsed (12 participants)
+5

RoomAttachmentsRow

Inline chip row for files and links shared into the room. TV-scale (bigger type than console attachment chips), with iconography that reads at 10 ft.

packages/cast-web/src/room/RoomAttachmentsRow.tsx
Three attachments
Q3-plan.pdfdesign.figbudget.xlsx

Feedback

Status indicators, alerts, toasts, progress. Communicate without modal interrupts.

HandRaiseConfirmCard

Transient confirmation panel that appears for ~5s after the user raises their hand. Shows queue position derived from screen.raisedHands sorted by handRaisedAt.

packages/cast-web/src/room/HandRaiseConfirmCard.tsx
Queued 3rd
You're 3rd in the queue
2 ahead · alice, chen

ParticipantCheckInView

/join landing shell shown after the participant scans the QR but before they fully join — name confirmation, avatar selector, and the "you're in" confirm.

packages/cast-web/src/room/ParticipantCheckInView.tsx
Check-in
Joining as
Ryan Snodgrass

YouAreInToast

Brief celebratory toast on successful join. Fades after ~3s; respects prefers-reduced-motion.

packages/cast-web/src/room/YouAreInToast.tsx
Joined
You're in · 4 others listening

Navigation

Tabs, breadcrumbs, menus, command palettes. Keyboard-first.

CastViewSelector

Switcher between /cast/* sub-views (meeting / wall / pulse). TV-scale segmented control; keyboard-navigable via the host BLE remote.

packages/cast-web/src/room/CastViewSelector.tsx
Three views
MeetingWallPulse

RoomPresentationHostBar

Host-only chrome strip overlaid on the TV during presentation mode. Shows the active presenter, time elapsed, and the take-back-control affordance.

packages/cast-web/src/room/RoomPresentationHostBar.tsx
Hosting Alice
● alice presenting · 04:32take back control

Overlays

Dialogs, popovers, tooltips, slide-overs. Animations are decisive (250ms in, 200ms out).

RoomSettingsMenu

Per-room settings (theme picker, mute, recording controls). Slide-over panel; host-only. Trigger lives in the ribbon corner.

packages/cast-web/src/room/RoomSettingsMenu.tsx
Trigger

Layout

Page containers, panels, grids, separators — structure without decoration.

Screen

Phone-shaped screen wrapper used by /join. Locks viewport, applies cast-theme tokens, and provides the column for participant chrome.

packages/cast-web/src/primitives/Screen/index.tsx
Empty screen

CastScreen

TV-shaped screen wrapper used by /cast/*. Locks 16:9, applies cast-theme tokens, and hosts RoomShell.

packages/cast-web/src/primitives/CastScreen/index.tsx
Empty TV

RoomShell

Top-level frame for any /cast/* TV surface. Composes ribbon (52px Workshop / 64px Tactile) + dock (120/152px) + main canvas. Every TV page mounts inside it.

packages/cast-web/src/room/RoomShell.tsx
Wireframe
ribbon · 52px
canvas
dock · 120px

RoomChatPanel

Right-rail chat panel for the TV meeting view. Shares the chat data model with the console /kb chat surface but renders for TV reading distance — bigger type, two-rail rendering (sage left / copper right) without bubble chrome.

packages/cast-web/src/room/RoomChatPanel.tsx
Two turns
what did we land on for Friday?
cut-over at 14:00, chen runs ops

Status

Pipeline states (pending → running → succeeded → failed). Semantic colors carry meaning.

StatusText

Cast-themed status text primitive. Two variants — baseline (terse) and enhanced (with motion + emphasis). Used wherever an ambient status string appears on a cast surface.

packages/cast-web/src/primitives/StatusText/index.tsx
Baseline vs enhanced
3 listening · 1 hand raised● 3 listening · 1 hand raised

PhoneStatusBar

iOS-style status strip sticky-fixed at the top of /join. Brand mark + live elapsed-meeting timer (1Hz monospace digits).

packages/cast-web/src/room/PhoneStatusBar.tsx
In session
SageOx12:04

IdentityCard

You-are-X card at the top of /join. Avatar (warm-bordered when hand is up), display name, status hint, and session timestamp.

packages/cast-web/src/room/IdentityCard.tsx
Hand raised
RS
Ryan Snodgrass
● hand raised · listening

Tokens

The raw values underneath — color scales, type ramp, spacing, motion. Reference for what every component composes from.

Foundations

Color tokens, typography, spacing — the visual primitives every component composes from.

Theme · Workshop

Default cast theme. Dark navy with violet accents; quiet, technical register. 52px ribbon, 120px dock, Inter + JetBrains Mono.

packages/cast-web/src/themes/workshop/tokens.css
Surface chips

Theme · Tactile

Warm paper-toy theme. Cream + mustard/mint/coral with claymorphic hard-offset shadows. Single-mode (light); 64px ribbon, 152px dock, Manrope + IBM Plex Mono.

packages/cast-web/src/themes/tactile/tokens.css
Surface chips

Wordmark

SageOx wordmark sized for 10-foot viewing on a TV. clamp()-based responsive sizing across receivers from a 720p Chromecast up to a 4K Bravia; three size tokens (sm/md/lg).

packages/cast-web/src/primitives/Wordmark/index.tsx
Three sizes
SageOxSageOxSageOx