ClaireDocs

Ask Claire

Search the project, not the web.

Answers are grounded in Claire’s published documentation and include the source pages used.

⌘/Ctrl + J opens Ask Claire anywhere in docs.

Design system migration guide

Move Claire surfaces onto shared semantic tokens and native primitives, incrementally.

DraftReviewed 2026-08-17View source ↗
The visual target for migrated screensOpen the mobile gallery →

This guide moves the existing Expo client toward the visual system the mockups demonstrate. The migration must stay incremental — do not rewrite routing, data fetching, and presentation in one change.

Migration goals#

  • One semantic token source for iOS, Android, macOS, Windows, and marketing web.
  • A shared product language, without pretending mobile and desktop layouts are the same thing.
  • One-off colors, radii, and text sizes replaced by primitives.
  • Messaging, bridge, authentication, and AI behaviour preserved throughout the visual rollout.
  • Every migrated screen easy to compare against the design reference.

The design-system package#

packages/design-system
src/
  tokens/      color · type · space · radius · motion
  theme/       ThemeProvider · useTheme
  primitives/  ClaireText · ClaireButton · ClaireIconButton · ClaireCard
               ClaireAvatar · ClaireChip · ClaireField · ClaireDivider
  patterns/    ConversationRow · MessageBubble · PlatformBadge
               AIAssistCard · LoopCard

Start inside mobile/design-system/ if workspace wiring would slow the first pull request, then extract to packages/ when the desktop bootstrap begins.

Token translation#

The HTML mockups use CSS custom properties as documentation only. Native apps import typed token objects.

packages/design-system/src/tokens.ts
export const colors = {
  ink: '#10120F',
  cream: '#F4F1EA',
  paper: '#FFFDF8',
  lime: '#DFFF64',
  sky: '#B9DCFF',
  focus: '#3C68FF',
  success: '#18794E',
  warning: '#B75D00',
  danger: '#C83A3A',
} as const;

export const space = { 1: 4, 2: 8, 3: 12, 4: 16, 6: 24, 8: 32, 12: 48, 16: 64, 24: 96 } as const;
export const radius = { control: 12, card: 20, panel: 32, feature: 48, pill: 999 } as const;

Semantic typography#

Define variants rather than passing raw font sizes.

VariantMobileDesktopUsage
display42/4252/52Onboarding and major empty states
screenTitle31/3428/31Screen or window destination title
sectionTitle20/2418/22Section and inspector headings
body15/2214/20Primary reading text
bodySmall13/1812/17Supporting content
label11/1510/14Controls and metadata
monoLabel10/149/13AI and status labels

Every text component must support Dynamic Type and system font scaling. Avoid fixed-height containers around user-generated text.

Component rules#

Avatar#

  • Always set equal width and height, aspectRatio: 1, and flexShrink: 0.
  • The platform badge is positioned relative to the avatar wrapper and never allowed to change avatar layout.
  • The text fallback uses initials with a stable contact-derived color.

Platform badge#

  • Include a glyph and an accessible platform name — color alone is insufficient.
  • Keep the badge subordinate to the person and the conversation.
  • Use real vector or SF Symbol assets in production, not the letter placeholders.

AI assist card#

  • Always state why it appeared: quick context, loop found, suggested reply, or answer.
  • Generated answers link back to their source messages.
  • The primary action is explicit; dismissal and correction are always available.
  • AI color is contextual — sky, lavender, or a warm loop yellow — never a generic gradient.

Button#

  • Mobile touch target at least 44 points, even when the icon is smaller.
  • Desktop pointer target at least 28 points, ideally 32–36.
  • Focus ring: a 3-point focus token with offset.
  • Destructive actions use the danger token only once intent is clear.

Existing screen mapping#

Existing routeNew targetMigration note
app/(tabs)/dashboard.tsxDaily briefKeep the smart-card data; replace section composition.
app/(tabs)/messages.tsxUnified inboxMove platform filters into chips; normalize conversation rows.
app/chat/[chatId].tsxChatAdd the AI context ribbon and inline loop card behind flags.
app/(tabs)/loops.tsxLoopsIntroduce summary metrics and source-message links.
app/(tabs)/contacts.tsxPeopleAdd a context-needed section and a relationship entry.
app/chat/settings/[chatId].tsxRelationship memoryRecompose prompt, type, and tone around a contact model.
app/(tabs)/settings.tsxSettings hubSplit Claire behaviour from app and infrastructure settings.
PlatformAuthModal.tsxConnection setupRender steps from capability and connection definitions.
MessageCard.tsxConversation and message patternsSplit the inbox row from the chat bubble instead of one card doing both.

