diff --git a/Makefile b/Makefile index fb1044f..19fce4a 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,27 @@ -# kindergarten — build & publish helpers (wasm .bnp workflow) +# kindergarten — 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 kindergarten-.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 kindergarten-.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 := kindergarten 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/alphabet_strip.go b/alphabet_strip.go deleted file mode 100644 index c087ab3..0000000 --- a/alphabet_strip.go +++ /dev/null @@ -1,64 +0,0 @@ -package main - -import ( - "bytes" - "context" - "strings" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// AlphabetStripBlockMeta defines metadata for the alphabet strip block. -var AlphabetStripBlockMeta = blocks.BlockMeta{ - Key: "alphabet_strip", - Title: "Alphabet Strip", - Description: "Decorative letter band; jumps to anchors when used as TOC.", - Category: blocks.CategoryNavigation, - Source: "kindergarten", -} - -// AlphabetStripData contains the letters + colorway for the rendered strip. -type AlphabetStripData struct { - Letters []string - ColorMode string -} - -// AlphabetStripBlock renders a decorative letter band. -// Content shape: {letters,colorMode}. -func AlphabetStripBlock(ctx context.Context, content map[string]any) string { - raw := getStringDefault(content, "letters", "") - colorMode := getStringDefault(content, "colorMode", "rainbow") - - // Validate colorMode against allowed set. - switch colorMode { - case "primary", "rainbow", "mono": - default: - colorMode = "rainbow" - } - - letters := splitLetters(raw) - data := AlphabetStripData{ - Letters: letters, - ColorMode: colorMode, - } - - var buf bytes.Buffer - _ = alphabetStripComponent(data).Render(ctx, &buf) - return buf.String() -} - -// splitLetters returns one entry per visible rune. Whitespace is trimmed. -func splitLetters(s string) []string { - s = strings.TrimSpace(s) - if s == "" { - return nil - } - letters := make([]string, 0, len(s)) - for _, r := range s { - if r == ' ' || r == '\t' || r == '\n' { - continue - } - letters = append(letters, string(r)) - } - return letters -} diff --git a/alphabet_strip.templ b/alphabet_strip.templ deleted file mode 100644 index cadede1..0000000 --- a/alphabet_strip.templ +++ /dev/null @@ -1,25 +0,0 @@ -package main - -// alphabetStripComponent renders the letter band. -templ alphabetStripComponent(data AlphabetStripData) { - -} - -// alphabetClass returns the modifier class for the chosen colorway. -func alphabetClass(mode string) string { - switch mode { - case "primary": - return "kg-alphabet-primary" - case "mono": - return "kg-alphabet-mono" - default: - return "" - } -} diff --git a/alphabet_strip_templ.go b/alphabet_strip_templ.go deleted file mode 100644 index 089cb1c..0000000 --- a/alphabet_strip_templ.go +++ /dev/null @@ -1,100 +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" - -// alphabetStripComponent renders the letter band. -func alphabetStripComponent(data AlphabetStripData) 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{"kg-alphabet-strip", alphabetClass(data.ColorMode)} - 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 - } - return nil - }) -} - -// alphabetClass returns the modifier class for the chosen colorway. -func alphabetClass(mode string) string { - switch mode { - case "primary": - return "kg-alphabet-primary" - case "mono": - return "kg-alphabet-mono" - default: - return "" - } -} - -var _ = templruntime.GeneratedTemplate diff --git a/big_cta.go b/big_cta.go deleted file mode 100644 index 5566d5d..0000000 --- a/big_cta.go +++ /dev/null @@ -1,45 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// BigCTABlockMeta defines metadata for the oversized CTA block. -var BigCTABlockMeta = blocks.BlockMeta{ - Key: "big_cta", - Title: "Big CTA", - Description: "Oversized pill button with crayon underline.", - Category: blocks.CategoryContent, - Source: "kindergarten", -} - -// BigCTAData is the renderer input. -type BigCTAData struct { - Label string - Href string - ColorVariant string -} - -// BigCTABlock renders the oversized pill button. -// Content shape: {label,href,colorVariant}. -func BigCTABlock(ctx context.Context, content map[string]any) string { - color := getStringDefault(content, "colorVariant", "yellow") - switch color { - case "red", "blue", "yellow", "green": - default: - color = "yellow" - } - - data := BigCTAData{ - Label: getString(content, "label"), - Href: getStringDefault(content, "href", "#"), - ColorVariant: color, - } - - var buf bytes.Buffer - _ = bigCTAComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/big_cta.templ b/big_cta.templ deleted file mode 100644 index da5930b..0000000 --- a/big_cta.templ +++ /dev/null @@ -1,28 +0,0 @@ -package main - -// bigCTAComponent renders the oversized pill CTA. -templ bigCTAComponent(data BigCTAData) { -
-
- if data.Label != "" { - { data.Label } - } else { - Add a label and link to publish this call-to-action. - } -
-
-} - -// ctaColorClass picks the modifier class for the four-color CTA variants. -func ctaColorClass(variant string) string { - switch variant { - case "red": - return "kg-pill-red" - case "blue": - return "kg-pill-blue" - case "green": - return "kg-pill-green" - default: - return "kg-pill-yellow" - } -} diff --git a/big_cta_templ.go b/big_cta_templ.go deleted file mode 100644 index 36b8de8..0000000 --- a/big_cta_templ.go +++ /dev/null @@ -1,114 +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" - -// bigCTAComponent renders the oversized pill CTA. -func bigCTAComponent(data BigCTAData) 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.Label != "" { - var templ_7745c5c3_Var2 = []any{"kg-pill", "kg-crayon-underline", ctaColorClass(data.ColorVariant)} - 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, 2, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(data.Label) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `big_cta.templ`, Line: 8, Col: 130} - } - _, 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, 5, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "Add a label and link to publish this call-to-action.") - 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 - }) -} - -// ctaColorClass picks the modifier class for the four-color CTA variants. -func ctaColorClass(variant string) string { - switch variant { - case "red": - return "kg-pill-red" - case "blue": - return "kg-pill-blue" - case "green": - return "kg-pill-green" - default: - return "kg-pill-yellow" - } -} - -var _ = templruntime.GeneratedTemplate diff --git a/blocks/alphabet_strip.ninjatpl b/blocks/alphabet_strip.ninjatpl new file mode 100644 index 0000000..02a95bb --- /dev/null +++ b/blocks/alphabet_strip.ninjatpl @@ -0,0 +1 @@ + diff --git a/schemas/alphabet_strip.schema.json b/blocks/alphabet_strip.schema.json similarity index 100% rename from schemas/alphabet_strip.schema.json rename to blocks/alphabet_strip.schema.json diff --git a/blocks/big_cta.ninjatpl b/blocks/big_cta.ninjatpl new file mode 100644 index 0000000..7150b32 --- /dev/null +++ b/blocks/big_cta.ninjatpl @@ -0,0 +1 @@ +
{% if label %}{{ label }}{% else %}Add a label and link to publish this call-to-action.{% endif %}
diff --git a/schemas/big_cta.schema.json b/blocks/big_cta.schema.json similarity index 100% rename from schemas/big_cta.schema.json rename to blocks/big_cta.schema.json diff --git a/blocks/blocks.yaml b/blocks/blocks.yaml new file mode 100644 index 0000000..a070299 --- /dev/null +++ b/blocks/blocks.yaml @@ -0,0 +1,54 @@ +# Kindergarten theme block definitions (codeless .bnp, WO-WZ-021). +# Keys are fully qualified (kindergarten:) 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: kindergarten:mascot_hero + title: Mascot Hero + description: Big rounded panel with mascot SVG and primary-colored confetti. + category: content + schema: mascot_hero.schema.json + template: mascot_hero.ninjatpl + - key: kindergarten:alphabet_strip + title: Alphabet Strip + description: Decorative letter band; jumps to anchors when used as TOC. + category: navigation + schema: alphabet_strip.schema.json + template: alphabet_strip.ninjatpl + - key: kindergarten:schedule + title: Day Schedule + description: Daycare/classroom day plan with crayon time-pills. + category: content + schema: schedule.schema.json + template: schedule.ninjatpl + - key: kindergarten:gallery_of_art + title: Gallery of Art + description: Polaroid-style grid for kid artwork. + category: content + schema: gallery_of_art.schema.json + template: gallery_of_art.ninjatpl + - key: kindergarten:numbers_counter + title: Numbers Counter + description: Big circular numeral badges for stats (e.g. '12 teachers'). + category: content + schema: numbers_counter.schema.json + template: numbers_counter.ninjatpl + - key: kindergarten:storybook_quote + title: Storybook Quote + description: Picture-book page treatment for a quote with optional illustration. + category: content + schema: storybook_quote.schema.json + template: storybook_quote.ninjatpl + - key: kindergarten:big_cta + title: Big CTA + description: Oversized pill button with crayon underline. + category: content + schema: big_cta.schema.json + template: big_cta.ninjatpl + - key: kindergarten:footer + title: Friendly Footer + description: Mascot wave, signup, contact, crayon-rule divider. + category: layout + schema: footer.schema.json + template: footer.ninjatpl diff --git a/blocks/footer.ninjatpl b/blocks/footer.ninjatpl new file mode 100644 index 0000000..c0c2186 --- /dev/null +++ b/blocks/footer.ninjatpl @@ -0,0 +1 @@ + diff --git a/schemas/footer.schema.json b/blocks/footer.schema.json similarity index 100% rename from schemas/footer.schema.json rename to blocks/footer.schema.json diff --git a/blocks/gallery_of_art.ninjatpl b/blocks/gallery_of_art.ninjatpl new file mode 100644 index 0000000..f304e23 --- /dev/null +++ b/blocks/gallery_of_art.ninjatpl @@ -0,0 +1 @@ +
{% set showNames = true %}{% if showChildName == false %}{% set showNames = false %}{% endif %}{% if title %}

{{ title }}

{% endif %}{% if not items %}
No artworks yet — add one to fill the gallery wall.
{% else %}{% endif %}
diff --git a/schemas/gallery_of_art.schema.json b/blocks/gallery_of_art.schema.json similarity index 100% rename from schemas/gallery_of_art.schema.json rename to blocks/gallery_of_art.schema.json diff --git a/blocks/mascot_hero.ninjatpl b/blocks/mascot_hero.ninjatpl new file mode 100644 index 0000000..d1a7de3 --- /dev/null +++ b/blocks/mascot_hero.ninjatpl @@ -0,0 +1 @@ +
{% if headline %}

{{ headline }}

{% else %}

Welcome!

{% endif %}{% if tagline %}

{{ tagline }}

