# DESIGN.md: Things-style design system

Measured from https://culturedcode.com/things/ on 2026-10-15 by PikSpec (https://www.pikspec.com). An independent measurement of the rendered page, not Things's official design system, and not affiliated with Things.

Use it to build your own product in this design language: put this file in your project root and tell your AI tool (Claude Code, Cursor, Codex, Lovable, v0) to follow DESIGN.md. Never use the original's name, logo, copy or images; licensed fonts are replaced with the closest free Google Fonts.

To capture any other page, or get a ready project for your tool: https://www.pikspec.com/build-with-ai

HOW IT SHOULD LOOK
Build it in the design language of culturedcode.com, measured from the live site: it should feel designed by the same team as culturedcode.com — the same temperament, colour, type and density — for a different product. Never use culturedcode.com's name, logo, words or images.

Stack: use the one your project already has. Starting fresh: React + Vite + TypeScript + Tailwind CSS v4, with no UI kit (no shadcn/ui, MUI or Chakra) — their defaults would override this system. In a chat that shows one file (an artifact or canvas), build one HTML file instead, with the tokens below in its <style> block.
Use every value exactly as written. Do not round, rename, approximate or substitute a colour, size, radius, shadow or easing (fonts: see section 1). Anything not listed here does not exist in this system.

THE WEBSITE THIS SYSTEM COMES FROM
- Reference page: https://culturedcode.com/things/ — "culturedcode.com".
- Page frame: a top navigation bar and a footer.
- Content is grouped in cards (25 on the page, up to 2 side by side). Keep cards for grouped content only, not for every section.
- It uses 24 images including 1 video, 6 of them large. Large, real product imagery is part of the look — leave clearly labelled image slots at those sizes rather than stock photos or abstract 3D shapes.
- Interaction: 1 button and 2 form fields on one page.
- The page runs about 9 screens long at 1440px wide.
- Density is low: few elements per screen, generous space around each one.

HOW IT LOOKS (WHAT MAKES IT LOOK LIKE ITSELF, BEYOND THE VALUES)
- Almost entirely neutral: 99% of the page is painted in #F2F5F7 and #FFFFFF.
- #5C9CF5 is an accent: under 0.1% of the page, used for text only. Don't fill large areas with it.
- #4F91FB is an accent: under 0.1% of the page, as small fills such as buttons and badges. Keep it to small areas.
- The largest type (36px ui-sans-serif) is bold (700).
- Open: text covers 9% of the page. Sections sit about 162px apart.
- Share of the painted page: #F2F5F7 67.4% (dominant, backgrounds); #FFFFFF 20.7% (dominant, backgrounds); #FBFCFE 7.7% (supporting, backgrounds); #303336 2.5% (supporting, text); #44474B 0.7% (supporting, text); #2C3138 0.3% (detail, text); #55606E 0.1% (detail, text); #000F24 0.1% (detail, text). Keep accents at these proportions; do not promote them to fills.
- Large images: Photographs, video or raster artwork cover about 28% of the page.
- Type as set (size, weight and tracking measured together; use these pairs): 36px weight 700; 23.99px weight 400; 20.25px weight 400; 18px weight 400; 16px weight 400; 15.3px weight 400.

