Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously an unversioned directory inside ~/src/blockninja-themes/noir. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
88 lines
2.8 KiB
Plaintext
88 lines
2.8 KiB
Plaintext
package main
|
|
|
|
// noirHeadingComponent renders a heading using the display-serif font slot.
|
|
templ noirHeadingComponent(level int, text, textClass string) {
|
|
switch level {
|
|
case 1:
|
|
<h1 class={ "noir-display", textClass } style="font-size: clamp(2.5rem, 5vw, 4rem); line-height: 1.05; letter-spacing: 0.005em; color: hsl(var(--foreground));">
|
|
{ text }
|
|
</h1>
|
|
case 2:
|
|
<h2 class={ "noir-display", textClass } style="font-size: clamp(2rem, 4vw, 3rem); line-height: 1.1; color: hsl(var(--foreground));">
|
|
{ text }
|
|
</h2>
|
|
case 3:
|
|
<h3 class={ "noir-display", textClass } style="font-size: clamp(1.5rem, 3vw, 2.25rem); line-height: 1.2; color: hsl(var(--foreground));">
|
|
{ text }
|
|
</h3>
|
|
case 4:
|
|
<h4 class={ "noir-display", textClass } style="font-size: 1.5rem; color: hsl(var(--foreground));">
|
|
{ text }
|
|
</h4>
|
|
case 5:
|
|
<h5 class={ "noir-display", textClass } style="font-size: 1.25rem; color: hsl(var(--foreground));">
|
|
{ text }
|
|
</h5>
|
|
case 6:
|
|
<h6 class={ "noir-display", textClass } style="font-size: 1.125rem; color: hsl(var(--foreground));">
|
|
{ text }
|
|
</h6>
|
|
default:
|
|
<h2 class={ "noir-display", textClass } style="font-size: clamp(2rem, 4vw, 3rem); line-height: 1.1; color: hsl(var(--foreground));">
|
|
{ text }
|
|
</h2>
|
|
}
|
|
}
|
|
|
|
// noirTextComponent renders text with the humanist sans family and generous leading.
|
|
// The body family resolves through --font-body; the surrounding .noir-page already
|
|
// supplies the fallback stack from style.css, so we only need spacing here.
|
|
templ noirTextComponent(text, class string) {
|
|
<div class={ "noir-text", class } style="line-height: 1.7; color: hsl(var(--foreground)); max-width: 65ch;">
|
|
@templ.Raw(text)
|
|
</div>
|
|
}
|
|
|
|
// noirImageComponent renders an image full-bleed within its container with a mono caption.
|
|
templ noirImageComponent(src, alt, caption string) {
|
|
<figure class="noir-figure bleed">
|
|
if src != "" {
|
|
<img src={ src } alt={ alt } loading="lazy" class="w-full h-auto block"/>
|
|
}
|
|
if caption != "" {
|
|
<figcaption class="tracked-mono mt-2 px-6" style="color: hsl(var(--mutedForeground));">
|
|
{ caption }
|
|
</figcaption>
|
|
}
|
|
</figure>
|
|
}
|
|
|
|
// noirButtonComponent renders the hairline outline button.
|
|
templ noirButtonComponent(text, href string) {
|
|
if href != "" {
|
|
<a href={ templ.SafeURL(href) } class="noir-btn">
|
|
{ text }
|
|
</a>
|
|
} else {
|
|
<button type="button" class="noir-btn">
|
|
{ text }
|
|
</button>
|
|
}
|
|
}
|
|
|
|
// noirCardComponent renders the transparent hairline-bordered card.
|
|
templ noirCardComponent(title, body string) {
|
|
<div class="noir-card" style="padding: 1.5rem;">
|
|
if title != "" {
|
|
<h3 class="noir-display" style="font-size: 1.5rem; margin-bottom: 0.75rem; color: hsl(var(--foreground));">
|
|
{ title }
|
|
</h3>
|
|
}
|
|
if body != "" {
|
|
<div style="color: hsl(var(--foreground)); line-height: 1.6;">
|
|
@templ.Raw(body)
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|