---
version: alpha
name: Greenhouse Catalogue
description: "Magazine-style storefront system: oversized Sora headlines, ink-on-paper neutrals and a single garden-green action color."
colors:
  background: "#faf8f3"
  foreground: "#181714"
  card: "#ffffff"
  card-foreground: "#181714"
  popover: "#ffffff"
  popover-foreground: "#181714"
  primary: "#1b7d52"
  primary-foreground: "#ffffff"
  secondary: "#f1eee6"
  secondary-foreground: "#2b2824"
  muted: "#f1eee6"
  muted-foreground: "#58534a"
  accent: "#d8f3e2"
  accent-foreground: "#123f2d"
  destructive: "#c02d56"
  destructive-foreground: "#ffffff"
  success: "#0f6054"
  success-foreground: "#ffffff"
  warning: "#f8d396"
  warning-foreground: "#3e2b02"
  border: "#e1ddd2"
  input: "#c9c4b7"
  ring: "#1b7d52"
  dark-background: "#181714"
  dark-foreground: "#faf8f3"
  dark-card: "#211f1b"
  dark-card-foreground: "#faf8f3"
  dark-popover: "#2b2824"
  dark-popover-foreground: "#faf8f3"
  dark-primary: "#4fb983"
  dark-primary-foreground: "#07241a"
  dark-secondary: "#413d36"
  dark-secondary-foreground: "#f1eee6"
  dark-muted: "#413d36"
  dark-muted-foreground: "#c9c4b7"
  dark-accent: "#123f2d"
  dark-accent-foreground: "#d8f3e2"
  dark-destructive: "#f66e89"
  dark-destructive-foreground: "#390011"
  dark-success: "#3cb2a0"
  dark-success-foreground: "#04201c"
  dark-warning: "#d39b2e"
  dark-warning-foreground: "#261900"
  dark-border: "#413d36"
  dark-input: "#58534a"
  dark-ring: "#4fb983"
typography:
  display-lg:
    fontFamily: Sora
    fontSize: 64px
    fontWeight: 700
    lineHeight: 1.0625
    letterSpacing: -0.035em
  display-md:
    fontFamily: Sora
    fontSize: 48px
    fontWeight: 700
    lineHeight: 1.08
    letterSpacing: -0.03em
  heading-lg:
    fontFamily: Sora
    fontSize: 32px
    fontWeight: 600
    lineHeight: 1.25
    letterSpacing: -0.02em
  heading-md:
    fontFamily: Plus Jakarta Sans
    fontSize: 24px
    fontWeight: 700
    lineHeight: 1.33
    letterSpacing: -0.01em
  heading-sm:
    fontFamily: Plus Jakarta Sans
    fontSize: 20px
    fontWeight: 700
    lineHeight: 1.4
    letterSpacing: -0.005em
  body-lg:
    fontFamily: Plus Jakarta Sans
    fontSize: 18px
    fontWeight: 400
    lineHeight: 1.56
  body-md:
    fontFamily: Plus Jakarta Sans
    fontSize: 16px
    fontWeight: 400
    lineHeight: 1.625
  body-sm:
    fontFamily: Plus Jakarta Sans
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.57
  label:
    fontFamily: Plus Jakarta Sans
    fontSize: 14px
    fontWeight: 600
    lineHeight: 1.43
    letterSpacing: 0.01em
  caption:
    fontFamily: Plus Jakarta Sans
    fontSize: 12px
    fontWeight: 600
    lineHeight: 1.33
    letterSpacing: 0.05em
  code:
    fontFamily: JetBrains Mono
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.57
rounded:
  sm: 2px
  md: 4px
  lg: 6px
  xl: 10px
  full: 9999px
spacing:
  xs: 4px
  sm: 8px
  md: 16px
  lg: 24px
  xl: 32px
  2xl: 48px
  3xl: 64px
