From 5dfc1cd4bec16595e5df709a0acb39442baa4002 Mon Sep 17 00:00:00 2001 From: Alex Dunmow Date: Sat, 4 Jul 2026 15:27:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20convert=20to=20codeless=20.bnp=20?= =?UTF-8?q?=E2=80=94=20templates=20+=20manifest,=20Go/templ=20deleted=20(W?= =?UTF-8?q?O-WZ-021)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- Makefile | 40 +- affirmation.go | 46 -- affirmation.templ | 37 -- affirmation_templ.go | 118 ---- blocks/affirmation.ninjatpl | 10 + {schemas => blocks}/affirmation.schema.json | 0 blocks/blocks.yaml | 42 ++ blocks/cozy-footer.ninjatpl | 23 + {schemas => blocks}/cozy-footer.schema.json | 0 blocks/feature-grid-soft.ninjatpl | 18 + .../feature-grid-soft.schema.json | 0 blocks/soft-navbar.ninjatpl | 23 + {schemas => blocks}/soft-navbar.schema.json | 0 blocks/testimonial-soft.ninjatpl | 27 + .../testimonial-soft.schema.json | 0 blocks/watercolor-hero.ninjatpl | 35 ++ .../watercolor-hero.schema.json | 0 button_override.go | 28 - button_override.templ | 8 - button_override_templ.go | 80 --- card_override.go | 29 - card_override.templ | 20 - card_override_templ.go | 92 ---- cozy_footer.go | 40 -- cozy_footer.templ | 42 -- cozy_footer_templ.go | 94 ---- email_wrapper.templ | 187 ------- email_wrapper_templ.go | 450 ---------------- embed.go | 49 -- feature_grid_soft.go | 53 -- feature_grid_soft.templ | 40 -- feature_grid_soft_templ.go | 147 ----- go.mod | 20 - go.sum | 46 -- heading_override.go | 42 -- heading_override.templ | 42 -- heading_override_templ.go | 312 ----------- helpers.go | 82 --- main.go | 17 - manifest.yaml | 231 ++++++++ master_pages.json | 23 + plugin.mod | 5 +- register.go | 187 ------- registration.go | 38 -- soft_navbar.go | 40 -- soft_navbar.templ | 31 -- soft_navbar_templ.go | 117 ---- template.templ | 252 --------- template_templ.go | 510 ------------------ templates/email/pastel-dream.ninjatpl | 98 ++++ .../overrides/pastel-dream/button.ninjatpl | 3 + .../overrides/pastel-dream/card.ninjatpl | 9 + .../overrides/pastel-dream/heading.ninjatpl | 1 + .../overrides/pastel-dream/text.ninjatpl | 3 + templates/pastel-dream/article.ninjatpl | 21 + templates/pastel-dream/default.ninjatpl | 19 + templates/pastel-dream/full-width.ninjatpl | 19 + templates/pastel-dream/landing.ninjatpl | 22 + testimonial_soft.go | 50 -- testimonial_soft.templ | 65 --- testimonial_soft_templ.go | 202 ------- text_override.go | 17 - text_override.templ | 8 - text_override_templ.go | 67 --- watercolor_hero.go | 44 -- watercolor_hero.templ | 54 -- watercolor_hero_templ.go | 153 ------ 67 files changed, 646 insertions(+), 3982 deletions(-) delete mode 100644 affirmation.go delete mode 100644 affirmation.templ delete mode 100644 affirmation_templ.go create mode 100644 blocks/affirmation.ninjatpl rename {schemas => blocks}/affirmation.schema.json (100%) create mode 100644 blocks/blocks.yaml create mode 100644 blocks/cozy-footer.ninjatpl rename {schemas => blocks}/cozy-footer.schema.json (100%) create mode 100644 blocks/feature-grid-soft.ninjatpl rename {schemas => blocks}/feature-grid-soft.schema.json (100%) create mode 100644 blocks/soft-navbar.ninjatpl rename {schemas => blocks}/soft-navbar.schema.json (100%) create mode 100644 blocks/testimonial-soft.ninjatpl rename {schemas => blocks}/testimonial-soft.schema.json (100%) create mode 100644 blocks/watercolor-hero.ninjatpl rename {schemas => blocks}/watercolor-hero.schema.json (100%) delete mode 100644 button_override.go delete mode 100644 button_override.templ delete mode 100644 button_override_templ.go delete mode 100644 card_override.go delete mode 100644 card_override.templ delete mode 100644 card_override_templ.go delete mode 100644 cozy_footer.go delete mode 100644 cozy_footer.templ delete mode 100644 cozy_footer_templ.go delete mode 100644 email_wrapper.templ delete mode 100644 email_wrapper_templ.go delete mode 100644 embed.go delete mode 100644 feature_grid_soft.go delete mode 100644 feature_grid_soft.templ delete mode 100644 feature_grid_soft_templ.go delete mode 100644 go.mod delete mode 100644 go.sum delete mode 100644 heading_override.go delete mode 100644 heading_override.templ delete mode 100644 heading_override_templ.go delete mode 100644 helpers.go delete mode 100644 main.go create mode 100644 manifest.yaml create mode 100644 master_pages.json delete mode 100644 register.go delete mode 100644 registration.go delete mode 100644 soft_navbar.go delete mode 100644 soft_navbar.templ delete mode 100644 soft_navbar_templ.go delete mode 100644 template.templ delete mode 100644 template_templ.go create mode 100644 templates/email/pastel-dream.ninjatpl create mode 100644 templates/overrides/pastel-dream/button.ninjatpl create mode 100644 templates/overrides/pastel-dream/card.ninjatpl create mode 100644 templates/overrides/pastel-dream/heading.ninjatpl create mode 100644 templates/overrides/pastel-dream/text.ninjatpl create mode 100644 templates/pastel-dream/article.ninjatpl create mode 100644 templates/pastel-dream/default.ninjatpl create mode 100644 templates/pastel-dream/full-width.ninjatpl create mode 100644 templates/pastel-dream/landing.ninjatpl delete mode 100644 testimonial_soft.go delete mode 100644 testimonial_soft.templ delete mode 100644 testimonial_soft_templ.go delete mode 100644 text_override.go delete mode 100644 text_override.templ delete mode 100644 text_override_templ.go delete mode 100644 watercolor_hero.go delete mode 100644 watercolor_hero.templ delete mode 100644 watercolor_hero_templ.go diff --git a/Makefile b/Makefile index 2a1dc2f..2217f69 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,27 @@ -# pastel-dream — build & publish helpers (wasm .bnp workflow) +# pastel-dream — 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 pastel-dream-.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 pastel-dream-.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 := pastel-dream 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/affirmation.go b/affirmation.go deleted file mode 100644 index 6a43ec2..0000000 --- a/affirmation.go +++ /dev/null @@ -1,46 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// AffirmationMeta defines the affirmation strip block. -var AffirmationMeta = blocks.BlockMeta{ - Key: "affirmation", - Title: "Affirmation Strip", - Description: "Slow-shimmer band carrying a short calming line in display type.", - Source: "pastel-dream", - Category: blocks.CategoryTheme, -} - -// AffirmationBlock renders the affirmation strip. -// Content shape: {quote, author, palette} -func AffirmationBlock(ctx context.Context, content map[string]any) string { - palette := getStringOr(content, "palette", "blush") - switch palette { - case "blush", "mint", "butter", "sky": - // valid - default: - palette = "blush" - } - - data := AffirmationData{ - Quote: getStringOr(content, "quote", "You are doing enough."), - Author: getString(content, "author"), - Palette: palette, - } - - var buf bytes.Buffer - _ = affirmationComponent(data).Render(ctx, &buf) - return buf.String() -} - -// AffirmationData is the rendered view of the affirmation block. -type AffirmationData struct { - Quote string - Author string - Palette string -} diff --git a/affirmation.templ b/affirmation.templ deleted file mode 100644 index 4d6ecc6..0000000 --- a/affirmation.templ +++ /dev/null @@ -1,37 +0,0 @@ -package main - -// affirmationPaletteVar maps a palette name to a token reference. All four -// names resolve to a theme token so the strip never fails to colorize. -func affirmationPaletteVar(palette string) string { - switch palette { - case "mint": - return "hsl(var(--secondary) / 0.55)" - case "butter": - return "hsl(var(--accent) / 0.55)" - case "sky": - return "hsl(var(--secondary) / 0.40)" - default: - return "hsl(var(--primary) / 0.35)" - } -} - -// affirmationComponent renders the shimmering affirmation strip. -templ affirmationComponent(data AffirmationData) { -
-
-

- “{ data.Quote }” -

- if data.Author != "" { -

- { data.Author } -

- } -
-
-} diff --git a/affirmation_templ.go b/affirmation_templ.go deleted file mode 100644 index 1bb8deb..0000000 --- a/affirmation_templ.go +++ /dev/null @@ -1,118 +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" - -// affirmationPaletteVar maps a palette name to a token reference. All four -// names resolve to a theme token so the strip never fails to colorize. -func affirmationPaletteVar(palette string) string { - switch palette { - case "mint": - return "hsl(var(--secondary) / 0.55)" - case "butter": - return "hsl(var(--accent) / 0.55)" - case "sky": - return "hsl(var(--secondary) / 0.40)" - default: - return "hsl(var(--primary) / 0.35)" - } -} - -// affirmationComponent renders the shimmering affirmation strip. -func affirmationComponent(data AffirmationData) 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_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(data.Quote) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `affirmation.templ`, Line: 28, Col: 23} - } - _, 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, 4, "”

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

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(data.Author) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `affirmation.templ`, Line: 32, Col: 18} - } - _, 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, 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/blocks/affirmation.ninjatpl b/blocks/affirmation.ninjatpl new file mode 100644 index 0000000..356d8d1 --- /dev/null +++ b/blocks/affirmation.ninjatpl @@ -0,0 +1,10 @@ +
+
+

