Brand
Everything needed to put the studio’s name on something. Every file here is generated from source by one script, so nothing is out of date and nothing was exported by hand.
01
The mark
One letter, three frames. The M is captured mid-move, like a stop-frame photograph: two ghost frames trail to the left, the present frame is solid and in colour.
It is the name doing the work. Motion is not decorative here, it is the construction.
The M is set in Archivo Black. Frame −2 sits 28% of the M’s width to the left at 22% opacity, frame −1 sits 14% to the left at 50%. Each ghost is knocked out where a later frame covers it, so there is never any overlap blending: three flat shapes, always. The wordmark continues in Archivo Black, with INTERACTIVE in IBM Plex Sans SemiBold tracked to the same width.
Colour: the present frame is vermilion, everything else is ink. Mono versions set the present frame in ink or chalk. The ghosts always take the text colour at their opacity, so the mark inherits its surroundings.
02
Logo
Four variants, four colourways. Use the primary lockup wherever there is room. The symbol carries the brand on its own from 16px up.
SVG for anything that scales, PNG at the listed sizes for anything that does not.
Symbol
Primary lockup
Stacked lockup
Inline lockup
Tiles (avatars)
The symbol on a square tile at 60% width, for anywhere that wants a square or circular image. The 184px size is Steam’s.
Colour
Colour on ink
Mono light
Mono dark
03
Clear space
One stem width on every side, measured from the outermost ink, including the ghost frames.
The stem width of the M. In the symbol's own units that is 203 (the M glyph is 824 wide, 688 tall, at 1000 units per em).
Minimum sizes
- symbol
- 16px tall. Below 24px the ghost frames read as a soft edge, which is fine.
- primary
- 120px wide. Below that use the symbol.
- stacked
- 96px wide.
- inline
- 160px wide.
Rules
- The ghost frames always trail to the left. The M moves right. Never flip the mark.
- Never add more or fewer frames, and never blur them. Three flat frames, always.
- Never rotate, skew or outline the mark.
- On photography or busy backgrounds use mono-light or mono-dark on a chalk or ink tile.
- Do not recolour the ghost frames. They take the text colour at 50% and 22% opacity.
04
Colour
Warm paper, warm black, one signal. Chalk is the default surface, ink is the default text, vermilion is the present frame and nothing else unless it earns it.
No gradients, no tints of vermilion, no dark mode on the site. Dark surfaces use ink with chalk text.
Palette
chalk
#F3EFE6Primary background. Warm paper, never pure white.
chalk-deep
#E6E0D2Surfaces, rules and dividers on chalk.
ink
#141311Primary text and the mono-light mark. Warm near-black, never pure black.
graphite
#4B4842Secondary text on chalk.
ash
#7D786FLarge text, captions over 24px, and rules. Fails AA for body text on chalk, do not use it for that.
vermilion
#E8461EThe signal colour. The present frame of the mark, large display text, and graphic accents. Not body text on chalk.
vermilion-deep
#B52E0AVermilion for text under 24px on chalk. Passes AA.
Pairings
Every text pairing on the site comes from this table. Ratios are WCAG 2.2 contrast, computed from the hex values above. AA needs 4.5:1 for text and 3:1 for large text (24px, or 19px bold) and graphics.
| Sample | Foreground on background | Ratio | Grade | Use |
|---|---|---|---|---|
| Aa | ink on chalk | 16.18:1 | AAA | Body text, headings, the mono-light mark. |
| Aa | graphite on chalk | 7.94:1 | AAA | Secondary text, captions, metadata. |
| Aa | ash on chalk | 3.82:1 | AA large | Large text only (24px+, or 19px+ bold). Rules and dividers. |
| Aa | vermilion-deep on chalk | 5.45:1 | AA | Links and small accent text on chalk. |
| Aa | vermilion on chalk | 3.44:1 | AA large | Large display text (24px+) and graphics only. |
| Aa | chalk on ink | 16.18:1 | AAA | Text on dark surfaces, the mono-dark mark. |
| Aa | vermilion on ink | 4.71:1 | AA | Accent text and the colour mark on dark surfaces. |
| Aa | ink on chalk-deep | 14.11:1 | AAA | Text on raised surfaces. |
| Aa | graphite on chalk-deep | 6.92:1 | AA | Secondary text on raised surfaces. |
05
Type
Archivo Black for the few words that need weight. IBM Plex Sans for every other word. Both are SIL Open Font Licence, so they can ship inside a game.
Self-hosted, latin subset, swapped in on load.
Display
Archivo Black
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789
Headlines and the wordmark. Always set in caps or sentence case, never letterspaced below 40px.
SIL Open Font License 1.1. Source
Body
IBM Plex Sans
ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz 0123456789
Everything else. 400 for reading, 500 for UI, 600 for the INTERACTIVE line and small caps labels.
SIL Open Font License 1.1. Weights 400, 500, 600. Source
Scale
Sizes in rem on a 16px root. Fluid sizes use clamp() between the 360px and 1280px viewports.
text-xsGames with moving parts
0.75rem / 1.5 / 0.02emtext-smGames with moving parts
0.875rem / 1.5 / 0.01emtext-baseGames with moving parts
1rem / 1.6 / 0text-lgGames with moving parts
1.125rem / 1.55 / 0text-xlGames with moving parts
1.25rem / 1.45 / -0.005emtext-2xlGames with moving parts
1.5rem / 1.3 / -0.01emtext-3xlGames with moving parts
2rem / 1.15 / -0.015emtext-4xlGames with moving parts
2.75rem / 1.05 / -0.02emtext-5xlGames with moving parts
3.75rem / 1 / -0.025emtext-6xlGames with moving parts
5rem / 0.95 / -0.03em
- text-display
- clamp(2.75rem, 1.5rem + 5.5vw, 6rem)
- text-title
- clamp(1.5rem, 1.1rem + 1.75vw, 2.5rem)
- text-lead
- clamp(1.125rem, 1rem + 0.5vw, 1.375rem)
Label style
Uppercase · 0.75rem · 0.14em tracking · weight 600
06
Motion
The studio is called Motion, so this is the part that has to be right. The rule is stop-frame: things arrive in discrete steps on an 80ms grid and leave in one.
The full timing of the mark is documented below so it can be rebuilt as a splash screen in any engine.
Principles
- Frames, not fades. Things arrive in discrete steps, like a stop-frame sequence, not a smooth tween.
- The brand runs at 12.5 frames per second. One frame is 80ms. Every duration is a whole number of frames.
- Leave a trail. When something moves, its previous position may linger for a frame or two at reduced opacity, then vanish. That is the mark, in motion.
- Arrive with weight. Continuous motion, where it must exist (hover, scroll), decelerates hard and settles. Nothing bounces, nothing floats.
- Exit fast. Leaving takes half the time of arriving and never trails.
- Motion is optional. With prefers-reduced-motion the finished frame is shown at once. The static design must look intended, not broken.
Durations
- --duration-frame
- 80ms (1 frame)
- --duration-hold
- 160ms (2 frames)
- --duration-step
- 240ms (3 frames)
- --duration-sequence
- 480ms (6 frames)
- --duration-long
- 720ms (9 frames)
Easing
- --ease-strobe-3
- steps(3, end)
- --ease-strobe-2
- steps(2, end)
- --ease-settle
- cubic-bezier(0.2, 0, 0, 1)
- --ease-exit
- cubic-bezier(0.4, 0, 1, 1)
- enter
- Opacity 0 to 1 over 240ms with steps(3, end). Three frames: 33%, 66%, 100%. No transform.
- exit
- Opacity 1 to 0 over 80ms, one frame, no easing. Elements leave, they do not fade.
- hover
- Colour and underline changes are instant (0ms). Position changes, if any, use settle over 160ms.
The animated mark
The animated mark. One M travels from frame -2 to frame 0 in two jumps, leaving a ghost at each position it vacates. The wordmark text then enters in three-step opacity. Total 720ms. Coordinates are in the symbol's own units where the M glyph is 824 wide.
Timeline
| Layer | Property | Keyframes (ms: value) | Easing |
|---|---|---|---|
| frame0 (solid M) | translateX | 0: -230.7 (-0.28 x 824) · 160: -115.4 (-0.14 x 824) · 320: 0 | steps(2, end) over 0-320ms, i.e. hold each position for 160ms |
| frame-2 (ghost, opacity 0.22) | opacity | 0: 0 · 160: 0.22 | step at 160ms |
| frame-1 (ghost, opacity 0.5) | opacity | 0: 0 · 320: 0.5 | step at 320ms |
| OTION | opacity | 320: 0 · 400: 0.33 · 480: 0.66 · 560: 1 | steps(3, end) over 320-560ms |
| INTERACTIVE | opacity | 480: 0 · 560: 0.33 · 640: 0.66 · 720: 1 | steps(3, end) over 480-720ms |
Frame table (for a desktop splash)
Nine states at 80ms each, 720ms in all. Render the lockup at any size, multiply the offsets by (rendered M width / 824), and switch state every 80ms. No tweening between rows. The ghost frames are the ink colour at the given opacity, knocked out where a later frame covers them.
| Frame | t (ms) | M translateX | ghost -2 opacity | ghost -1 opacity | OTION opacity | INTERACTIVE opacity |
|---|---|---|---|---|---|---|
| 0 | 0 | -230.72 | 0 | 0 | 0 | 0 |
| 1 | 80 | -230.72 | 0 | 0 | 0 | 0 |
| 2 | 160 | -115.36 | 0.22 | 0 | 0 | 0 |
| 3 | 240 | -115.36 | 0.22 | 0 | 0 | 0 |
| 4 | 320 | 0 | 0.22 | 0.5 | 0 | 0 |
| 5 | 400 | 0 | 0.22 | 0.5 | 0.33 | 0 |
| 6 | 480 | 0 | 0.22 | 0.5 | 0.66 | 0 |
| 7 | 560 | 0 | 0.22 | 0.5 | 1 | 0.33 |
| 8 | 640 | 0 | 0.22 | 0.5 | 1 | 0.66 |
| 9 | 720 | 0 | 0.22 | 0.5 | 1 | 1 |
Show the finished lockup immediately. No animation.
CSS, verbatim
/* One frame is 80ms. The M holds each position for two frames. */
@keyframes mark-travel {
from { transform: translateX(var(--dx2)); } /* --dx2 = -0.28 x 824 = -230.72 units */
to { transform: translateX(0); } /* steps(2, end): -230.72 for 0-160ms, -115.36 for 160-320ms, 0 at 320ms */
}
@keyframes ghost-2 { from { opacity: 0; } to { opacity: 0.22; } }
@keyframes ghost-1 { from { opacity: 0; } to { opacity: 0.5; } }
@keyframes strobe-in { from { opacity: 0; } to { opacity: 1; } }
[data-layer="frame0"] { animation: mark-travel 320ms steps(2, end) both; }
[data-layer="frame-2"] { animation: ghost-2 160ms step-end both; }
[data-layer="frame-1"] { animation: ghost-1 320ms step-end both; }
[data-layer="otion"] { animation: strobe-in 240ms steps(3, end) 320ms both; }
[data-layer="interactive"] { animation: strobe-in 240ms steps(3, end) 480ms both; }
@media (prefers-reduced-motion: reduce) { [data-layer] { animation: none; } }07
Voice
How the studio sounds in writing: store pages, posts, press emails, patch notes.
Short, confident, a bit dry. British without being twee. We say what we are doing and stop.
Rules
- Short sentences. If a sentence has a comma and an 'and', it is probably two sentences.
- No adjectives you would not say out loud to a friend. Nothing is 'immersive', 'passionate', 'crafted' or 'unforgettable'.
- Say what it is, not what it feels like. 'A card game about tax returns' beats 'an emotional journey'.
- Understate. If it is good, people will notice. If we have to tell them, it is not.
- First person plural is fine. It is one person, but a studio is a 'we'.
- Show the work, skip the hype. Devlogs, clips and an early Steam page are how people find a game, so share them freely. 'Big news soon', countdowns and vague teasers are not, so never post them.
- Dry humour is allowed. Jokes about the industry are not.
Yes
- “Motion Interactive makes games. The first one is in development.”
- “We are based in the West Midlands, which is not a marketing decision.”
- “Something is in development. We will say what when it is worth saying.”
- “Press enquiries: hello@motioninteractive.dev. We read everything and reply to most of it.”
- “The Steam page is up. Wishlisting it helps more than you would think.”
No
- “We are passionate about crafting immersive experiences that push the boundaries of play.”
- “Get ready for a revolutionary new take on the genre.”
- “Big things are coming. Stay tuned!”
- “Join our journey as we build the game of our dreams.”
08
Platform assets
Profile images and headers at each platform’s current recommended size, with content inside its safe area. Regenerated by the same script as everything else.
Sizes are listed with the source they came from. When a platform changes its numbers, change them in one place and re-export.
X

