# Open Brand Format 1.1

Open Brand Format (OBF) describes a brand kit as a predictable package. People, agencies and AI agents can read it without guessing. A brand publishes it as a zip, and as three stable URLs on its brand page.

## Package layout

A package is a zip. Folder and file names are fixed. `{slug}` is the brand's workspace slug.

```
{slug}-brand/
  VERSION.txt              format and version of this package
  BRAND.md                 read this first
  brand.json               manifest, the source of truth for exact values
  logos/
    {variant}/             primary/, reversed/, icon/, or other variants
      {name}.svg|.png      original file
      {name}.png           PNG render, only when the original is SVG
      {name}.eps|.pdf      print files, when the brand adds them
  graphics/
    {name}.{ext}
  colours/
    colours.json
    colours.css
    colour-cards.pdf       every palette as colour cards, one page each
    cards/{palette}-{name}.png   one colour card per colour
  type/
    fonts/{family}/        Google Fonts: licence, ttf/, woff2/, woff/
                           uploaded fonts: their files, only if the brand allows download
    fonts.md               every family, with its source
    text-styles.json
    text-styles.css
  guidelines/
    {name}.pdf
  collections/
    {collection}/          approved assets, one zip each, same root
      VERSION.txt          format and version of this collection zip
      USAGE.md             credit line, allowed channels, use-until date
      collection.json      the collection's manifest entry, package-relative
      {name}.{ext}         original files
```

Rules:
- Names are kebab-case ASCII.
- If two names collide, the later one gets `-2`, then `-3`.
- A section the brand hides is left out of the whole package.
- A folder with no content is not created. `colours/` and the `type/` files appear only when that section has content.
- Every zip says its version three ways: the download name ends in `-obf-{version}.zip` (for example `jam-content-brand-obf-1.1.zip`), `VERSION.txt` states `format` and `version`, and `brand.json` and `collection.json` start with them.
- Font files are named `{family}-{weight}.{ext}`. Italic files are named `{family}-{weight}-italic.{ext}`.
- The main zip never holds `collections/`. Each collection downloads as its own zip. Its files sit under the same `{slug}-brand/` root, so the zips unpack into one folder.

## brand.json

```json
{
  "format": "open-brand-format",
  "version": "1.1",
  "brand": {
    "name": "Jam",
    "url": "https://jamcontent.com/jam/brand",
    "updated_at": "2026-10-13T00:00:00+00:00"
  },
  "info": [
    { "heading": "Brand info", "body": "Always write Jam with a capital J." }
  ],
  "logos": [
    {
      "name": "Primary",
      "variant": "primary",
      "background": "#000000",
      "files": [
        { "path": "logos/primary/primary.svg", "url": "https://jamcontent.com/jam/brand/files/asset/7a1c", "type": "image/svg+xml" },
        { "path": "logos/primary/primary.png", "url": "https://jamcontent.com/jam/brand/files/asset/7a1c?format=png", "type": "image/png" }
      ]
    }
  ],
  "graphics": [
    {
      "name": "Jam pattern",
      "background": null,
      "files": [
        { "path": "graphics/jam-pattern.png", "url": "https://jamcontent.com/jam/brand/files/asset/92be", "type": "image/png" }
      ]
    }
  ],
  "colours": [
    {
      "palette": "Primary",
      "name": "Jam Red",
      "hex": "#FD385A",
      "rgb": [253, 56, 90],
      "hsl": [350, 98, 61],
      "pantone": "PANTONE 1787 C"
    }
  ],
  "fonts": [
    {
      "family": "Figtree",
      "source": "google",
      "url": "https://fonts.google.com/specimen/Figtree",
      "files": []
    },
    {
      "family": "Manrope",
      "source": "uploaded",
      "files": [
        { "path": "type/fonts/manrope/manrope-700.woff2", "url": "https://jamcontent.com/jam/brand/files/font/3d40", "weight": 700, "style": "normal" }
      ]
    }
  ],
  "text_styles": [
    {
      "name": "Heading",
      "font_family": "Figtree",
      "font_size": 48,
      "font_weight": 700,
      "italic": false,
      "line_height": 1.1,
      "letter_spacing": 0,
      "fill": "#071D49"
    }
  ],
  "guidelines": [
    {
      "name": "Brand guidelines 2026",
      "path": "guidelines/brand-guidelines-2026.pdf",
      "pages": 24,
      "bytes": 2400000,
      "url": "https://jamcontent.com/jam/brand/files/asset/c5f0",
      "cover": "https://ik.imagekit.io/jam/edits/c5f0-cover.jpg"
    }
  ],
  "collections": [
    {
      "id": "8f2c…",
      "name": "Launch day",
      "layout": "grid",
      "credit": "Photo: Jam",
      "channels": ["social", "press"],
      "expires_on": "2026-12-31",
      "gallery": "https://jamcontent.com/jam/launch-day",
      "download": "https://jamcontent.com/jam/brand/collections/8f2c…/download",
      "count": 48,
      "files": [
        {
          "name": "Lap 1.jpg",
          "path": "collections/launch-day/lap-1.jpg",
          "type": "image/jpeg",
          "url": "https://jamcontent.com/jam/brand/files/media/41aa…",
          "preview": "https://ik.imagekit.io/jam/…/lap-1.jpg"
        }
      ]
    }
  ]
}
```

