diff --git a/Makefile b/Makefile index f9619b6..6359168 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,27 @@ -# brutalist — build & publish helpers (wasm .bnp workflow) +# brutalist — build & publish helpers (CODELESS .bnp workflow, WO-WZ-021) # -# The theme compiles to a wasip1 reactor-mode wasm module packed into a .bnp -# artifact (`ninja plugin build`). The legacy .so path is retired (WO-WZ-015): -# the CMS is wasm-native and can no longer load .so plugins. Distribution is -# publish-to-registry -> InstallFromRegistry (hot-load, no restart). +# This theme is a CODELESS .bnp: pure declaration the host runs — blocks +# (blocks/blocks.yaml + .ninjatpl), page/system templates, template overrides, +# an email wrapper, master pages, presets, fonts and CSS in manifest.yaml. No +# Go, no templ, no plugin.wasm, no block/core dependency. `ninja plugin build` +# classifies the repo as codeless (no Go at the root) and packs the artifact +# with manifest.pb (codeless: true) and NO plugin.wasm. # # Usage: -# make build # compile wasm + pack brutalist-.bnp -# make verify # validate the built .bnp (layout/abi/name/size) -# make archive-check # prove a clean `git archive HEAD` compiles to wasm +# make build # pack brutalist-.bnp (codeless — no wasm) +# make verify # validate the built .bnp (loader-identical checks) +# make archive-check # prove a clean `git archive HEAD` still builds codeless # make publish # ninja plugin publish --bnp (to the active registry) -# make templ # regenerate templ Go files # make clean # remove build artefacts -.PHONY: build verify archive-check publish templ clean help +.PHONY: build verify archive-check publish clean help PLUGIN_NAME := brutalist NINJA := ninja BNP := $(PLUGIN_NAME)-$(shell grep '^version' plugin.mod | sed 's/.*"\(.*\)"/\1/').bnp -# Compile to wasm and pack the .bnp (GOOS=wasip1 GOARCH=wasm, DESCRIBE probe, -# tar.zst of plugin.wasm + plugin.mod + manifest.pb + schemas/ + assets/). +# Pack the codeless .bnp (manifest.pb synthesized from plugin.mod + manifest.yaml +# + blocks/ + templates/; no wasm compile, no DESCRIBE probe). build: $(NINJA) plugin build --dir . @@ -28,12 +29,12 @@ build: verify: $(NINJA) plugin verify $(BNP) -# Prove a clean `git archive HEAD` (what publish ships) compiles to wasm. +# Prove a clean `git archive HEAD` (what publish ships) still packs codeless. archive-check: @T=$$(mktemp -d /tmp/archive-check-$(PLUGIN_NAME).XXXXXX) && \ trap 'rm -rf "$$T"' EXIT && \ git archive HEAD | tar -x -C "$$T" && \ - cd "$$T" && GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o "$$T/check.wasm" . && \ + cd "$$T" && $(NINJA) plugin build --dir . && \ echo "archive-check OK" # Publish the prebuilt .bnp to the active registry. @@ -41,19 +42,14 @@ archive-check: publish: build $(NINJA) plugin publish --bnp $(BNP) -# Regenerate templ Go files locally. -templ: - templ generate - # Remove build artefacts. clean: - rm -f $(PLUGIN_NAME)-*.bnp $(PLUGIN_NAME).so plugin.wasm + rm -f $(PLUGIN_NAME)-*.bnp plugin.wasm help: @echo "Targets:" - @echo " build Compile wasm + pack the .bnp" + @echo " build Pack the codeless .bnp (no wasm)" @echo " verify Validate the built .bnp (loader-identical checks)" - @echo " archive-check Prove a clean git archive HEAD compiles to wasm" + @echo " archive-check Prove a clean git archive HEAD packs codeless" @echo " publish Publish the .bnp to the active registry" - @echo " templ Regenerate templ Go files" @echo " clean Remove build artefacts" diff --git a/css_append.go b/assets/style.css similarity index 93% rename from css_append.go rename to assets/style.css index d67ebac..c523117 100644 --- a/css_append.go +++ b/assets/style.css @@ -1,15 +1,3 @@ -package main - -// brutalistAppendCSS is appended to the host Tailwind input via CSSManifest. -// It declares font fallback stacks for the three font-* CSS variables, kills -// border radii on the standard interactive elements, defines hairline rule -// utilities, and ships a togglable 12-column debug grid overlay. -// -// All color references use the shadcn token pattern: hsl(var(--token)). -// No hex / rgb / named colors. Fonts go through var(--font-*) with fallbacks -// derived from the spec's typography list (Space Grotesk display, Inter body, -// JetBrains Mono mono). Per FONTS.md, no @font-face is emitted here. -const brutalistAppendCSS = ` /* === Brutalist theme utilities === */ :where(.brutalist-page, .brutalist-page *) { @@ -368,4 +356,3 @@ body.brutalist-grid-debug::before { transparent calc(100% / 12) ); } -` diff --git a/blocks/blocks.yaml b/blocks/blocks.yaml new file mode 100644 index 0000000..aaa886a --- /dev/null +++ b/blocks/blocks.yaml @@ -0,0 +1,48 @@ +# Brutalist theme block definitions (codeless .bnp, WO-WZ-021). +# Keys are fully qualified (brutalist:) because the codeless loader +# registers definitions verbatim — there is no PluginBlockRegistry prefixing +# in the codeless path (unlike the wasm/templ path). The qualified keys match +# the hardcoded data-block attributes and the master_pages.json references. +blocks: + - key: brutalist:masthead + title: Studio Masthead + description: Oversized studio wordmark with mono index counter top-right + category: layout + schema: masthead.schema.json + template: masthead.ninjatpl + - key: brutalist:project_ledger + title: Project Ledger + description: "Ordered project list on a 12-col grid: number / year / client / role / arrow" + category: content + schema: project_ledger.schema.json + template: project_ledger.ninjatpl + - key: brutalist:concrete_hero + title: Concrete Hero + description: 200pt+ display headline with optional eyebrow and full-bleed image + category: layout + schema: concrete_hero.schema.json + template: concrete_hero.ninjatpl + - key: brutalist:meta_strip + title: Metadata Strip + description: "Mono uppercase strip: CLIENT / YEAR / DISCIPLINE / LOCATION" + category: content + schema: meta_strip.schema.json + template: meta_strip.ninjatpl + - key: brutalist:caption_image + title: Captioned Image + description: Image with 11px mono caption in the left gutter + category: content + schema: caption_image.schema.json + template: caption_image.ninjatpl + - key: brutalist:pull_quote + title: Pull Quote + description: Massive quote spanning 8 columns with hairline rules above and below + category: content + schema: pull_quote.schema.json + template: pull_quote.ninjatpl + - key: brutalist:colophon + title: Colophon Footer + description: Three-row mono footer with copyright stamp + category: layout + schema: colophon.schema.json + template: colophon.ninjatpl diff --git a/blocks/caption_image.ninjatpl b/blocks/caption_image.ninjatpl new file mode 100644 index 0000000..aa1587d --- /dev/null +++ b/blocks/caption_image.ninjatpl @@ -0,0 +1 @@ +
{% if image %}{{ caption }}{% endif %}{% if caption or figureNumber %}
{% if figureNumber %}{{ figureNumber }}{% endif %}{% if caption %}{{ caption }}{% endif %}
{% endif %}
diff --git a/schemas/caption_image.schema.json b/blocks/caption_image.schema.json similarity index 100% rename from schemas/caption_image.schema.json rename to blocks/caption_image.schema.json diff --git a/blocks/colophon.ninjatpl b/blocks/colophon.ninjatpl new file mode 100644 index 0000000..45615df --- /dev/null +++ b/blocks/colophon.ninjatpl @@ -0,0 +1 @@ +
{% if address and showAddress != "false" and showAddress != false %}
{{ address }}
{% endif %}
{% if email %}{{ email }}{% endif %}{% for link in social %}{{ link.label }}{% endfor %}
© {% now "2006" %}
diff --git a/schemas/colophon.schema.json b/blocks/colophon.schema.json similarity index 100% rename from schemas/colophon.schema.json rename to blocks/colophon.schema.json diff --git a/blocks/concrete_hero.ninjatpl b/blocks/concrete_hero.ninjatpl new file mode 100644 index 0000000..1a49649 --- /dev/null +++ b/blocks/concrete_hero.ninjatpl @@ -0,0 +1 @@ +
{% if media %}{% endif %}
{% if eyebrow %}

{{ eyebrow }}

{% endif %}

{{ headline }}

diff --git a/schemas/concrete_hero.schema.json b/blocks/concrete_hero.schema.json similarity index 100% rename from schemas/concrete_hero.schema.json rename to blocks/concrete_hero.schema.json diff --git a/blocks/masthead.ninjatpl b/blocks/masthead.ninjatpl new file mode 100644 index 0000000..57d4512 --- /dev/null +++ b/blocks/masthead.ninjatpl @@ -0,0 +1,5 @@ +
+ {{ indexNumber|default:"01 / 14" }} +

{{ studioName|default:"STUDIO" }}

+ {% if tagline %}

{{ tagline }}

{% endif %} +
diff --git a/schemas/masthead.schema.json b/blocks/masthead.schema.json similarity index 100% rename from schemas/masthead.schema.json rename to blocks/masthead.schema.json diff --git a/blocks/meta_strip.ninjatpl b/blocks/meta_strip.ninjatpl new file mode 100644 index 0000000..cfea4c6 --- /dev/null +++ b/blocks/meta_strip.ninjatpl @@ -0,0 +1 @@ +
{% for item in items %}
{{ item.label }}
{{ item.value }}
{% endfor %}
diff --git a/schemas/meta_strip.schema.json b/blocks/meta_strip.schema.json similarity index 100% rename from schemas/meta_strip.schema.json rename to blocks/meta_strip.schema.json diff --git a/blocks/project_ledger.ninjatpl b/blocks/project_ledger.ninjatpl new file mode 100644 index 0000000..3ec9641 --- /dev/null +++ b/blocks/project_ledger.ninjatpl @@ -0,0 +1,3 @@ +
+ {% if not rows %}

