Brand system

Menuframer logo

The mark, badge, wordmark, and colour tokens — rendered from components/brand/logo.tsx. Import the components; the SVG exports are for surfaces that can’t run React (email, print, third parties).

LogoMark

The monogram, on its own. It fills with currentColor, so it inherits the surrounding text colour and adapts to light and dark without a variant. Size it with a size-* utility.

import { LogoMark } from "@/components/brand/logo"

<LogoMark className="size-8" />          // inherits text colour
<LogoMark className="size-8 text-primary" />  // or tint it

LogoBadge

The mark inside a self-contained dark badge with its own background and border. Use it as an app icon, on photography, or on any surface where a bare mark wouldn’t hold contrast. Colours are fixed — it does not follow the theme. It backs the favicon and the marketing header.

import { LogoBadge } from "@/components/brand/logo"

<LogoBadge className="size-9" />

Logo / LogoWordmark

Mark + wordmark. Logo wraps it in a link; LogoWordmark is the bare lockup for use inside a trigger. The wordmark carries the same flowing motion as the marketing accent.

MenuframerMenuframerMenuframer
PropTypeDefault
size"sm" | "lg""sm"
mark"simple" | "badge""simple"
withWordmarkbooleantrue
href (Logo)string"/"
import { Logo } from "@/components/brand/logo"

<Logo />                          // sm, simple mark, links to /
<Logo size="lg" mark="badge" />   // marketing header lockup

Sizing

Two lockup scales. Below 20px the mark’s loops start to merge — use the badge instead of the bare mark at favicon sizes.

ScaleMarkBadgeWordmark
sm28px32px15px
lg32px36px20px

Colour tokens

The chrome uses the standard shadcn semantic tokens, defined in app/globals.css and resolved per theme. Reference the token, never a hex. A restaurant’s own accent colour is set per-tenant at runtime, so it isn’t a brand token.

TokenUsage
--background
Page background
--foreground
Body text
--primary
Primary actions, brand chrome
--primary-foreground
Text/icons on --primary
--secondary
Secondary surfaces and buttons
--muted
Subtle fills and section backdrops
--border
Hairlines and dividers

Constraints

  • Colour comes from the parent. The mark and wordmark are currentColor— set it with a text utility; don’t hardcode a fill.
  • Minimum mark size 20px; use LogoBadge below that.
  • Clear space= half the mark’s height on every side.
  • Don’t rebuild the lockup by hand or restyle the badge — import the component so spacing and motion stay consistent.

Static exports

SVG files for non-React surfaces. Everything above is the source of truth.

Menuframer Badge

Badge

Contained mark, 128px.

SVG
Menuframer Lockup

Lockup

Mark + wordmark.

SVG
Menuframer Mark (mono)

Mark (mono)

Single-colour path.

SVG