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>
169 lines
8.7 KiB
Markdown
169 lines
8.7 KiB
Markdown
# 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` → slots `header, main, footer`.
|
||
- `landing` → slots `marquee, main, cta, footer`.
|
||
- `article` → slots `header, main, aside, footer`.
|
||
- `full-width` → slots `header, 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 / `SupportEmail` auto-injected as italic postscript line.
|
||
|
||
### Master pages (2)
|
||
- `art-deco:default-master` covers `default`, `article` — `navbar` (header,0), `art-deco:divider_fan` (header,1,sunburst), `slot` (main,0,slotName=main), `art-deco:footer` (footer,0).
|
||
- `art-deco:marquee-master` covers `landing`, `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%` — no `hsl(...)` wrappers, no hex.
|
||
|
||
### CSS manifest
|
||
- `CSSManifest.InputCSSAppend` registered via `ThemeCSSManifest()` in `embed.go`/`registration.go`.
|
||
- The injected CSS declares `@layer utilities` blocks 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))`; all `font-family` declarations go through `var(--font-heading|body|mono, <fallback>)`.
|
||
|
||
### Fonts policy (Wave-1)
|
||
- `fonts.json = []` (no bundled woff2s in this pass).
|
||
- `RECOMMENDED_FONTS.md` lists the spec §5 fonts as Google Fonts picker recommendations (Italiana, Cormorant Garamond, JetBrains Mono).
|
||
- Fallback stacks for `--font-heading`, `--font-body`, `--font-mono` are 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 a `RECOMMENDED_FONTS.md` for 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.json` if 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:footer` on `default-master` in 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 rebuild` and the container deploy targets — by build-instructions, `make rebuild` is
|
||
off-limits to the autonomous build pass. The Makefile here ships only `all`, `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}
|
||
```
|