No projects listed.

{% else %}
    {% for row in rows %}
  1. {{ row.no }}{{ row.year }}{% if row.link %}{{ row.client }}{% else %}{{ row.client }}{% endif %}{{ row.role }}{% if row.link %}{% endif %}
  2. {% endfor %}
{% endif %} +
diff --git a/schemas/project_ledger.schema.json b/blocks/project_ledger.schema.json similarity index 100% rename from schemas/project_ledger.schema.json rename to blocks/project_ledger.schema.json diff --git a/blocks/pull_quote.ninjatpl b/blocks/pull_quote.ninjatpl new file mode 100644 index 0000000..2aab9f6 --- /dev/null +++ b/blocks/pull_quote.ninjatpl @@ -0,0 +1 @@ +
{{ quote|safe }}
{% if attribution %}— {{ attribution }}{% endif %}
diff --git a/schemas/pull_quote.schema.json b/blocks/pull_quote.schema.json similarity index 100% rename from schemas/pull_quote.schema.json rename to blocks/pull_quote.schema.json diff --git a/button_override.go b/button_override.go deleted file mode 100644 index 4e57414..0000000 --- a/button_override.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// BrutalistButtonBlock applies square corners, 1px solid ink border, -// hover inverts to accent fill — per the spec block-overrides section. -func BrutalistButtonBlock(ctx context.Context, content map[string]any) string { - text := getString(content, "text") - href := getString(content, "href") - if href == "" { - href = getString(content, "url") - } - - var buf bytes.Buffer - _ = brutalistButtonComponent(text, resolveURL(href)).Render(ctx, &buf) - return buf.String() -} diff --git a/button_override.templ b/button_override.templ deleted file mode 100644 index 916b6d4..0000000 --- a/button_override.templ +++ /dev/null @@ -1,12 +0,0 @@ -package main - -templ brutalistButtonComponent(text, href string) { - - { text } - -} diff --git a/button_override_templ.go b/button_override_templ.go deleted file mode 100644 index befa050..0000000 --- a/button_override_templ.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func brutalistButtonComponent(text, href string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `button_override.templ`, Line: 10, Col: 8} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/caption_image.go b/caption_image.go deleted file mode 100644 index 165da81..0000000 --- a/caption_image.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// CaptionImageBlockMeta defines the Captioned Image block. -var CaptionImageBlockMeta = blocks.BlockMeta{ - Key: "caption_image", - Title: "Captioned Image", - Description: "Image with 11px mono caption in the left gutter", - Category: blocks.CategoryContent, - Source: "brutalist", -} - -// CaptionImageData carries data for the caption-image component. -type CaptionImageData struct { - ImageURL string - Caption string - FigureNumber string -} - -// CaptionImageBlock renders the captioned image. -// Content: {"image": "media:", "caption": "...", "figureNumber": "Fig. 01"} -func CaptionImageBlock(ctx context.Context, content map[string]any) string { - img := getString(content, "image") - resolvedImage := "" - if img != "" { - resolvedImage = blocks.ResolveMediaPath(img) - } - - data := CaptionImageData{ - ImageURL: resolvedImage, - Caption: getString(content, "caption"), - FigureNumber: getString(content, "figureNumber"), - } - - var buf bytes.Buffer - _ = captionImageComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/caption_image.templ b/caption_image.templ deleted file mode 100644 index 822e009..0000000 --- a/caption_image.templ +++ /dev/null @@ -1,19 +0,0 @@ -package main - -templ captionImageComponent(data CaptionImageData) { -
- if data.ImageURL != "" { - { - } - if data.Caption != "" || data.FigureNumber != "" { -
- if data.FigureNumber != "" { - { data.FigureNumber } - } - if data.Caption != "" { - { data.Caption } - } -
- } -
-} diff --git a/caption_image_templ.go b/caption_image_templ.go deleted file mode 100644 index 013a868..0000000 --- a/caption_image_templ.go +++ /dev/null @@ -1,124 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func captionImageComponent(data CaptionImageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.ImageURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"") ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if data.Caption != "" || data.FigureNumber != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.FigureNumber != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(data.FigureNumber) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `caption_image.templ`, Line: 11, Col: 60} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if data.Caption != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(data.Caption) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `caption_image.templ`, Line: 14, Col: 25} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/colophon.go b/colophon.go deleted file mode 100644 index ffbf785..0000000 --- a/colophon.go +++ /dev/null @@ -1,58 +0,0 @@ -package main - -import ( - "bytes" - "context" - "time" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// ColophonBlockMeta defines the Colophon Footer block. -var ColophonBlockMeta = blocks.BlockMeta{ - Key: "colophon", - Title: "Colophon Footer", - Description: "Three-row mono footer with copyright stamp", - Category: blocks.CategoryLayout, - Source: "brutalist", -} - -// ColophonSocialLink represents a single social link. -type ColophonSocialLink struct { - Label string - URL string -} - -// ColophonData carries data for the colophon component. -type ColophonData struct { - Address string - Email string - ShowAddress bool - Social []ColophonSocialLink - Year string -} - -// ColophonBlock renders the colophon footer. -// Content: {"address": "...", "email": "...", "showAddress": "true", "social": [{"label":"...","url":"..."}]} -func ColophonBlock(ctx context.Context, content map[string]any) string { - raw := getSlice(content, "social") - social := make([]ColophonSocialLink, 0, len(raw)) - for _, item := range raw { - social = append(social, ColophonSocialLink{ - Label: getString(item, "label"), - URL: getString(item, "url"), - }) - } - - data := ColophonData{ - Address: getString(content, "address"), - Email: getString(content, "email"), - ShowAddress: getBool(content, "showAddress", true), - Social: social, - Year: time.Now().UTC().Format("2006"), - } - - var buf bytes.Buffer - _ = colophonComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/colophon.templ b/colophon.templ deleted file mode 100644 index d47c607..0000000 --- a/colophon.templ +++ /dev/null @@ -1,18 +0,0 @@ -package main - -templ colophonComponent(data ColophonData) { -
- if data.ShowAddress && data.Address != "" { -
{ data.Address }
- } -
- if data.Email != "" { - { data.Email } - } - for _, link := range data.Social { - { link.Label } - } -
-
© { data.Year }
-
-} diff --git a/colophon_templ.go b/colophon_templ.go deleted file mode 100644 index 868dedf..0000000 --- a/colophon_templ.go +++ /dev/null @@ -1,144 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func colophonComponent(data ColophonData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.ShowAddress && data.Address != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(data.Address) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `colophon.templ`, Line: 6, Col: 77} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Email != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(data.Email) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `colophon.templ`, Line: 10, Col: 113} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - for _, link := range data.Social { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(link.Label) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `colophon.templ`, Line: 13, Col: 142} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
© ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(data.Year) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `colophon.templ`, Line: 16, Col: 35} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/concrete_hero.go b/concrete_hero.go deleted file mode 100644 index d25bc99..0000000 --- a/concrete_hero.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// ConcreteHeroBlockMeta defines the Concrete Hero block. -var ConcreteHeroBlockMeta = blocks.BlockMeta{ - Key: "concrete_hero", - Title: "Concrete Hero", - Description: "200pt+ display headline with optional eyebrow and full-bleed image", - Category: blocks.CategoryLayout, - Source: "brutalist", -} - -// ConcreteHeroData carries data for the concrete hero component. -type ConcreteHeroData struct { - Headline string - Eyebrow string - MediaURL string -} - -// ConcreteHeroBlock renders the concrete hero. -// Content: {"headline": "...", "eyebrow": "...", "media": "media:"} -func ConcreteHeroBlock(ctx context.Context, content map[string]any) string { - media := getString(content, "media") - resolvedMedia := "" - if media != "" { - resolvedMedia = blocks.ResolveMediaPath(media) - } - - data := ConcreteHeroData{ - Headline: getString(content, "headline"), - Eyebrow: getString(content, "eyebrow"), - MediaURL: resolvedMedia, - } - - var buf bytes.Buffer - _ = concreteHeroComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/concrete_hero.templ b/concrete_hero.templ deleted file mode 100644 index bd799b8..0000000 --- a/concrete_hero.templ +++ /dev/null @@ -1,24 +0,0 @@ -package main - -import "fmt" - -templ concreteHeroComponent(data ConcreteHeroData) { -
- if data.MediaURL != "" { - - } -
- if data.Eyebrow != "" { -

{ data.Eyebrow }

- } -

{ data.Headline }

