Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/art-deco. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
8.7 KiB
8.7 KiB
Art Deco — Build Report
Status: SHIPPED.
Compiled .so produced and the safety check exits 0.
What landed
Plugin metadata (plugin.mod)
kind = "theme",scope = "@themes",version = "0.1.0".categories = ["templates"](single whitelist entry).tags = ["luxury", "gold", "hospitality", "hotel", "wedding", "jewellery", "vintage", "glam", "fine-dining"](9 tags, within the 5–9 UAT range).[compatibility].block_core = ">=0.11.0 <0.12.0".
System & page templates
- System template registered with
Key: "art-deco". - 4 page templates registered:
default→ slotsheader, main, footer.landing→ slotsmarquee, main, cta, footer.article→ slotsheader, main, aside, footer.full-width→ slotsheader, main, footer.
Blocks (7, all Source: "art-deco")
| Key | Schema | Notes |
|---|---|---|
reservation |
schemas/reservation.schema.json |
Sticky gold-on-black strip with phone, OpenTable CTA, hours. |
menu |
schemas/menu.schema.json |
Symmetric menu card with rich-text course descriptions and prices. |
gallery_fan |
schemas/gallery_fan.schema.json |
Mirrored gallery framed by sunburst, 2/3/4 columns, collapses to 1 col <640px. |
divider_fan |
schemas/divider_fan.schema.json |
Pure-CSS sunburst / scallop / ziggurat divider — falls back to sunburst on unknown variant. |
footer |
schemas/footer.schema.json |
Centered footer with gold rule, address, reservations email, social row, menu name. |
marquee_hero |
schemas/marquee_hero.schema.json |
Wide hero with stepped ziggurat frame and sunburst overlay. |
press_quote |
schemas/press_quote.schema.json |
Italic Cormorant pull-quote with stars (clamped 0–5). |
Schemas are loaded BEFORE any br.Register(...) call (line ordering enforced in register.go).
Template overrides (4)
heading— caps tracking + hairline gold underline, Italiana display family.text— Cormorant body with italic drop-cap on first paragraph.button— black pill with gold border, stamped inset shadow on hover/focus.image— stepped ziggurat frame variant (also scallop / plain).
Email wrapper
tr.RegisterEmailWrapper("art-deco", ArtDecoEmailWrapper)wired.- 600px centered column, ivory body, jet-black masthead.
- Masthead uses a flat-gold SVG
<img>(not a CSS gradient) so Outlook renders it correctly. - Reservation phone /
SupportEmailauto-injected as italic postscript line.
Master pages (2)
art-deco:default-mastercoversdefault,article—navbar(header,0),art-deco:divider_fan(header,1,sunburst),slot(main,0,slotName=main),art-deco:footer(footer,0).art-deco:marquee-mastercoverslanding,full-width—navbar(marquee,0),art-deco:reservation(marquee,1),slot(main,0,slotName=main),art-deco:divider_fan(cta,0,scallop),art-deco:footer(footer,0).
Presets (presets.json, 3)
champagne-noir(mode: both, lightColors + darkColors, all 19 tokens each).ivory-rose(mode: light, lightColors only, all 19 tokens).velvet-onyx(mode: dark, darkColors only, all 19 tokens).- Every value is an HSL triple
H S% L%— nohsl(...)wrappers, no hex.
CSS manifest
CSSManifest.InputCSSAppendregistered viaThemeCSSManifest()inembed.go/registration.go.- The injected CSS declares
@layer utilitiesblocks for.deco-rule,.deco-frame,.deco-step,.deco-grain, plus aesthetic helpers.deco-foil,.deco-sunburst,.deco-scallop,.deco-ziggurat,.deco-caps,.deco-dropcap,.deco-underline,.deco-pill,.deco-link. - All colour values consume
hsl(var(--token)); allfont-familydeclarations go throughvar(--font-heading|body|mono, <fallback>).
Fonts policy (Wave-1)
fonts.json = [](no bundled woff2s in this pass).RECOMMENDED_FONTS.mdlists the spec §5 fonts as Google Fonts picker recommendations (Italiana, Cormorant Garamond, JetBrains Mono).- Fallback stacks for
--font-heading,--font-body,--font-monoare embedded inline in every template + utility.
Build output
$ cd ~/src/blockninja/themes/art-deco && go mod tidy
(no output — clean)
$ /home/alex/go/bin/templ generate
(✓) Complete [ updates=13 duration=… ]
$ make
CGO_ENABLED=1 go build -buildmode=plugin -ldflags="-s -w" -o art-deco.so .
$ ls -lh art-deco.so
-rw-rw-r-- 1 alex alex 21M art-deco.so
Safety check
$ cd ~/src/blockninja/check-safety && go run . ~/src/blockninja/themes/art-deco \
--plugin-dir ~/src/blockninja/themes/art-deco
…
=== Check 2c: Standalone plugin SDK import boundaries ===
OK: Standalone plugin imports and go.mod stay on SDK version v0.11.1
=== Check 3: Go code compiles and passes go fix, golangci-lint --fix, go vet, and strict lint ===
OK: Go lint pipeline clean for 1 module(s)
=== Check 6: No hardcoded colors in frontend (use theme tokens) ===
OK: No hardcoded colors in .templ files
=== Check 11: No placeholder code; only shipped features ===
OK: No placeholder code found
…
exit=0
Only WARN remaining is Check 2e (any usage in content map[string]any signatures). This is the
exact same warning Gotham emits — it is the standalone-plugin block signature contract and is
non-blocking.
Open items / deferred
Wave-1 deferrals (intentional, per themes/docs/FONTS.md)
- No bundled woff2 fonts. Theme ships
fonts.json = []and aRECOMMENDED_FONTS.mdfor the admin to pick Italiana / Cormorant Garamond / JetBrains Mono from the Google Fonts tab. - No
LICENSES.md— nothing is bundled.
Wave-2 follow-ups (out of scope for this pass)
- Commission a redistributable Art Deco display face (Italiana variants are limited) and bundle
via
fonts.jsonif Italiana proves brittle at retina sizes. UAT §11 FOUT timing and the licence audit only become checkable once a face is bundled. - Capture the 6 UAT marketplace screenshots (
docs/uat/art-deco-shots/01..06.png). Requires a running CMS instance — outside the autonomous build scope. - Seed the "Maison Étoile" demo content (6 pages, 4 courses, 1 press quote, 9 gallery images). Same constraint as above — requires the instance container.
- Run the UAT browser-side gates: WCAG contrast pairs, focus-visible ring sweep, viewport scroll-width checks at 360/768/1024/1440. The CSS is wired to satisfy them but the verification is an instance-side workflow.
- Master-page UAT cell "Replacing
art-deco:footerondefault-masterin admin produces a ghost-free re-render" — admin-side verification, not a build-side check.
Not implemented (called out by spec but explicitly listed in BUILD_REPORT)
make rebuildand the container deploy targets — by build-instructions,make rebuildis off-limits to the autonomous build pass. The Makefile here ships onlyall,templ,clean,help— production deploy is reserved for the gotham-style upstream Makefile and a human run.- Real woff2 bundles in
assets/fonts/— deferred to Wave-2 per FONTS.md.
File inventory
art-deco/
├── BUILD_REPORT.md ← this file
├── Makefile ← local-only build (make, make templ, make clean)
├── RECOMMENDED_FONTS.md ← Wave-1 Google Fonts picker guide
├── assets/style.css ← @layer utilities CSS (foil, frame, fan, grain, pill…)
├── button_override.{go,templ,_templ.go}
├── divider_fan.{go,templ,_templ.go}
├── email_wrapper.{templ,_templ.go}
├── embed.go ← //go:embed directives + CSSManifest hook
├── fonts.json ← []
├── footer.{go,templ,_templ.go}
├── gallery_fan.{go,templ,_templ.go}
├── go.{mod,sum} ← block/core v0.11.1, no replace directives
├── heading_override.{go,templ,_templ.go}
├── helpers.go ← getString / getInt / getSlice / getStringSlice / clampInt
├── image_override.{go,templ,_templ.go}
├── marquee_hero.{go,templ,_templ.go}
├── menu.{go,templ,_templ.go}
├── plugin.mod ← TOML metadata, kind=theme
├── presets.json ← 3 presets, 19 tokens each, HSL triples
├── press_quote.{go,templ,_templ.go}
├── press_quote_helpers.go
├── register.go ← Register(tr,br) + DefaultMasterPages()
├── registration.go ← var Registration plugin.PluginRegistration
├── reservation.{go,templ,_templ.go}
├── schemas/
│ ├── divider_fan.schema.json
│ ├── footer.schema.json
│ ├── gallery_fan.schema.json
│ ├── marquee_hero.schema.json
│ ├── menu.schema.json
│ ├── press_quote.schema.json
│ └── reservation.schema.json
├── template.templ + template_templ.go
└── text_override.{go,templ,_templ.go}