The Oshun V1 design system is the shared visual, behavioral, and copy foundation
that every customer and admin surface is built on. It is not a style guide that
lives in a deck — it ships as real, tested TypeScript: design tokens
(libs/oshun/design-tokens), a reusable component library (libs/oshun/ui),
the localization catalog (libs/oshun/i18n), and a suite of auditable
design-language modules (libs/oshun/design-language) that encode the rules an
engineer or reviewer can query and a test can enforce. This page sits in the
platform-quality area alongside
Analytics, Observability, Testing, and Security;
together they describe how Oshun makes the product feel calm, consistent,
accessible, and honest about AI. The companion architecture page is
Architecture, Platform Foundations, and Security.
What the design system is, and where it lives#
V1 deliberately splits the design system into four cooperating packages so that "the rules" are independently testable from "the components" and from "the words":
| Concern | Package | What it ships |
|---|---|---|
| Tokens (color, type, spacing, motion, behavior) | libs/oshun/design-tokens |
oshunTokenSchema, themes, and behavior tokens |
| Reusable components | libs/oshun/ui |
21 React components plus motion/ and theme/ subpackages |
| Localized strings and formatting | libs/oshun/i18n |
CUSTOMER_MESSAGES catalog, translate(), locale formatting |
| Design-language rules and audits | libs/oshun/design-language |
scorecards, ergonomics, voice/tone, disclosure copy, visual-QA claims |
The web app (apps/oshun/web) consumes all four: tokens drive its theme,
@oshun/ui provides the components, next-intl wires the localized messages
(apps/oshun/web/src/i18n/request.ts and apps/oshun/web/src/i18n/config.ts),
and the design-language audits gate the design-review checklist.
Product language and information architecture#
V1 design begins with a single product thesis encoded in
libs/oshun/design-language/src/index.ts as TARA_CENTERED_PRODUCT_LANGUAGE:
"Oshun starts from Tara practice: calm attention first, then evidence, sky
context, habits, texts, and learning." The voice is plain, source-aware,
non-shaming, specific, and quietly confident; the prohibited registers
are explicitly growth pressure, fear-led prompts, unattributed certainty,
and operator jargon. This is not decorative prose —
assertSurfaceUsesTaraLanguage() enforces that the home surface orders tara
first and that headlines avoid growth-pressure language, so a surface that
violates the thesis fails a test rather than merely a review.
The unified information architecture lives in OSHUN_UNIFIED_IA:
- Customer shell:
Home,Explore,Activity,Library,Assistant,Profile. - Admin shell:
Queues,Review,Policy,Incidents,Privacy,Models,Personas,Support. - Journey models:
morning Tara continuation,midday research-to-practice,evening sky-to-text,story-to-source, andassistant-led memory review.
The customer/admin shell distinction is also a visual distinction. The two
visual theses in OSHUN_VISUAL_THESES describe the customer surface as "a quiet
reading-and-practice workspace with Tara as the center, restrained chrome, clear
evidence affordances, and mobile-first continuity," and the admin surface as "a
dense operational console with scan-first hierarchy, hard audit edges, compact
queue states, and restrained color." These two theses explain almost every
density, color, and motion decision downstream — the customer shell trades
density for calm; the admin shell trades calm for scan speed.
For the customer-facing IA itself (Tara, Arete, Veritas, Nyx, Nisaba, Metis and the cross-domain journeys), see the per-domain pages such as Tara — Rituals and Contemplative Practice and Nisaba — Scholarly Study; the shell-level surfaces are detailed in Product Surfaces.
Design tokens — the canonical foundation#
libs/oshun/design-tokens/src/tokens.ts is the single source of truth for the
visual language. The canonical bundle is identified as
OSHUN_V1_FOUNDATION_TOKEN_BUNDLE_ID = 'oshun-v1-foundation' at version
OSHUN_V1_FOUNDATION_TOKEN_BUNDLE_VERSION = '1.0.0', exported as the
oshunV1Foundation object.
Color#
The canonical V1 surface is a cool, dark ink/teal-and-gold system, not a
warm paper palette. oshunTokenSchema.color is built from six full 50–950
scales:
| Role | Scale | Anchor values |
|---|---|---|
| Neutral | ink |
ink[500] = '#6E87A6', ink[950] = '#040B16' |
| Neutral | fog |
fog[500] = '#7386A2', fog[950] = '#0D1628' |
| Brand | aqua |
aqua[500] = '#20C9D8', aqua[600] = '#11A9B8' |
| Brand | amber |
amber[500] = '#F4A524', amber[600] = '#DD8618' |
| Status | success |
success[500] = '#2AB673' |
| Status | danger |
danger[500] = '#E24D4D' |
The default theme is dark: defaultOshunTheme = oshunThemes.dark, and
oshunThemes provides all four named themes from OshunThemeName — light,
dark, highContrastLight, and highContrastDark. Theme resolution helpers
(getSemanticTokens(), createCssVariables()) default to the dark theme, and a
high-contrast resolver maps a "prefers high contrast" hint onto the
highContrastLight/highContrastDark variants.
Correction to older docs. Earlier framing (e.g.
V1/ARCHITECTURE.mdaround the Design System section) described the canonical surface as "cream-paper + terracotta." That is inverted. In the real tokens, cream-paper and terracotta are the manuscript palette used only for the domain accents, which the code itself describes as being "mapped into the Lilith register." The canonical neutrals/brand are the darkink/fogandaqua/ambersystem above.
Domain accents (the "Lilith register" / manuscript palette)#
The domain accent hues live under oshunTokenSchema.color.domain (also exported
as oshunDomainAccents), and the source comment explains the intent directly:
each domain gets "a distinct hue from the manuscript palette … so the sidebar
reads as the same cream-paper-and-ink language as the rest of the surface."
| Domain | Accent hex | Manuscript name |
|---|---|---|
tara |
#5A7A3F |
Lilith green |
veritas |
#9A3E1C |
terracotta / burnt rust |
nyx |
#3B3325 |
ink-2 |
arete |
#3F5E2B |
deep green |
nisaba |
#C89657 |
honey / tan |
metis |
#6B5A44 |
tan-brown |
How these accents may be used is governed separately by
oshunDomainAccentBehavior, so the accent is a constrained signal (sidebar,
selection, domain header) rather than a free paint color. The translated
contemplative variants are applied at the persona-policy boundary — see
Lilith Persona Policy and
Persona, Avatar, and Voice Packs.
Typography, spacing, motion, elevation#
The non-color foundation tokens are exported as first-class constants:
oshunSpacingScale— the numeric step scale that the semantic spacing tokens (xxs … 3xl) index into.oshunFontWeights(regular,medium,semibold,bold,extrabold) andoshunTypographyRamp, with the type familiesSpace Grotesk/Manrope(display),Manrope/Avenir Next(body), andIBM Plex Mono(mono). The ramp runsdisplayXl(48/56) down throughlabelSmandmonoSm.oshunMotionDurationScaleandoshunMotionTokens(duration, easing, distance, scale) — motion is a token, so reduced-motion parity can be expressed by swapping tokens rather than rewriting components.oshunElevationTokens— a named shadow ramp (none,xs,sm,md,lg,xl,inner).- Component radius ceilings:
radius.sm = 8…radius.pill = 999. The experience-quality rules pin an "8px component radius ceiling" so the system stays calm rather than bubbly.
Behavior tokens — the part most design systems leave to convention#
The distinctive part of design-tokens is that interaction behavior is itself
tokenized, not just appearance. These exported behavior objects encode the rules
for the trust-and-honesty surfaces V1 cares about most:
oshunGroundedEvidenceUiBehavior— how evidence cards, source counts, and confidence bands present (pairs with Sophia Grounding).oshunDisclosureUiBehavior— where and how AI disclosure appears.oshunAssistantPersonaSwitchingUiBehavior— how a persona switch is signaled.oshunAvatarVoiceIdentityUiBehavior— avatar/voice identity affordances.oshunTrustSignalUiBehavior— trust/confidence/provenance badges.oshunReviewApprovalUiBehaviorandoshunAdminStateUiBehavior— review decisions, approval states, queue/severity/SLA states for the admin console.
The component library (@oshun/ui)#
libs/oshun/ui/src/index.ts re-exports three subpackages: components/,
motion/, and theme/. The component layer ships 21 real React components,
not a placeholder barrel:
| Group | Components |
|---|---|
| Primitives | Box, Stack, Text, Button, IconButton, Chip, Badge |
| Data display | Card, ListRow, StatTile |
| Navigation | TopBar, BottomNav, DomainSwitcher, CommandPalette |
| Feedback | Banner, Toast, EmptyState, ErrorState |
| Overlays | Modal, BottomSheet, ActionSheet |
Each group has a paired .stories.tsx and .test.tsx (primitives,
data-display, navigation, feedback, overlays), and the whole surface is
exercised by accessibility-snapshots.test.tsx, which asserts the rendered
accessibility tree — so a regression that strips an accessible name or focus
affordance fails CI rather than slipping into a release.
Richer, domain-specific composites (evidence sidebar, claim/source/passage
items, notebooks, collections, admin queues, policy diffs, avatar/voice cards)
are tracked as catalog requirements (next section) and implemented across
@oshun/ui and the web design-system package.
Design-language audit modules (@oshun/design-language)#
This package turns design rules into queryable, testable data — the mechanism
that lets V1 claim design-system completeness without manually re-reading every
component barrel. libs/oshun/design-language/src/index.ts re-exports ten audit
modules, each versioned and each with a sibling .test.ts:
| Module | Key export | What it encodes |
|---|---|---|
component-catalog.ts |
OSHUN_COMPONENT_CATALOG (component-catalog-v1) |
Maps each required component to its canonical export, implementation path, test path, customer/admin scope, and required a11y checks |
scorecards.ts |
OSHUN_SURFACE_SCORECARDS, OSHUN_IMMERSIVE_VS_INSTRUMENTAL |
Surface-by-surface quality scorecards; immersive-vs-instrumental guidance |
ergonomics.ts |
OSHUN_THUMB_ZONE_MODEL, OSHUN_DENSITY_TIERS, OSHUN_ERGONOMIC_BUDGETS, OSHUN_ONE_HANDED_SURFACE_CONTRACTS |
One-handed mobile thumb zones, layout-density tiers, ergonomic budgets |
responsive-system.ts |
OSHUN_BREAKPOINTS, OSHUN_CONTENT_MEASURE, OSHUN_READING_RHYTHM |
Grid/gutter/max-width, reading measure and rhythm |
surface-language.ts |
OSHUN_IMAGERY_RULES, OSHUN_ILLUSTRATION_RULES, OSHUN_TEXTURE_RULES, OSHUN_AMBIENT_MEDIA_RULES, OSHUN_CARD_AVOIDANCE_RULES |
Imagery/illustration/texture/ambient-media and the card-avoidance rules |
voice-and-tone.ts |
OSHUN_VOICE_TRAITS, OSHUN_PROHIBITED_COPY, OSHUN_VOICE_DO_DONT_PAIRS, OSHUN_ACCESSIBILITY_TONE_POLICIES |
The voice traits and prohibited-copy patterns, with do/don't pairs |
ai-disclosure-copy.ts |
OSHUN_DISCLOSURE_COPY, OSHUN_DISCLOSURE_SURFACE_RULES, OSHUN_AI_DISCLOSURE_PREFERRED_TERMS, OSHUN_AI_DISCLOSURE_BANNED_TERMS |
Canonical AI-disclosure copy and the terms you may/may not use |
failure-copy.ts |
OSHUN_FAILURE_TEMPLATES, OSHUN_INCIDENT_TITLES, title/body token budgets |
Error/outage/fallback copy with word/sentence budgets |
visual-qa.ts |
OSHUN_QA_VIEWPORTS, OSHUN_VISUAL_QA_CLAIMS (playwright-visual-qa-v1) |
The Playwright visual-QA checklist and viewport matrix |
completion-audit.ts |
OSHUN_29X_COMPLETION_REQUIREMENTS |
The 29.X design-system requirement audit |
Why a catalog instead of "just look at the code"#
component-catalog.ts exists, per its own header, so "completion can be
verified without manually reading barrels."
OSHUN_REQUIRED_COMPONENT_REQUIREMENTS enumerates the 22 required reusable
components from the feature list — domain-switcher, continuity-card,
evidence-card, evidence-sidebar, claim-item, source-item,
passage-item, notebook, collection, assistant-disclosure,
memory-state, provenance-badge, admin-queue, admin-filter,
incident-severity, sla-timer, review-decision, policy-diff, avatar,
voice-pack, rights-summary, license-summary — grouped into navigation,
continuity, evidence, library, assistant, admin, policy,
embodiment, and rights. Each OshunComponentCatalogEntry records its
canonicalExport, implementationPath, testPath, whether it appears in the
customerShell and/or adminShell, and the requiredA11yChecks (from
accessible-name, keyboard, focus-visible, semantic-state,
screen-reader-copy). A coverage function can then assert that every
requirement is met — turning "we have a component library" into a
machine-checked claim.
Accessibility, copy, and ergonomics as first-class rules#
The OSHUN_EXPERIENCE_QUALITY_RULES object fixes the non-negotiables:
- Accessibility:
visible focus,reduced motion parity,high-contrast tokens,screen-reader labels. The high-contrast token requirement is satisfied by thehighContrastLight/highContrastDarkthemes; reduced-motion parity is expressed throughoshunMotionTokens. - Disclosure:
body-copy disclosure,provenance link,confidence band,source count— the AI-honesty quartet, backed byoshunDisclosureUiBehaviorand theOSHUN_DISCLOSURE_COPY/OSHUN_AI_DISCLOSURE_BANNED_TERMSrules. - Layout:
8px component radius ceiling,no nested cards,stable control dimensions,Tara-first home ordering— the card-avoidance rule is enforced bysurface-language.ts, the ordering byassertSurfaceUsesTaraLanguage(). - Mobile:
one-handed primary actions,large tap targets,offline read fallback,handoff continuity— the thumb-zone model and one-handed surface contracts inergonomics.tsmake this checkable per surface.
The copy rules deserve emphasis because they are the part most easily faked. AI
disclosure copy is canonical (OSHUN_DISCLOSURE_COPY) with explicit
OSHUN_AI_DISCLOSURE_PREFERRED_TERMS and OSHUN_AI_DISCLOSURE_BANNED_TERMS, so
a surface cannot, for example, call a generated answer "verified" when it is
"AI-assisted." Failure/outage copy is bounded by token budgets
(OSHUN_FAILURE_TITLE_TOKEN_BUDGET = { minWords: 3, maxWords: 6 },
OSHUN_FAILURE_BODY_TOKEN_BUDGET = { minSentences: 1, maxSentences: 2 }) so
error states stay short, calm, and non-shaming under stress — the moment users
most need plain language.
Localized strings and formatting (@oshun/i18n)#
Localization is part of the design system, not an afterthought, because text
length and direction reshape layout. libs/oshun/i18n/src/index.ts is the
canonical catalog. (The web app layers next-intl on top —
apps/oshun/web/src/i18n/config.ts defines
locales = OSHUN_LAUNCH_LANGUAGE_PREFERENCES and derives rtlLocales from
RTL_LOCALES — but the shared catalog underneath is what guarantees coverage
and fallback.) For the full localization story see
Taxonomy, Localization, and Versioning;
the design-system-relevant facts are:
- Eight launch locales.
OSHUN_LAUNCH_LOCALES = ['en-US','es-US','fr-FR', 'de-DE','ar','he','ja-JP','pt-BR'], withOSHUN_DEFAULT_LAUNCH_LOCALE = 'en-US'andRTL_LOCALES = {ar, he}.localeDirection()returns'rtl'for Arabic and Hebrew so shells flip rather than break. - Text-expansion budgets drive layout QA.
LOCALE_EXPANSION_BUDGETrecords, per locale, how much longer than theen-USbaseline a string may run while still fitting the same shell:de-DE 1.4(the widest),fr-FR 1.3,pt-BR 1.3,es-US 1.25,ar 1.2,he 1.15, andja-JP 0.7(the only one that contracts). Layout QA verifies ade-DElabel at 1.4x does not truncate or break a grid column. - A complete working catalog, not just "externalized strings."
CUSTOMER_MESSAGESis a frozen map of customer-facing keys — covering shell navigation, AI disclosures, memory state, evidence/provenance, offline states, errors, status, auth, and privacy — fully translated across all eight locales. The catalog is keyed message-first then locale-second precisely so per-key audits ("which locales does this key cover?") are trivial. - Translation with a defined fallback chain.
translate(key, locale, options)resolves throughresolveFallbackChain()— requested locale → language-only locale →en-US(soes-UStrieses-US, thenes, thenen-US). It returns aTranslationResultof{ value, resolvedLocale, fallbackApplied }, and emits aTranslationFallbackEventwhen a fallback fired, so gaps are observable in telemetry rather than silent. - Critical messages are flagged.
isCriticalMessageKey()marks any key under the prefixesassistant.disclosure.,evidence.,auth.minimum_version_required, orprivacy.as critical — a fallback on a legally or safety-relevant string (an AI disclosure, a provenance label, a consent notice) is treated differently from a fallback on a nav label. - Gap detection for launch readiness.
findFallbackGaps()walks every key against every locale and returns any<key, locale>pair that resolves via fallback rather than a direct hit — a non-empty result is a translation gap to close before launch. - Locale-aware formatting.
formatForLocale()produces date, time, date-time, timezone, currency, number, region, and relative-time strings using the platformIntl.DateTimeFormat,Intl.NumberFormat,Intl.RelativeTimeFormat, andIntl.DisplayNameswith explicit options. All eight launch locales currently use the Gregorian calendar (LOCALE_CALENDAR); the Japanese imperial calendar is reserved for specific opted-in cultural surfaces.
Visual QA and design review#
Visual QA is encoded, not improvised. visual-qa.ts defines the viewport matrix
OSHUN_QA_VIEWPORTS and a list of OSHUN_VISUAL_QA_CLAIMS
(playwright-visual-qa-v1) that the design-review and Playwright-backed
checklist runs against — covering shell, domain, admin, and the
mobile/desktop/laptop/tablet/narrow-mobile states called for in the feature
list. Those claims feed the broader accessibility and Lighthouse CI coverage
tracked in
Analytics, Observability, Testing, and Security,
which is also where the web performance budgets
(apps/oshun/web/lighthouse-budget.json) and the per-journey automation matrix
live.
Honesty note#
The token, component, i18n, and design-language modules described above are
real, sizeable, tested code in libs/oshun/*. What this page does not
assert is that a full live Lighthouse, axe, or Playwright sweep currently passes
on every route — the budget files and CI-coverage manifests exist, but a green
run is a property of CI at a given commit, not of these source files. Where a
claim is a process gate rather than shipped code, the
analytics-and-testing.md page says so explicitly.
Related#
- Analytics, Observability, Testing, and Security — performance budgets, accessibility/Lighthouse CI, and the QA matrix.
- Taxonomy, Localization, and Versioning — the broader localization, taxonomy, and versioning story.
- Lilith Persona Policy and Persona, Avatar, and Voice Packs — where the translated contemplative register is applied.
- Sophia Grounding — the evidence and confidence model behind the grounded-evidence behavior tokens.
- Product Surfaces — the customer/admin shells the design system renders into.
- Architecture, Platform Foundations, and Security — the companion platform/architecture page.
- ../features.md — feature hub.