1. DESIGN TOKENS — PASTE INTO YOUR GLOBAL CSS
Allowed colours, with how the original uses each. Use no other colour, including in hover states:
- #F2F5F7 — 67.4% · backgrounds (var(--color-background))
- #FFFFFF — 20.7% · backgrounds (var(--color-ffffff))
- #FBFCFE — 7.7% · backgrounds (var(--color-surface))
- #303336 — 2.5% · text (var(--color-text))
- #44474B — 0.7% · text
- #2C3138 — 0.3% · text
- #55606E — 0.1% · text (var(--color-on-action))
- #000F24 — 0.1% · text
- #000712 — 0.1% · text
- #9299A4 — 0.1% · text
- #DFE3E8 — hairlines and grid lines (var(--color-border))
- #8792A1 — Text muted (var(--color-text-muted))
- #ECEEF0 — Action (var(--color-action))
- #26344A — Link (var(--color-link))
Keep every size, weight, line height and tracking exactly as listed whichever font renders.
```css
:root {
  --color-background: #F2F5F7; /* Background */
  --color-surface: #FBFCFE; /* Surface */
  --color-text: #303336; /* Text */
  --color-text-muted: #8792A1; /* Text muted */
  --color-border: #DFE3E8; /* Border */
  --color-action: #ECEEF0; /* Action */
  --color-on-action: #55606E; /* On action */
  --color-link: #26344A; /* Link */
  --color-ffffff: #FFFFFF; /* 20.7% of the page, as fills */
  --font-body: ui-sans-serif, sans-serif; /* ui-sans-serif */
  --type-display: 36px; /* Display, weight 700 */
  --type-display-leading: 36px;
  --type-title-large: 23.99px; /* Title Large, weight 400 */
  --type-title-large-leading: 29.9925px;
  --type-title-medium: 20.25px; /* Title Medium, weight 400 */
  --type-title-medium-leading: 26.325px;
  --type-title-small: 18px; /* Title Small, weight 400 */
  --type-title-small-leading: 24.3px;
  --type-body-1: 15.3px; /* Body 1, weight 400 */
  --type-body-1-leading: 18.36px;
  --type-body-2: 15.2px; /* Body 2, weight 400 */
  --type-body-2-leading: 19.76px;
  --type-body-3: 15px; /* Body 3, weight 600 */
  --type-body-3-leading: 24px;
  --type-body-4: 14.4px; /* Body 4, weight 800 */
  --type-body-4-leading: 14.4px;
  --type-label-large: 13.5px; /* Label Large, weight 400 */
  --type-label-large-leading: 16.2px;
  --type-label-small: 13px; /* Label Small, weight 700 */
  --type-label-small-leading: 15.6px;
  --space-4: 4px;
  --space-8: 8px;
  --space-12: 12px;
  --space-16: 16px;
  --space-20: 20px;
  --space-24: 24px;
  --space-28: 28px;
  --space-36: 36px;
  --space-40: 40px;
  --space-180: 180px;
  --space-200: 200px;
  --radius-sm: 3px;
  --radius-md: 4.5px;
  --radius-lg: 5px;
  --radius-xl: 5.472px;
  --radius-2xl: 6px;
  --radius-3xl: 6.4px;
  --radius-18: 18px; /* component radius */
  --radius-13: 12.8px; /* component radius */
  --radius-8: 7.632px; /* component radius */
  --elevation-1: rgba(38, 52, 74, 0.15) 0px 1px 0px 0px;
  --elevation-2: rgba(0, 0, 0, 0.1) 0px 2px 8px 0px, rgba(0, 0, 0, 0.1) 0px 0px 2px 0px;
  --elevation-3: rgba(0, 0, 0, 0.1) 0px 2px 10px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
  --duration-1: 0.2s;
  --ease-1: ease-out;
}
```
Tailwind CSS v4 (the default for new projects): put this after `@import "tailwindcss";`. It removes Tailwind's own palette, so only these colours exist as utilities:
```css
@theme {
  --color-*: initial;
  --color-background: #F2F5F7;
  --color-surface: #FBFCFE;
  --color-text: #303336;
  --color-text-muted: #8792A1;
  --color-border: #DFE3E8;
  --color-action: #ECEEF0;
  --color-on-action: #55606E;
  --color-link: #26344A;
  --color-ffffff: #FFFFFF;
  --font-body: ui-sans-serif, sans-serif;
  --text-display: 36px;
  --text-display--line-height: 36px;
  --text-title-large: 23.99px;
  --text-title-large--line-height: 29.9925px;
  --text-title-medium: 20.25px;
  --text-title-medium--line-height: 26.325px;
  --text-title-small: 18px;
  --text-title-small--line-height: 24.3px;
  --text-body-1: 15.3px;
  --text-body-1--line-height: 18.36px;
  --text-body-2: 15.2px;
  --text-body-2--line-height: 19.76px;
  --text-body-3: 15px;
  --text-body-3--line-height: 24px;
  --text-body-4: 14.4px;
  --text-body-4--line-height: 14.4px;
  --text-label-large: 13.5px;
  --text-label-large--line-height: 16.2px;
  --text-label-small: 13px;
  --text-label-small--line-height: 15.6px;
  --radius-sm: 3px;
  --radius-md: 4.5px;
  --radius-lg: 5px;
  --radius-xl: 5.472px;
  --radius-2xl: 6px;
  --radius-3xl: 6.4px;
  --shadow-e1: rgba(38, 52, 74, 0.15) 0px 1px 0px 0px;
  --shadow-e2: rgba(0, 0, 0, 0.1) 0px 2px 8px 0px, rgba(0, 0, 0, 0.1) 0px 0px 2px 0px;
  --shadow-e3: rgba(0, 0, 0, 0.1) 0px 2px 10px 0px, rgba(0, 0, 0, 0.05) 0px 0px 0px 1px;
  --ease-1: ease-out;
}
```
Tailwind CSS v3 only: extend the theme with these instead, and use no other palette:
```js
// tailwind.config — theme.extend
{
  colors: { "background": "var(--color-background)", "surface": "var(--color-surface)", "text": "var(--color-text)", "text-muted": "var(--color-text-muted)", "border": "var(--color-border)", "action": "var(--color-action)", "on-action": "var(--color-on-action)", "link": "var(--color-link)" },
  fontFamily: { "body": ["var(--font-body)"] },
  borderRadius: { "sm": "var(--radius-sm)", "md": "var(--radius-md)", "lg": "var(--radius-lg)", "xl": "var(--radius-xl)", "2xl": "var(--radius-2xl)", "3xl": "var(--radius-3xl)" },
  boxShadow: { "e1": "var(--elevation-1)", "e2": "var(--elevation-2)", "e3": "var(--elevation-3)" },
}
```

