Iconography
One set, drawn the same way
Product icons come from Lucide. Brand marks do not. Sizes follow four steps, the stroke stays even across them, and every icon a visitor needs to read carries a text label.
Base set
The base set is Lucide (lucide-react): outlined icons drawn on a 24px grid. Reach for a Lucide icon before drawing anything new.
Brand marks (LinkedIn, YouTube, Stripe and so on) are never Lucide icons. Lucide 1.x dropped brand icons, and a stroked outline is not the trademark. Ship each mark as an SVG component with fill="currentColor" so it takes the surrounding text colour like any other icon.
import { Search } from "lucide-react";
// Product icon: a Lucide outline.
<Search className="size-5" />
// Brand mark: a filled SVG component, not a Lucide icon.
function LinkedInMark({ className }: { className?: string }) {
return (
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" className={className}>
<path d="M20.447 20.452h-3.554v-5.569c0-1.328..." />
</svg>
);
}Sizes
Four steps cover the product. Pick by where the icon sits, not by how much room is left.
Stroke
Lucide draws its stroke on the 24px grid, so the stroke scales with the rendered size. The default of 2 reads as 2px at 24px, thinner at 16px, and heavier at 32px. At size-5 and below keep the default. At 24px and above set strokeWidth={1.5} so large icons stay as light as the small ones beside them.
// 16px and 20px: keep Lucide's default stroke.
<Download className="size-4" />
<Download className="size-5" />
// 24px and above: set the stroke to 1.5.
<Download className="size-6" strokeWidth={1.5} />
<Download className="size-8" strokeWidth={1.5} />Optical padding in buttons
An icon has less visual weight than a run of text, so a button with equal padding on both sides looks heavier on the icon side. The button corrects for this when the icon carries data-icon="inline-start" or data-icon="inline-end". The default and large sizes take 4px off the padding on that side. The small size takes 2px off. The button also fixes every inline icon at size-4, so you do not size it yourself.
// Symmetrical padding. The icon side looks heavier.
<Button variant="outline">
<Search className="size-4" />
Search
</Button>
// data-icon tells the button which side holds the icon.
<Button variant="outline">
<Search data-icon="inline-start" className="size-4" />
Search
</Button>Labels and meaning
Pair the icon with a label on first use
The first time an icon appears on a screen it sits next to its text label. Once a visitor has read the pair, the icon can stand alone in maps, filters and legend rows.
No colour-only meaning
The tinted tile or glow is decoration in the mapped event colour. It is never the only cue. Meaning comes from the icon and its label.
No emoji in product UI
Emoji render differently on every platform and cannot take the theme colour. Use a Lucide icon, or none.
Standard domain mappings
The same nine icons carry the same meanings across maps, filters, legend rows, hero connectors and section labels. Each sits at size-6 in a 48px tile tinted with its event colour. The colour is decorative and is always paired with the label.
Ride systems, attractions, queues, ride access
Sideshow games, skill zones, prize areas
Sessions, talks, expo halls, delegate flow
Stages, shows, entertainment programme
Visitor app, wayfinding, self-service journeys
Admissions, passes, gate control
Cashless spend, top-ups, refunds
Retail stalls, food outlets, settlement visibility
Visitors, delegates, staff views, audience segments