Branding
One config file rebrands every diagram — logo, name, footer note, and links, all inlined so output stays offline.
Everything that is identical across every diagram lives in one file at the
repo root: marrow.config.yaml.
brand:
name: Marrow
note: Proprietary & Confidential
# Single logo or theme-aware dual-variant logos
logo:
light: brand/logo-light.svg
dark: brand/logo-dark.svg
link: https://marrow.network # optional http(s)
github: https://github.com/raiz-toff/Marrow # optional http(s)One edit rebrands everything you build. npm run setup fills it in for you on
a fresh clone.
Where it appears
The sidebar footer, the inspector drawer, and the About modal dialog carry the brand mark too.
Watermarks
Diagrams can display canvas watermarks for classification, client confidentiality, or architectural blueprint labeling. Watermarks are declared directly in the topology YAML:
marrow: 1.0
name: Global Transit Backbone
watermark:
enabled: true
mode: blueprint # off | minimal | subtle | blueprint | full
text: CONFIDENTIAL
opacity: 0.15
font: mono # mono | sans
casing: uppercase # uppercase | preserveWatermark Modes
| Mode | Visual Presentation | Typical Use Case |
|---|---|---|
minimal | fig. 01 — {title} bottom-right blueprint label | Editorial and technical publications |
blueprint | Engineering diagonal CAD stamp with technical framing | Construction & migration blueprinted documents |
subtle | Soft, low-opacity backdrop typography | Security classification without obscuring wiring |
full | High-visibility diagonally repeating canvas watermark | Drafts, NDA reviews, and vendor-restricted distribution |
off | Watermark completely suppressed | Public marketing or documentation sites |
Branding is not per-diagram — on purpose
There are no branding keys in the topology schema, and there is no way to set a company name or a logo from a topology file. A topology describes a network; this file describes who it belongs to. Those are different kinds of fact with different rates of change.
Don't try to add a company name from a topology, and don't re-add a
backdrop: key — it was removed deliberately. The reasoning is recorded in
ADR-0003.
If you genuinely need two different brands, point at a different config:
npm run marrow -- build input/customer-a.yaml --config brands/customer-a.yaml--config works on build, serve, export, and snapshot.
Logos
Give a file path, not a URL. The bytes are inlined at build time so the diagram stays self-contained. Both single file strings and dual-variant light/dark objects are supported:
# Simple string
logo: brand/logo.svg
# Or dual-theme variants
logo:
light: brand/logo-dark-ink.svg
dark: brand/logo-white-ink.svg| Format | How it's embedded |
|---|---|
.svg | Inlined as markup — use fill="currentColor" so it follows the light/dark theme |
.png .jpg .webp .gif | Embedded as a data: URI |
Height is clamped in the chrome (14–20 px depending on position), so any source size works.
Sanitizing
Logo markup is inlined verbatim into every page Marrow builds, so it is sanitized conservatively first. Stripped on sight:
<script>,<iframe>,<object>,<embed>,<link>,<meta>- inline event handlers (
onclick=,onload=, …) - any URL that would reach outside the document
That last rule is what keeps the offline guarantee real. If your logo references an external image, that reference does not survive the build. Problems are reported rather than silently swallowed.
Links
link and github are hyperlinks, never resource loads. The page renders
fully offline; nothing is fetched unless a reader clicks. Both are http(s)-only.
link— the logo and name become a link to it, typically your company site.github— a small source mark beside the brand.
Theme design tokens and link styles
Customize diagram color palettes and physical edge stroke widths by defining a theme: block in marrow.config.yaml. Values map directly to CSS custom properties and Canvas 2D engine render styles:
theme:
dark:
bg: "#0b0f19" # canvas background
panel: "#111827" # inspector drawers and sidebar
accent: "#38bdf8" # selected nodes and primary highlight
up: "#10b981" # interface/device UP status LED
down: "#f43f5e" # interface/device DOWN status LED
light:
bg: "#ffffff"
panel: "#f8fafc"
accent: "#0284c7"
links:
default_stroke: 1.5 # base link thickness in pixels
ten_g_stroke: 2.5 # 10G link thickness
forty_g_stroke: 4.0 # 40G / 100G link thickness
trunk_stroke: 3.0 # VLAN trunk rail thickness
stack_stroke: 5.0 # Switch stack backplane bar thicknessColor values accept hex, rgb(), rgba(), hsl(), hsla(), oklch(), and color-mix(). The configuration parser validates all color entries against CSS injection attacks and enforces positive finite numbers for link stroke widths.
When editing marrow.config.yaml during an active npm run dev session, the server automatically detects file modifications. The build pipeline updates token stylesheets and triggers hot-reloads across connected browsers without restarting the process.
Falling back
Delete a key, or leave it blank, and Marrow uses its own mark. An empty
note: "" means no footer line at all.
Unknown keys in the config produce warnings rather than errors, and x-
prefixed keys are preserved and ignored, same as in topology files.