components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.primary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 24px
    height: 48px
  button-secondary:
    backgroundColor: "{colors.secondary}"
    textColor: "{colors.secondary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 24px
    height: 48px
  button-destructive:
    backgroundColor: "{colors.destructive}"
    textColor: "{colors.destructive-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 24px
    height: 48px
  input:
    backgroundColor: "{colors.background}"
    textColor: "{colors.foreground}"
    typography: "{typography.body-sm}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 48px
  card:
    backgroundColor: "{colors.card}"
    textColor: "{colors.card-foreground}"
    rounded: "{rounded.lg}"
    padding: 32px
  popover:
    backgroundColor: "{colors.popover}"
    textColor: "{colors.popover-foreground}"
    rounded: "{rounded.lg}"
    padding: 12px
  helper-text:
    backgroundColor: "{colors.background}"
    textColor: "{colors.muted-foreground}"
    typography: "{typography.body-sm}"
  table-row-alt:
    backgroundColor: "{colors.muted}"
    textColor: "{colors.muted-foreground}"
    typography: "{typography.body-sm}"
    height: 44px
  badge:
    backgroundColor: "{colors.accent}"
    textColor: "{colors.accent-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-success:
    backgroundColor: "{colors.success}"
    textColor: "{colors.success-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-warning:
    backgroundColor: "{colors.warning}"
    textColor: "{colors.warning-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-destructive:
    backgroundColor: "{colors.destructive}"
    textColor: "{colors.destructive-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  button-primary-dark:
    backgroundColor: "{colors.dark-primary}"
    textColor: "{colors.dark-primary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 24px
    height: 48px
  button-secondary-dark:
    backgroundColor: "{colors.dark-secondary}"
    textColor: "{colors.dark-secondary-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 24px
    height: 48px
  button-destructive-dark:
    backgroundColor: "{colors.dark-destructive}"
    textColor: "{colors.dark-destructive-foreground}"
    typography: "{typography.label}"
    rounded: "{rounded.md}"
    padding: 0 24px
    height: 48px
  input-dark:
    backgroundColor: "{colors.dark-background}"
    textColor: "{colors.dark-foreground}"
    typography: "{typography.body-sm}"
    rounded: "{rounded.md}"
    padding: 0 16px
    height: 48px
  card-dark:
    backgroundColor: "{colors.dark-card}"
    textColor: "{colors.dark-card-foreground}"
    rounded: "{rounded.lg}"
    padding: 32px
  popover-dark:
    backgroundColor: "{colors.dark-popover}"
    textColor: "{colors.dark-popover-foreground}"
    rounded: "{rounded.lg}"
    padding: 12px
  helper-text-dark:
    backgroundColor: "{colors.dark-background}"
    textColor: "{colors.dark-muted-foreground}"
    typography: "{typography.body-sm}"
  table-row-alt-dark:
    backgroundColor: "{colors.dark-muted}"
    textColor: "{colors.dark-muted-foreground}"
    typography: "{typography.body-sm}"
    height: 44px
  badge-dark:
    backgroundColor: "{colors.dark-accent}"
    textColor: "{colors.dark-accent-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-success-dark:
    backgroundColor: "{colors.dark-success}"
    textColor: "{colors.dark-success-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-warning-dark:
    backgroundColor: "{colors.dark-warning}"
    textColor: "{colors.dark-warning-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
  badge-destructive-dark:
    backgroundColor: "{colors.dark-destructive}"
    textColor: "{colors.dark-destructive-foreground}"
    typography: "{typography.caption}"
    rounded: "{rounded.full}"
    padding: 0 8px
    height: 24px
---

# Greenhouse Catalogue

## Overview

Greenhouse Catalogue is for online shops that should read like a printed magazine. Product pages are stories, collection pages are spreads, and checkout is the quiet last page. Hierarchy comes from a 64px display headline against 16px body text, wide margins and one green action color (primary). Every other surface is warm paper and ink, so photography and copy carry the page.

Moods: editorial, refined, calm, spacious. Built for: e-commerce, retail, publishing. Density: spacious.

