OpenFactory · Brand system V2
Brand system · V2

OpenFactory

Machine-shop editorial: a sturdy serif and a pale lemon for impact, a clean paper ground and hairline rules for the restraint that keeps it readable. One set of brand colors, a light theme and a dark theme, and no outlines anywhere.

OpenFactory
OpenFactory
Mark: solid square, never rotated

01 / Color

Ink
#14120D

Type and rules in light theme. The page ground in dark theme. Warm black, never pure #000.

Lemon zest
#F6F87E

Poster grounds, pass chips, primary buttons. Ink on top, never white. A filled area only, never type or a thin line on a light ground.

Paper
#FAFDF7

White with a breath of green. The reading ground in light theme; headline and UI type in dark theme.

Tangerine
#FF5A1F

Failure and send-back only, one use per screen. Ink on top as a fill. The send-back text color in dark theme.

Rust
#C2410C

The send-back text shade in light theme, where Tangerine is too bright to read. Never a fill.

Shop
#2A2519

Panels, queue tracks and cards in dark theme. The alternate lockup ground on ink.

Theme roles

RoleLight themeDark themeUsed for
--groundPaperInkPage background
--panel#F1F4EBShopBands, cards, queue tracks, soft buttons
--textInkPaperHeadlines, UI text, the header rule
--text-body#41443B#D2CDBDParagraphs
--text-caption#666A5C#A39D8ACaptions, mono labels
--hairline#DEE3D5#3A3628Section and row dividers
--accentLemon zestLemon zestPosters, pass chips, primary buttons (Ink on top)
--sendback-fillTangerineTangerineSend-back chip (Ink on top)
--sendback-textRustTangerineSend-back reasons in running text
--lockup-altInkShopGround of the second lockup

Contrast

PairingLight themeDark theme
Body text on the page groundAa9.7:1AAAa11.8:1AA
Caption text on the page groundAa5.4:1AAAa6.9:1AA
Caption text on a panelAa5.0:1AAAa5.6:1AA
Ink on Lemon zest (posters, pass chips, primary button)Aa16.6:1AAAa16.6:1AA
Lemon zest as type or a thin line on the groundAa1.1:1Blocks onlyAa16.6:1AA
Ink on Tangerine (send-back chip)Aa6.0:1AAAa6.0:1AA
Send-back text on the page groundAa5.0:1AAAa6.0:1AA
Paper on Ink (ink button, ink lockup)Aa18.2:1AAAa18.2:1AA

WCAG 2 contrast ratios. AA is fine for body text (4.5:1 or more). Large only is for headlines and chips (3:1 or more). Blocks only means a filled area, never type or thin lines on that ground.

02 / Type

Display
Young Serif

Wordmark, posters, section and card titles. Upper and lower case, never all caps. One weight; it reads bold without being black.

Nothing ships unchecked.

Sent back is not failed. It is the line doing its job.

Aa Ee Gg Kk Qq Rr Yy 24680 &?!

Body
Instrument Sans

Arguments, captions, buttons, swatch names. Regular 400, emphasis 600, buttons 700.

Writing code got cheap. Checking it did not. OpenFactory treats every change like a machined part: it moves down a line, gets measured against a tolerance, and either passes the gate or goes back with a reason attached. The type has to stay calm enough to carry that argument for a few hundred words at a time.

Mono
IBM Plex Mono

Labels, hex values, queue data, anything measured. Labels are the only all-caps text in the system.

OF-2293 · image-resize · send-back · tol ±0.02 mm
218 passed · 3 sent back · 98.6% first pass

Scale

Display XL
84px / 1.05 · Young Serif 400

OpenFactory

Display L
56px / 1.06 · Young Serif 400

Nothing ships unchecked.

Display M
36px / 1.1 · Young Serif 400

Sent back is not failed.

Display S
24px / 1.2 · Young Serif 400

Every build passes the gate.

Lede
18px / 1.5 · Instrument Sans 400

A clean paper ground and hairline rules for the restraint that keeps it readable.

Body
16px / 1.55 · Instrument Sans 400

It moves down a line, gets measured against a tolerance, and either passes the gate or goes back.

Caption
14px / 1.45 · Instrument Sans 400

Failure and send-back only, one use per screen.

Button
15px / 1.3 · Instrument Sans 700

Approve part

Label
12px / 1.4 · IBM Plex Mono 400

Line 04 · Inspection

Data
15px / 1.8 · IBM Plex Mono 400

OF-2293 · tol ±0.02 mm · 98.6%

The logo is the solid square plus the word OpenFactory in Young Serif. The SVG files in the logo folder have the letters converted to outlines, so they work without the font installed.

OpenFactory
Lemon lockup · primary, any ground
OpenFactory
Ink lockup · light grounds
OpenFactory
Shop lockup · dark grounds
OpenFactory
Open wordmark, ink · on lemon or paper
OpenFactory
Open wordmark, paper · on ink or shop
OpenFactory mark
Mark alone · favicons, avatars

04 / Components, light and dark

The same screen in both themes. Brand colors never change; only the ground, panels and text shades swap. Blocks are separated by fills, so there are no borders to restyle between themes.

