box brand

Generate the console’s theme from a brand.json file.

box brand [--init] [--force]

Synopsis

box brand reads a brand.json definition and generates the theme tokens the Next.js console consumes — a CSS-variable override file, the logo copied into the console, and the NEXT_PUBLIC_BOX_* branding environment variables. It is local-first: nothing is sent to the control plane.

Must be run inside a box (a directory created by box create).

Options

OptionDescription
--initScaffold a starter brand.json instead of applying one.
--forceOnly meaningful with --init: overwrite an existing brand.json, resetting it to defaults.

Behavior

  • box brand (no options) reads brand.json and applies it:
    • writes the generated stylesheet to console/src/app/box-theme.generated.css (imported by the console layout after globals.css so its variables win),
    • copies the logo file into the console,
    • upserts NEXT_PUBLIC_BOX_NAME and NEXT_PUBLIC_BOX_LOGO into console/.env.local.
  • box brand --init scaffolds a starter brand.json (for boxes created before branding existed; box create already ships one). It refuses to overwrite an existing file unless you add --force.

box start clears the console’s .next cache, so restarting the box picks up a regenerated theme. After editing brand.json and running box brand, run box start to see the changes.

brand.json

The committable, secret-free branding declaration for a box’s console. Friendly aliases under theme.colors and theme.button map onto the design system’s real CSS variables; anything not covered can be set verbatim through theme.css.

brand.json
{
  "name": "Box Dashboard",
  "logo": "assets/logo.svg",
  "theme": {
    "colors": {
      "brand": "#2563eb",
      "accent": "#111827",
      "background": "#ffffff",
      "surface": "#f5f5f5",
      "text": "#111827",
      "link": "#2563eb",
      "success": "#16a34a"
    },
    "button": {
      "radius": "0.5rem"
    },
    "css": {},
    "dark": {
      "colors": {
        "brand": "#3b82f6",
        "accent": "#f3f4f6"
      }
    }
  }
}

Top-level fields

FieldTypeDescription
namestring?Display name (dashboard title) → NEXT_PUBLIC_BOX_NAME.
logostring?Path (relative to the box root) to a logo image, copied into the console → NEXT_PUBLIC_BOX_LOGO.
themeobject?Colors, button radius, raw CSS, and a nested dark block.

theme.colors

Each key is a friendly alias that maps to a design-system CSS variable. Values must be non-empty strings (any valid CSS color). Unknown keys are rejected — use theme.css for raw tokens.

AliasCSS variableMeaning
brand--brand-500Primary brand color.
accent--accent-primaryAccent / primary action color.
accentHover--accent-hoverAccent hover (defaults to accent).
accentActive--accent-activeAccent active/pressed (defaults to accent).
background--bg-basePage background.
surface--bg-elevatedElevated surface background.
text--text-primaryPrimary text color.
link--text-linkLink color.
success--accent-successSuccess color.

Set accent without accentHover/accentActive and the CLI derives those interactive states from accent, so hovers stay on-brand.

theme.button

FieldTypeCSS variableDescription
radiusstring?--radiusCorner radius for buttons and cards.

theme.css

An escape hatch: a map of raw --token: value overrides applied verbatim. Keys must start with --; values must be non-empty strings.

brand.json (excerpt)
"css": {
  "--ring": "#2563eb",
  "--shadow-color": "220 3% 15%"
}

theme.dark

Dark-mode overrides with the same shape as theme (colors, button, css). These are emitted under the .dark selector; the light block is scoped to :root:not(.dark) so dark mode falls through to your overrides plus the template’s defaults.

Examples

# Scaffold a starter brand.json (won't clobber an existing one)
box brand --init
 
# Reset brand.json back to defaults
box brand --init --force
 
# Apply brand.json → generate the console theme
box brand

See also