Skip to main content

Rolter’s identity is one idea carried through everything: a cross-stitch. The mark is stitched, the ornament is stitched, and the two reds are the ones a folkloric embroidery actually uses. This page is the contract for anyone placing that identity somewhere — a README, a conference slide, an integration listing, a blog post about running Rolter.

Everything here is already in the repository. The mark is assets/logo.svg, the colours are tokens in ui/src/index.css, and the type ships from node_modules. Nothing needs downloading, and nothing here resolves to a CDN: Rolter has to run air-gapped, and so does anything that represents it.

The mark#

The Rolter mark

The mark is a cross-stitch diamond: 29 rounded squares on a 7-unit grid inside a 63 × 63 viewBox, in two reds. The bright red draws the outer lattice and the single centre stitch; the darker red fills the ring between them. That split is what makes it read as embroidery rather than as a pixel grid, so neither red may be dropped or recoloured independently.

Fileassets/logo.svg (also vendored at docs/user-docs/logo.svg and ui/public/logo-mark.svg)
Geometry29 rects, 6.2 × 6.2 with a 1 corner radius, pitch 7, viewBox="0 0 63 63"
Colours17 stitches #ff4017, 12 stitches #b41d21
Backgroundnone — the mark is transparent and takes the surface under it

Clear space#

Keep one stitch pitch of empty space on every side — that is 7 units in the mark’s own coordinates, or ⅑ of the rendered width. At a 63 px mark that is 7 px; at a 180 px mark it is 20 px. Nothing enters that margin: no wordmark, no rule, no card edge, no other logo.

The clear space is a minimum, not a target. On a title slide or a social preview, give it far more.

Minimum size#

24 px for the mark on screen, 8 mm in print. Below that the 0.8-unit gaps between stitches close up and the diamond fuses into a blob — the one thing the mark is not allowed to become. Where you need something smaller, use the favicon (ui/public/favicon.ico / favicon.svg), which is drawn for that size, rather than shrinking the mark further.

Light and dark#

docs/user-docs/docs.json points logo.light and logo.dark at the same /logo.svg, and that is deliberate, not an oversight. The mark is red-on-transparent, and both reds carry their shape on a light and a dark surface:

Stitch colourOn #ffffffOn --surface-base #111113
#ff4017 --red-5003.50:15.38:1
#b41d21 --red-folk6.69:12.82:1

The folk red is the weaker of the two on dark, but it never carries the silhouette: it only fills stitches held inside the bright-red lattice, so the mark’s outline is a 5.38:1 shape on the dashboard surface. There is therefore no logo-dark.svg, and adding one would fork a file that does not need forking. If a future mark ever puts --red-folk on the outer edge, that conclusion changes and the files split.

Do not place the mark on a mid-tone: between roughly #606060 and #a0a0a0 both reds fall under 3:1. Put it on a light surface, on the graphite family, or in its own clear-space panel.

Colour#

Two reds, and they are not interchangeable.

TokenValueRole
--red-500#ff4017The accent. Interactive and attention colour: the active nav marker, a focus accent, the mark’s lattice, the one rule on a hero.
--red-folk#b41d21The folkloric red. Ornament only: the вышивка rule, the mark’s inner stitches, a chart series. Never a label, never a link.

