Workspace marks
@flung.dev/flungies/marks draws a mark for a workspace, a team or an organisation from its id: a squared tile pressed with one of the brand's patterns, in a two-tone pair, with the workspace's initials on top. People get Flungies, round characters with a face; workspaces get marks, so the two never read as one another.
- Person
usr_8f3k2WorkspaceNorthwind Studio - Person
usr_01hzx3k9qvWorkspaceKestrel Media - Person
usr_7d1c0bWorkspaceLumen Labs - Person
usr_aWorkspaceQuill Agency - Person
usr_bWorkspaceKettle & Co - Person
flungWorkspaceAcme
TL;DR
| Question | Answer |
|---|---|
| How do I install it? | npm install @flung.dev/flungies, the same package as the Flungies. |
| What do I give it? | The workspace's id, which never changes, and its name, for the initials. A rename changes the letters, never the mark. |
| What does it give back? | An SVG string, from workspaceMark(). <WorkspaceMark> draws it in React and <flung-mark> as an element. |
| Where does it run? | Anywhere JavaScript runs: browsers, Node, Cloudflare Workers, Deno and Bun. The SVG needs no DOM. |
| How many are there? | 25,200 trait sets, before the phase that shifts each pattern on top of them. |
| When is it a Flungie instead? | When it stands for a person. A mark is for a workspace, a team, an organisation or anything else that is not someone. |
What a mark is
@flung.dev/flungies/marks draws workspaces. People get Flungies, which are round characters with a face. Workspaces get marks, which are squared objects, so the two never read as one another:
- A squircle with a 22% corner radius, never a circle.
- One of the brand's three patterns, embossed or debossed: tiles, lines or ripples.
- A two-tone pair from the Flungies palette, lit like the brand wash: the ground at the top left, turning toward the tone at the bottom right.
- The workspace's initials in Funnel Display at 750, in a calm zone where the pattern fades out.
- Two tiny speed lines in a corner, sometimes, from 64 px.
Try it
Type a workspace's name and see its mark at every size, with the traits its id picked. It opens on Northwind Studio.
Workspace mark NS: Mint into sky lines
- 16 px
- 20 px
- 24 px
- 32 px
- 48 px
- 64 px
- 96 px
- plain
- Pattern
- Lines
- Colour pair
- Mint into sky
- Finish
- Debossed (pressed)
- Scale
- Medium
- Angle
- −14°
- Line rhythm
- Brand
- Signature
- None
Install
npm install @flung.dev/flungiesUse
Flungies are for people. For workspaces, teams and organisations, @flung.dev/flungies/marks draws a workspace mark: a squircle pressed with one of three patterns (tiles, lines or ripples), in a two-tone colour pair, with the workspace's initials on top. A person is round and a workspace is square, so the two never read as one another.
import { workspaceMark, markTraits, renderMark, markInitials, plainMark } from '@flung.dev/flungies/marks'
workspaceMark(workspace.id, { size: 32, theme: 'dark', name: workspace.name }) // an SVG stringrenderMark(markTraits(workspace.id, { pattern: 'ripples' }), { size: 256, animate: true })markInitials('Northwind Studio') // 'NS'plainMark(workspace.id, { size: 24, name: workspace.name }) // initials on a tint, no patternSeed with the workspace's ID and pass its name for the initials, so a rename changes the letters but not the mark. Under 24 px a mark shows one letter.
| Option | For | Default |
|---|---|---|
size | Pixels. The pattern is bolder under 32 px, and the signature lines and grain appear from 64 px. | 64 |
theme | 'light' or 'dark'. The mark keeps its colours, and gains a rim only where it would melt into the page. | 'light' |
name | The workspace's display name, for the initials. Without it, the initials come from the seed. | none |
initials | 'auto', letters of your own, or false for none. | 'auto' |
grain | false turns the grain off. | true |
animate | A slow light sweep across the relief, from 64 px. Hidden under prefers-reduced-motion. | false |
id | The prefix for the SVG's internal ids, for a server render that a browser hydrates. | a counter |
overrides | Traits to set instead of the seed's ({ pattern: 'lines', pair: 'ocean' }). | none |
salt, palette, patterns | For other products: a salt, your own colour pairs ({ id, label, ground, tone }), and { include } or { exclude } for the patterns. | none |
Marks on a server
import { workspaceMark } from '@flung.dev/flungies/marks'
export default { fetch(request: Request): Response { const url = new URL(request.url) const id = url.searchParams.get('id') ?? '' const name = url.searchParams.get('name') ?? undefined const size = Math.min(512, Math.max(16, Number(url.searchParams.get('size')) || 64)) const theme = url.searchParams.get('theme') === 'dark' ? 'dark' : 'light' return new Response(workspaceMark(id, { size, name, theme }), { headers: { 'content-type': 'image/svg+xml', 'cache-control': 'public, max-age=86400' }, }) },}The initials follow the name, which can change, so cache a mark for a day rather than forever, or put the name in the URL as above.
Marks in React and as an element
import { WorkspaceMark } from '@flung.dev/flungies/react'
<WorkspaceMark seed={workspace.id} name={workspace.name} size={32} /><WorkspaceMark seed={workspace.id} name={workspace.name} size={96} theme="dark" animated />import { defineWorkspaceMark } from '@flung.dev/flungies/element'defineWorkspaceMark() // registers <flung-mark><flung-mark seed="ws_8f3k2" name="Northwind Studio" size="32" theme="dark"></flung-mark>The element takes the attributes seed, name, size, theme, initials (letters, or none), salt and animated. On a page that may not assign innerHTML, append toSvgElement(workspaceMark(...)), which /marks exports too.
Also exported from /marks: MARK_TRAITS and the tables (MARK_PAIRS, MARK_PATTERNS and the rest), markCombinations() (25,200 discrete trait sets), markPalette(), markGeometry() and describeMark(), the accessible name each SVG carries.
Size tiers
A mark is drawn for its size: a small one has fewer, bolder features and one letter, a large one gains the signature, the grain and the sweep.
| Size | What changes |
|---|---|
| Under 24 px | One letter. |
| Under 32 px | The features are 1.55 times larger, so fewer and bolder. The relief is a gradient across each feature, with no offset walls, and the calm zone is smaller. |
| 32 px and up | The relief is three draws of one path: a shaded wall, a lit wall, and a face that wears the ground gradient turned back by the pattern's lean, so only the walls show. The letters get a soft pressed shadow. |
| 64 px and up | The signature and the grain, which is feTurbulence specks sized in pixels. animate adds the light sweep (MARK_SWEEP_MIN). |
The sweep is a soft band, masked to the lit walls, that crosses the tile every 9 seconds in SMIL. A <style> inside the SVG hides it under prefers-reduced-motion, which leaves the still mark.
Colour
- Letters are ink or paper, whichever contrasts more with the pair's midpoint. Every pair gives at least 4:1, as a Flungie's eyes do. The mark is decorative: the name always sits beside it.
- Walls: the lit wall is the ground mixed toward white, and the shaded wall the midpoint mixed toward a deep violet. Dark pairs, with a midpoint luminance under 0.12, mix toward black instead.
- A rim: if the midpoint's contrast with the page is under 1.5, a rim is stroked round the tile, lighter on the dark page and darker on the light one. Ink gets one on dark, and Butter on light.
- The signature uses the brand pair, peach over sky, unless another line pair stands further from the tile in OKLab.
plainMark, the fallback with no pattern, tints the pair's ground 68% toward white (light) or 72% toward ink (dark), and holds its letters at 4.5:1.
The stability promise
A workspace's mark never changes, as a person's Flungie never does: every release is checked against a fixed set of workspaces and the exact SVG each one draws, and a change that would alter one ships behind an option. Only the initials follow the name, so a rename changes the letters on the same mark.
Traits
Every trait draws from a stream of its own, seeded by the id, so overriding one never changes another. The chance is how often an id picks the option; overrides picks it outright.
Patterns
Colour pairs
Finishes
Scales
Angles
Patterns
One of the brand's three patterns, pressed into the tile.
| Option | Id | Chance |
|---|---|---|
| Tiles | tiles | 37% |
| Lines | lines | 31% |
| Ripples | ripples | 31% |
Colour pairs
A ground, a Flungies body colour, turning toward its neighbour on the wheel.
| Pair | Id | Ground | Tone | Chance |
|---|---|---|---|---|
| Peach into coral | peach | #FFA584 | #FF8A72 | 10% |
| Sky into lilac | sky | #86C0FF | #A6ACFF | 10% |
| Butter into peach | butter | #FFD66E | #FFB37A | 7.8% |
| Mint into sky | mint | #8EDDB5 | #86CDE8 | 7.8% |
| Lilac into rose | lilac | #BFA4FF | #E6A2E6 | 7.8% |
| Coral into berry | coral | #FF7E6E | #EE6286 | 7.8% |
| Sand into peach | sand | #DDB27A | #E2885C | 3.1% |
| Cloud into sky | cloud | #D2D5EA | #93B2E8 | 3.1% |
| Ink into plum | ink | #2B2834 | #3A2F57 | 7.0% |
| Ocean into plum | ocean | #3F7EDB | #5A64CF | 7.0% |
| Moss into ocean | moss | #4E9A73 | #3F8A99 | 7.0% |
| Plum into berry | plum | #7457C9 | #9A4FAE | 7.0% |
| Berry into rust | berry | #D2457E | #D25A5C | 7.0% |
| Rust into butter | rust | #C9643B | #D98A3A | 7.0% |
Finishes
Raised or pressed: pressed features swap the lit and shaded walls.
| Option | Id | Chance |
|---|---|---|
| Embossed (raised) | emboss | 58% |
| Debossed (pressed) | deboss | 42% |
Scales
How large the features are, and so how many fit.
| Option | Id | Chance |
|---|---|---|
| Fine | fine | 28% |
| Medium | medium | 41% |
| Bold | bold | 31% |
Angles
The lean of the pattern. 14 degrees is the lean of the mark.
| Option | Id | Chance |
|---|---|---|
| 14°, the brand lean | 14 | 31% |
| −14° | -14 | 20% |
| 0° | 0 | 16% |
| 8° | 8 | 20% |
| 24° | 24 | 14% |
Ripple centres
Where the rings start. Ripples only.
| Option | Id | Chance |
|---|---|---|
| Centre | centre | 11% |
| Top left | topLeft | 14% |
| Top right | topRight | 14% |
| Bottom left | bottomLeft | 14% |
| Bottom right | bottomRight | 17% |
| Left edge | left | 14% |
| Bottom edge | bottom | 14% |
Line rhythms
The run of capsule lengths along each row. Lines only.
| Option | Id | Chance |
|---|---|---|
| Brand | brand | 36% |
| Dash and dot | dash | 24% |
| Long throws | long | 24% |
| Even | even | 17% |
Signatures
Two tiny speed lines in a corner, from 64 px, or none.
| Option | Id | Chance |
|---|---|---|
| None | none | 36% |
| Top right | topRight | 20% |
| Bottom left | bottomLeft | 16% |
| Bottom right | bottomRight | 16% |
| Top left | topLeft | 11% |
Accessibility
A mark is an image with a name: the SVG carries role="img" and an aria-label such as "Workspace mark NS: Mint into sky lines", which describeMark() returns too. The workspace's name almost always sits beside it, so there it is decorative: hide it with aria-hidden="true" on what holds it.
The letters are ink or paper, whichever stands further from the tile, at 4:1 or more. The sweep appears from 64 px only when asked for, and a style inside the SVG hides it under prefers-reduced-motion.