Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/magazine-bold. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
194 lines
9.3 KiB
Markdown
194 lines
9.3 KiB
Markdown
# Magazine Bold — Build Report
|
||
|
||
Generated from a clean wave-1 implementation pass against the spec at
|
||
`themes/docs/works/magazine-bold.md` (§§1–15) and the UAT at
|
||
`themes/docs/uat/magazine-bold.md`, with `themes/docs/FONTS.md` overriding
|
||
spec §5 and UAT §11.
|
||
|
||
## What landed
|
||
|
||
### Identity & metadata
|
||
- `plugin.mod` — `name = magazine-bold`, `kind = theme`, `scope = @themes`,
|
||
`version = 0.1.0`, `categories = ["templates", "media"]`,
|
||
`tags = [fashion, lifestyle, streetwear, magazine, bold, display, music,
|
||
editorial, art]` (9 entries, all from the whitelist), `block_core
|
||
compatibility = ">=0.11.0 <0.12.0"`, description verbatim from spec §1.
|
||
- `go.mod` — module `git.dev.alexdunmow.com/block/themes/magazine-bold`,
|
||
Go directive `1.26.4`, requires `block/core v0.11.1` and `a-h/templ
|
||
v0.3.1020`, no `replace` directives.
|
||
|
||
### File layout (templ-style)
|
||
```
|
||
magazine-bold/
|
||
plugin.mod go.mod go.sum
|
||
Makefile registration.go register.go
|
||
embed.go helpers.go css.go
|
||
template.templ + _templ.go # 4 page renderers
|
||
masthead.{go,templ} + _templ.go
|
||
cover_story.{go,templ} + _templ.go
|
||
photo_essay.{go,templ} + _templ.go
|
||
pull_quote.{go,templ} + _templ.go
|
||
issue_archive.{go,templ} + _templ.go
|
||
colophon.{go,templ} + _templ.go
|
||
heading_override.{go,templ} + _templ.go
|
||
text_override.{go,templ} + _templ.go
|
||
image_override.{go,templ} + _templ.go
|
||
button_override.{go,templ} + _templ.go
|
||
email_wrapper.{go,templ} + _templ.go
|
||
schemas/masthead.schema.json
|
||
schemas/cover_story.schema.json
|
||
schemas/photo_essay.schema.json
|
||
schemas/pull_quote.schema.json
|
||
schemas/issue_archive.schema.json
|
||
schemas/colophon.schema.json
|
||
presets.json fonts.json assets/.gitkeep
|
||
RECOMMENDED_FONTS.md BUILD_REPORT.md
|
||
```
|
||
|
||
### Registration
|
||
- One `tr.RegisterSystemTemplate({Key: "magazine-bold"})` call.
|
||
- Four `tr.RegisterPageTemplate("magazine-bold", ...)` calls with the slots:
|
||
- `default`: `["masthead", "main", "colophon"]`
|
||
- `landing`: `["cover", "secondary", "main", "colophon"]`
|
||
- `article`: `["masthead", "deck", "main", "colophon"]`
|
||
- `full-width`: `["masthead", "main", "colophon"]`
|
||
- `br.LoadSchemasFromFS(Schemas())` called BEFORE the first `br.Register(...)`.
|
||
- Six theme blocks registered with `Source: "magazine-bold"`:
|
||
- `masthead` → CategoryLayout
|
||
- `cover_story` → CategoryContent
|
||
- `photo_essay` → CategoryContent
|
||
- `pull_quote` → CategoryContent
|
||
- `issue_archive` → CategoryNavigation
|
||
- `colophon` → CategoryLayout
|
||
- Four built-in overrides via `br.RegisterTemplateOverride("magazine-bold", …)`:
|
||
`heading`, `text`, `image`, `button`.
|
||
- One `tr.RegisterEmailWrapper("magazine-bold", MagazineBoldEmailWrapper)`.
|
||
|
||
### Master pages
|
||
Both master pages from spec §7 are seeded in `DefaultMasterPages()`:
|
||
- `magazine-bold:default-master` — `PageTemplates: [default, article]`,
|
||
blocks: `navbar`@masthead/0 → `magazine-bold:masthead`@masthead/1 →
|
||
`slot`@main/0 → `magazine-bold:colophon`@colophon/0.
|
||
- `magazine-bold:landing-master` — `PageTemplates: [landing, full-width]`,
|
||
blocks: `navbar`@masthead/0 → `magazine-bold:cover_story`@cover/0 →
|
||
`magazine-bold:issue_archive`@secondary/0 → `slot`@main/0 →
|
||
`magazine-bold:colophon`@colophon/0.
|
||
- Every `slot` block carries `Content["slotName"] == "main"`.
|
||
|
||
### Presets (presets.json)
|
||
Three presets, each `mode: "both"`, each with both `lightColors` and
|
||
`darkColors` blocks carrying all 19 theme tokens:
|
||
- `paper-pink` — Paper & Hot Pink (default), spec §4 verbatim.
|
||
- `ink-blue` — same neutrals, accent swapped to `220 100% 56%` (light) /
|
||
`220 100% 62%` (dark), ring matches.
|
||
- `chalk-lime` — cool chalk background (`60 15% 97%` light / `0 0% 6%` dark),
|
||
lime accent (`78 90% 50%` / `78 90% 55%`), accentForeground reads ink
|
||
in both modes for ≥ 4.5:1 contrast on lime.
|
||
|
||
All HSL triples are bare strings — no `hsl(…)` wrappers anywhere.
|
||
|
||
### Schemas
|
||
All six schemas are draft-07, list properties matching the spec §8 field
|
||
table, and use only `x-editor` types from the allowed set. `pull_quote.accent`
|
||
enum is `["pink", "blue", "lime"]`. `photo_essay.frames` items use
|
||
`x-editor: collection` with item-level `media`, `text` and `select` (span
|
||
enum `["half", "full", "tall"]`).
|
||
|
||
### CSS strategy
|
||
`CSSManifest.InputCSSAppend` ships a single utility-CSS block at
|
||
`magazine-bold/css.go` (`magazineBoldUtilityCSS`). It defines:
|
||
- `.font-display`, `.font-serif-sub`, `.font-sans`, `.font-mono` — each
|
||
consumes `var(--font-heading|body|mono, <fallback stack>)` per FONTS.md.
|
||
- `.text-folio` clamp (220pt-equivalent at 1440px → ~80px at 360px).
|
||
- `.text-deck`, `.text-kicker` display-size utilities.
|
||
- `.mb-hairline*` for the 1px ink rules.
|
||
- `.mb-grid-12`, `.mb-grid-asym-cover`, `.mb-col-folio`, `.mb-col-headline`,
|
||
`.mb-col-deck` for the 12-column asymmetric layout.
|
||
- `.mb-photo-grid`, `.mb-frame-{half,full,tall}` for the photo-essay spans
|
||
(collapsing to 1-col at ≤ 768px).
|
||
- `.mb-dropcap` for the heading-override drop-cap.
|
||
- `.mb-button` squared-ink button with accent hover and a `:focus-visible`
|
||
outline using `hsl(var(--ring))`.
|
||
- `.mb-caption`, `.mb-image-folio` mono caption strip.
|
||
- `.colorblock-accent` + per-accent `[data-mb-accent="pink|blue|lime"]`
|
||
variants for pull quotes (using literal HSL triples that match the spec
|
||
§4 accent values so a pinned accent reads correctly across presets).
|
||
|
||
No hardcoded hex, rgb(), or named colors are used in `.templ` / `.go` /
|
||
`.html` files outside the email wrapper (see "Open items" below).
|
||
|
||
### Email wrapper
|
||
`RegisterEmailWrapper("magazine-bold", MagazineBoldEmailWrapper)` ships a
|
||
600px `<table>` with a paper-pink default background, an ink hairline below
|
||
the PP-Editorial-style wordmark (with Georgia / Times New Roman / serif
|
||
fallback for Outlook 365 web), a 16/24 Inter body, and a mono colophon
|
||
strip echoing the web colophon. Hex defaults inlined in `email_wrapper.go`
|
||
are derived from the paper-pink light preset so the layout reads correctly
|
||
in clients that strip the host CSS.
|
||
|
||
### Build output
|
||
- `make` produced `magazine-bold.so` at 21 MB (CGO `-buildmode=plugin
|
||
-ldflags="-s -w"`).
|
||
- `nm --dynamic magazine-bold.so | grep Registration` shows
|
||
`D git.dev.alexdunmow.com/block/themes/magazine-bold.Registration`
|
||
exported as the Go-plugin entry point.
|
||
- Zero `warning:` lines in the build output.
|
||
|
||
### Safety check
|
||
- `cd ~/src/blockninja/check-safety && go run . ~/src/blockninja/cms
|
||
--plugin-dir ~/src/blockninja/themes/magazine-bold` → **exit 0**, all 22
|
||
checks `OK` or `SKIP` (the SKIPs are frontend / orchestrator checks that
|
||
don't apply to a templ-only theme plugin).
|
||
- The task brief referenced the older path
|
||
`~/src/blockninja/backend/cmd/check-safety`, but the repo has been
|
||
re-organised so `check-safety/` now lives at the top level as its own
|
||
Go module. The equivalent invocation is the one above; behaviour is
|
||
identical and the plugin passes cleanly.
|
||
|
||
## Open items / deferred
|
||
|
||
- **Fonts (wave-2):** per `docs/FONTS.md`, this pass ships
|
||
`fonts.json = []` and no woff2 files. PP Editorial New, Migra, Inter and
|
||
JetBrains Mono are documented as recommended picks in
|
||
`RECOMMENDED_FONTS.md`. Wave-2 will commission / licence the commercial
|
||
faces (PP Editorial New + Migra) and bundle them with a `LICENSES.md`.
|
||
- **Email wrapper hex defaults:** the wrapper inlines six hex literals
|
||
(`#F7F2EB`, `#141414`, `#EEE9E0`, `#666666`, `#E0E0E0`, `#FFFFFF`) as
|
||
client-strip-proof defaults for the paper-pink preset. Mail clients
|
||
ignore `var()` and (often) strip `<style>` blocks, so these literals are
|
||
load-bearing — they only fire when the host doesn't populate
|
||
`EmailContext.Colors.*`. This is a deliberate exception to the "no
|
||
hardcoded colors" rule, scoped to `email_wrapper.go`. Spec §10 / UAT §10
|
||
call for this paper-pink fallback explicitly.
|
||
- **Marketplace assets:** the six 1440×900 screenshots, the demo content
|
||
seed (Vol. 1 / Spring + five posts + three pull quotes + an 8-frame photo
|
||
essay + an `issues` bucket), and the launch copy live in the
|
||
marketplace-listing pass that follows the build pass. Not produced here.
|
||
- **`make rebuild` / live deploy:** the task brief forbids running
|
||
`make rebuild` in this pass. The local `make` target builds the `.so`
|
||
and that's verified above.
|
||
- **`make logs` / `instance-magazine-bold` container:** depends on
|
||
`make rebuild`, so deferred with the live-deploy step.
|
||
- **UAT §11 `LICENSES.md`:** intentionally omitted per the wave-1 fonts
|
||
policy ("no `LICENSES.md` needed in this pass").
|
||
- **`nm | grep ' T main.Registration'` UAT check:** the Go-plugin runtime
|
||
exports the registration symbol under the module path
|
||
(`git.dev.alexdunmow.com/block/themes/magazine-bold.Registration` in
|
||
the dynamic symbol table), not as `main.Registration`. The loader still
|
||
resolves it correctly. UAT §3 line 35 would need wording-only tweak to
|
||
match the real Go-plugin symbol format; functionally the plugin is fine.
|
||
- **Per-page accent override (spec §15 open question):** kept at preset
|
||
scope. A pinned per-pull-quote accent is supported via
|
||
`data-mb-accent="pink|blue|lime"`. Per-page accent rotation is a v0.2.0
|
||
candidate.
|
||
|
||
## Counts
|
||
|
||
- Page templates: 4
|
||
- Theme blocks: 6
|
||
- Built-in overrides: 4 (heading, text, image, button)
|
||
- Email wrappers: 1
|
||
- Master pages: 2
|
||
- Presets: 3 (× 2 modes each)
|
||
- Tokens per preset block: 19
|