--red-folk is 2.82:1 on the dashboard surface, which is under the 4.5:1 floor for text. When brand red has to be text, use --red-folk-text (#ff5a3c, 6.09:1) — the same family lifted until it reads. The full set, including --red-600, --red-700, --red-tint and --red-tint-strong, is in ui/src/index.css.

Red is a seasoning. On any given surface it should account for a few percent of the pixels: one accent, one ornament, and graphite for everything else. A wall of #ff4017 is off-brand even though every pixel of it is on-palette.

The neutral ground is the zinc ramp — #111113 (--surface-base), #18181b (--surface-app), #1f1f23, #27272a — with #fafafa for primary text. Take these from the tokens; never re-type a hex.

The вышивка ornament#

.vyshivka-rule in ui/src/index.css is the cross-stitch band: a 10 px checkerboard of two offset 45° gradients in --red-folk. .vyshivka-dots is its quieter dotted sibling, for dividers.

It is a ceremonial device. It marks a threshold — a moment where somebody arrives, is welcomed, or is handed something — and it loses all of that if it turns into a decorative border.

Appropriate

  • Ceremonial surfaces: the sign-in card (ui/src/pages/Login.tsx) and the invitation acceptance card (ui/src/pages/AcceptInvite.tsx), where it runs full-bleed across the top of the card at full strength.
  • Brand surfaces: a title slide, a README header, the social preview image — one band at one edge.
  • As a whisper elsewhere: ScreenHeader runs it at 0.28 opacity, and EmptyState uses a 64 px stub of it. Both are deliberately faint.

Not appropriate

  • More than one or two instances on a screen. It is punctuation, not texture.
  • Around a data surface: tables, charts, log drawers, forms, dialogs. It competes with the thing the operator is reading.
  • As a page background, a full-screen tile, or a frame around content.
  • Recoloured. It is --red-folk, always. A green or blue вышивка is not the ornament with a different hue, it is a different ornament.
  • Animated, rotated, or scaled off the 10 px tile.
Note

“Вышивка” is Russian for embroidery. The class name is kept in the original because the motif is a specific folk tradition rather than a generic cross-hatch, and naming it that way is a reminder of where it came from.

Type#

Geist for everything, Geist Mono for anything a machine wrote: model ids, keys, JSON, logs, CLI output.

Both ship as @fontsource-variable/geist and @fontsource-variable/geist-mono and bundle into ui/dist/assets/*.woff2 at build time. They are never fetched from Google Fonts or any other font service — that would break the air-gapped guarantee on the first page load. If you are producing an asset outside this repository, take the .woff2 files from node_modules/@fontsource-variable/ and embed them.

The stacks are --font-sans and --font-mono. Fall back to the system UI sans and to ui-monospace only where Geist genuinely cannot be embedded; never substitute Inter, Roboto or Arial, which flatten the wordmark’s distinctive t and r.

The wordmark is the word rolter, set in Geist SemiBold, lowercase, with tight tracking (-0.04em at display sizes). It is lowercase everywhere, including at the start of a sentence in UI copy and in the browser tab title. Prose in this documentation capitalises it as “Rolter” for readability; the mark and the wordmark do not.

Social preview#

docs/user-docs/images/og.png is the 1200 × 630 preview used for the documentation site and the repository. Its source is assets/og.svg, and ui/scripts/render-og.ts rasterises it with the bundled Chromium and the bundled Geist, so the PNG can be regenerated byte-for-byte from any checkout:

Edit the SVG, re-render, and commit both. The PNG is also vendored at ui/public/og.png so the dashboard’s own og:image resolves locally instead of pointing at a hosted URL.

Don’ts#

  • Do not recolour the mark, invert it, or render it in a single red.
  • Do not add a gradient, a shadow, a glow, a stroke or a bevel to it.
  • Do not rotate, skew, stretch or squash it — scale uniformly or not at all.
  • Do not put it on a busy photograph, a mid-tone grey, or a red background.
  • Do not enclose it in a circle, a rounded square or any other badge; the diamond silhouette is the containment.
  • Do not rebuild it from the stitches into a different arrangement, and do not animate the stitches individually.
  • Do not set the wordmark in a font other than Geist, and do not capitalise it.
  • Do not lock the mark to another logo without the full clear space between them, and do not build a combined “Rolter × …” lockup.
  • Do not use the mark to imply that Rolter endorses your product. Describing an integration (“works with Rolter”) is fine; a partner badge is not.
  • Do not hot-link any of these assets from a CDN. Copy them into your project.

Licence#

The Rolter source is open, and the mark is not the source. Use it to refer to Rolter — to link to it, document it, or say your project integrates with it — following this page. Do not use it as your own product’s mark, as part of one, or in a way that suggests an official relationship. If you are unsure, open an issue on the repository and ask.