+ “{{ quote|default:"You are doing enough." }}” +

+ {% if author %}

+ {{ author }} +

{% endif %} +
+
diff --git a/schemas/affirmation.schema.json b/blocks/affirmation.schema.json similarity index 100% rename from schemas/affirmation.schema.json rename to blocks/affirmation.schema.json diff --git a/blocks/blocks.yaml b/blocks/blocks.yaml new file mode 100644 index 0000000..bd2d23c --- /dev/null +++ b/blocks/blocks.yaml @@ -0,0 +1,42 @@ +# Pastel Dream theme block definitions (codeless .bnp, WO-WZ-021). +# Keys are fully qualified (pastel-dream:) 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: pastel-dream:soft-navbar + title: Soft Navbar + description: Rounded pill navigation with a watercolor blob behind the logo. + category: navigation + schema: soft-navbar.schema.json + template: soft-navbar.ninjatpl + - key: pastel-dream:watercolor-hero + title: Watercolor Hero + description: Hero with two-tone watercolor blobs layered behind soft display type. + category: theme + schema: watercolor-hero.schema.json + template: watercolor-hero.ninjatpl + - key: pastel-dream:affirmation + title: Affirmation Strip + description: Slow-shimmer band carrying a short calming line in display type. + category: theme + schema: affirmation.schema.json + template: affirmation.ninjatpl + - key: pastel-dream:testimonial-soft + title: Soft Testimonial + description: Quote card with a deckle paper edge, avatar, and rating. + category: theme + schema: testimonial-soft.schema.json + template: testimonial-soft.ninjatpl + - key: pastel-dream:feature-grid-soft + title: Feature Trio + description: Three-up card grid for services, offerings, or core values. + category: layout + schema: feature-grid-soft.schema.json + template: feature-grid-soft.ninjatpl + - key: pastel-dream:cozy-footer + title: Cozy Footer + description: Newsletter signup, closing affirmation, menu column, and social pills. + category: navigation + schema: cozy-footer.schema.json + template: cozy-footer.ninjatpl diff --git a/blocks/cozy-footer.ninjatpl b/blocks/cozy-footer.ninjatpl new file mode 100644 index 0000000..8c8085f --- /dev/null +++ b/blocks/cozy-footer.ninjatpl @@ -0,0 +1,23 @@ +
+ +
+

+ {{ affirmation|default:"Be gentle with yourself today." }} +

+ {% if showSignup != "no" and showSignup != "false" and showSignup != "0" and showSignup != "off" and showSignup != false %}
+ + + +
{% endif %} + {% if social %}
+ {% for href in social %} + Visit + {% endfor %} +
{% endif %} +

+ Pastel Dream · with care +

+
+
diff --git a/schemas/cozy-footer.schema.json b/blocks/cozy-footer.schema.json similarity index 100% rename from schemas/cozy-footer.schema.json rename to blocks/cozy-footer.schema.json diff --git a/blocks/feature-grid-soft.ninjatpl b/blocks/feature-grid-soft.ninjatpl new file mode 100644 index 0000000..497e2aa --- /dev/null +++ b/blocks/feature-grid-soft.ninjatpl @@ -0,0 +1,18 @@ +
+
+ {% if intro %}
+ {{ intro|safe }} +
{% endif %} + {% if items %}
+ {% for item in items %}
+ {% if item.icon %}
+ +
{% else %}{% endif %} + {% if item.title %}

{{ item.title }}

{% endif %} + {% if item.body %}

{{ item.body }}

{% endif %} +
{% endfor %} +
{% else %}
+

Add up to three cards to the trio.

+
{% endif %} +
+
diff --git a/schemas/feature-grid-soft.schema.json b/blocks/feature-grid-soft.schema.json similarity index 100% rename from schemas/feature-grid-soft.schema.json rename to blocks/feature-grid-soft.schema.json diff --git a/blocks/soft-navbar.ninjatpl b/blocks/soft-navbar.ninjatpl new file mode 100644 index 0000000..bedb70f --- /dev/null +++ b/blocks/soft-navbar.ninjatpl @@ -0,0 +1,23 @@ + diff --git a/schemas/soft-navbar.schema.json b/blocks/soft-navbar.schema.json similarity index 100% rename from schemas/soft-navbar.schema.json rename to blocks/soft-navbar.schema.json diff --git a/blocks/testimonial-soft.ninjatpl b/blocks/testimonial-soft.ninjatpl new file mode 100644 index 0000000..caa6b99 --- /dev/null +++ b/blocks/testimonial-soft.ninjatpl @@ -0,0 +1,27 @@ +
+ {% if rating|integer > 0 %}
+ {% if rating|integer >= 1 %} + + {% endif %}{% if rating|integer >= 2 %} + + {% endif %}{% if rating|integer >= 3 %} + + {% endif %}{% if rating|integer >= 4 %} + + {% endif %}{% if rating|integer >= 5 %} + + {% endif %} +
{% endif %} +
+ {{ quote|safe }} +
+ {% if name or role %}
+ {% if avatar %}{{ name }}{% elif name %} + {% for w in name|split:" " %}{% if w and forloop.Counter <= 2 %}{{ w|first|upper }}{% endif %}{% endfor %} + {% endif %} +
+ {% if name %}

{{ name }}

{% endif %} + {% if role %}

{{ role }}

{% endif %} +
+
{% endif %} +
diff --git a/schemas/testimonial-soft.schema.json b/blocks/testimonial-soft.schema.json similarity index 100% rename from schemas/testimonial-soft.schema.json rename to blocks/testimonial-soft.schema.json diff --git a/blocks/watercolor-hero.ninjatpl b/blocks/watercolor-hero.ninjatpl new file mode 100644 index 0000000..03f900c --- /dev/null +++ b/blocks/watercolor-hero.ninjatpl @@ -0,0 +1,35 @@ +
+ + +
+
+ {% if eyebrow %}

+ {{ eyebrow }} +

{% endif %} +

+ {{ headline|default:"Soft starts"|safe }} +

+ {% if body %}
+ {{ body|safe }} +
{% endif %} + {% if ctaText %} + {{ ctaText }} + {% endif %} +
+ {% if image %}
+
+ +
+
{% else %}{% endif %} +
+
diff --git a/schemas/watercolor-hero.schema.json b/blocks/watercolor-hero.schema.json similarity index 100% rename from schemas/watercolor-hero.schema.json rename to blocks/watercolor-hero.schema.json diff --git a/button_override.go b/button_override.go deleted file mode 100644 index 2f91709..0000000 --- a/button_override.go +++ /dev/null @@ -1,28 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// PastelButtonBlock renders buttons as soft pills (9999px radius, tinted -// shadow, 2px hover lift, cubic-bezier(.22,1,.36,1) easing). -// Content shape: {text, href, variant} -func PastelButtonBlock(ctx context.Context, content map[string]any) string { - data := PastelButtonData{ - Text: getStringOr(content, "text", "Continue"), - Href: safeLink(getString(content, "href")), - Variant: getStringOr(content, "variant", "primary"), - } - - var buf bytes.Buffer - _ = pastelButtonComponent(data).Render(ctx, &buf) - return buf.String() -} - -// PastelButtonData drives the button override. -type PastelButtonData struct { - Text string - Href string - Variant string -} diff --git a/button_override.templ b/button_override.templ deleted file mode 100644 index f90009e..0000000 --- a/button_override.templ +++ /dev/null @@ -1,8 +0,0 @@ -package main - -// pastelButtonComponent renders the pill button override. -templ pastelButtonComponent(data PastelButtonData) { - - { data.Text } - -} diff --git a/button_override_templ.go b/button_override_templ.go deleted file mode 100644 index 5503f2c..0000000 --- a/button_override_templ.go +++ /dev/null @@ -1,80 +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" - -// pastelButtonComponent renders the pill button override. -func pastelButtonComponent(data PastelButtonData) 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_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(data.Text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `button_override.templ`, Line: 6, Col: 13} - } - _, 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, 4, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/card_override.go b/card_override.go deleted file mode 100644 index ab89c78..0000000 --- a/card_override.go +++ /dev/null @@ -1,29 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// PastelCardBlock renders cards with the soft 20px radius, blush-tinted -// shadow, and optional watercolor border. The body field accepts pre-rendered -// HTML so other blocks can be composed inside. -// Content shape: {title, body, footer} -func PastelCardBlock(ctx context.Context, content map[string]any) string { - data := PastelCardData{ - Title: getString(content, "title"), - Body: getString(content, "body"), - Footer: getString(content, "footer"), - } - - var buf bytes.Buffer - _ = pastelCardComponent(data).Render(ctx, &buf) - return buf.String() -} - -// PastelCardData drives the card override. -type PastelCardData struct { - Title string - Body string - Footer string -} diff --git a/card_override.templ b/card_override.templ deleted file mode 100644 index 2049079..0000000 --- a/card_override.templ +++ /dev/null @@ -1,20 +0,0 @@ -package main - -// pastelCardComponent renders the soft pastel card. -templ pastelCardComponent(data PastelCardData) { -
- if data.Title != "" { -

{ data.Title }

- } - if data.Body != "" { -
- @templ.Raw(data.Body) -
- } - if data.Footer != "" { -
- @templ.Raw(data.Footer) -
- } -
-} diff --git a/card_override_templ.go b/card_override_templ.go deleted file mode 100644 index 23b3c61..0000000 --- a/card_override_templ.go +++ /dev/null @@ -1,92 +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" - -// pastelCardComponent renders the soft pastel card. -func pastelCardComponent(data PastelCardData) 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.Title != "" { - 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.Title) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `card_override.templ`, Line: 7, Col: 98} - } - _, 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 - } - } - if data.Body != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Body).Render(ctx, templ_7745c5c3_Buffer) - 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.Footer != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.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 = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/cozy_footer.go b/cozy_footer.go deleted file mode 100644 index 24c0069..0000000 --- a/cozy_footer.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// CozyFooterMeta defines the footer block. -var CozyFooterMeta = blocks.BlockMeta{ - Key: "cozy-footer", - Title: "Cozy Footer", - Description: "Newsletter signup, closing affirmation, menu column, and social pills.", - Source: "pastel-dream", - Category: blocks.CategoryNavigation, -} - -// CozyFooterBlock renders the footer. -// Content shape: {showSignup, affirmation, menuName, social[]} -func CozyFooterBlock(ctx context.Context, content map[string]any) string { - data := CozyFooterData{ - ShowSignup: getBoolish(content, "showSignup", true), - Affirmation: getStringOr(content, "affirmation", "Be gentle with yourself today."), - MenuName: getString(content, "menuName"), - Social: getStringSlice(content, "social"), - } - - var buf bytes.Buffer - _ = cozyFooterComponent(data).Render(ctx, &buf) - return buf.String() -} - -// CozyFooterData is the rendered view of the cozy-footer block. -type CozyFooterData struct { - ShowSignup bool - Affirmation string - MenuName string - Social []string -} diff --git a/cozy_footer.templ b/cozy_footer.templ deleted file mode 100644 index 5d4a2ab..0000000 --- a/cozy_footer.templ +++ /dev/null @@ -1,42 +0,0 @@ -package main - -// cozyFooterComponent renders the cozy footer with newsletter signup, -// a closing affirmation, an optional menu column, and social pill links. -templ cozyFooterComponent(data CozyFooterData) { -
- // Decorative watercolor blob, top right - -
-