2. BASE STYLES
```css
html { background: var(--color-background); }
body { margin: 0; font-family: var(--font-body); color: var(--color-text); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
h1, h2, h3 { font-family: var(--font-body); margin: 0; }
a { color: var(--color-link); }
:focus-visible { outline: 2px solid var(--color-action); outline-offset: 2px; }
```

3. COMPONENTS — MATCH THESE EXACTLY
```css
.card { /* Default */
  background: var(--color-background);
  border-radius: var(--radius-18);
  padding: 27px 27px 27px 27px;
  min-height: 202px;
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--type-title-small);
  font-weight: 400;
  line-height: 25.2px;
}
.card-2 { /* Alternative 1 */
  background: var(--color-ffffff);
  border-radius: var(--radius-13);
  padding: 13px 13px 13px 13px;
  min-height: 162px;
  box-shadow: var(--elevation-2);
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 400;
  line-height: 20.8px;
}
.link { /* Inline */
  background: transparent;
  font-family: var(--font-body);
  font-size: var(--type-title-small);
  font-weight: 400;
  line-height: 21.6px;
  /* recorded states: hover, active */
}
.link-2 { /* Inline 2 */
  background: transparent;
  color: #000712;
  font-family: var(--font-body);
  font-size: var(--type-body-1);
  font-weight: 400;
  line-height: 18.36px;
  /* recorded states: hover, active */
}
.link-3 { /* Inline 3 */
  background: transparent;
  border-radius: var(--radius-sm);
  min-height: 36px;
  font-family: var(--font-body);
  font-size: var(--type-label-small);
  font-weight: 400;
  line-height: 15.6px;
  /* recorded states: hover, active */
}
.nav { /* Default */
  background: transparent;
  padding: 0px 0px 20px 0px;
  min-height: 88px;
  color: var(--color-text);
  font-family: var(--font-body);
  font-size: var(--type-body-3);
  font-weight: 600;
  line-height: 18px;
}
.input { /* Default */
  background: var(--color-ffffff);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-3xl);
  padding: var(--space-8);
  min-height: 36px;
  color: #000712;
  font-family: var(--font-body);
  font-size: 16px;
  font-weight: 400;
  /* recorded states: active, focus */
}
.input-2 { /* Alternative 1 */
  border-radius: var(--radius-8);
  padding: 7px 17px 7px 17px;
  min-height: 36px;
  color: var(--color-ffffff);
  font-family: var(--font-body);
  font-size: 16.96px;
  font-weight: 700;
  /* recorded states: hover, active, focus, disabled */
}
.button { /* Secondary */
  background: var(--color-action);
  border-radius: var(--radius-xl);
  padding: 0px 4px 0px 4px;
  color: var(--color-on-action);
  font-family: var(--font-body);
  font-size: 13.68px;
  font-weight: 400;
  line-height: 17.784px;
  /* recorded states: hover, active */
}
```
Where a component lists recorded states, write those states using only the colours above; the capture saw that the state exists, not its values. Never invent a state colour.

