# Kindergarten — BUILD_REPORT Build pass: wave-1 implementation against spec `themes/docs/works/kindergarten.md` and gating UAT `themes/docs/uat/kindergarten.md`, with fonts policy overridden by `themes/docs/FONTS.md`. ## What landed ### Plugin metadata - `plugin.mod` mirrors spec §2 verbatim (`kind=theme`, `scope=@themes`, `categories=["templates"]`, 9 tags including the literal-required `kids,education,playful,family,school`, compatibility pin `block_core=">=0.11.0 <0.12.0"`, `version=0.1.0`). - `go.mod` pins `git.dev.alexdunmow.com/block/core v0.11.1` and Go 1.26.4; no `replace` directives; matches the SDK pin used by `cms/backend/go.mod`. ### Registration surface - `var Registration plugin.PluginRegistration` exported in `registration.go`. - `Register(tr, br)`: - `tr.RegisterSystemTemplate("kindergarten", ...)` - 4 page templates: `default`, `landing`, `article`, `full-width` with the exact slot tuples from spec §6. - `br.LoadSchemasFromFS(Schemas())` called **before** any `br.Register(...)`. - 8 theme blocks registered: `mascot_hero`, `alphabet_strip`, `schedule`, `gallery_of_art`, `numbers_counter`, `storybook_quote`, `big_cta`, `footer` (all with `Source: "kindergarten"`). - 4 built-in overrides (`heading`, `text`, `button`, `card`) registered against template key `"kindergarten"`. - Email wrapper registered via `tr.RegisterEmailWrapper("kindergarten", ...)`. - `DefaultMasterPages()` ships both `kindergarten:default-master` (used by `default`+`article`) and `kindergarten:landing-master` (used by `landing`+`full-width`), with the block ordering from spec §7. ### Schemas - All 8 schemas live under `schemas/` and declare `"$schema": "http://json-schema.org/draft-07/schema#"`. Every JSON property matches the corresponding `content[...]` key in the Go renderers; all `x-editor` values come from the allowed set (`text, richtext, media, color, select, number, slug, textarea, array, collection, link`). ### Presets - `presets.json` is a JSON array of length 3, ordered `recess`, `chalkboard`, `crayon-box`. Every token value matches `^[0-9]+ [0-9]+% [0-9]+%$` (HSL triple, no `hsl()` wrappers). All 19 tokens present per preset: - `recess` → mode `light`, exposes `lightColors` only. - `chalkboard` → mode `dark`, exposes `darkColors` only. - `crayon-box` → mode `both`, exposes both `lightColors` and `darkColors`. ### Fonts - `fonts.json = []` per the wave-1 fonts policy (`themes/docs/FONTS.md`). - No woff2 bundled. - `RECOMMENDED_FONTS.md` at the theme root lists Quicksand (heading), Nunito (body), Fira Code (mono), and Sniglet (alt display) as Google Fonts picker recommendations. - Theme CSS goes through `var(--font-heading | --font-body | --font-mono)` with explicit fallback stacks so the type system stays close to the intended aesthetic until the admin makes a choice. ### CSS strategy - `assets/style.css` is registered into the host Tailwind input via `CSSManifest.InputCSSAppend` (see `embed.go::ThemeCSSManifest`). - Custom utilities cover crayon underline (`.kg-crayon-underline`), the dotted-paper background layer (`.kg-dotted-paper`), the sticker drop-shadow on pills (`box-shadow: 0 4px 0 0 …`), polaroid frames for the gallery, the numeral badge (`.kg-numeral { border-radius: 50%; aspect-ratio: 1 / 1; }`), and the schedule time-pill. - No hardcoded hex / `rgb()` / named colors in any `.templ` or `.go`; all color references are `hsl(var(--))` against the 19-token CSS variables. (Check 6 in `check-safety` confirms this.) ## Build output ``` $ cd /home/alex/src/blockninja/themes/kindergarten $ /home/alex/go/bin/templ generate (✓) Complete [ updates=14 ] $ make CGO_ENABLED=1 go build -buildmode=plugin -ldflags="-s -w" -o kindergarten.so . $ ls -lh kindergarten.so -rw-rw-r-- 1 alex alex 21M Jun 6 13:24 kindergarten.so ``` Build succeeded; no `warning:` / `WARN` lines on stdout. ## Safety check ``` $ cd /home/alex/src/blockninja/check-safety $ go run . /home/alex/src/blockninja/themes/kindergarten ... 22 checks ... exit 0 ``` Notes: - The task brief referenced `cd /home/alex/src/blockninja/backend && go run ./cmd/check-safety . --plugin-dir ../themes/kindergarten`. That path layout does not match this workspace; `check-safety` lives in `/home/alex/src/blockninja/check-safety` as a standalone module. The invocation above is the actual run that exits 0. - Check 2e ("warn on `any`") flags 32 informational warnings on `map[string]any` parameters in block render functions. The plugin SDK's `BlockFunc` signature is `func(ctx, content map[string]any) string` — these `any`s are mandated by the SDK contract; warnings are not failures and gotham trips the same ones. ## Open items / deferred | Item | Status | Notes | |---|---|---| | Bundled woff2 fonts | **Deferred** | Wave-1 policy: ship `fonts.json = []` and rely on admin Google Fonts picker. RECOMMENDED_FONTS.md lists the four recommended families. | | LICENSES.md | **Deferred** | Only required when bundling woff2s. Wave-2 follow-up. | | Real mascot SVG (Pip) | **Deferred** | The mascot renderer ships four primitive SVG variants (`pip`, `blocks`, `star`, `balloon`). Replace with illustrated Pip in v0.2 per spec §15. | | `make rebuild` (live-container deploy) | **Out of scope** | Explicitly disabled in the brief. The Makefile only carries `all` (build .so), `clean`, and `templ`. | | Marketplace screenshots (1440×900 × 6) | **Deferred** | No live container available in this pass; capture during v0.1.0 launch sprint. | | Seed demo content | **Deferred** | Mascot image + sample posts to be staged when a dev container is available. | | Email-client smoke testing (Gmail / Apple Mail / Outlook 365) | **Deferred** | Wrapper code shipped; visual verification needs Litmus/Mailbox access. | | Accessibility contrast audit | **Deferred** | Theme tokens follow spec §4 values; an automated audit needs a running site. | | `wave-2` Sniglet/Fira Code Rounded bundling | **Deferred** | See `themes/docs/FONTS.md`, last section. | ## Files produced ``` kindergarten/ BUILD_REPORT.md ← this file Makefile ← local-only build helpers README.md (not created — not requested) RECOMMENDED_FONTS.md assets/style.css ← injected via CSSManifest.InputCSSAppend embed.go fonts.json ← literal "[]" go.mod / go.sum plugin.mod presets.json ← 3 presets, 19 tokens each register.go ← system template + 4 page templates + 8 blocks + 4 overrides + email wrapper registration.go ← var Registration plugin.PluginRegistration schemas/{8 block schemas}.schema.json helpers.go template.templ + template_templ.go (4 page templates) email_wrapper.{go,templ,_templ.go} mascot_hero.{go,templ,_templ.go} alphabet_strip.{go,templ,_templ.go} schedule.{go,templ,_templ.go} gallery_of_art.{go,templ,_templ.go} numbers_counter.{go,templ,_templ.go} storybook_quote.{go,templ,_templ.go} big_cta.{go,templ,_templ.go} footer.{go,templ,_templ.go} heading_override.{go,templ,_templ.go} (built-in override) text_override.{go,templ,_templ.go} (built-in override) button_override.{go,templ,_templ.go} (built-in override) card_override.{go,templ,_templ.go} (built-in override) kindergarten.so ← compiled output (21 MB) ```