-
-
-} - -func heroHasMedia(data ConcreteHeroData) string { - if data.MediaURL != "" { - return "true" - } - return "false" -} diff --git a/concrete_hero_templ.go b/concrete_hero_templ.go deleted file mode 100644 index e558a6d..0000000 --- a/concrete_hero_templ.go +++ /dev/null @@ -1,121 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import "fmt" - -func concreteHeroComponent(data ConcreteHeroData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.MediaURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Eyebrow != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(data.Eyebrow) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `concrete_hero.templ`, Line: 12, Col: 37} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(data.Headline) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `concrete_hero.templ`, Line: 14, Col: 39} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -func heroHasMedia(data ConcreteHeroData) string { - if data.MediaURL != "" { - return "true" - } - return "false" -} - -var _ = templruntime.GeneratedTemplate diff --git a/email_wrapper.go b/email_wrapper.go deleted file mode 100644 index 86f4c5a..0000000 --- a/email_wrapper.go +++ /dev/null @@ -1,91 +0,0 @@ -package main - -import ( - "bytes" - "context" - "fmt" - - "git.dev.alexdunmow.com/block/core/templates" -) - -// BrutalistEmailWrapper renders the Brutalist branded email wrapper: -// off-white concrete background, 1px ink outer border, Space Grotesk -// headline, Inter body, JetBrains Mono signoff. -// -// Colors flow from emailCtx.Colors when present, falling back to HSL -// values derived from the spec's concrete-red light palette. The hot -// accent is reserved for the single CTA button. -func BrutalistEmailWrapper(body string, emailCtx templates.EmailContext) string { - var buf bytes.Buffer - _ = brutalistEmailTemplate(emailCtx, body).Render(context.Background(), &buf) - return buf.String() -} - -// Spec defaults for email rendering (matches concrete-red light preset HSL -// triples converted to hex-equivalent so email clients can compute colors). -const ( - brutalistEmailBgDefault = "#F2EFE8" // background 40 14% 93% - brutalistEmailCardDefault = "#F7F4ED" // card 40 10% 96% - brutalistEmailFgDefault = "#0A0A0A" // foreground 0 0% 4% - brutalistEmailMutedFgDefault = "#595959" // mutedForeground 0 0% 35% - brutalistEmailBorderDefault = "#0A0A0A" // border 0 0% 4% -) - -func brutalistEmailColor(v, fallback string) string { - if v != "" { - return v - } - return fallback -} - -func brutalistBg(emailCtx templates.EmailContext) string { - return brutalistEmailColor(emailCtx.Colors.Background, brutalistEmailBgDefault) -} - -func brutalistCard(emailCtx templates.EmailContext) string { - return brutalistEmailColor(emailCtx.Colors.Card, brutalistEmailCardDefault) -} - -func brutalistFg(emailCtx templates.EmailContext) string { - return brutalistEmailColor(emailCtx.Colors.Foreground, brutalistEmailFgDefault) -} - -func brutalistMutedFg(emailCtx templates.EmailContext) string { - return brutalistEmailColor(emailCtx.Colors.MutedForeground, brutalistEmailMutedFgDefault) -} - -func brutalistBorder(emailCtx templates.EmailContext) string { - return brutalistEmailColor(emailCtx.Colors.Border, brutalistEmailBorderDefault) -} - -func brutalistEmailBodyStyle(emailCtx templates.EmailContext) string { - return fmt.Sprintf("background-color: %s; margin: 0; padding: 0; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif; color: %s;", brutalistBg(emailCtx), brutalistFg(emailCtx)) -} - -func brutalistEmailOuterCellStyle(emailCtx templates.EmailContext) string { - return fmt.Sprintf("padding: 48px 16px; background-color: %s;", brutalistBg(emailCtx)) -} - -func brutalistEmailContainerStyle(emailCtx templates.EmailContext) string { - return fmt.Sprintf("max-width: 600px; background-color: %s; border: 1px solid %s; border-radius: 0;", brutalistCard(emailCtx), brutalistBorder(emailCtx)) -} - -func brutalistEmailHeaderStyle(emailCtx templates.EmailContext) string { - return fmt.Sprintf("padding: 32px 40px; border-bottom: 1px solid %s;", brutalistBorder(emailCtx)) -} - -func brutalistEmailHeadlineStyle(emailCtx templates.EmailContext) string { - return fmt.Sprintf("margin: 0; font-family: 'Space Grotesk', 'Inter Tight', Helvetica, Arial, sans-serif; font-weight: 700; font-size: 26px; letter-spacing: -0.02em; color: %s; text-transform: uppercase;", brutalistFg(emailCtx)) -} - -func brutalistEmailBodyCellStyle(emailCtx templates.EmailContext) string { - return fmt.Sprintf("padding: 40px 48px; color: %s; font-size: 16px; line-height: 1.7;", brutalistFg(emailCtx)) -} - -func brutalistEmailFooterStyle(emailCtx templates.EmailContext) string { - return fmt.Sprintf("padding: 24px 48px 32px; border-top: 1px solid %s; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: %s;", brutalistBorder(emailCtx), brutalistMutedFg(emailCtx)) -} - -func brutalistEmailLinkStyle(emailCtx templates.EmailContext) string { - return fmt.Sprintf("color: %s; text-decoration: none; border-bottom: 1px solid %s;", brutalistFg(emailCtx), brutalistBorder(emailCtx)) -} diff --git a/email_wrapper.templ b/email_wrapper.templ deleted file mode 100644 index 246b34a..0000000 --- a/email_wrapper.templ +++ /dev/null @@ -1,65 +0,0 @@ -package main - -import "git.dev.alexdunmow.com/block/core/templates" - -templ brutalistEmailTemplate(emailCtx templates.EmailContext, body string) { - - - - - - - - { emailCtx.SiteSettings.SiteName } - - - - if emailCtx.PreviewText != "" { -
{ emailCtx.PreviewText }
- } - - - - -
- - - - - - - - - - - -
- - -} diff --git a/email_wrapper_templ.go b/email_wrapper_templ.go deleted file mode 100644 index 8467aee..0000000 --- a/email_wrapper_templ.go +++ /dev/null @@ -1,281 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import "git.dev.alexdunmow.com/block/core/templates" - -func brutalistEmailTemplate(emailCtx templates.EmailContext, body string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.SiteSettings.SiteName) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 13, Col: 42} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.PreviewText != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.PreviewText) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 27, Col: 102} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.SiteSettings.SiteName != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var9 string - templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.SiteSettings.SiteName) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 36, Col: 94} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(body).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.SiteSettings.SiteURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if emailCtx.UnsubscribeURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/embed.go b/embed.go deleted file mode 100644 index 3004555..0000000 --- a/embed.go +++ /dev/null @@ -1,55 +0,0 @@ -package main - -import ( - "embed" - "io/fs" - "net/http" - - "git.dev.alexdunmow.com/block/core/plugin" -) - -//go:embed assets/* -var assetsFS embed.FS - -//go:embed schemas/* -var schemasFS embed.FS - -//go:embed presets.json -var presetsData []byte - -//go:embed fonts.json -var fontsData []byte - -//go:embed plugin.mod -var pluginModBytes []byte - -// Assets returns the embedded assets filesystem. -func Assets() fs.FS { - sub, _ := fs.Sub(assetsFS, "assets") - return sub -} - -// Schemas returns the embedded schemas filesystem. -func Schemas() fs.FS { - sub, _ := fs.Sub(schemasFS, "schemas") - return sub -} - -// AssetsHandler serves the embedded assets via HTTP. -func AssetsHandler() http.Handler { - return http.FileServer(http.FS(Assets())) -} - -// ThemePresets returns the embedded preset JSON bytes. -func ThemePresets() []byte { return presetsData } - -// BundledFonts returns the embedded fonts manifest JSON bytes. -func BundledFonts() []byte { return fontsData } - -// ThemeCSSManifest returns the Brutalist CSS additions (hairlines, no-radius, -// grid overlay, font-family fallback stacks via CSS custom properties). -func ThemeCSSManifest() *plugin.CSSManifest { - return &plugin.CSSManifest{ - InputCSSAppend: brutalistAppendCSS, - } -} diff --git a/go.mod b/go.mod deleted file mode 100644 index 8cfc384..0000000 --- a/go.mod +++ /dev/null @@ -1,20 +0,0 @@ -module git.dev.alexdunmow.com/block/themes/brutalist - -go 1.26.4 - -require ( - git.dev.alexdunmow.com/block/core v0.15.2 - github.com/a-h/templ v0.3.1020 -) - -require ( - connectrpc.com/connect v1.20.0 // indirect - github.com/BurntSushi/toml v1.6.0 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.9.2 // indirect - golang.org/x/mod v0.34.0 // indirect - golang.org/x/text v0.36.0 // indirect - google.golang.org/protobuf v1.36.11 // indirect -) diff --git a/go.sum b/go.sum deleted file mode 100644 index ebd3d11..0000000 --- a/go.sum +++ /dev/null @@ -1,46 +0,0 @@ -connectrpc.com/connect v1.20.0 h1:6TNDAB+WeNd2uolWNlYczB5E0KNNaVMNUEx8JEUsPmQ= -connectrpc.com/connect v1.20.0/go.mod h1:A2ygJrukXwWy32vkCAAHNVguZrqZ+jeZ9rGRnGR4dN4= -git.dev.alexdunmow.com/block/core v0.15.2 h1:qTjJxa1pClxwehkdTxXiJDpHQLr5DoXBUCa40QRO0L8= -git.dev.alexdunmow.com/block/core v0.15.2/go.mod h1:A+mgA9oeWoPhXruv4Mjpywwl2A9B5I3cKzlJjalBdlE= -github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= -github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= -github.com/a-h/templ v0.3.1020 h1:ypAT/L5ySWEnZ6Zft/5yfoWXYYkhFNvEFOeeqecg4tw= -github.com/a-h/templ v0.3.1020/go.mod h1:A2DlK61v+K+NRoGnhmYbNYVmtYHcFO5/AisMvBdDxTM= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= -github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= -github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.9.2 h1:3ZhOzMWnR4yJ+RW1XImIPsD1aNSz4T4fyP7zlQb56hw= -github.com/jackc/pgx/v5 v5.9.2/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= -github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= -github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tetratelabs/wazero v1.12.0 h1:DuWcpNu/FzgEXgGBDp8J1Spc+CWOvvtvVyjKlaZopYU= -github.com/tetratelabs/wazero v1.12.0/go.mod h1:LvKtzl2RqO4gyF27BiXU+nKAjcV8f38U+kP/q2vgxh0= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= -golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= -golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= -golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ= -golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= -golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= -google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= -google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/heading_override.go b/heading_override.go deleted file mode 100644 index 70db2a7..0000000 --- a/heading_override.go +++ /dev/null @@ -1,39 +0,0 @@ -package main - -import ( - "bytes" - "context" - "strconv" -) - -// BrutalistHeadingBlock applies brutalist treatment to heading blocks: kills -// default rounding/leading, uses var(--font-heading), tracking-tight, -// uppercase on h1/h2. -func BrutalistHeadingBlock(ctx context.Context, content map[string]any) string { - text := getString(content, "text") - textClass := getString(content, "textClass") - level := parseBrutalistHeadingLevel(content) - - var buf bytes.Buffer - _ = brutalistHeadingComponent(level, text, textClass).Render(ctx, &buf) - return buf.String() -} - -func parseBrutalistHeadingLevel(content map[string]any) int { - if v, ok := content["level"].(float64); ok { - if l := int(v); l >= 1 && l <= 6 { - return l - } - } - if v, ok := content["level"].(int); ok { - if v >= 1 && v <= 6 { - return v - } - } - if v, ok := content["level"].(string); ok { - if n, err := strconv.Atoi(v); err == nil && n >= 1 && n <= 6 { - return n - } - } - return 2 -} diff --git a/heading_override.templ b/heading_override.templ deleted file mode 100644 index 9c78a92..0000000 --- a/heading_override.templ +++ /dev/null @@ -1,38 +0,0 @@ -package main - -func brutalistHeadingStyle(level int) string { - switch level { - case 1: - return "font-family: var(--font-heading, 'Space Grotesk', 'Inter Tight', sans-serif); font-weight: 700; font-size: clamp(2.5rem, 6vw, 5rem); line-height: 0.9; letter-spacing: -0.03em; text-transform: uppercase; color: hsl(var(--foreground)); margin: 0;" - case 2: - return "font-family: var(--font-heading, 'Space Grotesk', 'Inter Tight', sans-serif); font-weight: 700; font-size: clamp(1.875rem, 4vw, 3rem); line-height: 0.95; letter-spacing: -0.02em; text-transform: uppercase; color: hsl(var(--foreground)); margin: 0;" - case 3: - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 700; font-size: 1.5rem; line-height: 1; letter-spacing: -0.015em; color: hsl(var(--foreground)); margin: 0;" - case 4: - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 600; font-size: 1.25rem; line-height: 1.1; letter-spacing: -0.01em; color: hsl(var(--foreground)); margin: 0;" - case 5: - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 600; font-size: 1.125rem; line-height: 1.15; color: hsl(var(--foreground)); margin: 0;" - case 6: - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 600; font-size: 1rem; line-height: 1.2; color: hsl(var(--foreground)); margin: 0;" - } - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 700; color: hsl(var(--foreground)); margin: 0;" -} - -templ brutalistHeadingComponent(level int, text, textClass string) { - switch level { - case 1: -