{% endif %}{% if ctaLabel and ctaHref %}{% endif %}
{% if mascot == "blocks" %}ABC{% elif mascot == "star" %}{% elif mascot == "balloon" %}{% else %}{% endif %}
diff --git a/schemas/mascot_hero.schema.json b/blocks/mascot_hero.schema.json similarity index 100% rename from schemas/mascot_hero.schema.json rename to blocks/mascot_hero.schema.json diff --git a/blocks/numbers_counter.ninjatpl b/blocks/numbers_counter.ninjatpl new file mode 100644 index 0000000..c2037eb --- /dev/null +++ b/blocks/numbers_counter.ninjatpl @@ -0,0 +1 @@ +
{% if not items %}
No numbers yet — add a few stats to celebrate.
{% else %}
{% for item in items %}
{{ item.number|integer }}{% if item.label %}{{ item.label }}{% endif %}
{% endfor %}
{% endif %}
diff --git a/schemas/numbers_counter.schema.json b/blocks/numbers_counter.schema.json similarity index 100% rename from schemas/numbers_counter.schema.json rename to blocks/numbers_counter.schema.json diff --git a/blocks/schedule.ninjatpl b/blocks/schedule.ninjatpl new file mode 100644 index 0000000..be23721 --- /dev/null +++ b/blocks/schedule.ninjatpl @@ -0,0 +1 @@ +
{% if title %}

{{ title }}

{% endif %}{% if not items %}
No schedule items yet — add a time block to get started.
{% else %}
    {% for item in items %}
  1. {% if item.time %}{{ item.time }}{% else %}--:--{% endif %}{% if item.activity %}{{ item.activity }}{% else %}Activity{% endif %}
  2. {% endfor %}
{% endif %}
diff --git a/schemas/schedule.schema.json b/blocks/schedule.schema.json similarity index 100% rename from schemas/schedule.schema.json rename to blocks/schedule.schema.json diff --git a/blocks/storybook_quote.ninjatpl b/blocks/storybook_quote.ninjatpl new file mode 100644 index 0000000..998a266 --- /dev/null +++ b/blocks/storybook_quote.ninjatpl @@ -0,0 +1 @@ +
{% if quote %}

"{{ quote }}"

{% else %}

Add a quote to inspire your readers.

{% endif %}{% if author %}
— {{ author }}
{% endif %}
{% if illustration %}Illustration accompanying the quote{% else %}{% endif %}
diff --git a/schemas/storybook_quote.schema.json b/blocks/storybook_quote.schema.json similarity index 100% rename from schemas/storybook_quote.schema.json rename to blocks/storybook_quote.schema.json diff --git a/button_override.go b/button_override.go deleted file mode 100644 index 8bf1dee..0000000 --- a/button_override.go +++ /dev/null @@ -1,31 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// KindergartenButtonBlock renders a pill (border-radius 9999px) button with -// the sticker drop-shadow effect from spec §9. -// -// Content shape (matches built-in button): {"text": "...", "href": "...", "variant": "..."}. -func KindergartenButtonBlock(ctx context.Context, content map[string]any) string { - label := getString(content, "text") - if label == "" { - // Some installs may store the label under "label" instead. - label = getString(content, "label") - } - href := getStringDefault(content, "href", "#") - variant := getStringDefault(content, "variant", "yellow") - switch variant { - case "red", "blue", "yellow", "green": - default: - variant = "yellow" - } - - data := BigCTAData{Label: label, Href: href, ColorVariant: variant} - - var buf bytes.Buffer - _ = kgButtonComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/button_override.templ b/button_override.templ deleted file mode 100644 index 97e120f..0000000 --- a/button_override.templ +++ /dev/null @@ -1,10 +0,0 @@ -package main - -// kgButtonComponent renders a pill-shaped button override. -templ kgButtonComponent(data BigCTAData) { - if data.Label != "" { - { data.Label } - } else { - Add label and link to render this button. - } -} diff --git a/button_override_templ.go b/button_override_templ.go deleted file mode 100644 index afd274f..0000000 --- a/button_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" - -// kgButtonComponent renders a pill-shaped button override. -func kgButtonComponent(data BigCTAData) 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) - if data.Label != "" { - var templ_7745c5c3_Var2 = []any{"kg-pill", ctaColorClass(data.ColorVariant)} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var5 string - templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(data.Label) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `button_override.templ`, Line: 6, Col: 105} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "Add label and link to render this button.") - 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 b39fcb6..0000000 --- a/card_override.go +++ /dev/null @@ -1,21 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// KindergartenCardBlock renders a soft cream card with a 4px primary-colored -// top stripe (spec §9). -// -// Content shape: {"title": "...", "body": "...", "class": "..."}. The body -// is rendered as raw HTML so it can host inline formatting. -func KindergartenCardBlock(ctx context.Context, content map[string]any) string { - title := getString(content, "title") - body := getString(content, "body") - class := getString(content, "class") - - var buf bytes.Buffer - _ = kgCardComponent(title, body, class).Render(ctx, &buf) - return buf.String() -} diff --git a/card_override.templ b/card_override.templ deleted file mode 100644 index d095d86..0000000 --- a/card_override.templ +++ /dev/null @@ -1,18 +0,0 @@ -package main - -// kgCardComponent renders the rounded card override. -templ kgCardComponent(title, body, class string) { -
- if title != "" { -

{ title }

- } - if body != "" { -
- @templ.Raw(body) -
- } - if title == "" && body == "" { -
Add a title or body to fill this card.
- } -
-} diff --git a/card_override_templ.go b/card_override_templ.go deleted file mode 100644 index 0c23bdc..0000000 --- a/card_override_templ.go +++ /dev/null @@ -1,102 +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" - -// kgCardComponent renders the rounded card override. -func kgCardComponent(title, body, 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{"kg-card", 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 - } - if title != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(title) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `card_override.templ`, Line: 7, Col: 96} - } - _, 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 body != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(body).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if title == "" && body == "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
Add a title or body to fill this card.
") - 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/email_wrapper.go b/email_wrapper.go deleted file mode 100644 index 68dec33..0000000 --- a/email_wrapper.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/templates" -) - -// KindergartenEmailWrapper wraps email body content in a Kindergarten-branded -// rounded card. Uses a centered 600px table with a 32px border-radius card for -// clients that support it; Outlook degrades gracefully to a square card. -func KindergartenEmailWrapper(body string, emailCtx templates.EmailContext) string { - var buf bytes.Buffer - _ = kindergartenEmailTemplate(emailCtx, body).Render(context.Background(), &buf) - return buf.String() -} - -// kgEmailColor returns the supplied hex color or the cream/foreground/etc. -// fallback when the engine has not resolved a value for the token. -func kgEmailColor(value, fallback string) string { - if value != "" { - return value - } - return fallback -} - -// kgEmailBg / etc. group fallbacks for the cream/navy palette per spec §10. -func kgEmailBg(ctx templates.EmailContext) string { - return kgEmailColor(ctx.Colors.Background, "#fdf9ed") -} -func kgEmailCard(ctx templates.EmailContext) string { - return kgEmailColor(ctx.Colors.Card, "#ffffff") -} -func kgEmailFg(ctx templates.EmailContext) string { - return kgEmailColor(ctx.Colors.Foreground, "#1a253b") -} -func kgEmailMuted(ctx templates.EmailContext) string { - return kgEmailColor(ctx.Colors.MutedForeground, "#5a6480") -} -func kgEmailAccent(ctx templates.EmailContext) string { - return kgEmailColor(ctx.Colors.Primary, "#fbcd1f") -} -func kgEmailAccentFg(ctx templates.EmailContext) string { - return kgEmailColor(ctx.Colors.PrimaryForeground, "#1a253b") -} -func kgEmailBorder(ctx templates.EmailContext) string { - return kgEmailColor(ctx.Colors.Border, "#e6d9b3") -} diff --git a/email_wrapper.templ b/email_wrapper.templ deleted file mode 100644 index e4e4202..0000000 --- a/email_wrapper.templ +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "fmt" - - "git.dev.alexdunmow.com/block/core/templates" -) - -// kindergartenEmailTemplate is the Kindergarten-branded email wrapper. Renders -// a centered 600px table with a 32px-radius card. Outlook degrades to square. -templ kindergartenEmailTemplate(emailCtx templates.EmailContext, body string) { - - - - - - - - - { emailCtx.SiteSettings.SiteName } - - - - if emailCtx.PreviewText != "" { -
- { emailCtx.PreviewText } -
- } - - - - -
- - - - - - - - - - - - - - -
- - -} diff --git a/email_wrapper_templ.go b/email_wrapper_templ.go deleted file mode 100644 index 5c70f80..0000000 --- a/email_wrapper_templ.go +++ /dev/null @@ -1,406 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import ( - "fmt" - - "git.dev.alexdunmow.com/block/core/templates" -) - -// kindergartenEmailTemplate is the Kindergarten-branded email wrapper. Renders -// a centered 600px table with a 32px-radius card. Outlook degrades to square. -func kindergartenEmailTemplate(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: 28, Col: 42} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.PreviewText != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.PreviewText) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 45, 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, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.SiteSettings.LogoURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\"")") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else if emailCtx.SiteSettings.SiteName != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var11 string - templ_7745c5c3_Var11, 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: 58, Col: 43} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(body).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.SiteSettings.SiteURL != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "Visit ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, 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: 72, Col: 49} - } - _, 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, 23, "") - 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 - } - var templ_7745c5c3_Var19 string - templ_7745c5c3_Var19, 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: 83, Col: 50} - } - _, 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, 27, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if emailCtx.SiteSettings.SupportEmail != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "

Need a hand? ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var21 string - templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(emailCtx.SiteSettings.SupportEmail) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `email_wrapper.templ`, Line: 87, Col: 63} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "

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

Unsubscribe

