diff --git a/app/page.tsx b/app/page.tsx index 9b86578..97dd0e0 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,9 +1,11 @@ +import AwardBand from "@/components/AwardBand"; import Filmography from "@/components/Filmography"; import Hero from "@/components/Hero"; import ProjectCard from "@/components/ProjectCard"; import Reveal from "@/components/Reveal"; import SectionLabel from "@/components/SectionLabel"; import { + awards, filmography, projects, services, @@ -40,8 +42,10 @@ export default function Home() { <> + {awards[0] && } + {/* Filmography */} -
+
Filmography
diff --git a/app/work/[slug]/page.tsx b/app/work/[slug]/page.tsx index 389cd88..c86be2d 100644 --- a/app/work/[slug]/page.tsx +++ b/app/work/[slug]/page.tsx @@ -2,7 +2,8 @@ import type { Metadata } from "next"; import Link from "next/link"; import { notFound } from "next/navigation"; import Frame from "@/components/Frame"; -import { projects, site } from "@/content/site"; +import Laurel from "@/components/Laurel"; +import { awardFor, projects, site } from "@/content/site"; export const dynamicParams = false; @@ -38,6 +39,7 @@ export default async function ProjectPage({ params }: PageProps<"/work/[slug]">) if (index === -1) notFound(); const project = projects[index]; const next = projects[(index + 1) % projects.length]; + const award = awardFor(project.slug); const meta = [ { k: "Client", v: project.client }, @@ -55,6 +57,17 @@ export default async function ProjectPage({ params }: PageProps<"/work/[slug]">) ← All work

{project.title}

+ {award && ( +
+ +
+

+ {award.edition} {award.body} · {award.result} +

+

{award.category}

+
+
+ )}
diff --git a/components/AwardBand.tsx b/components/AwardBand.tsx new file mode 100644 index 0000000..a1a4722 --- /dev/null +++ b/components/AwardBand.tsx @@ -0,0 +1,51 @@ +import Link from "next/link"; +import Laurel from "./Laurel"; +import PlayReel from "./PlayReel"; +import Reveal from "./Reveal"; +import type { Award } from "@/content/site"; + +// Full-bleed award callout over a still from the nominated work. +export default function AwardBand({ award }: { award: Award }) { + return ( +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + +
+
+ +
+ +
+

{award.edition}

+

{award.body}

+

{award.result}

+
+
+
+ +

+ {award.result} · {award.year} +

+

+ {award.category} +

+

+ Our creature and simulation work on {award.title} was nominated at the{" "} + {award.longName}. +

+
+ {award.reel && } + {award.project && ( + + See the project → + + )} +
+
+
+
+ ); +} diff --git a/components/Filmography.tsx b/components/Filmography.tsx index fbe5a22..35ac217 100644 --- a/components/Filmography.tsx +++ b/components/Filmography.tsx @@ -1,5 +1,5 @@ import Reveal from "./Reveal"; -import { filmography } from "@/content/site"; +import { awardFor, filmography } from "@/content/site"; export default function Filmography() { return ( @@ -23,6 +23,11 @@ export default function Filmography() { Upcoming )} + {awardFor(c.slug) && ( + + {awardFor(c.slug)!.body} {awardFor(c.slug)!.result} + + )} {c.network && ( {c.network} diff --git a/components/Laurel.tsx b/components/Laurel.tsx new file mode 100644 index 0000000..10bdf6d --- /dev/null +++ b/components/Laurel.tsx @@ -0,0 +1,45 @@ +// Laurel wreath: a left branch of leaves curving from the bottom up the side, +// mirrored for the right. SVG angles run clockwise from +x (90° = bottom). +const R = 40; +const C = 50; +const leaves = Array.from({ length: 8 }, (_, i) => { + const deg = 112 + i * 18; // bottom-left round to top-left + const a = (deg * Math.PI) / 180; + return { x: C + R * Math.cos(a), y: C + R * Math.sin(a), deg }; +}); + +function Branch() { + const start = leaves[0]; + const end = leaves[leaves.length - 1]; + return ( + + + {leaves.map((l, i) => { + // Outer and inner leaf at each node, angled toward the top of the wreath. + const tangent = l.deg + 90; + return ( + + + + + ); + })} + + ); +} + +export default function Laurel({ className = "" }: { className?: string }) { + return ( + + ); +} diff --git a/content/site.ts b/content/site.ts index 95a1488..0a338f8 100644 --- a/content/site.ts +++ b/content/site.ts @@ -65,6 +65,39 @@ export const studioStills = [ "/capabilities/penguin-box.jpg", ]; +export type Award = { + body: string; + longName: string; + edition: string; + year: number; + result: "Nominee" | "Winner"; + category: string; + title: string; + // Filmography slug and/or project slug this award belongs to. + credit?: string; + project?: string; + image: string; + reel?: string; +}; + +export const awards: Award[] = [ + { + body: "SAFTA", + longName: "19th South African Film and Television Awards", + edition: "19th", + year: 2026, + result: "Nominee", + category: "Best Achievement in Visual Effects – TV", + title: "Summertide", + credit: "summertide", + project: "summertide", + image: "/work/summertide/award-bg.jpg", + reel: "/reel/summertide-reel.mp4", + }, +]; + +export const awardFor = (slug: string) => awards.find((a) => a.credit === slug || a.project === slug); + export type Credit = { slug: string; title: string; @@ -105,7 +138,7 @@ export const stats = [ { value: `${yearsActive}+`, label: "Years in production" }, { value: String(filmography.length), label: "Film & series credits" }, { value: String(filmography.filter((c) => c.network === "Netflix").length), label: "Netflix titles" }, - { value: "PTA", label: "Pretoria, South Africa" }, + { value: "SAFTA", label: "2026 VFX nominee" }, ]; export type Project = { diff --git a/public/work/summertide/award-bg.jpg b/public/work/summertide/award-bg.jpg new file mode 100644 index 0000000..10272c7 Binary files /dev/null and b/public/work/summertide/award-bg.jpg differ