Every color has a light value and a dark value. Tokens named `dark-*` are the dark-mode counterparts of the token with the same role name.

## Colors

Neutrals are warm paper to ink (hue ~45, low chroma). neutral.50 #faf8f3 is the page and neutral.950 #181714 is the text, so nothing renders as cool grey. Brand green (hue ~150) is the only chromatic accent. Use it for primary, ring, links and accent fills. Success is a bluer teal (hue ~170) so confirmations never read as a call to action. Destructive is a crimson (hue ~345), far from green in both modes. The warning ramp was re-curved so chroma rises smoothly to 400–500 instead of jumping, which removes the muddy 300 step. Light contrast: primary-foreground on primary is 5.1:1, destructive-foreground on destructive 5.6:1, muted-foreground on muted 6.6:1, and primary on background 4.8:1. Dark contrast: primary-foreground on primary is 6.7:1, destructive 6.3:1, warning 6.9:1, and muted-foreground on muted 6.2:1.

- **Primary** `#1b7d52` / dark `#4fb983`: the single action color. Primary buttons, links, focus ring.
- **Background / Foreground** `#faf8f3` / dark `#181714` on `#181714` / dark `#faf8f3`: page surface and body text.
- **Card** `#ffffff` / dark `#211f1b`: raised surfaces.
- **Secondary** `#f1eee6` / dark `#413d36`: secondary buttons and quiet controls.
- **Muted** `#f1eee6` / dark `#413d36` with **muted-foreground** `#58534a` / dark `#c9c4b7`: helper text, table stripes, disabled-looking surfaces.
- **Accent** `#d8f3e2` / dark `#123f2d`: highlights, selected rows, badges.
- **Destructive** `#c02d56` / dark `#f66e89`, **Success** `#0f6054` / dark `#3cb2a0`, **Warning** `#f8d396` / dark `#d39b2e`: status only, always paired with an icon or label.
- **Border** `#e1ddd2` / dark `#413d36`, **Input** `#c9c4b7` / dark `#58534a`, **Ring** `#1b7d52` / dark `#4fb983`.

All text/background pairs above pass WCAG AA (4.5:1) in both modes; this is checked automatically at build time.

## Typography

The scale is a major third (1.25) from a 16px base, rounded to the 4px grid: 16, 20, 24, 32, 48, 64. The 39px step is skipped on purpose, so the display sizes jump hard like a masthead. 18px (body-lg) is a half-step for lead paragraphs. Sora (600/700) is used only at 32px and above: display-lg, display-md and heading-lg. Its tracking tightens from -0.02em at 32px to -0.035em at 64px. Plus Jakarta Sans (400–700) sets heading-md and below, body, labels, forms and prices. Body line heights land on the grid: 16/26, 18/28 and 14/22. JetBrains Mono (400/500) is only for SKUs, order numbers and codes.

- Display: **Sora** (fallback system-ui, sans-serif)
- Interface: **Plus Jakarta Sans** (fallback system-ui, sans-serif)
- Mono: **JetBrains Mono** (fallback ui-monospace, monospace)

| Token | Font | Size | Line height | Weight |
|---|---|---|---|---|
| display-lg | Sora | 64px | 1.0625 | 700 |
| display-md | Sora | 48px | 1.08 | 700 |
| heading-lg | Sora | 32px | 1.25 | 600 |
| heading-md | Plus Jakarta Sans | 24px | 1.33 | 700 |
| heading-sm | Plus Jakarta Sans | 20px | 1.4 | 700 |
| body-lg | Plus Jakarta Sans | 18px | 1.56 | 400 |
| body-md | Plus Jakarta Sans | 16px | 1.625 | 400 |
| body-sm | Plus Jakarta Sans | 14px | 1.57 | 400 |
| label | Plus Jakarta Sans | 14px | 1.43 | 600 |
| caption | Plus Jakarta Sans | 12px | 1.33 | 600 |
| code | JetBrains Mono | 14px | 1.57 | 400 |

## Layout

Spacious density on a 4px grid. Section gaps are {space.16}–{space.24} (64–96px), and card padding is {space.8} (32px). Use a 12-column grid with a 1200px max content width. Long-form editorial copy sits in a 640px column. Hero headlines leave one empty column beside them.

Spacing uses a 4px base: xs = 4px, sm = 8px, md = 16px, lg = 24px, xl = 32px, 2xl = 48px, 3xl = 64px.

## Elevation & Depth

Print is flat, so the system is too. Cards separate from the page with a 1px border and whitespace. Their shadow.sm is a 5% ink tint and is barely visible. shadow.md is for menus and popovers. shadow.lg is for dialogs and the sticky cart drawer. In dark mode, depth comes from surface steps rather than shadows: background #181714, card #211f1b, then popover and muted at neutral.900 and neutral.800.

- sm: `0 1px 2px rgba(24, 23, 20, 0.05)`
- md: `0 6px 16px -4px rgba(24, 23, 20, 0.12)`
- lg: `0 20px 48px -12px rgba(24, 23, 20, 0.22)`

## Shapes

Radii are small, like trimmed paper: {radius.md} 4px on buttons and inputs, {radius.lg} 6px on cards. {radius.full} is only for badges and avatars. Product imagery is never rounded beyond 6px.

Radius scale: sm 2px, md 4px, lg 6px, xl 10px, full 9999px.

## Components

Components ending in `-dark` are the dark-mode versions. Button: 48px tall, 24px horizontal padding, label type. Input: 48px tall with a 1px input-colored border; focus shows a 2px ring in the ring color. Card: 32px padding, 1px border, sm shadow. Badge: pill, caption type.

## Do's and Don'ts

- **Do:** Set page and collection titles in display-lg (Sora 64/68, -0.035em) or display-md (Sora 48/52, -0.03em), and follow them directly with body-lg (18px) so the size jump is at least 2.6×.
- **Do:** Give each view one primary button for the main action, such as Add to bag or Checkout. Use secondary (neutral.100 fill) or ghost buttons for every other action.
- **Do:** Show a 2px ring (brand.600 light, brand.400 dark) at a 2px offset on every focused button, input, link and product card.
- **Do:** Keep section gaps at {space.16}–{space.24} and card padding at {space.8}. Keep at least {space.4} between form fields.
- **Do:** Cap editorial copy at 640px (65–75 characters) in body-md (16/26) or body-lg (18/28).
- **Do:** Set prices and quantities in Plus Jakarta Sans with font-feature-settings 'tnum'. Use the code token (JetBrains Mono 14/22) only for SKUs and order IDs.
- **Do:** Separate cards with a 1px border token. Use shadow.md for menus and popovers, and shadow.lg for dialogs and the cart drawer.
- **Do:** Set category kickers above headlines in uppercase caption (12/16, 600, 0.05em) using muted-foreground.
- **Don't:** Don't set Sora below 32px (heading-lg). heading-md (24px) and anything smaller, including forms, tables, prices and buttons, use Plus Jakarta Sans.
- **Don't:** Don't put a second saturated color on a screen. Primary green is the only accent. Sale and error states use destructive or warning tokens, at most once per product card.
- **Don't:** Don't use primary or brand green for errors or out-of-stock states. Use destructive (danger.600 light, danger.400 dark).
- **Don't:** Don't use success teal for buttons or links. It only marks completed states such as 'Order placed' or 'In stock'.
- **Don't:** Don't round corners beyond {radius.lg} (6px) on cards or {radius.md} (4px) on buttons and inputs, and never round product imagery beyond 6px.
- **Don't:** Don't use #000000 or cool greys. Text uses neutral.950 (light) or neutral.50 (dark), and hairlines use border (neutral.200 light, neutral.800 dark).
- **Don't:** Don't place muted-foreground text on brand or accent fills. Use accent-foreground (brand.900 light, brand.100 dark) instead.
- **Don't:** Don't reduce button or input height below 48px, or badge height below 24px.