Profile · 400×400PNG
Shown as a circle. The symbol sits inside the inscribed circle.
X recommends 400x400 profile images.

Header · 1500×500PNG
Up to 60px at the top and bottom can be cropped, and the profile image overlaps the bottom-left on desktop. The lockup is centred and stays clear of both.
X recommends 1500x500 headers (3:1).
Bluesky

Profile · 1000×1000PNG
Shown as a circle. Kept under 1MB.
Bluesky avatars are 1:1; 1000x1000 renders sharp on high density screens.

Header · 3000×1000PNG
The avatar overlaps the bottom-left and mobile trims the outer edges. Content stays in the central 60% and upper two thirds.
Bluesky banners are 3:1; 3000x1000 recommended.
YouTube

Profile · 800×800PNG
Shown as a circle.
YouTube recommends 800x800 profile pictures.

Header · 2560×1440PNG
Only the central 1546x423 is visible on every device (TV shows the whole thing, phones show the centre strip). The lockup sits inside that area.
YouTube recommends 2560x1440 with a 1546x423 safe area; minimum 2048x1152.
Steam

Profile · 184×184PNG
The creator homepage avatar. Steam shows it square on a dark UI, so it is a chalk tile.
Steamworks: developer and publisher homepage avatar, 184x184.

Header · 1500×220PNG
A background strip. Steam fades the left and right edges and overlays the avatar and studio name on top, so this carries no logo, just the ghost frames as texture on ink.
Steamworks: developer and publisher homepage header background, 1500x220, edges faded automatically.
09
Tokens and kit
The whole system as data, and everything above in one archive.
tokens.json
Colour, type, space, motion, logo rules and voice, for any stack.
Downloadtokens.css
The same tokens as CSS custom properties in a Tailwind @theme block.
DownloadFull kit
Every logo, tile, platform asset and token file. 1.2 MB.
Download zip
Regenerate everything with npm run brand. Source: brand/tokens.json, scripts/lib/compose.ts, scripts/build-brand.ts.