B&J — five structural craft signals worth surfacing in case-study narrative (v2)
Five structural details surfaced in the v2 sweep that would read well in a case study — each verifiable from the repo or live site.
1. Two-tier component model (kit primitives + sections), enforced by convention
The repo deliberately splits src/components/ui/kit/ (19 single-concept primitives — buttons, dark surfaces, gauges) from src/components/sections/ (33 labelled, aria-labelled page sections composed from primitives).
- Pages compose sections, never primitives directly.
- The trigger to promote inline JSX into a real section is the second occurrence of the pattern.
- Documented in
src/components/sections/SECTIONS.md. - Result: App Router page files stay thin — typically 50–150 lines of "configuration" against typed content modules.
2. Schema infrastructure is helper-ised, not hand-rolled per page
Every JSON-LD block on the site goes through one of 9 functions in src/lib/schema.ts (organizationSchema, localBusinessSchema, breadcrumbSchema, buildBreadcrumbFromPath, faqPageSchema, articleSchema, serviceSchema, etc.).
- The Organization
@idis a single canonical entity emitted once in the root layout. - Every per-page schema references it via
{ "@id": ORG_ID }. - An audit can land on any page (homepage, vertical hub, resource article, location page) and find a consistent graph — no duplicated literal in any page file.
See B&J — JSON-LD schema deployment VERIFIED (v2) — supersedes the "biggest technical gap" claim in v1 for the live verification.
3. Service-functions-own-the-DB convention, lint-enforced
ESLint bans pg imports outside src/lib/. Combined with the "thin route handler" pattern, this means a future portal split (data layer → separate Express service) is a mechanical extraction, not a rewrite.
The migration rationale is documented in CLAUDE.md ("the three migration rules") — worth quoting in the case study as an example of architectural foresight that costs almost nothing today but pays off when the contract for the portal is signed.
4. Strict-from-day-one TypeScript + husky-gated commits
strict: truenoUnusedLocalsnoUnusedParametersnoFallthroughCasesInSwitchnoImplicitOverrideallowJs: false- ESLint runs with
--max-warnings 0(warnings are errors) - Both gated via husky pre-commit
185 commits in, the lint baseline has held — zero // @ts-ignore, zero any without rationale.
5. Single design-token source, no Tailwind config file
Tokens live in src/app/globals.css inside a @theme inline block (Tailwind v4 pattern). Brand colours, surface tokens, type scale, motion easings, layout dimensions — all expressed once as CSS custom properties, surfaced through Tailwind utilities.
The whole site renders against one --color-surface-card-dark (#141413) for every dark surface — no near-blacks, no alternate shades.
CLAUDE.mdspells out the rule and the rationale: two near-blacks side-by-side on/agriculture"read as cheap."
A small detail that materially distinguishes the site from a default shadcn build. See B&J — image and asset inventory (v2, verified 2026-05-24) for the broader "type + color + CSS shape, not imagery" approach this enables.
Related
- reference B&J marketing site stack (`bj-next`, dev URL `bjweb.candidcreative.ca`) — VERIFIED LIVE STACK
- reference B&J architectural decisions worth surfacing in case-study narrative — eight, ranked
- reference B&J — JSON-LD schema deployment VERIFIED (v2) — supersedes the "biggest technical gap" claim in v1