- { data.Affirmation } -

- if data.ShowSignup { -
- - - -
- } - if len(data.Social) > 0 { -
- for _, href := range data.Social { - - Visit - - } -
- } -

- Pastel Dream · with care -

-
-
-} diff --git a/cozy_footer_templ.go b/cozy_footer_templ.go deleted file mode 100644 index 3d5634d..0000000 --- a/cozy_footer_templ.go +++ /dev/null @@ -1,94 +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" - -// cozyFooterComponent renders the cozy footer with newsletter signup, -// a closing affirmation, an optional menu column, and social pill links. -func cozyFooterComponent(data CozyFooterData) 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.Affirmation) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `cozy_footer.templ`, Line: 13, Col: 22} - } - _, 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 data.ShowSignup { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if len(data.Social) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, href := range data.Social { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "Visit") - 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, "

Pastel Dream · with care

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/email_wrapper.templ b/email_wrapper.templ deleted file mode 100644 index ca8274b..0000000 --- a/email_wrapper.templ +++ /dev/null @@ -1,187 +0,0 @@ -package main - -import ( - "bytes" - "context" - "fmt" - - "git.dev.alexdunmow.com/block/core/templates" -) - -// PastelEmailWrapper wraps body content in the Pastel Dream branded email -// frame: cream paper background, watercolor blob watermark, 560px centered -// frame, Caveat Brush masthead, Nunito body, mint CTA pill, unsubscribe and a -// closing affirmation in the footer. -func PastelEmailWrapper(body string, emailCtx templates.EmailContext) string { - var buf bytes.Buffer - _ = pastelEmailTemplate(emailCtx, body).Render(context.Background(), &buf) - return buf.String() -} - -// emailColorOr falls back to the supplied default when the EmailContext has -// not been populated with the preset color (e.g. for raw previews). -// All defaults pull from the blush-morning palette, expressed as hex because -// email clients cannot resolve CSS custom properties. -func emailColorOr(value, fallback string) string { - if value == "" { - return fallback - } - return value -} - -func pastelEmailBg(c templates.EmailColors) string { - // blush-morning background: hsl(25 60% 98%) ≈ #fdf7f1 - return emailColorOr(c.Background, "#fdf7f1") -} - -func pastelEmailCard(c templates.EmailColors) string { - return emailColorOr(c.Card, "#ffffff") -} - -func pastelEmailForeground(c templates.EmailColors) string { - // hsl(340 20% 22%) ≈ #432e36 - return emailColorOr(c.Foreground, "#432e36") -} - -func pastelEmailMutedFg(c templates.EmailColors) string { - // hsl(340 12% 48%) ≈ #80707a - return emailColorOr(c.MutedForeground, "#80707a") -} - -func pastelEmailPrimary(c templates.EmailColors) string { - // hsl(350 65% 72%) ≈ #e9a1ad - return emailColorOr(c.Primary, "#e9a1ad") -} - -func pastelEmailPrimaryFg(c templates.EmailColors) string { - return emailColorOr(c.PrimaryForeground, "#432e36") -} - -func pastelEmailBorder(c templates.EmailColors) string { - return emailColorOr(c.Border, "#f0d8de") -} - -// pastelEmailTemplate is the Pastel Dream email body template. -templ pastelEmailTemplate(emailCtx templates.EmailContext, body string) { - - - - - - - - { emailCtx.SiteSettings.SiteName } - - - - if emailCtx.PreviewText != "" { -
- { emailCtx.PreviewText } -
- } - - - - -
- -
- -
- - - - - - - - - - - - - - -
- - -} - -// pastelEmailPillStyle returns the inline CSS for the mint-tinted CTA pill -// that templates may use inside the body slot. The wrapper exposes it as a -// reusable token because the body is opaque pre-rendered HTML. -func pastelEmailPillStyle(c templates.EmailColors) string { - primary := pastelEmailPrimary(c) - primaryFg := pastelEmailPrimaryFg(c) - return fmt.Sprintf( - "display: inline-block; padding: 12px 28px; border-radius: 9999px; background-color: %s; color: %s; font-family: 'Nunito', Helvetica, Arial, sans-serif; font-weight: 600; text-decoration: none;", - primary, - primaryFg, - ) -} diff --git a/email_wrapper_templ.go b/email_wrapper_templ.go deleted file mode 100644 index d73a1da..0000000 --- a/email_wrapper_templ.go +++ /dev/null @@ -1,450 +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 ( - "bytes" - "context" - "fmt" - - "git.dev.alexdunmow.com/block/core/templates" -) - -// PastelEmailWrapper wraps body content in the Pastel Dream branded email -// frame: cream paper background, watercolor blob watermark, 560px centered -// frame, Caveat Brush masthead, Nunito body, mint CTA pill, unsubscribe and a -// closing affirmation in the footer. -func PastelEmailWrapper(body string, emailCtx templates.EmailContext) string { - var buf bytes.Buffer - _ = pastelEmailTemplate(emailCtx, body).Render(context.Background(), &buf) - return buf.String() -} - -// emailColorOr falls back to the supplied default when the EmailContext has -// not been populated with the preset color (e.g. for raw previews). -// All defaults pull from the blush-morning palette, expressed as hex because -// email clients cannot resolve CSS custom properties. -func emailColorOr(value, fallback string) string { - if value == "" { - return fallback - } - return value -} - -func pastelEmailBg(c templates.EmailColors) string { - // blush-morning background: hsl(25 60% 98%) ≈ #fdf7f1 - return emailColorOr(c.Background, "#fdf7f1") -} - -func pastelEmailCard(c templates.EmailColors) string { - return emailColorOr(c.Card, "#ffffff") -} - -func pastelEmailForeground(c templates.EmailColors) string { - // hsl(340 20% 22%) ≈ #432e36 - return emailColorOr(c.Foreground, "#432e36") -} - -func pastelEmailMutedFg(c templates.EmailColors) string { - // hsl(340 12% 48%) ≈ #80707a - return emailColorOr(c.MutedForeground, "#80707a") -} - -func pastelEmailPrimary(c templates.EmailColors) string { - // hsl(350 65% 72%) ≈ #e9a1ad - return emailColorOr(c.Primary, "#e9a1ad") -} - -func pastelEmailPrimaryFg(c templates.EmailColors) string { - return emailColorOr(c.PrimaryForeground, "#432e36") -} - -func pastelEmailBorder(c templates.EmailColors) string { - return emailColorOr(c.Border, "#f0d8de") -} - -// pastelEmailTemplate is the Pastel Dream email body template. -func pastelEmailTemplate(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: 73, Col: 41} - } - _, 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: 115, Col: 26} - } - _, 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 - }) -} - -// pastelEmailPillStyle returns the inline CSS for the mint-tinted CTA pill -// that templates may use inside the body slot. The wrapper exposes it as a -// reusable token because the body is opaque pre-rendered HTML. -func pastelEmailPillStyle(c templates.EmailColors) string { - primary := pastelEmailPrimary(c) - primaryFg := pastelEmailPrimaryFg(c) - return fmt.Sprintf( - "display: inline-block; padding: 12px 28px; border-radius: 9999px; background-color: %s; color: %s; font-family: 'Nunito', Helvetica, Arial, sans-serif; font-weight: 600; text-decoration: none;", - primary, - primaryFg, - ) -} - -var _ = templruntime.GeneratedTemplate diff --git a/embed.go b/embed.go deleted file mode 100644 index 101c4b3..0000000 --- a/embed.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "embed" - "io/fs" - "net/http" -) - -//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 returns an http.Handler that serves the embedded assets. -func AssetsHandler() http.Handler { - return http.FileServer(http.FS(Assets())) -} - -// ThemePresets returns the embedded theme presets JSON. -func ThemePresets() []byte { - return presetsData -} - -// BundledFonts returns the embedded fonts manifest JSON. -func BundledFonts() []byte { - return fontsData -} diff --git a/feature_grid_soft.go b/feature_grid_soft.go deleted file mode 100644 index 6ff0625..0000000 --- a/feature_grid_soft.go +++ /dev/null @@ -1,53 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// FeatureGridSoftMeta defines the three-up soft feature grid. -var FeatureGridSoftMeta = blocks.BlockMeta{ - Key: "feature-grid-soft", - Title: "Feature Trio", - Description: "Three-up card grid for services, offerings, or core values.", - Source: "pastel-dream", - Category: blocks.CategoryLayout, -} - -// FeatureGridSoftBlock renders the feature grid. -// Content shape: {intro, items: [{icon, title, body}]} -func FeatureGridSoftBlock(ctx context.Context, content map[string]any) string { - rawItems := getSlice(content, "items") - items := make([]FeatureSoftItem, 0, len(rawItems)) - for _, it := range rawItems { - items = append(items, FeatureSoftItem{ - Icon: getString(it, "icon"), - Title: getString(it, "title"), - Body: getString(it, "body"), - }) - } - - data := FeatureGridSoftData{ - Intro: getString(content, "intro"), - Items: items, - } - - var buf bytes.Buffer - _ = featureGridSoftComponent(data).Render(ctx, &buf) - return buf.String() -} - -// FeatureGridSoftData is the rendered view of the feature-grid-soft block. -type FeatureGridSoftData struct { - Intro string - Items []FeatureSoftItem -} - -// FeatureSoftItem is a single card in the trio. -type FeatureSoftItem struct { - Icon string - Title string - Body string -} diff --git a/feature_grid_soft.templ b/feature_grid_soft.templ deleted file mode 100644 index bb93626..0000000 --- a/feature_grid_soft.templ +++ /dev/null @@ -1,40 +0,0 @@ -package main - -// featureGridSoftComponent renders the three-up grid. It reflows to 1 column -// at 360px and 2-3 columns at 768px+, satisfying UAT §7. -templ featureGridSoftComponent(data FeatureGridSoftData) { -
-
- if data.Intro != "" { -
- @templ.Raw(data.Intro) -
- } - if len(data.Items) > 0 { -
- for _, item := range data.Items { -
- if item.Icon != "" { -
- -
- } else { - - } - if item.Title != "" { -

{ item.Title }

- } - if item.Body != "" { -

{ item.Body }

- } -
- } -
- } else { -
-

Add up to three cards to the trio.

-
- } -
-
-} diff --git a/feature_grid_soft_templ.go b/feature_grid_soft_templ.go deleted file mode 100644 index 5e18d1d..0000000 --- a/feature_grid_soft_templ.go +++ /dev/null @@ -1,147 +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" - -// featureGridSoftComponent renders the three-up grid. It reflows to 1 column -// at 360px and 2-3 columns at 768px+, satisfying UAT §7. -func featureGridSoftComponent(data FeatureGridSoftData) 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.Intro != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Intro).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 - } - } - if len(data.Items) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, item := range data.Items { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if item.Icon != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
\"\"
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if item.Title != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(item.Title) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `feature_grid_soft.templ`, Line: 25, Col: 98} - } - _, 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, 10, "

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

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(item.Body) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `feature_grid_soft.templ`, Line: 28, Col: 115} - } - _, 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, 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 = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

