{
  "notes": [
    "Brand assets are slots, not values — the file-level equivalent of semantic roles. Rebrand by replacing file contents at these exact paths; consumers render identity artwork through the canonical ds-brand-asset recipe and never use bespoke paths or substitute artwork.",
    "The slot set describes identity architecture, not one brand's. Only wordmark, favicon and fonts are required — every brand has a name, a tab and a typeface. mark, wordmark-stacked and lockup are the forms a brand may or may not own, and a brand that lacks one deletes its slot rather than aliasing another drawing into it. A slot present here must have its file; a slot absent here is absent from the brand.",
    "The shipped identity assets and Geist typography are the active brand defaults; consumers inherit them through the same canonical slots and font roles used for any later rebrand."
  ],
  "slots": {
    "mark": {
      "file": "brand/mark.svg",
      "status": "ready",
      "aspect-ratio": 1,
      "required": false,
      "purpose": "the symbol alone, with no name attached; the brand at small sizes, in tight spaces, and as a social avatar",
      "color": "currentColor — single-color, adapts to the surface it sits on",
      "min-size": "24px"
    },
    "wordmark": {
      "file": "brand/wordmark.svg",
      "status": "ready",
      "aspect-ratio": 5.5,
      "required": true,
      "purpose": "the name alone, set in the brand face, no symbol; the horizontal primary orientation",
      "color": "currentColor — single-color",
      "min-width": "96px"
    },
    "wordmark-stacked": {
      "file": "brand/wordmark-stacked.svg",
      "status": "ready",
      "aspect-ratio": 2.7037037037,
      "required": false,
      "purpose": "the same name alone, stacked onto two or more lines; an orientation of the wordmark, not a different asset, for spaces too narrow to take the horizontal one",
      "color": "currentColor — single-color",
      "min-width": "72px"
    },
    "lockup": {
      "file": "brand/lockup.svg",
      "status": "ready",
      "aspect-ratio": 3.6666666667,
      "required": false,
      "purpose": "mark + wordmark locked into one fixed relationship; the full signature. Only brands that own both a symbol and a name have one — a wordmark-only brand has no lockup, and stacking the wordmark does not make it one",
      "color": "currentColor — single-color",
      "min-width": "128px"
    },
    "favicon": {
      "file": "brand/favicon.svg",
      "required": true,
      "purpose": "browser tab and bookmark icon",
      "mode": "adaptive-monochrome",
      "color": "adaptive-monochrome normalizes one paint to currentColor and answers the OS theme via prefers-color-scheme; use self-colored only when preserving multiple intentional brand colors"
    },
    "fonts": {
      "file": "brand/fonts.css",
      "required": true,
      "purpose": "@font-face home for the Geist Sans and Geist Mono variable brand faces",
      "pairing": "font.family.* tokens name available stacks; font.role.* maps consumer roles to those stacks. This slot delivers the custom faces. Font files live beside it (brand/*.woff2).",
      "fallbacks": [
        {
          "for-family": "Geist",
          "family": "Geist Fallback",
          "local": "Arial",
          "file": "brand/geist.woff2",
          "metrics": {
            "size-adjust": 102.31,
            "ascent-override": 98.72,
            "descent-override": 28.35,
            "line-gap-override": 0.0,
            "corpus-sha256": "146895b56c042b1bfa4f5972ffb946aa0ce7f1ff53b99c3c28692414f873c578",
            "source-sha256": "a369fcf5628ea2aa4e1b9e2ec6a5b3624e365bda588e1f0f2f12b564f728fbb8"
          }
        },
        {
          "for-family": "Geist Mono",
          "family": "Geist Mono Fallback",
          "local": "Courier New",
          "file": "brand/geist-mono.woff2",
          "metrics": {
            "size-adjust": 99.98,
            "ascent-override": 101.02,
            "descent-override": 29.0,
            "line-gap-override": 0.0,
            "corpus-sha256": "146895b56c042b1bfa4f5972ffb946aa0ce7f1ff53b99c3c28692414f873c578",
            "source-sha256": "fba8f577f38a2bbcbe818efa6348dd58f36303a10b8737c42fefad275be563ab"
          }
        }
      ]
    }
  },
  "rules": [
    "Never recolor, distort, rotate, or add effects to a brand asset per instance.",
    "Each artwork slot declares one aspect-ratio. Run scripts/export_brand.py after changing the manifest so the web adapter and BrandAsset contract refresh from that single source.",
    "Set status to pending while declared artwork is not yet delivered; the specimen presents a pending state instead of reviewing placeholder art as final. Ready slots must ship their declared files.",
    "A slot may declare an on-dark polarity drawing and a small optical cut. Polarity follows the theme unless an on-light/on-dark modifier names the surface; a small cut switches from the asset's rendered width through a container query, never from a consumer-guessed size class.",
    "Identity artwork stays single-color currentColor; favicon mode is adaptive-monochrome by default and self-colored only for intentional multicolor art.",
    "Below a slot's minimum size, step down the ladder to the next form the brand actually owns: lockup to wordmark to mark — never scale past legibility, and never step to a slot this brand has not declared.",
    "Clearspace around the mark is at least a quarter of its height on every side.",
    "In app bars (topbars, sidebars) identity renders at about half the bar height, clamped to 20–28px: the lockup where the brand has one, the wordmark where it does not. When the bar cannot afford that width, use the mark alone.",
    "On web, render identity artwork through ds-brand-asset so the external SVG acts as a currentColor mask; never replace the mark with an i-* interface icon or reconstruct the wordmark as live text.",
    "After replacing favicon.svg, run scripts/prepare_favicon.py: adaptive-monochrome normalizes the uploaded silhouette and injects the neutral-anchor OS-theme colors; self-colored preserves the upload unchanged.",
    "Declare only the forms the brand owns, and never fill a slot with a copy of another. A slot exists so consumers can reference it blindly; a slot aliased to a neighbor keeps that guarantee by lying about what the artwork is, and the lie is load-bearing — headers place a lockup at lockup proportions and get a wordmark. Delete the slot instead: the specimen then shows the form as absent rather than showing the same drawing twice under two names.",
    "Custom faces load from brand/fonts.css with the files beside it; never inline @font-face into generated adapters (web/theme.css is regenerated).",
    "Every custom first family declares a metric-matched local fallback in slots.fonts.fallbacks. Run scripts/prepare_fonts.py after changing the face, file, or fallback: it measures a real text corpus, writes size/ascent/descent/line-gap overrides, and inserts the generated fallback immediately after the brand face in font.family.*."
  ]
}