### Fields

| Field | What it holds |
|---|---|
| `format` | Always `open-brand-format`. |
| `version` | `major.minor`, for example `1.1`. |
| `brand` | `name`, `url` (the public brand page) and `updated_at`. |
| `info` | The brand's written rules, in page order. Each has `heading` and `body`. |
| `logos` | Each entry has `name`, `variant`, `background` and `files`. `background` is the colour the logo was designed to sit on, or `null` for transparent. `files` holds every format of that logo: screen files (SVG, PNG) and print files (EPS, PDF). |
| `graphics` | As `logos`, without `variant`. |
| `colours` | `hex` is uppercase. `rgb` is `[r, g, b]`. `hsl` is `[h, s, l]` in degrees and percent. `pantone` is `null` if not set. A colour that cannot be parsed is left out. |
| `fonts` | `source` is `google` or `uploaded`. A Google font has a specimen `url`. An uploaded font lists files only when the brand allows download; otherwise `files` is empty: licensed, not included. `download`, when present, is the whole family as one zip. |
| `text_styles` | Named styles. `font_family` matches a `fonts[].family`. |
| `guidelines` | PDF files with `name` and `path`. `pages` and `bytes` are optional. Online copies can have `cover`, an image of the first page. |
| `collections` | Approved assets (1.1). See below. |

### File entries

| Field | What it holds |
|---|---|
| `path` | Package-relative, for example `logos/primary/jam.svg`. |
| `type` | MIME type, on logo, graphic and collection files. Print files are `application/postscript` (EPS) or `application/pdf`. |
| `weight`, `style` | On font files. |
| `url` | Online copies only: the absolute file URL. An SVG always has a PNG render beside it; online, that is the same URL with `?format=png`. |

`type/fonts.md` lists each family with one of three notes: a Google Fonts link with its open-source files in `fonts/{family}/`, `included in fonts/`, or `licensed, not included`. Google Fonts files are TTF (static and variable), with WOFF2 and WOFF made from them, and the family's licence.

### Collections (1.1)

Approved assets: photos, video and other files the brand allows others to use, with their usage rights.

