SageOx · MobileSageOx 1.0.0 · sageox://

Mobile design catalog

Tokens, components, and screens for the SageOx mobile app (React Native + Expo). This catalog is a snapshot; the canonical rules live in DESIGN.md and the source of truth is src/catalog/registry.ts in the sageox-app repo. Coverage lint fails CI if a screen is added without a registry entry — see scripts/lint-catalog-coverage.ts.

Sections below render in the canonical order Surfaces → Components → Tokens per catalog/README.md. The live in-app catalog at sageox://internal/design-catalog renders the same data natively in RN.

Surfaces

Whole-screen flows the user actually experiences. Login, empty-state, account, recording — what the app looks like in use, end to end.

Auth & account

Splash / route gate

/
screen snapshot pending

Root entry. Decides whether to send the user to login or into the tabs based on the current session. On web the redirect is instant; the native iOS launch image is captured via Maestro.

app/index.tsxsince 1.0.0

Login

/login
Login screen
react-native-web @ 390×844 · pre-auth empty state

Email + password sign-in via Better Auth. Stores the session token in expo-secure-store, then exchanges it for a short-lived JWT for /api/v1 calls.

app/login.tsxsince 1.0.0

Account

/account
Account screen
react-native-web @ 390×844 · pre-auth empty state

Signed-in account screen. Profile, theme preference (light / dark / system toggle), and sign-out.

app/account.tsxsince 1.0.0

Primary tabs

Home

/(tabs)
Home screen
react-native-web @ 390×844 · pre-auth empty state

Default tab landing. Recent activity across the user’s teams.

app/(tabs)/index.tsxsince 1.0.0

Teams

/(tabs)/teams
Teams screen
react-native-web @ 390×844 · pre-auth empty state

List of teams the user is a member of. Tap to drill in.

app/(tabs)/teams/index.tsxsince 1.0.0

Devices

/(tabs)/devices
Devices screen
react-native-web @ 390×844 · pre-auth empty state

Registered Scribe devices and pairing flow entry point.

app/(tabs)/devices/index.tsxsince 1.0.0

Team

Team overview

/team/[teamId]
Team overview screen
react-native-web @ 390×844 · pre-auth empty state

Team home: members, activity, jump-off to sub-sections.

app/team/[teamId]/index.tsxsince 1.0.0sageox://team/team_123

Team discussions

/team/[teamId]/discussions
Team discussions screen
react-native-web @ 390×844 · pre-auth empty state

Conversations between coworkers (humans + AI). Sourced from the team-context channel.

app/team/[teamId]/discussions.tsxsince 1.0.0

AI sessions

/team/[teamId]/sessions
AI sessions screen
react-native-web @ 390×844 · pre-auth empty state

Prior AI-coworker coding sessions for this team’s repos. Read-only ledger view.

app/team/[teamId]/sessions.tsxsince 1.0.0

Repos

/team/[teamId]/repos
Repos screen
react-native-web @ 390×844 · pre-auth empty state

Repositories connected to this team.

app/team/[teamId]/repos.tsxsince 1.0.0

Coworkers

/team/[teamId]/coworkers
Coworkers screen
react-native-web @ 390×844 · pre-auth empty state

Member roster — both human and AI coworkers.

app/team/[teamId]/coworkers.tsxsince 1.0.0

Invite coworker

/team/[teamId]/invite
Invite coworker screen
react-native-web @ 390×844 · pre-auth empty state

Send an invite to add a coworker to this team.

app/team/[teamId]/invite.tsxsince 1.0.0

Team settings

/team/[teamId]/settings
Team settings screen
react-native-web @ 390×844 · pre-auth empty state

Team name, visibility, integrations.

app/team/[teamId]/settings.tsxsince 1.0.0

Start recording

/team/[teamId]/record
Start recording screen
react-native-web @ 390×844 · pre-auth empty state

Pre-flight: request microphone permission, name the recording, then transition to the active recording screen.

app/team/[teamId]/record.tsxsince 1.0.0

Recording (active)

/team/[teamId]/record/active
Recording (active) screen
react-native-web @ 390×844 · pre-auth empty state

Live recording surface. Chunked Opus upload via presigned S3 URLs, heartbeat ping, pause/resume. Audio is Sacred — never silently dropped.

app/team/[teamId]/record/active.tsxsince 1.0.0

Recording detail

/team/[teamId]/recordings/[recId]
Recording detail screen
react-native-web @ 390×844 · pre-auth empty state

Playback, transcript, meeting notes, decisions for a completed recording.

app/team/[teamId]/recordings/[recId].tsxsince 1.0.0

Device

Device detail

/devices/[devId]
Device detail screen
react-native-web @ 390×844 · pre-auth empty state

Single Scribe device. Rename, change team binding, view live config, unpair.

app/devices/[devId].tsxsince 1.0.0

Meeting (live)

Join meeting

/meeting/[recId]/join
Join meeting screen
react-native-web @ 390×844 · pre-auth empty state

Phone-participant surface for a meeting cast to a TV. Chat, reactions, hand-raise, avatar plays.

app/meeting/[recId]/join.tsxsince 1.0.0sageox://meeting/rec_123/join

System

Internal · Design catalog (live)

/internal/design-catalog
screen snapshot pending

In-app live catalog. Dev-only deep link for agents and designers to browse Surfaces → Components → Tokens against the running app — mirrors the published snapshot.

app/internal/design-catalog.tsxsince 1.1.0sageox://internal/design-catalog

404 / not found

*
404 / not found screen
react-native-web @ 390×844 · pre-auth empty state

Fallback route for unknown deep links.

app/+not-found.tsxsince 1.0.0

