diff --git a/components/layout/site-hero.tsx b/components/layout/site-hero.tsx
index a8525b7..772039a 100644
--- a/components/layout/site-hero.tsx
+++ b/components/layout/site-hero.tsx
@@ -3,11 +3,28 @@
import type { ReactNode } from "react";
import { ArrowDown } from "lucide-react";
+import { motion } from "framer-motion";
import { Container } from "@/components/layout/container";
import { HeroMotionBackdrop } from "@/components/layout/hero-motion-backdrop";
import { cn } from "@/lib/utils";
+const heroItemVariants = {
+ hidden: { opacity: 0, y: 16 },
+ visible: {
+ opacity: 1,
+ y: 0,
+ transition: { duration: 0.54, ease: [0.22, 1, 0.36, 1] as [number, number, number, number] },
+ },
+};
+
+const heroContainerVariants = {
+ hidden: {},
+ visible: {
+ transition: { staggerChildren: 0.13, delayChildren: 0.08 },
+ },
+};
+
type HeroTone = "default" | "accent" | "soft";
type HeroLineAlign = "start" | "center" | "end";
@@ -119,14 +136,27 @@ export function HeroContentMotion({
children,
className,
}: HeroContentMotionProps) {
- return
{children}
;
+ return (
+
+ {children}
+
+ );
}
export function HeroMotionItem({
children,
className,
}: HeroContentMotionProps) {
- return {children}
;
+ return (
+
+ {children}
+
+ );
}
export function HeroTitle({
@@ -147,7 +177,7 @@ export function HeroTitle({
);
return (
-
+
{lines.map((line, index) => (
))}
-
+
);
}
diff --git a/components/site/portfolio-project-detail.tsx b/components/site/portfolio-project-detail.tsx
index 67bb2c9..e4bd014 100644
--- a/components/site/portfolio-project-detail.tsx
+++ b/components/site/portfolio-project-detail.tsx
@@ -47,7 +47,6 @@ function PortfolioImage({
alt={alt}
width={width}
height={height}
- unoptimized
className={className}
/>
);
@@ -121,11 +120,7 @@ function SectionBlock({
height={880}
className="h-72 w-full rounded-surface object-cover"
/>
- ) : (
-
- No image configured.
-
- )}
+ ) : null}
);
}
@@ -216,7 +211,7 @@ function AssetGallery({
function BadgeCount({ count }: { count: number }) {
return (
- {count}
+ {count} {count === 1 ? "file" : "files"}
);
}
diff --git a/lib/portfolio.ts b/lib/portfolio.ts
index c420d46..7a8b887 100644
--- a/lib/portfolio.ts
+++ b/lib/portfolio.ts
@@ -6,6 +6,8 @@ import type {
PortfolioSection,
} from "@prisma/client";
+import { cache } from "react";
+
import { getPortfolioMediaBindings } from "@/lib/media";
import type { AppLocale } from "@/lib/locale";
import { prisma } from "@/lib/prisma";
@@ -329,7 +331,7 @@ export async function getPublishedPortfolioProjects(filters?: { categorySlug?: s
return projects.map((project) => mapProject(project));
}
-export async function getPublishedPortfolioProjectBySlug(slug: string) {
+export const getPublishedPortfolioProjectBySlug = cache(async function (slug: string) {
const project = await prisma.portfolioProject.findFirst({
where: {
slug,
@@ -350,7 +352,7 @@ export async function getPublishedPortfolioProjectBySlug(slug: string) {
});
return project ? mapProject(project) : null;
-}
+});
export async function getAdminPortfolioProjectById(id: string) {
const project = await prisma.portfolioProject.findUnique({