") - 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 - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/embed.go b/embed.go deleted file mode 100644 index 60789b1..0000000 --- a/embed.go +++ /dev/null @@ -1,64 +0,0 @@ -package main - -import ( - "embed" - "io/fs" - "net/http" - - "git.dev.alexdunmow.com/block/core/plugin" -) - -//go:embed assets/* -var assetsFS embed.FS - -//go:embed schemas/* -var schemasFS embed.FS - -//go:embed presets.json -var presetsData []byte - -//go:embed fonts.json -var fontsData []byte - -//go:embed plugin.mod -var pluginModBytes []byte - -// Assets returns the embedded assets filesystem. -func Assets() fs.FS { - sub, _ := fs.Sub(assetsFS, "assets") - return sub -} - -// Schemas returns the embedded schemas filesystem. -func Schemas() fs.FS { - sub, _ := fs.Sub(schemasFS, "schemas") - return sub -} - -// AssetsHandler 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 -} - -// ThemeCSSManifest returns the CSS manifest used by host Tailwind to pick up -// theme-owned utility classes (crayon underline, dotted-paper background, -// sticker drop-shadow, font-family fallback stacks, etc.). -func ThemeCSSManifest() *plugin.CSSManifest { - css, err := assetsFS.ReadFile("assets/style.css") - if err != nil { - return &plugin.CSSManifest{} - } - return &plugin.CSSManifest{ - InputCSSAppend: string(css), - } -} diff --git a/footer.go b/footer.go deleted file mode 100644 index d444ce3..0000000 --- a/footer.go +++ /dev/null @@ -1,53 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// FooterBlockMeta defines metadata for the friendly footer block. -var FooterBlockMeta = blocks.BlockMeta{ - Key: "footer", - Title: "Friendly Footer", - Description: "Mascot wave, signup, contact, crayon-rule divider.", - Category: blocks.CategoryLayout, - Source: "kindergarten", -} - -// FooterSocial is a single social link entry. -type FooterSocial struct { - Platform string - Href string -} - -// FooterData is the renderer input. -type FooterData struct { - ShowSignup bool - MascotName string - SocialLinks []FooterSocial -} - -// FooterBlock renders the friendly footer. -// Content shape: {showSignup,mascotName,socialLinks}. -func FooterBlock(ctx context.Context, content map[string]any) string { - raw := getSlice(content, "socialLinks") - links := make([]FooterSocial, 0, len(raw)) - for _, m := range raw { - links = append(links, FooterSocial{ - Platform: getString(m, "platform"), - Href: getString(m, "href"), - }) - } - - data := FooterData{ - ShowSignup: getBool(content, "showSignup", true), - MascotName: getStringDefault(content, "mascotName", "Pip"), - SocialLinks: links, - } - - var buf bytes.Buffer - _ = footerComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/footer.templ b/footer.templ deleted file mode 100644 index 80391f5..0000000 --- a/footer.templ +++ /dev/null @@ -1,64 +0,0 @@ -package main - -// footerComponent renders the friendly footer. -templ footerComponent(data FooterData) { - -} - -// socialLabel renders an accessible label for the icon link. -func socialLabel(platform string) string { - switch platform { - case "facebook": - return "Visit our Facebook" - case "instagram": - return "Visit our Instagram" - case "youtube": - return "Visit our YouTube" - case "tiktok": - return "Visit our TikTok" - case "email": - return "Send us an email" - default: - return "Open social link" - } -} - -// socialIcon renders a small social icon (Lucide-style stroke). -templ socialIcon(platform string) { - switch platform { - case "facebook": - - case "instagram": - - case "youtube": - - case "tiktok": - - case "email": - - default: - - } -} diff --git a/footer_templ.go b/footer_templ.go deleted file mode 100644 index ebb6283..0000000 --- a/footer_templ.go +++ /dev/null @@ -1,216 +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" - -// footerComponent renders the friendly footer. -func footerComponent(data FooterData) 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.ShowSignup { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if len(data.SocialLinks) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, link := range data.SocialLinks { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = socialIcon(link.Platform).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 = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// socialLabel renders an accessible label for the icon link. -func socialLabel(platform string) string { - switch platform { - case "facebook": - return "Visit our Facebook" - case "instagram": - return "Visit our Instagram" - case "youtube": - return "Visit our YouTube" - case "tiktok": - return "Visit our TikTok" - case "email": - return "Send us an email" - default: - return "Open social link" - } -} - -// socialIcon renders a small social icon (Lucide-style stroke). -func socialIcon(platform 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_Var7 := templ.GetChildren(ctx) - if templ_7745c5c3_Var7 == nil { - templ_7745c5c3_Var7 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - switch platform { - case "facebook": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "instagram": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "youtube": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "tiktok": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "email": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - default: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/gallery_of_art.go b/gallery_of_art.go deleted file mode 100644 index 5423bc0..0000000 --- a/gallery_of_art.go +++ /dev/null @@ -1,57 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// GalleryOfArtBlockMeta defines metadata for the gallery of art block. -var GalleryOfArtBlockMeta = blocks.BlockMeta{ - Key: "gallery_of_art", - Title: "Gallery of Art", - Description: "Polaroid-style grid for kid artwork.", - Category: blocks.CategoryContent, - Source: "kindergarten", -} - -// GalleryArt represents a single artwork entry. -type GalleryArt struct { - Image string - ChildName string - Age int -} - -// GalleryData is the renderer input. -type GalleryData struct { - Title string - ShowChildName bool - Items []GalleryArt -} - -// GalleryOfArtBlock renders the polaroid grid. -// Content shape: {title,showChildName,items:[{image,childName,age}]}. -// -// Privacy: when showChildName=false, no child names are rendered. -func GalleryOfArtBlock(ctx context.Context, content map[string]any) string { - raw := getSlice(content, "items") - items := make([]GalleryArt, 0, len(raw)) - for _, m := range raw { - items = append(items, GalleryArt{ - Image: getString(m, "image"), - ChildName: getString(m, "childName"), - Age: getInt(m, "age", 0), - }) - } - - data := GalleryData{ - Title: getString(content, "title"), - ShowChildName: getBool(content, "showChildName", true), - Items: items, - } - - var buf bytes.Buffer - _ = galleryOfArtComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/gallery_of_art.templ b/gallery_of_art.templ deleted file mode 100644 index 88c4993..0000000 --- a/gallery_of_art.templ +++ /dev/null @@ -1,52 +0,0 @@ -package main - -import ( - "fmt" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// galleryOfArtComponent renders a polaroid-style grid of artworks. -templ galleryOfArtComponent(data GalleryData) { -
-
- if data.Title != "" { -

{ data.Title }

- } - if len(data.Items) == 0 { -
No artworks yet — add one to fill the gallery wall.
- } else { - - } -
-
-} - -// polaroidAlt produces a respectful alt-text that honours the privacy toggle. -func polaroidAlt(art GalleryArt, showChildName bool) string { - if showChildName && art.ChildName != "" { - return fmt.Sprintf("Artwork by %s", art.ChildName) - } - return "Children's artwork" -} diff --git a/gallery_of_art_templ.go b/gallery_of_art_templ.go deleted file mode 100644 index 61d51a2..0000000 --- a/gallery_of_art_templ.go +++ /dev/null @@ -1,197 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import ( - "fmt" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// galleryOfArtComponent renders a polaroid-style grid of artworks. -func galleryOfArtComponent(data GalleryData) 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: `gallery_of_art.templ`, Line: 14, Col: 107} - } - _, 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 len(data.Items) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
No artworks yet — add one to fill the gallery wall.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - 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, 19, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// polaroidAlt produces a respectful alt-text that honours the privacy toggle. -func polaroidAlt(art GalleryArt, showChildName bool) string { - if showChildName && art.ChildName != "" { - return fmt.Sprintf("Artwork by %s", art.ChildName) - } - return "Children's artwork" -} - -var _ = templruntime.GeneratedTemplate diff --git a/go.mod b/go.mod deleted file mode 100644 index 1225523..0000000 --- a/go.mod +++ /dev/null @@ -1,20 +0,0 @@ -module git.dev.alexdunmow.com/block/themes/kindergarten - -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 00befa8..0000000 --- a/heading_override.go +++ /dev/null @@ -1,65 +0,0 @@ -package main - -import ( - "bytes" - "context" - "strconv" -) - -// KindergartenHeadingBlock renders a heading with the Kindergarten crayon-underline -// accent and an optional numeral step badge. -// -// Content expects: {"text": "...", "level": 1-6, "textClass": "...", "step": 1-9} -func KindergartenHeadingBlock(ctx context.Context, content map[string]any) string { - text := getString(content, "text") - textClass := getString(content, "textClass") - level := parseHeadingLevel(content) - step := parseStep(content) - - var buf bytes.Buffer - _ = kgHeadingComponent(level, text, textClass, step).Render(ctx, &buf) - return buf.String() -} - -// parseHeadingLevel parses the level from content, 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 -} - -// parseStep parses an optional step badge (1-9). Returns 0 if not provided -// or out of range; renderer skips the badge when step == 0. -func parseStep(content map[string]any) int { - if v, ok := content["step"].(float64); ok { - s := int(v) - if s >= 1 && s <= 9 { - return s - } - } - if v, ok := content["step"].(int); ok { - if v >= 1 && v <= 9 { - return v - } - } - if v, ok := content["step"].(string); ok { - if s, err := strconv.Atoi(v); err == nil && s >= 1 && s <= 9 { - return s - } - } - return 0 -} diff --git a/heading_override.templ b/heading_override.templ deleted file mode 100644 index a909279..0000000 --- a/heading_override.templ +++ /dev/null @@ -1,57 +0,0 @@ -package main - -import "fmt" - -// kgHeadingBaseClass returns size classes per heading level (Tailwind-like -// utilities scoped to the kindergarten CSS). -func kgHeadingBaseClass(level int) string { - switch level { - case 1: - return "kg-display kg-crayon-underline" - case 2: - return "kg-display kg-crayon-underline" - case 3: - return "kg-display" - case 4: - return "kg-display" - case 5: - return "kg-display" - case 6: - return "kg-display" - default: - return "kg-display" - } -} - -// kgHeadingComponent renders a heading with Kindergarten accents, optionally -// preceded by a circular step badge (e.g. for "Step 1", "Step 2" sections). -templ kgHeadingComponent(level int, text, textClass string, step int) { - if step > 0 { -
- - @kgHeadingTag(level, text, textClass) -
- } else { - @kgHeadingTag(level, text, textClass) - } -} - -// kgHeadingTag emits the actual

..

