diff --git a/app/globals.css b/app/globals.css
index 02db03b..195a766 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -121,7 +121,7 @@ body {
@keyframes brutal-rise {
from {
opacity: 0;
- transform: translateY(18px);
+ transform: translateY(28px);
}
to {
opacity: 1;
@@ -131,26 +131,26 @@ body {
.rise {
opacity: 0;
- animation: brutal-rise 700ms cubic-bezier(0.2, 0.8, 0.2, 1) forwards;
+ animation: brutal-rise 850ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
.rise-0 {
animation-delay: 0ms;
}
.rise-1 {
- animation-delay: 120ms;
+ animation-delay: 80ms;
}
.rise-2 {
- animation-delay: 180ms;
+ animation-delay: 200ms;
}
.rise-3 {
- animation-delay: 260ms;
+ animation-delay: 320ms;
}
.rise-4 {
- animation-delay: 340ms;
+ animation-delay: 460ms;
}
.rise-5 {
- animation-delay: 420ms;
+ animation-delay: 600ms;
}
@media (prefers-reduced-motion: reduce) {
@@ -234,19 +234,22 @@ a.underline-brutal {
text-decoration: none;
padding-bottom: 2px;
border-bottom: 1px solid currentColor;
- transition: letter-spacing 220ms ease;
+ transition: border-bottom-color 260ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
a.underline-brutal:hover {
- letter-spacing: 0.02em;
+ border-bottom-color: var(--whisper);
}
a.underline-brutal .arrow {
- transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
+ transition:
+ transform 260ms cubic-bezier(0.16, 1, 0.3, 1),
+ color 260ms cubic-bezier(0.16, 1, 0.3, 1);
}
a.underline-brutal:hover .arrow {
- transform: translateX(4px);
+ transform: translateX(6px);
+ color: var(--whisper);
}
/* --- hero terminal -----------------------------------------------------
diff --git a/app/sitemap-pages.xml/route.ts b/app/sitemap-pages.xml/route.ts
new file mode 100644
index 0000000..cefc622
--- /dev/null
+++ b/app/sitemap-pages.xml/route.ts
@@ -0,0 +1,17 @@
+import { SITE_URL } from "@/lib/links";
+
+// Required by Next 16 under `output: "export"` for route handlers that emit
+// static files at build time. GET-only is the only verb supported in export.
+export const dynamic = "force-static";
+
+const BODY = `
+
+ ${SITE_URL}
+
+`;
+
+export function GET() {
+ return new Response(BODY, {
+ headers: { "Content-Type": "application/xml" },
+ });
+}
diff --git a/app/sitemap.ts b/app/sitemap.ts
deleted file mode 100644
index 9666446..0000000
--- a/app/sitemap.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import type { MetadataRoute } from "next";
-import { SITE_URL } from "@/lib/links";
-
-// Required by Next 16 under `output: "export"` for metadata route handlers.
-export const dynamic = "force-static";
-
-export default function sitemap(): MetadataRoute.Sitemap {
- return [{ url: SITE_URL }];
-}
diff --git a/app/sitemap.xml/route.ts b/app/sitemap.xml/route.ts
new file mode 100644
index 0000000..f44c056
--- /dev/null
+++ b/app/sitemap.xml/route.ts
@@ -0,0 +1,22 @@
+import { SITE_URL, links } from "@/lib/links";
+
+// Required by Next 16 under `output: "export"` for route handlers that emit
+// static files at build time. GET-only is the only verb supported in export.
+export const dynamic = "force-static";
+
+// Cross-host sitemap entries are only honored by Google when both hosts are
+// verified in Search Console.
+const DOCS_SITEMAP = `${new URL(links.docs).origin}/sitemap.xml`;
+
+const BODY = `
+
+ ${SITE_URL}sitemap-pages.xml
+ ${DOCS_SITEMAP}
+
+`;
+
+export function GET() {
+ return new Response(BODY, {
+ headers: { "Content-Type": "application/xml" },
+ });
+}
diff --git a/components/site/Hero.tsx b/components/site/Hero.tsx
index 9a7fbb1..29aaee6 100644
--- a/components/site/Hero.tsx
+++ b/components/site/Hero.tsx
@@ -71,7 +71,7 @@ export function Hero() {