Brand guidelines.
What noorandmachine.com actually uses today, written down so every other feature can match it. Nothing here is aspirational — if it is on this page, it is on the main page. Drag the dial to see both palettes.
01 · Identity
Name. Noor & Machine. Written with an ampersand in prose and in the <title>; “Noor and Machine” only inside the signature.
Signature. — MSW/Noor and Machine. Em dash, space, then MSW/Noor and Machine. It sits under the headline, right-aligned to the headline’s width, like a quote attribution. It is the only place the author’s initials appear.
Contact. hello@noorandmachine.com, bottom-left of every page, in the muted colour.
Mark. There is no wordmark or logo yet. The favicon is the eight-spoked asterisk ✳ (U+2733) as an inline SVG data URI.
Voice. One sentence, first person, sentence case. The headline is a plain promise — I post my work here. — not a tagline. The full stop is the accent colour and is the only control in the copy: pressing it grows a light out of the dot, the page empties, and the list of pages appears. No exclamation marks, no capitals for emphasis.
02 · Colour
Two palettes. Light is the default; Dark is reached through the circle at the top-right, and the page blends between them continuously. Every colour lives in a CSS custom property — nothing is hard-coded in a rule.
Light (default)
#f6f6f8--bg#0e0e12--fg · text#ff2e5b--accent · theme circle, dot, focus ring, glow#6f6d78--muted · footer, signature, bordersDark
#0a0a0a--bg#f5f3ee--fg · text#e8c46a--accent · theme circle, dot, focus ring, glow#8a8578--muted · footer, signature, bordersRules
- Accent is never text — except the full stop of the headline, which is a button. Otherwise it colours the theme circle, the focus ring, the corner glow and the light. Headlines and body are always
--fg. - Muted is for chrome. Footer, signature, eyebrow, 1px borders. Borders are
--fgat 8% opacity, not a fixed grey, so they survive both palettes. - Glow. The background is
--bgwith one radial gradient of the accent in the top-left corner:radial-gradient(60% 60% at 15% 0%, var(--glow), transparent 70%). Accent alpha is 0.16 in light, 0.08 in dark. - Blending. A value
t(0 light → 1 dark) linearly mixes every token between the two sets and writes the result into<meta name="theme-color">. The circle glides between 0 and 1; any in-between value is valid.
03 · Typography
Montserrat, from Google Fonts, variable weight 300–800, display=swap. Fallback stack: "Helvetica Neue", Arial, sans-serif. One family for everything; contrast comes from weight and size, not from a second face.
| Role | Weight | Size | Line height | Tracking | Colour |
|---|---|---|---|---|---|
| Display (h1) | 800 | clamp(2.4rem, 6.5vw, 5rem) | 1.06 | 0.01em | --fg |
| Body / lede | 400 | clamp(1rem, 1.5vw, 1.1rem) | 1.6 | 0 | --fg |
| Meta (footer, signature, eyebrow) | 400 | 0.8rem | normal | 0.05em | --muted |
| Section label | 600 | 0.8rem | normal | 0.12em, uppercase | --accent |
- Sentence case everywhere. No small-caps, no all-caps in headlines (section labels on documentation pages are the one exception).
- The display line is capped at
22chso it never runs the full width of a wide screen. - Headline ends with a full stop.
04 · Layout & spacing
- Gutter.
6vwon every side of the page; on phones (≤ 600px) 16px sides. - Vertical rhythm of the main page. The body is a flex column, content centred, with the title block pushed up by a
14vhbottom margin so the headline sits just above the middle of the screen. - Fixed chrome. Theme circle: top
2.5rem, right6vw. Footer email: bottom2rem, left6vw. On scrolling pages the footer is in flow instead, email left, signature right. - Signature offset.
1.1rembelow the headline; the title block iswidth: fit-contentso the right edge of the signature is the right edge of the headline. - Nothing else. No cards, no shadows, no rounded panels on the main page. Rules on documentation pages are 1px
--fgat 8%.
05 · Components
Title block
I post my work here.
Theme circle
A 14px circle filled with --accent, so it follows the theme it is on. Click to switch; the palette glides over 380ms. It is a <button role="switch"> with aria-checked; the hit area extends 12px around it. The choice persists per browser in localStorage["nm-dark"] (0 = light, 1 = dark).
The dot
The headline's full stop is a <button> in --accent, same font and weight as the headline but 1.4× its size (the line box is kept the same), with a soft accent glow so it reads as the thing to press. Pressing it: a fixed circle (160vmax, radial gradient of the accent at 60% → 24% → 6% → transparent) scales from 0 to 1 out of the dot in 900ms; the headline words, signature, footer and dial fade out in 450ms; the page list fades in 350ms later, in the same position as the headline. Heads are one step below display size (clamp(1.92rem, 5.2vw, 4rem)), weight 300, 600 on hover — the light counterpart of the 800 headline — with a 0.86em gap between them and a 1px --muted hairline (1.6em long, 45%) centred in the gap to mark them as separate things. While open the dot glides (600ms) up to the circle's spot in the corner, so it never sits on the list and stays the close control. Escape, the dot, or a click outside closes it. At rest the dot invites the press: two 1.5px accent rings ripple out of it (radius 0.1em → 0.55em, fading, 4.8s loop, 2.4s apart) and the dot itself swells 18% as each ring leaves. The ring's left side is masked so it dies out where it meets the e of here. The wave stops while the list is open and under prefers-reduced-motion.
Footer link
The email in --muted, underlined (browser default), 0.8rem, tracking 0.05em. The page list behind the dot holds the only other links.
06 · Motion
Two state changes: the theme glide, 380ms, cubic ease-out (1 − (1 − k)³), and the light, 900ms cubic-bezier(.2,.8,.2,1) with 450ms fades. While open the light slowly shifts hue (±20°, 9s, off under prefers-reduced-motion). Dragging is immediate. The only thing that moves on its own is the dot's wave, and it exists to be pressed. Any feature that adds motion should keep it to state changes the user caused, at or under 400ms.
07 · Tokens
Drop these into any feature to inherit the palette. Keep the names.
:root {
--bg: #f6f6f8;
--fg: #0e0e12;
--accent: #ff2e5b;
--muted: #6f6d78;
--glow: rgba(255,46,91,0.16);
--line: color-mix(in srgb, var(--fg) 8%, transparent);
}
/* Light is the default; dark is reached through the circle (t: 0 → 1) */
const light = { bg: "#f6f6f8", fg: "#0e0e12", accent: "#ff2e5b", muted: "#6f6d78", glow: 0.16 };
const dark = { bg: "#0a0a0a", fg: "#f5f3ee", accent: "#e8c46a", muted: "#8a8578", glow: 0.08 };
font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;
/* https://fonts.googleapis.com/css2?family=Montserrat:wght@300..800&display=swap */
Source of truth: apps/web/public/index.html. When the main page changes, this page changes.