Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/earthen. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
105 lines
3.1 KiB
Plaintext
105 lines
3.1 KiB
Plaintext
package main
|
|
|
|
// footerComponent renders the cream-on-moss footer with optional newsletter and link columns.
|
|
templ footerComponent(data FooterData) {
|
|
<div
|
|
data-block="earthen:footer"
|
|
data-empty?={ data.Empty }
|
|
class="earthen-footer w-full"
|
|
style="background-color: hsl(var(--primary)); color: hsl(var(--primary-foreground));"
|
|
>
|
|
<div class="max-w-6xl mx-auto px-6 py-16">
|
|
<div class="botanical-rule flex items-center gap-4 mb-10" aria-hidden="true">
|
|
<span class="flex-1 h-px" style="background-color: hsl(var(--primary-foreground) / 0.3);"></span>
|
|
@botanicalGlyph("fern", 32)
|
|
<span class="flex-1 h-px" style="background-color: hsl(var(--primary-foreground) / 0.3);"></span>
|
|
</div>
|
|
if data.Tagline != "" {
|
|
<p
|
|
class="earthen-display text-2xl md:text-3xl text-center mb-10"
|
|
style={ "font-family: var(--font-heading, \"Fraunces\", \"Playfair Display\", Georgia, serif);" }
|
|
>
|
|
{ data.Tagline }
|
|
</p>
|
|
}
|
|
if data.ShowNewsletter {
|
|
<form class="max-w-xl mx-auto mb-12 flex flex-col sm:flex-row gap-3">
|
|
<label class="sr-only" for="earthen-footer-email">Email address</label>
|
|
<input
|
|
id="earthen-footer-email"
|
|
type="email"
|
|
placeholder="you@example.org"
|
|
class="flex-1 rounded-lg px-4 py-3 text-base"
|
|
style="background-color: hsl(var(--primary-foreground) / 0.1); color: hsl(var(--primary-foreground)); border: 1px solid hsl(var(--primary-foreground) / 0.3);"
|
|
/>
|
|
<button
|
|
type="submit"
|
|
class="rounded-lg px-6 py-3 font-semibold"
|
|
style="background-color: hsl(var(--accent)); color: hsl(var(--accent-foreground));"
|
|
>
|
|
Subscribe
|
|
</button>
|
|
</form>
|
|
}
|
|
if len(data.Columns) > 0 {
|
|
<div class={ "grid gap-8 mb-10", footerGridCols(len(data.Columns)) }>
|
|
for _, col := range data.Columns {
|
|
<div>
|
|
if col.Title != "" {
|
|
<h4
|
|
class="earthen-display text-lg mb-4"
|
|
style={ "font-family: var(--font-heading, \"Fraunces\", \"Playfair Display\", Georgia, serif);" }
|
|
>
|
|
{ col.Title }
|
|
</h4>
|
|
}
|
|
if len(col.Links) > 0 {
|
|
<ul class="space-y-2">
|
|
for _, link := range col.Links {
|
|
<li>
|
|
<a
|
|
href={ templ.SafeURL(footerLinkURL(link.URL)) }
|
|
class="earthen-footer-link transition-colors"
|
|
style="color: hsl(var(--primary-foreground) / 0.85);"
|
|
>
|
|
{ link.Text }
|
|
</a>
|
|
</li>
|
|
}
|
|
</ul>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
<div
|
|
class="text-center text-sm pt-6"
|
|
style="border-top: 1px solid hsl(var(--primary-foreground) / 0.2); color: hsl(var(--primary-foreground) / 0.7);"
|
|
>
|
|
<span>Rooted in place. Made with care.</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
|
|
// footerGridCols returns a responsive grid class for the footer column count.
|
|
func footerGridCols(count int) string {
|
|
switch count {
|
|
case 1:
|
|
return "grid-cols-1"
|
|
case 2:
|
|
return "grid-cols-1 sm:grid-cols-2"
|
|
case 3:
|
|
return "grid-cols-1 sm:grid-cols-3"
|
|
default:
|
|
return "grid-cols-2 lg:grid-cols-4"
|
|
}
|
|
}
|
|
|
|
func footerLinkURL(url string) string {
|
|
if url == "" {
|
|
return "#"
|
|
}
|
|
return url
|
|
}
|