Skip to content
Signal

Brand

Brand integration

How each platform consumes the Signal mark, and which tokens its colours come from.

How the Signal mark fits the design system and how each platform uses it. Usage rules are in BRAND.md.

Where it sits

The brand assets are in brand/signal/ (svg/, png/, manifest.json). They are identity artwork, not a component: no states, no contract in components/, and separate from the transit icons in icons/ (train, bus, train + bus, refresh), which are the app's glyphs. go generate ./... copies the marks the docs site uses into docs/brand/; nothing under platforms/ ships them yet.

Tokens

tokens/tokens.json stays the only colour source of truth. There are no signal.* tokens: every colour in the artwork is already an existing token, listed below with its key in tokens.json, its CSS custom property (platforms/web/tokens.css) and its Swift name (DesignTokens.swift). go test ./... fails if a fill or stroke in brand/signal/svg/ isn't one of these values.

Part tokens.json key CSS Swift Light Dark
Housing fixedColors → alwaysInk --always-black DesignTokens.FixedColor.alwaysInk #101A2E #101A2E
Top lamp lines → blue --blue-line DesignTokens.lineColors "blue" #00A1DE #00A1DE
Middle lamp lines → brown --brown-line DesignTokens.lineColors "brown" #62361B #A8653A
Bottom lamp lines → red --red-line DesignTokens.lineColors "red" #C60C30 #C60C30
Wordmark colors → ink --ink DesignColorToken.ink #101A2E #EEF1F6
Subtitle colors → muted --muted DesignColorToken.muted #5B6472 #98A2B3
Dark keyline colors → ink, dark value --ink in dark DesignColorToken.ink, dark — #EEF1F6

Notes on the mapping the brand package suggested (signal.housing, signal.blue, …):

  • Housing is fixed ink, which already exists as fixedColors.alwaysInk (its CSS name is --always-black for historical reasons). Don't use the theme-aware ink: it turns near-white in dark mode.
  • Lamps use the line tokens' light / dark values, not route (the GTFS colour). They agree for Blue, Brown and Red today except Brown's dark value.
  • Dark keyline has no fixed token. The SVG bakes in ink's dark value. liveBg has the same dark value but means something else; don't borrow it. If the keyline needs to be addressable on its own, add a fixed token (for example fixedColors.alwaysPaleInk) rather than a signal.* group.
  • Typeface is font.family (Figtree). The outlined production SVGs use Inter; see BRAND.md.

The assets are static files with colours baked in, so they don't follow a runtime token change. When one of these tokens changes, re-export the SVGs and PNGs together (the colour test above fails until you do).

Web and the docs site

Pick the variant from the colour scheme. On GitHub and anywhere that follows the OS setting:

<picture>
  <source srcset="brand/signal/svg/signal-lockup-dark.svg" media="(prefers-color-scheme: dark)">
  <img src="brand/signal/svg/signal-lockup-light.svg" alt="Signal — ChiTransit design system" width="320">
</picture>

The docs site serves its copies from /brand/ (/brand/signal-favicon.svg, /brand/signal-mark.svg, /brand/signal-mark-dark.svg) and uses the favicon on every page. A page with its own theme switch should choose the variant from the page theme rather than only prefers-color-scheme.

@chitransit/signal (npm, planned in CTA-212) doesn't ship the brand files. Add them to platforms/web/ through the generator if a consumer needs them.

SwiftUI

The Signal Swift package doesn't ship the brand mark; it isn't app UI. To use it in a docs or about screen, add the SVGs to an asset catalog with "Preserve Vector Data" (or convert to PDF), as SignalLockupLight / SignalLockupDark, or one image set with a dark appearance:

Image(colorScheme == .dark ? "SignalLockupDark" : "SignalLockupLight")
    .resizable()
    .scaledToFit()
    .accessibilityLabel("Signal design system")

Android / Compose

No Android package yet (platforms/android/ is reserved). Convert the mark SVGs to VectorDrawables; they are plain rects and circles and convert cleanly. The outlined lockups convert too but are heavier; the density PNGs are the fallback. Don't assume Compose's ImageVector reads SVG directly.

Hygiene

  • Keep SVGs and their PNG exports in the same commit.
  • Check contrast on the real background, not the artboard.
  • Name the mark once: decorative when visible "Signal" text sits next to it.
  • After a typeface or colour change, compare the PNG previews before and after.