FoundationsUpdated Oct 3, 2026
Branding
Highlight's own mark, from the Highlight 2.0 Brand file. The one logo in the library the system recolours, because it is ours; the third-party marks in the Logo component are shown the way their owners draw them.
Never a copy of the paths, and never the word typed in a heading font: the wordmark's letters are drawn, not set.
import { HighlightLogo } from '@highlight/ui' // The lockup names the product where nothing else does. No children is the full lockup<HighlightLogo size="md" /> // The same lockup, composed. The root sets size and the gap; the parts only draw<HighlightLogo size="md"> <HighlightLogo.Icon /> <HighlightLogo.Title /></HighlightLogo> // The icon stands alone where the word would repeat a title beside it<HighlightLogo size="sm"> <HighlightLogo.Icon /></HighlightLogo> // The wordmark alone, where the symbol is already on screen<HighlightLogo size="sm"> <HighlightLogo.Title /></HighlightLogo> // Not a part: the icon on its yellow square, as the app icon<HighlightLogo.Tile size="md" /> // No tone: currentColor, like a Lucide icon. It follows the text and the theme<HighlightLogo /> // tone pins a fixed colour, for a background the theme doesn't own: a photo, a hero<HighlightLogo tone="dark" /> // always dark<HighlightLogo tone="light" /> // always white<HighlightLogo tone="brand" /> // always brand yellowHighlightLogo is the formatting: it owns the frame height and the 7-in-29 gap between icon and title. HighlightLogo.Icon and HighlightLogo.Title only draw, at the height the root sets, so any arrangement of them keeps the lockup's spacing and letterforms. Both size from the root, so they only belong inside one.
It ships from @highlight/ui, so any app on the package can use it. The product still carries hand-copied versions (HighlightLogoIcon, HighlightIcon, HighlightMacIcon); each one swapped for this retires a copy of the paths.
The lockup names the product. The icon stands alone where the word would repeat a title beside it; the title stands alone where the icon is already on screen. The tile is the icon on its yellow square: the app icon.
LockupIconTitleTileWhich part to reach for, by what is already on screen.
A top bar
The lockup at xs names the product where nothing else on screen does.
import { HighlightLogo } from '@highlight/ui' export default function TopBar() { return ( <header className="bg-background-raised shadow-xs corner-smooth flex w-full max-w-md items-center justify-between rounded-xl px-4 py-3"> <HighlightLogo size="xs" /> <nav className="text-foreground-secondary type-ui-sm flex gap-4"> <span>Chats</span> <span>Meetings</span> <span>Settings</span> </nav> </header> )}A sign-in screen
The heading already says Highlight, so the word would repeat it. The tile leads instead.
Sign in to Highlight
import { HighlightLogo } from '@highlight/ui' export default function SignIn() { return ( <div className="flex flex-col items-center gap-4"> <HighlightLogo.Tile size="lg" /> <p className="type-h3 text-foreground m-0">Sign in to Highlight</p> </div> )}Inside secondary text
No class at all: it takes the colour of the line it sits in, as a Lucide icon would.
Made with
import { HighlightLogo } from '@highlight/ui' export default function Inherited() { return ( <p className="text-foreground-secondary type-ui-sm m-0 flex items-center gap-1.5"> Made with <HighlightLogo size="xs"> <HighlightLogo.Icon /> </HighlightLogo> </p> )}On brand yellow
The background sets the text colour, and the logo inherits it.
import { HighlightLogo } from '@highlight/ui' export default function BrandGround() { return ( <div className="bg-brand text-on-brand corner-smooth flex w-full max-w-md justify-center rounded-2xl py-10"> <HighlightLogo size="lg" /> </div> )}Yellow on dark
Where no brand yellow is in the ground, the mark can carry it.
import { HighlightLogo } from '@highlight/ui' export default function DarkGround() { return ( <div className="bg-background corner-smooth dark flex w-full max-w-md justify-center rounded-2xl py-10"> <HighlightLogo size="lg" tone="brand" /> </div> )}No tone is currentColor, like a Lucide icon: it inherits the text colour and follows the theme. A tone pins one of the brand's three colours for a background the theme doesn't own, named by the colour: dark, light or brand. Any text-* class overrides both.
No toneInherits the text colourtone="dark"tone="light"tone="brand"The brandbook's ramp, by frame height. The tile takes the same names, so a tile and a lockup of one size stand the same height.
Icon and Title size from the root and only belong inside one. Each accepts className and forwards the rest of its props to its svg.
HighlightLogo- A span that lays out the Icon and Title side by side; size sets both and the gap.
HighlightLogo.Icon- The mark alone, two posts and a lens, on a 29 by 29 frame.
HighlightLogo.Title- The drawn wordmark, 92 by 29, set 7 units after the icon.
HighlightLogo.Tile- The icon on its yellow square, the app icon. Standalone, not inside a root: size takes the root's names, className overrides its fill and colour.
Props added on top of the root span.
| Prop | Type | Default | Description |
|---|---|---|---|
size | 'xs'|'sm'|'md'|'lg'|'xl'|'2xl'|number | 'sm' | Frame height, from the brandbook's ramp: 24, 32, 40, 56, 72, 96px, or a number for any other height. Every part sizes from it. |
tone | 'dark'|'light'|'brand' | — | Pins a fixed colour for a background the theme does not own. Omitted, the logo is currentColor and follows the theme. A text-* class overrides it. |
children | ReactNode | Icon + Title | The parts to draw, in order. Omitted, the root renders the full lockup. |