Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/kindergarten. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
156 lines
7.3 KiB
Markdown
156 lines
7.3 KiB
Markdown
# 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(--<token>))` 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)
|
||
```
|