Recommended rollout#

  1. Snapshot and protect behaviour. Capture screenshots and flow tests for sign-in, inbox filters, chat send, platform auth, loop tracking, and relationship settings. Add a newDesignSystem flag that switches presentation only — never maintain two data implementations.
  2. Tokens and primitives. Typed tokens, then text, button, icon button, card, avatar, chip, field, and divider. Test light mode first.
  3. Shared patterns. Platform badge, conversation row, message bubble and composer, AI assist and loop cards, settings row and toggle, and the empty, error, and skeleton states.
  4. Migrate the core loop, one screen at a time behind the flag: inbox, chat, daily brief, loops, search.
  5. People and settings. Replace free-form relationship strings with an enum plus an optional custom label; keep the prompt user-authored and visible.
  6. Remove legacy styling. Delete old color constants only when no references remain, then drop the flag.
  7. Extract for desktop. Move tokens and primitives to packages/design-system, and keep navigation and window composition outside the shared package.

The proposed mobile shell is Home, Inbox, Loops, and Search, with People as an Inbox subview and Settings opening from the profile.

Relationship memory data model#

Relationship memory
type RelationshipType =
  | 'business' | 'client' | 'colleague' | 'mentor'
  | 'family' | 'close_friend' | 'friend' | 'acquaintance'
  | 'dating' | 'partner' | 'former_partner'
  | 'community' | 'service_provider' | 'other';

type SuggestionTone = 'warm_direct' | 'professional' | 'casual' | 'playful' | 'custom';

interface RelationshipMemory {
  contactId: string;
  type: RelationshipType;
  customType?: string;
  prompt?: string;
  suggestionTone: SuggestionTone;
  updatedAt: string;
}

Platform-specific styling policy#

Three layers, in order:

  1. Shared semantics. Colors, spacing, typography variants, state names.
  2. Shared patterns. Data and interaction contract.
  3. Platform composition. Mobile tab screens versus desktop panes and windows.

So ConversationRow.tsx shares behaviour and base visuals, while ConversationRow.macos.tsx and ConversationRow.windows.tsx add host keyboard conventions, hover, context menus, selection, and pointer density. Do not scale a 390-point phone screen to fill a desktop window.

Styling technology#

Native production code consumes token objects and React Native style props. Do not make Tailwind or NativeWind a requirement for the shared desktop package until both desktop-host compatibility spikes are proven.

  • Existing NativeWind screens can import token values through the client Tailwind mapping.
  • New shared primitives accept semantic props and produce native styles internally.
  • Feature screens must not contain raw hex codes.
  • Use continuous border curves on Apple platforms where supported.
  • Use native boxShadow, not the legacy shadow* or elevation APIs.

Accessibility checklist#

  • 44-point mobile touch targets and visible keyboard focus on desktop.
  • Correct roles and labels for icon-only buttons.
  • Platform badges announced after the contact or conversation name.
  • Dynamic Type, system text scaling, reduced motion, and reduced transparency.
  • Contrast testing for cream, paper, and all pastel surfaces.
  • Text or icons accompany every status color.
  • Message state — sending, failed, read — is never communicated by color alone.

Visual QA matrix#

Test each migrated screen at:

  • iPhone SE width, standard iPhone, and large iPhone; iPad split view if enabled.
  • macOS and Windows at 1024×680 minimum, 1280×800, and 1440×900.
  • Increased text size at 135% and 200%.
  • Reduce Motion, Increase Contrast, and VoiceOver.
  • Empty, one-item, typical, and high-density data.
  • Every platform capability combination.
  • Light mode — add dark only after semantic dark tokens are approved.

Definition of done, per screen#

  • No raw colors, radii, or spacing values outside an approved exception.
  • All icon-only controls have accessible names and correct target sizes.
  • Existing functional flow tests pass, and new visual states have screenshot coverage.
  • Loading, empty, offline, error, and partial states all exist.
  • User-generated text scales without clipping.
  • Platform-specific actions are capability-gated.
  • Design reference and implementation differ only for documented native behaviour.