Skip to main content
Skip to content

Last updated on 4 June 2026

Customisation Guide — UI07 Ember

Marketing kit · Next.js 16 App Router · Tailwind v4 · TypeScript strict · static export. Brand colour: coral / red, OKLCH hue 22°. Dark mode is the default.

Token Architecture

A 3-tier OKLCH colour system lives in src/app/globals.css:

Tier 1: Primitives  → Named colour stops: --p-accent-50…950 (coral, hue 22°),
                       --p-ink-50…950 (warm near-black, hue 7° = accent − 15°)
Tier 2: Semantics   → Role tokens: --primary, --bg, --card, --border,
                       --text-primary, --gradient-hero, --glow-*, --severity-*
Tier 3: Components  → Tailwind/shadcn arbitrary props: bg-(--card), text-(--primary), …

To re-brand the colour, change the Tier-1 hue in globals.css and everything CSS cascades automatically. Edit the --p-accent-* ramp hue (and, for a matched warm canvas, the --p-ink-* ramp hue to accent − 15). Tiers 2 and 3 inherit; no per-component edits.

The two colour surfaces that are NOT plain CSS

CSS custom properties can't be read by a WebGL shader, a build-time image, or an SSR crash page. UI07 handles each so a re-hue still reaches them:

SurfaceHow it gets the brand colourOn re-hue
Hero FogSphere orb (components/sections/hero.tsx)useBrandColors() (src/lib/use-brand-colors.ts) reads --primary / --p-accent-300 from the live DOM at runtime and re-reads on theme changeAutomatic — follows globals.css, no edit
OG image (app/opengraph-image.tsx)Imports BRAND from src/lib/tokens.tsEdit BRAND in tokens.ts
Crash page (app/global-error.tsx)Imports BRAND from src/lib/tokens.tsEdit BRAND in tokens.ts
Favicon (app/icon.svg)Static SVG fill literalEdit the hex in icon.svg
WebGL fallback uniforms (ambient-glow.tsx, error.tsx)RGB-float triplets (error/danger semantics, not the brand accent)Usually leave — these are status colours

So a full colour re-brand is: globals.css Tier-1 hue + tokens.ts BRAND hexes + icon.svg. Everything else cascades.

src/lib/tokens.ts is the single source of truth for literal-hex contexts. BRAND.primary.accent, BRAND.surface.*, etc. must stay in sync with the OKLCH primitives — the file documents the sRGB equivalents.

Rebranding Checklist

1. src/config/site.ts — brand metadata (single source of truth)

ts
export const SITE_CONFIG = {
  name: "Ember",
  tagline: "Build. Ship. Grow.",
  url: "https://ember.app",
  legal: { /* effective dates, copyright name */ },
  nav: [ /* header nav items */ ],
  social: { twitter, github, linkedin },     // "/#" sentinels hide the icons
  contact: { email, sales, legal, privacy, security },
  legalEntity: { companyName, companyNumber, placeOfRegistration, registeredAddress, vatNumber, regulator, regulatorNumber },
  regions: { uk, eu, us },                   // toggles region-conditional legal links
  compliance: { dmca, ccpa, modernSlaveryStatementUrl },
};

Every page reads SITE_CONFIG. The legalEntity defaults are deliberate REPLACE WITH … sentinels (Gate 17 compliance — an unedited build is visibly wrong, not plausibly-real). Fill them with your real registered-entity details before publishing.

2. src/app/globals.css — colour

  • Coral hue: change 22 → your hue in the --p-accent-* ramp (lines under "PRIMITIVE: Coral accent ramp"). For a non-warm brand, also set the --p-ink-* ramp hue to your-hue − 15.
  • Chroma: the ramp ships at 0.17 (a clean coral). Bump toward 0.20 for more saturation if your hue tolerates it.
  • Semantic coral tokens (--gradient-hero, --glow-*, --heat-*, --gradient-edge) carry the hue inline — they're updated alongside the ramp (search the file for the hue number).

3. src/lib/tokens.ts — literal-hex fallbacks

Update BRAND.primary.accent / .hover / .accentRgb / .glow / .muted and BRAND.surface.* to the sRGB equivalents of your new OKLCH values (convert at oklch.com or via the canvas trick useBrandColors uses). Feeds the OG image, crash page, and any WebGL default.

4. src/app/icon.svg — favicon

Static SVG. Update the <rect fill="…"> to your brand hex.

5. Fonts — src/app/layout.tsx + globals.css

The kit loads two fonts in layout.tsx:

  • Sans / body: Geist via next/font/google--font-geist-sans--font-sans
  • Display / headings: Cabinet Grotesk (Fontshare) self-hosted via next/font/local from src/app/fonts/CabinetGrotesk-Variable.woff2--font-cabinet--font-display. It's a variable font (weight 100–900) and is bundled locally, so the build has no font CDN dependency. Licence: src/app/fonts/CabinetGrotesk-LICENSE.txt (free for commercial use).

To change the display font: drop your woff2 in src/app/fonts/, update the localFont({ src }) path in layout.tsx, and keep the --font-cabinet variable (or rename it and update --font-display in globals.css). Headings use font-display; body uses the default sans.

6. public/ + OG image

  • Favicon is src/app/icon.svg (above). Replace public/ brand assets (logos) as needed.
  • The social share image is generated at build time by src/app/opengraph-image.tsx (reads SITE_CONFIG + BRAND) — no static og-image.png to replace; restyle the component if desired.

7. Demo content

Every page with sample content carries a /* DEMO_CONTENT */ header. See DEMO_CONTENT.md for the full replacement inventory.

Kit-specific surfaces

  • Hero orb (components/sections/hero.tsxfog-sphere.tsx): a ray-marched coral fog-orb. Colour auto-tracks --primary via useBrandColors(). Tune size/motion through the <FogSphere> props (sphereRadius, brightness, turbulence*, opacity). A theme-aware contrast scrim sits between the orb and the hero text.
  • Audience cluster map (components/ui/audience-cluster-map.tsx): the signature visualisation. Cluster tones read var(--p-accent-500) / --p-status-bounced / --p-cluster-dormant — re-hues with the brand.

Dark / Light Mode

Dark is the default (className="… dark" on <html> in layout.tsx). Light mode applies via the .light class (theme toggle). All tokens have light-mode values under the @variant dark / light blocks in globals.css; the scrim and orb are theme-aware. Test both.

Adding New Pages

  1. Create src/app/your-page/page.tsx.
  2. Import Navbar / Footer from @/components/layout/.
  3. Use semantic tokens only — text-(--fg), bg-(--card), text-(--primary), border-(--border), --severity-* for status. Never hardcode hex or Tailwind named colours (bg-violet-500, etc.) — they won't follow a re-hue.
  4. Use font-display for headings, animate-enter for entrance.

Template Empire — Halbon Labs — UI07 Ember