Light themeGround #FAFDF7 · Type #14120D
Line 04 · Inspection

Nothing ships unchecked.

Every build passes the gate or goes back with a reason.

Queue · today
  • OF-2291auth-servicePass
  • OF-2293image-resizeSend-back
  • OF-2294search-indexIn check
218 passed · 3 sent back · 98.6% first pass

Sent back is not failed.

A send-back carries the measurement that missed and the step that caught it, so the fix starts from a fact.

Send-back reason: tolerance out by 0.02 mm

Read the inspection rules

Dark themeGround #14120D · Type #FAFDF7
Line 04 · Inspection

Nothing ships unchecked.

Every build passes the gate or goes back with a reason.

Queue · today
  • OF-2291auth-servicePass
  • OF-2293image-resizeSend-back
  • OF-2294search-indexIn check
218 passed · 3 sent back · 98.6% first pass

Sent back is not failed.

A send-back carries the measurement that missed and the step that caught it, so the fix starts from a fact.

Send-back reason: tolerance out by 0.02 mm

Read the inspection rules

ComponentBuild
Primary buttonLemon fill, Ink text, Instrument Sans 700 at 15px, padding 12 by 18, square corners, no outline.
Ink buttonInk fill, Paper text. Use on Lemon posters, where a Lemon button would vanish.
Soft buttonPanel fill, theme text color. The secondary action next to a primary.
Status chipIBM Plex Mono 11px caps, tracking 0.1em, padding 4 by 8. Pass is Lemon, send-back is Tangerine, in check is Panel.
QueuePanel fill with rows in the ground color, 6px apart. No dividers.
PosterFull Lemon fill, Young Serif headline, one Ink button. No outline.
Keyboard focus2px outline in the theme text color, 2px offset. The only outline in the system, and only while focused.

05 / Layout rules

Spacing

1 · 4px
2 · 8px
3 · 12px
4 · 16px
5 · 24px
6 · 32px
7 · 48px
8 · 64px
9 · 96px

06 / Tokens

This is tokens.css from the package. The same values are in tokens.json in the W3C design tokens format. Dark theme follows the system setting, and setting data-theme on the root element to light or dark overrides it.

/* OpenFactory brand system V2 · tokens */
:root {
  /* brand colors: the same in both themes */
  --ink: #14120D;
  --lemon: #F6F87E;        /* Lemon zest. Ink on top, filled areas only on light grounds */
  --paper: #FAFDF7;
  --tangerine: #FF5A1F;    /* send-back fill, one use per screen, ink on top */
  --rust: #C2410C;         /* send-back text in light theme */
  --shop: #2A2519;

  /* fixed roles */
  --accent: var(--lemon);
  --on-accent: var(--ink);
  --sendback-fill: var(--tangerine);
  --on-sendback: var(--ink);

  /* type */
  --font-display: "Young Serif", Georgia, "Times New Roman", serif;
  --font-body: "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --size-display-xl: 5.25rem;   /* 84px, line-height 1.05, tracking -0.015em */
  --size-display-l: 3.5rem;   /* 56px, line-height 1.06, tracking -0.015em */
  --size-display-m: 2.25rem;   /* 36px, line-height 1.1, tracking -0.015em */
  --size-display-s: 1.5rem;   /* 24px, line-height 1.2, tracking -0.01em */
  --size-lede: 1.125rem;   /* 18px, line-height 1.5, tracking 0 */
  --size-body: 1rem;   /* 16px, line-height 1.55, tracking 0 */
  --size-caption: 0.875rem;   /* 14px, line-height 1.45, tracking 0 */
  --size-button: 0.9375rem;   /* 15px, line-height 1.3, tracking 0.01em */
  --size-label: 0.75rem;   /* 12px, line-height 1.4, tracking 0.12em */
  --size-data: 0.9375rem;   /* 15px, line-height 1.8, tracking 0 */

  /* layout */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --space-7: 48px;
  --space-8: 64px;
  --space-9: 96px;
  --radius: 0;
  --rule: 1px;             /* hairlines divide sections and rows; nothing gets a box outline */
}

/* light theme roles (default) */
:root, [data-theme="light"] {
  --ground: var(--paper);
  --panel: #F1F4EB;
  --text: var(--ink);
  --text-body: #41443B;
  --text-caption: #666A5C;
  --hairline: #DEE3D5;
  --sendback-text: var(--rust);
  --lockup-alt: var(--ink);
}

/* dark theme: follows the system setting... */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --ground: var(--ink);
    --panel: var(--shop);
    --text: var(--paper);
    --text-body: #D2CDBD;
    --text-caption: #A39D8A;
    --hairline: #3A3628;
    --sendback-text: var(--tangerine);
    --lockup-alt: var(--shop);
  }
}
/* ...and data-theme="dark" on the root, or on any container, wins either way */
[data-theme="dark"] {
  --ground: var(--ink);
  --panel: var(--shop);
  --text: var(--paper);
  --text-body: #D2CDBD;
  --text-caption: #A39D8A;
  --hairline: #3A3628;
  --sendback-text: var(--tangerine);
  --lockup-alt: var(--shop);
}