Skip to Content
Living documentation — last reviewed 2026-05-28
ArchitectureBrand system

Brand system

How the Taikan identity (brand kit v3.1) is encoded in code, and the rules that keep every surface on it. The design source is the Claude Design project “Taikan Brand Kit v3”; everything in the repos is derived from it.

One source, everything generated

scripts/brand/mark.mjs geometry, palette, ramp, SVG builders ← the source of truth scripts/brand/extract-text.mjs outlines "Taikan" (Rubik 600) + tagline (Assistant 700) scripts/generate-brand-assets.mjs composes + rasterises every output assets/brand/ generated outlines + the asset README
pnpm brand:assets # web, marketing, admin, docs, minisites (+ the React/Astro marks) pnpm brand:assets:all # + the mobile repo (TAIKAN_MOBILE_ROOT, default ../FitKit-mobile) pnpm brand:check # assert every expected output exists

Generated and never hand-edited: apps/*/public/{favicon*,favicons,icons,logo,og-social,ms-tiles}, apps/web/src/components/brand/taikan-mark.tsx, apps/marketing/src/components/ui/TaikanMark.astro, apps/admin/src/components/taikan-mark.tsx, apps/docs/app/taikan-mark.tsx, the mobile assets/images/* and store-assets/{play,appstore} icons and feature graphic.

CI (ci-smoke-tests.yml → “Brand assets in sync”) regenerates and diffs the text outputs, so a palette or geometry edit that was not re-run fails the build.

The mark

A barbell glyph on a 24×24 grid, one closed outline, filled with a vertical teal → violet ramp (#3FE0DC → #2AB8B8 → #3E8FD0 → #8A5CF0 → #6C43D8). Two rules the generator and the components enforce mechanically:

  • Below 32px, ship the flat file. The fillets and shading bands sit near 1u — sub-pixel at 20px. <TaikanMark size={n}> (web, admin, docs), <TaikanMark size={n}> (marketing) and <FKBrandMark size={n}> (mobile) all pick the variant from size, so a call site cannot forget.
  • Alpha-only outputs always use the flat file. Android discards a gradient on the notification icon; MS tiles composite against TileColor; the email letterhead is 18px on a light ground.

And the rules a human still has to enforce:

  • Ramps run vertically only. A diagonal ramp breaks the mark’s left–right mirror and would force a second file for the RTL lockup.
  • The wordmark never takes the ramp. “Taikan” is Rubik SemiBold, tracking −18/1000, solid.
  • Mint #B0E5C4 is not in the ramp. Reserved for PR / streak / today, so success states can’t read as brand chrome. Four colours in the brand, three in the mark.
  • The favicon is the app icon. Same tile, same art fraction, downscaled. A tab glyph that differs from the home-screen icon reads as a different product.

Palette → tokens

RoleLightDarkWeb tokenMobile
Brand teal (graphics, never behind text)#0E8C8C#2AB8B8--brand-tealbrandTeal
Primary action fill#0B7575#2AB8B8--primaryprimary
Ink on primarywhite#0A1628--primary-foregroundonPrimary
Violet — secondary action#7A4BE0#9B6BFF--violetviolet
Ink on violetwhite#0A1628--violet-foregroundonViolet
Violet as text#6C43D8#A987FF--violet-textvioletText
Mint (PR / streak / today)#2E7A4D text#B0E5C4--brand-mint, successsuccess
Ground#F6F8FA#0A1628 (web) · #07202B (mobile, admin, bands)--backgroundbackground

Marketing carries the same values as --color-* in apps/marketing/src/styles/global.css, with on-band remaps inside <Band>.

Two contrast rules that came out of the rollout

The raw brand teal can’t carry white text. White on #0E8C8C is 4.08:1 — below AA. Filled controls use #0B7575 (5.50:1); the raw teal is kept for graphics.

Bright fills on dark grounds take dark ink. White on dark-mode teal #2AB8B8 is 2.43:1; dark ink is 7.46:1. The same holds for violet (#9B6BFF + white 3.53:1, + #0A1628 5.13:1). This is why --primary-foreground flips to navy in .dark — any surface that pairs it with a hardcoded dark background must use text-white explicitly (see the workout drawer header).

Where violet goes

Violet is the secondary action and the colour of the AI surface. Teal stays the primary path.

  • Web: Button variant="violet" | "violet-outline", Badge variant="violet"; “Ask Spotter” in the action center is violet-outline.
  • Marketing: Button variant="violet", Badge variant="violet"; the Spotter section and the AI pillar card are violet, Autopilot event chips are violet.
  • Mobile: violet / violetText / onViolet / violetSoft / violetEdge tokens. No call site yet — there is no Spotter surface in the app.

Typography

Only the wordmark changed: Rubik 600 at −18/1000 (--font-wordmark, TaikanLockup). The product UI keeps Manrope + Clash Grotesk (web), Rubik display + Assistant body (mobile), Heebo for Hebrew. The kit’s tagline “Train. Track. Thrive.” (he: “אימון. מעקב. שגשוג.”, ru: “Тренируйся. Отслеживай. Процветай.”) is used on the OG cards, the Play feature graphic and the mobile splash, one ramp colour per word.

Surfaces and where they are configured

SurfaceConfig
Web favicons, PWA icons, OGapps/web/src/app/[lang]/layout.tsx (generateMetadata), public/manifest.webmanifest, browserconfig.xml
Web auth pagescomponents/brand/auth-frame.tsx; Clerk themed via appearance={{ baseTheme: shadcn }} on ClerkProvider
Marketingcomponents/Head.astro, Navbar.astro, Footer.astro (inline TaikanMark.astro)
Adminindex.html, src/theme.ts, Refine ThemedTitle icon=
Docsapps/docs/app/layout.jsx
Minisites/favicon.ico fallback only — sites are white-labelled per org, never a Taikan favicon.svg
Emailapps/api/src/notifications/templates/theme.ts; letterhead mark is the flat 64px raster
Mobileapp.config.ts (icon, ios.icon.{light,dark,tinted}, android.adaptiveIcon + monochromeImage, expo-notifications.icon, expo-splash-screen)
Store listingsstore-assets/play/ (feature graphic, 512 icon), store-assets/appstore/icon-1024.png; screenshots are captured, not generated

Off-repo surfaces (manual checklist)

These hold a logo or icon that nothing in the repos controls. After a brand change, update by hand: Clerk dashboard (hosted accounts.taikan.fit pages, email logo), App Store Connect + Play Console listings, GitHub org/repo social preview, Sentry / PostHog / Railway / Vercel project avatars, Cloudflare email-routing sender, and the WhatsApp Business profile.