Add up to three cards to the trio.

") - 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/go.mod b/go.mod deleted file mode 100644 index 44f4274..0000000 --- a/go.mod +++ /dev/null @@ -1,20 +0,0 @@ -module git.dev.alexdunmow.com/block/themes/pastel-dream - -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 21e9fea..0000000 --- a/heading_override.go +++ /dev/null @@ -1,42 +0,0 @@ -package main - -import ( - "bytes" - "context" - "strconv" -) - -// PastelHeadingBlock renders headings with pastel-dream styling. -// Caveat Brush display at H1/H2; Nunito for H3+; soft brush-stroke underline. -// Content shape: {text, level: 1-6, textClass} -func PastelHeadingBlock(ctx context.Context, content map[string]any) string { - text := getString(content, "text") - textClass := getString(content, "textClass") - level := parseHeadingLevel(content) - - var buf bytes.Buffer - _ = pastelHeadingComponent(level, text, textClass).Render(ctx, &buf) - return buf.String() -} - -// parseHeadingLevel reads level from various JSON-compatible types and clamps -// the result to 1..6, defaulting to 2. -func parseHeadingLevel(content map[string]any) int { - if level, ok := content["level"].(float64); ok { - l := int(level) - if l >= 1 && l <= 6 { - return l - } - } - if level, ok := content["level"].(int); ok { - if level >= 1 && level <= 6 { - return level - } - } - if level, ok := content["level"].(string); ok { - if l, err := strconv.Atoi(level); err == nil && l >= 1 && l <= 6 { - return l - } - } - return 2 -} diff --git a/heading_override.templ b/heading_override.templ deleted file mode 100644 index de42584..0000000 --- a/heading_override.templ +++ /dev/null @@ -1,42 +0,0 @@ -package main - -// pastelHeadingBaseClass returns the Tailwind size/weight class for a level. -// H1 and H2 get the display face; H3+ uses the body face. -func pastelHeadingBaseClass(level int) string { - switch level { - case 1: - return "font-display text-5xl md:text-6xl leading-tight brush-underline" - case 2: - return "font-display text-4xl md:text-5xl leading-tight brush-underline" - case 3: - return "font-body text-3xl font-semibold tracking-tight" - case 4: - return "font-body text-2xl font-semibold" - case 5: - return "font-body text-xl font-medium" - case 6: - return "font-body text-lg font-medium" - default: - return "font-body text-3xl font-semibold tracking-tight" - } -} - -// pastelHeadingComponent renders a heading with pastel-dream styling. -templ pastelHeadingComponent(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 a4842fc..0000000 --- a/heading_override_templ.go +++ /dev/null @@ -1,312 +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" - -// pastelHeadingBaseClass returns the Tailwind size/weight class for a level. -// H1 and H2 get the display face; H3+ uses the body face. -func pastelHeadingBaseClass(level int) string { - switch level { - case 1: - return "font-display text-5xl md:text-6xl leading-tight brush-underline" - case 2: - return "font-display text-4xl md:text-5xl leading-tight brush-underline" - case 3: - return "font-body text-3xl font-semibold tracking-tight" - case 4: - return "font-body text-2xl font-semibold" - case 5: - return "font-body text-xl font-medium" - case 6: - return "font-body text-lg font-medium" - default: - return "font-body text-3xl font-semibold tracking-tight" - } -} - -// pastelHeadingComponent renders a heading with pastel-dream styling. -func pastelHeadingComponent(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{pastelHeadingBaseClass(1), 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_Var4 string - templ_7745c5c3_Var4, 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: 99} - } - _, 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, 3, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 2: - var templ_7745c5c3_Var5 = []any{pastelHeadingBaseClass(2), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, 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 - } - var templ_7745c5c3_Var7 string - templ_7745c5c3_Var7, 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: 99} - } - _, 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, 6, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 3: - var templ_7745c5c3_Var8 = []any{pastelHeadingBaseClass(3), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...) - 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 - } - var templ_7745c5c3_Var10 string - templ_7745c5c3_Var10, 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: 99} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(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 - } - case 4: - var templ_7745c5c3_Var11 = []any{pastelHeadingBaseClass(4), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var11...) - 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_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: 34, Col: 99} - } - _, 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 5: - var templ_7745c5c3_Var14 = []any{pastelHeadingBaseClass(5), 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_Var16 string - templ_7745c5c3_Var16, 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: 99} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) - 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 - } - case 6: - var templ_7745c5c3_Var17 = []any{pastelHeadingBaseClass(6), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, 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 - } - var templ_7745c5c3_Var19 string - templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 38, Col: 99} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) - 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 - } - default: - var templ_7745c5c3_Var20 = []any{pastelHeadingBaseClass(2), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var20...) - 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 - } - var templ_7745c5c3_Var22 string - templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 40, Col: 99} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(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 - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/helpers.go b/helpers.go deleted file mode 100644 index 7496164..0000000 --- a/helpers.go +++ /dev/null @@ -1,82 +0,0 @@ -package main - -// getString extracts a string value from a content map. -// Returns "" when the key is missing or holds a non-string value. -func getString(content map[string]any, key string) string { - if v, ok := content[key].(string); ok { - return v - } - return "" -} - -// getStringOr extracts a string with a fallback for empty/missing values. -func getStringOr(content map[string]any, key, fallback string) string { - if v := getString(content, key); v != "" { - return v - } - return fallback -} - -// getFloat extracts a float from content. -func getFloat(content map[string]any, key string, defaultVal float64) float64 { - if v, ok := content[key].(float64); ok { - return v - } - if v, ok := content[key].(int); ok { - return float64(v) - } - return defaultVal -} - -// getBoolish reads "yes"/"no" select fields or actual booleans into a bool. -func getBoolish(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 v { - case "yes", "true", "1", "on": - return true - case "no", "false", "0", "off": - return false - } - } - return defaultVal -} - -// getSlice extracts a slice of maps from a content map (collections/arrays -// of objects). -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 -} - -// getStringSlice extracts a slice of strings (e.g. social URLs). -func getStringSlice(content map[string]any, key string) []string { - if v, ok := content[key].([]any); ok { - result := make([]string, 0, len(v)) - for _, item := range v { - if s, ok := item.(string); ok && s != "" { - result = append(result, s) - } - } - return result - } - return nil -} - -// safeLink returns href if non-empty, otherwise "#". -func safeLink(href string) string { - if href == "" { - return "#" - } - return href -} diff --git a/main.go b/main.go deleted file mode 100644 index 6a1d0d8..0000000 --- a/main.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build wasip1 - -// Package main compiles the pastel-dream 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..c976349 --- /dev/null +++ b/manifest.yaml @@ -0,0 +1,231 @@ +# Pastel Dream 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: pastel-dream + title: Pastel Dream + description: "Soft watercolor theme with blush, mint, and butter palettes for wellness, parenting, and spa brands." + +page_templates: + - system: pastel-dream + key: default + title: Default + description: "Soft layered hero, masthead nav, footer with newsletter." + slots: [header, main, footer] + - system: pastel-dream + key: landing + title: Soft Landing + description: "Watercolor hero, affirmation strip, CTA, footer." + slots: [hero, main, cta, footer] + - system: pastel-dream + key: article + title: Reading Room + description: "Narrow, centered editorial column with side rail." + slots: [header, main, footer] + - system: pastel-dream + key: full-width + title: Open Air + description: "Edge-to-edge sections for galleries and seasonal looks." + slots: [header, main, footer] + +template_overrides: + - { template: pastel-dream, block: heading } + - { template: pastel-dream, block: text } + - { template: pastel-dream, block: button } + - { template: pastel-dream, block: card } + +email_wrappers: + - pastel-dream + +css: + input_css_append: | + /* Pastel Dream — theme-specific CSS appended to host Tailwind input. + * + * Rules: + * - All colors must consume tokens via hsl(var(--token)). No hardcoded hex/rgb/named colors. + * - All font-family declarations must consume var(--font-*) with a graceful fallback stack. + * - Animations must be guarded by prefers-reduced-motion: reduce. + */ + + :root { + --radius-soft: 20px; + } + + /* --- Watercolor utility classes ---------------------------------------- */ + /* Soft radial wash backgrounds, tinted from the active palette via primary + * and accent tokens. Used as decorative layers behind hero and footer. + */ + .bg-watercolor-blush { + background-image: + radial-gradient(60% 70% at 20% 30%, hsl(var(--primary) / 0.18) 0%, transparent 65%), + radial-gradient(50% 60% at 80% 70%, hsl(var(--accent) / 0.15) 0%, transparent 60%); + } + + .bg-watercolor-mint { + background-image: + radial-gradient(60% 70% at 25% 35%, hsl(var(--secondary) / 0.45) 0%, transparent 65%), + radial-gradient(55% 65% at 75% 65%, hsl(var(--primary) / 0.12) 0%, transparent 60%); + } + + /* --- Soft shadow utilities -------------------------------------------- */ + /* Shadows are large, low-alpha, and tinted toward primary rather than grey. */ + .shadow-soft { + box-shadow: 0 12px 40px -8px hsl(var(--primary) / 0.18), + 0 4px 12px -2px hsl(var(--primary) / 0.10); + } + + .shadow-soft-hover { + box-shadow: 0 16px 48px -8px hsl(var(--primary) / 0.24), + 0 6px 16px -2px hsl(var(--primary) / 0.14); + } + + /* --- Deckle edge ------------------------------------------------------- */ + /* Hand-torn paper effect for testimonial cards. Uses mask-image so it + * renders against whatever background lies beneath. + */ + .deckle-edge { + -webkit-mask-image: + radial-gradient(circle at 6px 6px, transparent 4px, hsl(var(--card)) 4.5px), + linear-gradient(to bottom, hsl(var(--card)) 0%, hsl(var(--card)) 100%); + mask-image: + radial-gradient(circle at 6px 6px, transparent 4px, hsl(var(--card)) 4.5px), + linear-gradient(to bottom, hsl(var(--card)) 0%, hsl(var(--card)) 100%); + -webkit-mask-composite: source-over; + mask-composite: add; + border: 1px dashed hsl(var(--border)); + } + + /* --- Pill button override --------------------------------------------- */ + /* Spec §"Block overrides": every button is pill (9999px), tinted shadow, + * 2px hover lift, easing cubic-bezier(.22,1,.36,1). + */ + .pastel-pill { + border-radius: 9999px; + padding: 0.75rem 1.75rem; + font-family: var(--font-body, "Nunito", "Quicksand", system-ui, sans-serif); + font-weight: 600; + background-color: hsl(var(--primary)); + color: hsl(var(--primary-foreground)); + box-shadow: 0 8px 24px -6px hsl(var(--primary) / 0.40); + transition: transform 240ms cubic-bezier(.22,1,.36,1), + box-shadow 240ms cubic-bezier(.22,1,.36,1), + background-color 240ms cubic-bezier(.22,1,.36,1); + border: none; + cursor: pointer; + display: inline-block; + } + + .pastel-pill:hover { + transform: translateY(-2px); + box-shadow: 0 12px 32px -6px hsl(var(--primary) / 0.50); + background-color: hsl(var(--primary) / 0.92); + } + + .pastel-pill:focus-visible { + outline: 2px solid hsl(var(--ring)); + outline-offset: 2px; + } + + /* --- Soft card -------------------------------------------------------- */ + .pastel-card { + border-radius: var(--radius-soft); + background-color: hsl(var(--card)); + color: hsl(var(--card-foreground)); + border: 1px solid hsl(var(--border)); + box-shadow: 0 12px 40px -8px hsl(var(--primary) / 0.18), + 0 4px 12px -2px hsl(var(--primary) / 0.10); + } + + /* --- Brush-stroke underline for headings ------------------------------ */ + .brush-underline { + position: relative; + display: inline-block; + } + + .brush-underline::after { + content: ""; + position: absolute; + left: 0; + right: 0; + bottom: -0.2em; + height: 0.22em; + background-color: hsl(var(--accent) / 0.55); + border-radius: 9999px; + z-index: -1; + } + + /* --- Typography fallbacks --------------------------------------------- */ + /* Spec §"Visual language" pairs Caveat Brush + Nunito; admin can override + * via the font picker. Fallback stacks degrade gracefully. + */ + .font-display { + font-family: var(--font-heading, "Caveat Brush", "Sacramento", "Brush Script MT", cursive); + letter-spacing: 0.01em; + } + + .font-body { + font-family: var(--font-body, "Nunito", "Quicksand", "Helvetica Neue", system-ui, sans-serif); + line-height: 1.75; + } + + .font-mono { + font-family: var(--font-mono, "JetBrains Mono", "Fira Code", ui-monospace, monospace); + } + + /* --- Animations ------------------------------------------------------- */ + /* @keyframes pastel-shimmer — drift the accent overlay slowly across the + * affirmation strip. Spec §13.10: animation-duration >= 6s. + */ + @keyframes pastel-shimmer { + 0% { + background-position: 0% 50%; + opacity: 0.85; + } + 50% { + background-position: 100% 50%; + opacity: 1; + } + 100% { + background-position: 0% 50%; + opacity: 0.85; + } + } + + /* @keyframes breathe — gentle scale pulse, used by hero CTA and watercolor + * blobs for an in-and-out breath rhythm. + */ + @keyframes breathe { + 0%, 100% { + transform: scale(1); + opacity: 0.85; + } + 50% { + transform: scale(1.04); + opacity: 1; + } + } + + .animate-pastel-shimmer { + background-size: 200% 200%; + animation: pastel-shimmer 8s ease-in-out infinite; + } + + .animate-breathe { + animation: breathe 6s ease-in-out infinite; + } + + /* --- Accessibility: respect prefers-reduced-motion -------------------- */ + @media (prefers-reduced-motion: reduce) { + .animate-pastel-shimmer, + .animate-breathe, + .pastel-pill { + animation: none !important; + transition: none !important; + } + .pastel-pill:hover { + transform: none; + } + } diff --git a/master_pages.json b/master_pages.json new file mode 100644 index 0000000..2ee973e --- /dev/null +++ b/master_pages.json @@ -0,0 +1,23 @@ +[ + { + "key": "pastel-dream:default-master", + "title": "Pastel Dream Default Master", + "page_templates": ["default", "article"], + "blocks": [ + { "block_key": "pastel-dream:soft-navbar", "title": "Soft Nav", "content": { "menuName": "main", "logo": "Pastel Dream" }, "slot": "header", "sort_order": 0 }, + { "block_key": "slot", "title": "Main Slot", "content": { "slotName": "main", "placeholder": "Page content" }, "slot": "main", "sort_order": 0 }, + { "block_key": "pastel-dream:cozy-footer", "title": "Cozy Footer", "content": { "showSignup": "yes", "affirmation": "Be gentle with yourself today." }, "slot": "footer", "sort_order": 0 } + ] + }, + { + "key": "pastel-dream:landing-master", + "title": "Pastel Dream Landing Master", + "page_templates": ["landing"], + "blocks": [ + { "block_key": "pastel-dream:watercolor-hero", "title": "Watercolor Hero", "content": { "eyebrow": "new", "headline": "Soft starts", "body": "A gentle place to begin.", "ctaText": "Begin" }, "slot": "hero", "sort_order": 0 }, + { "block_key": "slot", "title": "Main Slot", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, + { "block_key": "pastel-dream:affirmation", "title": "Affirmation Strip", "content": { "quote": "You are doing enough.", "author": "Pastel Dream" }, "slot": "cta", "sort_order": 0 }, + { "block_key": "pastel-dream:cozy-footer", "title": "Cozy Footer", "content": { "showSignup": "yes" }, "slot": "footer", "sort_order": 0 } + ] + } +] diff --git a/plugin.mod b/plugin.mod index c7becd6..b54e49b 100644 --- a/plugin.mod +++ b/plugin.mod @@ -2,11 +2,8 @@ name = "pastel-dream" display_name = "Pastel Dream" scope = "@themes" -version = "0.1.2" +version = "0.2.0" description = "Soft watercolor theme with blush, mint, and butter palettes for wellness, parenting, and spa brands." kind = "theme" categories = ["templates"] tags = ["pastel", "soft", "wellness", "parenting", "spa", "doula", "calm", "skincare", "mindfulness"] - -[compatibility] -block_core = ">=0.15.0 <0.16.0" diff --git a/register.go b/register.go deleted file mode 100644 index 9c69fb9..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 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 is the plugin entry point. It registers the system template, page -// templates, theme-owned blocks, built-in overrides, and the email wrapper. -// -// Order of operations matters: br.LoadSchemasFromFS MUST run before any -// br.Register call so schema binding sees the blocks as they register. -func Register(tr templates.TemplateRegistry, br blocks.BlockRegistry) error { - // System template registration. - tr.RegisterSystemTemplate(templates.SystemTemplateMeta{ - Key: "pastel-dream", - Title: "Pastel Dream", - Description: "Soft watercolor theme with blush, mint, and butter palettes for wellness, parenting, and spa brands.", - }) - - // Page templates per spec §"Page templates". - if err := tr.RegisterPageTemplate("pastel-dream", templates.PageTemplateMeta{ - Key: "default", - Title: "Default", - Description: "Soft layered hero, masthead nav, footer with newsletter.", - Slots: []string{"header", "main", "footer"}, - }, wrap(RenderPastelDefault)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("pastel-dream", templates.PageTemplateMeta{ - Key: "landing", - Title: "Soft Landing", - Description: "Watercolor hero, affirmation strip, CTA, footer.", - Slots: []string{"hero", "main", "cta", "footer"}, - }, wrap(RenderPastelLanding)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("pastel-dream", templates.PageTemplateMeta{ - Key: "article", - Title: "Reading Room", - Description: "Narrow, centered editorial column with side rail.", - Slots: []string{"header", "main", "footer"}, - }, wrap(RenderPastelArticle)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("pastel-dream", templates.PageTemplateMeta{ - Key: "full-width", - Title: "Open Air", - Description: "Edge-to-edge sections for galleries and seasonal looks.", - Slots: []string{"header", "main", "footer"}, - }, wrap(RenderPastelFullWidth)); err != nil { - return err - } - - // Schemas MUST load before blocks register so editor metadata binds. - if err := br.LoadSchemasFromFS(Schemas()); err != nil { - return err - } - - // Theme-owned blocks. - br.Register(SoftNavbarMeta, SoftNavbarBlock) - br.Register(WatercolorHeroMeta, WatercolorHeroBlock) - br.Register(AffirmationMeta, AffirmationBlock) - br.Register(TestimonialSoftMeta, TestimonialSoftBlock) - br.Register(FeatureGridSoftMeta, FeatureGridSoftBlock) - br.Register(CozyFooterMeta, CozyFooterBlock) - - // Overrides for built-ins, only when this theme is active. - br.RegisterTemplateOverride("pastel-dream", "heading", PastelHeadingBlock) - br.RegisterTemplateOverride("pastel-dream", "text", PastelTextBlock) - br.RegisterTemplateOverride("pastel-dream", "button", PastelButtonBlock) - br.RegisterTemplateOverride("pastel-dream", "card", PastelCardBlock) - - // Email wrapper. - tr.RegisterEmailWrapper("pastel-dream", PastelEmailWrapper) - - return nil -} - -// DefaultMasterPages returns the master pages seeded on first plugin load. -// Two definitions per spec §"Master pages": -// - pastel-dream:default-master — used by default and article page templates -// - pastel-dream:landing-master — used by the landing page template -func DefaultMasterPages() []plugin.MasterPageDefinition { - return []plugin.MasterPageDefinition{ - { - Key: "pastel-dream:default-master", - Title: "Pastel Dream Default Master", - PageTemplates: []string{"default", "article"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "pastel-dream:soft-navbar", - Title: "Soft Nav", - Content: map[string]any{ - "menuName": "main", - "logo": "Pastel Dream", - }, - Slot: "header", - SortOrder: 0, - }, - { - BlockKey: "slot", - Title: "Main Slot", - Content: map[string]any{ - "slotName": "main", - "placeholder": "Page content", - }, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "pastel-dream:cozy-footer", - Title: "Cozy Footer", - Content: map[string]any{ - "showSignup": "yes", - "affirmation": "Be gentle with yourself today.", - }, - Slot: "footer", - SortOrder: 0, - }, - }, - }, - { - Key: "pastel-dream:landing-master", - Title: "Pastel Dream Landing Master", - PageTemplates: []string{"landing"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "pastel-dream:watercolor-hero", - Title: "Watercolor Hero", - Content: map[string]any{ - "eyebrow": "new", - "headline": "Soft starts", - "body": "A gentle place to begin.", - "ctaText": "Begin", - }, - Slot: "hero", - SortOrder: 0, - }, - { - BlockKey: "slot", - Title: "Main Slot", - Content: map[string]any{ - "slotName": "main", - }, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "pastel-dream:affirmation", - Title: "Affirmation Strip", - Content: map[string]any{ - "quote": "You are doing enough.", - "author": "Pastel Dream", - }, - Slot: "cta", - SortOrder: 0, - }, - { - BlockKey: "pastel-dream:cozy-footer", - Title: "Cozy Footer", - Content: map[string]any{ - "showSignup": "yes", - }, - Slot: "footer", - SortOrder: 0, - }, - }, - }, - } -} diff --git a/registration.go b/registration.go deleted file mode 100644 index 502b30e..0000000 --- a/registration.go +++ /dev/null @@ -1,38 +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 Pastel Dream theme. -var Registration = plugin.PluginRegistration{ - Name: "pastel-dream", - 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() }, -} - -// ThemeCSSManifest returns the Pastel Dream CSS to be appended to the host Tailwind input. -// This includes keyframes (pastel-shimmer, breathe), the --radius-soft variable, -// watercolor utility classes, font-family fallback stacks, and reduced-motion guards. -func ThemeCSSManifest() *plugin.CSSManifest { - css, err := assetsFS.ReadFile("assets/css/pastel-dream.css") - if err != nil { - return &plugin.CSSManifest{} - } - return &plugin.CSSManifest{ - InputCSSAppend: string(css), - } -} diff --git a/soft_navbar.go b/soft_navbar.go deleted file mode 100644 index 99cd595..0000000 --- a/soft_navbar.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// SoftNavbarMeta defines metadata for the rounded pill navbar. -var SoftNavbarMeta = blocks.BlockMeta{ - Key: "soft-navbar", - Title: "Soft Navbar", - Description: "Rounded pill navigation with a watercolor blob behind the logo.", - Source: "pastel-dream", - Category: blocks.CategoryNavigation, -} - -// SoftNavbarBlock renders the navbar. -// Content shape: {logo: string, menuName: string, ctaText: string, ctaHref: string} -func SoftNavbarBlock(ctx context.Context, content map[string]any) string { - data := SoftNavbarData{ - Logo: getStringOr(content, "logo", "Pastel Dream"), - MenuName: getString(content, "menuName"), - CTAText: getString(content, "ctaText"), - CTAHref: safeLink(getString(content, "ctaHref")), - } - - var buf bytes.Buffer - _ = softNavbarComponent(data).Render(ctx, &buf) - return buf.String() -} - -// SoftNavbarData is the rendered view of the navbar block. -type SoftNavbarData struct { - Logo string - MenuName string - CTAText string - CTAHref string -} diff --git a/soft_navbar.templ b/soft_navbar.templ deleted file mode 100644 index 93705af..0000000 --- a/soft_navbar.templ +++ /dev/null @@ -1,31 +0,0 @@ -package main - -// softNavbarComponent renders a rounded pill navigation with watercolor wash -// behind the logo wordmark. -templ softNavbarComponent(data SoftNavbarData) { - -} diff --git a/soft_navbar_templ.go b/soft_navbar_templ.go deleted file mode 100644 index d18afe7..0000000 --- a/soft_navbar_templ.go +++ /dev/null @@ -1,117 +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" - -// softNavbarComponent renders a rounded pill navigation with watercolor wash -// behind the logo wordmark. -func softNavbarComponent(data SoftNavbarData) 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 - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/template.templ b/template.templ deleted file mode 100644 index f10267b..0000000 --- a/template.templ +++ /dev/null @@ -1,252 +0,0 @@ -package main - -import ( - "context" - - "git.dev.alexdunmow.com/block/core/templates/bn" -) - -// PastelPageData carries the per-render page context. -type PastelPageData 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 -} - -// parsePastelPageData converts the wire-format doc map into a PastelPageData. -// It is lenient: missing fields fall back to sensible defaults so empty pages -// render without panicking. -func parsePastelPageData(doc map[string]any) PastelPageData { - title := "Untitled" - if t, ok := doc["title"].(string); ok && t != "" { - 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 PastelPageData{ - 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), - } -} - -// PastelDefault is the standard pastel-dream page template — masthead, main -// column, and footer. Used by both `default` and (with a slightly wider main) -// the `full-width` template. -templ PastelDefault(data PastelPageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/pastel-dream/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 { -
-

