NBD Asset Library

Help Guide

A single source of truth for all North Bend Digital brand assets. Built for humans browsing visually and AI agents querying programmatically.

Browsing Assets

Dashboard

Overview of the library with total counts, category breakdown, recently added assets, and a quick search bar.

Browse

Full grid of all assets. Filter by category, format, or tags. Search by keyword across all metadata.

Detail View

Click any asset to see preview, file info, tags, colors, license details, usage notes, and AI context.

Searching

Type in the search bar on any page or press Cmd+K / Ctrl+K to focus it.

Search matches against:

  • Asset ID (the descriptive name)
  • Alt text
  • Description
  • Tags
  • AI context

On the Browse page you can also filter by category, format, and tags using the sidebar.

Copying Asset Info

Every asset card has two quick-copy buttons:

Copy Path

Copies the full URL (e.g. https://images.northbend.io/assets/images/stock/foggy-mountain.webp) for use in code or markup.

Copy Alt

Copies the alt text for accessibility attributes.

The detail page also has a Copy AI Context button with the full description an AI agent would need.

Adding New Assets

  1. Place the original file in src/assets/originals/.
  2. Run optimization: npm run optimize — generates WebP + AVIF at 480w, 768w, 1024w, and 1920w.
  3. Generate manifest entry: npm run manifest:generate.
  4. Fill in metadata in src/data/asset-manifest.json — search for TODO: to find incomplete entries:
    • alt — descriptive alt text (required)
    • tags — from the controlled vocabulary
    • license — type and attribution
    • ai_context — when and how an AI should use this asset
  5. Validate: npm run manifest:validate — check for errors.

Or upload directly via the Upload page — works great on mobile.

Naming Convention

Assets use two descriptive words separated by a hyphen. No spaces, no uppercase.

foggy-mountain.webp flowing-river.webp coffee-beans.webp pennsylvania-elk.webp

AI Agents — Quick Start

The asset manifest is the single source of truth:

src/data/asset-manifest.json

Read this file to discover every available asset with its path, alt text, dimensions, license, tags, and usage recommendations.

Also see /api/assets.json for the full manifest via HTTP. This endpoint is publicly accessible (no auth required), so AI agents can fetch the catalog directly.

Referencing an Asset

Always use two fields from the manifest:

  • path — the URL-accessible file path
  • alt — the alt text (never leave empty)

In HTML

<img src="/assets/images/stock/foggy-mountain.webp"
     alt="a mountain covered in fog with trees in the foreground"
     loading="lazy" />

With responsive variants

<picture>
  <source srcset="/assets/images/stock/foggy-mountain-480w.avif 480w,
                  /assets/images/stock/foggy-mountain-768w.avif 768w"
          type="image/avif" />
  <source srcset="/assets/images/stock/foggy-mountain-480w.webp 480w,
                  /assets/images/stock/foggy-mountain-768w.webp 768w"
          type="image/webp" />
  <img src="/assets/images/stock/foggy-mountain.webp"
       alt="a mountain covered in fog with trees in the foreground" />
</picture>

Finding the Right Asset

JSON API

EndpointDescription
/api/assets.jsonFull manifest (public, no auth required)
/api/asset/{id}.jsonSingle asset metadata (public, no auth required)

Keyword and tag filtering is now done client-side on the Browse page — there is no separate /api/search.json endpoint.

Key manifest fields to check

  • ai_context — when and how to use this asset
  • usage.recommended_for — suggested placements
  • usage.avoid_for — where not to use it
  • tags — semantic labels for filtering

Responsive Images

Most assets have responsive variants in the variants field:

{
  "480w":      "/assets/images/stock/foggy-mountain-480w.webp",
  "768w":      "/assets/images/stock/foggy-mountain-768w.webp",
  "1024w":     "/assets/images/stock/foggy-mountain-1024w.webp",
  "480w-avif": "/assets/images/stock/foggy-mountain-480w.avif",
  "768w-avif": "/assets/images/stock/foggy-mountain-768w.avif",
  "1024w-avif":"/assets/images/stock/foggy-mountain-1024w.avif"
}

Placeholder Strategy

When an asset doesn't exist yet, generate a placeholder:

https://placehold.co/1920x1080/1D451D/FFFFFF?text=Description+Here

Uses NBD brand colors: Black Forest #1D451D with white text #FFFFFF.

License Rules

Always check license.type before using an asset.

TypeRules
originalCreated by North Bend Digital. Unrestricted internal use.
unsplashFree for commercial use. Attribution appreciated but not required.
shutterstockCheck license.usage field. Do not use outside licensed scope.
creative-commonsCheck specific CC variant. Attribution typically required.

Tag Vocabulary

Tags are drawn from a controlled vocabulary in src/data/tags.json:

Brand

pnwnorthwestnorth-bendsnoqualmienbd

Nature

mountainsforestelkantlersmistrivertreesmeadowfogwildlifesunrisesunset

Technology

codescreendevicecloudsecuritynetworkaiautomation

Business

officeteammeetingworkspaceprofessionalclient

Usage

herobackgroundthumbnailcardiconlogofaviconsocialog-imagestock

Style

moodybrightminimaltexturedaerialcloseupportraitlandscape

Color

greenearthdarklightwarmcoolneutral

CLI Commands

CommandWhat it does
npm run devStart local dev server (Next.js) at localhost:3000
npm run swa:startRun SWA CLI on top of Next.js to emulate /.auth/* locally
npm run buildBuild static site for production
npm run seed:siteCrawl northbend.digital and catalog found assets
npm run seed:unsplashPull photos from the Unsplash collection
npm run optimizeGenerate WebP/AVIF variants from originals
npm run manifest:generateScan filesystem and add missing manifest entries
npm run manifest:validateCheck manifest for errors and warnings
npm run testRun the test suite

Brand Colors

Canonical palette defined in the North Bend Digital brand guide. Fonts are Montserrat (headings), Open Sans (body), and Fira Code (monospace).

Black Forest#1D451DPrimary brand color, headers, primary buttons
Prussian Blue#101D42Secondary headers, dark backgrounds, footer accents
Rosy Granite#847D7FSecondary backgrounds, secondary elements
Sky Blue#81AFCAAccents, links (large text only)
Charcoal#333333Primary body text on light backgrounds
Light Gray#F5F5F5Page backgrounds, dividers