From 07fdc3c004fcbd7a04ce8d73628f16ca67342c6d Mon Sep 17 00:00:00 2001 From: Hayden Bruin Date: Mon, 24 Aug 2026 21:50:12 +1000 Subject: [PATCH] feat(brand): add the Engine wordmark and figure mark as vector components MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Vector artwork from the brand team, which closes the third gap in ENGINE-DESIGN-SYSTEM.md §12: every mark in this system until now was a raster extraction from deck page images at roughly 29px source, and went soft above 24px. These scale. Two components rather than four. The primary and secondary SVGs are the same geometry with a different `fill` — white for dark surfaces, Off Black for print and inverted panels — so shipping both files would duplicate 3.9KB of path data for one attribute and let the copies drift. One component each, with a two-value `variant`. Colour is that variant rather than `currentColor`, deliberately. currentColor would let any ancestor's text colour become brand colour, and a magenta wordmark is one careless `text-primary` away — the brand allows white and Off Black and nothing else, never outlined, stretched, skewed or recoloured. Constraining it to two named values makes the sanctioned choice the only reachable one. Sizing is height-only by class, with width from the viewBox. The brand forbids distortion and neither 810:1000 nor 2000:449 is a ratio anybody reproduces by hand, so there is no width prop to get wrong. Accessibility follows what the mark is doing. The wordmark carries the company name as its content, so it defaults to title="Engine" and role="img"; the figure mark is decorative by default and gets aria-hidden, so a screen reader does not announce the brand twice when it sits beside naming text. Either can be flipped per instance. Used where the branding already was: the gallery header now carries the wordmark instead of the word "Engine" in mono caps, and the favicon is the figure mark inlined as a data URI — no extra request, and no second copy of the path to drift from the component. New Section 00 shows both marks, both colourways and the scale range. The wordmark being artwork rather than type is the whole reason this belongs in the package: with the vector here, there is no longer any excuse to typeset "engine" in Proxima Nova and hope. --- README.md | 5 ++ package.json | 6 +- src/app.html | 1 + src/lib/components/brand/engine-icon.svelte | 75 ++++++++++++++++ .../components/brand/engine-wordmark.svelte | 86 +++++++++++++++++++ src/lib/components/brand/index.ts | 4 + src/lib/index.ts | 6 ++ src/routes/+page.svelte | 52 +++++++++-- 8 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 src/lib/components/brand/engine-icon.svelte create mode 100644 src/lib/components/brand/engine-wordmark.svelte create mode 100644 src/lib/components/brand/index.ts diff --git a/README.md b/README.md index e0b9da5..01d3078 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,11 @@ shadows, three easings. your bundler fingerprints them out of `node_modules`. You do not need a copy in `static/fonts`. +**Marks** — `EngineWordmark` and `EngineIcon`, vector, in the two sanctioned +colourways (`variant="primary"` white, `variant="secondary"` Off Black). Size +by height alone. The wordmark is artwork, not type — with the vector in the +package there is no reason to typeset "engine" in Proxima Nova again. + **Primitives** — Alert, Badge, Button, Card, Checkbox, Dialog, Input, Label, Popover, Progress, RadioGroup, Select, Separator, Skeleton, Switch, Table, Tabs, Textarea, Tooltip. diff --git a/package.json b/package.json index da63069..1c915bc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@engineio/ui", "version": "0.0.0-development", - "description": "The Engine design system — tokens, fonts and Svelte primitives.", + "description": "The Engine design system \u2014 tokens, fonts and Svelte primitives.", "license": "UNLICENSED", "private": false, "type": "module", @@ -38,6 +38,10 @@ "./components/ui/*": { "types": "./dist/components/ui/*/index.d.ts", "svelte": "./dist/components/ui/*/index.js" + }, + "./components/brand": { + "types": "./dist/components/brand/index.d.ts", + "svelte": "./dist/components/brand/index.js" } }, "scripts": { diff --git a/src/app.html b/src/app.html index 27978f3..e243d03 100644 --- a/src/app.html +++ b/src/app.html @@ -5,6 +5,7 @@ Engine Design System + %sveltekit.head% diff --git a/src/lib/components/brand/engine-icon.svelte b/src/lib/components/brand/engine-icon.svelte new file mode 100644 index 0000000..5d8398e --- /dev/null +++ b/src/lib/components/brand/engine-icon.svelte @@ -0,0 +1,75 @@ + + + + + + {#if title} + {title} + {/if} + + diff --git a/src/lib/components/brand/engine-wordmark.svelte b/src/lib/components/brand/engine-wordmark.svelte new file mode 100644 index 0000000..169752e --- /dev/null +++ b/src/lib/components/brand/engine-wordmark.svelte @@ -0,0 +1,86 @@ + + + + {#if title} + {title} + {/if} + + + + + + + + + diff --git a/src/lib/components/brand/index.ts b/src/lib/components/brand/index.ts new file mode 100644 index 0000000..b3481e5 --- /dev/null +++ b/src/lib/components/brand/index.ts @@ -0,0 +1,4 @@ +import EngineIcon, { type EngineMarkVariant } from "./engine-icon.svelte" +import EngineWordmark from "./engine-wordmark.svelte" + +export { EngineIcon, EngineWordmark, type EngineMarkVariant } diff --git a/src/lib/index.ts b/src/lib/index.ts index 467b35a..2717d96 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -30,6 +30,12 @@ export type { WithoutChildrenOrChild, } from "./utils.js" +export { + EngineIcon, + EngineWordmark, + type EngineMarkVariant, +} from "./components/brand/index.js" + export { Alert, AlertDescription, diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 962b500..4e78e18 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -19,6 +19,8 @@ DialogHeader, DialogTitle, DialogTrigger, + EngineIcon, + EngineWordmark, Input, Label, Popover, @@ -111,11 +113,15 @@
-

- Engine · Design System · {__DS_VERSION__} -

+
+ + +

+ Design System · {__DS_VERSION__} +

+

One system. Every surface.

@@ -127,6 +133,42 @@

+
+ + + + + + + +
+ + +
+
+ +
+ + + + +
+
+

+ Colour is a two-value variant + rather than currentColor on + purpose: with currentColor any ancestor's text colour silently becomes + brand colour, and a magenta wordmark is one careless + text-primary away. Size by + height alone — the brand forbids distortion, and neither the 810:1000 + nor the 2000:449 ratio is one anybody reproduces by hand. +

+
+