Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/brutalist. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
189 lines
6.5 KiB
Plaintext
189 lines
6.5 KiB
Plaintext
package main
|
|
|
|
import (
|
|
"context"
|
|
|
|
"git.dev.alexdunmow.com/block/core/templates/bn"
|
|
)
|
|
|
|
// Brutalist default page template: header / 12-col body / colophon footer.
|
|
templ Brutalist(data PageData) {
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
@bn.Head(bn.HeadData{
|
|
Title: data.Title,
|
|
Settings: data.SiteSettings,
|
|
PageMeta: data.PageMeta,
|
|
ThemeMode: data.ThemeMode,
|
|
ThemeCSS: data.ThemeCSS,
|
|
PluginStyles: []string{"/templates/brutalist/style.css"},
|
|
StructuredData: data.StructuredData,
|
|
CSSHash: data.CSSHash,
|
|
PageviewNonce: data.PageviewNonce,
|
|
EngagementConfig: data.EngagementConfig,
|
|
})
|
|
<body class="brutalist-page antialiased min-h-screen flex flex-col" data-brutalist-template="default">
|
|
@bn.AdminBypassBanner(data.SiteSettings)
|
|
<header class="w-full" style="border-bottom: 1px solid hsl(var(--border));">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 0 1.5rem;">
|
|
@templ.Raw(data.Slots["header"])
|
|
</div>
|
|
</header>
|
|
<main class="flex-grow w-full">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 2rem 1.5rem 4rem;">
|
|
if main, ok := data.Slots["main"]; ok && main != "" {
|
|
@templ.Raw(main)
|
|
} else {
|
|
<p class="brutalist-mono" style="color: hsl(var(--muted-foreground)); padding: 4rem 0;">NO CONTENT BLOCKS ASSIGNED TO THIS PAGE.</p>
|
|
}
|
|
</div>
|
|
</main>
|
|
<footer class="w-full mt-auto">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 0 1.5rem;">
|
|
@templ.Raw(data.Slots["footer"])
|
|
</div>
|
|
</footer>
|
|
@bn.BodyEnd(data.SiteSettings)
|
|
</body>
|
|
</html>
|
|
}
|
|
|
|
// BrutalistLanding: oversized headline + project ledger.
|
|
templ BrutalistLanding(data PageData) {
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
@bn.Head(bn.HeadData{
|
|
Title: data.Title,
|
|
Settings: data.SiteSettings,
|
|
PageMeta: data.PageMeta,
|
|
ThemeMode: data.ThemeMode,
|
|
ThemeCSS: data.ThemeCSS,
|
|
PluginStyles: []string{"/templates/brutalist/style.css"},
|
|
StructuredData: data.StructuredData,
|
|
CSSHash: data.CSSHash,
|
|
PageviewNonce: data.PageviewNonce,
|
|
EngagementConfig: data.EngagementConfig,
|
|
})
|
|
<body class="brutalist-page antialiased min-h-screen flex flex-col" data-brutalist-template="landing">
|
|
@bn.AdminBypassBanner(data.SiteSettings)
|
|
<section class="w-full">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 0 1.5rem;">
|
|
@templ.Raw(data.Slots["hero"])
|
|
</div>
|
|
</section>
|
|
<main class="flex-grow w-full">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 2rem 1.5rem;">
|
|
if ledger, ok := data.Slots["ledger"]; ok && ledger != "" {
|
|
@templ.Raw(ledger)
|
|
}
|
|
</div>
|
|
</main>
|
|
<footer class="w-full mt-auto">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 0 1.5rem;">
|
|
@templ.Raw(data.Slots["footer"])
|
|
</div>
|
|
</footer>
|
|
@bn.BodyEnd(data.SiteSettings)
|
|
</body>
|
|
</html>
|
|
}
|
|
|
|
// BrutalistArticle: case study with metadata strip.
|
|
templ BrutalistArticle(data PageData) {
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
@bn.Head(bn.HeadData{
|
|
Title: data.Title,
|
|
Settings: data.SiteSettings,
|
|
PageMeta: data.PageMeta,
|
|
ThemeMode: data.ThemeMode,
|
|
ThemeCSS: data.ThemeCSS,
|
|
PluginStyles: []string{"/templates/brutalist/style.css"},
|
|
StructuredData: data.StructuredData,
|
|
CSSHash: data.CSSHash,
|
|
PageviewNonce: data.PageviewNonce,
|
|
EngagementConfig: data.EngagementConfig,
|
|
})
|
|
<body class="brutalist-page antialiased min-h-screen flex flex-col" data-brutalist-template="article">
|
|
@bn.AdminBypassBanner(data.SiteSettings)
|
|
<header class="w-full" style="border-bottom: 1px solid hsl(var(--border));">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 0 1.5rem;">
|
|
@templ.Raw(data.Slots["header"])
|
|
</div>
|
|
</header>
|
|
<section class="w-full">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 1rem 1.5rem;">
|
|
@templ.Raw(data.Slots["meta"])
|
|
</div>
|
|
</section>
|
|
<main class="flex-grow w-full">
|
|
<article class="brutalist-shell" style="max-width: 60rem; margin: 0 auto; padding: 2rem 1.5rem 4rem;">
|
|
if main, ok := data.Slots["main"]; ok && main != "" {
|
|
@templ.Raw(main)
|
|
}
|
|
</article>
|
|
</main>
|
|
<footer class="w-full mt-auto">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 0 1.5rem;">
|
|
@templ.Raw(data.Slots["footer"])
|
|
</div>
|
|
</footer>
|
|
@bn.BodyEnd(data.SiteSettings)
|
|
</body>
|
|
</html>
|
|
}
|
|
|
|
// BrutalistFullWidth: edge-to-edge gallery layout.
|
|
templ BrutalistFullWidth(data PageData) {
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
@bn.Head(bn.HeadData{
|
|
Title: data.Title,
|
|
Settings: data.SiteSettings,
|
|
PageMeta: data.PageMeta,
|
|
ThemeMode: data.ThemeMode,
|
|
ThemeCSS: data.ThemeCSS,
|
|
PluginStyles: []string{"/templates/brutalist/style.css"},
|
|
StructuredData: data.StructuredData,
|
|
CSSHash: data.CSSHash,
|
|
PageviewNonce: data.PageviewNonce,
|
|
EngagementConfig: data.EngagementConfig,
|
|
})
|
|
<body class="brutalist-page antialiased min-h-screen flex flex-col" data-brutalist-template="full-width">
|
|
@bn.AdminBypassBanner(data.SiteSettings)
|
|
<header class="w-full" style="border-bottom: 1px solid hsl(var(--border));">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 0 1.5rem;">
|
|
@templ.Raw(data.Slots["header"])
|
|
</div>
|
|
</header>
|
|
<main class="flex-grow w-full">
|
|
if main, ok := data.Slots["main"]; ok && main != "" {
|
|
@templ.Raw(main)
|
|
}
|
|
</main>
|
|
<footer class="w-full mt-auto">
|
|
<div class="brutalist-shell" style="max-width: 90rem; margin: 0 auto; padding: 0 1.5rem;">
|
|
@templ.Raw(data.Slots["footer"])
|
|
</div>
|
|
</footer>
|
|
@bn.BodyEnd(data.SiteSettings)
|
|
</body>
|
|
</html>
|
|
}
|
|
|
|
func RenderBrutalist(ctx context.Context, doc map[string]any) templ.Component {
|
|
return Brutalist(parseBrutalistPageData(doc))
|
|
}
|
|
|
|
func RenderBrutalistLanding(ctx context.Context, doc map[string]any) templ.Component {
|
|
return BrutalistLanding(parseBrutalistPageData(doc))
|
|
}
|
|
|
|
func RenderBrutalistArticle(ctx context.Context, doc map[string]any) templ.Component {
|
|
return BrutalistArticle(parseBrutalistPageData(doc))
|
|
}
|
|
|
|
func RenderBrutalistFullWidth(ctx context.Context, doc map[string]any) templ.Component {
|
|
return BrutalistFullWidth(parseBrutalistPageData(doc))
|
|
}
|