This page is still resting. Add a block to begin.

-
- } -
-
- @templ.Raw(data.Slots["footer"]) -
- @bn.BodyEnd(data.SiteSettings) - - -} - -// PastelLanding is the marketing landing layout — full-width hero, body, -// affirmation CTA, footer. -templ PastelLanding(data PastelPageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/pastel-dream/style.css"}, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
- @templ.Raw(data.Slots["hero"]) -
-
- if main, ok := data.Slots["main"]; ok && main != "" { -
- @templ.Raw(main) -
- } -
-
- @templ.Raw(data.Slots["cta"]) -
-
- @templ.Raw(data.Slots["footer"]) -
- @bn.BodyEnd(data.SiteSettings) - - -} - -// PastelArticle is the narrow reading-room layout for editorial posts. -templ PastelArticle(data PastelPageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/pastel-dream/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 { -
-

This page is still resting. Add a block to begin.

-
- } -
-
- @templ.Raw(data.Slots["footer"]) -
- @bn.BodyEnd(data.SiteSettings) - - -} - -// PastelFullWidth is the edge-to-edge layout for galleries and seasonal looks. -templ PastelFullWidth(data PastelPageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: []string{"/templates/pastel-dream/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 { -
-

This page is still resting. Add a block to begin.

-
- } -
-
- @templ.Raw(data.Slots["footer"]) -
- @bn.BodyEnd(data.SiteSettings) - - -} - -// RenderPastelDefault is the registered render entry for the default template. -func RenderPastelDefault(ctx context.Context, doc map[string]any) templ.Component { - return PastelDefault(parsePastelPageData(doc)) -} - -// RenderPastelLanding is the registered render entry for the landing template. -func RenderPastelLanding(ctx context.Context, doc map[string]any) templ.Component { - return PastelLanding(parsePastelPageData(doc)) -} - -// RenderPastelArticle is the registered render entry for the article template. -func RenderPastelArticle(ctx context.Context, doc map[string]any) templ.Component { - return PastelArticle(parsePastelPageData(doc)) -} - -// RenderPastelFullWidth is the registered render entry for the full-width template. -func RenderPastelFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return PastelFullWidth(parsePastelPageData(doc)) -} diff --git a/template_templ.go b/template_templ.go deleted file mode 100644 index 9363d58..0000000 --- a/template_templ.go +++ /dev/null @@ -1,510 +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" -) - -// PastelPageData carries the per-render page context. -type PastelPageData 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 -} - -// parsePastelPageData converts the wire-format doc map into a PastelPageData. -// It is lenient: missing fields fall back to sensible defaults so empty pages -// render without panicking. -func parsePastelPageData(doc map[string]any) PastelPageData { - title := "Untitled" - if t, ok := doc["title"].(string); ok && t != "" { - 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 PastelPageData{ - 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), - } -} - -// PastelDefault is the standard pastel-dream page template — masthead, main -// column, and footer. Used by both `default` and (with a slightly wider main) -// the `full-width` template. -func PastelDefault(data PastelPageData) 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/pastel-dream/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, "