4. PAGE COMPOSITION
- Light interface on #F2F5F7. Keep that ground; do not add a dark mode.
- The opening screen carries a large image or video on the left. Leave a [content: hero image or video] slot there, at least half the screen wide; the opening is not text alone.
- Sections change ground between Background (#F2F5F7), Surface (#FBFCFE) and #FFFFFF; use only those.
- #ECEEF0 is the action colour. Fill the primary action with it and little else — at most one #ECEEF0-filled element per screen; other accents keep to the uses listed above.
- Type: ui-sans-serif for body. Hierarchy comes from size and weight, not colour or decoration.
- Corner radii are 3px, 4.5px, 5px, 5.472px, 6px, 6.4px — nothing else.
- Body text uses ui-sans-serif at around 16px, weights 400, 600, 700, 800.
- Headings use the same family as body text; the largest heading is 36px.
- Primary buttons are #ECEEF0, 5.472px radius, weight 400.
- Cards use 18px corners.
- Corner radii in use: 18px, 3px, 4.5px, 6px, 12.8px.

HOW THE ORIGINAL PACES ITS PAGE (BORROW THE RHYTHM — THE OPENING, THE COLOURED BANDS, THE CARD GRIDS — NOT THE LIST; BUILD THE SECTIONS YOUR PRODUCT NEEDS)
1. Hero — 1135px tall, split 7 / 5, left-aligned 23.99px heading (weight 400), image on the left, on #F2F5F7.
2. Full-bleed image — 1293px tall, centred 36px heading (weight 700), image behind the content.
3. Cards — 888px tall, 4 equal columns, 18px gap, centred 36px heading (weight 700), on #FFFFFF.
4. Grid — 987px tall, 8 items in 4 columns with 16px gaps, centred 36px heading (weight 700), on #F2F5F7.
5. Split — 2250px tall, split 10 / 2, 10px gap, left-aligned 18px heading (weight 400), image on the right.
6. Statement — 620px tall, centred 36px heading (weight 700), on #F2F5F7.
7. Footer — 303px tall, 4 equal columns, 24px gap, left-aligned 15.3px heading (weight 400), on #F2F5F7.
- Content runs 901px wide with 283px side margins at 1440px; there is no narrower centred container.
- A 88px header scrolls away, transparent over the first section.
- The hero is 1135px (1.3 screens): split 7 / 5, left-aligned 23.99px heading (weight 400), image on the left, on #F2F5F7.
- Column splits on a 12-column grid: quarters (3×), 7/5, 10/2; gaps of 18px.
- Headings mix left (3) and centred (4) alignment.
- Sections change background 5 times, between #F2F5F7, #FFFFFF: colour comes in full-width bands, not in boxes.
- A typical section is about 987px tall.

COPY SHAPE (MATCH THE LENGTH AND CASE; WRITE YOUR OWN WORDS)
- The main heading is 1 word long.
- Section headings are medium length: typically 4 words.
- Heading case varies.
- The page describes itself in about 23 words; keep your intro paragraph to about that length.

5. MOTION
Interactive elements change colour, background, border and opacity with the measured timing. Animate nothing else.
```css
a, button, [role="button"], input { transition: color var(--duration-1) var(--ease-1), background-color var(--duration-1) var(--ease-1), border-color var(--duration-1) var(--ease-1), opacity var(--duration-1) var(--ease-1); }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
}
```
No scroll-triggered fade-ins, parallax, typewriter text or bouncing elements.

6. RESPONSIVE
- The design was measured at 1440px wide. Lay it out for that width first, then let it reflow down to 360px.
- Content sits in a column at most 1015px wide, centred, with var(--space-16) (16px) side padding on small screens.
- The largest heading scales fluidly: font-size: clamp(20.25px, 2.5vw, 36px). Every other size stays fixed.
- Break on composition, not device names: a row of columns drops a column when any column would be narrower than 240px; side-by-side splits stack when either side would be narrower than 320px.
- Spacing steps never change between sizes; use smaller steps from the same list where space is tight.
- On touch screens, every link and button has a hit area of at least 44 × 44px without changing its drawn size.

7. ACCESSIBILITY
- Text pairs that pass for body copy: Text on Background (11.6:1), Link on Background (11.5:1), Text on Surface (12.4:1), Link on Surface (12.2:1) and On action on Action (5.5:1).
- Only for text 24px and up, or 18.66px bold: Text muted on Surface (3.1:1).
- Use no other text-on-background pairing.
- One h1 per page, headings in order, landmarks (header, nav, main, footer), real buttons and links, a label on every field, alt text on every image, an aria-label on icon-only buttons.
- Every interactive element shows the :focus-visible outline above.

8. DO NOT (THESE ARE WHAT MAKE AI-BUILT SITES LOOK GENERIC)
- No gradients: not in backgrounds, text, buttons or borders. (No gradient was measured.)
- Only these colours: #F2F5F7, #FFFFFF, #FBFCFE, #303336, #44474B, #2C3138, #55606E, #000F24, #000712, #9299A4, #DFE3E8, #8792A1, #ECEEF0, #26344A. No new tints, no Tailwind defaults (slate, indigo, violet). (They are every colour that covers a measurable part of the page, and the colours its lines and drawings use.)
- #5C9CF5 only for text — never as a section background or a large panel. (It covers under 0.1% of the page.)
- #4F91FB only as small fills (buttons, badges) — never a section background or a large panel. (It covers under 0.1% of the page.)
- Only the fonts in the tokens: ui-sans-serif for body. No other typeface, and no Inter, Roboto or system UI font unless it is one of these. (The page is set in ui-sans-serif; the tokens carry what stands in for them.)
- Headings and large text never heavier than weight 700. Do not make headlines bold to add emphasis. (Every size from 24px up is set at weight 700 or lighter.)
- No icon above every feature, no emoji, no decorative blobs, sparkles or glows. (None of these is part of the captured design; they are a coding model's defaults.)
- The hero is left-aligned. Do not centre it. (The captured hero sets its heading on the left.)
- Build the sections your product needs, not the original's list. Give each one this system's look: its kinds of section (hero, image, cards, grid, split, statement, footer), its colours, type, shapes and spacing. (The style carries to any kind of site; the original's page was for a different product.)
- No glassmorphism, backdrop blur, glowing orbs, noise blobs or neon outlines.
- No row of three identical feature cards as the default section. Vary the layout from section to section: a split, a list, a single large statement, a table.
- No centred-everything hero with a pill badge, a gradient headline and two buttons. Lead with the most specific thing about the product.
- No filler copy: no "Unlock your potential", "Revolutionize", "Seamless", "Elevate", "Supercharge", "Next-gen" or lorem ipsum. Write plain, specific sentences a real company would publish.
- No made-up statistics, testimonials or customer logos. Leave a clearly marked [content: …] slot instead.
- No radius larger than the largest one listed.
- No shadows other than the levels listed.
- Do not use culturedcode.com's name, logo, copy or images. This is its design system, not its content.

BEFORE YOU FINISH
- Search your code for every colour, font size, spacing value, radius, shadow and easing, and replace anything that is not a variable above.
- Check that no [content: …] slot has been filled with invented facts.
- Search your CSS for gradient(. There should be none.
- Every colour value in your CSS is one of the allowed colours. Nothing else, including in hover states.
- #5C9CF5 covers about 0.1% of the page or less, as on the original.
- #4F91FB covers about 0.1% of the page or less, as on the original.
- No text 24px or larger has a font-weight above 700.
- Every section, including ones the original does not have, uses only this system's colours, type, shapes and spacing.
- There is no placeholder copy (lorem ipsum, "Feature one", "Your headline here"). Every word is real.
- Take a screenshot at 1440px and put it beside the original. List every difference in colour, weight, spacing, alignment and imagery, and fix each before finishing. Then check 390px wide: nothing scrolls sideways and no heading runs off the screen.
