MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-1150

8.3.5 Apply the brand mark across the app (shell / auth / email / public chrome / favicon-manifest / OG)

Done
Description

Type: code · Executor: coding_agent · Apply the approved brand mark (8.3.1 + 8.3.2) everywhere the brand is rendered, and ship the full favicon/app-icon set. Today every brand rendering is plain text or an ad-hoc purple M-tile.

The mark is the wave band, approved 2026-08-06 (MOTIR-1140). One <path>, six segments, fill="currentColor"design/brand/wave-band.svg / wave-band-24.svg, derived from design/brand/motir-logo.drawio.svg. design/brand/design-notes.md is the source of truth for every number below; read §1–§9 before starting.

Apply across (surfaces corrected against the §0 renders — see the warning below):

  • App shell — a new brand slot at the extreme left of TopNav's left cluster, before the mobile hamburger, with a hairline divider before ShellTierNav. Mark only, 24 px (§7a). Not SidebarHeader — that is ProjectSwitcher / the create-project CTA and has no room.
  • Auth — horizontal lockup, 28 px, in AuthLayout (not per page) so all five auth screens inherit it (§7b). ⚠️ /device is the exception: its fold budget is measured, so it takes mark-only at 24 px or suppresses the lockup — re-measure it, do not assume.
  • Email — header + sign-off (lib/emailTemplates/_components/EmailLayout.tsx); an <img> with a literal #5645d4, explicit width/height and alt="Motir" — never inline <svg>, never a CSS variable (§7e).
  • Public chromeExploreTopBar takes the horizontal lockup at 26 px, replacing the tile + letter (§7c). PublicTopBar gets a quiet 18 px "on Motir" lockup on the right, before the auth CTAs — its project tile is left alone (§7d); it is project identity, not a brand surface. PublicOverviewHero per §7.
  • OG images — replace the ad-hoc M-tile in app/(public)/explore/opengraph-image.tsx and app/(public)/p/[identifier]/opengraph-image.tsx with the real mark. Two layouts, not one (§6); pass Inter via ImageResponse's fonts option; export const alt must exist on both routes.
  • Favicon / app-icon set — add app/icon.svg, app/apple-icon.png, app/icon-192.png, app/icon-512.png and app/manifest.ts (maskable 192/512); keep favicon.ico as the legacy fallback (§5).

UI subtask — blocked_by the brand-mark design (8.3.1) and the approval (8.3.2). Dark mode is a token choice, not a second asset: the glyph paints currentColor and the lockup sets --el-accent-on-surface (§4).

Acceptance criteria

  • Brand lockup rendered in the shell top bar, auth, email, ExploreTopBar and PublicTopBar, all from a single reusable BrandMark component with variant (lockup | mark | stacked) and size.
  • app/icon.svg, app/apple-icon.png, app/icon-192.png, app/icon-512.png, app/manifest.ts (maskable 192/512) added; favicon set complete.
  • Maskable icons render the glyph at 0.60 × canvas, not 0.66 — the band's extreme point is its bounding-box corner, so 0.66 overflows the 0.8 safe circle and the OS mask clips it (§5). Non-maskable icons use 0.66.
  • The wordmark reads font-family: var(--font-sans-source), … — the raw face variable, never var(--font-sans), which three [data-type] blocks re-point (§3). A wordmark wired to the role token looks correct in review and re-letters itself when a user changes their Appearance pairing.
  • Both OG images render the real mark (no more ad-hoc M-tile), with Inter passed through fonts.
  • Dark-mode variant correct; accessible names follow §8's decorative-vs-informative table — never both an aria-label and a visible wordmark in the same link.
  • Locale brand strings unchanged-by-byte where text remains; build + CI green.

⚠️ This card's original surface list was wrong and has been corrected above. The 8.3.1 renders (§0) established that SidebarHeader has no room for the brand (TopNav's own docstring already reserves the slot) and that PublicTopBar's tile is project identity, not the brand. Build against design-notes.md §7, not against any earlier version of this description.

Context refs

  • blocked_by 8.3.1 (brand mark) + 8.3.2 (approval) — both done
  • design/brand/design-notes.md (source of truth), design/brand/brand-mark.mock.html
  • app/(authed)/_components/TopNav.tsx (§7a — the reserved brand slot)
  • app/(auth)/layout.tsx + _components/AuthShell.tsx (§7b), app/(auth)/device (the fold exception)
  • lib/emailTemplates/_components/EmailLayout.tsx
  • app/(public)/explore/_components/ExploreTopBar.tsx, app/(public)/_components/{PublicTopBar,PublicOverviewHero}.tsx
  • app/(public)/explore/opengraph-image.tsx, app/(public)/p/[identifier]/opengraph-image.tsx
  • app/favicon.ico (legacy fallback to keep)
  • relates_to MOTIR-2267 (trademark clearance — does not block this card)