tag at the requested level. -templ kgHeadingTag(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 5fb9092..0000000 --- a/heading_override_templ.go +++ /dev/null @@ -1,373 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import "fmt" - -// kgHeadingBaseClass returns size classes per heading level (Tailwind-like -// utilities scoped to the kindergarten CSS). -func kgHeadingBaseClass(level int) string { - switch level { - case 1: - return "kg-display kg-crayon-underline" - case 2: - return "kg-display kg-crayon-underline" - case 3: - return "kg-display" - case 4: - return "kg-display" - case 5: - return "kg-display" - case 6: - return "kg-display" - default: - return "kg-display" - } -} - -// kgHeadingComponent renders a heading with Kindergarten accents, optionally -// preceded by a circular step badge (e.g. for "Step 1", "Step 2" sections). -func kgHeadingComponent(level int, text, textClass string, step int) 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) - if step > 0 { - 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(fmt.Sprintf("%d", step)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 31, Col: 83} - } - _, 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 - } - templ_7745c5c3_Err = kgHeadingTag(level, text, textClass).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 - } - } else { - templ_7745c5c3_Err = kgHeadingTag(level, text, textClass).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - return nil - }) -} - -// kgHeadingTag emits the actual

..

tag at the requested level. -func kgHeadingTag(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_Var3 := templ.GetChildren(ctx) - if templ_7745c5c3_Var3 == nil { - templ_7745c5c3_Var3 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - switch level { - case 1: - var templ_7745c5c3_Var4 = []any{kgHeadingBaseClass(1), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, 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 - } - var templ_7745c5c3_Var6 string - templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 43, Col: 112} - } - _, 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, 6, "

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 2: - var templ_7745c5c3_Var7 = []any{kgHeadingBaseClass(2), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var7...) - 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_Var9 string - templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 45, Col: 95} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "

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

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

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case 4: - var templ_7745c5c3_Var13 = []any{kgHeadingBaseClass(4), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var13...) - 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_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 49, Col: 94} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) - 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 5: - var templ_7745c5c3_Var16 = []any{kgHeadingBaseClass(5), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...) - 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_Var18 string - templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 51, Col: 95} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) - 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 - } - case 6: - var templ_7745c5c3_Var19 = []any{kgHeadingBaseClass(6), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var19...) - 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_Var21 string - templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(text) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `heading_override.templ`, Line: 53, Col: 96} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - default: - var templ_7745c5c3_Var22 = []any{kgHeadingBaseClass(2), textClass} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "

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

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/helpers.go b/helpers.go deleted file mode 100644 index b4f9ceb..0000000 --- a/helpers.go +++ /dev/null @@ -1,63 +0,0 @@ -package main - -// getString extracts a string value from content map. -func getString(content map[string]any, key string) string { - if v, ok := content[key].(string); ok { - return v - } - return "" -} - -// getStringDefault extracts a string value from content with a fallback. -func getStringDefault(content map[string]any, key, def string) string { - if v, ok := content[key].(string); ok && v != "" { - return v - } - return def -} - -// getBool extracts a bool value from content. Accepts native bool, "true"/"false" -// strings, and the JSON-encoded float forms ("true" via 1, 0). Defaults to def. -func getBool(content map[string]any, key string, def bool) bool { - switch v := content[key].(type) { - case bool: - return v - case string: - switch v { - case "true": - return true - case "false": - return false - } - case float64: - return v != 0 - } - return def -} - -// getInt extracts an int value from content map (handles float64 from JSON). -func getInt(content map[string]any, key string, defaultVal int) int { - if v, ok := content[key].(float64); ok { - return int(v) - } - if v, ok := content[key].(int); ok { - return v - } - return defaultVal -} - -// getSlice extracts a slice of maps from content. If the underlying value is -// not a JSON array of objects (e.g. malformed content provides a bare string), -// the function returns nil so renderers can fall back to their empty state. -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 -} diff --git a/main.go b/main.go deleted file mode 100644 index 24c53c7..0000000 --- a/main.go +++ /dev/null @@ -1,17 +0,0 @@ -//go:build wasip1 - -// Package main compiles the kindergarten 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..bc49032 --- /dev/null +++ b/manifest.yaml @@ -0,0 +1,532 @@ +# Kindergarten theme — codeless .bnp manifest (WO-WZ-021 Phase B). +# 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: kindergarten + title: Kindergarten + description: "Primary-colored, hand-lettered theme for schools, daycares, toy shops, museums, and kids' publishers." + +page_templates: + - system: kindergarten + key: default + title: Default + description: "Standard rounded layout with header, main, footer" + slots: [header, main, footer] + - system: kindergarten + key: landing + title: Landing + description: "Mascot-led hero plus stacked feature sections" + slots: [hero, main, cta, footer] + - system: kindergarten + key: article + title: Story Page + description: "Picture-book reading layout for blog posts and stories" + slots: [header, main, aside, footer] + - system: kindergarten + key: full-width + title: Full Width + description: "Edge-to-edge gallery / classroom showcase" + slots: [header, main, footer] + +template_overrides: + - { template: kindergarten, block: heading } + - { template: kindergarten, block: text } + - { template: kindergarten, block: button } + - { template: kindergarten, block: card } + +email_wrappers: + - kindergarten + +css: + input_css_append: | + /* ============================================================ + Kindergarten — Primary-colored, hand-lettered theme + ------------------------------------------------------------ + Token strategy: every color reference goes through + `hsl(var(--))` and font-family goes through + `var(--font-{heading|body|mono}, )`. + ============================================================ */ + + /* ---- Typography (CSS-variable consumers + fallbacks) ------- */ + + .kg-page { + font-family: var(--font-body, "Nunito", "Quicksand", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif); + line-height: 1.7; + background-color: hsl(var(--background)); + color: hsl(var(--foreground)); + } + + .kg-display, + .kg-page h1, + .kg-page h2, + .kg-page h3, + .kg-page h4, + .kg-page h5, + .kg-page h6 { + font-family: var(--font-heading, "Quicksand", "Sniglet", "Nunito", -apple-system, sans-serif); + font-weight: 700; + letter-spacing: -0.01em; + } + + .kg-mono { + font-family: var(--font-mono, "Fira Code", "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace); + } + + /* ---- Layout utilities -------------------------------------- */ + + .kg-section { + padding-block: 4rem; + } + + .kg-container { + max-width: 72rem; + margin-inline: auto; + padding-inline: 1.5rem; + } + + /* ---- Rounded primitives ------------------------------------ */ + + .kg-chip { + border-radius: 24px; + padding: 0.5rem 1rem; + display: inline-flex; + align-items: center; + gap: 0.5rem; + } + + .kg-card { + border-radius: 32px; + background-color: hsl(var(--card)); + color: hsl(var(--card-foreground, var(--foreground))); + padding: 2rem; + border: 1px solid hsl(var(--border)); + position: relative; + overflow: hidden; + } + + .kg-card::before { + content: ""; + position: absolute; + inset: 0 0 auto 0; + height: 4px; + background-color: hsl(var(--primary)); + } + + .kg-hero-panel { + border-radius: 48px; + padding: clamp(2rem, 6vw, 4rem); + position: relative; + overflow: hidden; + background-color: hsl(var(--accent) / 0.15); + } + + .kg-pill { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 0.5rem; + padding: 1.25rem 2.5rem; + border-radius: 9999px; + font-family: var(--font-heading, "Quicksand", "Sniglet", "Nunito", sans-serif); + font-weight: 700; + font-size: 1.125rem; + background-color: hsl(var(--primary)); + color: hsl(var(--primary-foreground)); + border: 0; + cursor: pointer; + box-shadow: 0 4px 0 0 hsl(var(--foreground) / 0.15); + text-decoration: none; + transition: transform 120ms ease, box-shadow 120ms ease; + } + + .kg-pill:hover { + transform: translateY(-1px); + box-shadow: 0 5px 0 0 hsl(var(--foreground) / 0.15); + } + + .kg-pill:active { + transform: translateY(2px); + box-shadow: 0 2px 0 0 hsl(var(--foreground) / 0.15); + } + + .kg-pill:focus-visible { + outline: 3px solid hsl(var(--ring)); + outline-offset: 3px; + } + + /* CTA colorways */ + .kg-pill-red { background-color: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); } + .kg-pill-blue { background-color: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); } + .kg-pill-yellow { background-color: hsl(var(--accent)); color: hsl(var(--accent-foreground)); } + .kg-pill-green { background-color: hsl(145 65% 45%); color: hsl(0 0% 100%); } + + /* ---- Crayon underline (utility on headings) ---------------- */ + + .kg-crayon-underline { + position: relative; + display: inline-block; + } + + .kg-crayon-underline::after { + content: ""; + position: absolute; + left: 0; + right: 0; + bottom: -6px; + height: 8px; + background: linear-gradient(90deg, + hsl(var(--primary)) 0 22%, + hsl(var(--accent)) 22% 50%, + hsl(var(--secondary)) 50% 78%, + currentColor 78% 100%); + border-radius: 4px; + transform: rotate(-1deg); + z-index: -1; + } + + /* ---- Numeral badges ---------------------------------------- */ + + .kg-numeral { + display: inline-flex; + align-items: center; + justify-content: center; + width: 96px; + height: 96px; + border-radius: 50%; + aspect-ratio: 1 / 1; + background-color: hsl(var(--accent)); + color: hsl(var(--accent-foreground)); + font-family: var(--font-heading, "Quicksand", "Sniglet", sans-serif); + font-weight: 700; + font-size: 2.5rem; + box-shadow: 0 4px 0 0 hsl(var(--foreground) / 0.15); + } + + /* ---- Polaroid frame for gallery_of_art --------------------- */ + + .kg-polaroid { + background-color: hsl(var(--card)); + border-radius: 16px; + padding-top: 12px; + padding-inline: 12px; + padding-bottom: 36px; + box-shadow: 0 6px 24px hsl(var(--foreground) / 0.12); + transform: rotate(-1deg); + transition: transform 200ms ease; + } + + .kg-polaroid:nth-child(2n) { transform: rotate(1.5deg); } + .kg-polaroid:nth-child(3n) { transform: rotate(-0.5deg); } + .kg-polaroid:hover { transform: rotate(0deg); } + + .kg-polaroid > img, + .kg-polaroid > .kg-polaroid-image { + display: block; + width: 100%; + aspect-ratio: 1 / 1; + object-fit: cover; + border-radius: 8px; + background-color: hsl(var(--muted)); + } + + .kg-polaroid-caption { + text-align: center; + margin-top: 0.75rem; + font-family: var(--font-heading, "Quicksand", "Sniglet", sans-serif); + color: hsl(var(--foreground)); + } + + /* ---- Alphabet strip ---------------------------------------- */ + + .kg-alphabet-strip { + display: flex; + overflow-x: auto; + gap: 0.5rem; + padding: 1rem; + scrollbar-width: thin; + } + + .kg-alphabet-letter { + flex: 0 0 auto; + display: inline-flex; + align-items: center; + justify-content: center; + width: 56px; + height: 56px; + border-radius: 24px; + background-color: hsl(var(--primary)); + color: hsl(var(--primary-foreground)); + font-family: var(--font-heading, "Quicksand", "Sniglet", sans-serif); + font-weight: 700; + font-size: 1.5rem; + box-shadow: 0 4px 0 0 hsl(var(--foreground) / 0.12); + } + + .kg-alphabet-letter:nth-child(4n+1) { background-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); } + .kg-alphabet-letter:nth-child(4n+2) { background-color: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); } + .kg-alphabet-letter:nth-child(4n+3) { background-color: hsl(var(--accent)); color: hsl(var(--accent-foreground)); } + .kg-alphabet-letter:nth-child(4n+4) { background-color: hsl(145 65% 45%); color: hsl(0 0% 100%); } + + .kg-alphabet-mono .kg-alphabet-letter { + background-color: hsl(var(--muted)); + color: hsl(var(--muted-foreground)); + } + + .kg-alphabet-primary .kg-alphabet-letter { + background-color: hsl(var(--primary)); + color: hsl(var(--primary-foreground)); + } + + /* ---- Day schedule pills ------------------------------------ */ + + .kg-schedule-item { + display: grid; + grid-template-columns: auto 1fr auto; + gap: 1rem; + align-items: center; + padding: 1rem; + border-radius: 24px; + background-color: hsl(var(--card)); + border: 1px solid hsl(var(--border)); + margin-bottom: 0.75rem; + } + + .kg-schedule-time { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.25rem 0.75rem; + border-radius: 9999px; + background-color: hsl(var(--accent)); + color: hsl(var(--accent-foreground)); + font-family: var(--font-mono, "Fira Code", monospace); + font-weight: 700; + } + + .kg-schedule-activity { + font-family: var(--font-body, "Nunito", sans-serif); + color: hsl(var(--foreground)); + } + + .kg-schedule-icon { + color: hsl(var(--primary)); + } + + /* ---- Storybook quote --------------------------------------- */ + + .kg-storybook { + display: grid; + grid-template-columns: 1fr; + gap: 2rem; + padding: 2rem; + border-radius: 32px; + background-color: hsl(var(--card)); + border: 1px solid hsl(var(--border)); + } + + @media (min-width: 768px) { + .kg-storybook { + grid-template-columns: 1fr 1fr; + align-items: center; + } + } + + .kg-storybook-quote { + font-family: var(--font-heading, "Quicksand", "Sniglet", serif); + font-size: clamp(1.25rem, 3vw, 2rem); + line-height: 1.4; + color: hsl(var(--foreground)); + } + + .kg-storybook-author { + margin-top: 1rem; + color: hsl(var(--muted-foreground)); + font-family: var(--font-body, "Nunito", sans-serif); + } + + .kg-storybook-illustration { + width: 100%; + aspect-ratio: 4 / 3; + object-fit: cover; + border-radius: 24px; + background-color: hsl(var(--muted)); + } + + /* ---- Friendly footer --------------------------------------- */ + + .kg-footer { + padding: 3rem 1.5rem; + background-color: hsl(var(--muted)); + color: hsl(var(--foreground)); + border-top: 6px dashed hsl(var(--primary)); + border-radius: 48px 48px 0 0; + } + + .kg-footer-mascot { + display: inline-flex; + align-items: center; + gap: 0.5rem; + margin-bottom: 1rem; + font-family: var(--font-heading, "Quicksand", sans-serif); + } + + .kg-footer-signup { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-block: 1.5rem; + max-width: 32rem; + } + + .kg-footer-signup input { + flex: 1 1 12rem; + padding: 0.75rem 1rem; + border-radius: 9999px; + border: 2px solid hsl(var(--border)); + background-color: hsl(var(--input)); + color: hsl(var(--foreground)); + font-family: var(--font-body, "Nunito", sans-serif); + } + + .kg-footer-signup input:focus-visible { + outline: 3px solid hsl(var(--ring)); + outline-offset: 2px; + } + + .kg-social-row { + display: flex; + gap: 0.75rem; + margin-top: 1rem; + } + + .kg-social-link { + display: inline-flex; + align-items: center; + justify-content: center; + width: 40px; + height: 40px; + border-radius: 9999px; + background-color: hsl(var(--card)); + color: hsl(var(--primary)); + border: 1px solid hsl(var(--border)); + } + + .kg-social-link:focus-visible { + outline: 3px solid hsl(var(--ring)); + outline-offset: 2px; + } + + /* ---- Mascot hero confetti dots ----------------------------- */ + + .kg-confetti { + position: absolute; + inset: 0; + pointer-events: none; + background-image: + radial-gradient(circle, hsl(var(--primary) / 0.5) 8px, transparent 9px), + radial-gradient(circle, hsl(var(--secondary) / 0.5) 6px, transparent 7px), + radial-gradient(circle, hsl(var(--accent) / 0.5) 5px, transparent 6px); + background-size: 80px 80px, 50px 50px, 30px 30px; + background-position: 10% 20%, 70% 30%, 40% 80%; + opacity: 0.6; + } + + /* ---- Dotted paper layer (page background) ------------------ */ + + .kg-dotted-paper { + background-color: hsl(var(--background)); + background-image: radial-gradient(circle, hsl(var(--muted-foreground) / 0.15) 1px, transparent 1.5px); + background-size: 24px 24px; + } + + /* ---- Heading override (numeral badge variant) -------------- */ + + .kg-heading-stepped { + display: flex; + align-items: center; + gap: 1rem; + } + + .kg-heading-step-badge { + display: inline-flex; + align-items: center; + justify-content: center; + width: 48px; + height: 48px; + border-radius: 50%; + background-color: hsl(var(--accent)); + color: hsl(var(--accent-foreground)); + font-family: var(--font-heading, "Quicksand", "Sniglet", sans-serif); + font-weight: 700; + font-size: 1.5rem; + flex: 0 0 auto; + } + + /* ---- Text override: rounded selection highlight ------------ */ + + .kg-text ::selection { + background-color: hsl(var(--accent)); + color: hsl(var(--accent-foreground)); + } + + .kg-text { + font-family: var(--font-body, "Nunito", sans-serif); + line-height: 1.7; + color: hsl(var(--foreground)); + } + + /* ---- Numbers counter grid ---------------------------------- */ + + .kg-numbers-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); + gap: 2rem; + text-align: center; + } + + .kg-numbers-item { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.75rem; + } + + .kg-numbers-label { + font-family: var(--font-body, "Nunito", sans-serif); + color: hsl(var(--muted-foreground)); + text-transform: uppercase; + letter-spacing: 0.05em; + font-size: 0.875rem; + } + + /* ---- Gallery grid ------------------------------------------ */ + + .kg-gallery-grid { + display: grid; + grid-template-columns: 1fr; + gap: 1.5rem; + } + + @media (min-width: 640px) { .kg-gallery-grid { grid-template-columns: repeat(2, 1fr); } } + @media (min-width: 1024px) { .kg-gallery-grid { grid-template-columns: repeat(3, 1fr); } } + + /* ---- Big CTA panel (spec §9 button override) --------------- */ + + .kg-big-cta { + text-align: center; + padding: 3rem 1.5rem; + } + + /* ---- Empty-state placeholder ------------------------------- */ + + .kg-empty { + text-align: center; + padding: 2rem; + border-radius: 24px; + border: 2px dashed hsl(var(--border)); + color: hsl(var(--muted-foreground)); + font-family: var(--font-body, "Nunito", sans-serif); + } diff --git a/mascot_hero.go b/mascot_hero.go deleted file mode 100644 index 22c226d..0000000 --- a/mascot_hero.go +++ /dev/null @@ -1,44 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// MascotHeroBlockMeta defines metadata for the mascot hero block. -var MascotHeroBlockMeta = blocks.BlockMeta{ - Key: "mascot_hero", - Title: "Mascot Hero", - Description: "Big rounded panel with mascot SVG and primary-colored confetti.", - Category: blocks.CategoryContent, - Source: "kindergarten", -} - -// MascotHeroData carries the strongly-typed shape consumed by the templ component. -type MascotHeroData struct { - Mascot string - Headline string - Tagline string - CTALabel string - CTAHref string - BgColor string -} - -// MascotHeroBlock renders the mascot hero block from the unstructured content map. -// Content shape: {mascot,headline,tagline,ctaLabel,ctaHref,bgColor}. -func MascotHeroBlock(ctx context.Context, content map[string]any) string { - data := MascotHeroData{ - Mascot: getStringDefault(content, "mascot", "pip"), - Headline: getString(content, "headline"), - Tagline: getString(content, "tagline"), - CTALabel: getString(content, "ctaLabel"), - CTAHref: getString(content, "ctaHref"), - BgColor: getString(content, "bgColor"), - } - - var buf bytes.Buffer - _ = mascotHeroComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/mascot_hero.templ b/mascot_hero.templ deleted file mode 100644 index 87fdd15..0000000 --- a/mascot_hero.templ +++ /dev/null @@ -1,78 +0,0 @@ -package main - -// mascotHeroComponent renders the mascot hero panel. -templ mascotHeroComponent(data MascotHeroData) { -
-
-
- -
-
- if data.Headline != "" { -

{ data.Headline }

- } else { -

Welcome!

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

{ data.Tagline }

- } - if data.CTALabel != "" && data.CTAHref != "" { - - } -
-
- @mascotSVG(data.Mascot) -
-
-
-
-
-} - -// mascotSVG renders a primitive, license-free mascot illustration. -// The SVGs intentionally use `currentColor` (and the theme primary) so they -// inherit colorways from the active preset. -templ mascotSVG(name string) { - switch name { - case "blocks": - - - - - A - B - C - - case "star": - - - - - - - case "balloon": - - - - - - - - - default: - - - - - - - - - - - - - } -} diff --git a/mascot_hero_templ.go b/mascot_hero_templ.go deleted file mode 100644 index 2a0ee59..0000000 --- a/mascot_hero_templ.go +++ /dev/null @@ -1,178 +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" - -// mascotHeroComponent renders the mascot hero panel. -func mascotHeroComponent(data MascotHeroData) 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.Headline != "" { - 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.Headline) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `mascot_hero.templ`, Line: 12, Col: 121} - } - _, 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 - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