| Field | What it holds |
|---|---|
| `name` | The collection name. |
| `credit` | The credit line to show with the assets, or `null` when none is needed. |
| `channels` | Where the assets may be used: `social`, `web`, `print`, `press`, `broadcast`, `advertising`, `internal`. Empty means any channel. |
| `expires_on` | The last day (`YYYY-MM-DD`, UTC) the assets may be used, or `null`. After that day the collection leaves the page and the manifest. |
| `gallery` | The collection's public gallery. |
| `download` | The collection's own zip. |
| `count` | How many files are listed. |
| `files` | The newest 500 files at most. A file past its own expiry is left out. Online files have `url` (the original) and can have `preview` (an image). The zip copy keeps `path` and drops `url` and `preview`. |

### Package paths and online URLs

- The `brand.json` inside the zip uses package-relative paths only. File entries have `path` and no `url`. The folder works offline.
- The `brand.json` served online has the same package-relative `path` values (for example `logos/primary/primary.svg`, with no `{slug}-brand/` prefix) plus an absolute `url` on each file. An agent can fetch each file directly.
- `brand.url` is the public brand page. Online, `BRAND.md` links to absolute URLs. In the zip, it links to relative paths.

## BRAND.md

`BRAND.md` is generated plain markdown. The order is fixed:

1. `# {Brand name}`, then one line with the brand page URL and the updated date.
2. Each info section, copied as written, in page order.
3. Logos: one line each with name, variant, intended background and file links.
4. Graphics: one line each with name and file links.
5. Colours: a table with name, hex, RGB, HSL and Pantone.
6. Type: families with their sources, then a table of text styles.
7. Guidelines: links.
8. Approved assets: one line each with name, file count, gallery and zip links, credit, channels and use-until date.
9. A footer: `Open Brand Format 1.1. Machine-readable: brand.json`.

A section with no content is left out.

## CSS files

`colours/colours.css` declares one custom property per colour:

```css
:root {
  --primary-jam-red: #FD385A;
}
```

The name is `--{palette}-{name}`, kebab-case.

`type/text-styles.css` declares one class per text style:

```css
.text-heading {
  font-family: "Figtree";
  font-size: 48px;
  font-weight: 700;
  font-style: normal;
  line-height: 1.1;
  letter-spacing: 0px;
  color: #071D49;
}
```

## Discovery

A brand page that publishes OBF serves these stable URLs. `{page}` is the brand page URL, for example `https://jamcontent.com/jam/brand`.

| URL | Returns |
|---|---|
| `{page}/brand.json` | The manifest, with absolute file URLs |
| `{page}/brand.md` | `BRAND.md`, as `text/markdown` |
| `{page}/download` | The zip package |
| `{page}/colours.pdf` | The colour cards as one PDF |
| `{page}/collections/{id}/download` | One approved-asset collection as a zip |
| `{page}/fonts/{family}/download` | One font family as a zip |

The page HTML also links the two text files in its head:

```html
<link rel="alternate" type="text/markdown" href="{page}/brand.md">
<link rel="alternate" type="application/json" href="{page}/brand.json">
```

A client can find a package from the page URL alone.

## For agents

- Read `BRAND.md` first.
- Use `brand.json` for exact values. Do not estimate colours or sizes from images.
- Never alter a logo. Do not recolour, stretch, crop or add effects.
- Put a logo on its listed `background`. Use a variant meant for the background you have.
- Follow the info sections as rules. They hold naming and usage terms.
- Use only the fonts listed. If a font has no files, do not ship it. Link to its source.
- Check `brand.updated_at` before you reuse a cached copy.
- Use approved assets only on their listed `channels`, with their `credit`, and not after `expires_on`.

## Versioning

- The version is `major.minor`. This document describes 1.1.
- 1.1 added `collections`, `VERSION.txt`, versioned zip names, print files on logos and graphics, font family downloads, and the `pages`, `bytes` and `cover` fields on guidelines.
- Adding a field or an optional section keeps the major version. It becomes 1.1, 1.2 and so on.
- Removing or renaming a field, or changing the meaning of a field, makes a new major version (2.0).
- Readers must ignore fields they do not know.
- Readers should check `format` and the major version before they read the rest.