{ text }

- case 2: -

{ text }

- case 3: -

{ text }

- case 4: -

{ text }

- case 5: -
{ text }
- case 6: -
{ text }
- default: -

{ text }

- } -} diff --git a/heading_override_templ.go b/heading_override_templ.go deleted file mode 100644 index f3b6e9f..0000000 --- a/heading_override_templ.go +++ /dev/null @@ -1,399 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func brutalistHeadingStyle(level int) string { - switch level { - case 1: - return "font-family: var(--font-heading, 'Space Grotesk', 'Inter Tight', sans-serif); font-weight: 700; font-size: clamp(2.5rem, 6vw, 5rem); line-height: 0.9; letter-spacing: -0.03em; text-transform: uppercase; color: hsl(var(--foreground)); margin: 0;" - case 2: - return "font-family: var(--font-heading, 'Space Grotesk', 'Inter Tight', sans-serif); font-weight: 700; font-size: clamp(1.875rem, 4vw, 3rem); line-height: 0.95; letter-spacing: -0.02em; text-transform: uppercase; color: hsl(var(--foreground)); margin: 0;" - case 3: - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 700; font-size: 1.5rem; line-height: 1; letter-spacing: -0.015em; color: hsl(var(--foreground)); margin: 0;" - case 4: - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 600; font-size: 1.25rem; line-height: 1.1; letter-spacing: -0.01em; color: hsl(var(--foreground)); margin: 0;" - case 5: - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 600; font-size: 1.125rem; line-height: 1.15; color: hsl(var(--foreground)); margin: 0;" - case 6: - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 600; font-size: 1rem; line-height: 1.2; color: hsl(var(--foreground)); margin: 0;" - } - return "font-family: var(--font-heading, 'Space Grotesk', sans-serif); font-weight: 700; color: hsl(var(--foreground)); margin: 0;" -} - -func brutalistHeadingComponent(level int, text, textClass string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - switch level { - case 1: - var templ_7745c5c3_Var2 = []any{textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 24, Col: 68} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 2: - var templ_7745c5c3_Var6 = []any{textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var9 string - templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 26, Col: 68} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 3: - var templ_7745c5c3_Var10 = []any{textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 28, Col: 68} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 4: - var templ_7745c5c3_Var14 = []any{textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 30, Col: 68} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 5: - var templ_7745c5c3_Var18 = []any{textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var21 string - templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 32, Col: 68} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 6: - var templ_7745c5c3_Var22 = []any{textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var25 string - templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 34, Col: 68} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - default: - var templ_7745c5c3_Var26 = []any{textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var26...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var29 string - templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 36, Col: 68} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/helpers.go b/helpers.go deleted file mode 100644 index aaa6d03..0000000 --- a/helpers.go +++ /dev/null @@ -1,51 +0,0 @@ -package main - -import "strings" - -// getString extracts a string value from a content map. -func getString(content map[string]any, key string) string { - if v, ok := content[key].(string); ok { - return v - } - return "" -} - -// getSlice extracts a slice of map[string]any from a content map. -func getSlice(content map[string]any, key string) []map[string]any { - if v, ok := content[key].([]any); ok { - result := make([]map[string]any, 0, len(v)) - for _, item := range v { - if m, ok := item.(map[string]any); ok { - result = append(result, m) - } - } - return result - } - return nil -} - -// getBool extracts a boolean-ish value from a content map. -// Accepts native bool plus the string forms "true"/"false" emitted by select-style editors. -func getBool(content map[string]any, key string, defaultVal bool) bool { - if v, ok := content[key].(bool); ok { - return v - } - if v, ok := content[key].(string); ok { - switch strings.ToLower(strings.TrimSpace(v)) { - case "true", "yes", "1": - return true - case "false", "no", "0": - return false - } - } - return defaultVal -} - -// resolveURL returns a safe-ish href value, defaulting to "#" when blank. -func resolveURL(s string) string { - s = strings.TrimSpace(s) - if s == "" { - return "#" - } - return s -} diff --git a/image_override.go b/image_override.go deleted file mode 100644 index 9e75bd5..0000000 --- a/image_override.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// BrutalistImageBlock wraps image content in a
with a mono caption slot. -func BrutalistImageBlock(ctx context.Context, content map[string]any) string { - src := getString(content, "src") - if src == "" { - src = getString(content, "url") - } - if src != "" { - src = blocks.ResolveMediaPath(src) - } - alt := getString(content, "alt") - caption := getString(content, "caption") - - var buf bytes.Buffer - _ = brutalistImageComponent(src, alt, caption).Render(ctx, &buf) - return buf.String() -} diff --git a/image_override.templ b/image_override.templ deleted file mode 100644 index ab260a1..0000000 --- a/image_override.templ +++ /dev/null @@ -1,12 +0,0 @@ -package main - -templ brutalistImageComponent(src, alt, caption string) { -
- if src != "" { - { - } - if caption != "" { -
{ caption }
- } -
-} diff --git a/image_override_templ.go b/image_override_templ.go deleted file mode 100644 index 0e16278..0000000 --- a/image_override_templ.go +++ /dev/null @@ -1,95 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func brutalistImageComponent(src, alt, caption string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if src != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"") ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if caption != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(caption) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `image_override.templ`, Line: 9, Col: 24} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/main.go b/main.go deleted file mode 100644 index 0e848b0..0000000 --- a/main.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build wasip1 - -// Package main compiles the brutalist theme to a wasip1 reactor-mode wasm guest -// (WO-WZ-015). The .so build path is retired; `ninja plugin build` produces the -// .bnp artifact the registry serves. -// -// Reactor mode: the host runs `_initialize` once per pooled instance, which -// runs this init func (hence wasmguest.Serve) before any bn_invoke. Serve is -// non-blocking; all theme work then arrives over the ABI hook calls. main is -// never called. -package main - -import "git.dev.alexdunmow.com/block/core/plugin/wasmguest" - -func init() { wasmguest.Serve(Registration) } - -func main() {} // never called — reactor mode diff --git a/manifest.yaml b/manifest.yaml new file mode 100644 index 0000000..e7d4c67 --- /dev/null +++ b/manifest.yaml @@ -0,0 +1,403 @@ +# Brutalist theme — codeless .bnp manifest (WO-WZ-021 Phase B1). +# Synthesized into manifest.pb by `ninja plugin build` (no plugin.wasm). +theme_presets: presets.json +bundled_fonts: fonts.json +master_pages: master_pages.json + +system_templates: + - key: brutalist + title: Brutalist + description: "Concrete, oversized type, hard 12-col grid theme for design studios, architecture firms and art galleries." + +page_templates: + - system: brutalist + key: default + title: Default + description: "Standard masthead + 12-col body + footer" + slots: [header, main, footer] + - system: brutalist + key: landing + title: Index Sheet + description: "Oversized headline + project ledger" + slots: [hero, ledger, footer] + - system: brutalist + key: article + title: Case Study + description: "Long-form project page with metadata strip" + slots: [header, meta, main, footer] + - system: brutalist + key: full-width + title: Full Bleed + description: "Edge-to-edge gallery layout" + slots: [header, main, footer] + +template_overrides: + - { template: brutalist, block: heading } + - { template: brutalist, block: text } + - { template: brutalist, block: button } + - { template: brutalist, block: image } + +email_wrappers: + - brutalist + +css: + input_css_append: | + /* === Brutalist theme utilities === */ + + :where(.brutalist-page, .brutalist-page *) { + border-radius: 0 !important; + } + + .brutalist-page { + font-family: var(--font-body, "Inter", "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif); + color: hsl(var(--foreground)); + background-color: hsl(var(--background)); + letter-spacing: 0.005em; + } + + .brutalist-display { + font-family: var(--font-heading, "Space Grotesk", "Inter Tight", "Helvetica Neue", Helvetica, Arial, sans-serif); + font-weight: 700; + letter-spacing: -0.02em; + line-height: 0.9; + text-transform: uppercase; + } + + .brutalist-mono { + font-family: var(--font-mono, "JetBrains Mono", "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace); + letter-spacing: 0.04em; + text-transform: uppercase; + } + + /* --- Hairline rules and solid slabs --- */ + + .brutalist-rule-ink { + border-color: hsl(var(--border)); + border-style: solid; + border-width: 1px; + } + + .brutalist-rule-thick { + border-color: hsl(var(--border)); + border-style: solid; + border-width: 4px; + } + + .brutalist-divider { + border-top: 1px solid hsl(var(--border)); + } + + /* --- 12-column grid scaffolding --- */ + + .brutalist-grid-12 { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + column-gap: 0; + row-gap: 0; + } + + .brutalist-col-span-8 { + grid-column: span 8 / span 8; + } + + /* Project ledger row: 12-col grid with mono leading number. */ + + .brutalist-ledger-row { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + align-items: baseline; + padding: 1.25rem 0; + border-bottom: 1px solid hsl(var(--border)); + } + + .brutalist-ledger-row > * { + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 0.875rem; + letter-spacing: 0.06em; + text-transform: uppercase; + } + + .brutalist-ledger-row .ledger-no { grid-column: span 1; } + .brutalist-ledger-row .ledger-year { grid-column: span 2; } + .brutalist-ledger-row .ledger-client { grid-column: span 5; font-family: var(--font-heading, "Space Grotesk", sans-serif); font-size: 1.125rem; text-transform: none; letter-spacing: -0.005em; } + .brutalist-ledger-row .ledger-role { grid-column: span 3; } + .brutalist-ledger-row .ledger-arrow { grid-column: span 1; text-align: right; } + + @media (max-width: 768px) { + .brutalist-ledger-row { + grid-template-columns: 1fr; + row-gap: 0.25rem; + padding: 1rem 0; + } + .brutalist-ledger-row .ledger-no, + .brutalist-ledger-row .ledger-year, + .brutalist-ledger-row .ledger-client, + .brutalist-ledger-row .ledger-role, + .brutalist-ledger-row .ledger-arrow { grid-column: 1 / -1; text-align: left; } + } + + /* --- Caption block --- */ + + .brutalist-figure figcaption { + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 11px; + line-height: 1.4; + letter-spacing: 0.08em; + text-transform: uppercase; + color: hsl(var(--muted-foreground)); + padding-top: 0.5rem; + } + + /* --- Pull quote --- */ + + .brutalist-pullquote { + display: grid; + grid-template-columns: repeat(12, minmax(0, 1fr)); + padding: 3rem 0; + border-top: 1px solid hsl(var(--border)); + border-bottom: 1px solid hsl(var(--border)); + } + + .brutalist-pullquote blockquote { + grid-column: 3 / span 8; + font-family: var(--font-heading, "Space Grotesk", sans-serif); + font-weight: 700; + font-size: clamp(1.75rem, 5vw, 3.5rem); + line-height: 1; + letter-spacing: -0.02em; + color: hsl(var(--foreground)); + } + + .brutalist-pullquote cite { + grid-column: 3 / span 8; + margin-top: 1.5rem; + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 0.75rem; + letter-spacing: 0.1em; + text-transform: uppercase; + font-style: normal; + color: hsl(var(--muted-foreground)); + } + + @media (max-width: 768px) { + .brutalist-pullquote blockquote, + .brutalist-pullquote cite { grid-column: 1 / -1; } + } + + /* --- Meta strip --- */ + + .brutalist-meta-strip { + display: flex; + flex-wrap: wrap; + gap: 2rem; + padding: 1rem 0; + border-top: 1px solid hsl(var(--border)); + border-bottom: 1px solid hsl(var(--border)); + } + + .brutalist-meta-strip dt { + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 11px; + letter-spacing: 0.12em; + text-transform: uppercase; + color: hsl(var(--muted-foreground)); + } + + .brutalist-meta-strip dd { + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 0.75rem; + letter-spacing: 0.06em; + text-transform: uppercase; + color: hsl(var(--foreground)); + margin: 0; + } + + /* --- Buttons: square, 1px ink border, hover inverts to accent --- */ + + .brutalist-page button, + .brutalist-page .brutalist-btn, + .brutalist-page [data-brutalist-btn] { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.75rem 1.5rem; + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 0.75rem; + letter-spacing: 0.12em; + text-transform: uppercase; + background-color: transparent; + color: hsl(var(--foreground)); + border: 1px solid hsl(var(--border)); + border-radius: 0; + cursor: pointer; + transition: background-color 80ms linear, color 80ms linear; + } + + .brutalist-page button:hover, + .brutalist-page .brutalist-btn:hover, + .brutalist-page [data-brutalist-btn]:hover { + background-color: hsl(var(--accent)); + color: hsl(var(--accent-foreground)); + } + + .brutalist-page button:focus-visible, + .brutalist-page .brutalist-btn:focus-visible, + .brutalist-page [data-brutalist-btn]:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 2px; + } + + /* --- Inputs: square --- */ + + .brutalist-page input, + .brutalist-page select, + .brutalist-page textarea { + border-radius: 0; + border: 1px solid hsl(var(--input)); + background-color: transparent; + color: hsl(var(--foreground)); + padding: 0.5rem 0.75rem; + } + + .brutalist-page input:focus, + .brutalist-page select:focus, + .brutalist-page textarea:focus { + outline: 2px solid hsl(var(--ring)); + outline-offset: 2px; + } + + /* --- Masthead --- */ + + .brutalist-masthead { + position: relative; + padding: 4rem 0 2rem; + } + + .brutalist-masthead .studio-name { + font-family: var(--font-heading, "Space Grotesk", sans-serif); + font-weight: 700; + font-size: clamp(3rem, 14vw, 16rem); + line-height: 0.85; + letter-spacing: -0.03em; + text-transform: uppercase; + color: hsl(var(--foreground)); + margin: 0; + } + + .brutalist-masthead .tagline { + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 0.75rem; + letter-spacing: 0.12em; + text-transform: uppercase; + color: hsl(var(--muted-foreground)); + margin-top: 1rem; + } + + .brutalist-masthead .index-counter { + position: absolute; + top: 1.5rem; + right: 0; + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 11px; + letter-spacing: 0.12em; + text-transform: uppercase; + color: hsl(var(--muted-foreground)); + } + + /* --- Concrete hero --- */ + + .brutalist-hero { + position: relative; + padding: 6rem 0 4rem; + overflow: hidden; + } + + .brutalist-hero .eyebrow { + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 0.75rem; + letter-spacing: 0.16em; + text-transform: uppercase; + color: hsl(var(--muted-foreground)); + margin-bottom: 1.5rem; + } + + .brutalist-hero .headline { + font-family: var(--font-heading, "Space Grotesk", sans-serif); + font-weight: 700; + font-size: clamp(3rem, 22vw, 18rem); + line-height: 0.85; + letter-spacing: -0.04em; + text-transform: uppercase; + color: hsl(var(--foreground)); + margin: 0; + } + + .brutalist-hero[data-has-media="true"] .headline { + color: hsl(var(--background)); + mix-blend-mode: difference; + } + + .brutalist-hero .media-bg { + position: absolute; + inset: 0; + z-index: 0; + background-size: cover; + background-position: center; + } + + .brutalist-hero .media-bg::after { + content: ""; + position: absolute; + inset: 0; + background-color: hsl(var(--background) / 0.4); + } + + .brutalist-hero .inner { + position: relative; + z-index: 1; + } + + /* --- Colophon --- */ + + .brutalist-colophon { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 2rem; + padding: 3rem 0 1.5rem; + border-top: 4px solid hsl(var(--border)); + font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); + font-size: 0.75rem; + letter-spacing: 0.1em; + text-transform: uppercase; + color: hsl(var(--muted-foreground)); + } + + .brutalist-colophon .stamp { + text-align: right; + color: hsl(var(--foreground)); + } + + @media (max-width: 768px) { + .brutalist-colophon { + grid-template-columns: 1fr; + } + .brutalist-colophon .stamp { text-align: left; } + } + + /* --- Grid overlay debug --- */ + + body.brutalist-grid-debug::before { + content: ""; + position: fixed; + inset: 0; + z-index: 9999; + pointer-events: none; + background-image: repeating-linear-gradient( + to right, + hsl(var(--ring) / 0.18) 0, + hsl(var(--ring) / 0.18) 1px, + transparent 1px, + transparent calc(100% / 12) + ); + } + diff --git a/master_pages.json b/master_pages.json new file mode 100644 index 0000000..0b5db75 --- /dev/null +++ b/master_pages.json @@ -0,0 +1,33 @@ +[ + { + "key": "brutalist:default-master", + "title": "Brutalist Default Master", + "page_templates": ["default", "article"], + "blocks": [ + { "block_key": "navbar", "title": "Masthead Nav", "content": { "menuName": "main" }, "slot": "header", "sort_order": 0 }, + { "block_key": "brutalist:masthead", "title": "Studio Masthead", "content": { "studioName": "STUDIO" }, "slot": "header", "sort_order": 1 }, + { "block_key": "slot", "title": "Main Content", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, + { "block_key": "brutalist:colophon", "title": "Colophon Footer", "content": { "showAddress": true }, "slot": "footer", "sort_order": 0 } + ] + }, + { + "key": "brutalist:index-master", + "title": "Brutalist Index Master", + "page_templates": ["landing"], + "blocks": [ + { "block_key": "brutalist:masthead", "title": "Studio Masthead", "content": { "studioName": "STUDIO" }, "slot": "hero", "sort_order": 0 }, + { "block_key": "slot", "title": "Ledger Slot", "content": { "slotName": "ledger" }, "slot": "ledger", "sort_order": 0 }, + { "block_key": "brutalist:colophon", "title": "Colophon Footer", "content": { "showAddress": true }, "slot": "footer", "sort_order": 0 } + ] + }, + { + "key": "brutalist:fullbleed-master", + "title": "Brutalist Full Bleed Master", + "page_templates": ["full-width"], + "blocks": [ + { "block_key": "navbar", "title": "Masthead Nav", "content": { "menuName": "main" }, "slot": "header", "sort_order": 0 }, + { "block_key": "slot", "title": "Full Bleed Slot", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, + { "block_key": "brutalist:colophon", "title": "Colophon Footer", "content": { "showAddress": false }, "slot": "footer", "sort_order": 0 } + ] + } +] diff --git a/masthead.go b/masthead.go deleted file mode 100644 index 7c5e3c1..0000000 --- a/masthead.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// MastheadBlockMeta defines the Studio Masthead block. -var MastheadBlockMeta = blocks.BlockMeta{ - Key: "masthead", - Title: "Studio Masthead", - Description: "Oversized studio wordmark with mono index counter top-right", - Category: blocks.CategoryLayout, - Source: "brutalist", -} - -// MastheadData carries display data for the masthead component. -type MastheadData struct { - StudioName string - Tagline string - IndexNumber string -} - -// MastheadBlock renders the studio masthead. -// Content: {"studioName": "...", "tagline": "...", "indexNumber": "01 / 14"} -func MastheadBlock(ctx context.Context, content map[string]any) string { - data := MastheadData{ - StudioName: getString(content, "studioName"), - Tagline: getString(content, "tagline"), - IndexNumber: getString(content, "indexNumber"), - } - if data.StudioName == "" { - data.StudioName = "STUDIO" - } - if data.IndexNumber == "" { - data.IndexNumber = "01 / 14" - } - - var buf bytes.Buffer - _ = mastheadComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/masthead.templ b/masthead.templ deleted file mode 100644 index cade958..0000000 --- a/masthead.templ +++ /dev/null @@ -1,11 +0,0 @@ -package main - -templ mastheadComponent(data MastheadData) { -
- { data.IndexNumber } -

{ data.StudioName }

- if data.Tagline != "" { -

{ data.Tagline }

- } -
-} diff --git a/masthead_templ.go b/masthead_templ.go deleted file mode 100644 index 2175013..0000000 --- a/masthead_templ.go +++ /dev/null @@ -1,89 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func mastheadComponent(data MastheadData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(data.IndexNumber) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `masthead.templ`, Line: 5, Col: 63} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(data.StudioName) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `masthead.templ`, Line: 6, Col: 43} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Tagline != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(data.Tagline) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `masthead.templ`, Line: 8, Col: 36} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/meta_strip.go b/meta_strip.go deleted file mode 100644 index b291b7f..0000000 --- a/meta_strip.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// MetaStripBlockMeta defines the Metadata Strip block. -var MetaStripBlockMeta = blocks.BlockMeta{ - Key: "meta_strip", - Title: "Metadata Strip", - Description: "Mono uppercase strip: CLIENT / YEAR / DISCIPLINE / LOCATION", - Category: blocks.CategoryContent, - Source: "brutalist", -} - -// MetaStripItem is one label/value pair in the metadata strip. -type MetaStripItem struct { - Label string - Value string -} - -// MetaStripData carries data for the metadata strip component. -type MetaStripData struct { - Items []MetaStripItem -} - -// MetaStripBlock renders the metadata strip. -// Content: {"items": [{"label":"CLIENT","value":"..."}, ...]} -func MetaStripBlock(ctx context.Context, content map[string]any) string { - raw := getSlice(content, "items") - items := make([]MetaStripItem, 0, len(raw)) - for _, item := range raw { - items = append(items, MetaStripItem{ - Label: getString(item, "label"), - Value: getString(item, "value"), - }) - } - - var buf bytes.Buffer - _ = metaStripComponent(MetaStripData{Items: items}).Render(ctx, &buf) - return buf.String() -} diff --git a/meta_strip.templ b/meta_strip.templ deleted file mode 100644 index 7847b27..0000000 --- a/meta_strip.templ +++ /dev/null @@ -1,12 +0,0 @@ -package main - -templ metaStripComponent(data MetaStripData) { -
- for _, item := range data.Items { -
-
{ item.Label }
-
{ item.Value }
-
- } -
-} diff --git a/meta_strip_templ.go b/meta_strip_templ.go deleted file mode 100644 index 9b8102e..0000000 --- a/meta_strip_templ.go +++ /dev/null @@ -1,76 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func metaStripComponent(data MetaStripData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, item := range data.Items { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `meta_strip.templ`, Line: 7, Col: 20} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(item.Value) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `meta_strip.templ`, Line: 8, Col: 20} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/page_data.go b/page_data.go deleted file mode 100644 index 000f1f7..0000000 --- a/page_data.go +++ /dev/null @@ -1,69 +0,0 @@ -package main - -import ( - "git.dev.alexdunmow.com/block/core/templates/bn" -) - -// PageData carries the data passed into Brutalist page templates. -type PageData struct { - Title string - Slots map[string]string - ThemeMode string - ThemeCSS string - SiteSettings bn.SiteSettingsData - PageMeta bn.PageMeta - StructuredData string - CSSHash string - PageviewNonce string - EngagementConfig bn.EngagementConfig -} - -func parseBrutalistPageData(doc map[string]any) PageData { - title := "Untitled" - if t, ok := doc["title"].(string); ok { - title = t - } - - slots := make(map[string]string) - if s, ok := doc["slots"].(map[string]string); ok { - slots = s - } - - themeCSS := "" - if tc, ok := doc["theme_css"].(string); ok { - themeCSS = tc - } - - structuredData := "" - if sd, ok := doc["structured_data"].(string); ok { - structuredData = sd - } - - cssHash := "" - if ch, ok := doc["css_hash"].(string); ok { - cssHash = ch - } - - pageviewNonce := "" - if pn, ok := doc["pageview_nonce"].(string); ok { - pageviewNonce = pn - } - - themeMode := "light" - if tm, ok := doc["theme_mode"].(string); ok && tm != "" { - themeMode = tm - } - - return PageData{ - Title: title, - Slots: slots, - ThemeMode: themeMode, - ThemeCSS: themeCSS, - SiteSettings: bn.ParseSiteSettings(doc), - PageMeta: bn.ParsePageMeta(doc), - StructuredData: structuredData, - CSSHash: cssHash, - PageviewNonce: pageviewNonce, - EngagementConfig: bn.ParseEngagementConfig(doc), - } -} diff --git a/plugin.mod b/plugin.mod index 6e94c7e..8007dd3 100644 --- a/plugin.mod +++ b/plugin.mod @@ -2,11 +2,8 @@ name = "brutalist" display_name = "Brutalist" scope = "@themes" -version = "0.1.2" +version = "0.2.0" description = "Concrete, oversized type, hard 12-col grid theme for design studios, architecture firms and art galleries." kind = "theme" categories = ["templates"] tags = ["brutalist", "raw", "mono", "agency", "architecture", "gallery", "editorial", "minimal"] - -[compatibility] -block_core = ">=0.15.0 <0.16.0" diff --git a/project_ledger.go b/project_ledger.go deleted file mode 100644 index 0c036f1..0000000 --- a/project_ledger.go +++ /dev/null @@ -1,51 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// ProjectLedgerBlockMeta defines the Project Ledger block. -var ProjectLedgerBlockMeta = blocks.BlockMeta{ - Key: "project_ledger", - Title: "Project Ledger", - Description: "Ordered project list on a 12-col grid: number / year / client / role / arrow", - Category: blocks.CategoryContent, - Source: "brutalist", -} - -// ProjectLedgerRow is one row in the ledger. -type ProjectLedgerRow struct { - No string - Year string - Client string - Role string - Link string -} - -// ProjectLedgerData carries data for the ledger component. -type ProjectLedgerData struct { - Rows []ProjectLedgerRow -} - -// ProjectLedgerBlock renders the project ledger. -// Content: {"rows": [{"no":"01","year":"2024","client":"...","role":"...","link":"..."}]} -func ProjectLedgerBlock(ctx context.Context, content map[string]any) string { - raw := getSlice(content, "rows") - rows := make([]ProjectLedgerRow, 0, len(raw)) - for _, item := range raw { - rows = append(rows, ProjectLedgerRow{ - No: getString(item, "no"), - Year: getString(item, "year"), - Client: getString(item, "client"), - Role: getString(item, "role"), - Link: getString(item, "link"), - }) - } - - var buf bytes.Buffer - _ = projectLedgerComponent(ProjectLedgerData{Rows: rows}).Render(ctx, &buf) - return buf.String() -} diff --git a/project_ledger.templ b/project_ledger.templ deleted file mode 100644 index f847b3c..0000000 --- a/project_ledger.templ +++ /dev/null @@ -1,31 +0,0 @@ -package main - -templ projectLedgerComponent(data ProjectLedgerData) { -
- if len(data.Rows) == 0 { -

No projects listed.

- } else { -
    - for _, row := range data.Rows { -
  1. - { row.No } - { row.Year } - - if row.Link != "" { - { row.Client } - } else { - { row.Client } - } - - { row.Role } - - if row.Link != "" { - - } - -
  2. - } -
- } -
-} diff --git a/project_ledger_templ.go b/project_ledger_templ.go deleted file mode 100644 index a61baf5..0000000 --- a/project_ledger_templ.go +++ /dev/null @@ -1,173 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func projectLedgerComponent(data ProjectLedgerData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if len(data.Rows) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "

No projects listed.

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, row := range data.Rows { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
  1. ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(row.No) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `project_ledger.templ`, Line: 11, Col: 38} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(row.Year) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `project_ledger.templ`, Line: 12, Col: 42} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if row.Link != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(row.Client) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `project_ledger.templ`, Line: 15, Col: 115} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(row.Client) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `project_ledger.templ`, Line: 17, Col: 20} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(row.Role) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `project_ledger.templ`, Line: 20, Col: 42} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if row.Link != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
  2. ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/pull_quote.go b/pull_quote.go deleted file mode 100644 index 6ea4ed6..0000000 --- a/pull_quote.go +++ /dev/null @@ -1,36 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// PullQuoteBlockMeta defines the Pull Quote block. -var PullQuoteBlockMeta = blocks.BlockMeta{ - Key: "pull_quote", - Title: "Pull Quote", - Description: "Massive quote spanning 8 columns with hairline rules above and below", - Category: blocks.CategoryContent, - Source: "brutalist", -} - -// PullQuoteData carries data for the pull-quote component. -type PullQuoteData struct { - Quote string - Attribution string -} - -// PullQuoteBlock renders the pull quote. -// Content: {"quote": "", "attribution": "..."} -func PullQuoteBlock(ctx context.Context, content map[string]any) string { - data := PullQuoteData{ - Quote: getString(content, "quote"), - Attribution: getString(content, "attribution"), - } - - var buf bytes.Buffer - _ = pullQuoteComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/pull_quote.templ b/pull_quote.templ deleted file mode 100644 index 102d52b..0000000 --- a/pull_quote.templ +++ /dev/null @@ -1,12 +0,0 @@ -package main - -templ pullQuoteComponent(data PullQuoteData) { -
