Living Brand Document

Garden OS
Brand Guide

Tokens, type, components, voice, and identity rules for everything built under the Garden OS name.

v4.4 · Updated March 2026
§ 0

Brand Statement

The one-paragraph brief that everything else should feel consistent with.

The position

Garden OS is a local-first raised bed garden planning system and narrative strategy game. It reads like a garden journal, not a SaaS dashboard. It is warm, grounded, and organic — but precise underneath. Every pixel either explains something or gets out of the way.

The promise

No cloud. No login. No tracking. Just dirt, data, and decisions. The system earns trust by being transparent: every score shows exactly why, every action is reversible, every file is yours.

Core attributes
🌱
Warm and groundedSoil tones, natural language, no jargon. Feels handmade, not generated.
🧮
Precise and explainableEvery number has a reason. Every score is traceable. Trust is built by showing work.
🔒
Local and permanentYour data lives in your browser. The app works offline. Nothing disappears when the server does.
🎮
Serious but funReal horticultural logic. But also: a 12-chapter season game with narrators and recipes. Both are meant.
§ 1

Colour Palette

Four families. One intentional light theme. Click any swatch to copy its hex value.

Soil — structure, headers, text
Leaf — success, growth, good states
Sun / Amber — accent, CTA, warmth
Cream — backgrounds, panels, borders
Semantic aliases — use these in component code, not raw scale values
TokenValuePreviewUse for
🎨
Single-theme policyGarden OS ships one intentional light theme. Do not add dark mode without updating all surface, text, and border tokens systematically. Do not introduce purple, blue, or grey as primary tones — they undermine the warm soil aesthetic.
§ 2

Typography

Three typefaces. One for narrative, one for prose, one for data.

Fraunces — Display & Headings Optical size: 9–144 · Ital + Roman
Where should the
tomatoes go?
56px / 3.5rem
--text-5xl
Garden OS
40px / 2.5rem
--text-4xl
Season Engine
32px / 2rem
--text-3xl
The Planner
24px / 1.5rem
--text-2xl
Scoring Engine
20px / 1.25rem
--text-xl
Bed Score: 78
Italic variant
font-style: italic
"An aphid surge hit the nightshade row."
Weight reference
Fraunces 200
Hero titles, display
Fraunces 300
Section heads
Fraunces 400
Panel titles, cards
Fraunces 600
Score numbers, emphasis
DM Sans — Body & UI Prose Weights: 300, 400, 500, 600
16px
--text-md
Plan your bed. Learn why each placement scores the way it does.
14px
--text-base
No cloud. No login. No tracking. Just dirt, data, and decisions.
12px
--text-sm
Works offline. Saves to localStorage. No backend required.
500 weight
font-weight:500
Labels, button text, field headings
DM Mono — Data, Labels, Code Weights: 400, 500 · Always ALL-CAPS for UI labels
UI labels
0.55–0.65rem
BED SCORE   SUN FIT   VERSION v4.4   SCHEMA v1
Data values
0.7–0.8rem
78 / 100  ·  4.5 hrs sun  ·  Zone 7  ·  Last frost Apr-01
Token names
code usage
--soil-500 --text-base scoreBed() gardenOS_workspace
Nav + tabs
letter-spacing:.1em
⚠️
Never substituteDo not replace Fraunces with a geometric sans (e.g. Nunito, Outfit, Plus Jakarta). The optical-size serif is load-bearing for the warm/grounded aesthetic. DM Mono can be replaced with another mono in code contexts only.
§ 3

Spacing Scale

4px base unit. Always use tokens — never write arbitrary pixel values.

--sp-1
4px Icon gap, dot, fine spacing
--sp-2
8px Tag padding, close pairs
--sp-3
12px Inline elements, label-field gap
--sp-4
16px List items, row padding, callout
--sp-5
20px Card padding (compact)
--sp-6
24px Card padding, section gap
--sp-8
32px Page gutter, panel spacing
--sp-10
40px Section vertical padding
--sp-12
48px Major section breaks
--sp-16
64px Hero padding, full-bleed gaps
Radius scale
--r-sm · 4px
Tags, dots, cells
--r-md · 8px
Buttons, inputs, cards
--r-lg · 12px
Panels, modals
--r-full
Pills, toggles, dots
§ 4

Components

Live examples of every reusable element. All behaviour is in-page, no framework.

Buttons Interactive
Variants
Sizes
With icons
Tags & Badges Display
Semantic tags
Local First Offline Season Strategy Nightshade Greens Annotation
Status tags
✓ Confirmed ⚠ At risk ✕ Conflict
Score badges
92/100
74/100
51/100
28/100
Factor Bars — Scoring Breakdown Data Viz
Placement score · Tomato R1C2
Sun Fit
9
Support
8
Shade Tol.
5
Access
7
Season
10
Adjacency
+1
Bed grid · 4 × 4
🍅
🍅
🌶️
🌶️
🥬
🌿
🥕
🥕
🫘
🫘
🥬
🌿
Form Elements Interactive
Trellis / cage present
Protected zone active
Show heatmap overlay
Callouts & Warnings Feedback
💡
TipPlanting beans next to corn activates the Three Sisters bonus — a confirmed nitrogen fixation benefit.
Good placementTomato in R1C1 scores 8.4 — sun fit and trellis access are both optimal.
⚠️
Season warningLettuce is a cool-season crop. Planting in July risks bolting within 2 weeks.
Conflict detectedGarlic and beans are in adjacent cells. Allium sulfur compounds suppress legume nitrogen fixation — move one.
§ 5

