Design Specification — Locomotive | Montreal web agency
| Field | Value |
| Site / Project | https://locomotive.ca/ |
| Analyzed on | 2026-08-20 |
| Analysis mode | Automated code extraction (no AI) |
Overview
This design system was extracted programmatically from the source page. It is built on a light canvas (#FFFFFF), ink text (#000000), a vivid accent (#312DFB). All type is set in "LocomotiveNew",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif. Detected font weights: 400, 600, 700. Detected style signatures: technical / mono accents.
Logo asset(s): https://locomotive.ca/assets/images/favicons/apple-touch-icon.png
Color System
Detected palette (by frequency)
| Hex | RGB | HSL | Count |
#000000 | 0, 0, 0 | 0° 0% 0% | 22 |
#FFFFFF | 255, 255, 255 | 0° 0% 100% | 22 |
#DA382E | 218, 56, 46 | 3° 70% 52% | 5 |
#312DFB | 49, 45, 251 | 241° 96% 58% | 4 |
#F0F4F7 | 240, 244, 247 | 206° 30% 95% | 3 |
#D4DAE0 | 212, 218, 224 | 210° 16% 85% | 2 |
#E9EFF4 | 233, 239, 244 | 207° 33% 94% | 2 |
#CCCCCC | 204, 204, 204 | 0° 0% 80% | 1 |
#007AFF | 0, 122, 255 | 211° 100% 50% | 1 |
#2C2F31 | 44, 47, 49 | 204° 5% 18% | 1 |
#5E6266 | 94, 98, 102 | 210° 4% 38% | 1 |
#30363C | 48, 54, 60 | 210° 11% 21% | 1 |
#EAEFF2 | 234, 239, 242 | 203° 24% 93% | 1 |
#667481 | 102, 116, 129 | 209° 12% 45% | 1 |
#D5DEE2 | 213, 222, 226 | 198° 18% 86% | 1 |
#DEE4E9 | 222, 228, 233 | 207° 20% 89% | 1 |
#E4EAED | 228, 234, 237 | 200° 20% 91% | 1 |
#000002 | 0, 0, 2 | 240° 100% 0% | 1 |
#808080 | 128, 128, 128 | 0° 0% 50% | 1 |
Assigned roles
Roles are taken from the page's own semantic CSS custom properties when present, otherwise inferred from usage frequency + luminance/saturation.
| Token | Hex | RGB | HSL |
--color-primary | #DA382E | 218, 56, 46 | 3° 70% 52% |
--color-accent | #312DFB | 49, 45, 251 | 241° 96% 58% |
--color-background | #FFFFFF | 255, 255, 255 | 0° 0% 100% |
--color-surface | #F0F4F7 | 240, 244, 247 | 206° 30% 95% |
--color-text-primary | #000000 | 0, 0, 0 | 0° 0% 0% |
--color-secondary | #000000 | 0, 0, 0 | 0° 0% 0% |
--color-text-secondary | #D4DAE0 | 212, 218, 224 | 210° 16% 85% |
--color-border | #CCCCCC | 204, 204, 204 | 0° 0% 80% |
--color-on-primary | #FFFFFF | 255, 255, 255 | 0° 0% 100% |
--color-on-secondary | #FFFFFF | 255, 255, 255 | 0° 0% 100% |
--color-on-accent | #FFFFFF | 255, 255, 255 | 0° 0% 100% |
Surface ramp (derived from detected light neutrals)
| Token | Hex |
--color-surface-container-lowest | #FFFFFF |
--color-surface-container-low | #F0F4F7 |
--color-surface-container | #EAEFF2 |
--color-surface-container-high | #E9EFF4 |
--color-surface-container-highest | #E4EAED |
Gradients
linear-gradient(currentColor, currentColor)
linear-gradient(180deg, rgba(0, 0, 0, 0.95) 0%, rgba(0, 0, 0, 0.7) 100%)
linear-gradient(0deg, rgba(255, 255, 255, 0) 0%, white 50%)
linear-gradient(0deg, rgba(218, 56, 46, 0) 0%, #da382e 50%)
linear-gradient(0deg, rgba(0, 0, 0, 0) 0%, black 50%)
Typography
Primary typeface: LocomotiveNew — stack: "LocomotiveNew",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif
Font stacks (most used first)
"LocomotiveNew",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif
inherit
monospace,monospace
ff("primary")
"LocomotiveNew"
"HelveticaNowDisplay",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif
"swiper-icons"
var(--cc-font-family)
-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"
Derived type scale
| Token | Size |
| headline-lg | 32px |
| headline-md | 28px |
| title-lg | 21px |
| body-lg | 17px |
| body-md | 16px |
| label-sm | 12.8px |
Font sizes (by frequency)
| Size | Count |
| 15px | 10 |
| 1em | 3 |
| 17px | 2 |
| 19px | 2 |
| 21px | 2 |
| 2em | 1 |
| 16px | 1 |
| 1.75em | 1 |
| .8em | 1 |
Weights in use: 400, 600, 700
Line heights (by frequency)
| Value | Count |
| 1.2 | 14 |
| 1.3 | 4 |
| 1 | 3 |
| 1.15 | 2 |
| 0 | 1 |
| 1.1 | 1 |
| 1.4 | 1 |
Spacing
Derived spacing scale
| Token | Value |
| xs | 5px |
| sm | 8px |
| md | 16px |
| lg | 42.6666666672px |
| xl | 64px |
Raw values (by frequency)
| Value | Count |
| 1.3333333333rem | 3 |
| 0px | 3 |
| 8px | 2 |
| .67em | 1 |
| .35em | 1 |
| 1em | 1 |
| 2.6666666667rem | 1 |
| 20px | 1 |
| 1rem | 1 |
| .5em | 1 |
| 10px | 1 |
| 5px | 1 |
| .6666666667rem | 1 |
| 4rem | 1 |
Borders & Radius
Derived radius tokens
| Token | Value |
| md | 6.4px |
| lg | 16px |
Raw values (resolved, by frequency)
| Radius | Count |
0 | 4 |
.5rem | 2 |
.4rem | 1 |
4em | 1 |
1rem | 1 |
Shadows
Derived elevation
| Token | Value |
| md | 0 .625em 1.875em rgba(0, 0, 2, 0.3) |
All detected shadows
0 .625em 1.875em rgba(0, 0, 2, 0.3)
Layout
Container max-width: 1024px
Grid columns (largest detected grid): 12
Breakpoints
- 640px
- 699px
- 700px
- 1024px
- 1025px
- 1199px
- 1599px
- 1999px
Animation & Motion
Transitions
background-color .3s cubic-bezier(0.215, 0.61, 0.355, 1)
opacity .9s cubic-bezier(0.215, 0.61, 0.355, 1)
background-size .25s,color .25s ease
transform .2s cubic-bezier(0.215, 0.61, 0.355, 1)
width
opacity .6s cubic-bezier(0.215, 0.61, 0.355, 1)
opacity .25s cubic-bezier(0.215, 0.61, 0.355, 1)
transform .15s cubic-bezier(0.215, 0.61, 0.355, 1)
opacity .15s cubic-bezier(0.23, 1, 0.32, 1),transform 0s cubic-bezier(0.23, 1, 0.32, 1) .15s
Easing curves
cubic-bezier(0.215, 0.61, 0.355, 1)
ease-out
ease-in-out
cubic-bezier(0.23, 1, 0.32, 1)
Keyframes
@keyframes preloaderAppear { 0%{opacity:0;transform:scale(0.9) translate3d(0, 0, 0)}100%{opacity:1;transform:scale(1) translate3d(0, 0, 0)} }
@keyframes swiper-preloader-spin { 0%{transform:rotate(0deg)}100%{transform:rotate(360deg)} }
@keyframes spin { 0%{transform:rotate(0deg)}to{transform:rotate(1turn)} }
@keyframes shake { 10%,90%{transform:translateX(-0.0625em)}20%,80%{transform:translateX(0.125em)}30%,50%,70%{transform:translateX(-0.25em)}40%,60%{transform:translateX(0.25em)} }
@keyframes fall { 0%{opacity:0;transform:scale(0.5);animation-timing-function:ease-out}70%{opacity:1;transform:scale(1.1);animation-timing-function:ease-in-out}to{transform:scale(1);animation-timing-function:ease-out} }
@keyframes featuredProjectsAllFlash { 0%,25%{content:""}26%,50%{content:"🔺"}51%,75%{content:""}76%,100%{content:"🕳"} }
@keyframes lisaDisclaimerFlash { 0%,50%{opacity:1}51%,100%{opacity:0} }
@keyframes lisaDisclaimerProcedure { 0%,50%{text-decoration:underline}51%,100%{text-decoration:none} }
@keyframes lisaLoader { 0%{transform:rotate(0deg)}100%{transform:rotate(360deg)} }
@keyframes lisaCursor { 0%{opacity:1}49%{opacity:1}50%{opacity:0}100%{opacity:0} }
Animations
preloaderAppear .9s cubic-bezier(0.215, 0.61, 0.355, 1) .3s
fall .5s linear .125s both
featuredProjectsAllFlash 2s linear infinite
none
CTA labels found on page
- Let's talk
- The dynasty
- Agency
- Careers
- Subscribe
> Page contains canvas/WebGL elements — consider ambient effects layers.
Source Design Tokens (CSS custom properties)
:root {
--color: #000000;
--color-bg: #FFFFFF;
--font-size: 15px;
--spacing-micro-mobile: 8;
--spacing-micro: 14;
--spacing-tiny-mobile: 20;
--spacing-tiny: 20;
--spacing-small-mobile: 30;
--spacing-small: 30;
--spacing-medium-mobile: 40;
--spacing-medium: 40;
--spacing-large-mobile: 52;
--spacing-large: 80;
--spacing-big-mobile: 80;
--spacing-big: 150;
--spacing-huge-mobile: 100;
--spacing-huge: 200;
--spacing-enormous-mobile: 140;
--spacing-enormous: 250;
--border: solid var(--border-size);
--grid-columns: 12;
--grid-gutter: 20px;
--grid-margin: 2.6666666667rem;
--header-height: 4rem;
--head-padding-vh: 0.25;
--about-head-content-offset-vh: 0.15;
--menu-color: #FFFFFF;
--menu-color-bg: #312DFB;
--font-size-medium: 1.7333333333rem;
--font-size-huge: 7.6388888889vw;
--font-size-h1: 4.6666666667rem;
--font-size-h2: 1.7333333333rem;
--font-size-h3: 1.4666666667rem;
--font-size-h4: 1.3333333333rem;
--font-size-h5: 1.2rem;
--font-size-h6: 1.0666666667rem;
--border-size: 2px;
--swiper-theme-color: #007aff;
--swiper-navigation-size: 44px;
--cc-font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";
--cc-modal-border-radius: .5rem;
--cc-btn-border-radius: .4rem;
--cc-modal-transition-duration: .25s;
--cc-link-color: var(--cc-btn-primary-bg);
--cc-modal-margin: 1rem;
--cc-z-index: 2147483647;
--cc-bg: #fff;
--cc-primary-color: #2c2f31;
--cc-secondary-color: #5e6266;
--cc-btn-primary-bg: #30363c;
--cc-btn-primary-color: #fff;
--cc-btn-primary-border-color: var(--cc-btn-primary-bg);
--cc-btn-primary-hover-bg: #000;
--cc-btn-primary-hover-color: #fff;
--cc-btn-primary-hover-border-color: var(--cc-btn-primary-hover-bg);
--cc-btn-secondary-bg: #eaeff2;
--cc-btn-secondary-color: var(--cc-primary-color);
--cc-btn-secondary-border-color: var(--cc-btn-secondary-bg);
--cc-btn-secondary-hover-bg: #d4dae0;
--cc-btn-secondary-hover-color: #000;
}
Do's and Don'ts
Do
- Do reserve the accent
#312DFB for interactive highlights and key moments — it is used sparingly on the source page.
- Do keep the canvas at
#FFFFFF; surfaces should stay within the detected neutral ramp.
- Do stick to the detected font weight(s): 400, 600, 700.
Don't
- Don't introduce colors outside the detected palette — every hue above was found in the source.
Design Tokens (copy-paste)
:root {
--color-primary: #DA382E;
--color-accent: #312DFB;
--color-background: #FFFFFF;
--color-surface: #F0F4F7;
--color-text-primary: #000000;
--color-secondary: #000000;
--color-text-secondary: #D4DAE0;
--color-border: #CCCCCC;
--color-on-primary: #FFFFFF;
--color-on-secondary: #FFFFFF;
--color-on-accent: #FFFFFF;
--color-surface-container-lowest: #FFFFFF;
--color-surface-container-low: #F0F4F7;
--color-surface-container: #EAEFF2;
--color-surface-container-high: #E9EFF4;
--color-surface-container-highest: #E4EAED;
--font-sans: "LocomotiveNew",-apple-system,BlinkMacSystemFont,avenir next,avenir,segoe ui,helvetica neue,helvetica,Cantarell,Ubuntu,roboto,noto,arial,sans-serif;
--font-size-headline-lg: 32px;
--font-size-headline-md: 28px;
--font-size-title-lg: 21px;
--font-size-body-lg: 17px;
--font-size-body-md: 16px;
--font-size-label-sm: 12.8px;
--radius-md: 6.4px;
--radius-lg: 16px;
--shadow-md: 0 .625em 1.875em rgba(0, 0, 2, 0.3);
--space-xs: 5px;
--space-sm: 8px;
--space-md: 16px;
--space-lg: 42.6666666672px;
--space-xl: 64px;
--container-max: 1024px;
}