This page is still resting. Add a block to begin.

") - 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 - }) -} - -// PastelLanding is the marketing landing layout — full-width hero, body, -// affirmation CTA, footer. -func PastelLanding(data PastelPageData) 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/pastel-dream/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 main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - 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, 14, "
") - 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 = templ.Raw(data.Slots["cta"]).Render(ctx, templ_7745c5c3_Buffer) - 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 - } - 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, 17, "
") - 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, 18, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// PastelArticle is the narrow reading-room layout for editorial posts. -func PastelArticle(data PastelPageData) 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, 19, "") - 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/pastel-dream/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, 20, "") - 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, 21, "
") - 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, 22, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - 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, 24, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "

This page is still resting. Add a block to begin.

") - 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["footer"]).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 - } - 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, 28, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// PastelFullWidth is the edge-to-edge layout for galleries and seasonal looks. -func PastelFullWidth(data PastelPageData) 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, 29, "") - 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/pastel-dream/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, 30, "") - 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, 31, "
") - 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, 32, "
") - 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, 33, "

This page is still resting. Add a block to begin.

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
") - 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, 35, "
") - 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, 36, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// RenderPastelDefault is the registered render entry for the default template. -func RenderPastelDefault(ctx context.Context, doc map[string]any) templ.Component { - return PastelDefault(parsePastelPageData(doc)) -} - -// RenderPastelLanding is the registered render entry for the landing template. -func RenderPastelLanding(ctx context.Context, doc map[string]any) templ.Component { - return PastelLanding(parsePastelPageData(doc)) -} - -// RenderPastelArticle is the registered render entry for the article template. -func RenderPastelArticle(ctx context.Context, doc map[string]any) templ.Component { - return PastelArticle(parsePastelPageData(doc)) -} - -// RenderPastelFullWidth is the registered render entry for the full-width template. -func RenderPastelFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return PastelFullWidth(parsePastelPageData(doc)) -} - -var _ = templruntime.GeneratedTemplate diff --git a/templates/email/pastel-dream.ninjatpl b/templates/email/pastel-dream.ninjatpl new file mode 100644 index 0000000..8aed80c --- /dev/null +++ b/templates/email/pastel-dream.ninjatpl @@ -0,0 +1,98 @@ + + + + + + + + {{ site_name }} + + + + {% if preview_text %}
+ {{ preview_text }} +
{% endif %} + + + + +
+ +
+ +
+ + + + + + + + + + + + + + +
+ + diff --git a/templates/overrides/pastel-dream/button.ninjatpl b/templates/overrides/pastel-dream/button.ninjatpl new file mode 100644 index 0000000..b9e1205 --- /dev/null +++ b/templates/overrides/pastel-dream/button.ninjatpl @@ -0,0 +1,3 @@ + + {{ text|default:"Continue" }} + diff --git a/templates/overrides/pastel-dream/card.ninjatpl b/templates/overrides/pastel-dream/card.ninjatpl new file mode 100644 index 0000000..d7f9fb6 --- /dev/null +++ b/templates/overrides/pastel-dream/card.ninjatpl @@ -0,0 +1,9 @@ +
+ {% if title %}

{{ title }}

{% endif %} + {% if body %}
+ {{ body|safe }} +
{% endif %} + {% if footer %}
+ {{ footer|safe }} +
{% endif %} +
diff --git a/templates/overrides/pastel-dream/heading.ninjatpl b/templates/overrides/pastel-dream/heading.ninjatpl new file mode 100644 index 0000000..8f4b5fb --- /dev/null +++ b/templates/overrides/pastel-dream/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/pastel-dream/text.ninjatpl b/templates/overrides/pastel-dream/text.ninjatpl new file mode 100644 index 0000000..c1c8059 --- /dev/null +++ b/templates/overrides/pastel-dream/text.ninjatpl @@ -0,0 +1,3 @@ +
+ {{ text|safe }} +
diff --git a/templates/pastel-dream/article.ninjatpl b/templates/pastel-dream/article.ninjatpl new file mode 100644 index 0000000..c6d6bd6 --- /dev/null +++ b/templates/pastel-dream/article.ninjatpl @@ -0,0 +1,21 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+ {{ slots.header|safe }} +
+
+ {% if slots.main %}
+ {{ slots.main|safe }} +
{% else %}
+

This page is still resting. Add a block to begin.

+
{% endif %} +
+
+ {{ slots.footer|safe }} +
+ {{ body_end_html|safe }} + + diff --git a/templates/pastel-dream/default.ninjatpl b/templates/pastel-dream/default.ninjatpl new file mode 100644 index 0000000..8165ca8 --- /dev/null +++ b/templates/pastel-dream/default.ninjatpl @@ -0,0 +1,19 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+ {{ slots.header|safe }} +
+
+ {% if slots.main %}{{ slots.main|safe }}{% else %}
+

This page is still resting. Add a block to begin.

+
{% endif %} +
+
+ {{ slots.footer|safe }} +
+ {{ body_end_html|safe }} + + diff --git a/templates/pastel-dream/full-width.ninjatpl b/templates/pastel-dream/full-width.ninjatpl new file mode 100644 index 0000000..c70176d --- /dev/null +++ b/templates/pastel-dream/full-width.ninjatpl @@ -0,0 +1,19 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+ {{ slots.header|safe }} +
+
+ {% if slots.main %}{{ slots.main|safe }}{% else %}
+