Voice & Copy

Garden OS speaks like a knowledgeable friend, not a SaaS dashboard or a textbook.

Tone principles Foundation
Warm, not cozy

The voice is direct and helpful. It doesn't over-explain, doesn't use filler phrases like "Great choice!", and doesn't hedge with "you might want to consider."

Precise, not clinical

Numbers have context. "Score: 8.4" alone is not enough — "sun fit: 9, season fit: 7" explains it. Always show the reason behind the number.

Grounded, not formal

Use plain English. Horticultural terms are allowed when they're more precise (e.g. "bolting", "allium", "trellis zone") — but always explain them on first use.

Do / Don't — UI microcopy Rules
✓ Do "Auto-fill a starter layout →"
Direct, verb-first. The arrow implies action. No "click here."
✕ Don't "Click here to automatically fill your garden bed with recommended crops"
Too long, passive, explains what the user can already see.
✓ Do "Lettuce risks bolting — plant before May or after September."
States the problem, gives the solution, cites the condition.
✕ Don't "Warning: This crop may not be optimal for the current season settings."
Vague, passive, gives no actionable guidance.
✓ Do "Saved just now · 78 cells · 4 beds"
Compact, specific, reassuring. Uses DM Mono for data.
✕ Don't "Your changes have been successfully saved to local storage."
Wordy, formal, sounds like a server response.
Narrator voice — Season Engine Game context

Season Engine narrators speak in the first person with a fixed voice and consistent point of view. Each line references at least one live game signal — score, event severity, crop status, or resource level.

Voice example — good state (bed score 80+)

"The basil held its line. Your companion layout paid off — the nightshade row took zero pest pressure this week. Harvest window opens in 12 days."

Voice example — stress event (drought, score dropping)

"Third dry week. The cucumbers are pulling ahead of your water budget. You'll need to choose between them and the bean row before Friday's commit."

§ 6

Identity & Logomark

The wordmark, usage rules, and clear space requirements.

Approved wordmark variants
Garden OS
On dark / primary use
Garden OS
On light / cream backgrounds
Garden OS
On panel / medium backgrounds
Usage rules
Always set "Garden" and "OS" at different weights and sizes — "Garden" is subordinate, "OS" is the identity anchor.
Use Fraunces 200 (ultralight) for "Garden" and Fraunces 200–300 for "OS". The lightness is intentional — it reads as grown, not bold.
Page headers use the full wordmark with version metadata in DM Mono below: v4.4 · Schema v1
✕ Never Render "Garden OS" in a single weight — the two-weight stacking is structurally part of the mark.
✕ Never Use a logo on a pure white or pure black background — always pair with cream, soil, or the brand gradient.
✕ Never Abbreviate to "GOS" — the wordmark is always "Garden OS", never shortened.
Aesthetic in one sentence

"Warm, grounded, organic.
Reads like a garden journal,
not a SaaS dashboard."

§ 7

CSS Token Reference

Copy these directly into any Garden OS page's :root block.

:root {
  /* ── Soil ── */
  --soil-900: #0f0804;  --soil-800: #1a0f07;  --soil-700: #2d1a0e;
  --soil-600: #3d2210;  --soil-500: #5c3d1e;  --soil-400: #7a5230;
  --soil-300: #9a6b42;  --soil-200: #c8a882;  --soil-100: #e8d5b8;

  /* ── Leaf ── */
  --leaf-900: #0d1f10;  --leaf-800: #1a3520;  --leaf-700: #2a5030;
  --leaf-600: #3a6b42;  --leaf-500: #52924a;  --leaf-400: #6aaa60;
  --leaf-300: #8aba80;  --leaf-200: #b8d8b0;  --leaf-100: #dff0dc;

  /* ── Sun / Amber ── */
  --sun-900: #3d2000;   --sun-800: #6a3800;   --sun-700: #9a5800;
  --sun-600: #c8781a;   --sun-500: #e8a030;   --sun-400: #f5c14a;
  --sun-300: #f8d470;   --sun-200: #fbe8a8;   --sun-100: #fdf5dc;

  /* ── Cream ── */
  --cream-900: #2a2018; --cream-800: #4a3828; --cream-700: #6a5540;
  --cream-600: #8a7258; --cream-500: #aa9070; --cream-400: #c8b090;
  --cream-300: #ddd0b8; --cream-200: #ede5d8; --cream-100: #f7f2ea;
  --cream-50:  #faf8f4;

  /* ── Semantic ── */
  --bg: var(--cream-50);          --bg-panel: var(--cream-100);
  --text: var(--soil-700);        --text-mid: var(--soil-400);
  --text-dim: var(--cream-600);   --border: var(--cream-300);
  --accent: var(--sun-600);       --good: var(--leaf-600);
  --warn: #c85820;                --bad: #b02a1e;

  /* ── Fonts ── */
  --font-display: 'Fraunces', serif;
  --font-body:    'DM Sans', sans-serif;
  --font-mono:    'DM Mono', monospace;

  /* ── Spacing ── */
  --sp-1:4px; --sp-2:8px;  --sp-3:12px; --sp-4:16px;
  --sp-5:20px; --sp-6:24px; --sp-8:32px; --sp-10:40px;
  --sp-12:48px; --sp-16:64px;

  /* ── Radius ── */
  --r-sm:4px; --r-md:8px; --r-lg:12px; --r-xl:16px; --r-full:9999px;
}