From 20ce3ba59c8f227b2eed88ca5953ea61e7bac26e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 16:28:08 +0200
Subject: [PATCH 01/29] Prototype new design

---
 index.html | 323 +++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 299 insertions(+), 24 deletions(-)

diff --git a/index.html b/index.html
index ac55cee..9d2c659 100644
--- a/index.html
+++ b/index.html
@@ -1,24 +1,299 @@
-<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=Edge"/><meta name="viewport" content="width=device-width, initial-scale=1"/><title>Spock</title><style>*{box-sizing:border-box}.cxs-96960423 pre .hljs-literal{color:#08e}.cxs-799160745{font-size:48px}.cxs-3954183383{font-size:24px}.cxs-857983649 a:hover{text-decoration:underline}.cxs-3377994344{}.cxs-3377994344:hover{box-shadow:inset 0 0 0 999px rgba(0, 0, 0, .125)}.cxs-96960423{}.cxs-96960423 h1{font-weight:600;line-height:1.25;font-size:48px;margin-top:32px;margin-bottom:8px}.cxs-96960423 h1 h0{}.cxs-96960423 h1 h1{}.cxs-96960423 h1 h2{}.cxs-96960423 h1 h3{}.cxs-96960423 h1 h4{}.cxs-96960423 h1 h5{}.cxs-96960423 h1 h6{}.cxs-96960423 h2{font-weight:600;line-height:1.25;font-size:24px;margin-top:32px;margin-bottom:8px}.cxs-96960423 h2 h0{}.cxs-96960423 h2 h1{}.cxs-96960423 h2 h2{}.cxs-96960423 h2 h3{}.cxs-96960423 h2 h4{}.cxs-96960423 h2 h5{}.cxs-96960423 h2 h6{}.cxs-96960423 h3{font-weight:600;line-height:1.25;font-size:20px;margin-top:32px;margin-bottom:8px}.cxs-96960423 h3 h0{}.cxs-96960423 h3 h1{}.cxs-96960423 h3 h2{}.cxs-96960423 h3 h3{}.cxs-96960423 h3 h4{}.cxs-96960423 h3 h5{}.cxs-96960423 h3 h6{}.cxs-96960423 h4{font-weight:600;line-height:1.25;font-size:16px;margin-top:32px;margin-bottom:8px}.cxs-96960423 h4 h0{}.cxs-96960423 h4 h1{}.cxs-96960423 h4 h2{}.cxs-96960423 h4 h3{}.cxs-96960423 h4 h4{}.cxs-96960423 h4 h5{}.cxs-96960423 h4 h6{}.cxs-96960423 h5{font-weight:600;line-height:1.25;font-size:14px;margin-top:32px;margin-bottom:8px}.cxs-96960423 h5 h0{}.cxs-96960423 h5 h1{}.cxs-96960423 h5 h2{}.cxs-96960423 h5 h3{}.cxs-96960423 h5 h4{}.cxs-96960423 h5 h5{}.cxs-96960423 h5 h6{}.cxs-96960423 h6{font-weight:600;line-height:1.25;font-size:12px;margin-top:32px;margin-bottom:8px}.cxs-96960423 h6 h0{}.cxs-96960423 h6 h1{}.cxs-96960423 h6 h2{}.cxs-96960423 h6 h3{}.cxs-96960423 h6 h4{}.cxs-96960423 h6 h5{}.cxs-96960423 h6 h6{}.cxs-96960423 p{overflow-x:auto;margin-top:0px;margin-bottom:16px}.cxs-96960423 code{font-family:Menlo, monospace;font-size:14px;padding:4px;background-color:#eee;border-radius:2px}.cxs-96960423 pre{font-family:Menlo, monospace;font-size:14px;overflow-x:auto;padding:16px;margin-top:8px;margin-bottom:32px;background-color:#eee;border-radius:2px}.cxs-96960423 pre .hljs-keyword{color:#08e}.cxs-96960423 pre .hljs-built_in{color:#059}.cxs-96960423 pre .hljs-type{color:#059}.cxs-857983649 a{color:#05a}.cxs-96960423 pre .hljs-number{color:#e08}.cxs-96960423 pre .hljs-regexp{color:#08e}.cxs-96960423 pre .hljs-string{color:#059}.cxs-96960423 pre .hljs-subst{color:#059}.cxs-96960423 pre .hljs-symbol{color:#08e}.cxs-96960423 pre .hljs-class{color:#08e}.cxs-96960423 pre .hljs-function{color:#e08}.cxs-96960423 pre .hljs-title{color:#08e}.cxs-96960423 pre .hljs-params{color:#059}.cxs-96960423 pre .hljs-comment{color:#059}.cxs-96960423 pre .hljs-doctag{color:#059}.cxs-96960423 pre .hljs-meta{color:#059}.cxs-96960423 pre .hljs-meta-keyword{color:#08e}.cxs-96960423 pre .hljs-meta-string{color:#08e}.cxs-96960423 hr{margin-top:48px;margin-bottom:48px;border:0px;border-bottom-style:solid;border-bottom-width:1px;border-bottom:2px solid #ddd}.cxs-96960423 table{border-collapse:separate;border-spacing:0px;max-width:100%;width:100%}.cxs-96960423 th{text-align:left;line-height:inherit;vertical-align:bottom}.cxs-96960423 td{vertical-align:top;line-height:inherit}.cxs-96960423 img{max-width: 100%;height: auto;margin-top:16px;margin-bottom:16px}.cxs-96960423 a{color:#08e;text-decoration: none}.cxs-96960423 a:hover{text-decoration:underline}.cxs-96960423 ul{padding-left:32px;margin-top:0px;margin-bottom:16px}.cxs-857983649{}.cxs-857983649 h1{font-weight:700;letter-spacing:-0.01em;font-size:24px;margin-top:48px;margin-bottom:48px;border-bottom-width:4px;border-bottom-style:solid}.cxs-857983649 img{max-width: 100%;height: auto;margin-top:16px;margin-bottom:16px}.cxs-857983649 h2{font-weight:700;letter-spacing:-0.01em;font-size:24px;margin-top:48px;margin-bottom:48px;border-bottom-width:4px;border-bottom-style:solid}.cxs-857983649 td{vertical-align:top;line-height:inherit}.cxs-857983649 h3{font-weight:700;letter-spacing:-0.01em;font-size:20px;margin-top:48px;margin-bottom:48px;border-bottom-width:2px;border-bottom-style:solid}.cxs-857983649 th{text-align:left;line-height:inherit;vertical-align:bottom}.cxs-857983649 h4{font-weight:700;letter-spacing:-0.01em;font-size:20px;margin-top:32px;margin-bottom:8px}.cxs-857983649 h5{font-weight:700;letter-spacing:-0.01em;font-size:20px;margin-top:32px;margin-bottom:8px}.cxs-857983649 h6{font-weight:700;letter-spacing:-0.01em;font-size:20px;margin-top:32px;margin-bottom:8px}.cxs-857983649 p{overflow-x:auto;max-width:40em;margin-top:0px;margin-bottom:16px}.cxs-857983649 code{font-family:Menlo, monospace;font-size:14px;color:#05a}.cxs-857983649 pre{font-family:Menlo, monospace;font-size:14px;overflow-x:auto;padding-top:16px;padding-bottom:16px;margin-top:32px;margin-bottom:32px;border-top:1px solid;border-bottom:1px solid}.cxs-857983649 pre .hljs-keyword{color:#05a}.cxs-857983649 pre .hljs-built_in{color:#444}.cxs-857983649 pre .hljs-type{color:#444}.cxs-857983649 pre .hljs-literal{color:#05a}.cxs-857983649 pre .hljs-number{color:#f30}.cxs-857983649 pre .hljs-regexp{color:#05a}.cxs-857983649 pre .hljs-string{color:#444}.cxs-857983649 pre .hljs-subst{color:#444}.cxs-857983649 pre .hljs-symbol{color:#05a}.cxs-857983649 pre .hljs-class{color:#05a}.cxs-857983649 pre .hljs-function{color:#f30}.cxs-857983649 pre .hljs-title{color:#05a}.cxs-857983649 pre .hljs-params{color:#444}.cxs-857983649 pre .hljs-comment{color:#444}.cxs-857983649 pre .hljs-doctag{color:#444}.cxs-857983649 pre .hljs-meta{color:#444}.cxs-857983649 pre .hljs-meta-keyword{color:#05a}.cxs-857983649 pre .hljs-meta-string{color:#05a}.cxs-857983649 hr{margin-top:48px;margin-bottom:48px;border:0px;border-bottom:2px solid}.cxs-857983649 table{border-collapse:separate;border-spacing:0px;max-width:100%;width:100%}.cxs-857983649 ul{list-style:square inside;padding-left:0px;margin-top:0px;margin-bottom:32px}@media screen and (min-width:52em) { .cxs-857983649 h3{font-size:24px} }@media screen and (min-width:52em) { .cxs-857983649 h2{font-size:48px} }@media screen and (min-width:52em) { .cxs-857983649 h1{font-size:48px} }@media screen and (min-width: 52em) { .cxs-799160745{font-size:72px} }@media screen and (min-width: 52em) { .cxs-3954183383{} }</style></head><body style="margin:0;"><div class="Xv" style="font-family:-apple-system, BlinkMacSystemFont, sans-serif;font-weight:400;line-height:1.5;color:#111;background-color:#fff;"><header class="BannerHeader" style="display:flex;align-items:center;justify-content:center;text-align:left;min-height:100vh;color:white;background-color:#111;background-image:url(undefined);background-size:cover;background-position:center;"><div style="box-sizing:border-box;width:100%;max-width:1024px;margin-left:auto;margin-right:auto;padding-top:48px;padding-bottom:48px;padding-left:32px;padding-right:32px;"><h1 class="cxs-799160745" style="box-sizing:border-box;font-weight:600;line-height:1.25;h0:[object Object];h1:[object Object];h2:[object Object];h3:[object Object];h4:[object Object];h5:[object Object];h6:[object Object];margin:0;">Spock</h1><h2 class="cxs-3954183383" style="box-sizing:border-box;font-weight:600;line-height:1.25;h0:[object Object];h1:[object Object];h2:[object Object];h3:[object Object];h4:[object Object];h5:[object Object];h6:[object Object];margin:0;">the enterprise ready specification framework</h2><div style="box-sizing:border-box;margin-left:-16px;margin-right:-16px;"><a href="https://docs.spockframework.org/" class="cxs-3377994344" style="box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:600;line-height:1.5;display:inline-block;margin:16px;padding-top:8px;padding-bottom:8px;padding-left:16px;padding-right:16px;border-width:1px;border-style:solid;border-color:transparent;cursor:pointer;border-radius:2px;color:#fff;background-color:#08e;text-decoration:none;hover:[object Object];">Documentation</a><a href="https://github.com/spockframework/spock" class="cxs-3377994344" style="box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:600;line-height:1.5;display:inline-block;margin:16px;padding-top:8px;padding-bottom:8px;padding-left:16px;padding-right:16px;border-width:1px;border-style:solid;border-color:transparent;cursor:pointer;border-radius:2px;color:#fff;background-color:#08e;text-decoration:none;hover:[object Object];">Source</a><a href="https://github.com/spockframework/spock/issues" class="cxs-3377994344" style="box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:600;line-height:1.5;display:inline-block;margin:16px;padding-top:8px;padding-bottom:8px;padding-left:16px;padding-right:16px;border-width:1px;border-style:solid;border-color:transparent;cursor:pointer;border-radius:2px;color:#fff;background-color:#08e;text-decoration:none;hover:[object Object];">Issues</a><a href="https://gitter.im/spockframework/spock/" class="cxs-3377994344" style="box-sizing:border-box;font-family:inherit;font-size:inherit;font-weight:600;line-height:1.5;display:inline-block;margin:16px;padding-top:8px;padding-bottom:8px;padding-left:16px;padding-right:16px;border-width:1px;border-style:solid;border-color:transparent;cursor:pointer;border-radius:2px;color:#fff;background-color:#08e;text-decoration:none;hover:[object Object];">Chat</a><div style="display:table;clear:both;"></div></div><div style="box-sizing:border-box;margin-left:-8px;margin-right:-8px;padding-top:16px;padding-bottom:16px;"><iframe src="https://platform.twitter.com/widgets/tweet_button.html?text=spockframework.github.io%3A%20Spock%20project%20homepage&amp;url=&amp;via=&amp;hashtags=&amp;size=" height="20" allowtransparency="true" frameborder="0" scrolling="no" style="box-sizing:border-box;width:61px;overflow:hidden;margin:8px;"></iframe><iframe src="https://ghbtns.com/github-btn.html?type=star&amp;count=true&amp;user=spockframework&amp;repo=spock&amp;size=" height="20" frameborder="0" scrolling="no" style="box-sizing:border-box;width:100px;overflow:hidden;margin:8px;"></iframe><div style="display:table;clear:both;"></div></div></div></header><div class="cxs-96960423" style="box-sizing:border-box;max-width:1024px;margin-left:auto;margin-right:auto;padding-top:32px;padding-bottom:32px;padding-left:32px;padding-right:32px;"><article style="box-sizing:border-box;"><div><h2>What is it?</h2>
-<p>Spock is a testing and specification framework for Java and Groovy applications. What makes it stand out from the crowd is its beautiful and highly expressive specification language. Thanks to its JUnit runner, Spock is compatible with most IDEs, build tools, and continuous integration servers. Spock is inspired from <a href="https://www.junit.org/">JUnit</a>, <a href="https://rspec.info/">RSpec</a>, <a href="http://www.jmock.org/">jMock</a>, <a href="https://site.mockito.org">Mockito</a>, <a href="https://groovy-lang.org/">Groovy</a>, <a href="https://www.scala-lang.org/">Scala</a>, <a href="https://en.wikipedia.org/wiki/Vulcans">Vulcans</a>, and other fascinating life forms.</p>
-<h2>How Do I Get Started?</h2>
-<p>Read <a href="https://github.com/spockframework/spock/wiki/10-Reasons-to-use-Spock">ten reasons</a> why Spock is for you, run your first spec in <a href="https://gwc-experiment.appspot.com/?gist=58f61cf36e112ff654041eeec8d11a98">Groovy Web Console</a>, fork the <a href="https://github.com/spockframework/spock-example">spock-example</a> project, learn how to write a specification, or dive into the <a href="https://docs.spockframework.org">reference documentation</a>.</p>
-<h2>Install</h2>
-<h3>with Gradle</h3>
-<pre><span class="hljs-selector-tag">testImplementation</span> &quot;<span class="hljs-selector-tag">org</span><span class="hljs-selector-class">.spockframework</span><span class="hljs-selector-pseudo">:spock-core</span><span class="hljs-selector-pseudo">:2.1-groovy-3.0&quot;</span></pre><h3>with Maven:</h3>
-<pre><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
-  <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.spockframework<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
-  <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spock-core<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
-  <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>2.1-groovy-3.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
-  <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>test<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span>
-<span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span></pre><h2>Where Are The Docs?</h2>
-<ul>
-<li>Reference Documentation: <a href="http://docs.spockframework.org">http://docs.spockframework.org</a></li>
-<li>Javadoc: <a href="https://spockframework.org/spock/javadoc/current">https://spockframework.org/spock/javadoc/current</a></li>
-</ul>
-<h2>How Can I Get Involved?</h2>
-<ul>
-<li>Source Code: <a href="https://github.com/spockframework/spock">https://github.com/spockframework/spock</a></li>
-<li>Issue Tracker: <a href="https://github.com/spockframework/spock/issues">https://github.com/spockframework/spock/issues</a></li>
-<li>Discussion Chat: <a href="https://gitter.im/spockframework/spock">https://gitter.im/spockframework/spock</a></li>
-</ul>
-</div></article></div><footer><div style="box-sizing:border-box;max-width:1024px;margin-left:auto;margin-right:auto;margin-bottom:32px;padding-top:8px;padding-bottom:8px;padding-left:32px;padding-right:32px;"><div style="margin-left:-16px;margin-right:-16px;"><a href="https://github.com/spockframework/spock" class="Link" style="box-sizing:border-box;color:inherit;display:inline-block;font-size:14px;line-height:16px;padding-left:16px;padding-right:16px;padding-top:16px;padding-bottom:16px;font-weight:600;text-decoration:none;">GitHub</a><a href="https://github.com/spockframework/spock/issues" class="Link" style="box-sizing:border-box;color:inherit;display:inline-block;font-size:14px;line-height:16px;padding-left:16px;padding-right:16px;padding-top:16px;padding-bottom:16px;font-weight:600;text-decoration:none;">Issues</a><a href="https://gitter.im/spockframework/spock/" class="Link" style="box-sizing:border-box;color:inherit;display:inline-block;font-size:14px;line-height:16px;padding-left:16px;padding-right:16px;padding-top:16px;padding-bottom:16px;font-weight:600;text-decoration:none;">Chat</a><a href="http://docs.spockframework.org/" class="Link" style="box-sizing:border-box;color:inherit;display:inline-block;font-size:14px;line-height:16px;padding-left:16px;padding-right:16px;padding-top:16px;padding-bottom:16px;font-weight:600;text-decoration:none;">Documentation</a></div><div></div></div></footer></div><div style="font-family:-apple-system, sans-serif;font-size:12px;font-weight:600;text-align:right;padding:24px;color:#333;background-color:#eee;"><a href="http://compositor.io" style="color:inherit;text-decoration:none;">Built with Compositor.io</a></div></body></html>
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Spock Framework - Expressive Testing for Java & Groovy</title>
+    <script src="https://cdn.tailwindcss.com"></script>
+    <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet"
+          integrity="sha384-/rJKQnzOkEo+daG0jMjU1IwwY9unxt1NBw3Ef2fmOJ3PW/TfAg2KXVoWwMZQZtw9"
+          crossorigin="anonymous">
+    <link rel="preconnect" href="https://fonts.googleapis.com">
+    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
+    <style>
+        /* Custom styles - Dark theme is now default */
+        body {
+            font-family: 'Inter', sans-serif;
+            /* Dark mode defaults */
+            background-color: #111827; /* Darker gray background */
+            color: #d1d5db; /* Lighter gray text */
+            transition: background-color 0.3s ease, color 0.3s ease; /* Smooth transition */
+        }
+
+        /* Spock primary color variable */
+        :root {
+            --spock-blue: #1562ae;
+            --spock-blue-dark-text: #60a5fa; /* Lighter blue for text/links in dark */
+        }
+        .spock-blue-bg { background-color: var(--spock-blue); }
+        /* Use the lighter blue for text elements in dark mode */
+        .spock-blue-text { color: var(--spock-blue-dark-text); }
+        .spock-blue-border { border-color: var(--spock-blue-dark-text); } /* Use lighter blue for borders */
+
+        /* Style for code block */
+        pre {
+            background-color: #2d3748; /* Dark background for code */
+            color: #e2e8f0; /* Light text for code */
+            padding: 1.5rem;
+            border-radius: 0.5rem; /* Rounded corners */
+            overflow-x: auto; /* Allow horizontal scrolling */
+            font-family: 'Courier New', Courier, monospace;
+            font-size: 0.9em;
+            line-height: 1.6;
+        }
+        /* Syntax highlighting colors */
+        code .keyword { color: #9ae6b4; } /* Green */
+        code .string { color: #fbd38d; } /* Orange */
+        code .comment { color: #a0aec0; } /* Gray */
+        code .class-name { color: #faf089; } /* Yellow */
+        code .number { color: #fca5a5; } /* Red */
+
+        /* Style for inline code elements within regular text */
+        .inline-code {
+            color: #cbd5e1; /* Slightly lighter gray for inline code */
+            background-color: #374151; /* Slightly lighter dark background */
+            padding: 0.1em 0.4em;
+            border-radius: 0.25rem;
+            font-size: 0.875em; /* Slightly smaller font size */
+            font-family: 'Courier New', Courier, monospace;
+        }
+
+
+        /* Button Styling */
+        .cta-button {
+            display: inline-block;
+            padding: 0.75rem 1.5rem;
+            border-radius: 0.5rem;
+            font-weight: 600;
+            text-align: center;
+            transition: all 0.3s ease;
+            border: 2px solid transparent;
+        }
+        /* Primary Button */
+        .cta-primary {
+            background-color: var(--spock-blue); /* Original blue for background */
+            color: white;
+        }
+        .cta-primary:hover {
+            background-color: #115192; /* Darker blue on hover */
+            transform: translateY(-2px);
+            box-shadow: 0 4px 10px rgba(21, 98, 174, 0.3);
+        }
+
+        /* Secondary Button */
+        .cta-secondary {
+            background-color: transparent;
+            color: var(--spock-blue-dark-text); /* Lighter blue text */
+            border-color: var(--spock-blue-dark-text); /* Lighter blue border */
+        }
+        /* Dark mode secondary button hover */
+        .cta-secondary:hover {
+            background-color: rgba(59, 130, 246, 0.2); /* Lighter blue tint for dark bg */
+            transform: translateY(-2px);
+            box-shadow: 0 4px 10px rgba(59, 130, 246, 0.1);
+        }
+
+        /* Tertiary Button */
+        .cta-tertiary {
+            background-color: #374151; /* Dark gray background */
+            color: #d1d5db; /* Light gray text */
+        }
+        .cta-tertiary:hover {
+            background-color: #4b5563; /* Slightly lighter dark gray on hover */
+            transform: translateY(-2px);
+            box-shadow: 0 4px 10px rgba(255, 255, 255, 0.05);
+        }
+
+        /* Simple underline animation for links */
+        .hover-underline-animation {
+            display: inline-block;
+            position: relative;
+            color: var(--spock-blue-dark-text); /* Lighter blue for dark mode */
+            transition: color 0.3s ease;
+        }
+
+        .hover-underline-animation::after {
+            content: '';
+            position: absolute;
+            width: 100%;
+            transform: scaleX(0);
+            height: 2px;
+            bottom: 0;
+            left: 0;
+            background-color: var(--spock-blue-dark-text); /* Lighter blue underline */
+            transform-origin: bottom right;
+            transition: transform 0.25s ease-out, background-color 0.3s ease;
+        }
+
+        .hover-underline-animation:hover::after {
+            transform: scaleX(1);
+            transform-origin: bottom left;
+        }
+
+        /* Feature Card Styling */
+        .feature-card {
+            background-color: #374151; /* Changed from #1f2937 for better contrast vs bg-gray-800 */
+            padding: 1.5rem; /* p-6 */
+            border-radius: 0.5rem; /* rounded-lg */
+            box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); /* shadow-md */
+            transition: transform 0.3s ease, box-shadow 0.3s ease;
+        }
+        .feature-card:hover {
+            transform: translateY(-4px);
+            box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* shadow-lg */
+        }
+
+        /* Additional Links Separator */
+        .link-separator::after {
+            content: '|';
+            margin-left: 0.75rem; /* mx-3 */
+            margin-right: 0.75rem; /* mx-3 */
+            color: #4b5563; /* gray-600 */
+        }
+        .additional-links a:last-child .link-separator::after {
+            content: ''; /* Don't show separator after the last link */
+            margin: 0;
+        }
+    </style>
+</head>
+<body class="leading-normal tracking-normal">
+
+<section class="pt-24 pb-16 md:pt-32 md:pb-24 bg-gray-800">
+    <div class="container mx-auto px-6 text-center">
+        <div class="mb-8" data-aos="fade-down">
+            <img
+                src="spock-main-logo.svg"
+                alt="Spock Framework Logo"
+                class="h-64 w-auto mx-auto block logo-img"
+            >
+        </div>
+
+        <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text" data-aos="fade-up">
+            Write Beautiful & Expressive Tests
+        </h1>
+        <p class="text-xl md:text-2xl text-gray-400 mb-8" data-aos="fade-up" data-aos-delay="100">
+            Spock: The highly practical testing framework for Java and Groovy applications.
+        </p>
+        <p class="max-w-3xl mx-auto text-lg text-gray-300 mb-12" data-aos="fade-up" data-aos-delay="200">
+            Spock combines the power of Behavior-Driven Development (BDD) with an elegant Groovy-based syntax.
+            Write tests that are not only powerful but also highly readable and maintainable, making collaboration easier and development faster.
+        </p>
+    </div>
+</section>
+
+<section class="py-16 md:py-24">
+    <div class="container mx-auto px-6">
+        <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up">
+            See How Readable Tests Can Be
+        </h2>
+        <div class="max-w-3xl mx-auto" data-aos="fade-up" data-aos-delay="100">
+                <pre><code class="language-groovy"><span class="keyword">import</span> spock.lang.*
+
+<span class="keyword">class</span> <span class="class-name">MathSpec</span> <span class="keyword">extends</span> <span class="class-name">Specification</span> {
+
+    <span class="class-name">def</span> <span class="string">"should add two numbers correctly"</span>() {
+        <span class="keyword">given:</span> <span class="string">"Setup preconditions"</span>
+        <span class="class-name">int</span> a = <span class="number">5</span>
+        <span class="class-name">int</span> b = <span class="number">3</span>
+
+        <span class="keyword">when:</span> <span class="string">"Perform the action under test"</span>
+        <span class="class-name">int</span> result = a + b
+
+        <span class="keyword">then:</span> <span class="string">"Assert the expected outcome"</span>
+        result == <span class="number">8</span>
+    }
+}
+</code></pre>
+            <p class="text-center text-gray-400 mt-6" data-aos="fade-up" data-aos-delay="200">
+                Spock's clear <code class="inline-code">given:</code>, <code class="inline-code">when:</code>, <code class="inline-code">then:</code> blocks make understanding test logic intuitive.
+            </p>
+        </div>
+    </div>
+</section>
+
+<section class="py-16 md:py-24 bg-gray-800">
+    <div class="container mx-auto px-6">
+        <h2 class="text-3xl md:text-4xl font-bold text-center mb-16 text-gray-100" data-aos="fade-up">
+            Why Choose Spock?
+        </h2>
+        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="100">
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Expressive Specifications</h3>
+                <p class="text-gray-300">Write tests that are easy to read and understand, even for non-programmers.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="150">
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Powerful Mocking</h3>
+                <p class="text-gray-300">Create flexible and powerful mocks and stubs with built-in support.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="200">
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Runner</h3>
+                <p class="text-gray-300">Seamless integration with JUnit runners and build tools.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="250">
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Data-Driven Testing</h3>
+                <p class="text-gray-300">Easily run the same test with different sets of data.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="300">
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Groovy DSL</h3>
+                <p class="text-gray-300">Leverage the power and flexibility of the Groovy language.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="350">
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
+                <p class="text-gray-300">Use a rich set of matchers to verify expectations with clarity.</p>
+            </div>
+        </div>
+    </div>
+</section>
+
+<section class="py-16 md:py-24"> <div class="container mx-auto px-6 text-center">
+    <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up">Ready to Improve Your Testing?</h2>
+    <p class="text-lg text-gray-300 mb-12 max-w-2xl mx-auto" data-aos="fade-up" data-aos-delay="100">
+        Explore the documentation, check out examples, or get started right away.
+    </p>
+
+    <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-up" data-aos-delay="200">
+        <a href="https://groovyconsole.dev/?github=spockframework/spock/blob/6d2e6cc6475346f2fef256124e37f70514f0b98e/spock-specs/src/test/groovy/org/spockframework/docs/datadriven/v5/MathSpec.groovy#dgTIqWleyl" target="_blank" class="cta-button cta-primary">
+            Try it online
+        </a>
+        <a href="http://docs.spockframework.org" target="_blank" class="cta-button cta-secondary">
+            Read the Docs
+        </a>
+        <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary">
+            Clone the Example Project
+        </a>
+    </div>
+</div>
+</section>
+
+<section class="py-12">
+    <div class="container mx-auto px-6 text-center text-gray-400 text-sm additional-links flex flex-wrap justify-center items-center gap-y-2">
+        <a href="https://spockframework.org/spock/javadoc/current" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Javadoc</span></a>
+        <a href="https://github.com/spockframework/spock" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Source Code</span></a>
+        <a href="https://github.com/spockframework/spock/issues" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Issue Tracker</span></a>
+        <a href="https://github.com/spockframework/spock/discussions" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Discussions</span></a>
+        <a href="https://gitter.im/spockframework/spock" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Chat</span></a>
+    </div>
+</section>
+
+<footer class="py-8 text-center text-gray-400 text-sm bg-gray-800">
+<div class="container mx-auto px-6">
+        &copy; 2025 Spock Framework Team. All rights reserved.
+    </div>
+</footer>
+
+
+<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"
+        integrity="sha384-wziAfh6b/qT+3LrqebF9WeK4+J5sehS6FA10J1t3a866kJ/fvU5UwofWnQyzLtwu"
+        crossorigin="anonymous"></script>
+<script>
+    // Initialize AOS library
+    AOS.init({
+        duration: 800, // Animation duration
+        once: true, // Whether animation should happen only once - while scrolling down
+        offset: 50, // Offset (in px) from the original trigger point
+    });
+</script>
+
+</body>
+</html>

From a2ced4141dac1340ae6bd0cc36337bbfa847b8d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 17:44:22 +0200
Subject: [PATCH 02/29] design v2

---
 index.html | 192 +++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 133 insertions(+), 59 deletions(-)

diff --git a/index.html b/index.html
index 9d2c659..f9dc186 100644
--- a/index.html
+++ b/index.html
@@ -144,6 +144,14 @@
             box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* shadow-lg */
         }
 
+        .feature-card svg {
+            height: 40px;
+            margin-bottom: 1rem;
+            fill: none;
+            stroke: var(--spock-blue);
+            stroke-width: 2;
+        }
+
         /* Additional Links Separator */
         .link-separator::after {
             content: '|';
@@ -170,48 +178,33 @@
         </div>
 
         <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text" data-aos="fade-up">
-            Write Beautiful & Expressive Tests
+            Spock
         </h1>
-        <p class="text-xl md:text-2xl text-gray-400 mb-8" data-aos="fade-up" data-aos-delay="100">
-            Spock: The highly practical testing framework for Java and Groovy applications.
-        </p>
         <p class="max-w-3xl mx-auto text-lg text-gray-300 mb-12" data-aos="fade-up" data-aos-delay="200">
-            Spock combines the power of Behavior-Driven Development (BDD) with an elegant Groovy-based syntax.
-            Write tests that are not only powerful but also highly readable and maintainable, making collaboration easier and development faster.
+            Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity.
+            By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are not only easy to understand but also enjoyable to maintain.
         </p>
     </div>
 </section>
 
-<section class="py-16 md:py-24">
-    <div class="container mx-auto px-6">
-        <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up">
-            See How Readable Tests Can Be
-        </h2>
-        <div class="max-w-3xl mx-auto" data-aos="fade-up" data-aos-delay="100">
-                <pre><code class="language-groovy"><span class="keyword">import</span> spock.lang.*
-
-<span class="keyword">class</span> <span class="class-name">MathSpec</span> <span class="keyword">extends</span> <span class="class-name">Specification</span> {
-
-    <span class="class-name">def</span> <span class="string">"should add two numbers correctly"</span>() {
-        <span class="keyword">given:</span> <span class="string">"Setup preconditions"</span>
-        <span class="class-name">int</span> a = <span class="number">5</span>
-        <span class="class-name">int</span> b = <span class="number">3</span>
-
-        <span class="keyword">when:</span> <span class="string">"Perform the action under test"</span>
-        <span class="class-name">int</span> result = a + b
+<section class="py-16 md:py-24"> <div class="container mx-auto px-6 text-center">
+    <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up">Ready to Improve Your Testing?</h2>
 
-        <span class="keyword">then:</span> <span class="string">"Assert the expected outcome"</span>
-        result == <span class="number">8</span>
-    }
-}
-</code></pre>
-            <p class="text-center text-gray-400 mt-6" data-aos="fade-up" data-aos-delay="200">
-                Spock's clear <code class="inline-code">given:</code>, <code class="inline-code">when:</code>, <code class="inline-code">then:</code> blocks make understanding test logic intuitive.
-            </p>
-        </div>
+    <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-up" data-aos-delay="200">
+        <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
+            Try it online
+        </a>
+        <a href="http://docs.spockframework.org" target="_blank" class="cta-button cta-secondary">
+            Read the Docs
+        </a>
+        <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary">
+            Clone the Example Project
+        </a>
     </div>
+</div>
 </section>
 
+
 <section class="py-16 md:py-24 bg-gray-800">
     <div class="container mx-auto px-6">
         <h2 class="text-3xl md:text-4xl font-bold text-center mb-16 text-gray-100" data-aos="fade-up">
@@ -219,26 +212,32 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-16 text-gray-100" data-
         </h2>
         <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
             <div class="feature-card" data-aos="fade-up" data-aos-delay="100">
+                <svg viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="2"/></svg>
                 <h3 class="text-xl font-semibold text-gray-100 mb-2">Expressive Specifications</h3>
                 <p class="text-gray-300">Write tests that are easy to read and understand, even for non-programmers.</p>
             </div>
             <div class="feature-card" data-aos="fade-up" data-aos-delay="150">
+                <svg viewBox="0 0 24 24"><path d="M3 17l6-6 4 4 8-8" /></svg>
                 <h3 class="text-xl font-semibold text-gray-100 mb-2">Powerful Mocking</h3>
                 <p class="text-gray-300">Create flexible and powerful mocks and stubs with built-in support.</p>
             </div>
             <div class="feature-card" data-aos="fade-up" data-aos-delay="200">
-                <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Runner</h3>
-                <p class="text-gray-300">Seamless integration with JUnit runners and build tools.</p>
+                <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" /></svg>
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Platform</h3>
+                <p class="text-gray-300">Seamless integration with JUnit Platform and build tools.</p>
             </div>
             <div class="feature-card" data-aos="fade-up" data-aos-delay="250">
+                <svg viewBox="0 0 24 24"><path d="M3 3h18v6H3zM3 15h18v6H3z" /><path d="M9 9v6" /></svg>
                 <h3 class="text-xl font-semibold text-gray-100 mb-2">Data-Driven Testing</h3>
                 <p class="text-gray-300">Easily run the same test with different sets of data.</p>
             </div>
             <div class="feature-card" data-aos="fade-up" data-aos-delay="300">
+                <svg viewBox="0 0 24 24"><polygon points="12 2 15 8 22 9 17 14 18 21 12 18 6 21 7 14 2 9 9 8 12 2" /></svg>
                 <h3 class="text-xl font-semibold text-gray-100 mb-2">Groovy DSL</h3>
                 <p class="text-gray-300">Leverage the power and flexibility of the Groovy language.</p>
             </div>
             <div class="feature-card" data-aos="fade-up" data-aos-delay="350">
+                <svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2" /><path d="M9 12l2 2 4-4" /></svg>
                 <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
                 <p class="text-gray-300">Use a rich set of matchers to verify expectations with clarity.</p>
             </div>
@@ -246,38 +245,113 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
     </div>
 </section>
 
-<section class="py-16 md:py-24"> <div class="container mx-auto px-6 text-center">
-    <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up">Ready to Improve Your Testing?</h2>
-    <p class="text-lg text-gray-300 mb-12 max-w-2xl mx-auto" data-aos="fade-up" data-aos-delay="100">
-        Explore the documentation, check out examples, or get started right away.
-    </p>
+<section class="py-16 md:py-24"> <div class="container mx-auto px-6">
+    <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up">
+        See How Readable Tests Can Be
+    </h2>
+    <div class="max-w-3xl mx-auto" data-aos="fade-up" data-aos-delay="100">
+                <pre><code class="language-groovy"><span class="comment">// CalculatorSpec.groovy</span>
+<span class="keyword">import</span> spock.lang.Specification
 
-    <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-up" data-aos-delay="200">
-        <a href="https://groovyconsole.dev/?github=spockframework/spock/blob/6d2e6cc6475346f2fef256124e37f70514f0b98e/spock-specs/src/test/groovy/org/spockframework/docs/datadriven/v5/MathSpec.groovy#dgTIqWleyl" target="_blank" class="cta-button cta-primary">
-            Try it online
-        </a>
-        <a href="http://docs.spockframework.org" target="_blank" class="cta-button cta-secondary">
-            Read the Docs
-        </a>
-        <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary">
-            Clone the Example Project
-        </a>
+<span class="keyword">class</span> <span class="class-name">CalculatorSpec</span> <span class="keyword">extends</span> Specification {
+
+    <span class="keyword">def</span> <span class="string">"Test calculate method: #a #operation #b = #expectedResult"</span>() {
+        <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span>
+        <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>()
+
+        <span class="keyword">when:</span> <span class="comment">"Perform the calculation"</span>
+        <span class="keyword">int</span> result = calculator.calculate(a, b, operation)
+
+        <span class="keyword">then:</span> <span class="comment">"The result should match the expected value"</span>
+        result == expectedResult
+
+        <span class="keyword">where:</span> <span class="comment">"Define test data"</span>
+        a  | b  | operation || expectedResult
+        <span class="number">1</span>  | <span class="number">2</span>  | <span class="string">"+"</span>       || <span class="number">3</span>
+        <span class="number">5</span>  | <span class="number">3</span>  | <span class="string">"-"</span>       || <span class="number">2</span>
+        <span class="number">4</span>  | <span class="number">2</span>  | <span class="string">"*"</span>       || <span class="number">8</span>
+        <span class="number">10</span> | <span class="number">2</span>  | <span class="string">"/"</span>       || <span class="number">5</span>
+        <span class="number">-1</span> | <span class="number">1</span>  | <span class="string">"+"</span>       || <span class="number">0</span>
+        <span class="number">1</span>  | <span class="number">-1</span> | <span class="string">"-"</span>       || <span class="number">2</span>
+        <span class="number">-2</span> | <span class="number">-2</span> | <span class="string">"*"</span>       || <span class="number">4</span>
+        <span class="number">-4</span> | <span class="number">-2</span> | <span class="string">"/"</span>       || <span class="number">2</span>
+    }
+
+    <span class="keyword">def</span> <span class="string">"Test calculate method with division by zero"</span>() {
+        <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span>
+        <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>()
+
+        <span class="keyword">when:</span> <span class="comment">"Perform division by zero"</span>
+        calculator.calculate(<span class="number">10</span>, <span class="number">0</span>, <span class="string">"/"</span>)
+
+        <span class="keyword">then:</span> <span class="comment">"An IllegalArgumentException is thrown"</span>
+        <span class="keyword">def</span> exception = thrown(<span class="class-name">IllegalArgumentException</span>)
+
+        <span class="keyword">and:</span> <span class="comment">"The exception message is correct"</span>
+        exception.message == <span class="string">"Cannot divide by zero"</span>
+    }
+
+    <span class="keyword">def</span> <span class="string">"Test calculate method with invalid operation"</span>() {
+        <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span>
+        <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>()
+
+        <span class="keyword">when:</span> <span class="comment">"Perform calculation with invalid operation"</span>
+        calculator.calculate(<span class="number">1</span>, <span class="number">2</span>, <span class="string">"**"</span>)
+
+        <span class="keyword">then:</span> <span class="comment">"An IllegalArgumentException is thrown"</span>
+        <span class="keyword">def</span> exception = thrown(<span class="class-name">IllegalArgumentException</span>)
+
+        <span class="keyword">and:</span> <span class="comment">"The exception message is correct"</span>
+        exception.message == <span class="string">"Invalid operation: **"</span>
+    }
+}
+
+
+<span class="comment">// Calculator.groovy</span>
+<span class="keyword">class</span> <span class="class-name">Calculator</span> {
+<span class="comment">    /**
+     * Performs arithmetic operations on two integers.
+     *
+     * <span class="annotation">@param</span> a         The first integer.
+     * <span class="annotation">@param</span> b         The second integer.
+     * <span class="annotation">@param</span> operation The operation to perform (+, -, *, /).
+     * <span class="annotation">@return</span> The result of the operation.
+     * <span class="annotation">@throws</span> IllegalArgumentException if the operation is invalid or division by zero is attempted.
+     */</span>
+    <span class="keyword">int</span> calculate(<span class="keyword">int</span> a, <span class="keyword">int</span> b, <span class="class-name">String</span> operation) {
+        <span class="keyword">switch</span> (operation) {
+            <span class="keyword">case</span> <span class="string">"+"</span>: <span class="keyword">return</span> a + b
+            <span class="keyword">case</span> <span class="string">"-"</span>: <span class="keyword">return</span> a - b
+            <span class="keyword">case</span> <span class="string">"*"</span>: <span class="keyword">return</span> a * b
+            <span class="keyword">case</span> <span class="string">"/"</span>:
+                <span class="keyword">if</span> (b == <span class="number">0</span>) {
+                    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class-name">IllegalArgumentException</span>(<span class="string">"Cannot divide by zero"</span>)
+                }
+                <span class="keyword">return</span> a / b
+            <span class="keyword">default</span>:
+                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class-name">IllegalArgumentException</span>(<span class="string">"Invalid operation: "</span> + operation)
+        }
+    }
+}
+</code></pre>
+        <p class="text-center text-gray-400 mt-6" data-aos="fade-up" data-aos-delay="200">
+            Spock's clear <code class="inline-code">given:</code>, <code class="inline-code">when:</code>, <code class="inline-code">then:</code> blocks make understanding test logic intuitive.
+        </p>
     </div>
 </div>
 </section>
 
-<section class="py-12">
-    <div class="container mx-auto px-6 text-center text-gray-400 text-sm additional-links flex flex-wrap justify-center items-center gap-y-2">
-        <a href="https://spockframework.org/spock/javadoc/current" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Javadoc</span></a>
-        <a href="https://github.com/spockframework/spock" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Source Code</span></a>
-        <a href="https://github.com/spockframework/spock/issues" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Issue Tracker</span></a>
-        <a href="https://github.com/spockframework/spock/discussions" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Discussions</span></a>
-        <a href="https://gitter.im/spockframework/spock" target="_blank" class="hover-underline-animation mx-3"><span class="link-separator">Chat</span></a>
-    </div>
+<section class="py-12 bg-gray-800"> <div class="container mx-auto px-6 text-center text-gray-400 text-sm additional-links flex flex-wrap justify-center items-center gap-y-2">
+    <a href="https://spockframework.org/spock/javadoc/current" class="hover-underline-animation mx-3"><span class="link-separator">Javadoc</span></a>
+    <a href="https://github.com/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Source Code</span></a>
+    <a href="https://github.com/spockframework/spock/issues" class="hover-underline-animation mx-3"><span class="link-separator">Issue Tracker</span></a>
+    <a href="https://github.com/spockframework/spock/discussions" class="hover-underline-animation mx-3"><span class="link-separator">Discussions</span></a>
+    <a href="https://gitter.im/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Discussion Chat</span></a>
+</div>
 </section>
 
-<footer class="py-8 text-center text-gray-400 text-sm bg-gray-800">
-<div class="container mx-auto px-6">
+<footer class="py-8 text-center text-gray-400 text-sm">
+    <div class="container mx-auto px-6">
         &copy; 2025 Spock Framework Team. All rights reserved.
     </div>
 </footer>

From 8a8e916e9b4531b82be0f16e869678726e431526 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 17:49:47 +0200
Subject: [PATCH 03/29] Add missing tag line

---
 index.html | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/index.html b/index.html
index f9dc186..ac1f888 100644
--- a/index.html
+++ b/index.html
@@ -180,6 +180,9 @@
         <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text" data-aos="fade-up">
             Spock
         </h1>
+        <p class="text-xl md:text-2xl text-gray-400 mb-8" data-aos="fade-up" data-aos-delay="100">
+            the enterprise ready specification framework
+        </p>
         <p class="max-w-3xl mx-auto text-lg text-gray-300 mb-12" data-aos="fade-up" data-aos-delay="200">
             Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity.
             By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are not only easy to understand but also enjoyable to maintain.

From ee7a311d2756889947306068560859cdb8ddc19a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 17:51:21 +0200
Subject: [PATCH 04/29] Fix link text

---
 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/index.html b/index.html
index ac1f888..4fad483 100644
--- a/index.html
+++ b/index.html
@@ -349,7 +349,7 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-
     <a href="https://github.com/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Source Code</span></a>
     <a href="https://github.com/spockframework/spock/issues" class="hover-underline-animation mx-3"><span class="link-separator">Issue Tracker</span></a>
     <a href="https://github.com/spockframework/spock/discussions" class="hover-underline-animation mx-3"><span class="link-separator">Discussions</span></a>
-    <a href="https://gitter.im/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Discussion Chat</span></a>
+    <a href="https://gitter.im/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Chat</span></a>
 </div>
 </section>
 

From e2a93ec012fed31ee4898e32eead4253ed43ec57 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 18:00:12 +0200
Subject: [PATCH 05/29] Add logo and .gitignore

---
 .gitignore          | 1 +
 spock-main-logo.svg | 1 +
 2 files changed, 2 insertions(+)
 create mode 100644 .gitignore
 create mode 100644 spock-main-logo.svg

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9f11b75
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.idea/
diff --git a/spock-main-logo.svg b/spock-main-logo.svg
new file mode 100644
index 0000000..5e732d1
--- /dev/null
+++ b/spock-main-logo.svg
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 552.35 623.05"><defs><style>.cls-1{fill:#1562ae;}.cls-2{fill:none;stroke:#050606;stroke-miterlimit:10;stroke-width:23px;}</style></defs><rect class="cls-1" width="552.35" height="623.05" rx="196.17"/><path class="cls-2" d="M478.05,270.53,538,187.62l-14.6,72.55-1.46,90.41a39.67,39.67,0,0,1-15.87,26.49l-28,23.67V437c0,83.29-68.15,151.43-151.44,151.43S175.2,520.3,175.2,437h92.28a71.68,71.68,0,0,0,12.82,26.61c3.83,4.94,18.8,22.87,43.66,26.5,35.79,5.24,61-23.73,63.34-26.5,27.46-32.62,13.86-74.39,12.84-77.35-10-29.09-66.16-58.1-73.51-62.86-11.47-7.74-69-43.16-76.18-64-1-3-14.62-44.73,12.84-77.35,2.34-2.77,27.55-31.74,63.34-26.5,24.86,3.63,39.83,21.56,43.66,26.5A67.5,67.5,0,0,1,384,212.25l.34,1.54h93.78c0-83.29-68.15-151.44-151.44-151.44S175.2,130.49,175.2,213.78V273.5l-3.09-4.27-60-82.91,14.6,72.55,1.46,90.41a39.67,39.67,0,0,0,15.87,26.49l31.93,27" transform="translate(-48.91 -13.87)"/></svg>
\ No newline at end of file

From 9e5cde1db263790e203556a6fcc20fb770fc6d32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 18:18:09 +0200
Subject: [PATCH 06/29] Polish blurb

---
 index.html | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/index.html b/index.html
index 4fad483..91cf2d8 100644
--- a/index.html
+++ b/index.html
@@ -185,7 +185,7 @@ <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text" data
         </p>
         <p class="max-w-3xl mx-auto text-lg text-gray-300 mb-12" data-aos="fade-up" data-aos-delay="200">
             Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity.
-            By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are not only easy to understand but also enjoyable to maintain.
+            By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.
         </p>
     </div>
 </section>

From 16d2e6887f6964f1ec64e686cea66468fe8334e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 18:23:22 +0200
Subject: [PATCH 07/29] Move links section

---
 index.html | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/index.html b/index.html
index 91cf2d8..e22bd8e 100644
--- a/index.html
+++ b/index.html
@@ -248,7 +248,17 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
     </div>
 </section>
 
-<section class="py-16 md:py-24"> <div class="container mx-auto px-6">
+
+<section class="py-12"> <div class="container mx-auto px-6 text-center text-gray-400 text-lg additional-links flex flex-wrap justify-center items-center gap-y-2">
+    <a href="https://spockframework.org/spock/javadoc/current" class="hover-underline-animation mx-3"><span class="link-separator">JavaDoc</span></a>
+    <a href="https://github.com/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Source Code</span></a>
+    <a href="https://github.com/spockframework/spock/issues" class="hover-underline-animation mx-3"><span class="link-separator">Issue Tracker</span></a>
+    <a href="https://github.com/spockframework/spock/discussions" class="hover-underline-animation mx-3"><span class="link-separator">Discussions</span></a>
+    <a href="https://gitter.im/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Chat</span></a>
+</div>
+</section>
+
+<section class="py-16 md:py-24 bg-gray-800"> <div class="container mx-auto px-6">
     <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up">
         See How Readable Tests Can Be
     </h2>
@@ -344,15 +354,6 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-
 </div>
 </section>
 
-<section class="py-12 bg-gray-800"> <div class="container mx-auto px-6 text-center text-gray-400 text-sm additional-links flex flex-wrap justify-center items-center gap-y-2">
-    <a href="https://spockframework.org/spock/javadoc/current" class="hover-underline-animation mx-3"><span class="link-separator">Javadoc</span></a>
-    <a href="https://github.com/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Source Code</span></a>
-    <a href="https://github.com/spockframework/spock/issues" class="hover-underline-animation mx-3"><span class="link-separator">Issue Tracker</span></a>
-    <a href="https://github.com/spockframework/spock/discussions" class="hover-underline-animation mx-3"><span class="link-separator">Discussions</span></a>
-    <a href="https://gitter.im/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Chat</span></a>
-</div>
-</section>
-
 <footer class="py-8 text-center text-gray-400 text-sm">
     <div class="container mx-auto px-6">
         &copy; 2025 Spock Framework Team. All rights reserved.

From 30587e81b280103c5cbca8ed4a2bec9bab16f314 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 18:25:28 +0200
Subject: [PATCH 08/29] Remove hover animation for links

---
 index.html | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/index.html b/index.html
index e22bd8e..50692cf 100644
--- a/index.html
+++ b/index.html
@@ -249,12 +249,12 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
 </section>
 
 
-<section class="py-12"> <div class="container mx-auto px-6 text-center text-gray-400 text-lg additional-links flex flex-wrap justify-center items-center gap-y-2">
-    <a href="https://spockframework.org/spock/javadoc/current" class="hover-underline-animation mx-3"><span class="link-separator">JavaDoc</span></a>
-    <a href="https://github.com/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Source Code</span></a>
-    <a href="https://github.com/spockframework/spock/issues" class="hover-underline-animation mx-3"><span class="link-separator">Issue Tracker</span></a>
-    <a href="https://github.com/spockframework/spock/discussions" class="hover-underline-animation mx-3"><span class="link-separator">Discussions</span></a>
-    <a href="https://gitter.im/spockframework/spock" class="hover-underline-animation mx-3"><span class="link-separator">Chat</span></a>
+<section class="py-12"> <div class="container mx-auto px-6 text-center spock-blue-text text-lg additional-links flex flex-wrap justify-center items-center gap-y-2">
+    <a href="https://spockframework.org/spock/javadoc/current" class="mx-3"><span class="link-separator">JavaDoc</span></a>
+    <a href="https://github.com/spockframework/spock" class="mx-3"><span class="link-separator">Source Code</span></a>
+    <a href="https://github.com/spockframework/spock/issues" class="mx-3"><span class="link-separator">Issue Tracker</span></a>
+    <a href="https://github.com/spockframework/spock/discussions" class="mx-3"><span class="link-separator">Discussions</span></a>
+    <a href="https://gitter.im/spockframework/spock" class="mx-3"><span class="link-separator">Chat</span></a>
 </div>
 </section>
 

From 5b3c61beb5b3b72438c970ecd7d6008a84c6827c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 18:36:39 +0200
Subject: [PATCH 09/29] Merge links into cta section

---
 index.html | 48 +++++++++++++++++++++++-------------------------
 1 file changed, 23 insertions(+), 25 deletions(-)

diff --git a/index.html b/index.html
index 50692cf..e9e5717 100644
--- a/index.html
+++ b/index.html
@@ -190,21 +190,29 @@ <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text" data
     </div>
 </section>
 
-<section class="py-16 md:py-24"> <div class="container mx-auto px-6 text-center">
-    <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up">Ready to Improve Your Testing?</h2>
-
-    <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-up" data-aos-delay="200">
-        <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
-            Try it online
-        </a>
-        <a href="http://docs.spockframework.org" target="_blank" class="cta-button cta-secondary">
-            Read the Docs
-        </a>
-        <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary">
-            Clone the Example Project
-        </a>
+<section class="py-16 md:py-24">
+    <div class="container mx-auto px-6 text-center">
+        <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up">Ready to Improve Your Testing?</h2>
+
+        <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-up" data-aos-delay="200">
+            <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
+                Try it online
+            </a>
+            <a href="http://docs.spockframework.org" target="_blank" class="cta-button cta-secondary">
+                Read the Docs
+            </a>
+            <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary">
+                Clone the Example Project
+            </a>
+        </div>
+    </div>
+    <div class="container mx-auto px-6 text-center spock-blue-text text-md additional-links flex flex-wrap justify-center items-center gap-y-2 pt-8">
+        <a href="https://spockframework.org/spock/javadoc/current" class="mx-3"><span class="link-separator">JavaDoc</span></a>
+        <a href="https://github.com/spockframework/spock" class="mx-3"><span class="link-separator">Source Code</span></a>
+        <a href="https://github.com/spockframework/spock/issues" class="mx-3"><span class="link-separator">Issue Tracker</span></a>
+        <a href="https://github.com/spockframework/spock/discussions" class="mx-3"><span class="link-separator">Discussions</span></a>
+        <a href="https://gitter.im/spockframework/spock" class="mx-3"><span class="link-separator">Chat</span></a>
     </div>
-</div>
 </section>
 
 
@@ -248,17 +256,7 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
     </div>
 </section>
 
-
-<section class="py-12"> <div class="container mx-auto px-6 text-center spock-blue-text text-lg additional-links flex flex-wrap justify-center items-center gap-y-2">
-    <a href="https://spockframework.org/spock/javadoc/current" class="mx-3"><span class="link-separator">JavaDoc</span></a>
-    <a href="https://github.com/spockframework/spock" class="mx-3"><span class="link-separator">Source Code</span></a>
-    <a href="https://github.com/spockframework/spock/issues" class="mx-3"><span class="link-separator">Issue Tracker</span></a>
-    <a href="https://github.com/spockframework/spock/discussions" class="mx-3"><span class="link-separator">Discussions</span></a>
-    <a href="https://gitter.im/spockframework/spock" class="mx-3"><span class="link-separator">Chat</span></a>
-</div>
-</section>
-
-<section class="py-16 md:py-24 bg-gray-800"> <div class="container mx-auto px-6">
+<section class="py-16 md:py-24"> <div class="container mx-auto px-6">
     <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up">
         See How Readable Tests Can Be
     </h2>

From 9dcdbb1f36ca6ba9786dcfba77ffe02ca38cacf1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 18:42:55 +0200
Subject: [PATCH 10/29] Fix link animations

---
 index.html | 17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/index.html b/index.html
index e9e5717..513ba3a 100644
--- a/index.html
+++ b/index.html
@@ -153,16 +153,11 @@
         }
 
         /* Additional Links Separator */
-        .link-separator::after {
-            content: '|';
+        .link-separator {
             margin-left: 0.75rem; /* mx-3 */
             margin-right: 0.75rem; /* mx-3 */
             color: #4b5563; /* gray-600 */
         }
-        .additional-links a:last-child .link-separator::after {
-            content: ''; /* Don't show separator after the last link */
-            margin: 0;
-        }
     </style>
 </head>
 <body class="leading-normal tracking-normal">
@@ -207,11 +202,11 @@ <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up"
         </div>
     </div>
     <div class="container mx-auto px-6 text-center spock-blue-text text-md additional-links flex flex-wrap justify-center items-center gap-y-2 pt-8">
-        <a href="https://spockframework.org/spock/javadoc/current" class="mx-3"><span class="link-separator">JavaDoc</span></a>
-        <a href="https://github.com/spockframework/spock" class="mx-3"><span class="link-separator">Source Code</span></a>
-        <a href="https://github.com/spockframework/spock/issues" class="mx-3"><span class="link-separator">Issue Tracker</span></a>
-        <a href="https://github.com/spockframework/spock/discussions" class="mx-3"><span class="link-separator">Discussions</span></a>
-        <a href="https://gitter.im/spockframework/spock" class="mx-3"><span class="link-separator">Chat</span></a>
+        <a href="https://spockframework.org/spock/javadoc/current" class="mx-3 hover-underline-animation">JavaDoc</a> <span class="link-separator">|</span>
+        <a href="https://github.com/spockframework/spock" class="mx-3 hover-underline-animation">Source Code</a> <span class="link-separator">|</span>
+        <a href="https://github.com/spockframework/spock/issues" class="mx-3 hover-underline-animation">Issue Tracker</a> <span class="link-separator">|</span>
+        <a href="https://github.com/spockframework/spock/discussions" class="mx-3 hover-underline-animation">Discussions</a> <span class="link-separator">|</span>
+        <a href="https://gitter.im/spockframework/spock" class="mx-3 hover-underline-animation">Chat</a>
     </div>
 </section>
 

From 2e1dd5a25e95777be387c9f65c0e49105f13f71b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 18:58:25 +0200
Subject: [PATCH 11/29] Repeat CTA after code block

---
 index.html | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/index.html b/index.html
index 513ba3a..401340a 100644
--- a/index.html
+++ b/index.html
@@ -164,7 +164,7 @@
 
 <section class="pt-24 pb-16 md:pt-32 md:pb-24 bg-gray-800">
     <div class="container mx-auto px-6 text-center">
-        <div class="mb-8" data-aos="fade-down">
+        <div class="mb-8">
             <img
                 src="spock-main-logo.svg"
                 alt="Spock Framework Logo"
@@ -172,13 +172,13 @@
             >
         </div>
 
-        <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text" data-aos="fade-up">
+        <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text">
             Spock
         </h1>
-        <p class="text-xl md:text-2xl text-gray-400 mb-8" data-aos="fade-up" data-aos-delay="100">
+        <p class="text-xl md:text-2xl text-gray-400 mb-8">
             the enterprise ready specification framework
         </p>
-        <p class="max-w-3xl mx-auto text-lg text-gray-300 mb-12" data-aos="fade-up" data-aos-delay="200">
+        <p class="max-w-3xl mx-auto text-lg text-gray-300 mb-12">
             Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity.
             By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.
         </p>
@@ -201,7 +201,7 @@ <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up"
             </a>
         </div>
     </div>
-    <div class="container mx-auto px-6 text-center spock-blue-text text-md additional-links flex flex-wrap justify-center items-center gap-y-2 pt-8">
+    <div class="container mx-auto px-6 text-center spock-blue-text text-md additional-links flex flex-wrap justify-center items-center gap-y-2 pt-8" data-aos="fade-up" data-aos-delay="300">
         <a href="https://spockframework.org/spock/javadoc/current" class="mx-3 hover-underline-animation">JavaDoc</a> <span class="link-separator">|</span>
         <a href="https://github.com/spockframework/spock" class="mx-3 hover-underline-animation">Source Code</a> <span class="link-separator">|</span>
         <a href="https://github.com/spockframework/spock/issues" class="mx-3 hover-underline-animation">Issue Tracker</a> <span class="link-separator">|</span>
@@ -343,6 +343,11 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-
         <p class="text-center text-gray-400 mt-6" data-aos="fade-up" data-aos-delay="200">
             Spock's clear <code class="inline-code">given:</code>, <code class="inline-code">when:</code>, <code class="inline-code">then:</code> blocks make understanding test logic intuitive.
         </p>
+        <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4 mt-8" data-aos="fade-up" data-aos-delay="200">
+            <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
+                Try it online
+            </a>
+        </div>
     </div>
 </div>
 </section>

From 3e6a61dd79c4d6b3b859a5eef4408c50c519480a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 19:49:35 +0200
Subject: [PATCH 12/29] Update example code and add output

---
 index.html | 41 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 34 insertions(+), 7 deletions(-)

diff --git a/index.html b/index.html
index 401340a..40b8fc5 100644
--- a/index.html
+++ b/index.html
@@ -256,7 +256,7 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-
         See How Readable Tests Can Be
     </h2>
     <div class="max-w-3xl mx-auto" data-aos="fade-up" data-aos-delay="100">
-                <pre><code class="language-groovy"><span class="comment">// CalculatorSpec.groovy</span>
+            <pre><code class="language-groovy"><span class="comment">// CalculatorSpec.groovy</span>
 <span class="keyword">import</span> spock.lang.Specification
 
 <span class="keyword">class</span> <span class="class-name">CalculatorSpec</span> <span class="keyword">extends</span> Specification {
@@ -265,11 +265,8 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-
         <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span>
         <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>()
 
-        <span class="keyword">when:</span> <span class="comment">"Perform the calculation"</span>
-        <span class="keyword">int</span> result = calculator.calculate(a, b, operation)
-
-        <span class="keyword">then:</span> <span class="comment">"The result should match the expected value"</span>
-        result == expectedResult
+        <span class="keyword">expect:</span> <span class="comment">"The calculation should match the expected value"</span> <span class="comment">// Changed from when/then</span>
+        calculator.calculate(a, b, operation) == expectedResult
 
         <span class="keyword">where:</span> <span class="comment">"Define test data"</span>
         a  | b  | operation || expectedResult
@@ -281,6 +278,7 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-
         <span class="number">1</span>  | <span class="number">-1</span> | <span class="string">"-"</span>       || <span class="number">2</span>
         <span class="number">-2</span> | <span class="number">-2</span> | <span class="string">"*"</span>       || <span class="number">4</span>
         <span class="number">-4</span> | <span class="number">-2</span> | <span class="string">"/"</span>       || <span class="number">2</span>
+        <span class="number">1</span>  | <span class="number">1</span>  | <span class="string">"+"</span>       || <span class="number">42</span> <span class="comment">// A failing test case</span>
     }
 
     <span class="keyword">def</span> <span class="string">"Test calculate method with division by zero"</span>() {
@@ -338,12 +336,41 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-
                 <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class-name">IllegalArgumentException</span>(<span class="string">"Invalid operation: "</span> + operation)
         }
     }
+
+    <span class="class-name">String</span> toString() {
+        <span class="keyword">return</span> <span class="string">"Calc"</span>
+    }
 }
 </code></pre>
         <p class="text-center text-gray-400 mt-6" data-aos="fade-up" data-aos-delay="200">
             Spock's clear <code class="inline-code">given:</code>, <code class="inline-code">when:</code>, <code class="inline-code">then:</code> blocks make understanding test logic intuitive.
         </p>
-        <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4 mt-8" data-aos="fade-up" data-aos-delay="200">
+        <div class="mt-12" data-aos="fade-up" data-aos-delay="500">
+            <h3 class="text-xl font-semibold text-center mb-4 text-gray-100">Example Test Output:</h3>
+            <pre>â•·
+└─ Spock ✔
+   └─ CalculatorSpec ✔
+      ├─ Test calculate method: #a #operation #b = #expectedResult ✔
+      │  ├─ Test calculate method: 1 + 2 = 3 ✔
+      │  ├─ Test calculate method: 5 - 3 = 2 ✔
+      │  ├─ Test calculate method: 4 * 2 = 8 ✔
+      │  ├─ Test calculate method: 10 / 2 = 5 ✔
+      │  ├─ Test calculate method: -1 + 1 = 0 ✔
+      │  ├─ Test calculate method: 1 - -1 = 2 ✔
+      │  ├─ Test calculate method: -2 * -2 = 4 ✔
+      │  ├─ Test calculate method: -4 / -2 = 2 ✔
+      │  └─ Test calculate method: 1 + 1 = 42 ✘ Condition not satisfied:
+      │
+      │           calculator.calculate(a, b, operation) == expectedResult
+      │           |          |         |  |  |          |  |
+      │           Calc       2         1  1  +          |  42
+      │                                                 false
+      ├─ Test calculate method with division by zero ✔
+      └─ Test calculate method with invalid operation ✔</pre>
+                </div>
+            </div>
+        </div>
+        <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4 mt-8" data-aos="fade-up" data-aos-delay="800">
             <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
                 Try it online
             </a>

From d8d9e9e56515f7c9813fd8c56aa8b21d993cf85d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Tue, 15 Apr 2025 20:14:10 +0200
Subject: [PATCH 13/29] More cleanup

---
 index.html | 20 +++++++++-----------
 1 file changed, 9 insertions(+), 11 deletions(-)

diff --git a/index.html b/index.html
index 40b8fc5..eedb28e 100644
--- a/index.html
+++ b/index.html
@@ -168,8 +168,7 @@
             <img
                 src="spock-main-logo.svg"
                 alt="Spock Framework Logo"
-                class="h-64 w-auto mx-auto block logo-img"
-            >
+                class="h-64 w-auto mx-auto block logo-img">
         </div>
 
         <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text">
@@ -193,7 +192,7 @@ <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up"
             <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
                 Try it online
             </a>
-            <a href="http://docs.spockframework.org" target="_blank" class="cta-button cta-secondary">
+            <a href="https://docs.spockframework.org" target="_blank" class="cta-button cta-secondary">
                 Read the Docs
             </a>
             <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary">
@@ -251,11 +250,12 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
     </div>
 </section>
 
-<section class="py-16 md:py-24"> <div class="container mx-auto px-6">
-    <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up">
-        See How Readable Tests Can Be
-    </h2>
-    <div class="max-w-3xl mx-auto" data-aos="fade-up" data-aos-delay="100">
+<section class="py-16 md:py-24">
+    <div class="container mx-auto px-6">
+        <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up">
+            See How Readable Tests Can Be
+        </h2>
+        <div class="max-w-3xl mx-auto" data-aos="fade-up" data-aos-delay="100">
             <pre><code class="language-groovy"><span class="comment">// CalculatorSpec.groovy</span>
 <span class="keyword">import</span> spock.lang.Specification
 
@@ -265,7 +265,7 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-
         <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span>
         <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>()
 
-        <span class="keyword">expect:</span> <span class="comment">"The calculation should match the expected value"</span> <span class="comment">// Changed from when/then</span>
+        <span class="keyword">expect:</span> <span class="comment">"The calculation should match the expected value"</span>
         calculator.calculate(a, b, operation) == expectedResult
 
         <span class="keyword">where:</span> <span class="comment">"Define test data"</span>
@@ -375,8 +375,6 @@ <h3 class="text-xl font-semibold text-center mb-4 text-gray-100">Example Test Ou
                 Try it online
             </a>
         </div>
-    </div>
-</div>
 </section>
 
 <footer class="py-8 text-center text-gray-400 text-sm">

From b77cdf2c1cd8d760fd556d4c1ba06e95d0264d34 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Wed, 16 Apr 2025 10:42:57 +0200
Subject: [PATCH 14/29] Add some seo metadata

---
 index.html | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/index.html b/index.html
index eedb28e..a12b0f1 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,22 @@
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Spock Framework - Expressive Testing for Java & Groovy</title>
+    <title>Spock Framework - the enterprise ready specification framework</title>
+    <meta name="description" content="Spock is an expressive testing and specification framework for Java and Groovy applications. Write highly readable, maintainable BDD-style tests with powerful mocking.">
+    <meta name="keywords" content="Spock Framework, Groovy, Java, Kotlin, JVM, testing, specification, BDD, Behavior-Driven Development, unit testing, mocking, JUnit, JUnit 5">
+    <meta name="author" content="Spock Framework Team">
+    <link rel="canonical" href="https://spockframework.org/">
+    <meta name="robots" content="index, follow">
+
+    <meta property="og:type" content="website">
+    <meta property="og:url" content="https://spockframework.org/"> <meta property="og:title" content="Spock Framework - the enterprise ready specification framework">
+    <meta property="og:description" content="Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity. By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.">
+    <meta property="og:image" content="spock-main-logo.svg">
+    <meta property="twitter:card" content="summary">
+    <meta property="twitter:url" content="https://spockframework.org/"> <meta property="twitter:title" content="Spock Framework - the enterprise ready specification framework">
+    <meta property="twitter:description" content="Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity. By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.">
+    <meta property="twitter:image" content="spock-main-logo.svg">
+
     <script src="https://cdn.tailwindcss.com"></script>
     <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet"
           integrity="sha384-/rJKQnzOkEo+daG0jMjU1IwwY9unxt1NBw3Ef2fmOJ3PW/TfAg2KXVoWwMZQZtw9"
@@ -229,7 +244,7 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Powerful Mocking</h3>
             <div class="feature-card" data-aos="fade-up" data-aos-delay="200">
                 <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" /></svg>
                 <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Platform</h3>
-                <p class="text-gray-300">Seamless integration with JUnit Platform and build tools.</p>
+                <p class="text-gray-300">Seamless integration with JUnit 5+ and build tools.</p>
             </div>
             <div class="feature-card" data-aos="fade-up" data-aos-delay="250">
                 <svg viewBox="0 0 24 24"><path d="M3 3h18v6H3zM3 15h18v6H3z" /><path d="M9 9v6" /></svg>

From bc74fffdd495bab989581e023d901eaf7f64f607 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 15:06:37 +0200
Subject: [PATCH 15/29] Moved to vite and tailwind for building

---
 .github/workflows/deploy.yaml                 |   51 +
 .gitignore                                    |   26 +
 compositor.json                               |  157 --
 index.html                                    |    8 +-
 spock-website/index.html                      |  267 +++
 spock-website/package-lock.json               | 1504 +++++++++++++++++
 spock-website/package.json                    |   19 +
 .../public/spock-main-logo.svg                |    0
 spock-website/src/main.ts                     |    1 +
 spock-website/src/style.css                   |  148 ++
 spock-website/src/vite-env.d.ts               |    1 +
 spock-website/tsconfig.json                   |   24 +
 spock-website/vite.config.ts                  |    9 +
 13 files changed, 2054 insertions(+), 161 deletions(-)
 create mode 100644 .github/workflows/deploy.yaml
 delete mode 100644 compositor.json
 create mode 100644 spock-website/index.html
 create mode 100644 spock-website/package-lock.json
 create mode 100644 spock-website/package.json
 rename spock-main-logo.svg => spock-website/public/spock-main-logo.svg (100%)
 create mode 100644 spock-website/src/main.ts
 create mode 100644 spock-website/src/style.css
 create mode 100644 spock-website/src/vite-env.d.ts
 create mode 100644 spock-website/tsconfig.json
 create mode 100644 spock-website/vite.config.ts

diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml
new file mode 100644
index 0000000..37c2e54
--- /dev/null
+++ b/.github/workflows/deploy.yaml
@@ -0,0 +1,51 @@
+# Simple workflow for deploying static content to GitHub Pages
+name: Deploy static content to Pages
+
+on:
+    # Runs on pushes targeting the default branch
+    push:
+        branches: [ 'main' ]
+
+    # Allows you to run this workflow manually from the Actions tab
+    workflow_dispatch:
+
+# Sets the GITHUB_TOKEN permissions to allow deployment to GitHub Pages
+permissions:
+    contents: read
+    pages: write
+    id-token: write
+
+# Allow one concurrent deployment
+concurrency:
+    group: 'pages'
+    cancel-in-progress: true
+
+jobs:
+    # Single deploy job since we're just deploying
+    deploy:
+        environment:
+            name: github-pages
+            url: ${{ steps.deployment.outputs.page_url }}
+        runs-on: ubuntu-latest
+        steps:
+            -   name: Checkout
+                uses: actions/checkout@v4
+            -   name: Set up Node
+                uses: actions/setup-node@v4
+                with:
+                    node-version: lts/*
+                    cache: 'npm'
+            -   name: Install dependencies
+                run: npm ci
+            -   name: Build
+                run: npm run build
+            -   name: Setup Pages
+                uses: actions/configure-pages@v4
+            -   name: Upload artifact
+                uses: actions/upload-pages-artifact@v3
+                with:
+                    # Upload dist folder
+                    path: './spock-website/dist'
+            -   name: Deploy to GitHub Pages
+                id: deployment
+                uses: actions/deploy-pages@v4
diff --git a/.gitignore b/.gitignore
index 9f11b75..0d3bb91 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,27 @@
 .idea/
+node_modules/
+
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist
+dist-ssr
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
diff --git a/compositor.json b/compositor.json
deleted file mode 100644
index ef69af2..0000000
--- a/compositor.json
+++ /dev/null
@@ -1,157 +0,0 @@
-{
-  "name": "spockframework/spockframework.github.io",
-  "version": "0.1.4",
-  "libraries": {
-    "xv": "^1.1.21"
-  },
-  "title": "Spock",
-  "branch": "",
-  "style": {
-    "name": "Default",
-    "componentSet": {
-      "nav": "nav/BasicNav",
-      "header": "header/BannerHeader",
-      "article": "article/BasicArticle",
-      "footer": "footer/BasicFooter"
-    },
-    "fontFamily": "-apple-system, BlinkMacSystemFont, sans-serif",
-    "fontWeight": 400,
-    "bold": 600,
-    "lineHeight": 1.5,
-    "typeScale": [
-      72,
-      48,
-      24,
-      20,
-      16,
-      14,
-      12
-    ],
-    "monospace": "Menlo, monospace",
-    "heading": {
-      "fontFamily": null,
-      "fontStyle": null,
-      "fontWeight": 600,
-      "lineHeight": 1.25,
-      "textTransform": null,
-      "letterSpacing": null,
-      "h0": {},
-      "h1": {},
-      "h2": {},
-      "h3": {},
-      "h4": {},
-      "h5": {},
-      "h6": {}
-    },
-    "alternativeText": {},
-    "space": [
-      0,
-      8,
-      16,
-      32,
-      48,
-      64,
-      96
-    ],
-    "layout": {
-      "maxWidth": 1024,
-      "centered": false
-    },
-    "colors": {
-      "text": "#111",
-      "background": "#fff",
-      "primary": "#08e",
-      "secondary": "#059",
-      "highlight": "#e08",
-      "border": "#ddd",
-      "muted": "#eee"
-    },
-    "border": {
-      "width": 1,
-      "radius": 2
-    },
-    "link": {},
-    "button": {
-      "hover": {
-        "boxShadow": "inset 0 0 0 999px rgba(0, 0, 0, .125)"
-      }
-    },
-    "input": {},
-    "body": {
-      "margin": 0
-    },
-    "breakpoints": {
-      "xs": "@media screen and (max-width:40em)",
-      "sm": "@media screen and (min-width:40em)",
-      "md": "@media screen and (min-width:52em)",
-      "lg": "@media screen and (min-width:64em)"
-    }
-  },
-  "content": [
-    {
-      "component": "header",
-      "heading": "Spock",
-      "subhead": "the enterprise ready specification framework",
-      "children": [
-        {
-          "component": "ui/TweetButton",
-          "text": "spockframework.github.io: Spock project homepage",
-          "url": null
-        },
-        {
-          "component": "ui/GithubButton",
-          "user": "spockframework",
-          "repo": "spockframework.github.io"
-        }
-      ],
-      "links": [
-        {
-          "href": "http://docs.spockframework.org/",
-          "text": "Documentation"
-        },
-        {
-          "href": "http://github.spockframework.org/",
-          "text": "Source"
-        },
-        {
-          "href": "http://issues.spockframework.org/",
-          "text": "Issues"
-        },
-        {
-          "href": "http://forum.spockframework.org/",
-          "text": "Forum"
-        }
-      ],
-      "slug": ""
-    },
-    {
-      "component": "article",
-      "metadata": {
-        "source": "github.readme"
-      },
-      "html": "<h2>What is it?</h2>\n<p>Spock is a testing and specification framework for Java and Groovy applications. What makes it stand out from the crowd is its beautiful and highly expressive specification language. Thanks to its JUnit runner, Spock is compatible with most IDEs, build tools, and continuous integration servers. Spock is inspired from <a href=\"http://www.junit.org/\">JUnit</a>, <a href=\"http://rspec.info/\">RSpec</a>, <a href=\"http://www.jmock.org/\">jMock</a>, <a href=\"http://www.mockito.org\">Mockito</a>, <a href=\"http://groovy.codehaus.org/\">Groovy</a>, <a href=\"http://www.scala-lang.org/\">Scala</a>, <a href=\"http://en.wikipedia.org/wiki/Vulcans\">Vulcans</a>, and other fascinating life forms.</p>\n<h2>How Do I Get Started?</h2>\n<p>Read ten reasons why Spock is for you, run your first spec in <a href=\"http://meetspock.appspot.com/?id=9001\">Spock Web Console</a>, fork the <a href=\"https://github.com/spockframework/spock-example\">spock-example</a> project, learn how to write a specification, or dive into the <a href=\"http://docs.spockframework.org\">reference documentation</a>.</p>\n<h2>Install</h2>\n<h3>with Gradle</h3>\n<pre><span class=\"hljs-selector-tag\">testCompile</span> &quot;<span class=\"hljs-selector-tag\">org</span><span class=\"hljs-selector-class\">.spockframework</span><span class=\"hljs-selector-pseudo\">:spock-core</span><span class=\"hljs-selector-pseudo\">:1.1-groovy-2.4-rc-2&quot;</span></pre><h3>with Maven:</h3>\n<pre><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId</span>&gt;</span>org.spockframework<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">groupId</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId</span>&gt;</span>spock-core<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">artifactId</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">version</span>&gt;</span>1.1-groovy-2.4-rc-2<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">version</span>&gt;</span>\n  <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">scope</span>&gt;</span>test<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">scope</span>&gt;</span>\n<span class=\"hljs-tag\">&lt;/<span class=\"hljs-name\">dependency</span>&gt;</span></pre><h2>Where Are The Docs?</h2>\n<ul>\n<li>Reference Documentation: <a href=\"http://docs.spockframework.org\">http://docs.spockframework.org</a></li>\n<li>Wiki (old): <a href=\"http://wiki.spockframework.org\">http://wiki.spockframework.org</a></li>\n<li>Javadoc: <a href=\"http://javadoc.spockframework.org/latest\">http://javadoc.spockframework.org/latest</a></li>\n</ul>\n<h2>How Can I Get Involved?</h2>\n<ul>\n<li>Source Code: <a href=\"http://github.spockframework.org\">http://github.spockframework.org</a></li>\n<li>Issue Tracker: <a href=\"http://issues.spockframework.org\">http://issues.spockframework.org</a></li>\n<li>Discussion Forum: <a href=\"http://forum.spockframework.org\">http://forum.spockframework.org</a></li>\n<li>Continuous Build: <a href=\"http://builds.spockframework.org\">http://builds.spockframework.org</a></li>\n</ul>\n<h3>Supporters</h3>\n<p>Thanks to JetBrains for providing <a href=\"http://www.jetbrains.com/idea/\">IDEA</a> and <a href=\"http://www.jetbrains.com/teamcity/\">TeamCity</a> licenses.</p>\n<p>YourKit is kindly supporting open source projects with its full-featured Java Profiler.</p>\n<p>YourKit, LLC is the creator of innovative and intelligent tools for profiling\nJava and .NET applications. Take a look at YourKit&apos;s leading software products:\n<a href=\"http://www.yourkit.com/java/profiler/index.jsp\">YourKit Java Profiler</a> and\n<a href=\"http://www.yourkit.com/.net/profiler/index.jsp\">YourKit .NET Profiler</a>.</p>\n"
-    },
-    {
-      "component": "footer",
-      "links": [
-        {
-          "href": "https://github.com/spockframework/spock",
-          "text": "GitHub"
-        },
-        {
-          "href": "https://github.com/spockframework/spock/issues",
-          "text": "Issues"
-        },
-        {
-          "href": "http://forum.spockframework.org/",
-          "text": "Forum"
-        },
-        {
-          "href": "http://docs.spockframework.org/",
-          "text": "Documentation"
-        }
-      ],
-      "heading": ""
-    }
-  ]
-}
\ No newline at end of file
diff --git a/index.html b/index.html
index a12b0f1..bfe7528 100644
--- a/index.html
+++ b/index.html
@@ -3,7 +3,7 @@
 <head>
     <meta charset="UTF-8">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Spock Framework - the enterprise ready specification framework</title>
+    <title>Spock Framework - the enterprise-ready specification framework</title>
     <meta name="description" content="Spock is an expressive testing and specification framework for Java and Groovy applications. Write highly readable, maintainable BDD-style tests with powerful mocking.">
     <meta name="keywords" content="Spock Framework, Groovy, Java, Kotlin, JVM, testing, specification, BDD, Behavior-Driven Development, unit testing, mocking, JUnit, JUnit 5">
     <meta name="author" content="Spock Framework Team">
@@ -11,11 +11,11 @@
     <meta name="robots" content="index, follow">
 
     <meta property="og:type" content="website">
-    <meta property="og:url" content="https://spockframework.org/"> <meta property="og:title" content="Spock Framework - the enterprise ready specification framework">
+    <meta property="og:url" content="https://spockframework.org/"> <meta property="og:title" content="Spock Framework - the enterprise-ready specification framework">
     <meta property="og:description" content="Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity. By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.">
     <meta property="og:image" content="spock-main-logo.svg">
     <meta property="twitter:card" content="summary">
-    <meta property="twitter:url" content="https://spockframework.org/"> <meta property="twitter:title" content="Spock Framework - the enterprise ready specification framework">
+    <meta property="twitter:url" content="https://spockframework.org/"> <meta property="twitter:title" content="Spock Framework - the enterprise-ready specification framework">
     <meta property="twitter:description" content="Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity. By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.">
     <meta property="twitter:image" content="spock-main-logo.svg">
 
@@ -190,7 +190,7 @@ <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text">
             Spock
         </h1>
         <p class="text-xl md:text-2xl text-gray-400 mb-8">
-            the enterprise ready specification framework
+            the enterprise-ready specification framework
         </p>
         <p class="max-w-3xl mx-auto text-lg text-gray-300 mb-12">
             Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity.
diff --git a/spock-website/index.html b/spock-website/index.html
new file mode 100644
index 0000000..024487c
--- /dev/null
+++ b/spock-website/index.html
@@ -0,0 +1,267 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Spock Framework - the enterprise-ready specification framework</title>
+    <meta name="description" content="Spock is an expressive testing and specification framework for Java and Groovy applications. Write highly readable, maintainable BDD-style tests with powerful mocking.">
+    <meta name="keywords" content="Spock Framework, Groovy, Java, Kotlin, JVM, testing, specification, BDD, Behavior-Driven Development, unit testing, mocking, JUnit, JUnit 5">
+    <meta name="author" content="Spock Framework Team">
+    <link rel="canonical" href="https://spockframework.org/">
+    <meta name="robots" content="index, follow">
+
+    <meta property="og:type" content="website">
+    <meta property="og:url" content="https://spockframework.org/"> <meta property="og:title" content="Spock Framework - the enterprise-ready specification framework">
+    <meta property="og:description" content="Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity. By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.">
+    <meta property="og:image" content="spock-main-logo.svg">
+    <meta property="twitter:card" content="summary">
+    <meta property="twitter:url" content="https://spockframework.org/"> <meta property="twitter:title" content="Spock Framework - the enterprise-ready specification framework">
+    <meta property="twitter:description" content="Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity. By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.">
+    <meta property="twitter:image" content="spock-main-logo.svg">
+
+    <link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet"
+          integrity="sha384-/rJKQnzOkEo+daG0jMjU1IwwY9unxt1NBw3Ef2fmOJ3PW/TfAg2KXVoWwMZQZtw9"
+          crossorigin="anonymous">
+    <link rel="preconnect" href="https://fonts.googleapis.com">
+    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
+    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
+</head>
+<body class="leading-normal tracking-normal">
+
+<section class="pt-24 pb-16 md:pt-32 md:pb-24 bg-gray-800">
+    <div class="container mx-auto px-6 text-center">
+        <div class="mb-8">
+            <img
+                src="spock-main-logo.svg"
+                alt="Spock Framework Logo"
+                class="h-64 w-auto mx-auto block logo-img">
+        </div>
+
+        <h1 class="text-4xl md:text-5xl lg:text-6xl font-bold mb-4 spock-blue-text">
+            Spock
+        </h1>
+        <p class="text-xl md:text-2xl text-gray-400 mb-8">
+            the enterprise-ready specification framework
+        </p>
+        <p class="max-w-3xl mx-auto text-lg text-gray-300 mb-12">
+            Spock is a testing, specification, and mocking framework for JVM developers that emphasizes readability and clarity.
+            By blending BDD concepts and Groovy's concise syntax, Spock helps teams write tests that are easy to understand and enjoyable to maintain.
+        </p>
+    </div>
+</section>
+
+<section class="py-16 md:py-24">
+    <div class="container mx-auto px-6 text-center">
+        <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up">Ready to Improve Your Testing?</h2>
+
+        <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-up" data-aos-delay="200">
+            <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
+                Try it online
+            </a>
+            <a href="https://docs.spockframework.org" target="_blank" class="cta-button cta-secondary">
+                Read the Docs
+            </a>
+            <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary">
+                Clone the Example Project
+            </a>
+        </div>
+    </div>
+    <div class="container mx-auto px-6 text-center spock-blue-text text-md additional-links flex flex-wrap justify-center items-center gap-y-2 pt-8" data-aos="fade-up" data-aos-delay="300">
+        <a href="https://spockframework.org/spock/javadoc/current" class="mx-3 hover-underline-animation">JavaDoc</a> <span class="link-separator">|</span>
+        <a href="https://github.com/spockframework/spock" class="mx-3 hover-underline-animation">Source Code</a> <span class="link-separator">|</span>
+        <a href="https://github.com/spockframework/spock/issues" class="mx-3 hover-underline-animation">Issue Tracker</a> <span class="link-separator">|</span>
+        <a href="https://github.com/spockframework/spock/discussions" class="mx-3 hover-underline-animation">Discussions</a> <span class="link-separator">|</span>
+        <a href="https://gitter.im/spockframework/spock" class="mx-3 hover-underline-animation">Chat</a>
+    </div>
+</section>
+
+
+<section class="py-16 md:py-24 bg-gray-800">
+    <div class="container mx-auto px-6">
+        <h2 class="text-3xl md:text-4xl font-bold text-center mb-16 text-gray-100" data-aos="fade-up">
+            Why Choose Spock?
+        </h2>
+        <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="100">
+                <svg viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="2"/></svg>
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Expressive Specifications</h3>
+                <p class="text-gray-300">Write tests that are easy to read and understand, even for non-programmers.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="150">
+                <svg viewBox="0 0 24 24"><path d="M3 17l6-6 4 4 8-8" /></svg>
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Powerful Mocking</h3>
+                <p class="text-gray-300">Create flexible and powerful mocks and stubs with built-in support.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="200">
+                <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" /></svg>
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Platform</h3>
+                <p class="text-gray-300">Seamless integration with JUnit 5+ and build tools.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="250">
+                <svg viewBox="0 0 24 24"><path d="M3 3h18v6H3zM3 15h18v6H3z" /><path d="M9 9v6" /></svg>
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Data-Driven Testing</h3>
+                <p class="text-gray-300">Easily run the same test with different sets of data.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="300">
+                <svg viewBox="0 0 24 24"><polygon points="12 2 15 8 22 9 17 14 18 21 12 18 6 21 7 14 2 9 9 8 12 2" /></svg>
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Groovy DSL</h3>
+                <p class="text-gray-300">Leverage the power and flexibility of the Groovy language.</p>
+            </div>
+            <div class="feature-card" data-aos="fade-up" data-aos-delay="350">
+                <svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2" /><path d="M9 12l2 2 4-4" /></svg>
+                <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
+                <p class="text-gray-300">Use a rich set of matchers to verify expectations with clarity.</p>
+            </div>
+        </div>
+    </div>
+</section>
+
+<section class="py-16 md:py-24">
+    <div class="container mx-auto px-6">
+        <h2 class="text-3xl md:text-4xl font-bold text-center mb-12 text-gray-100" data-aos="fade-up">
+            See How Readable Tests Can Be
+        </h2>
+        <div class="max-w-3xl mx-auto" data-aos="fade-up" data-aos-delay="100">
+            <pre><code class="language-groovy"><span class="comment">// CalculatorSpec.groovy</span>
+<span class="keyword">import</span> spock.lang.Specification
+
+<span class="keyword">class</span> <span class="class-name">CalculatorSpec</span> <span class="keyword">extends</span> Specification {
+
+    <span class="keyword">def</span> <span class="string">"Test calculate method: #a #operation #b = #expectedResult"</span>() {
+        <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span>
+        <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>()
+
+        <span class="keyword">expect:</span> <span class="comment">"The calculation should match the expected value"</span>
+        calculator.calculate(a, b, operation) == expectedResult
+
+        <span class="keyword">where:</span> <span class="comment">"Define test data"</span>
+        a  | b  | operation || expectedResult
+        <span class="number">1</span>  | <span class="number">2</span>  | <span class="string">"+"</span>       || <span class="number">3</span>
+        <span class="number">5</span>  | <span class="number">3</span>  | <span class="string">"-"</span>       || <span class="number">2</span>
+        <span class="number">4</span>  | <span class="number">2</span>  | <span class="string">"*"</span>       || <span class="number">8</span>
+        <span class="number">10</span> | <span class="number">2</span>  | <span class="string">"/"</span>       || <span class="number">5</span>
+        <span class="number">-1</span> | <span class="number">1</span>  | <span class="string">"+"</span>       || <span class="number">0</span>
+        <span class="number">1</span>  | <span class="number">-1</span> | <span class="string">"-"</span>       || <span class="number">2</span>
+        <span class="number">-2</span> | <span class="number">-2</span> | <span class="string">"*"</span>       || <span class="number">4</span>
+        <span class="number">-4</span> | <span class="number">-2</span> | <span class="string">"/"</span>       || <span class="number">2</span>
+        <span class="number">1</span>  | <span class="number">1</span>  | <span class="string">"+"</span>       || <span class="number">42</span> <span class="comment">// A failing test case</span>
+    }
+
+    <span class="keyword">def</span> <span class="string">"Test calculate method with division by zero"</span>() {
+        <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span>
+        <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>()
+
+        <span class="keyword">when:</span> <span class="comment">"Perform division by zero"</span>
+        calculator.calculate(<span class="number">10</span>, <span class="number">0</span>, <span class="string">"/"</span>)
+
+        <span class="keyword">then:</span> <span class="comment">"An IllegalArgumentException is thrown"</span>
+        <span class="keyword">def</span> exception = thrown(<span class="class-name">IllegalArgumentException</span>)
+
+        <span class="keyword">and:</span> <span class="comment">"The exception message is correct"</span>
+        exception.message == <span class="string">"Cannot divide by zero"</span>
+    }
+
+    <span class="keyword">def</span> <span class="string">"Test calculate method with invalid operation"</span>() {
+        <span class="keyword">given:</span> <span class="comment">"A calculator instance"</span>
+        <span class="keyword">def</span> calculator = <span class="keyword">new</span> <span class="class-name">Calculator</span>()
+
+        <span class="keyword">when:</span> <span class="comment">"Perform calculation with invalid operation"</span>
+        calculator.calculate(<span class="number">1</span>, <span class="number">2</span>, <span class="string">"**"</span>)
+
+        <span class="keyword">then:</span> <span class="comment">"An IllegalArgumentException is thrown"</span>
+        <span class="keyword">def</span> exception = thrown(<span class="class-name">IllegalArgumentException</span>)
+
+        <span class="keyword">and:</span> <span class="comment">"The exception message is correct"</span>
+        exception.message == <span class="string">"Invalid operation: **"</span>
+    }
+}
+
+
+<span class="comment">// Calculator.groovy</span>
+<span class="keyword">class</span> <span class="class-name">Calculator</span> {
+<span class="comment">    /**
+     * Performs arithmetic operations on two integers.
+     *
+     * <span class="annotation">@param</span> a         The first integer.
+     * <span class="annotation">@param</span> b         The second integer.
+     * <span class="annotation">@param</span> operation The operation to perform (+, -, *, /).
+     * <span class="annotation">@return</span> The result of the operation.
+     * <span class="annotation">@throws</span> IllegalArgumentException if the operation is invalid or division by zero is attempted.
+     */</span>
+    <span class="keyword">int</span> calculate(<span class="keyword">int</span> a, <span class="keyword">int</span> b, <span class="class-name">String</span> operation) {
+        <span class="keyword">switch</span> (operation) {
+            <span class="keyword">case</span> <span class="string">"+"</span>: <span class="keyword">return</span> a + b
+            <span class="keyword">case</span> <span class="string">"-"</span>: <span class="keyword">return</span> a - b
+            <span class="keyword">case</span> <span class="string">"*"</span>: <span class="keyword">return</span> a * b
+            <span class="keyword">case</span> <span class="string">"/"</span>:
+                <span class="keyword">if</span> (b == <span class="number">0</span>) {
+                    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class-name">IllegalArgumentException</span>(<span class="string">"Cannot divide by zero"</span>)
+                }
+                <span class="keyword">return</span> a / b
+            <span class="keyword">default</span>:
+                <span class="keyword">throw</span> <span class="keyword">new</span> <span class="class-name">IllegalArgumentException</span>(<span class="string">"Invalid operation: "</span> + operation)
+        }
+    }
+
+    <span class="class-name">String</span> toString() {
+        <span class="keyword">return</span> <span class="string">"Calc"</span>
+    }
+}
+</code></pre>
+            <p class="text-center text-gray-400 mt-6" data-aos="fade-up" data-aos-delay="200">
+                Spock's clear <code class="inline-code">given:</code>, <code class="inline-code">when:</code>, <code class="inline-code">then:</code> blocks make understanding test logic intuitive.
+            </p>
+            <div class="mt-12" data-aos="fade-up" data-aos-delay="500">
+                <h3 class="text-xl font-semibold text-center mb-4 text-gray-100">Example Test Output:</h3>
+                <pre>â•·
+└─ Spock ✔
+   └─ CalculatorSpec ✔
+      ├─ Test calculate method: #a #operation #b = #expectedResult ✔
+      │  ├─ Test calculate method: 1 + 2 = 3 ✔
+      │  ├─ Test calculate method: 5 - 3 = 2 ✔
+      │  ├─ Test calculate method: 4 * 2 = 8 ✔
+      │  ├─ Test calculate method: 10 / 2 = 5 ✔
+      │  ├─ Test calculate method: -1 + 1 = 0 ✔
+      │  ├─ Test calculate method: 1 - -1 = 2 ✔
+      │  ├─ Test calculate method: -2 * -2 = 4 ✔
+      │  ├─ Test calculate method: -4 / -2 = 2 ✔
+      │  └─ Test calculate method: 1 + 1 = 42 ✘ Condition not satisfied:
+      │
+      │           calculator.calculate(a, b, operation) == expectedResult
+      │           |          |         |  |  |          |  |
+      │           Calc       2         1  1  +          |  42
+      │                                                 false
+      ├─ Test calculate method with division by zero ✔
+      └─ Test calculate method with invalid operation ✔</pre>
+            </div>
+        </div>
+    </div>
+    <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4 mt-8" data-aos="fade-up" data-aos-delay="800">
+        <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
+            Try it online
+        </a>
+    </div>
+</section>
+
+<footer class="py-8 text-center text-gray-400 text-sm">
+    <div class="container mx-auto px-6">
+        &copy; 2025 Spock Framework Team. All rights reserved.
+    </div>
+</footer>
+
+
+<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"
+        integrity="sha384-wziAfh6b/qT+3LrqebF9WeK4+J5sehS6FA10J1t3a866kJ/fvU5UwofWnQyzLtwu"
+        crossorigin="anonymous"></script>
+<script>
+    // Initialize AOS library
+    AOS.init({
+        duration: 800, // Animation duration
+        once: true, // Whether animation should happen only once - while scrolling down
+        offset: 50, // Offset (in px) from the original trigger point
+    });
+</script>
+
+<script type="module" src="/src/main.ts"></script>
+</body>
+</html>
diff --git a/spock-website/package-lock.json b/spock-website/package-lock.json
new file mode 100644
index 0000000..4b51682
--- /dev/null
+++ b/spock-website/package-lock.json
@@ -0,0 +1,1504 @@
+{
+  "name": "spock-website",
+  "version": "0.0.0",
+  "lockfileVersion": 3,
+  "requires": true,
+  "packages": {
+    "": {
+      "name": "spock-website",
+      "version": "0.0.0",
+      "dependencies": {
+        "@tailwindcss/vite": "^4.1.4",
+        "tailwindcss": "^4.1.4"
+      },
+      "devDependencies": {
+        "typescript": "~5.7.2",
+        "vite": "^6.3.1"
+      }
+    },
+    "node_modules/@esbuild/aix-ppc64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz",
+      "integrity": "sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==",
+      "cpu": [
+        "ppc64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "aix"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-arm": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.2.tgz",
+      "integrity": "sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-arm64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.2.tgz",
+      "integrity": "sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/android-x64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.2.tgz",
+      "integrity": "sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/darwin-arm64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.2.tgz",
+      "integrity": "sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/darwin-x64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.2.tgz",
+      "integrity": "sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/freebsd-arm64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.2.tgz",
+      "integrity": "sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/freebsd-x64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.2.tgz",
+      "integrity": "sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-arm": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.2.tgz",
+      "integrity": "sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-arm64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.2.tgz",
+      "integrity": "sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-ia32": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.2.tgz",
+      "integrity": "sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==",
+      "cpu": [
+        "ia32"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-loong64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.2.tgz",
+      "integrity": "sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==",
+      "cpu": [
+        "loong64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-mips64el": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.2.tgz",
+      "integrity": "sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==",
+      "cpu": [
+        "mips64el"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-ppc64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.2.tgz",
+      "integrity": "sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==",
+      "cpu": [
+        "ppc64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-riscv64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.2.tgz",
+      "integrity": "sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==",
+      "cpu": [
+        "riscv64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-s390x": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.2.tgz",
+      "integrity": "sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==",
+      "cpu": [
+        "s390x"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/linux-x64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.2.tgz",
+      "integrity": "sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/netbsd-arm64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.2.tgz",
+      "integrity": "sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/netbsd-x64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.2.tgz",
+      "integrity": "sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "netbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/openbsd-arm64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.2.tgz",
+      "integrity": "sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/openbsd-x64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.2.tgz",
+      "integrity": "sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openbsd"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/sunos-x64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.2.tgz",
+      "integrity": "sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "sunos"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-arm64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.2.tgz",
+      "integrity": "sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-ia32": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.2.tgz",
+      "integrity": "sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==",
+      "cpu": [
+        "ia32"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@esbuild/win32-x64": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.2.tgz",
+      "integrity": "sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/@rollup/rollup-android-arm-eabi": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz",
+      "integrity": "sha512-+Fbls/diZ0RDerhE8kyC6hjADCXA1K4yVNlH0EYfd2XjyH0UGgzaQ8MlT0pCXAThfxv3QUAczHaL+qSv1E4/Cg==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-android-arm64": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.0.tgz",
+      "integrity": "sha512-PPA6aEEsTPRz+/4xxAmaoWDqh67N7wFbgFUJGMnanCFs0TV99M0M8QhhaSCks+n6EbQoFvLQgYOGXxlMGQe/6w==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-arm64": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.0.tgz",
+      "integrity": "sha512-GwYOcOakYHdfnjjKwqpTGgn5a6cUX7+Ra2HeNj/GdXvO2VJOOXCiYYlRFU4CubFM67EhbmzLOmACKEfvp3J1kQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-darwin-x64": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.0.tgz",
+      "integrity": "sha512-CoLEGJ+2eheqD9KBSxmma6ld01czS52Iw0e2qMZNpPDlf7Z9mj8xmMemxEucinev4LgHalDPczMyxzbq+Q+EtA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-arm64": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.0.tgz",
+      "integrity": "sha512-r7yGiS4HN/kibvESzmrOB/PxKMhPTlz+FcGvoUIKYoTyGd5toHp48g1uZy1o1xQvybwwpqpe010JrcGG2s5nkg==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-freebsd-x64": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.0.tgz",
+      "integrity": "sha512-mVDxzlf0oLzV3oZOr0SMJ0lSDd3xC4CmnWJ8Val8isp9jRGl5Dq//LLDSPFrasS7pSm6m5xAcKaw3sHXhBjoRw==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.0.tgz",
+      "integrity": "sha512-y/qUMOpJxBMy8xCXD++jeu8t7kzjlOCkoxxajL58G62PJGBZVl/Gwpm7JK9+YvlB701rcQTzjUZ1JgUoPTnoQA==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.0.tgz",
+      "integrity": "sha512-GoCsPibtVdJFPv/BOIvBKO/XmwZLwaNWdyD8TKlXuqp0veo2sHE+A/vpMQ5iSArRUz/uaoj4h5S6Pn0+PdhRjg==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-gnu": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.0.tgz",
+      "integrity": "sha512-L5ZLphTjjAD9leJzSLI7rr8fNqJMlGDKlazW2tX4IUF9P7R5TMQPElpH82Q7eNIDQnQlAyiNVfRPfP2vM5Avvg==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-arm64-musl": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.0.tgz",
+      "integrity": "sha512-ATZvCRGCDtv1Y4gpDIXsS+wfFeFuLwVxyUBSLawjgXK2tRE6fnsQEkE4csQQYWlBlsFztRzCnBvWVfcae/1qxQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.0.tgz",
+      "integrity": "sha512-wG9e2XtIhd++QugU5MD9i7OnpaVb08ji3P1y/hNbxrQ3sYEelKJOq1UJ5dXczeo6Hj2rfDEL5GdtkMSVLa/AOg==",
+      "cpu": [
+        "loong64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.0.tgz",
+      "integrity": "sha512-vgXfWmj0f3jAUvC7TZSU/m/cOE558ILWDzS7jBhiCAFpY2WEBn5jqgbqvmzlMjtp8KlLcBlXVD2mkTSEQE6Ixw==",
+      "cpu": [
+        "ppc64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.0.tgz",
+      "integrity": "sha512-uJkYTugqtPZBS3Z136arevt/FsKTF/J9dEMTX/cwR7lsAW4bShzI2R0pJVw+hcBTWF4dxVckYh72Hk3/hWNKvA==",
+      "cpu": [
+        "riscv64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-riscv64-musl": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.0.tgz",
+      "integrity": "sha512-rKmSj6EXQRnhSkE22+WvrqOqRtk733x3p5sWpZilhmjnkHkpeCgWsFFo0dGnUGeA+OZjRl3+VYq+HyCOEuwcxQ==",
+      "cpu": [
+        "riscv64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-s390x-gnu": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.0.tgz",
+      "integrity": "sha512-SpnYlAfKPOoVsQqmTFJ0usx0z84bzGOS9anAC0AZ3rdSo3snecihbhFTlJZ8XMwzqAcodjFU4+/SM311dqE5Sw==",
+      "cpu": [
+        "s390x"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-gnu": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.0.tgz",
+      "integrity": "sha512-RcDGMtqF9EFN8i2RYN2W+64CdHruJ5rPqrlYw+cgM3uOVPSsnAQps7cpjXe9be/yDp8UC7VLoCoKC8J3Kn2FkQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-linux-x64-musl": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.0.tgz",
+      "integrity": "sha512-HZvjpiUmSNx5zFgwtQAV1GaGazT2RWvqeDi0hV+AtC8unqqDSsaFjPxfsO6qPtKRRg25SisACWnJ37Yio8ttaw==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-arm64-msvc": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.0.tgz",
+      "integrity": "sha512-UtZQQI5k/b8d7d3i9AZmA/t+Q4tk3hOC0tMOMSq2GlMYOfxbesxG4mJSeDp0EHs30N9bsfwUvs3zF4v/RzOeTQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-ia32-msvc": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.0.tgz",
+      "integrity": "sha512-+m03kvI2f5syIqHXCZLPVYplP8pQch9JHyXKZ3AGMKlg8dCyr2PKHjwRLiW53LTrN/Nc3EqHOKxUxzoSPdKddA==",
+      "cpu": [
+        "ia32"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@rollup/rollup-win32-x64-msvc": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.0.tgz",
+      "integrity": "sha512-lpPE1cLfP5oPzVjKMx10pgBmKELQnFJXHgvtHCtuJWOv8MxqdEIMNtgHgBFf7Ea2/7EuVwa9fodWUfXAlXZLZQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ]
+    },
+    "node_modules/@tailwindcss/node": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/node/-/node-4.1.4.tgz",
+      "integrity": "sha512-MT5118zaiO6x6hNA04OWInuAiP1YISXql8Z+/Y8iisV5nuhM8VXlyhRuqc2PEviPszcXI66W44bCIk500Oolhw==",
+      "license": "MIT",
+      "dependencies": {
+        "enhanced-resolve": "^5.18.1",
+        "jiti": "^2.4.2",
+        "lightningcss": "1.29.2",
+        "tailwindcss": "4.1.4"
+      }
+    },
+    "node_modules/@tailwindcss/oxide": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.1.4.tgz",
+      "integrity": "sha512-p5wOpXyOJx7mKh5MXh5oKk+kqcz8T+bA3z/5VWWeQwFrmuBItGwz8Y2CHk/sJ+dNb9B0nYFfn0rj/cKHZyjahQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 10"
+      },
+      "optionalDependencies": {
+        "@tailwindcss/oxide-android-arm64": "4.1.4",
+        "@tailwindcss/oxide-darwin-arm64": "4.1.4",
+        "@tailwindcss/oxide-darwin-x64": "4.1.4",
+        "@tailwindcss/oxide-freebsd-x64": "4.1.4",
+        "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.4",
+        "@tailwindcss/oxide-linux-arm64-gnu": "4.1.4",
+        "@tailwindcss/oxide-linux-arm64-musl": "4.1.4",
+        "@tailwindcss/oxide-linux-x64-gnu": "4.1.4",
+        "@tailwindcss/oxide-linux-x64-musl": "4.1.4",
+        "@tailwindcss/oxide-wasm32-wasi": "4.1.4",
+        "@tailwindcss/oxide-win32-arm64-msvc": "4.1.4",
+        "@tailwindcss/oxide-win32-x64-msvc": "4.1.4"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-android-arm64": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.1.4.tgz",
+      "integrity": "sha512-xMMAe/SaCN/vHfQYui3fqaBDEXMu22BVwQ33veLc8ep+DNy7CWN52L+TTG9y1K397w9nkzv+Mw+mZWISiqhmlA==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "android"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-darwin-arm64": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.1.4.tgz",
+      "integrity": "sha512-JGRj0SYFuDuAGilWFBlshcexev2hOKfNkoX+0QTksKYq2zgF9VY/vVMq9m8IObYnLna0Xlg+ytCi2FN2rOL0Sg==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-darwin-x64": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.1.4.tgz",
+      "integrity": "sha512-sdDeLNvs3cYeWsEJ4H1DvjOzaGios4QbBTNLVLVs0XQ0V95bffT3+scptzYGPMjm7xv4+qMhCDrkHwhnUySEzA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-freebsd-x64": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.1.4.tgz",
+      "integrity": "sha512-VHxAqxqdghM83HslPhRsNhHo91McsxRJaEnShJOMu8mHmEj9Ig7ToHJtDukkuLWLzLboh2XSjq/0zO6wgvykNA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-linux-arm-gnueabihf": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.1.4.tgz",
+      "integrity": "sha512-OTU/m/eV4gQKxy9r5acuesqaymyeSCnsx1cFto/I1WhPmi5HDxX1nkzb8KYBiwkHIGg7CTfo/AcGzoXAJBxLfg==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-linux-arm64-gnu": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.1.4.tgz",
+      "integrity": "sha512-hKlLNvbmUC6z5g/J4H+Zx7f7w15whSVImokLPmP6ff1QqTVE+TxUM9PGuNsjHvkvlHUtGTdDnOvGNSEUiXI1Ww==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-linux-arm64-musl": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.1.4.tgz",
+      "integrity": "sha512-X3As2xhtgPTY/m5edUtddmZ8rCruvBvtxYLMw9OsZdH01L2gS2icsHRwxdU0dMItNfVmrBezueXZCHxVeeb7Aw==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-linux-x64-gnu": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.1.4.tgz",
+      "integrity": "sha512-2VG4DqhGaDSmYIu6C4ua2vSLXnJsb/C9liej7TuSO04NK+JJJgJucDUgmX6sn7Gw3Cs5ZJ9ZLrnI0QRDOjLfNQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-linux-x64-musl": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.1.4.tgz",
+      "integrity": "sha512-v+mxVgH2kmur/X5Mdrz9m7TsoVjbdYQT0b4Z+dr+I4RvreCNXyCFELZL/DO0M1RsidZTrm6O1eMnV6zlgEzTMQ==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-wasm32-wasi": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.1.4.tgz",
+      "integrity": "sha512-2TLe9ir+9esCf6Wm+lLWTMbgklIjiF0pbmDnwmhR9MksVOq+e8aP3TSsXySnBDDvTTVd/vKu1aNttEGj3P6l8Q==",
+      "bundleDependencies": [
+        "@napi-rs/wasm-runtime",
+        "@emnapi/core",
+        "@emnapi/runtime",
+        "@tybys/wasm-util",
+        "@emnapi/wasi-threads",
+        "tslib"
+      ],
+      "cpu": [
+        "wasm32"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "dependencies": {
+        "@emnapi/core": "^1.4.0",
+        "@emnapi/runtime": "^1.4.0",
+        "@emnapi/wasi-threads": "^1.0.1",
+        "@napi-rs/wasm-runtime": "^0.2.8",
+        "@tybys/wasm-util": "^0.9.0",
+        "tslib": "^2.8.0"
+      },
+      "engines": {
+        "node": ">=14.0.0"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.1.4.tgz",
+      "integrity": "sha512-VlnhfilPlO0ltxW9/BgfLI5547PYzqBMPIzRrk4W7uupgCt8z6Trw/tAj6QUtF2om+1MH281Pg+HHUJoLesmng==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/oxide-win32-x64-msvc": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.1.4.tgz",
+      "integrity": "sha512-+7S63t5zhYjslUGb8NcgLpFXD+Kq1F/zt5Xv5qTv7HaFTG/DHyHD9GA6ieNAxhgyA4IcKa/zy7Xx4Oad2/wuhw==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 10"
+      }
+    },
+    "node_modules/@tailwindcss/vite": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/@tailwindcss/vite/-/vite-4.1.4.tgz",
+      "integrity": "sha512-4UQeMrONbvrsXKXXp/uxmdEN5JIJ9RkH7YVzs6AMxC/KC1+Np7WZBaNIco7TEjlkthqxZbt8pU/ipD+hKjm80A==",
+      "license": "MIT",
+      "dependencies": {
+        "@tailwindcss/node": "4.1.4",
+        "@tailwindcss/oxide": "4.1.4",
+        "tailwindcss": "4.1.4"
+      },
+      "peerDependencies": {
+        "vite": "^5.2.0 || ^6"
+      }
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
+      "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
+      "license": "MIT"
+    },
+    "node_modules/detect-libc": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+      "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
+      "license": "Apache-2.0",
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/enhanced-resolve": {
+      "version": "5.18.1",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
+      "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
+      "license": "MIT",
+      "dependencies": {
+        "graceful-fs": "^4.2.4",
+        "tapable": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/esbuild": {
+      "version": "0.25.2",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.2.tgz",
+      "integrity": "sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "bin": {
+        "esbuild": "bin/esbuild"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "optionalDependencies": {
+        "@esbuild/aix-ppc64": "0.25.2",
+        "@esbuild/android-arm": "0.25.2",
+        "@esbuild/android-arm64": "0.25.2",
+        "@esbuild/android-x64": "0.25.2",
+        "@esbuild/darwin-arm64": "0.25.2",
+        "@esbuild/darwin-x64": "0.25.2",
+        "@esbuild/freebsd-arm64": "0.25.2",
+        "@esbuild/freebsd-x64": "0.25.2",
+        "@esbuild/linux-arm": "0.25.2",
+        "@esbuild/linux-arm64": "0.25.2",
+        "@esbuild/linux-ia32": "0.25.2",
+        "@esbuild/linux-loong64": "0.25.2",
+        "@esbuild/linux-mips64el": "0.25.2",
+        "@esbuild/linux-ppc64": "0.25.2",
+        "@esbuild/linux-riscv64": "0.25.2",
+        "@esbuild/linux-s390x": "0.25.2",
+        "@esbuild/linux-x64": "0.25.2",
+        "@esbuild/netbsd-arm64": "0.25.2",
+        "@esbuild/netbsd-x64": "0.25.2",
+        "@esbuild/openbsd-arm64": "0.25.2",
+        "@esbuild/openbsd-x64": "0.25.2",
+        "@esbuild/sunos-x64": "0.25.2",
+        "@esbuild/win32-arm64": "0.25.2",
+        "@esbuild/win32-ia32": "0.25.2",
+        "@esbuild/win32-x64": "0.25.2"
+      }
+    },
+    "node_modules/fdir": {
+      "version": "6.4.4",
+      "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz",
+      "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==",
+      "license": "MIT",
+      "peerDependencies": {
+        "picomatch": "^3 || ^4"
+      },
+      "peerDependenciesMeta": {
+        "picomatch": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/fsevents": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
+    "node_modules/graceful-fs": {
+      "version": "4.2.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+      "license": "ISC"
+    },
+    "node_modules/jiti": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
+      "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
+      "license": "MIT",
+      "bin": {
+        "jiti": "lib/jiti-cli.mjs"
+      }
+    },
+    "node_modules/lightningcss": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.29.2.tgz",
+      "integrity": "sha512-6b6gd/RUXKaw5keVdSEtqFVdzWnU5jMxTUjA2bVcMNPLwSQ08Sv/UodBVtETLCn7k4S1Ibxwh7k68IwLZPgKaA==",
+      "license": "MPL-2.0",
+      "dependencies": {
+        "detect-libc": "^2.0.3"
+      },
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      },
+      "optionalDependencies": {
+        "lightningcss-darwin-arm64": "1.29.2",
+        "lightningcss-darwin-x64": "1.29.2",
+        "lightningcss-freebsd-x64": "1.29.2",
+        "lightningcss-linux-arm-gnueabihf": "1.29.2",
+        "lightningcss-linux-arm64-gnu": "1.29.2",
+        "lightningcss-linux-arm64-musl": "1.29.2",
+        "lightningcss-linux-x64-gnu": "1.29.2",
+        "lightningcss-linux-x64-musl": "1.29.2",
+        "lightningcss-win32-arm64-msvc": "1.29.2",
+        "lightningcss-win32-x64-msvc": "1.29.2"
+      }
+    },
+    "node_modules/lightningcss-darwin-arm64": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.29.2.tgz",
+      "integrity": "sha512-cK/eMabSViKn/PG8U/a7aCorpeKLMlK0bQeNHmdb7qUnBkNPnL+oV5DjJUo0kqWsJUapZsM4jCfYItbqBDvlcA==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-darwin-x64": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.29.2.tgz",
+      "integrity": "sha512-j5qYxamyQw4kDXX5hnnCKMf3mLlHvG44f24Qyi2965/Ycz829MYqjrVg2H8BidybHBp9kom4D7DR5VqCKDXS0w==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-freebsd-x64": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.29.2.tgz",
+      "integrity": "sha512-wDk7M2tM78Ii8ek9YjnY8MjV5f5JN2qNVO+/0BAGZRvXKtQrBC4/cn4ssQIpKIPP44YXw6gFdpUF+Ps+RGsCwg==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "freebsd"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-arm-gnueabihf": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.29.2.tgz",
+      "integrity": "sha512-IRUrOrAF2Z+KExdExe3Rz7NSTuuJ2HvCGlMKoquK5pjvo2JY4Rybr+NrKnq0U0hZnx5AnGsuFHjGnNT14w26sg==",
+      "cpu": [
+        "arm"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-arm64-gnu": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.29.2.tgz",
+      "integrity": "sha512-KKCpOlmhdjvUTX/mBuaKemp0oeDIBBLFiU5Fnqxh1/DZ4JPZi4evEH7TKoSBFOSOV3J7iEmmBaw/8dpiUvRKlQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-arm64-musl": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.29.2.tgz",
+      "integrity": "sha512-Q64eM1bPlOOUgxFmoPUefqzY1yV3ctFPE6d/Vt7WzLW4rKTv7MyYNky+FWxRpLkNASTnKQUaiMJ87zNODIrrKQ==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-x64-gnu": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.29.2.tgz",
+      "integrity": "sha512-0v6idDCPG6epLXtBH/RPkHvYx74CVziHo6TMYga8O2EiQApnUPZsbR9nFNrg2cgBzk1AYqEd95TlrsL7nYABQg==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-linux-x64-musl": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.29.2.tgz",
+      "integrity": "sha512-rMpz2yawkgGT8RULc5S4WiZopVMOFWjiItBT7aSfDX4NQav6M44rhn5hjtkKzB+wMTRlLLqxkeYEtQ3dd9696w==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "linux"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-win32-arm64-msvc": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.29.2.tgz",
+      "integrity": "sha512-nL7zRW6evGQqYVu/bKGK+zShyz8OVzsCotFgc7judbt6wnB2KbiKKJwBE4SGoDBQ1O94RjW4asrCjQL4i8Fhbw==",
+      "cpu": [
+        "arm64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/lightningcss-win32-x64-msvc": {
+      "version": "1.29.2",
+      "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.29.2.tgz",
+      "integrity": "sha512-EdIUW3B2vLuHmv7urfzMI/h2fmlnOQBk1xlsDxkN1tCWKjNFjfLhGxYk8C8mzpSfr+A6jFFIi8fU6LbQGsRWjA==",
+      "cpu": [
+        "x64"
+      ],
+      "license": "MPL-2.0",
+      "optional": true,
+      "os": [
+        "win32"
+      ],
+      "engines": {
+        "node": ">= 12.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/parcel"
+      }
+    },
+    "node_modules/nanoid": {
+      "version": "3.3.11",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+      "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "bin": {
+        "nanoid": "bin/nanoid.cjs"
+      },
+      "engines": {
+        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+      "license": "ISC"
+    },
+    "node_modules/picomatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+      "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
+    },
+    "node_modules/postcss": {
+      "version": "8.5.3",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+      "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/postcss/"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/postcss"
+        },
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/ai"
+        }
+      ],
+      "license": "MIT",
+      "dependencies": {
+        "nanoid": "^3.3.8",
+        "picocolors": "^1.1.1",
+        "source-map-js": "^1.2.1"
+      },
+      "engines": {
+        "node": "^10 || ^12 || >=14"
+      }
+    },
+    "node_modules/rollup": {
+      "version": "4.40.0",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.0.tgz",
+      "integrity": "sha512-Noe455xmA96nnqH5piFtLobsGbCij7Tu+tb3c1vYjNbTkfzGqXqQXG3wJaYXkRZuQ0vEYN4bhwg7QnIrqB5B+w==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/estree": "1.0.7"
+      },
+      "bin": {
+        "rollup": "dist/bin/rollup"
+      },
+      "engines": {
+        "node": ">=18.0.0",
+        "npm": ">=8.0.0"
+      },
+      "optionalDependencies": {
+        "@rollup/rollup-android-arm-eabi": "4.40.0",
+        "@rollup/rollup-android-arm64": "4.40.0",
+        "@rollup/rollup-darwin-arm64": "4.40.0",
+        "@rollup/rollup-darwin-x64": "4.40.0",
+        "@rollup/rollup-freebsd-arm64": "4.40.0",
+        "@rollup/rollup-freebsd-x64": "4.40.0",
+        "@rollup/rollup-linux-arm-gnueabihf": "4.40.0",
+        "@rollup/rollup-linux-arm-musleabihf": "4.40.0",
+        "@rollup/rollup-linux-arm64-gnu": "4.40.0",
+        "@rollup/rollup-linux-arm64-musl": "4.40.0",
+        "@rollup/rollup-linux-loongarch64-gnu": "4.40.0",
+        "@rollup/rollup-linux-powerpc64le-gnu": "4.40.0",
+        "@rollup/rollup-linux-riscv64-gnu": "4.40.0",
+        "@rollup/rollup-linux-riscv64-musl": "4.40.0",
+        "@rollup/rollup-linux-s390x-gnu": "4.40.0",
+        "@rollup/rollup-linux-x64-gnu": "4.40.0",
+        "@rollup/rollup-linux-x64-musl": "4.40.0",
+        "@rollup/rollup-win32-arm64-msvc": "4.40.0",
+        "@rollup/rollup-win32-ia32-msvc": "4.40.0",
+        "@rollup/rollup-win32-x64-msvc": "4.40.0",
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/source-map-js": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+      "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/tailwindcss": {
+      "version": "4.1.4",
+      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.4.tgz",
+      "integrity": "sha512-1ZIUqtPITFbv/DxRmDr5/agPqJwF69d24m9qmM1939TJehgY539CtzeZRjbLt5G6fSy/7YqqYsfvoTEw9xUI2A==",
+      "license": "MIT"
+    },
+    "node_modules/tapable": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
+      "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/tinyglobby": {
+      "version": "0.2.13",
+      "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz",
+      "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==",
+      "license": "MIT",
+      "dependencies": {
+        "fdir": "^6.4.4",
+        "picomatch": "^4.0.2"
+      },
+      "engines": {
+        "node": ">=12.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/SuperchupuDev"
+      }
+    },
+    "node_modules/typescript": {
+      "version": "5.7.3",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
+      "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
+    },
+    "node_modules/vite": {
+      "version": "6.3.2",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.2.tgz",
+      "integrity": "sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==",
+      "license": "MIT",
+      "dependencies": {
+        "esbuild": "^0.25.0",
+        "fdir": "^6.4.3",
+        "picomatch": "^4.0.2",
+        "postcss": "^8.5.3",
+        "rollup": "^4.34.9",
+        "tinyglobby": "^0.2.12"
+      },
+      "bin": {
+        "vite": "bin/vite.js"
+      },
+      "engines": {
+        "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/vitejs/vite?sponsor=1"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.3"
+      },
+      "peerDependencies": {
+        "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+        "jiti": ">=1.21.0",
+        "less": "*",
+        "lightningcss": "^1.21.0",
+        "sass": "*",
+        "sass-embedded": "*",
+        "stylus": "*",
+        "sugarss": "*",
+        "terser": "^5.16.0",
+        "tsx": "^4.8.1",
+        "yaml": "^2.4.2"
+      },
+      "peerDependenciesMeta": {
+        "@types/node": {
+          "optional": true
+        },
+        "jiti": {
+          "optional": true
+        },
+        "less": {
+          "optional": true
+        },
+        "lightningcss": {
+          "optional": true
+        },
+        "sass": {
+          "optional": true
+        },
+        "sass-embedded": {
+          "optional": true
+        },
+        "stylus": {
+          "optional": true
+        },
+        "sugarss": {
+          "optional": true
+        },
+        "terser": {
+          "optional": true
+        },
+        "tsx": {
+          "optional": true
+        },
+        "yaml": {
+          "optional": true
+        }
+      }
+    }
+  }
+}
diff --git a/spock-website/package.json b/spock-website/package.json
new file mode 100644
index 0000000..cf760ef
--- /dev/null
+++ b/spock-website/package.json
@@ -0,0 +1,19 @@
+{
+  "name": "spock-website",
+  "private": true,
+  "version": "0.0.0",
+  "type": "module",
+  "scripts": {
+    "dev": "vite",
+    "build": "tsc && vite build",
+    "preview": "vite preview"
+  },
+  "devDependencies": {
+    "typescript": "~5.7.2",
+    "vite": "^6.3.1"
+  },
+  "dependencies": {
+    "@tailwindcss/vite": "^4.1.4",
+    "tailwindcss": "^4.1.4"
+  }
+}
diff --git a/spock-main-logo.svg b/spock-website/public/spock-main-logo.svg
similarity index 100%
rename from spock-main-logo.svg
rename to spock-website/public/spock-main-logo.svg
diff --git a/spock-website/src/main.ts b/spock-website/src/main.ts
new file mode 100644
index 0000000..cab743a
--- /dev/null
+++ b/spock-website/src/main.ts
@@ -0,0 +1 @@
+import './style.css'
diff --git a/spock-website/src/style.css b/spock-website/src/style.css
new file mode 100644
index 0000000..b46ece7
--- /dev/null
+++ b/spock-website/src/style.css
@@ -0,0 +1,148 @@
+@import "tailwindcss";
+
+/* Custom styles - Dark theme is now default */
+body {
+    font-family: 'Inter', sans-serif;
+    /* Dark mode defaults */
+    background-color: #111827; /* Darker gray background */
+    color: #d1d5db; /* Lighter gray text */
+    transition: background-color 0.3s ease, color 0.3s ease; /* Smooth transition */
+}
+
+/* Spock primary color variable */
+:root {
+    --spock-blue: #1562ae;
+    --spock-blue-dark-text: #60a5fa; /* Lighter blue for text/links in dark */
+}
+.spock-blue-bg { background-color: var(--spock-blue); }
+/* Use the lighter blue for text elements in dark mode */
+.spock-blue-text { color: var(--spock-blue-dark-text); }
+.spock-blue-border { border-color: var(--spock-blue-dark-text); } /* Use lighter blue for borders */
+
+/* Style for code block */
+pre {
+    background-color: #2d3748; /* Dark background for code */
+    color: #e2e8f0; /* Light text for code */
+    padding: 1.5rem;
+    border-radius: 0.5rem; /* Rounded corners */
+    overflow-x: auto; /* Allow horizontal scrolling */
+    font-family: 'Courier New', Courier, monospace;
+    font-size: 0.9em;
+    line-height: 1.6;
+}
+/* Syntax highlighting colors */
+code .keyword { color: #9ae6b4; } /* Green */
+code .string { color: #fbd38d; } /* Orange */
+code .comment { color: #a0aec0; } /* Gray */
+code .class-name { color: #faf089; } /* Yellow */
+code .number { color: #fca5a5; } /* Red */
+
+/* Style for inline code elements within regular text */
+.inline-code {
+    color: #cbd5e1; /* Slightly lighter gray for inline code */
+    background-color: #374151; /* Slightly lighter dark background */
+    padding: 0.1em 0.4em;
+    border-radius: 0.25rem;
+    font-size: 0.875em; /* Slightly smaller font size */
+    font-family: 'Courier New', Courier, monospace;
+}
+
+
+/* Button Styling */
+.cta-button {
+    display: inline-block;
+    padding: 0.75rem 1.5rem;
+    border-radius: 0.5rem;
+    font-weight: 600;
+    text-align: center;
+    transition: all 0.3s ease;
+    border: 2px solid transparent;
+}
+/* Primary Button */
+.cta-primary {
+    background-color: var(--spock-blue); /* Original blue for background */
+    color: white;
+}
+.cta-primary:hover {
+    background-color: #115192; /* Darker blue on hover */
+    transform: translateY(-2px);
+    box-shadow: 0 4px 10px rgba(21, 98, 174, 0.3);
+}
+
+/* Secondary Button */
+.cta-secondary {
+    background-color: transparent;
+    color: var(--spock-blue-dark-text); /* Lighter blue text */
+    border-color: var(--spock-blue-dark-text); /* Lighter blue border */
+}
+/* Dark mode secondary button hover */
+.cta-secondary:hover {
+    background-color: rgba(59, 130, 246, 0.2); /* Lighter blue tint for dark bg */
+    transform: translateY(-2px);
+    box-shadow: 0 4px 10px rgba(59, 130, 246, 0.1);
+}
+
+/* Tertiary Button */
+.cta-tertiary {
+    background-color: #374151; /* Dark gray background */
+    color: #d1d5db; /* Light gray text */
+}
+.cta-tertiary:hover {
+    background-color: #4b5563; /* Slightly lighter dark gray on hover */
+    transform: translateY(-2px);
+    box-shadow: 0 4px 10px rgba(255, 255, 255, 0.05);
+}
+
+/* Simple underline animation for links */
+.hover-underline-animation {
+    display: inline-block;
+    position: relative;
+    color: var(--spock-blue-dark-text); /* Lighter blue for dark mode */
+    transition: color 0.3s ease;
+}
+
+.hover-underline-animation::after {
+    content: '';
+    position: absolute;
+    width: 100%;
+    transform: scaleX(0);
+    height: 2px;
+    bottom: 0;
+    left: 0;
+    background-color: var(--spock-blue-dark-text); /* Lighter blue underline */
+    transform-origin: bottom right;
+    transition: transform 0.25s ease-out, background-color 0.3s ease;
+}
+
+.hover-underline-animation:hover::after {
+    transform: scaleX(1);
+    transform-origin: bottom left;
+}
+
+/* Feature Card Styling */
+.feature-card {
+    background-color: #374151; /* Changed from #1f2937 for better contrast vs bg-gray-800 */
+    padding: 1.5rem; /* p-6 */
+    border-radius: 0.5rem; /* rounded-lg */
+    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); /* shadow-md */
+    transition: transform 0.3s ease, box-shadow 0.3s ease;
+}
+.feature-card:hover {
+    transform: translateY(-4px);
+    box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* shadow-lg */
+}
+
+.feature-card svg {
+    height: 40px;
+    margin-bottom: 1rem;
+    fill: none;
+    stroke: var(--spock-blue);
+    stroke-width: 2;
+}
+
+/* Additional Links Separator */
+.link-separator {
+    margin-left: 0.75rem; /* mx-3 */
+    margin-right: 0.75rem; /* mx-3 */
+    color: #4b5563; /* gray-600 */
+}
diff --git a/spock-website/src/vite-env.d.ts b/spock-website/src/vite-env.d.ts
new file mode 100644
index 0000000..11f02fe
--- /dev/null
+++ b/spock-website/src/vite-env.d.ts
@@ -0,0 +1 @@
+/// <reference types="vite/client" />
diff --git a/spock-website/tsconfig.json b/spock-website/tsconfig.json
new file mode 100644
index 0000000..a4883f2
--- /dev/null
+++ b/spock-website/tsconfig.json
@@ -0,0 +1,24 @@
+{
+  "compilerOptions": {
+    "target": "ES2020",
+    "useDefineForClassFields": true,
+    "module": "ESNext",
+    "lib": ["ES2020", "DOM", "DOM.Iterable"],
+    "skipLibCheck": true,
+
+    /* Bundler mode */
+    "moduleResolution": "bundler",
+    "allowImportingTsExtensions": true,
+    "isolatedModules": true,
+    "moduleDetection": "force",
+    "noEmit": true,
+
+    /* Linting */
+    "strict": true,
+    "noUnusedLocals": true,
+    "noUnusedParameters": true,
+    "noFallthroughCasesInSwitch": true,
+    "noUncheckedSideEffectImports": true
+  },
+  "include": ["src"]
+}
diff --git a/spock-website/vite.config.ts b/spock-website/vite.config.ts
new file mode 100644
index 0000000..a326629
--- /dev/null
+++ b/spock-website/vite.config.ts
@@ -0,0 +1,9 @@
+import { defineConfig } from 'vite'
+import tailwindcss from '@tailwindcss/vite'
+
+export default defineConfig({
+    base: '/',
+    plugins: [
+        tailwindcss(),
+    ],
+})

From 2aaa2c555afe998ea1a11c77f631eb4649d81a2b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 15:35:57 +0200
Subject: [PATCH 16/29] Fix hover animation for cards

---
 spock-website/index.html    | 78 +++++++++++++++++++++++++------------
 spock-website/src/style.css |  2 +-
 2 files changed, 54 insertions(+), 26 deletions(-)

diff --git a/spock-website/index.html b/spock-website/index.html
index 024487c..3aebcbe 100644
--- a/spock-website/index.html
+++ b/spock-website/index.html
@@ -58,7 +58,7 @@ <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up"
             <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
                 Try it online
             </a>
-            <a href="https://docs.spockframework.org" target="_blank" class="cta-button cta-secondary">
+            <a href="https://docs.spockframework.org" target="_blank" class="cta-button cta-tertiary">
                 Read the Docs
             </a>
             <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary">
@@ -82,35 +82,63 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-16 text-gray-100" data-
             Why Choose Spock?
         </h2>
         <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
-            <div class="feature-card" data-aos="fade-up" data-aos-delay="100">
-                <svg viewBox="0 0 24 24"><rect x="4" y="4" width="16" height="16" rx="2"/></svg>
-                <h3 class="text-xl font-semibold text-gray-100 mb-2">Expressive Specifications</h3>
-                <p class="text-gray-300">Write tests that are easy to read and understand, even for non-programmers.</p>
+            <div data-aos="fade-up" data-aos-delay="100">
+                <div class="feature-card h-full">
+                    <svg viewBox="0 0 24 24">
+                        <rect x="4" y="4" width="16" height="16" rx="2"/>
+                    </svg>
+                    <h3 class="text-xl font-semibold text-gray-100 mb-2">Expressive Specifications</h3>
+                    <p class="text-gray-300">Write tests that are easy to read and understand, even for
+                        non-programmers.</p>
+                </div>
             </div>
-            <div class="feature-card" data-aos="fade-up" data-aos-delay="150">
-                <svg viewBox="0 0 24 24"><path d="M3 17l6-6 4 4 8-8" /></svg>
-                <h3 class="text-xl font-semibold text-gray-100 mb-2">Powerful Mocking</h3>
-                <p class="text-gray-300">Create flexible and powerful mocks and stubs with built-in support.</p>
+            <div data-aos="fade-up" data-aos-delay="150">
+                <div class="feature-card h-full">
+                    <svg viewBox="0 0 24 24">
+                        <path d="M3 17l6-6 4 4 8-8"/>
+                    </svg>
+                    <h3 class="text-xl font-semibold text-gray-100 mb-2">Powerful Mocking</h3>
+                    <p class="text-gray-300">Create flexible and powerful mocks and stubs with built-in support.</p>
+                </div>
             </div>
-            <div class="feature-card" data-aos="fade-up" data-aos-delay="200">
-                <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="10" /><path d="M12 6v6l4 2" /></svg>
-                <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Platform</h3>
-                <p class="text-gray-300">Seamless integration with JUnit 5+ and build tools.</p>
+            <div data-aos="fade-up" data-aos-delay="200">
+                <div class="feature-card h-full">
+                    <svg viewBox="0 0 24 24">
+                        <circle cx="12" cy="12" r="10"/>
+                        <path d="M12 6v6l4 2"/>
+                    </svg>
+                    <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Platform</h3>
+                    <p class="text-gray-300">Seamless integration with JUnit 5+ and build tools.</p>
+                </div>
             </div>
-            <div class="feature-card" data-aos="fade-up" data-aos-delay="250">
-                <svg viewBox="0 0 24 24"><path d="M3 3h18v6H3zM3 15h18v6H3z" /><path d="M9 9v6" /></svg>
-                <h3 class="text-xl font-semibold text-gray-100 mb-2">Data-Driven Testing</h3>
-                <p class="text-gray-300">Easily run the same test with different sets of data.</p>
+            <div data-aos="fade-up" data-aos-delay="250">
+                <div class="feature-card h-full">
+                    <svg viewBox="0 0 24 24">
+                        <path d="M3 3h18v6H3zM3 15h18v6H3z"/>
+                        <path d="M9 9v6"/>
+                    </svg>
+                    <h3 class="text-xl font-semibold text-gray-100 mb-2">Data-Driven Testing</h3>
+                    <p class="text-gray-300">Easily run the same test with different sets of data.</p>
+                </div>
             </div>
-            <div class="feature-card" data-aos="fade-up" data-aos-delay="300">
-                <svg viewBox="0 0 24 24"><polygon points="12 2 15 8 22 9 17 14 18 21 12 18 6 21 7 14 2 9 9 8 12 2" /></svg>
-                <h3 class="text-xl font-semibold text-gray-100 mb-2">Groovy DSL</h3>
-                <p class="text-gray-300">Leverage the power and flexibility of the Groovy language.</p>
+            <div data-aos="fade-up" data-aos-delay="300">
+                <div class="feature-card h-full">
+                    <svg viewBox="0 0 24 24">
+                        <polygon points="12 2 15 8 22 9 17 14 18 21 12 18 6 21 7 14 2 9 9 8 12 2"/>
+                    </svg>
+                    <h3 class="text-xl font-semibold text-gray-100 mb-2">Groovy DSL</h3>
+                    <p class="text-gray-300">Leverage the power and flexibility of the Groovy language.</p>
+                </div>
             </div>
-            <div class="feature-card" data-aos="fade-up" data-aos-delay="350">
-                <svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2" /><path d="M9 12l2 2 4-4" /></svg>
-                <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
-                <p class="text-gray-300">Use a rich set of matchers to verify expectations with clarity.</p>
+            <div data-aos="fade-up" data-aos-delay="350">
+                <div class="feature-card h-full">
+                    <svg viewBox="0 0 24 24">
+                        <rect x="3" y="3" width="18" height="18" rx="2"/>
+                        <path d="M9 12l2 2 4-4"/>
+                    </svg>
+                    <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
+                    <p class="text-gray-300">Use a rich set of matchers to verify expectations with clarity.</p>
+                </div>
             </div>
         </div>
     </div>
diff --git a/spock-website/src/style.css b/spock-website/src/style.css
index b46ece7..f55d223 100644
--- a/spock-website/src/style.css
+++ b/spock-website/src/style.css
@@ -128,7 +128,7 @@ code .number { color: #fca5a5; } /* Red */
     transition: transform 0.3s ease, box-shadow 0.3s ease;
 }
 .feature-card:hover {
-    transform: translateY(-4px);
+    transform: translateY(-8px);
     box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05); /* shadow-lg */
 }
 

From fdba659e69f7042930d596c8614e43f7c479dda4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 15:37:10 +0200
Subject: [PATCH 17/29] Increase delay for fade animation of cards

---
 spock-website/index.html | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/spock-website/index.html b/spock-website/index.html
index 3aebcbe..a8a3256 100644
--- a/spock-website/index.html
+++ b/spock-website/index.html
@@ -92,7 +92,7 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Expressive Specifications</
                         non-programmers.</p>
                 </div>
             </div>
-            <div data-aos="fade-up" data-aos-delay="150">
+            <div data-aos="fade-up" data-aos-delay="200">
                 <div class="feature-card h-full">
                     <svg viewBox="0 0 24 24">
                         <path d="M3 17l6-6 4 4 8-8"/>
@@ -101,7 +101,7 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Powerful Mocking</h3>
                     <p class="text-gray-300">Create flexible and powerful mocks and stubs with built-in support.</p>
                 </div>
             </div>
-            <div data-aos="fade-up" data-aos-delay="200">
+            <div data-aos="fade-up" data-aos-delay="300">
                 <div class="feature-card h-full">
                     <svg viewBox="0 0 24 24">
                         <circle cx="12" cy="12" r="10"/>
@@ -111,7 +111,7 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Platform</h3>
                     <p class="text-gray-300">Seamless integration with JUnit 5+ and build tools.</p>
                 </div>
             </div>
-            <div data-aos="fade-up" data-aos-delay="250">
+            <div data-aos="fade-up" data-aos-delay="400">
                 <div class="feature-card h-full">
                     <svg viewBox="0 0 24 24">
                         <path d="M3 3h18v6H3zM3 15h18v6H3z"/>
@@ -121,7 +121,7 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Data-Driven Testing</h3>
                     <p class="text-gray-300">Easily run the same test with different sets of data.</p>
                 </div>
             </div>
-            <div data-aos="fade-up" data-aos-delay="300">
+            <div data-aos="fade-up" data-aos-delay="500">
                 <div class="feature-card h-full">
                     <svg viewBox="0 0 24 24">
                         <polygon points="12 2 15 8 22 9 17 14 18 21 12 18 6 21 7 14 2 9 9 8 12 2"/>
@@ -130,7 +130,7 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Groovy DSL</h3>
                     <p class="text-gray-300">Leverage the power and flexibility of the Groovy language.</p>
                 </div>
             </div>
-            <div data-aos="fade-up" data-aos-delay="350">
+            <div data-aos="fade-up" data-aos-delay="600">
                 <div class="feature-card h-full">
                     <svg viewBox="0 0 24 24">
                         <rect x="3" y="3" width="18" height="18" rx="2"/>

From 2b74a4f8f764f4ea08daeb4c2b5cb31807c238b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 15:45:47 +0200
Subject: [PATCH 18/29] Add switch to disable AOS animations

---
 spock-website/index.html | 1 +
 1 file changed, 1 insertion(+)

diff --git a/spock-website/index.html b/spock-website/index.html
index a8a3256..c2c2c26 100644
--- a/spock-website/index.html
+++ b/spock-website/index.html
@@ -287,6 +287,7 @@ <h3 class="text-xl font-semibold text-center mb-4 text-gray-100">Example Test Ou
         duration: 800, // Animation duration
         once: true, // Whether animation should happen only once - while scrolling down
         offset: 50, // Offset (in px) from the original trigger point
+        disable: new URLSearchParams(window.location.search).get('disableaos') !== null,
     });
 </script>
 

From 2fa5e585678431d2426c28a7ecc1885076a5f8d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 16:56:15 +0200
Subject: [PATCH 19/29] Add fontawesome svg icons

---
 spock-website/index.html        | 17 ++++++------
 spock-website/package-lock.json | 48 +++++++++++++++++++++++++++++++++
 spock-website/package.json      |  3 +++
 spock-website/src/icons.ts      |  9 +++++++
 spock-website/src/main.ts       |  1 +
 5 files changed, 69 insertions(+), 9 deletions(-)
 create mode 100644 spock-website/src/icons.ts

diff --git a/spock-website/index.html b/spock-website/index.html
index c2c2c26..005cfc8 100644
--- a/spock-website/index.html
+++ b/spock-website/index.html
@@ -56,22 +56,21 @@ <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up"
 
         <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4" data-aos="fade-up" data-aos-delay="200">
             <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
-                Try it online
+                <i class="fa-solid fa-laptop-code"></i> Try it online
             </a>
             <a href="https://docs.spockframework.org" target="_blank" class="cta-button cta-tertiary">
-                Read the Docs
+                <i class="fa-solid fa-book"></i> Read the Docs
             </a>
             <a href="https://github.com/spockframework/spock-example" target="_blank" class="cta-button cta-tertiary">
-                Clone the Example Project
+                <i class="fa-solid fa-code"></i> Clone the Example Project
             </a>
         </div>
     </div>
     <div class="container mx-auto px-6 text-center spock-blue-text text-md additional-links flex flex-wrap justify-center items-center gap-y-2 pt-8" data-aos="fade-up" data-aos-delay="300">
-        <a href="https://spockframework.org/spock/javadoc/current" class="mx-3 hover-underline-animation">JavaDoc</a> <span class="link-separator">|</span>
-        <a href="https://github.com/spockframework/spock" class="mx-3 hover-underline-animation">Source Code</a> <span class="link-separator">|</span>
-        <a href="https://github.com/spockframework/spock/issues" class="mx-3 hover-underline-animation">Issue Tracker</a> <span class="link-separator">|</span>
-        <a href="https://github.com/spockframework/spock/discussions" class="mx-3 hover-underline-animation">Discussions</a> <span class="link-separator">|</span>
-        <a href="https://gitter.im/spockframework/spock" class="mx-3 hover-underline-animation">Chat</a>
+        <a href="https://spockframework.org/spock/javadoc/current" class="mx-3 hover-underline-animation"><i class="fa-brands fa-java"></i> JavaDoc</a> <span class="link-separator">|</span>
+        <a href="https://github.com/spockframework/spock" class="mx-3 hover-underline-animation"><i class="fa-brands fa-github fa-lg"></i> Code &amp; Issues</a> <span class="link-separator">|</span>
+        <a href="https://github.com/spockframework/spock/discussions" class="mx-3 hover-underline-animation"><i class="fas fa-comment-dots"></i> Discussions</a> <span class="link-separator">|</span>
+        <a href="https://gitter.im/spockframework/spock" class="mx-3 hover-underline-animation"><i class="fas fa-comments"></i> Chat</a>
     </div>
 </section>
 
@@ -266,7 +265,7 @@ <h3 class="text-xl font-semibold text-center mb-4 text-gray-100">Example Test Ou
     </div>
     <div class="flex flex-col sm:flex-row justify-center items-center space-y-4 sm:space-y-0 sm:space-x-4 mt-8" data-aos="fade-up" data-aos-delay="800">
         <a href="https://groovyconsole.dev/?g=groovy_4_0&gist=437e9026ff86d2d709c2c56eb7e2eef1#g8qcDpYAQE" target="_blank" class="cta-button cta-primary">
-            Try it online
+            <i class="fa-solid fa-laptop-code"></i> Try it online
         </a>
     </div>
 </section>
diff --git a/spock-website/package-lock.json b/spock-website/package-lock.json
index 4b51682..b012960 100644
--- a/spock-website/package-lock.json
+++ b/spock-website/package-lock.json
@@ -8,6 +8,9 @@
       "name": "spock-website",
       "version": "0.0.0",
       "dependencies": {
+        "@fortawesome/fontawesome-svg-core": "^6.7.2",
+        "@fortawesome/free-brands-svg-icons": "^6.7.2",
+        "@fortawesome/free-solid-svg-icons": "^6.7.2",
         "@tailwindcss/vite": "^4.1.4",
         "tailwindcss": "^4.1.4"
       },
@@ -416,6 +419,51 @@
         "node": ">=18"
       }
     },
+    "node_modules/@fortawesome/fontawesome-common-types": {
+      "version": "6.7.2",
+      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz",
+      "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@fortawesome/fontawesome-svg-core": {
+      "version": "6.7.2",
+      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz",
+      "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==",
+      "license": "MIT",
+      "dependencies": {
+        "@fortawesome/fontawesome-common-types": "6.7.2"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@fortawesome/free-brands-svg-icons": {
+      "version": "6.7.2",
+      "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.7.2.tgz",
+      "integrity": "sha512-zu0evbcRTgjKfrr77/2XX+bU+kuGfjm0LbajJHVIgBWNIDzrhpRxiCPNT8DW5AdmSsq7Mcf9D1bH0aSeSUSM+Q==",
+      "license": "(CC-BY-4.0 AND MIT)",
+      "dependencies": {
+        "@fortawesome/fontawesome-common-types": "6.7.2"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
+    "node_modules/@fortawesome/free-solid-svg-icons": {
+      "version": "6.7.2",
+      "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz",
+      "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==",
+      "license": "(CC-BY-4.0 AND MIT)",
+      "dependencies": {
+        "@fortawesome/fontawesome-common-types": "6.7.2"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/@rollup/rollup-android-arm-eabi": {
       "version": "4.40.0",
       "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz",
diff --git a/spock-website/package.json b/spock-website/package.json
index cf760ef..a677167 100644
--- a/spock-website/package.json
+++ b/spock-website/package.json
@@ -13,6 +13,9 @@
     "vite": "^6.3.1"
   },
   "dependencies": {
+    "@fortawesome/fontawesome-svg-core": "^6.7.2",
+    "@fortawesome/free-brands-svg-icons": "^6.7.2",
+    "@fortawesome/free-solid-svg-icons": "^6.7.2",
     "@tailwindcss/vite": "^4.1.4",
     "tailwindcss": "^4.1.4"
   }
diff --git a/spock-website/src/icons.ts b/spock-website/src/icons.ts
new file mode 100644
index 0000000..062dea0
--- /dev/null
+++ b/spock-website/src/icons.ts
@@ -0,0 +1,9 @@
+import { library, dom } from '@fortawesome/fontawesome-svg-core';
+import { faBook, faCode, faLaptopCode, faComments, faCommentDots} from '@fortawesome/free-solid-svg-icons';
+import { faGithub, faStackOverflow, faJava } from '@fortawesome/free-brands-svg-icons';
+
+// Add icons to the library
+library.add(faGithub, faStackOverflow, faJava, faBook, faCode, faLaptopCode, faComments, faCommentDots);
+
+// Watch for <i> tags and replace with SVG
+dom.watch();
diff --git a/spock-website/src/main.ts b/spock-website/src/main.ts
index cab743a..3fa6072 100644
--- a/spock-website/src/main.ts
+++ b/spock-website/src/main.ts
@@ -1 +1,2 @@
 import './style.css'
+import './icons'

From c1134b0a11a8e5ee53337ad52266ee4f46326e96 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 17:53:18 +0200
Subject: [PATCH 20/29] Add stackoverflow and latest version shield

---
 spock-website/index.html | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/spock-website/index.html b/spock-website/index.html
index 005cfc8..eb65ab4 100644
--- a/spock-website/index.html
+++ b/spock-website/index.html
@@ -69,9 +69,13 @@ <h2 class="text-3xl md:text-4xl font-bold mb-8 text-gray-100" data-aos="fade-up"
     <div class="container mx-auto px-6 text-center spock-blue-text text-md additional-links flex flex-wrap justify-center items-center gap-y-2 pt-8" data-aos="fade-up" data-aos-delay="300">
         <a href="https://spockframework.org/spock/javadoc/current" class="mx-3 hover-underline-animation"><i class="fa-brands fa-java"></i> JavaDoc</a> <span class="link-separator">|</span>
         <a href="https://github.com/spockframework/spock" class="mx-3 hover-underline-animation"><i class="fa-brands fa-github fa-lg"></i> Code &amp; Issues</a> <span class="link-separator">|</span>
+        <a href="https://stackoverflow.com/questions/tagged/spock" class="mx-3 hover-underline-animation"><i class="fa-brands fa-stack-overflow"></i> Q&amp;A</a> <span class="link-separator">|</span>
         <a href="https://github.com/spockframework/spock/discussions" class="mx-3 hover-underline-animation"><i class="fas fa-comment-dots"></i> Discussions</a> <span class="link-separator">|</span>
         <a href="https://gitter.im/spockframework/spock" class="mx-3 hover-underline-animation"><i class="fas fa-comments"></i> Chat</a>
     </div>
+    <div class="text-center mt-8 flex flex-wrap justify-center items-center" data-aos="fade-up" data-aos-delay="400">
+        <a href="https://search.maven.org/search?q=g:org.spockframework" target="_blank"><img src="https://img.shields.io/maven-central/v/org.spockframework/spock-core?style=for-the-badge&label=Latest%20Version&labelColor=374151&color=1562ae" alt="Spock Latest Version"></a>
+    </div>
 </section>
 
 

From beab51df0dbb72a6aa3474363fc826e08c5d7eab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 17:59:09 +0200
Subject: [PATCH 21/29] Add workflow for verifying and previewing PR

---
 .github/workflows/verify.yaml | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)
 create mode 100644 .github/workflows/verify.yaml

diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml
new file mode 100644
index 0000000..606849c
--- /dev/null
+++ b/.github/workflows/verify.yaml
@@ -0,0 +1,30 @@
+name: Verify PR build
+
+on:
+    pull_request:
+        branches: [ 'main' ]
+
+concurrency:
+    group: '${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}'
+    cancel-in-progress: true
+
+jobs:
+    verify:
+        runs-on: ubuntu-latest
+        steps:
+            -   name: Checkout
+                uses: actions/checkout@v4
+            -   name: Set up Node
+                uses: actions/setup-node@v4
+                with:
+                    node-version: lts/*
+                    cache: 'npm'
+            -   name: Install dependencies
+                run: npm ci
+            -   name: Build
+                run: npm run build
+            -   name: Upload artifact
+                uses: 'actions/upload-artifact@v4'
+                with:
+                    name: 'gh-pages-preview'
+                    path: './spock-website/dist'

From 55afb7f8a8aeeba6f76c3af99b596fe47cfc8de9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 18:38:01 +0200
Subject: [PATCH 22/29] Add Playwright for visual testing and setup git lfs

---
 .gitattributes                     |  1 +
 .github/workflows/verify.yaml      | 37 ++++++++++++++++-
 .gitignore                         |  5 ++-
 spock-website/package-lock.json    | 64 ++++++++++++++++++++++++++++++
 spock-website/package.json         |  1 +
 spock-website/playwright.config.ts | 32 +++++++++++++++
 spock-website/tests/visual.spec.ts |  6 +++
 spock-website/tsconfig.test.json   |  6 +++
 8 files changed, 149 insertions(+), 3 deletions(-)
 create mode 100644 .gitattributes
 create mode 100644 spock-website/playwright.config.ts
 create mode 100644 spock-website/tests/visual.spec.ts
 create mode 100644 spock-website/tsconfig.test.json

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..0c5e9d0
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+spock-website/tests/__screenshots__/**/*.png filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml
index 606849c..ff2039d 100644
--- a/.github/workflows/verify.yaml
+++ b/.github/workflows/verify.yaml
@@ -9,22 +9,57 @@ concurrency:
     cancel-in-progress: true
 
 jobs:
-    verify:
+    build:
         runs-on: ubuntu-latest
         steps:
             -   name: Checkout
                 uses: actions/checkout@v4
+
+            -   name: Verify LFS files
+                run: |
+                    git lfs install
+                    git lfs fsck --pointers HEAD
+
             -   name: Set up Node
                 uses: actions/setup-node@v4
                 with:
                     node-version: lts/*
                     cache: 'npm'
+
             -   name: Install dependencies
                 run: npm ci
+
             -   name: Build
                 run: npm run build
+
             -   name: Upload artifact
                 uses: 'actions/upload-artifact@v4'
                 with:
                     name: 'gh-pages-preview'
                     path: './spock-website/dist'
+
+    verify:
+        runs-on: ubuntu-latest
+        steps:
+            -   name: Checkout
+                uses: actions/checkout@v4
+                with:
+                    lfs: true # Download LFS files for screenshots
+
+            -   name: Set up Node
+                uses: actions/setup-node@v4
+                with:
+                    node-version: lts/*
+                    cache: 'npm'
+            -   name: Install dependencies
+                run: npm ci
+
+            -   name: Run Playwright Tests
+                run: npx playwright test
+
+            -   name: Upload Test Results (optional)
+                uses: actions/upload-artifact@v4
+                if: always()
+                with:
+                    name: playwright-report
+                    path: spock-website/playwright-report/
diff --git a/.gitignore b/.gitignore
index 0d3bb91..d68c6f6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,8 @@
 .idea/
 node_modules/
+dist/
+playwright-report/
+test-results/
 
 # Logs
 logs
@@ -10,8 +13,6 @@ yarn-error.log*
 pnpm-debug.log*
 lerna-debug.log*
 
-node_modules
-dist
 dist-ssr
 *.local
 
diff --git a/spock-website/package-lock.json b/spock-website/package-lock.json
index b012960..dbd83ab 100644
--- a/spock-website/package-lock.json
+++ b/spock-website/package-lock.json
@@ -15,6 +15,7 @@
         "tailwindcss": "^4.1.4"
       },
       "devDependencies": {
+        "@playwright/test": "^1.52.0",
         "typescript": "~5.7.2",
         "vite": "^6.3.1"
       }
@@ -464,6 +465,22 @@
         "node": ">=6"
       }
     },
+    "node_modules/@playwright/test": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.52.0.tgz",
+      "integrity": "sha512-uh6W7sb55hl7D6vsAeA+V2p5JnlAqzhqFyF0VcJkKZXkgnFcVG9PziERRHQfPLfNGx1C292a4JqbWzhR8L4R1g==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "playwright": "1.52.0"
+      },
+      "bin": {
+        "playwright": "cli.js"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
     "node_modules/@rollup/rollup-android-arm-eabi": {
       "version": "4.40.0",
       "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.0.tgz",
@@ -1353,6 +1370,53 @@
         "url": "https://github.com/sponsors/jonschlinkert"
       }
     },
+    "node_modules/playwright": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.52.0.tgz",
+      "integrity": "sha512-JAwMNMBlxJ2oD1kce4KPtMkDeKGHQstdpFPcPH3maElAXon/QZeTvtsfXmTMRyO9TslfoYOXkSsvao2nE1ilTw==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "dependencies": {
+        "playwright-core": "1.52.0"
+      },
+      "bin": {
+        "playwright": "cli.js"
+      },
+      "engines": {
+        "node": ">=18"
+      },
+      "optionalDependencies": {
+        "fsevents": "2.3.2"
+      }
+    },
+    "node_modules/playwright-core": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.52.0.tgz",
+      "integrity": "sha512-l2osTgLXSMeuLZOML9qYODUQoPPnUsKsb5/P6LJ2e6uPKXUdPK5WYhN4z03G+YNbWmGDY4YENauNu4ZKczreHg==",
+      "dev": true,
+      "license": "Apache-2.0",
+      "bin": {
+        "playwright-core": "cli.js"
+      },
+      "engines": {
+        "node": ">=18"
+      }
+    },
+    "node_modules/playwright/node_modules/fsevents": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+      "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+      "dev": true,
+      "hasInstallScript": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
+    },
     "node_modules/postcss": {
       "version": "8.5.3",
       "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
diff --git a/spock-website/package.json b/spock-website/package.json
index a677167..59ddae1 100644
--- a/spock-website/package.json
+++ b/spock-website/package.json
@@ -9,6 +9,7 @@
     "preview": "vite preview"
   },
   "devDependencies": {
+    "@playwright/test": "^1.52.0",
     "typescript": "~5.7.2",
     "vite": "^6.3.1"
   },
diff --git a/spock-website/playwright.config.ts b/spock-website/playwright.config.ts
new file mode 100644
index 0000000..2cfb547
--- /dev/null
+++ b/spock-website/playwright.config.ts
@@ -0,0 +1,32 @@
+import { defineConfig, devices } from '@playwright/test';
+
+export default defineConfig({
+    reporter: process.env.CI ? ['github', 'html'] : 'html',
+    // Configure projects for major browsers.
+    projects: [
+        {
+            name: 'chromium',
+            use: devices['Desktop Chrome'],
+        },
+        {
+            name: 'firefox',
+            use: devices['Desktop Firefox'],
+        },
+    ],
+    // Single template for all assertions
+    testDir: 'tests',
+    snapshotPathTemplate: '{testDir}/__screenshots__{/projectName}/{testFilePath}/{arg}{ext}',
+    // Run local dev server before starting the tests.
+    use: {
+        // Base URL to use in actions like `await page.goto('/')`.
+        baseURL: 'http://localhost:5173',
+
+        // Collect trace when retrying the failed test.
+        trace: 'on-first-retry',
+    },
+    webServer: {
+        command: 'npm run dev',
+        url: 'http://localhost:5173',
+        reuseExistingServer: !process.env.CI,
+    },
+});
diff --git a/spock-website/tests/visual.spec.ts b/spock-website/tests/visual.spec.ts
new file mode 100644
index 0000000..9e023f6
--- /dev/null
+++ b/spock-website/tests/visual.spec.ts
@@ -0,0 +1,6 @@
+import { test, expect } from '@playwright/test';
+
+test('visual snapshot', async ({ page }) => {
+    await page.goto('/?disableaos');
+    await expect(page).toHaveScreenshot('index.png', { fullPage: true });
+});
diff --git a/spock-website/tsconfig.test.json b/spock-website/tsconfig.test.json
new file mode 100644
index 0000000..fcc10ca
--- /dev/null
+++ b/spock-website/tsconfig.test.json
@@ -0,0 +1,6 @@
+{
+    "extends": "./tsconfig.json",
+    "include": [
+        "tests/**/*.spec.ts",
+    ],
+}

From f178025f38bc1af19fe0a69f36192f2488eb1e3d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 18:52:24 +0200
Subject: [PATCH 23/29] Add workflow for updating screenshots

---
 .../update-reference-screenshots.yaml         | 41 +++++++++++++++++++
 .github/workflows/verify.yaml                 |  1 +
 2 files changed, 42 insertions(+)
 create mode 100644 .github/workflows/update-reference-screenshots.yaml

diff --git a/.github/workflows/update-reference-screenshots.yaml b/.github/workflows/update-reference-screenshots.yaml
new file mode 100644
index 0000000..8fb3b58
--- /dev/null
+++ b/.github/workflows/update-reference-screenshots.yaml
@@ -0,0 +1,41 @@
+name: Deploy static content to Pages
+
+on:
+    workflow_dispatch:
+
+permissions:
+    contents: write
+
+jobs:
+    update-screenshots:
+        runs-on: ubuntu-latest
+        steps:
+            -   name: Checkout
+                uses: actions/checkout@v4
+                with:
+                    lfs: true # Download LFS files for screenshots
+
+            -   name: Set up Node
+                uses: actions/setup-node@v4
+                with:
+                    node-version: lts/*
+                    cache: 'npm'
+
+            -   name: Install dependencies
+                run: npm ci
+
+            -   name: Run Playwright Tests updating snapshots
+                run: npx playwright test --update-snapshots
+
+            -   name: Commit updated snapshots
+                run: |
+                    git config user.email "dev@forum.spockframework.org"
+                    git config user.name "Spock Framework Robot"
+                    git add spock-website/tests/__screenshots__/
+                    if [[ -n "$(git status --porcelain)" ]]; then
+                        echo "::set-output name=has_changes::true"
+                        git commit -m "Update reference screenshots"
+                        git push origin HEAD:${{ github.ref_name }}
+                    else
+                        echo "::set-output name=has_changes::false"
+                    fi
diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml
index ff2039d..dac9ea4 100644
--- a/.github/workflows/verify.yaml
+++ b/.github/workflows/verify.yaml
@@ -51,6 +51,7 @@ jobs:
                 with:
                     node-version: lts/*
                     cache: 'npm'
+
             -   name: Install dependencies
                 run: npm ci
 

From 315c3edc1839a4a349f8dd6b49b6466d23e5031b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 18:58:14 +0200
Subject: [PATCH 24/29] Support both `main` and `master` for now

---
 .github/workflows/deploy.yaml | 2 +-
 .github/workflows/verify.yaml | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml
index 37c2e54..02199dd 100644
--- a/.github/workflows/deploy.yaml
+++ b/.github/workflows/deploy.yaml
@@ -4,7 +4,7 @@ name: Deploy static content to Pages
 on:
     # Runs on pushes targeting the default branch
     push:
-        branches: [ 'main' ]
+        branches: [ 'main', 'master' ]
 
     # Allows you to run this workflow manually from the Actions tab
     workflow_dispatch:
diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml
index dac9ea4..ebb387c 100644
--- a/.github/workflows/verify.yaml
+++ b/.github/workflows/verify.yaml
@@ -2,7 +2,7 @@ name: Verify PR build
 
 on:
     pull_request:
-        branches: [ 'main' ]
+        branches: [ 'main', 'master' ]
 
 concurrency:
     group: '${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}'

From 9bd0e1d724e4f194e0a5efbb2c350a11845c9ddc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 19:16:27 +0200
Subject: [PATCH 25/29] Add social links

---
 spock-website/index.html   | 14 ++++++++++++++
 spock-website/src/icons.ts |  4 ++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/spock-website/index.html b/spock-website/index.html
index eb65ab4..afd86d5 100644
--- a/spock-website/index.html
+++ b/spock-website/index.html
@@ -274,6 +274,20 @@ <h3 class="text-xl font-semibold text-center mb-4 text-gray-100">Example Test Ou
     </div>
 </section>
 
+<section class="py-16 bg-gray-800">
+    <div class="container mx-auto px-6">
+        <h3 class="text-3xl md:text-4xl font-bold text-center text-gray-100" data-aos="fade-up">
+            Follow Us on
+        </h3>
+        <div class="container mx-auto px-6 text-center spock-blue-text text-md additional-links flex flex-wrap justify-center items-center gap-y-2 pt-8" data-aos="fade-up" data-aos-delay="100">
+            <a href="https://fosstodon.org/@spockframework" class="mx-3 hover-underline-animation"><i class="fa-brands fa-mastodon"></i> @spockframework</a> <span class="link-separator">|</span>
+            <a href="https://bsky.app/profile/spockframework.org" class="mx-3 hover-underline-animation"><i class="fa-brands fa-bluesky"></i> spockframework.org</a> <span class="link-separator">|</span>
+            <a href="https://twitter.com/SpockFramework" class="mx-3 hover-underline-animation"><i class="fa-brands fa-x-twitter"></i> @spockframework</a> <span class="link-separator">|</span>
+            <a href="https://github.com/spockframework/spock" class="mx-3 hover-underline-animation"><i class="fa-brands fa-github fa-lg"></i> spockframework/spock</a>
+        </div>
+    </div>
+</section>
+
 <footer class="py-8 text-center text-gray-400 text-sm">
     <div class="container mx-auto px-6">
         &copy; 2025 Spock Framework Team. All rights reserved.
diff --git a/spock-website/src/icons.ts b/spock-website/src/icons.ts
index 062dea0..edb39cb 100644
--- a/spock-website/src/icons.ts
+++ b/spock-website/src/icons.ts
@@ -1,9 +1,9 @@
 import { library, dom } from '@fortawesome/fontawesome-svg-core';
 import { faBook, faCode, faLaptopCode, faComments, faCommentDots} from '@fortawesome/free-solid-svg-icons';
-import { faGithub, faStackOverflow, faJava } from '@fortawesome/free-brands-svg-icons';
+import { faGithub, faStackOverflow, faJava, faXTwitter, faMastodon, faBluesky } from '@fortawesome/free-brands-svg-icons';
 
 // Add icons to the library
-library.add(faGithub, faStackOverflow, faJava, faBook, faCode, faLaptopCode, faComments, faCommentDots);
+library.add(faGithub, faStackOverflow, faJava, faXTwitter, faMastodon, faBluesky, faBook, faCode, faLaptopCode, faComments, faCommentDots);
 
 // Watch for <i> tags and replace with SVG
 dom.watch();

From cf68a9090141a610af315f0aef87b7612cee2b80 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 19:23:25 +0200
Subject: [PATCH 26/29] Set default working dir to `spock-website/`

---
 .github/workflows/deploy.yaml                       | 3 +++
 .github/workflows/update-reference-screenshots.yaml | 5 ++++-
 .github/workflows/verify.yaml                       | 6 ++++++
 3 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml
index 02199dd..4eed3b3 100644
--- a/.github/workflows/deploy.yaml
+++ b/.github/workflows/deploy.yaml
@@ -27,6 +27,9 @@ jobs:
             name: github-pages
             url: ${{ steps.deployment.outputs.page_url }}
         runs-on: ubuntu-latest
+        defaults:
+            run:
+                working-directory: ./spock-website
         steps:
             -   name: Checkout
                 uses: actions/checkout@v4
diff --git a/.github/workflows/update-reference-screenshots.yaml b/.github/workflows/update-reference-screenshots.yaml
index 8fb3b58..666fe89 100644
--- a/.github/workflows/update-reference-screenshots.yaml
+++ b/.github/workflows/update-reference-screenshots.yaml
@@ -9,6 +9,9 @@ permissions:
 jobs:
     update-screenshots:
         runs-on: ubuntu-latest
+        defaults:
+            run:
+                working-directory: ./spock-website
         steps:
             -   name: Checkout
                 uses: actions/checkout@v4
@@ -31,7 +34,7 @@ jobs:
                 run: |
                     git config user.email "dev@forum.spockframework.org"
                     git config user.name "Spock Framework Robot"
-                    git add spock-website/tests/__screenshots__/
+                    git add tests/__screenshots__/
                     if [[ -n "$(git status --porcelain)" ]]; then
                         echo "::set-output name=has_changes::true"
                         git commit -m "Update reference screenshots"
diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml
index ebb387c..9928c51 100644
--- a/.github/workflows/verify.yaml
+++ b/.github/workflows/verify.yaml
@@ -11,6 +11,9 @@ concurrency:
 jobs:
     build:
         runs-on: ubuntu-latest
+        defaults:
+            run:
+                working-directory: ./spock-website
         steps:
             -   name: Checkout
                 uses: actions/checkout@v4
@@ -40,6 +43,9 @@ jobs:
 
     verify:
         runs-on: ubuntu-latest
+        defaults:
+            run:
+                working-directory: ./spock-website
         steps:
             -   name: Checkout
                 uses: actions/checkout@v4

From 3b103c8388f761aaac069bb9a5bb071c44c3f205 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 19:26:41 +0200
Subject: [PATCH 27/29] Help `setup-node` to find package-lock.json file

---
 .github/workflows/deploy.yaml                       | 1 +
 .github/workflows/update-reference-screenshots.yaml | 1 +
 .github/workflows/verify.yaml                       | 2 ++
 3 files changed, 4 insertions(+)

diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml
index 4eed3b3..ac78283 100644
--- a/.github/workflows/deploy.yaml
+++ b/.github/workflows/deploy.yaml
@@ -38,6 +38,7 @@ jobs:
                 with:
                     node-version: lts/*
                     cache: 'npm'
+                    cache-dependency-path: spock-website/package-lock.json
             -   name: Install dependencies
                 run: npm ci
             -   name: Build
diff --git a/.github/workflows/update-reference-screenshots.yaml b/.github/workflows/update-reference-screenshots.yaml
index 666fe89..5cf706e 100644
--- a/.github/workflows/update-reference-screenshots.yaml
+++ b/.github/workflows/update-reference-screenshots.yaml
@@ -23,6 +23,7 @@ jobs:
                 with:
                     node-version: lts/*
                     cache: 'npm'
+                    cache-dependency-path: spock-website/package-lock.json
 
             -   name: Install dependencies
                 run: npm ci
diff --git a/.github/workflows/verify.yaml b/.github/workflows/verify.yaml
index 9928c51..25bca4c 100644
--- a/.github/workflows/verify.yaml
+++ b/.github/workflows/verify.yaml
@@ -28,6 +28,7 @@ jobs:
                 with:
                     node-version: lts/*
                     cache: 'npm'
+                    cache-dependency-path: spock-website/package-lock.json
 
             -   name: Install dependencies
                 run: npm ci
@@ -57,6 +58,7 @@ jobs:
                 with:
                     node-version: lts/*
                     cache: 'npm'
+                    cache-dependency-path: spock-website/package-lock.json
 
             -   name: Install dependencies
                 run: npm ci

From 3dca2e2825a188b47060cf2d9cd1d7723ab3034f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 19:29:11 +0200
Subject: [PATCH 28/29] Fix playwright reporter config

---
 spock-website/playwright.config.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spock-website/playwright.config.ts b/spock-website/playwright.config.ts
index 2cfb547..dabb68f 100644
--- a/spock-website/playwright.config.ts
+++ b/spock-website/playwright.config.ts
@@ -1,7 +1,7 @@
 import { defineConfig, devices } from '@playwright/test';
 
 export default defineConfig({
-    reporter: process.env.CI ? ['github', 'html'] : 'html',
+    reporter: process.env.CI ? [['github'], ['html']] : [['html'], ['list']],
     // Configure projects for major browsers.
     projects: [
         {

From 166185fb1998f3fb597fb4692d631fe7372fa800 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Leonard=20Br=C3=BCnings?= <leonard.bruenings@gradle.com>
Date: Sun, 20 Apr 2025 19:47:15 +0200
Subject: [PATCH 29/29] Use fontawesome for feature card icons as well

---
 spock-website/index.html   | 27 ++++++---------------------
 spock-website/src/icons.ts |  4 ++--
 2 files changed, 8 insertions(+), 23 deletions(-)

diff --git a/spock-website/index.html b/spock-website/index.html
index afd86d5..d9028c3 100644
--- a/spock-website/index.html
+++ b/spock-website/index.html
@@ -87,9 +87,7 @@ <h2 class="text-3xl md:text-4xl font-bold text-center mb-16 text-gray-100" data-
         <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
             <div data-aos="fade-up" data-aos-delay="100">
                 <div class="feature-card h-full">
-                    <svg viewBox="0 0 24 24">
-                        <rect x="4" y="4" width="16" height="16" rx="2"/>
-                    </svg>
+                    <div><i class="fas fa-receipt spock-blue-text"></i></div>
                     <h3 class="text-xl font-semibold text-gray-100 mb-2">Expressive Specifications</h3>
                     <p class="text-gray-300">Write tests that are easy to read and understand, even for
                         non-programmers.</p>
@@ -97,48 +95,35 @@ <h3 class="text-xl font-semibold text-gray-100 mb-2">Expressive Specifications</
             </div>
             <div data-aos="fade-up" data-aos-delay="200">
                 <div class="feature-card h-full">
-                    <svg viewBox="0 0 24 24">
-                        <path d="M3 17l6-6 4 4 8-8"/>
-                    </svg>
+                    <div><i class="fas fa-masks-theater spock-blue-text"></i></div>
                     <h3 class="text-xl font-semibold text-gray-100 mb-2">Powerful Mocking</h3>
                     <p class="text-gray-300">Create flexible and powerful mocks and stubs with built-in support.</p>
                 </div>
             </div>
             <div data-aos="fade-up" data-aos-delay="300">
                 <div class="feature-card h-full">
-                    <svg viewBox="0 0 24 24">
-                        <circle cx="12" cy="12" r="10"/>
-                        <path d="M12 6v6l4 2"/>
-                    </svg>
+                    <div><i class="fas fa-vial-circle-check spock-blue-text"></i></div>
                     <h3 class="text-xl font-semibold text-gray-100 mb-2">JUnit Platform</h3>
                     <p class="text-gray-300">Seamless integration with JUnit 5+ and build tools.</p>
                 </div>
             </div>
             <div data-aos="fade-up" data-aos-delay="400">
                 <div class="feature-card h-full">
-                    <svg viewBox="0 0 24 24">
-                        <path d="M3 3h18v6H3zM3 15h18v6H3z"/>
-                        <path d="M9 9v6"/>
-                    </svg>
+                    <div><i class="fas fa-table-cells spock-blue-text"></i></div>
                     <h3 class="text-xl font-semibold text-gray-100 mb-2">Data-Driven Testing</h3>
                     <p class="text-gray-300">Easily run the same test with different sets of data.</p>
                 </div>
             </div>
             <div data-aos="fade-up" data-aos-delay="500">
                 <div class="feature-card h-full">
-                    <svg viewBox="0 0 24 24">
-                        <polygon points="12 2 15 8 22 9 17 14 18 21 12 18 6 21 7 14 2 9 9 8 12 2"/>
-                    </svg>
+                    <div><i class="fas fa-star spock-blue-text"></i></div>
                     <h3 class="text-xl font-semibold text-gray-100 mb-2">Groovy DSL</h3>
                     <p class="text-gray-300">Leverage the power and flexibility of the Groovy language.</p>
                 </div>
             </div>
             <div data-aos="fade-up" data-aos-delay="600">
                 <div class="feature-card h-full">
-                    <svg viewBox="0 0 24 24">
-                        <rect x="3" y="3" width="18" height="18" rx="2"/>
-                        <path d="M9 12l2 2 4-4"/>
-                    </svg>
+                    <div><i class="fas fa-circle-check spock-blue-text"></i></div>
                     <h3 class="text-xl font-semibold text-gray-100 mb-2">Built-in Matchers</h3>
                     <p class="text-gray-300">Use a rich set of matchers to verify expectations with clarity.</p>
                 </div>
diff --git a/spock-website/src/icons.ts b/spock-website/src/icons.ts
index edb39cb..b329997 100644
--- a/spock-website/src/icons.ts
+++ b/spock-website/src/icons.ts
@@ -1,9 +1,9 @@
 import { library, dom } from '@fortawesome/fontawesome-svg-core';
-import { faBook, faCode, faLaptopCode, faComments, faCommentDots} from '@fortawesome/free-solid-svg-icons';
+import { faBook, faCode, faLaptopCode, faComments, faCommentDots, faReceipt, faMasksTheater, faVialCircleCheck, faTableCells, faStar, faCircleCheck} from '@fortawesome/free-solid-svg-icons';
 import { faGithub, faStackOverflow, faJava, faXTwitter, faMastodon, faBluesky } from '@fortawesome/free-brands-svg-icons';
 
 // Add icons to the library
-library.add(faGithub, faStackOverflow, faJava, faXTwitter, faMastodon, faBluesky, faBook, faCode, faLaptopCode, faComments, faCommentDots);
+library.add(faGithub, faStackOverflow, faJava, faXTwitter, faMastodon, faBluesky, faBook, faCode, faLaptopCode, faComments, faCommentDots, faReceipt, faMasksTheater, faVialCircleCheck, faTableCells, faStar, faCircleCheck);
 
 // Watch for <i> tags and replace with SVG
 dom.watch();