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>
83 lines
2.5 KiB
Plaintext
83 lines
2.5 KiB
Plaintext
package main
|
|
|
|
// impactMetricsComponent renders a row of impact metrics with optional botanical illustration.
|
|
templ impactMetricsComponent(data ImpactMetricsData) {
|
|
<section
|
|
data-block="earthen:impact_metrics"
|
|
data-empty?={ data.Empty }
|
|
class="earthen-impact-metrics py-16 px-4"
|
|
style="background-color: hsl(var(--background)); color: hsl(var(--foreground));"
|
|
>
|
|
<div class="max-w-5xl mx-auto">
|
|
if data.Title != "" {
|
|
<h2
|
|
class="earthen-display text-3xl md:text-4xl text-center mb-12"
|
|
style={ "font-family: var(--font-heading, \"Fraunces\", \"Playfair Display\", Georgia, serif); color: hsl(var(--primary));" }
|
|
>
|
|
{ data.Title }
|
|
</h2>
|
|
}
|
|
if data.Illustration != "" {
|
|
<div class="flex justify-center mb-8">
|
|
<img src={ resolveMedia(data.Illustration) } alt="" class="max-h-40 object-contain"/>
|
|
</div>
|
|
} else if data.Title != "" || len(data.Metrics) > 0 {
|
|
<div class="flex justify-center mb-8">
|
|
@botanicalGlyph("fern", 64)
|
|
</div>
|
|
}
|
|
if len(data.Metrics) > 0 {
|
|
<div class={ "grid gap-8", metricGridCols(len(data.Metrics)) }>
|
|
for _, m := range data.Metrics {
|
|
<div class="text-center px-4">
|
|
<div
|
|
class="earthen-display text-5xl font-semibold mb-2"
|
|
style={ "font-family: var(--font-heading, \"Fraunces\", \"Playfair Display\", Georgia, serif); color: hsl(var(--accent));" }
|
|
>
|
|
{ m.Value }{ m.Suffix }
|
|
</div>
|
|
<div
|
|
class="earthen-body uppercase tracking-wider text-sm"
|
|
style={ "font-family: var(--font-body, \"Spectral\", Georgia, serif); color: hsl(var(--muted-foreground));" }
|
|
>
|
|
{ m.Label }
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
} else {
|
|
<p
|
|
class="text-center"
|
|
style="color: hsl(var(--muted-foreground));"
|
|
>
|
|
Add impact metrics to bring this section to life.
|
|
</p>
|
|
}
|
|
</div>
|
|
</section>
|
|
}
|
|
|
|
// metricGridCols returns the responsive grid class for metric count.
|
|
func metricGridCols(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"
|
|
}
|
|
}
|
|
|
|
// resolveMedia rewrites a media reference to its served URL. The wave-1
|
|
// implementation passes the path through verbatim and is wired so admins
|
|
// can drop in their own media adapter later without touching templates.
|
|
func resolveMedia(path string) string {
|
|
if path == "" {
|
|
return ""
|
|
}
|
|
return path
|
|
}
|