feat: enhance HeroBlock with SPA navigation for anchor links and update feature card styles

This commit is contained in:
2026-02-27 13:58:46 +00:00
parent d1ef9800f1
commit 18b5af5617
4 changed files with 71 additions and 16 deletions

View File

@@ -29,15 +29,21 @@
"headline": "Was dieses Template kann", "headline": "Was dieses Template kann",
"tagline": "Features", "tagline": "Features",
"anchorId": "features", "anchorId": "features",
"padding": { "top": "lg", "bottom": "lg" }, "padding": {
"text": "<div class='grid gap-8 sm:grid-cols-2 lg:grid-cols-3'><div class='feature-card'><div class='feature-icon'>⚡</div><h3>Svelte 5 Runes</h3><p>Reaktives UI mit $state, $derived und $effect — kein Boilerplate, maximale Performance.</p></div><div class='feature-card'><div class='feature-icon'>🎨</div><h3>Tailwind CSS 4</h3><p>Utility-first Styling mit Custom-Theme, Dark-Mode-ready und blitzschnellen Builds.</p></div><div class='feature-card'><div class='feature-icon'>🔌</div><h3>Tibi CMS API</h3><p>Collections, Hooks, Medialib — alles über eine REST-API. Mit Mock-Modus für offline-Entwicklung.</p></div><div class='feature-card'><div class='feature-icon'>🌍</div><h3>i18n Built-in</h3><p>Mehrsprachigkeit aus der Box: URL-basierte Sprachauswahl, Lazy-Loaded Locales, SSR-kompatibel.</p></div><div class='feature-card'><div class='feature-icon'>🖥️</div><h3>SSR via goja</h3><p>Server-Side Rendering in Go — schnelle Erstauslieferung, SEO-freundlich, mit Cache-Invalidierung.</p></div><div class='feature-card'><div class='feature-icon'>🧪</div><h3>Playwright Tests</h3><p>E2E, API, Visual Regression und Video-Tours — alles vorkonfiguriert und ready to go.</p></div></div>" "top": "lg",
"bottom": "lg"
},
"text": "<div class='grid gap-8 sm:grid-cols-2 lg:grid-cols-3'><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\"/></svg></div><h3>Svelte 5 Runes</h3><p>Reaktives UI mit $state, $derived und $effect — kein Boilerplate, maximale Performance.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.93 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.04-.23-.29-.38-.63-.38-1.01 0-.83.67-1.5 1.5-1.5H16c3.31 0 6-2.69 6-6 0-5.17-4.49-9-10-9z\"/><circle cx=\"7.5\" cy=\"11.5\" r=\"1.5\"/><circle cx=\"10.5\" cy=\"7.5\" r=\"1.5\"/><circle cx=\"14.5\" cy=\"7.5\" r=\"1.5\"/><circle cx=\"17.5\" cy=\"11.5\" r=\"1.5\"/></svg></div><h3>Tailwind CSS 4</h3><p>Utility-first Styling mit Custom-Theme, Dark-Mode-ready und blitzschnellen Builds.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 22v-5\"/><path d=\"M9 8V2\"/><path d=\"M15 8V2\"/><path d=\"M18 8v5a6 6 0 0 1-12 0V8h12z\"/></svg></div><h3>Tibi CMS API</h3><p>Collections, Hooks, Medialib — alles über eine REST-API. Mit Mock-Modus für offline-Entwicklung.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M2 12h20\"/><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/></svg></div><h3>i18n Built-in</h3><p>Mehrsprachigkeit aus der Box: URL-basierte Sprachauswahl, Lazy-Loaded Locales, SSR-kompatibel.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\"/><path d=\"M8 21h8\"/><path d=\"M12 17v4\"/></svg></div><h3>SSR via goja</h3><p>Server-Side Rendering in Go — schnelle Erstauslieferung, SEO-freundlich, mit Cache-Invalidierung.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M9 2h6\"/><path d=\"M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.578A1 1 0 0 0 5.598 22h12.804a1 1 0 0 0 .878-1.422l-5.069-10.155A2 2 0 0 1 14 9.527V2\"/></svg></div><h3>Playwright Tests</h3><p>E2E, API, Visual Regression und Video-Tours — alles vorkonfiguriert und ready to go.</p></div></div>"
}, },
{ {
"type": "richtext", "type": "richtext",
"headline": "So funktioniert's", "headline": "So funktioniert's",
"tagline": "Workflow", "tagline": "Workflow",
"anchorId": "workflow", "anchorId": "workflow",
"padding": { "top": "lg", "bottom": "sm" }, "padding": {
"top": "lg",
"bottom": "sm"
},
"externalImageUrl": "https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=800&q=80", "externalImageUrl": "https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=800&q=80",
"imagePosition": "right", "imagePosition": "right",
"text": "<p>Starte die Entwicklungsumgebung mit <code>make docker-up && make docker-start</code>. Der esbuild-Watcher kompiliert Änderungen in Echtzeit, BrowserSync lädt den Browser automatisch neu.</p><p>Für Offline-Entwicklung aktiviere den Mock-Modus mit <code>MOCK=1</code> in der <code>.env</code>. Content wird über die Tibi-API geladen und mit dem BlockRenderer dargestellt.</p><p>Jeder Block-Typ (Hero, Richtext, Accordion, Features) ist eine eigene Svelte-Komponente — <strong>erweiterbar und austauschbar</strong>.</p>" "text": "<p>Starte die Entwicklungsumgebung mit <code>make docker-up && make docker-start</code>. Der esbuild-Watcher kompiliert Änderungen in Echtzeit, BrowserSync lädt den Browser automatisch neu.</p><p>Für Offline-Entwicklung aktiviere den Mock-Modus mit <code>MOCK=1</code> in der <code>.env</code>. Content wird über die Tibi-API geladen und mit dem BlockRenderer dargestellt.</p><p>Jeder Block-Typ (Hero, Richtext, Accordion, Features) ist eine eigene Svelte-Komponente — <strong>erweiterbar und austauschbar</strong>.</p>"
@@ -47,7 +53,10 @@
"headline": "Häufige Fragen", "headline": "Häufige Fragen",
"tagline": "FAQ", "tagline": "FAQ",
"anchorId": "faq", "anchorId": "faq",
"padding": { "top": "sm", "bottom": "lg" }, "padding": {
"top": "sm",
"bottom": "lg"
},
"accordionItems": [ "accordionItems": [
{ {
"question": "Wie starte ich ein neues Projekt mit diesem Template?", "question": "Wie starte ich ein neues Projekt mit diesem Template?",
@@ -105,15 +114,21 @@
"headline": "What this template offers", "headline": "What this template offers",
"tagline": "Features", "tagline": "Features",
"anchorId": "features", "anchorId": "features",
"padding": { "top": "lg", "bottom": "lg" }, "padding": {
"text": "<div class='grid gap-8 sm:grid-cols-2 lg:grid-cols-3'><div class='feature-card'><div class='feature-icon'>⚡</div><h3>Svelte 5 Runes</h3><p>Reactive UI with $state, $derived and $effect — no boilerplate, maximum performance.</p></div><div class='feature-card'><div class='feature-icon'>🎨</div><h3>Tailwind CSS 4</h3><p>Utility-first styling with custom theme, dark-mode-ready and blazing fast builds.</p></div><div class='feature-card'><div class='feature-icon'>🔌</div><h3>Tibi CMS API</h3><p>Collections, hooks, media library — all via REST API. With mock mode for offline development.</p></div><div class='feature-card'><div class='feature-icon'>🌍</div><h3>Built-in i18n</h3><p>Multi-language out of the box: URL-based language selection, lazy-loaded locales, SSR-compatible.</p></div><div class='feature-card'><div class='feature-icon'>🖥️</div><h3>SSR via goja</h3><p>Server-side rendering in Go — fast initial delivery, SEO-friendly, with cache invalidation.</p></div><div class='feature-card'><div class='feature-icon'>🧪</div><h3>Playwright Tests</h3><p>E2E, API, visual regression and video tours — all preconfigured and ready to go.</p></div></div>" "top": "lg",
"bottom": "lg"
},
"text": "<div class='grid gap-8 sm:grid-cols-2 lg:grid-cols-3'><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\"/></svg></div><h3>Svelte 5 Runes</h3><p>Reactive UI with $state, $derived and $effect — no boilerplate, maximum performance.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.93 0 1.5-.67 1.5-1.5 0-.39-.15-.74-.39-1.04-.23-.29-.38-.63-.38-1.01 0-.83.67-1.5 1.5-1.5H16c3.31 0 6-2.69 6-6 0-5.17-4.49-9-10-9z\"/><circle cx=\"7.5\" cy=\"11.5\" r=\"1.5\"/><circle cx=\"10.5\" cy=\"7.5\" r=\"1.5\"/><circle cx=\"14.5\" cy=\"7.5\" r=\"1.5\"/><circle cx=\"17.5\" cy=\"11.5\" r=\"1.5\"/></svg></div><h3>Tailwind CSS 4</h3><p>Utility-first styling with custom theme, dark-mode-ready and blazing fast builds.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12 22v-5\"/><path d=\"M9 8V2\"/><path d=\"M15 8V2\"/><path d=\"M18 8v5a6 6 0 0 1-12 0V8h12z\"/></svg></div><h3>Tibi CMS API</h3><p>Collections, hooks, media library — all via REST API. With mock mode for offline development.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M2 12h20\"/><path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/></svg></div><h3>Built-in i18n</h3><p>Multi-language out of the box: URL-based language selection, lazy-loaded locales, SSR-compatible.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"2\" y=\"3\" width=\"20\" height=\"14\" rx=\"2\"/><path d=\"M8 21h8\"/><path d=\"M12 17v4\"/></svg></div><h3>SSR via goja</h3><p>Server-side rendering in Go — fast initial delivery, SEO-friendly, with cache invalidation.</p></div><div class='feature-card'><div class='feature-icon'><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M9 2h6\"/><path d=\"M10 2v7.527a2 2 0 0 1-.211.896L4.72 20.578A1 1 0 0 0 5.598 22h12.804a1 1 0 0 0 .878-1.422l-5.069-10.155A2 2 0 0 1 14 9.527V2\"/></svg></div><h3>Playwright Tests</h3><p>E2E, API, visual regression and video tours — all preconfigured and ready to go.</p></div></div>"
}, },
{ {
"type": "richtext", "type": "richtext",
"headline": "How it works", "headline": "How it works",
"tagline": "Workflow", "tagline": "Workflow",
"anchorId": "workflow", "anchorId": "workflow",
"padding": { "top": "lg", "bottom": "sm" }, "padding": {
"top": "lg",
"bottom": "sm"
},
"externalImageUrl": "https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=800&q=80", "externalImageUrl": "https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=800&q=80",
"imagePosition": "right", "imagePosition": "right",
"text": "<p>Start the dev environment with <code>make docker-up && make docker-start</code>. The esbuild watcher compiles changes in real-time, BrowserSync auto-reloads the browser.</p><p>For offline development, enable mock mode with <code>MOCK=1</code> in <code>.env</code>. Content is loaded via the Tibi API and rendered with the BlockRenderer.</p><p>Each block type (Hero, Richtext, Accordion, Features) is its own Svelte component — <strong>extensible and swappable</strong>.</p>" "text": "<p>Start the dev environment with <code>make docker-up && make docker-start</code>. The esbuild watcher compiles changes in real-time, BrowserSync auto-reloads the browser.</p><p>For offline development, enable mock mode with <code>MOCK=1</code> in <code>.env</code>. Content is loaded via the Tibi API and rendered with the BlockRenderer.</p><p>Each block type (Hero, Richtext, Accordion, Features) is its own Svelte component — <strong>extensible and swappable</strong>.</p>"
@@ -123,7 +138,10 @@
"headline": "Frequently Asked Questions", "headline": "Frequently Asked Questions",
"tagline": "FAQ", "tagline": "FAQ",
"anchorId": "faq", "anchorId": "faq",
"padding": { "top": "sm", "bottom": "lg" }, "padding": {
"top": "sm",
"bottom": "lg"
},
"accordionItems": [ "accordionItems": [
{ {
"question": "How do I start a new project with this template?", "question": "How do I start a new project with this template?",
@@ -174,13 +192,19 @@
{ {
"type": "richtext", "type": "richtext",
"headline": "Warum dieses Template?", "headline": "Warum dieses Template?",
"padding": { "top": "lg", "bottom": "md" }, "padding": {
"top": "lg",
"bottom": "md"
},
"text": "<p>Das Tibi Svelte Starter vereint bewährte Patterns aus dutzenden Projekten in einem sofort einsetzbaren Fundament:</p><ul><li><strong>API-Layer</strong> mit Request-Deduplication, Loading-States und Caching</li><li><strong>Widget-Bibliothek</strong> mit Button, Input, Select, Carousel, Pagination und mehr</li><li><strong>Block-Rendering</strong> für CMS-gesteuerte Seiten mit beliebig erweiterbaren Typen</li><li><strong>Testing-Setup</strong> mit Playwright für E2E, API und visuelle Regressionstests</li></ul>" "text": "<p>Das Tibi Svelte Starter vereint bewährte Patterns aus dutzenden Projekten in einem sofort einsetzbaren Fundament:</p><ul><li><strong>API-Layer</strong> mit Request-Deduplication, Loading-States und Caching</li><li><strong>Widget-Bibliothek</strong> mit Button, Input, Select, Carousel, Pagination und mehr</li><li><strong>Block-Rendering</strong> für CMS-gesteuerte Seiten mit beliebig erweiterbaren Typen</li><li><strong>Testing-Setup</strong> mit Playwright für E2E, API und visuelle Regressionstests</li></ul>"
}, },
{ {
"type": "richtext", "type": "richtext",
"headline": "Technologie-Stack", "headline": "Technologie-Stack",
"padding": { "top": "md", "bottom": "lg" }, "padding": {
"top": "md",
"bottom": "lg"
},
"externalImageUrl": "https://images.unsplash.com/photo-1461749280684-dccba630e2f6?w=800&q=80", "externalImageUrl": "https://images.unsplash.com/photo-1461749280684-dccba630e2f6?w=800&q=80",
"imagePosition": "left", "imagePosition": "left",
"text": "<p>Jede Komponente wurde sorgfältig ausgewählt:</p><ul><li><strong>Svelte 5</strong> — Reaktives Framework mit Runes-API</li><li><strong>Tailwind CSS 4</strong> — Utility-first CSS mit @theme</li><li><strong>esbuild</strong> — Extrem schneller Bundler</li><li><strong>Tibi CMS</strong> — Headless CMS mit Go-Backend</li><li><strong>goja SSR</strong> — Server-Side Rendering in Go</li><li><strong>Playwright</strong> — Modernes Testing-Framework</li></ul>" "text": "<p>Jede Komponente wurde sorgfältig ausgewählt:</p><ul><li><strong>Svelte 5</strong> — Reaktives Framework mit Runes-API</li><li><strong>Tailwind CSS 4</strong> — Utility-first CSS mit @theme</li><li><strong>esbuild</strong> — Extrem schneller Bundler</li><li><strong>Tibi CMS</strong> — Headless CMS mit Go-Backend</li><li><strong>goja SSR</strong> — Server-Side Rendering in Go</li><li><strong>Playwright</strong> — Modernes Testing-Framework</li></ul>"
@@ -215,13 +239,19 @@
{ {
"type": "richtext", "type": "richtext",
"headline": "Why this template?", "headline": "Why this template?",
"padding": { "top": "lg", "bottom": "md" }, "padding": {
"top": "lg",
"bottom": "md"
},
"text": "<p>The Tibi Svelte Starter combines proven patterns from dozens of projects into an immediately usable foundation:</p><ul><li><strong>API layer</strong> with request deduplication, loading states and caching</li><li><strong>Widget library</strong> with Button, Input, Select, Carousel, Pagination and more</li><li><strong>Block rendering</strong> for CMS-driven pages with extensible types</li><li><strong>Testing setup</strong> with Playwright for E2E, API and visual regression tests</li></ul>" "text": "<p>The Tibi Svelte Starter combines proven patterns from dozens of projects into an immediately usable foundation:</p><ul><li><strong>API layer</strong> with request deduplication, loading states and caching</li><li><strong>Widget library</strong> with Button, Input, Select, Carousel, Pagination and more</li><li><strong>Block rendering</strong> for CMS-driven pages with extensible types</li><li><strong>Testing setup</strong> with Playwright for E2E, API and visual regression tests</li></ul>"
}, },
{ {
"type": "richtext", "type": "richtext",
"headline": "Technology Stack", "headline": "Technology Stack",
"padding": { "top": "md", "bottom": "lg" }, "padding": {
"top": "md",
"bottom": "lg"
},
"externalImageUrl": "https://images.unsplash.com/photo-1461749280684-dccba630e2f6?w=800&q=80", "externalImageUrl": "https://images.unsplash.com/photo-1461749280684-dccba630e2f6?w=800&q=80",
"imagePosition": "left", "imagePosition": "left",
"text": "<p>Every component was carefully chosen:</p><ul><li><strong>Svelte 5</strong> — Reactive framework with Runes API</li><li><strong>Tailwind CSS 4</strong> — Utility-first CSS with @theme</li><li><strong>esbuild</strong> — Extremely fast bundler</li><li><strong>Tibi CMS</strong> — Headless CMS with Go backend</li><li><strong>goja SSR</strong> — Server-side rendering in Go</li><li><strong>Playwright</strong> — Modern testing framework</li></ul>" "text": "<p>Every component was carefully chosen:</p><ul><li><strong>Svelte 5</strong> — Reactive framework with Runes API</li><li><strong>Tailwind CSS 4</strong> — Utility-first CSS with @theme</li><li><strong>esbuild</strong> — Extremely fast bundler</li><li><strong>Tibi CMS</strong> — Headless CMS with Go backend</li><li><strong>goja SSR</strong> — Server-side rendering in Go</li><li><strong>Playwright</strong> — Modern testing framework</li></ul>"
@@ -256,7 +286,10 @@
{ {
"type": "contact-form", "type": "contact-form",
"headline": "Nachricht senden", "headline": "Nachricht senden",
"padding": { "top": "lg", "bottom": "lg" } "padding": {
"top": "lg",
"bottom": "lg"
}
} }
], ],
"meta": { "meta": {
@@ -288,7 +321,10 @@
{ {
"type": "contact-form", "type": "contact-form",
"headline": "Send a message", "headline": "Send a message",
"padding": { "top": "lg", "bottom": "lg" } "padding": {
"top": "lg",
"bottom": "lg"
}
} }
], ],
"meta": { "meta": {
@@ -297,4 +333,4 @@
"keywords": "contact, inquiry" "keywords": "contact, inquiry"
} }
} }
] ]

View File

@@ -1,9 +1,11 @@
<script lang="ts"> <script lang="ts">
import { reveal } from "../lib/actions/reveal" import { reveal } from "../lib/actions/reveal"
import { spaLink } from "../lib/navigation"
let { block }: { block: ContentBlockEntry } = $props() let { block }: { block: ContentBlockEntry } = $props()
const hasImage = $derived(block.heroImage?.externalUrl || block.heroImage?.image) const hasImage = $derived(block.heroImage?.externalUrl || block.heroImage?.image)
const isAnchorLink = $derived(block.callToAction?.buttonLink?.startsWith("#"))
</script> </script>
<section <section
@@ -53,6 +55,7 @@
<a <a
href={block.callToAction.buttonLink || "#"} href={block.callToAction.buttonLink || "#"}
target={block.callToAction.buttonTarget || undefined} target={block.callToAction.buttonTarget || undefined}
use:spaLink={{ noScroll: isAnchorLink }}
class="inline-flex items-center gap-2 bg-brand-500 hover:bg-brand-400 text-white font-bold px-8 py-4 rounded-xl text-lg transition-all duration-300 hover:shadow-lg hover:shadow-brand-500/25 hover:-translate-y-0.5" class="inline-flex items-center gap-2 bg-brand-500 hover:bg-brand-400 text-white font-bold px-8 py-4 rounded-xl text-lg transition-all duration-300 hover:shadow-lg hover:shadow-brand-500/25 hover:-translate-y-0.5"
> >
{block.callToAction.buttonText} {block.callToAction.buttonText}

View File

@@ -128,8 +128,14 @@
} }
.feature-card .feature-icon { .feature-card .feature-icon {
font-size: 2.5rem;
margin-bottom: 1rem; margin-bottom: 1rem;
color: var(--color-brand-600);
line-height: 1;
}
.feature-card .feature-icon svg {
width: 2.5rem;
height: 2.5rem;
} }
.feature-card h3 { .feature-card h3 {

View File

@@ -173,6 +173,16 @@ export const spaLink = (node: HTMLAnchorElement, options: SpaNavigateOptions = {
return return
} }
// Handle anchor links: scroll to element instead of SPA navigation
if (href.startsWith("#")) {
event.preventDefault()
const target = document.getElementById(href.slice(1))
if (target) {
target.scrollIntoView({ behavior: "smooth" })
}
return
}
// Skip if target is set (e.g., _blank) // Skip if target is set (e.g., _blank)
if (node.target && node.target !== "_self") { if (node.target && node.target !== "_self") {
return return