Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/brutalist. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
9.5 KiB
Brutalist — Build Report
Theme slug: brutalist
Module path: git.dev.alexdunmow.com/block/themes/brutalist
Tech: templ-style (gotham-pattern), per spec §11.
Implementation pass: wave-1 (fonts policy applies — fonts.json = []).
What landed
Module + metadata
plugin.modper spec §2 verbatim:kind = "theme",scope = "@themes",version = "0.1.0",categories = ["templates"], tags array exactly the 8 spec values,[compatibility] block_core = ">=0.11.0 <0.12.0".go.modpinned togit.dev.alexdunmow.com/block/core v0.11.1,go 1.26.4, noreplacedirectives.Makefiledefault target buildsbrutalist.soviaCGO_ENABLED=1 go build -buildmode=plugin. Norebuildtarget (per agent scope; deploy is explicit).
System / page templates / blocks
- System template registered:
brutalist("Brutalist", spec description verbatim). - 4 page templates registered with exact spec slot arrays:
default→{header, main, footer}→RenderBrutalistlanding("Index Sheet") →{hero, ledger, footer}→RenderBrutalistLandingarticle("Case Study") →{header, meta, main, footer}→RenderBrutalistArticlefull-width("Full Bleed") →{header, main, footer}→RenderBrutalistFullWidth
- 7 theme blocks registered (all
Source: "brutalist"):masthead,project_ledger,concrete_hero,meta_strip,caption_image,pull_quote,colophon
- 4 built-in block overrides via
RegisterTemplateOverride("brutalist", ...):heading,text,button,image— spec §9 treatments (square corners, font-display, mono code, figure wrapping).
- Email wrapper registered via
tr.RegisterEmailWrapper("brutalist", BrutalistEmailWrapper).
Master pages
3 master pages in DefaultMasterPages() per spec §7 row-by-row:
brutalist:default-master→ templates[default, article], blocks navbar/masthead/slot(main)/colophon(showAddress=true)brutalist:index-master→ template[landing], blocks masthead(hero)/slot(ledger)/colophon(showAddress=true)brutalist:fullbleed-master→ template[full-width], blocks navbar/slot(main)/colophon(showAddress=false)
Schemas
7 draft-07 schemas in schemas/<key>.schema.json. x-editor values used: text, richtext, media, select, textarea, collection, link. All inside the allowed set per CLAUDE.md.
br.LoadSchemasFromFS(Schemas())is called BEFORE anybr.Register(...)inregister.go— verified by reading top-to-bottom.
Presets
presets.json ships two presets:
concrete-red(modeboth) withlightColors+darkColors, all 19 tokens each, HSL triple strings only.hazard-yellow(modedark) with bothdarkColorsand a mirrorlightColorsfor editor preview, all 19 tokens each.- Spot values from spec verbatim:
concrete-red.lightColors.background = "40 14% 93%",concrete-red.lightColors.primary = "4 86% 48%",hazard-yellow.darkColors.primary = "48 100% 50%",hazard-yellow.darkColors.background = "0 0% 6%". - check-safety presets check (Check 21): OK.
CSS
CSSManifest.InputCSSAppend ships utility CSS via ThemeCSSManifest():
:where(.brutalist-page, .brutalist-page *) { border-radius: 0 !important; }(kills rounding theme-wide)..brutalist-display,.brutalist-monofont utilities flowing throughvar(--font-heading|body|mono, <fallback-stack>).- Hairline / thick rule utilities (
.brutalist-rule-ink,.brutalist-rule-thick,.brutalist-divider). - 12-column grid scaffolding (
.brutalist-grid-12,.brutalist-col-span-8). - Block-specific styles for
.brutalist-masthead,.brutalist-hero,.brutalist-ledger-row,.brutalist-meta-strip,.brutalist-pullquote,.brutalist-figure figcaption,.brutalist-colophon. - Square buttons + hover-invert-to-accent (spec §9 button override surface).
- Togglable
body.brutalist-grid-debug12-col overlay (UAT §13.11). - All color references go through
hsl(var(--token)); no hex/rgb/named colors anywhere in*.go,*.templ, or the appended CSS (Check 6 OK).
Fonts (wave-1 policy)
fonts.json = [](per FONTS.md override of spec §5 / UAT §11).assets/contains only a.gitkeep; no woff2 bundled.- All
font-familydeclarations in templates and CSS go throughvar(--font-heading|body|mono, <fallback>)with fallback stacks derived from the spec typography list (Space Grotesk → Inter Tight → Helvetica; Inter → -apple-system → Segoe UI; JetBrains Mono → IBM Plex Mono → ui-monospace). RECOMMENDED_FONTS.mdwritten at the theme root listing the spec §5 fonts as Google Fonts picker recommendations with admin instructions.
Build output
$ make
CGO_ENABLED=1 go build -buildmode=plugin -ldflags="-s -w" -o brutalist.so .
$ ls -la brutalist.so
-rw-rw-r-- 1 alex alex 21522624 brutalist.so
- File:
brutalist.so(~20.5 MB; gotham reference.sois 21.1 MB, lcars is similar). - No stderr warnings.
templ generateproduced 13_templ.gofiles (committed alongside.templsources).
Safety check
Run from the actual check-safety location (the path in the spec's instructions points at ~/src/blockninja/backend/cmd/check-safety but the real tool lives at ~/src/blockninja/check-safety/).
$ cd /home/alex/src/blockninja/check-safety
$ go run . /home/alex/src/blockninja/themes/brutalist --plugin-dir /home/alex/src/blockninja/themes/brutalist
... (all 22 checks)
exit=0
Key results:
- Check 2c (Standalone plugin SDK import boundaries): OK — pinned to v0.11.1, no
replacedirectives. - Check 3 (Go lint pipeline): OK after dropping unused
brutalistAccent,brutalistAccentFg,brutalistEmailCTAStyle, andrenderPagehelpers. - Check 6 (No hardcoded colors in .templ): OK — all color references use
hsl(var(--token)). - Check 11 (No placeholder code): OK.
- Check 17 (No TODO markers): OK.
- Check 21 (presets.json validation): OK.
- Check 22 (No hand-rolled HTML sanitization): OK.
Warnings (non-fatal):
- Check 2e (
anyusage): 30 warnings, all from the required SDK signaturefunc(ctx context.Context, content map[string]any) stringandMasterPageBlock.Content map[string]any. Cannot be removed without breaking the SDK contract; same surface gotham exposes.
Overall: exit 0, plugin builds, safety passes.
Open items / deferred
These items are explicitly deferred per the agent's hard scope rules ("local-build only, no woff2 bundling, no live deploy, no screenshots") and the FONTS.md wave-1 policy:
- Bundled woff2 files — wave-2 follow-up. Currently
fonts.json = [];RECOMMENDED_FONTS.mdcovers the admin path until Space Grotesk, Inter, and JetBrains Mono are bundled. LICENSES.md— not written this pass (FONTS.md §"Wave-1 implementation policy" explicitly says "NoLICENSES.mdneeded in this pass").- Marketplace screenshots (spec §13.1) — 6 frames at 1440×900 deferred until a running CMS instance is available; agent scope says "no
make rebuild". - Demo-content seed (spec §13.2) — not implemented in this pass.
make rebuildagainst running CMS — UAT §2 "instance-brutalist Up within 15s" check cannot run from this agent's scope; needs a live instance.- UAT §6, §7, §13 runtime checks — accessibility, responsive, and aesthetic gates require a running container and visual verification; out of scope for the build agent.
- Email wrapper Litmus/cross-client verification (UAT §10) — wrapper compiles and registers; live capture testing deferred.
concrete_hero.mediavideo support (spec open question) — schema ismedia(image only) per the spec, deferred to v0.2 if the media type needs to widen.
File inventory
brutalist/
├── BUILD_REPORT.md
├── Makefile
├── RECOMMENDED_FONTS.md
├── assets/
│ └── .gitkeep
├── brutalist.so
├── button_override.go
├── button_override.templ
├── button_override_templ.go
├── caption_image.go
├── caption_image.templ
├── caption_image_templ.go
├── colophon.go
├── colophon.templ
├── colophon_templ.go
├── concrete_hero.go
├── concrete_hero.templ
├── concrete_hero_templ.go
├── css_append.go
├── email_wrapper.go
├── email_wrapper.templ
├── email_wrapper_templ.go
├── embed.go
├── fonts.json
├── go.mod
├── go.sum
├── heading_override.go
├── heading_override.templ
├── heading_override_templ.go
├── helpers.go
├── image_override.go
├── image_override.templ
├── image_override_templ.go
├── masthead.go
├── masthead.templ
├── masthead_templ.go
├── meta_strip.go
├── meta_strip.templ
├── meta_strip_templ.go
├── page_data.go
├── plugin.mod
├── presets.json
├── project_ledger.go
├── project_ledger.templ
├── project_ledger_templ.go
├── pull_quote.go
├── pull_quote.templ
├── pull_quote_templ.go
├── register.go
├── registration.go
├── schemas/
│ ├── caption_image.schema.json
│ ├── colophon.schema.json
│ ├── concrete_hero.schema.json
│ ├── masthead.schema.json
│ ├── meta_strip.schema.json
│ ├── project_ledger.schema.json
│ └── pull_quote.schema.json
├── template.templ
├── template_templ.go
├── text_override.go
├── text_override.templ
└── text_override_templ.go
7 blocks, 7 schemas, 4 page templates, 4 built-in overrides, 1 email wrapper, 3 master pages, 2 presets. brutalist.so 21.5 MB. Safety check exit 0.