This page is still resting. Add a block to begin.

+
{% endif %} +
+
+ {{ slots.footer|safe }} +
+ {{ body_end_html|safe }} + + diff --git a/templates/pastel-dream/landing.ninjatpl b/templates/pastel-dream/landing.ninjatpl new file mode 100644 index 0000000..ae6a2f5 --- /dev/null +++ b/templates/pastel-dream/landing.ninjatpl @@ -0,0 +1,22 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
+ {{ slots.hero|safe }} +
+
+ {% if slots.main %}
+ {{ slots.main|safe }} +
{% endif %} +
+
+ {{ slots.cta|safe }} +
+
+ {{ slots.footer|safe }} +
+ {{ body_end_html|safe }} + + diff --git a/testimonial_soft.go b/testimonial_soft.go deleted file mode 100644 index 0304a50..0000000 --- a/testimonial_soft.go +++ /dev/null @@ -1,50 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// TestimonialSoftMeta defines the soft testimonial card. -var TestimonialSoftMeta = blocks.BlockMeta{ - Key: "testimonial-soft", - Title: "Soft Testimonial", - Description: "Quote card with a deckle paper edge, avatar, and rating.", - Source: "pastel-dream", - Category: blocks.CategoryTheme, -} - -// TestimonialSoftBlock renders the testimonial card. -// Content shape: {quote, name, role, avatar, rating} -func TestimonialSoftBlock(ctx context.Context, content map[string]any) string { - rating := getFloat(content, "rating", 0) - if rating < 0 { - rating = 0 - } - if rating > 5 { - rating = 5 - } - - data := TestimonialSoftData{ - Quote: getString(content, "quote"), - Name: getString(content, "name"), - Role: getString(content, "role"), - Avatar: getString(content, "avatar"), - Rating: int(rating), - } - - var buf bytes.Buffer - _ = testimonialSoftComponent(data).Render(ctx, &buf) - return buf.String() -} - -// TestimonialSoftData is the rendered view of the testimonial-soft block. -type TestimonialSoftData struct { - Quote string - Name string - Role string - Avatar string - Rating int -} diff --git a/testimonial_soft.templ b/testimonial_soft.templ deleted file mode 100644 index 0741893..0000000 --- a/testimonial_soft.templ +++ /dev/null @@ -1,65 +0,0 @@ -package main - -// initials returns up to two uppercase initials for a name. Used as an avatar -// fallback so the card renders cleanly when no portrait is provided. -func initials(name string) string { - if name == "" { - return "" - } - out := []rune{} - prevSpace := true - for _, r := range name { - if r == ' ' { - prevSpace = true - continue - } - if prevSpace { - if r >= 'a' && r <= 'z' { - r -= 32 - } - out = append(out, r) - prevSpace = false - if len(out) >= 2 { - break - } - } - } - return string(out) -} - -// testimonialSoftComponent renders the deckle-edged testimonial card. -templ testimonialSoftComponent(data TestimonialSoftData) { -
- if data.Rating > 0 { -
- for i := 0; i < data.Rating; i++ { - - - - } -
- } -
- @templ.Raw(data.Quote) -
- if data.Name != "" || data.Role != "" { -
- if data.Avatar != "" { - { - } else if data.Name != "" { - - { initials(data.Name) } - - } -
- if data.Name != "" { -

{ data.Name }

- } - if data.Role != "" { -

{ data.Role }

- } -
-
- } -
-} diff --git a/testimonial_soft_templ.go b/testimonial_soft_templ.go deleted file mode 100644 index 1f5d635..0000000 --- a/testimonial_soft_templ.go +++ /dev/null @@ -1,202 +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" - -// initials returns up to two uppercase initials for a name. Used as an avatar -// fallback so the card renders cleanly when no portrait is provided. -func initials(name string) string { - if name == "" { - return "" - } - out := []rune{} - prevSpace := true - for _, r := range name { - if r == ' ' { - prevSpace = true - continue - } - if prevSpace { - if r >= 'a' && r <= 'z' { - r -= 32 - } - out = append(out, r) - prevSpace = false - if len(out) >= 2 { - break - } - } - } - return string(out) -} - -// testimonialSoftComponent renders the deckle-edged testimonial card. -func testimonialSoftComponent(data TestimonialSoftData) 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.Rating > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for i := 0; i < data.Rating; i++ { - 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 - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - 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, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Name != "" || data.Role != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Avatar != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\"")") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else if data.Name != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(initials(data.Name)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `testimonial_soft.templ`, Line: 51, Col: 27} - } - _, 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, 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 - } - if data.Name != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(data.Name) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `testimonial_soft.templ`, Line: 56, Col: 102} - } - _, 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, 15, "

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

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(data.Role) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `testimonial_soft.templ`, Line: 59, Col: 91} - } - _, 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, 17, "

") - 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 = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/text_override.go b/text_override.go deleted file mode 100644 index aabd9c5..0000000 --- a/text_override.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// PastelTextBlock renders text with pastel-dream styling: Nunito body with -// generous line-height (1.75) and wider tracking on small caps. -func PastelTextBlock(ctx context.Context, content map[string]any) string { - text := getString(content, "text") - class := getString(content, "class") - - var buf bytes.Buffer - _ = pastelTextComponent(text, class).Render(ctx, &buf) - return buf.String() -} diff --git a/text_override.templ b/text_override.templ deleted file mode 100644 index d065afd..0000000 --- a/text_override.templ +++ /dev/null @@ -1,8 +0,0 @@ -package main - -// pastelTextComponent renders body text with Nunito at line-height 1.75. -templ pastelTextComponent(text, class string) { -
- @templ.Raw(text) -
-} diff --git a/text_override_templ.go b/text_override_templ.go deleted file mode 100644 index f9ab8fb..0000000 --- a/text_override_templ.go +++ /dev/null @@ -1,67 +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" - -// pastelTextComponent renders body text with Nunito at line-height 1.75. -func pastelTextComponent(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{"font-body prose max-w-none", 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 diff --git a/watercolor_hero.go b/watercolor_hero.go deleted file mode 100644 index 3d0f67d..0000000 --- a/watercolor_hero.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// WatercolorHeroMeta defines metadata for the watercolor hero. -var WatercolorHeroMeta = blocks.BlockMeta{ - Key: "watercolor-hero", - Title: "Watercolor Hero", - Description: "Hero with two-tone watercolor blobs layered behind soft display type.", - Source: "pastel-dream", - Category: blocks.CategoryTheme, -} - -// WatercolorHeroBlock renders the hero section. -// Content shape: {eyebrow, headline, body, image, ctaText, ctaHref} -func WatercolorHeroBlock(ctx context.Context, content map[string]any) string { - data := WatercolorHeroData{ - Eyebrow: getString(content, "eyebrow"), - Headline: getStringOr(content, "headline", "Soft starts"), - Body: getString(content, "body"), - Image: getString(content, "image"), - CTAText: getString(content, "ctaText"), - CTAHref: safeLink(getString(content, "ctaHref")), - } - - var buf bytes.Buffer - _ = watercolorHeroComponent(data).Render(ctx, &buf) - return buf.String() -} - -// WatercolorHeroData is the rendered view of the watercolor-hero block. -type WatercolorHeroData struct { - Eyebrow string - Headline string - Body string - Image string - CTAText string - CTAHref string -} diff --git a/watercolor_hero.templ b/watercolor_hero.templ deleted file mode 100644 index 852b1af..0000000 --- a/watercolor_hero.templ +++ /dev/null @@ -1,54 +0,0 @@ -package main - -// watercolorHeroComponent renders the watercolor hero with inline SVG blobs. -// Path fill colors come from hsl(var(--primary)) / hsl(var(--accent)) so they -// follow whatever preset is active. A scrim under the headline keeps text -// readable when an image is provided. -templ watercolorHeroComponent(data WatercolorHeroData) { -
- // Decorative watercolor blobs. Inline SVG so fills can reference theme tokens. - - -
-
- if data.Eyebrow != "" { -

- { data.Eyebrow } -

- } -

- @templ.Raw(data.Headline) -

- if data.Body != "" { -
- @templ.Raw(data.Body) -
- } - if data.CTAText != "" { - - { data.CTAText } - - } -
- if data.Image != "" { -
-
- -
-
- } else { - - } -
-
-} diff --git a/watercolor_hero_templ.go b/watercolor_hero_templ.go deleted file mode 100644 index 1113c1d..0000000 --- a/watercolor_hero_templ.go +++ /dev/null @@ -1,153 +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" - -// watercolorHeroComponent renders the watercolor hero with inline SVG blobs. -// Path fill colors come from hsl(var(--primary)) / hsl(var(--accent)) so they -// follow whatever preset is active. A scrim under the headline keeps text -// readable when an image is provided. -func watercolorHeroComponent(data WatercolorHeroData) 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.Eyebrow != "" { - 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.Eyebrow) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `watercolor_hero.templ`, Line: 20, 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 - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Headline).Render(ctx, templ_7745c5c3_Buffer) - 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.Body != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Body).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 - } - } - if data.CTAText != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(data.CTAText) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `watercolor_hero.templ`, Line: 33, Col: 20} - } - _, 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, 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 - } - if data.Image != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
\"\"
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") - 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 - }) -} - -var _ = templruntime.GeneratedTemplate