Components

Reusable primitives the surfaces are composed of. Each shown in every variant; flip the chrome Mode toggle to verify light + dark. The canonical render is the live in-app catalog at /internal/design-catalog; the HTML reflections here are pixel-approximate.

Inputs & actions

Button

primarysecondaryghostdestructiveloading

Pressable action with semantic variants. One Copper-tier primary per screen — additional actions stay secondary or ghost so hierarchy reads. Loading state never silently disables; it dims and locks input.

primary
secondary
ghost
destructive
loading
src/components/Button.tsxsince 1.1.0

Feedback & status

EmptyState

defaultwith-cta

Centered icon + headline + supporting body + optional CTA. Used wherever a list is legitimately empty (no teams, no devices, no recordings). Calm, never alarming.

default
No teams yet
Join an existing team with an invite code, or create your own.
with-cta
No paired devices
Turn on your Scribe and enter the pairing code shown on its display.
src/components/EmptyState.tsxsince 1.1.0

Layout & surfaces

Card

staticpressable

Elevated surface tile. Use for list items and grouped content. Pressable variant adds the standard press-opacity feedback; static variant has none.

static
Acme Engineering
12 members · Public
pressable
src/components/Card.tsxsince 1.1.0

Tokens

The raw values underneath surfaces and components — color scales, semantic theme slots, spacing, radius, type, motion. The bottom of the stack.

Palette

Core palette. Sage is the primary brand color, Copper the accent, Charcoal the neutral scale.

sage
sage · 50
#f3f6f2
sage · 100
#e5ede3
sage · 200
#d8e3d5
sage · 300
#c4d1c0
sage · 400
#aebca7
sage · 500
#7a8f78
sage · 600
#677d66
sage · 700
#546a54
sage · 800
#445743
sage · 900
#364634
copper
copper · 50
#fdf7f1
copper · 100
#f8e7d5
copper · 200
#f1d2ae
copper · 300
#e9be8b
copper · 400
#e0a56a
copper · 500
#c47a4a
copper · 600
#a8613b
copper · 700
#8c4b2e
copper · 800
#6f3923
copper · 900
#59301d
charcoal
charcoal · 50
#f5f6f7
charcoal · 100
#e7e9ea
charcoal · 200
#d1d5d7
charcoal · 300
#b8bfc2
charcoal · 400
#8f99a3
charcoal · 500
#6f767c
charcoal · 600
#4c5358
charcoal · 700
#2c3236
charcoal · 800
#1a1f22
charcoal · 900
#111518

Light theme

Sage-centric surfaces, charcoal text. Default on light system mode.

background
base
#f3f6f2
surface
#ffffff
elevated
#ffffff
overlay
rgba(17, 21, 24, 0.1)
text
primary
#111518
secondary
#4c5358
muted
#6f767c
disabled
#8f99a3
inverse
#ffffff
border
light
#d1d5d7
medium
#b8bfc2
strong
#8f99a3
interactive
primary
#7a8f78
primaryHover
#677d66
primaryActive
#546a54
secondary
#c47a4a
secondaryHover
#a8613b
secondaryActive
#8c4b2e
state
error
#c44747
warning
#e0a56a
success
#7a8f78
info
#7fa7c8
focus
ring
#aebca7
background
#f3f6f2

Dark theme

Charcoal-centric surfaces, sage accents. Default on dark system mode.

background
base
#111518
surface
#1a1f22
elevated
#2c3236
overlay
rgba(0, 0, 0, 0.5)
text
primary
#e7e9ea
secondary
#aebca7
muted
#8f99a3
disabled
#4c5358
inverse
#111518
border
light
#2c3236
medium
#4c5358
strong
#6f767c
interactive
primary
#aebca7
primaryHover
#c4d1c0
primaryActive
#7a8f78
secondary
#e0a56a
secondaryHover
#e9be8b
secondaryActive
#c47a4a
state
error
#f87171
warning
#e0a56a
success
#aebca7
info
#9fc3e0
focus
ring
#c4d1c0
background
#364634

Spacing

Base unit is 2 px. Use directly with padding, margin, gap. Tokens skip values intentionally — there are no half-steps.

spacing.0
0 px
spacing.1
2 px
spacing.2
4 px
spacing.3
8 px
spacing.4
12 px
spacing.5
16 px
spacing.6
24 px
spacing.7
32 px
spacing.8
48 px
spacing.9
64 px
spacing.10
80 px
spacing.11
96 px
spacing.12
128 px

Radius

Border-radius scale. `full` clamps to a circle at any size.

none
0 px
xs
2 px
sm
4 px
md
6 px
lg
8 px
xl
12 px
2xl
16 px
3xl
24 px
full
9999 px

Typography

Headings (display / h1 / h2) use Space Grotesk 600; body and UI use Inter (400 / 500 / 600). See DESIGN.md §4 for the full type policy.

display
36/40 · w600 · ls-0.72
The quick sage fox jumps over the lazy copper dog.
h1
24/30 · w600 · ls-0.48
The quick sage fox jumps over the lazy copper dog.
h2
20/25 · w600 · ls0
The quick sage fox jumps over the lazy copper dog.
h3
16/20 · w600 · ls0
The quick sage fox jumps over the lazy copper dog.
body
14/21 · w400 · ls0
The quick sage fox jumps over the lazy copper dog.
small
12/18 · w400 · ls0
The quick sage fox jumps over the lazy copper dog.
tiny
10/15 · w500 · ls0.5
The quick sage fox jumps over the lazy copper dog.

Shadows

iOS values shown. Android uses `elevation` — see src/theme/tokens.ts for the per-platform mapping.

small
medium
large