Brand
ReelBolt's identity is a single mark, an outlined wordmark, and the violet palette the marketing
site, dashboard and docs already share. This page is the reference for using them. The masters
live in /brand at the repo root; every app copy is produced from them by one script.
The ReelBolt mark
The ReelBolt mark is a bold, rounded letter R (the "Reel") with a lightning bolt cutting
across its lower right leg. The R is lavender (#C4B5FD), the bolt a brighter violet (#A855F7),
and a thin gap is cut out of the R around the bolt so the two shapes read separately even at
favicon size. It replaced the earlier purple play-triangle square; that mark must no longer
appear anywhere.
The geometry is fixed. Do not redraw, re-weight or re-angle it: always use a file from /brand.
The mark is drawn on a 120 x 120 unit box (viewBox="0 0 120 120"). The R is a 14-unit stroke,
and the bolt is a filled polygon. The ReelBolt app icon is the same mark on a #2E1065 rounded
square (corner radius 28 of 120).
Mark files and where each is used
/brand is the single source of truth for ReelBolt artwork. Edit a master there, then run
node brand/scripts/sync.mjs to copy it into every app (each app builds from its own folder in
Docker, so assets are copied, not referenced).
Master in brand/ | What it is | Used for |
|---|---|---|
app-icon.svg | Mark on a #2E1065 rounded square | Favicons, PWA icons, dashboard logo, docs logo (synced, see below) |
app-icon-maskable.svg | Full-bleed #2E1065 square, mark inside the central 80% | Maskable PWA/Android icons (the OS crops it to any shape) |
mark.svg | The mark alone, full colour, transparent background | Placing the mark on a dark surface or inside a layout |
mark-mono.svg | The mark in currentColor | One-colour use: print, embossing, light surfaces, themed UI |
tray-template.svg | Pure black plus alpha, no colour | Reserved for a macOS runner tray icon (macOS is out of scope below, so nothing currently loads it) |
wordmark.svg | "ReelBolt" outlined in Chakra Petch Bold, currentColor | Text-only placements |
lockup-horizontal.svg | Mark + wordmark, full colour, wordmark in #F5F3F8 | Headers, cards, OG images on dark backgrounds |
lockup-horizontal-mono.svg | Mark + wordmark, all currentColor | One-colour lockup on any background |
app-icon.svg is byte-copied by brand/scripts/sync.mjs to:
site/assets/logo.svgandsite/app/icon.svg(marketing site)web/assets/logo.svg,web/app/icon.svgandweb/public/logo.svg(dashboard)docs-site/static/img/logo.svg(documentation site navbar and favicon)
All six files were already identical when /brand was introduced, so app-icon.svg is the
canonical copy and there is no separate docs-site variant any more.
node brand/scripts/sync.mjs --check exits non-zero if any copy has drifted or is missing. Run it
before committing a change under brand/ or any of the paths above.
Files that intentionally differ
These are not synced, because they are inline code rather than file copies. They draw the same geometry and must be edited by hand if the mark ever changes:
site/components/layout/SiteHeader.tsxandsite/components/layout/SiteFooter.tsx(inline JSX<svg>in eachLockup()).site/app/opengraph-image.tsx(inline<svg>rendered by Satori;twitter-image.tsxre-exports it).web/components/shell/BrandMark.tsx(the dashboard's mark, inline for the app shell and the auth screens). It draws the same geometry asbrand/app-icon.svgbut takes its colours from Mantine's violet ramp (--mantine-color-violet-1/9/6) rather than the master's hexes, so it followsweb/app/theme.ts'sprimaryColor: 'violet'. The colour differs; the geometry does not.site/app/icon.svg-derived PNGs (site/public/favicon-*.png,apple-touch-icon.png,favicon.ico) and the equivalents inweb/public/andweb/app/apple-icon.png; these are rasters generated by each app'snpm run icons, see "Regenerating raster icons".brand/app-icon-maskable.svghas one app copy,site/assets/logo-maskable.svg(synced bybrand/scripts/sync.mjs), whichsite/scripts/generate-icons.mjsrasterizes as-is intosite/public/favicon-512-maskable.png. The dashboard has no copy:web/scripts/generate-icons.mjsbuilds the same thing itself by compositingweb/assets/logo.svgat 80% onto a full-bleed#2E1065canvas. Both manifests label only that PNGpurpose: 'maskable'.
Clear space
Keep an empty margin around the ReelBolt mark equal to 25% of the mark's height on every side (30 units on the 120-unit box). For the horizontal lockup, measure from the mark's height, and keep the same margin around the whole lockup. Nothing (text, other logos, image edges) may enter that margin. The app icon is exempt: its rounded square already carries its own padding.
Minimum sizes
- Mark or app icon: 16 px wide on screen, 6 mm in print. Below that the gap between the R and
the bolt closes up. The 16 px favicon is rendered straight from
app-icon.svg. - Horizontal lockup: 96 px wide on screen, 25 mm in print. Below that, use the mark alone.
- Wordmark alone: 64 px wide on screen.
- Tray icon: 16, 20, 22, 24 or 32 px depending on the platform. The desktop runner's Windows
tray renders
mark.svgat 16–32 px and its Linux tray at 22–24 px; see "Desktop runner icons".
Colour
ReelBolt uses only the existing violet tokens from the marketing site's palette (see
docs/site-design-system.md, "Palette", which owns the contrast audit). No new colour is added
for the brand.
| Role in the mark | Token | Hex |
|---|---|---|
| App-icon background | accent-deep | #2E1065 |
| R (letter) | accent-ink | #C4B5FD |
| Bolt | accent | #A855F7 |
| Lockup wordmark on dark | ink | #F5F3F8 |
| Dark page behind lockups | paper | #0B0B12 |
| Buttons, theme colour, docs primary | accent-strong | #7C3AED |
Rules for the one-colour versions:
- Black (
#000, or#0B0B12) on light backgrounds, white (#F5F3F8or#FFF) on dark ones. - Never violet on violet; if the surface is violet, use the white mono mark.
- The full-colour mark and lockup are for dark surfaces. On a light surface use the mono version, because the lavender R has too little contrast against white.
Desktop runner icons
The ReelBolt desktop runner (runner/, Area E) ships a generated icon pack, not hand-made artwork:
brand/scripts/runner-icons.mjs rasterizes brand/mark.svg and brand/app-icon.svg with sharp and
packs the Windows containers with png-to-ico, writing runner/assets/icons/ plus an
icons.manifest.json that records the sha256 of every master it read and every file it wrote.
Those PNG and ICO files are never to be edited or re-exported by hand — the same rule that covers
every other ReelBolt asset.
Platforms. The runner supports Windows x64 and Linux x64/arm64 (decision D26). macOS is not
supported, so the macOS half of the icon set does not exist: there is no trayTemplate.png, no
[email protected], no macOS status variants and no AppIcon.icns, and nothing depends on
AppKit tinting a file whose name ends in Template. brand/tray-template.svg is kept as the master
that set would use if macOS returns.
The pack (the table in runner/assets/icons/README.md maps every file to the API that loads
it): tray.ico at 16/20/24/32 px for the Windows notification area, one tray-<state>.ico per tray
state, app.ico at 16/24/32/48/64/256 px for the executable and its shortcuts, tray-*.png at
22/24 px for Linux panels, and reelbolt-runner-{256,512}.png for the .desktop entry. The states
are the runner's own (idle, working, paused, error, unpaired); idle is the unmarked
mark.svg and each other state adds a bottom-right badge that differs in shape as well as in
colour (dot, two pause bars, dot, hollow ring), so it stays readable at 16 px.
Badge colour uses only tokens this guide already defines and never recolours the mark: accent
#A855F7 for working, accent-strong #7C3AED for paused and unpaired, and danger #F87171
(the audited error token from docs/site-design-system.md) for error. The badge is cut into the mark
with a transparent gap so it reads on a light or a dark panel; a variant differs from the unmarked
mark only inside that badge.
node brand/scripts/sync.mjs --check verifies icons.manifest.json — a master that changed without
the pack being regenerated, or a file in runner/assets/icons/ edited by hand, both fail the check.
Wordmark and typography
The ReelBolt wordmark is the word "ReelBolt" set in Chakra Petch Bold (700) and converted to
vector outlines, so it renders identically with no font installed. brand/wordmark.svg and the
lockups contain no <text> element. Chakra Petch is licensed under the SIL Open Font License; the
licence text sits next to the font file at brand/fonts/OFL.txt, and outlining glyphs into a logo
is permitted.
Typography around the brand follows the marketing site: Chakra Petch for headings, JetBrains Mono
for labels, code and the "AI video team" tagline (see docs/site-design-system.md, "Typography").
Spell the name as one word with a capital R and B: ReelBolt. Never "Reel Bolt", "Reelbolt" or
"REELBOLT" in running text.
The outlined paths come from brand/scripts/outline-wordmark.mjs, which reads
brand/fonts/ChakraPetch-Bold.ttf with opentype.js, applies kerning from the font plus 12 units
(of 1000 per em) of tracking, and writes wordmark.svg, lockup-horizontal.svg and
lockup-horizontal-mono.svg. Re-run it only if the wordmark text, tracking or lockup spacing
changes: cd brand && npm install && npm run wordmark.
Email
ReelBolt's transactional email is rendered by the Go API (api/services/smtp_service.go, templates in
api/services/email_templates/). Email clients block or half-render SVG, so the templates use one
raster logo, site/public/brand/email-logo.png, served by the marketing site at
https://reelbolt.ai/brand/email-logo.png.
The file is 240 x 48 pixels — the 2x asset for a 120 x 24 CSS box — and shows the horizontal lockup
(the ReelBolt mark plus the outlined wordmark) in #0B0B12, the paper token. It is deliberately
the mono lockup and not the full-colour one: the colour lockup is for dark surfaces and its
wordmark is #F5F3F8, which is invisible on the white card every template draws, and the colour
rules above make the mono lockup the light-surface version. The lockup is contained, never stretched,
and sits flush at the left edge so it lines up with the body copy.
Header snippet. Each template in api/services/email_templates/*.html opens the white card with
this one row:
<tr><td style="font-size:20px;font-weight:700;color:#6d28d9;padding-bottom:16px;">ReelBolt</td></tr>
Replace that row with the ReelBolt logo — the alt text carries the same word the row used to:
<tr><td style="padding-bottom:16px;">
<img src="https://reelbolt.ai/brand/email-logo.png" width="120" height="24" alt="ReelBolt"
style="display:block;border:0;width:120px;height:24px;">
</td></tr>
display:block removes the inline-image baseline gap, and the explicit width/height attributes
keep Outlook from rescaling it — the style pair repeats them for clients that ignore attributes.
At that 120 x 24 box the lockup's ink is about 95 px wide, a hair under the 96 px minimum above; a
template that wants more can declare the same 240 x 48 file at width="130" height="26", which is
still a downscale and not a stretch.
The URL is absolute and hard-coded because MailData in api/services/smtp_service.go carries only a
fixed field set (Name, Link, ExpiresIn, OrgName, InviterName, Role, DeletionDate,
Balance, Unsubscribe, Subject) and Render builds its template data from a whitelist of those
keys, so there is no LogoURL/BaseURL to reference. A ReelBolt instance not served from
reelbolt.ai must add that field to MailData and to Render's field map before the templates can
point at its own origin.
Misuse
Do not, with the ReelBolt mark, wordmark or lockup:
- stretch, squash, skew or rotate it;
- recolour it outside the tokens above, or swap the R and bolt colours;
- add outlines, strokes, drop shadows, glows or gradients;
- place it on a busy photo or on a background that lowers contrast below the sizes above;
- rebuild the wordmark with a live font, or set it in any typeface other than the outlined paths;
- crop the mark, or put it inside another shape other than the supplied app-icon square;
- redraw the mark or use the retired purple play-triangle square (
M180 150L360 256L180 362Zon a 512 canvas, orM9 8.5L19 14L9 19.5on a 24 px canvas).
Regenerating raster icons
SVG masters never need regenerating; PNG and ICO icons do whenever the mark changes. From the repo root:
node brand/scripts/sync.mjscopiesbrand/app-icon.svginto every app location.cd site && npm run iconsandcd web && npm run iconsrasterize those SVGs intopublic/favicon-{16,32,192,512}.png, the Apple touch icon andfavicon.ico(the web script also writesfavicon-512-maskable.png).node brand/scripts/render-email-logo.mjsre-renderssite/public/brand/email-logo.png, andnode brand/scripts/runner-icons.mjsre-renders the desktop runner's icon pack intorunner/assets/icons/(see "Desktop runner icons");node brand/scripts/sync.mjs --checkthen confirms nothing drifted — including that pack, whose generatorsync.mjsre-runs by itself when it is stale.- Update the inline marks listed under "Files that intentionally differ" by hand, then
cd docs-site && npm run buildandcd site && npm run buildto confirm both sites still build.
To eyeball the brand SVGs as PNGs on dark and light backgrounds, run
node brand/scripts/render-previews.mjs <outputDir> (needs npm install in brand/).