Welcome!

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

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

") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - if data.CTALabel != "" && data.CTAHref != "" { - 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, 10, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = mascotSVG(data.Mascot).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 - } - return nil - }) -} - -// mascotSVG renders a primitive, license-free mascot illustration. -// The SVGs intentionally use `currentColor` (and the theme primary) so they -// inherit colorways from the active preset. -func mascotSVG(name 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_Var6 := templ.GetChildren(ctx) - if templ_7745c5c3_Var6 == nil { - templ_7745c5c3_Var6 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - switch name { - case "blocks": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " A B C") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "star": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "balloon": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - default: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/master_pages.json b/master_pages.json new file mode 100644 index 0000000..fca0431 --- /dev/null +++ b/master_pages.json @@ -0,0 +1,25 @@ +[ + { + "key": "kindergarten:default-master", + "title": "Kindergarten Default Master", + "page_templates": ["default", "article"], + "blocks": [ + { "block_key": "navbar", "title": "Crayon Nav", "content": { "menuName": "main" }, "slot": "header", "sort_order": 0 }, + { "block_key": "kindergarten:alphabet_strip", "title": "ABC Strip", "content": { "letters": "ABCDEFGHIJ", "colorMode": "rainbow" }, "slot": "header", "sort_order": 1 }, + { "block_key": "slot", "title": "Main Slot", "content": { "slotName": "main", "placeholder": "Page content" }, "slot": "main", "sort_order": 0 }, + { "block_key": "kindergarten:footer", "title": "Friendly Footer", "content": { "showSignup": "true", "mascotName": "Pip" }, "slot": "footer", "sort_order": 0 } + ] + }, + { + "key": "kindergarten:landing-master", + "title": "Kindergarten Landing Master", + "page_templates": ["landing", "full-width"], + "blocks": [ + { "block_key": "navbar", "title": "Crayon Nav", "content": { "menuName": "main" }, "slot": "header", "sort_order": 0 }, + { "block_key": "kindergarten:mascot_hero", "title": "Mascot Hero", "content": { "mascot": "pip", "headline": "Welcome to school!", "tagline": "Big fun, small humans." }, "slot": "hero", "sort_order": 0 }, + { "block_key": "slot", "title": "Main Slot", "content": { "slotName": "main" }, "slot": "main", "sort_order": 0 }, + { "block_key": "kindergarten:big_cta", "title": "Big Yellow CTA", "content": { "label": "Enrol today", "href": "/enrol", "colorVariant": "yellow" }, "slot": "cta", "sort_order": 0 }, + { "block_key": "kindergarten:footer", "title": "Friendly Footer", "content": { "showSignup": "true" }, "slot": "footer", "sort_order": 0 } + ] + } +] diff --git a/numbers_counter.go b/numbers_counter.go deleted file mode 100644 index 3b84b15..0000000 --- a/numbers_counter.go +++ /dev/null @@ -1,47 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// NumbersCounterBlockMeta defines metadata for the numbers counter block. -var NumbersCounterBlockMeta = blocks.BlockMeta{ - Key: "numbers_counter", - Title: "Numbers Counter", - Description: "Big circular numeral badges for stats (e.g. '12 teachers').", - Category: blocks.CategoryContent, - Source: "kindergarten", -} - -// NumberItem is a single numeral + label pair. -type NumberItem struct { - Number int - Label string -} - -// NumbersData is the renderer input. -type NumbersData struct { - Items []NumberItem -} - -// NumbersCounterBlock renders the round numeral grid. -// Content shape: {items:[{number,label}]}. -func NumbersCounterBlock(ctx context.Context, content map[string]any) string { - raw := getSlice(content, "items") - items := make([]NumberItem, 0, len(raw)) - for _, m := range raw { - items = append(items, NumberItem{ - Number: getInt(m, "number", 0), - Label: getString(m, "label"), - }) - } - - data := NumbersData{Items: items} - - var buf bytes.Buffer - _ = numbersCounterComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/numbers_counter.templ b/numbers_counter.templ deleted file mode 100644 index 5fa440a..0000000 --- a/numbers_counter.templ +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import "fmt" - -// numbersCounterComponent renders circular numeral badges. -templ numbersCounterComponent(data NumbersData) { -
-
- if len(data.Items) == 0 { -
No numbers yet — add a few stats to celebrate.
- } else { -
- for _, item := range data.Items { -
- { fmt.Sprintf("%d", item.Number) } - if item.Label != "" { - { item.Label } - } -
- } -
- } -
-
-} diff --git a/numbers_counter_templ.go b/numbers_counter_templ.go deleted file mode 100644 index a445d16..0000000 --- a/numbers_counter_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" - -import "fmt" - -// numbersCounterComponent renders circular numeral badges. -func numbersCounterComponent(data NumbersData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if len(data.Items) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
No numbers yet — add a few stats to celebrate.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, item := range data.Items { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", item.Number)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `numbers_counter.templ`, Line: 15, Col: 111} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if item.Label != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(item.Label) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `numbers_counter.templ`, Line: 17, Col: 51} - } - _, 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, 8, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/plugin.mod b/plugin.mod index ef86e4d..9e6f6fc 100644 --- a/plugin.mod +++ b/plugin.mod @@ -2,11 +2,8 @@ name = "kindergarten" display_name = "Kindergarten" scope = "@themes" -version = "0.1.2" +version = "0.2.0" description = "Primary-colored, hand-lettered theme for schools, daycares, toy shops, museums, and kids' publishers." kind = "theme" categories = ["templates"] tags = ["kids", "education", "playful", "family", "school", "museum", "friendly", "daycare", "publisher"] - -[compatibility] -block_core = ">=0.15.0 <0.16.0" diff --git a/register.go b/register.go deleted file mode 100644 index e7e773f..0000000 --- a/register.go +++ /dev/null @@ -1,181 +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 satisfies 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 wires the Kindergarten theme into the host registries. The call -// order matters: the system template + page templates are registered first, -// then schemas are loaded before any block registrations so the schema -// bindings resolve. -func Register(tr templates.TemplateRegistry, br blocks.BlockRegistry) error { - tr.RegisterSystemTemplate(templates.SystemTemplateMeta{ - Key: "kindergarten", - Title: "Kindergarten", - Description: "Primary-colored, hand-lettered theme for schools, daycares, toy shops, museums, and kids' publishers.", - }) - - if err := tr.RegisterPageTemplate("kindergarten", templates.PageTemplateMeta{ - Key: "default", - Title: "Default", - Description: "Standard rounded layout with header, main, footer", - Slots: []string{"header", "main", "footer"}, - }, wrap(RenderKindergarten)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("kindergarten", templates.PageTemplateMeta{ - Key: "landing", - Title: "Landing", - Description: "Mascot-led hero plus stacked feature sections", - Slots: []string{"hero", "main", "cta", "footer"}, - }, wrap(RenderKindergartenLanding)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("kindergarten", templates.PageTemplateMeta{ - Key: "article", - Title: "Story Page", - Description: "Picture-book reading layout for blog posts and stories", - Slots: []string{"header", "main", "aside", "footer"}, - }, wrap(RenderKindergartenArticle)); err != nil { - return err - } - - if err := tr.RegisterPageTemplate("kindergarten", templates.PageTemplateMeta{ - Key: "full-width", - Title: "Full Width", - Description: "Edge-to-edge gallery / classroom showcase", - Slots: []string{"header", "main", "footer"}, - }, wrap(RenderKindergartenFullWidth)); err != nil { - return err - } - - // Schemas must be loaded before block registrations so each Register() - // call can bind to its declared schema. - if err := br.LoadSchemasFromFS(Schemas()); err != nil { - return err - } - - // Theme-owned blocks (eight per spec §8). Registered unqualified; the host - // addresses them as "kindergarten:" downstream. - br.Register(MascotHeroBlockMeta, MascotHeroBlock) - br.Register(AlphabetStripBlockMeta, AlphabetStripBlock) - br.Register(ScheduleBlockMeta, ScheduleBlock) - br.Register(GalleryOfArtBlockMeta, GalleryOfArtBlock) - br.Register(NumbersCounterBlockMeta, NumbersCounterBlock) - br.Register(StorybookQuoteBlockMeta, StorybookQuoteBlock) - br.Register(BigCTABlockMeta, BigCTABlock) - br.Register(FooterBlockMeta, FooterBlock) - - // Built-in overrides (spec §9). Each is scoped to the kindergarten template, - // so they only apply when this theme is active. - br.RegisterTemplateOverride("kindergarten", "heading", KindergartenHeadingBlock) - br.RegisterTemplateOverride("kindergarten", "text", KindergartenTextBlock) - br.RegisterTemplateOverride("kindergarten", "button", KindergartenButtonBlock) - br.RegisterTemplateOverride("kindergarten", "card", KindergartenCardBlock) - - // Branded email wrapper. - tr.RegisterEmailWrapper("kindergarten", KindergartenEmailWrapper) - - return nil -} - -// DefaultMasterPages returns the default master pages that Kindergarten ships. -// Per spec §7, two masters: default-master (used by default + article page -// templates) and landing-master (used by landing + full-width). -func DefaultMasterPages() []plugin.MasterPageDefinition { - return []plugin.MasterPageDefinition{ - { - Key: "kindergarten:default-master", - Title: "Kindergarten Default Master", - PageTemplates: []string{"default", "article"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "navbar", - Title: "Crayon Nav", - Content: map[string]any{"menuName": "main"}, - Slot: "header", - SortOrder: 0, - }, - { - BlockKey: "kindergarten:alphabet_strip", - Title: "ABC Strip", - Content: map[string]any{"letters": "ABCDEFGHIJ", "colorMode": "rainbow"}, - Slot: "header", - SortOrder: 1, - }, - { - BlockKey: "slot", - Title: "Main Slot", - Content: map[string]any{"slotName": "main", "placeholder": "Page content"}, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "kindergarten:footer", - Title: "Friendly Footer", - Content: map[string]any{"showSignup": "true", "mascotName": "Pip"}, - Slot: "footer", - SortOrder: 0, - }, - }, - }, - { - Key: "kindergarten:landing-master", - Title: "Kindergarten Landing Master", - PageTemplates: []string{"landing", "full-width"}, - Blocks: []plugin.MasterPageBlock{ - { - BlockKey: "navbar", - Title: "Crayon Nav", - Content: map[string]any{"menuName": "main"}, - Slot: "header", - SortOrder: 0, - }, - { - BlockKey: "kindergarten:mascot_hero", - Title: "Mascot Hero", - Content: map[string]any{"mascot": "pip", "headline": "Welcome to school!", "tagline": "Big fun, small humans."}, - Slot: "hero", - SortOrder: 0, - }, - { - BlockKey: "slot", - Title: "Main Slot", - Content: map[string]any{"slotName": "main"}, - Slot: "main", - SortOrder: 0, - }, - { - BlockKey: "kindergarten:big_cta", - Title: "Big Yellow CTA", - Content: map[string]any{"label": "Enrol today", "href": "/enrol", "colorVariant": "yellow"}, - Slot: "cta", - SortOrder: 0, - }, - { - BlockKey: "kindergarten:footer", - Title: "Friendly Footer", - Content: map[string]any{"showSignup": "true"}, - Slot: "footer", - SortOrder: 0, - }, - }, - }, - } -} diff --git a/registration.go b/registration.go deleted file mode 100644 index 72e18ba..0000000 --- a/registration.go +++ /dev/null @@ -1,25 +0,0 @@ -package main - -import ( - "io/fs" - "net/http" - - "git.dev.alexdunmow.com/block/core/blocks" - "git.dev.alexdunmow.com/block/core/plugin" - "git.dev.alexdunmow.com/block/core/templates" -) - -// Registration is the compile-time plugin registration for the Kindergarten theme. -var Registration = plugin.PluginRegistration{ - Name: "kindergarten", - Version: plugin.ParseModVersion(pluginModBytes), - Register: func(tr templates.TemplateRegistry, br blocks.BlockRegistry) error { - return Register(tr, br) - }, - Assets: func() http.Handler { return AssetsHandler() }, - Schemas: func() fs.FS { return Schemas() }, - ThemePresets: func() []byte { return ThemePresets() }, - BundledFonts: func() []byte { return BundledFonts() }, - MasterPages: func() []plugin.MasterPageDefinition { return DefaultMasterPages() }, - CSSManifest: func() *plugin.CSSManifest { return ThemeCSSManifest() }, -} diff --git a/schedule.go b/schedule.go deleted file mode 100644 index d1af1a6..0000000 --- a/schedule.go +++ /dev/null @@ -1,53 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// ScheduleBlockMeta defines metadata for the day schedule block. -var ScheduleBlockMeta = blocks.BlockMeta{ - Key: "schedule", - Title: "Day Schedule", - Description: "Daycare/classroom day plan with crayon time-pills.", - Category: blocks.CategoryContent, - Source: "kindergarten", -} - -// ScheduleItem is a single time/activity row. -type ScheduleItem struct { - Time string - Activity string - Icon string -} - -// ScheduleData is the renderer's strongly-typed input. -type ScheduleData struct { - Title string - Items []ScheduleItem -} - -// ScheduleBlock renders the day-schedule block. -// Content shape: {title,items:[{time,activity,icon}]}. -func ScheduleBlock(ctx context.Context, content map[string]any) string { - raw := getSlice(content, "items") - items := make([]ScheduleItem, 0, len(raw)) - for _, m := range raw { - items = append(items, ScheduleItem{ - Time: getString(m, "time"), - Activity: getString(m, "activity"), - Icon: getString(m, "icon"), - }) - } - - data := ScheduleData{ - Title: getString(content, "title"), - Items: items, - } - - var buf bytes.Buffer - _ = scheduleComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/schedule.templ b/schedule.templ deleted file mode 100644 index 0579d25..0000000 --- a/schedule.templ +++ /dev/null @@ -1,60 +0,0 @@ -package main - -// scheduleComponent renders the day schedule. -templ scheduleComponent(data ScheduleData) { -
-
- if data.Title != "" { -

{ data.Title }

- } - if len(data.Items) == 0 { -
No schedule items yet — add a time block to get started.
- } else { -
    - for _, item := range data.Items { -
  1. - - if item.Time != "" { - { item.Time } - } else { - --:-- - } - - - if item.Activity != "" { - { item.Activity } - } else { - Activity - } - - -
  2. - } -
- } -
-
-} - -// scheduleIcon renders a small SVG matching the icon name. Defaults to a star -// shape when the icon is missing or unknown so we never render a broken image. -templ scheduleIcon(name string) { - switch name { - case "sun": - - case "book": - - case "paint": - - case "snack": - - case "play": - - case "nap": - - default: - - } -} diff --git a/schedule_templ.go b/schedule_templ.go deleted file mode 100644 index dd45d07..0000000 --- a/schedule_templ.go +++ /dev/null @@ -1,197 +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" - -// scheduleComponent renders the day schedule. -func scheduleComponent(data ScheduleData) 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: `schedule.templ`, Line: 8, Col: 107} - } - _, 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 len(data.Items) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
No schedule items yet — add a time block to get started.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
    ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, item := range data.Items { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
  1. ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if item.Time != "" { - var templ_7745c5c3_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(item.Time) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `schedule.templ`, Line: 18, Col: 20} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - 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 - } - if item.Activity != "" { - var templ_7745c5c3_Var4 string - templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(item.Activity) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `schedule.templ`, Line: 25, Col: 24} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "Activity") - 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 = scheduleIcon(item.Icon).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
  2. ") - 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 - } - return nil - }) -} - -// scheduleIcon renders a small SVG matching the icon name. Defaults to a star -// shape when the icon is missing or unknown so we never render a broken image. -func scheduleIcon(name 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_Var5 := templ.GetChildren(ctx) - if templ_7745c5c3_Var5 == nil { - templ_7745c5c3_Var5 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - switch name { - case "sun": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "book": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "paint": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "snack": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "play": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - case "nap": - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - default: - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/storybook_quote.go b/storybook_quote.go deleted file mode 100644 index ebea8df..0000000 --- a/storybook_quote.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import ( - "bytes" - "context" - - "git.dev.alexdunmow.com/block/core/blocks" -) - -// StorybookQuoteBlockMeta defines metadata for the storybook quote block. -var StorybookQuoteBlockMeta = blocks.BlockMeta{ - Key: "storybook_quote", - Title: "Storybook Quote", - Description: "Picture-book page treatment for a quote with optional illustration.", - Category: blocks.CategoryContent, - Source: "kindergarten", -} - -// StorybookQuoteData is the renderer input. -type StorybookQuoteData struct { - Quote string - Author string - Illustration string -} - -// StorybookQuoteBlock renders the quote panel. -// Content shape: {quote,author,illustration}. -func StorybookQuoteBlock(ctx context.Context, content map[string]any) string { - data := StorybookQuoteData{ - Quote: getString(content, "quote"), - Author: getString(content, "author"), - Illustration: getString(content, "illustration"), - } - - var buf bytes.Buffer - _ = storybookQuoteComponent(data).Render(ctx, &buf) - return buf.String() -} diff --git a/storybook_quote.templ b/storybook_quote.templ deleted file mode 100644 index 4cd0ed3..0000000 --- a/storybook_quote.templ +++ /dev/null @@ -1,42 +0,0 @@ -package main - -import "git.dev.alexdunmow.com/block/core/blocks" - -// storybookQuoteComponent renders a quote with optional illustration. -templ storybookQuoteComponent(data StorybookQuoteData) { -