-
- @templ.Raw(data.Quote) -
- if data.Attribution != "" { - — { data.Attribution } - } -
-} diff --git a/pull_quote_templ.go b/pull_quote_templ.go deleted file mode 100644 index 43d0c97..0000000 --- a/pull_quote_templ.go +++ /dev/null @@ -1,71 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func pullQuoteComponent(data PullQuoteData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Quote).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Attribution != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "— ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var2 string - templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(data.Attribution) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `pull_quote.templ`, Line: 9, Col: 31} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/register.go b/register.go deleted file mode 100644 index b8c4bf3..0000000 --- a/register.go +++ /dev/null @@ -1,187 +0,0 @@ -package main - -import ( - "context" - - "github.com/a-h/templ" - - "git.dev.alexdunmow.com/block/core/blocks" - "git.dev.alexdunmow.com/block/core/plugin" - "git.dev.alexdunmow.com/block/core/templates" -) - -// wrap adapts a templ-returning render function to a templates.TemplateFunc. -// templ.Component already implements templates.HTMLComponent via Render. -func wrap(f func(ctx context.Context, doc map[string]any) templ.Component) templates.TemplateFunc { - return func(ctx context.Context, doc map[string]any) templates.HTMLComponent { - return f(ctx, doc) - } -} - -// Register installs the Brutalist system template, its four page templates, -// theme-specific blocks, block overrides, and the email wrapper. -func Register(tr templates.TemplateRegistry, br blocks.BlockRegistry) error { - tr.RegisterSystemTemplate(templates.SystemTemplateMeta{ - Key: "brutalist", - Title: "Brutalist", - Description: "Concrete, oversized type, hard 12-col grid theme for design studios, architecture firms and art galleries.", - }) - - if err := tr.RegisterPageTemplate("brutalist", templates.PageTemplateMeta{ - Key: "default", - Title: "Default", - Description: "Standard masthead + 12-col body + footer", - Slots: []string{"header", "main", "footer"}, - }, wrap(RenderBrutalist)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("brutalist", templates.PageTemplateMeta{ - Key: "landing", - Title: "Index Sheet", - Description: "Oversized headline + project ledger", - Slots: []string{"hero", "ledger", "footer"}, - }, wrap(RenderBrutalistLanding)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("brutalist", templates.PageTemplateMeta{ - Key: "article", - Title: "Case Study", - Description: "Long-form project page with metadata strip", - Slots: []string{"header", "meta", "main", "footer"}, - }, wrap(RenderBrutalistArticle)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("brutalist", templates.PageTemplateMeta{ - Key: "full-width", - Title: "Full Bleed", - Description: "Edge-to-edge gallery layout", - Slots: []string{"header", "main", "footer"}, - }, wrap(RenderBrutalistFullWidth)); err != nil { - return err - } - - // Load schemas BEFORE any block registration so the registry can bind - // content shapes to the block keys. - if err := br.LoadSchemasFromFS(Schemas()); err != nil { - return err - } - - br.Register(MastheadBlockMeta, MastheadBlock) - br.Register(ProjectLedgerBlockMeta, ProjectLedgerBlock) - br.Register(ConcreteHeroBlockMeta, ConcreteHeroBlock) - br.Register(MetaStripBlockMeta, MetaStripBlock) - br.Register(CaptionImageBlockMeta, CaptionImageBlock) - br.Register(PullQuoteBlockMeta, PullQuoteBlock) - br.Register(ColophonBlockMeta, ColophonBlock) - - br.RegisterTemplateOverride("brutalist", "heading", BrutalistHeadingBlock) - br.RegisterTemplateOverride("brutalist", "text", BrutalistTextBlock) - br.RegisterTemplateOverride("brutalist", "button", BrutalistButtonBlock) - br.RegisterTemplateOverride("brutalist", "image", BrutalistImageBlock) - - tr.RegisterEmailWrapper("brutalist", BrutalistEmailWrapper) - - return nil -} - -// DefaultMasterPages provisions the Brutalist default master pages on first -// theme activation. Three masters cover the four page templates per -// spec section 7. -func DefaultMasterPages() []plugin.MasterPageDefinition { - return []plugin.MasterPageDefinition{ - { - Key: "brutalist:default-master", - Title: "Brutalist Default Master", - PageTemplates: []string{"default", "article"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "navbar", - Title: "Masthead Nav", - Content: map[string]any{"menuName": "main"}, - Slot: "header", - SortOrder: 0, - }, - { - BlockKey: "brutalist:masthead", - Title: "Studio Masthead", - Content: map[string]any{"studioName": "STUDIO"}, - Slot: "header", - SortOrder: 1, - }, - { - BlockKey: "slot", - Title: "Main Content", - Content: map[string]any{"slotName": "main"}, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "brutalist:colophon", - Title: "Colophon Footer", - Content: map[string]any{"showAddress": true}, - Slot: "footer", - SortOrder: 0, - }, - }, - }, - { - Key: "brutalist:index-master", - Title: "Brutalist Index Master", - PageTemplates: []string{"landing"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "brutalist:masthead", - Title: "Studio Masthead", - Content: map[string]any{"studioName": "STUDIO"}, - Slot: "hero", - SortOrder: 0, - }, - { - BlockKey: "slot", - Title: "Ledger Slot", - Content: map[string]any{"slotName": "ledger"}, - Slot: "ledger", - SortOrder: 0, - }, - { - BlockKey: "brutalist:colophon", - Title: "Colophon Footer", - Content: map[string]any{"showAddress": true}, - Slot: "footer", - SortOrder: 0, - }, - }, - }, - { - Key: "brutalist:fullbleed-master", - Title: "Brutalist Full Bleed Master", - PageTemplates: []string{"full-width"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "navbar", - Title: "Masthead Nav", - Content: map[string]any{"menuName": "main"}, - Slot: "header", - SortOrder: 0, - }, - { - BlockKey: "slot", - Title: "Full Bleed Slot", - Content: map[string]any{"slotName": "main"}, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "brutalist:colophon", - Title: "Colophon Footer", - Content: map[string]any{"showAddress": false}, - Slot: "footer", - SortOrder: 0, - }, - }, - }, - } -} diff --git a/registration.go b/registration.go deleted file mode 100644 index 995af6d..0000000 --- a/registration.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "io/fs" - "net/http" - - "git.dev.alexdunmow.com/block/core/blocks" - "git.dev.alexdunmow.com/block/core/plugin" - "git.dev.alexdunmow.com/block/core/templates" -) - -// Registration is the compile-time plugin registration for the Brutalist theme. -var Registration = plugin.PluginRegistration{ - Name: "brutalist", - Version: plugin.ParseModVersion(pluginModBytes), - Register: func(tr templates.TemplateRegistry, br blocks.BlockRegistry) error { - return Register(tr, br) - }, - Assets: func() http.Handler { return AssetsHandler() }, - Schemas: func() fs.FS { return Schemas() }, - ThemePresets: func() []byte { return ThemePresets() }, - BundledFonts: func() []byte { return BundledFonts() }, - MasterPages: func() []plugin.MasterPageDefinition { return DefaultMasterPages() }, - CSSManifest: func() *plugin.CSSManifest { return ThemeCSSManifest() }, -} diff --git a/template.templ b/template.templ deleted file mode 100644 index 0d0f0e5..0000000 --- a/template.templ +++ /dev/null @@ -1,188 +0,0 @@ -package main - -import ( - "context" - - "git.dev.alexdunmow.com/block/core/templates/bn" -) - -// Brutalist default page template: header / 12-col body / colophon footer. -templ Brutalist(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/brutalist/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
-
- @templ.Raw(data.Slots["header"]) -
-
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } else { -

NO CONTENT BLOCKS ASSIGNED TO THIS PAGE.

- } -
-
-
-
- @templ.Raw(data.Slots["footer"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// BrutalistLanding: oversized headline + project ledger. -templ BrutalistLanding(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/brutalist/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
-
- @templ.Raw(data.Slots["hero"]) -
-
-
-
- if ledger, ok := data.Slots["ledger"]; ok && ledger != "" { - @templ.Raw(ledger) - } -
-
-
-
- @templ.Raw(data.Slots["footer"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// BrutalistArticle: case study with metadata strip. -templ BrutalistArticle(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/brutalist/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
-
- @templ.Raw(data.Slots["header"]) -
-
-
-
- @templ.Raw(data.Slots["meta"]) -
-
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } -
-
-
-
- @templ.Raw(data.Slots["footer"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -// BrutalistFullWidth: edge-to-edge gallery layout. -templ BrutalistFullWidth(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/brutalist/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
-
- @templ.Raw(data.Slots["header"]) -
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } -
-
-
- @templ.Raw(data.Slots["footer"]) -
-
- @bn.BodyEnd(data.SiteSettings) - - -} - -func RenderBrutalist(ctx context.Context, doc map[string]any) templ.Component { - return Brutalist(parseBrutalistPageData(doc)) -} - -func RenderBrutalistLanding(ctx context.Context, doc map[string]any) templ.Component { - return BrutalistLanding(parseBrutalistPageData(doc)) -} - -func RenderBrutalistArticle(ctx context.Context, doc map[string]any) templ.Component { - return BrutalistArticle(parseBrutalistPageData(doc)) -} - -func RenderBrutalistFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return BrutalistFullWidth(parseBrutalistPageData(doc)) -} diff --git a/template_templ.go b/template_templ.go deleted file mode 100644 index ed0392b..0000000 --- a/template_templ.go +++ /dev/null @@ -1,410 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import ( - "context" - - "git.dev.alexdunmow.com/block/core/templates/bn" -) - -// Brutalist default page template: header / 12-col body / colophon footer. -func Brutalist(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/brutalist/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.AdminBypassBanner(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["header"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templ.Raw(main).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "

NO CONTENT BLOCKS ASSIGNED TO THIS PAGE.

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["footer"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// BrutalistLanding: oversized headline + project ledger. -func BrutalistLanding(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/brutalist/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.AdminBypassBanner(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["hero"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if ledger, ok := data.Slots["ledger"]; ok && ledger != "" { - templ_7745c5c3_Err = templ.Raw(ledger).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["footer"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// BrutalistArticle: case study with metadata strip. -func BrutalistArticle(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var3 := templ.GetChildren(ctx) - if templ_7745c5c3_Var3 == nil { - templ_7745c5c3_Var3 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/brutalist/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.AdminBypassBanner(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["header"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["meta"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templ.Raw(main).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["footer"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// BrutalistFullWidth: edge-to-edge gallery layout. -func BrutalistFullWidth(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var4 := templ.GetChildren(ctx) - if templ_7745c5c3_Var4 == nil { - templ_7745c5c3_Var4 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/brutalist/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.AdminBypassBanner(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["header"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templ.Raw(main).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["footer"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -func RenderBrutalist(ctx context.Context, doc map[string]any) templ.Component { - return Brutalist(parseBrutalistPageData(doc)) -} - -func RenderBrutalistLanding(ctx context.Context, doc map[string]any) templ.Component { - return BrutalistLanding(parseBrutalistPageData(doc)) -} - -func RenderBrutalistArticle(ctx context.Context, doc map[string]any) templ.Component { - return BrutalistArticle(parseBrutalistPageData(doc)) -} - -func RenderBrutalistFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return BrutalistFullWidth(parseBrutalistPageData(doc)) -} - -var _ = templruntime.GeneratedTemplate diff --git a/templates/brutalist/article.ninjatpl b/templates/brutalist/article.ninjatpl new file mode 100644 index 0000000..e0fac74 --- /dev/null +++ b/templates/brutalist/article.ninjatpl @@ -0,0 +1,22 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+
{{ slots.header|safe }}
+
+
+
{{ slots.meta|safe }}
+
+
+
+ {% if slots.main %}{{ slots.main|safe }}{% endif %} +
+
+
+
{{ slots.footer|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/brutalist/default.ninjatpl b/templates/brutalist/default.ninjatpl new file mode 100644 index 0000000..737b84f --- /dev/null +++ b/templates/brutalist/default.ninjatpl @@ -0,0 +1,19 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+
{{ slots.header|safe }}
+
+
+
+ {% if slots.main %}{{ slots.main|safe }}{% else %}

NO CONTENT BLOCKS ASSIGNED TO THIS PAGE.

{% endif %} +
+
+
+
{{ slots.footer|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/brutalist/full-width.ninjatpl b/templates/brutalist/full-width.ninjatpl new file mode 100644 index 0000000..c88c6e6 --- /dev/null +++ b/templates/brutalist/full-width.ninjatpl @@ -0,0 +1,17 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+
{{ slots.header|safe }}
+
+
+ {% if slots.main %}{{ slots.main|safe }}{% endif %} +
+
+
{{ slots.footer|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/brutalist/landing.ninjatpl b/templates/brutalist/landing.ninjatpl new file mode 100644 index 0000000..89e334c --- /dev/null +++ b/templates/brutalist/landing.ninjatpl @@ -0,0 +1,19 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+
{{ slots.hero|safe }}
+
+
+
+ {% if slots.ledger %}{{ slots.ledger|safe }}{% endif %} +
+
+
+
{{ slots.footer|safe }}
+
+ {{ body_end_html|safe }} + + diff --git a/templates/email/brutalist.ninjatpl b/templates/email/brutalist.ninjatpl new file mode 100644 index 0000000..18fa1f6 --- /dev/null +++ b/templates/email/brutalist.ninjatpl @@ -0,0 +1,45 @@ + + + + + + + + {{ site_name }} + + + + {% if preview_text %}
{{ preview_text }}
{% endif %} + + + + +
+ + + + + + + + + + + +
+ + diff --git a/templates/overrides/brutalist/button.ninjatpl b/templates/overrides/brutalist/button.ninjatpl new file mode 100644 index 0000000..041af3d --- /dev/null +++ b/templates/overrides/brutalist/button.ninjatpl @@ -0,0 +1 @@ +{{ text }} diff --git a/templates/overrides/brutalist/heading.ninjatpl b/templates/overrides/brutalist/heading.ninjatpl new file mode 100644 index 0000000..4088b13 --- /dev/null +++ b/templates/overrides/brutalist/heading.ninjatpl @@ -0,0 +1 @@ +{% if level|integer == 1 %}

{{ text }}

{% elif level|integer == 3 %}

{{ text }}

{% elif level|integer == 4 %}

{{ text }}

{% elif level|integer == 5 %}
{{ text }}
{% elif level|integer == 6 %}
{{ text }}
{% else %}

{{ text }}

{% endif %} diff --git a/templates/overrides/brutalist/image.ninjatpl b/templates/overrides/brutalist/image.ninjatpl new file mode 100644 index 0000000..5e3b029 --- /dev/null +++ b/templates/overrides/brutalist/image.ninjatpl @@ -0,0 +1 @@ +
{% if src %}{{ alt }}{% elif url %}{{ alt }}{% endif %}{% if caption %}
{{ caption }}
{% endif %}
diff --git a/templates/overrides/brutalist/text.ninjatpl b/templates/overrides/brutalist/text.ninjatpl new file mode 100644 index 0000000..a5b0597 --- /dev/null +++ b/templates/overrides/brutalist/text.ninjatpl @@ -0,0 +1 @@ +
{{ text|safe }}
diff --git a/text_override.go b/text_override.go deleted file mode 100644 index 3c2d178..0000000 --- a/text_override.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// BrutalistTextBlock overrides the built-in text block with brutalist -// measure (wider, no max-w-prose), Inter body, and mono styling. -func BrutalistTextBlock(ctx context.Context, content map[string]any) string { - text := getString(content, "text") - class := getString(content, "class") - - var buf bytes.Buffer - _ = brutalistTextComponent(text, class).Render(ctx, &buf) - return buf.String() -} diff --git a/text_override.templ b/text_override.templ deleted file mode 100644 index fbeb731..0000000 --- a/text_override.templ +++ /dev/null @@ -1,10 +0,0 @@ -package main - -templ brutalistTextComponent(text, class string) { -
- @templ.Raw(text) -
-} diff --git a/text_override_templ.go b/text_override_templ.go deleted file mode 100644 index 9f53c84..0000000 --- a/text_override_templ.go +++ /dev/null @@ -1,66 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -func brutalistTextComponent(text, class string) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - var templ_7745c5c3_Var2 = []any{"brutalist-text", class} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(text).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate