Michael L. Lawson

Project case study

Brand system + product / 2026

Forge City Circuit

One city. Every season.

A civic sports identity carried from a single forged shield into a 3D crest and a working fan portal for eight neighborhood franchises across three sports.

Explore live project
Project
Self-initiated concept
Role
Creative Direction + Design + Development
Built with
JavaScript ES modules · Three.js · HTML · CSS
Code
View on GitHub ↗
Forge City Circuit project home: One city. Every season. with the 3D shield
The live project home with the interactive 3D crest.

01 / The brief

A brand that survives a real product.

Forge City Circuit is a fictional amateur league: eight neighborhood franchises playing baseball, basketball and flag football.

The challenge was not to draw a crest. It was to build an identity flexible enough to organize three sports and eight teams across standings, schedules, rosters and playoffs without losing its character.

02 / Identity system

One shield, worn three ways.

  • A chamfered steel shield, six rivets and one central field form the fixed grammar.
  • Sport icons and accent colors do the variable work: red for baseball, orange for basketball, steel blue for flag football.
  • A simplified mark takes over at small sizes, where rivets and fine lines would turn to noise.
  • The same silhouette and rivet positions become a 3D crest in Three.js, with drag and arrow-key rotation and a static SVG fallback.

03 / The key decision

No framework for the fan portal.

The portal has five views: home, standings, schedule, bracket and team pages. Each reads from one JSON season snapshot. That is small enough that a framework would add more than it saves.

So the portal is plain JavaScript ES modules and a hash router under 50 lines. There is no build step, the code is easy to follow, and it deploys as static files.

The trade-off: every view manages its own DOM updates. If the data became live and the views grew more interactive, I would move to a component framework.

portal/js/router.js ↗
export function route(pattern, render) {
  const segments = pattern.split('/').filter(Boolean);
  routes.push({ segments, render });
}

async function dispatch() {
  const hash = location.hash.replace(/^#\/?/, '');
  const found = match(hash.split('/').filter(Boolean));
  window.scrollTo(0, 0);
  if (found) await found.render(found.params);
  else onNotFound();
}
Forge City Circuit fan portal with standings for all three sports, upcoming games and latest results
Portal home: standings for all three sports, next games and latest results.
Forge City Circuit baseball playoff bracket
Playoff bracket generated from the same season data.

04 / Data

Every view tells the same story.

Standings, schedules, rosters and brackets all come from one deterministic season snapshot covering eight teams across three sports. A score shown on the home page matches the standings, the schedule and the bracket, because they are all calculated from the same source.

Forge City Circuit project home on a phone with the 3D shield
Phone: project home and 3D crest
Forge City Circuit standings on a phone
Phone: standings by sport

05 / Scope & next steps

Built deliberately. Scoped honestly.

The league, teams, venues, scores and schedules are fictional portfolio content, shown as a fixed snapshot.

There are no automated tests yet.

Next: smoke tests that load every portal route, plus a check that standings, schedules and brackets agree with the source data.

EXPLORE THE WORK

See the experience
in motion.

Open Forge City Circuit