-
-
-
- if data.Quote != "" { -

"{ data.Quote }"

- } else { -

Add a quote to inspire your readers.

- } - if data.Author != "" { -
— { data.Author }
- } -
-
- if data.Illustration != "" { - { - } else { - @storybookFallbackIllustration() - } -
-
-
-
-} - -// storybookFallbackIllustration renders a friendly SVG when no illustration -// is supplied. It guarantees a visible, themed graphic instead of a broken -// image icon. -templ storybookFallbackIllustration() { - - - - - - -} diff --git a/storybook_quote_templ.go b/storybook_quote_templ.go deleted file mode 100644 index b9fb0b4..0000000 --- a/storybook_quote_templ.go +++ /dev/null @@ -1,163 +0,0 @@ -// Code generated by templ - DO NOT EDIT. - -// templ: version: v0.3.1020 -package main - -//lint:file-ignore SA4006 This context is only used if a nested component is present. - -import "github.com/a-h/templ" -import templruntime "github.com/a-h/templ/runtime" - -import "git.dev.alexdunmow.com/block/core/blocks" - -// storybookQuoteComponent renders a quote with optional illustration. -func storybookQuoteComponent(data StorybookQuoteData) 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.Quote != "" { - 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.Quote) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `storybook_quote.templ`, Line: 12, Col: 49} - } - _, 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 - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "

Add a quote to inspire your readers.

") - 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_Var3 string - templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(data.Author) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `storybook_quote.templ`, Line: 17, Col: 63} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.Illustration != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\"")") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = storybookFallbackIllustration().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 - } - return nil - }) -} - -// storybookFallbackIllustration renders a friendly SVG when no illustration -// is supplied. It guarantees a visible, themed graphic instead of a broken -// image icon. -func storybookFallbackIllustration() 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_Var6 := templ.GetChildren(ctx) - if templ_7745c5c3_Var6 == nil { - templ_7745c5c3_Var6 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate diff --git a/template.templ b/template.templ deleted file mode 100644 index bf6ab91..0000000 --- a/template.templ +++ /dev/null @@ -1,257 +0,0 @@ -package main - -import ( - "context" - - "git.dev.alexdunmow.com/block/core/templates/bn" -) - -// PageData carries everything the page templates need to render. -type PageData struct { - Title string - Slots map[string]string - ThemeMode string - ThemeCSS string - SiteSettings bn.SiteSettingsData - PageMeta bn.PageMeta - StructuredData string - CSSHash string - PageviewNonce string - EngagementConfig bn.EngagementConfig -} - -// parseKindergartenPageData converts the unstructured doc map the engine -// passes in into the strongly-typed PageData used by the templ components. -func parseKindergartenPageData(doc map[string]any) PageData { - title := "Untitled" - if t, ok := doc["title"].(string); ok { - title = t - } - - slots := make(map[string]string) - if s, ok := doc["slots"].(map[string]string); ok { - slots = s - } - - themeCSS := "" - if tc, ok := doc["theme_css"].(string); ok { - themeCSS = tc - } - - structuredData := "" - if sd, ok := doc["structured_data"].(string); ok { - structuredData = sd - } - - cssHash := "" - if ch, ok := doc["css_hash"].(string); ok { - cssHash = ch - } - - pageviewNonce := "" - if pn, ok := doc["pageview_nonce"].(string); ok { - pageviewNonce = pn - } - - themeMode := "light" - if tm, ok := doc["theme_mode"].(string); ok && tm != "" { - themeMode = tm - } - - siteSettings := bn.ParseSiteSettings(doc) - pageMeta := bn.ParsePageMeta(doc) - engagementConfig := bn.ParseEngagementConfig(doc) - - return PageData{ - Title: title, - Slots: slots, - ThemeMode: themeMode, - ThemeCSS: themeCSS, - SiteSettings: siteSettings, - PageMeta: pageMeta, - StructuredData: structuredData, - CSSHash: cssHash, - PageviewNonce: pageviewNonce, - EngagementConfig: engagementConfig, - } -} - -// pluginStyles is the canonical list of theme stylesheet URLs each page sends to . -var pluginStyles = []string{"/templates/kindergarten/style.css"} - -// Kindergarten — default template. -templ Kindergarten(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: pluginStyles, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
- @templ.Raw(data.Slots["header"]) -
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } else { -
No content blocks assigned to this page.
- } -
-
- @templ.Raw(data.Slots["footer"]) -
- @bn.BodyEnd(data.SiteSettings) - - -} - -// Kindergarten — landing template with mascot hero + CTA strip. -templ KindergartenLanding(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: pluginStyles, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
- @templ.Raw(data.Slots["header"]) -
-
- @templ.Raw(data.Slots["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) - - -} - -// Kindergarten — article (storybook reading) template. -templ KindergartenArticle(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: pluginStyles, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
- @templ.Raw(data.Slots["header"]) -
-
-
- if main, ok := data.Slots["main"]; ok && main != "" { -
- @templ.Raw(main) -
- } else { -
No content yet — start a story.
- } -
- if aside, ok := data.Slots["aside"]; ok && aside != "" { - - } -
-
- @templ.Raw(data.Slots["footer"]) -
- @bn.BodyEnd(data.SiteSettings) - - -} - -// Kindergarten — full-width gallery / showcase template. -templ KindergartenFullWidth(data PageData) { - - - @bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: pluginStyles, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }) - - @bn.AdminBypassBanner(data.SiteSettings) -
- @templ.Raw(data.Slots["header"]) -
-
- if main, ok := data.Slots["main"]; ok && main != "" { - @templ.Raw(main) - } else { -
-
No content blocks assigned to this page.
-
- } -
-
- @templ.Raw(data.Slots["footer"]) -
- @bn.BodyEnd(data.SiteSettings) - - -} - -// Render functions invoked by the registry. - -func RenderKindergarten(ctx context.Context, doc map[string]any) templ.Component { - return Kindergarten(parseKindergartenPageData(doc)) -} - -func RenderKindergartenLanding(ctx context.Context, doc map[string]any) templ.Component { - return KindergartenLanding(parseKindergartenPageData(doc)) -} - -func RenderKindergartenArticle(ctx context.Context, doc map[string]any) templ.Component { - return KindergartenArticle(parseKindergartenPageData(doc)) -} - -func RenderKindergartenFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return KindergartenFullWidth(parseKindergartenPageData(doc)) -} diff --git a/template_templ.go b/template_templ.go deleted file mode 100644 index 35986b2..0000000 --- a/template_templ.go +++ /dev/null @@ -1,529 +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" -) - -// PageData carries everything the page templates need to render. -type PageData struct { - Title string - Slots map[string]string - ThemeMode string - ThemeCSS string - SiteSettings bn.SiteSettingsData - PageMeta bn.PageMeta - StructuredData string - CSSHash string - PageviewNonce string - EngagementConfig bn.EngagementConfig -} - -// parseKindergartenPageData converts the unstructured doc map the engine -// passes in into the strongly-typed PageData used by the templ components. -func parseKindergartenPageData(doc map[string]any) PageData { - title := "Untitled" - if t, ok := doc["title"].(string); ok { - title = t - } - - slots := make(map[string]string) - if s, ok := doc["slots"].(map[string]string); ok { - slots = s - } - - themeCSS := "" - if tc, ok := doc["theme_css"].(string); ok { - themeCSS = tc - } - - structuredData := "" - if sd, ok := doc["structured_data"].(string); ok { - structuredData = sd - } - - cssHash := "" - if ch, ok := doc["css_hash"].(string); ok { - cssHash = ch - } - - pageviewNonce := "" - if pn, ok := doc["pageview_nonce"].(string); ok { - pageviewNonce = pn - } - - themeMode := "light" - if tm, ok := doc["theme_mode"].(string); ok && tm != "" { - themeMode = tm - } - - siteSettings := bn.ParseSiteSettings(doc) - pageMeta := bn.ParsePageMeta(doc) - engagementConfig := bn.ParseEngagementConfig(doc) - - return PageData{ - Title: title, - Slots: slots, - ThemeMode: themeMode, - ThemeCSS: themeCSS, - SiteSettings: siteSettings, - PageMeta: pageMeta, - StructuredData: structuredData, - CSSHash: cssHash, - PageviewNonce: pageviewNonce, - EngagementConfig: engagementConfig, - } -} - -// pluginStyles is the canonical list of theme stylesheet URLs each page sends to . -var pluginStyles = []string{"/templates/kindergarten/style.css"} - -// Kindergarten — default template. -func Kindergarten(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var1 := templ.GetChildren(ctx) - if templ_7745c5c3_Var1 == nil { - templ_7745c5c3_Var1 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: pluginStyles, - StructuredData: data.StructuredData, - CSSHash: data.CSSHash, - PageviewNonce: data.PageviewNonce, - EngagementConfig: data.EngagementConfig, - }).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.AdminBypassBanner(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["header"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templ.Raw(main).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "
No content blocks assigned to this page.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["footer"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// Kindergarten — landing template with mascot hero + CTA strip. -func KindergartenLanding(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var2 := templ.GetChildren(ctx) - if templ_7745c5c3_Var2 == nil { - templ_7745c5c3_Var2 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.Head(bn.HeadData{ - Title: data.Title, - Settings: data.SiteSettings, - PageMeta: data.PageMeta, - ThemeMode: data.ThemeMode, - ThemeCSS: data.ThemeCSS, - PluginStyles: pluginStyles, - 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["header"]).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 - } - 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, 13, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if main, ok := data.Slots["main"]; ok && main != "" { - templ_7745c5c3_Err = templ.Raw(main).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
") - 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, 15, "
") - 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, 16, "
") - 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, 17, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// Kindergarten — article (storybook reading) template. -func KindergartenArticle(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var3 := templ.GetChildren(ctx) - if templ_7745c5c3_Var3 == nil { - templ_7745c5c3_Var3 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "") - 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: pluginStyles, - 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, 19, "") - 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, 20, "
") - 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, 21, "
") - 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, 22, "
") - 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, 23, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
No content yet — start a story.
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if aside, ok := data.Slots["aside"]; ok && aside != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(data.Slots["footer"]).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = bn.BodyEnd(data.SiteSettings).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// Kindergarten — full-width gallery / showcase template. -func KindergartenFullWidth(data PageData) templ.Component { - return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { - templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context - if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { - return templ_7745c5c3_CtxErr - } - templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) - if !templ_7745c5c3_IsBuffer { - defer func() { - templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) - if templ_7745c5c3_Err == nil { - templ_7745c5c3_Err = templ_7745c5c3_BufErr - } - }() - } - ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var4 := templ.GetChildren(ctx) - if templ_7745c5c3_Var4 == nil { - templ_7745c5c3_Var4 = templ.NopComponent - } - ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "") - 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: pluginStyles, - 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, 32, "") - 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, 33, "
") - 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, 34, "
") - 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, 35, "
No content blocks assigned to this page.
") - 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 - } - 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, 37, "
") - 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, 38, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -// Render functions invoked by the registry. - -func RenderKindergarten(ctx context.Context, doc map[string]any) templ.Component { - return Kindergarten(parseKindergartenPageData(doc)) -} - -func RenderKindergartenLanding(ctx context.Context, doc map[string]any) templ.Component { - return KindergartenLanding(parseKindergartenPageData(doc)) -} - -func RenderKindergartenArticle(ctx context.Context, doc map[string]any) templ.Component { - return KindergartenArticle(parseKindergartenPageData(doc)) -} - -func RenderKindergartenFullWidth(ctx context.Context, doc map[string]any) templ.Component { - return KindergartenFullWidth(parseKindergartenPageData(doc)) -} - -var _ = templruntime.GeneratedTemplate diff --git a/templates/email/kindergarten.ninjatpl b/templates/email/kindergarten.ninjatpl new file mode 100644 index 0000000..fc05ee4 --- /dev/null +++ b/templates/email/kindergarten.ninjatpl @@ -0,0 +1,68 @@ + + + + + + + + + {{ site_name }} + + + + {% if preview_text %}
{{ preview_text }}
{% endif %} + + + + +
+ + + + + + + + + + + + + + +
+ + diff --git a/templates/kindergarten/article.ninjatpl b/templates/kindergarten/article.ninjatpl new file mode 100644 index 0000000..7f8e017 --- /dev/null +++ b/templates/kindergarten/article.ninjatpl @@ -0,0 +1,16 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
{{ slots.header|safe }}
+
+
+ {% if slots.main %}
{{ slots.main|safe }}
{% else %}
No content yet — start a story.
{% endif %} +
+ {% if slots.aside %}{% endif %} +
+
{{ slots.footer|safe }}
+ {{ body_end_html|safe }} + + diff --git a/templates/kindergarten/default.ninjatpl b/templates/kindergarten/default.ninjatpl new file mode 100644 index 0000000..9c074c2 --- /dev/null +++ b/templates/kindergarten/default.ninjatpl @@ -0,0 +1,13 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
{{ slots.header|safe }}
+
+ {% if slots.main %}{{ slots.main|safe }}{% else %}
No content blocks assigned to this page.
{% endif %} +
+
{{ slots.footer|safe }}
+ {{ body_end_html|safe }} + + diff --git a/templates/kindergarten/full-width.ninjatpl b/templates/kindergarten/full-width.ninjatpl new file mode 100644 index 0000000..ff0bce7 --- /dev/null +++ b/templates/kindergarten/full-width.ninjatpl @@ -0,0 +1,13 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
{{ slots.header|safe }}
+
+ {% if slots.main %}{{ slots.main|safe }}{% else %}
No content blocks assigned to this page.
{% endif %} +
+
{{ slots.footer|safe }}
+ {{ body_end_html|safe }} + + diff --git a/templates/kindergarten/landing.ninjatpl b/templates/kindergarten/landing.ninjatpl new file mode 100644 index 0000000..18d3b7f --- /dev/null +++ b/templates/kindergarten/landing.ninjatpl @@ -0,0 +1,15 @@ + + +{{ head_html|safe }} + + {{ admin_banner_html|safe }} +
{{ slots.header|safe }}
+
{{ slots.hero|safe }}
+
+ {% if slots.main %}{{ slots.main|safe }}{% endif %} +
+
{{ slots.cta|safe }}
+
{{ slots.footer|safe }}
+ {{ body_end_html|safe }} + + diff --git a/templates/overrides/kindergarten/button.ninjatpl b/templates/overrides/kindergarten/button.ninjatpl new file mode 100644 index 0000000..3dae610 --- /dev/null +++ b/templates/overrides/kindergarten/button.ninjatpl @@ -0,0 +1 @@ +{% if text %}{% set lbl = text %}{% else %}{% set lbl = label %}{% endif %}{% if lbl %}{{ lbl }}{% else %}Add label and link to render this button.{% endif %} diff --git a/templates/overrides/kindergarten/card.ninjatpl b/templates/overrides/kindergarten/card.ninjatpl new file mode 100644 index 0000000..e2e2d1e --- /dev/null +++ b/templates/overrides/kindergarten/card.ninjatpl @@ -0,0 +1 @@ +
{% if title %}

{{ title }}

{% endif %}{% if body %}
{{ body|safe }}
{% endif %}{% if not title and not body %}
Add a title or body to fill this card.
{% endif %}
diff --git a/templates/overrides/kindergarten/heading.ninjatpl b/templates/overrides/kindergarten/heading.ninjatpl new file mode 100644 index 0000000..aaa106d --- /dev/null +++ b/templates/overrides/kindergarten/heading.ninjatpl @@ -0,0 +1 @@ +{% if step|integer >= 1 and step|integer <= 9 %}
{% endif %}{% 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 %}{% if step|integer >= 1 and step|integer <= 9 %}
{% endif %} diff --git a/templates/overrides/kindergarten/text.ninjatpl b/templates/overrides/kindergarten/text.ninjatpl new file mode 100644 index 0000000..2e1cfd7 --- /dev/null +++ b/templates/overrides/kindergarten/text.ninjatpl @@ -0,0 +1 @@ +
{{ text|safe }}
diff --git a/text_override.go b/text_override.go deleted file mode 100644 index 8e6da6b..0000000 --- a/text_override.go +++ /dev/null @@ -1,17 +0,0 @@ -package main - -import ( - "bytes" - "context" -) - -// KindergartenTextBlock renders text with Nunito body, 1.7 line-height, -// and the rounded ::selection highlight in primary yellow. -func KindergartenTextBlock(ctx context.Context, content map[string]any) string { - text := getString(content, "text") - class := getString(content, "class") - - var buf bytes.Buffer - _ = kgTextComponent(text, class).Render(ctx, &buf) - return buf.String() -} diff --git a/text_override.templ b/text_override.templ deleted file mode 100644 index 989e066..0000000 --- a/text_override.templ +++ /dev/null @@ -1,9 +0,0 @@ -package main - -// kgTextComponent renders rich text body styled to match the Kindergarten -// reading rhythm. -templ kgTextComponent(text, class string) { -
- @templ.Raw(text) -
-} diff --git a/text_override_templ.go b/text_override_templ.go deleted file mode 100644 index b388ef9..0000000 --- a/text_override_templ.go +++ /dev/null @@ -1,68 +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" - -// kgTextComponent renders rich text body styled to match the Kindergarten -// reading rhythm. -func kgTextComponent(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{"kg-text", class} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templ.Raw(text).Render(ctx, templ_7745c5c3_Buffer) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - return nil - }) -} - -var _ = templruntime.GeneratedTemplate