-
-
Nabla
-
- Our Open Source Rendering Framework
+
+
+
+
+
+
Open Source Rendering Framework
+
Nabla
+
+ A Vulkan-only, thread-agnostic C++ and HLSL framework for demanding rendering middleware.
-
-
-
);
diff --git a/app/components/ProjectsSection.tsx b/app/components/ProjectsSection.tsx
index 9b981da..f816d7d 100644
--- a/app/components/ProjectsSection.tsx
+++ b/app/components/ProjectsSection.tsx
@@ -153,7 +153,7 @@ function ProjectImageCard({ image }: { image: ProjectImage; priority?: boolean }
const mediaClassName = `absolute inset-0 h-full w-full ${image.fit === "contain" ? "object-contain" : "object-cover"} rounded-lg transition-transform duration-500 group-hover:scale-[1.035]`;
return (
-
+
{image.type === "video" ? (
)}
{image.text && (
-
+
{image.text}
@@ -184,10 +184,12 @@ function ConsultingScope({ project }: { project: Project }) {
const scope = project.scope ?? ["Analysis", "Design", "Review"];
return (
-
-
{project.accent ?? "Consulting scope"}
-
{project.title}
-
{project.summary}
+
+
+
{project.accent ?? "Consulting scope"}
+
{project.title}
+
+
{project.summary}
{scope.map((item) => (
@@ -210,7 +212,7 @@ function ImageGrid({ images, layout = "grid" }: { images: ProjectImage[]; layout
if (layout === "stacked") {
return (
-
+
{images.map((image, index) => (
))}
@@ -220,7 +222,7 @@ function ImageGrid({ images, layout = "grid" }: { images: ProjectImage[]; layout
if (images.length === 3) {
return (
-
+
{images.map((image, index) => (
@@ -231,7 +233,7 @@ function ImageGrid({ images, layout = "grid" }: { images: ProjectImage[]; layout
}
return (
-
+
{images.slice(0, 4).map((image, index) => (
))}
@@ -263,18 +265,20 @@ function ProjectRow({ project, index }: { project: Project; index: number }) {
if (!hasImages) {
return (
-
-
-
+
+
+
-
-
{project.accent ?? project.title}
-
{heading}
-
+
+
+
{project.accent ?? project.title}
+
{heading}
+
+
{project.bullets.map((bullet) => (
- -
-
+
-
+
{bullet}
))}
@@ -288,26 +292,28 @@ function ProjectRow({ project, index }: { project: Project; index: number }) {
return (
-
+
-
{project.accent ?? project.title}
-
{heading}
+
+
{project.accent ?? project.title}
+
{heading}
+
{project.summary}
-
+
{project.bullets.map((bullet) => (
- -
-
+
-
+
{bullet}
))}
-
+
@@ -316,14 +322,14 @@ function ProjectRow({ project, index }: { project: Project; index: number }) {
export default function ProjectsSection() {
return (
-
+
-
+
Commercial work
Engineered Solutions for Our Partners
-
+
{projects.map((project, index) => (
))}
diff --git a/app/components/TestimonialsSection.tsx b/app/components/TestimonialsSection.tsx
index 9a63ea3..1463523 100644
--- a/app/components/TestimonialsSection.tsx
+++ b/app/components/TestimonialsSection.tsx
@@ -1,11 +1,9 @@
-"use client";
-
import Image from "next/image";
-import { useRef, useState, useEffect } from "react";
type Testimonial = {
name: string;
role: string;
+ profileUrl: string;
profilePicture: string;
companyIcon: string;
testimonial: string;
@@ -15,6 +13,7 @@ const testimonials: Testimonial[] = [
{
name: "Phil Langrishe",
role: "Managing Director at Applications in Cadd",
+ profileUrl: "https://www.linkedin.com/in/aic-phil/",
profilePicture: "/testimonials/phil.jpg",
companyIcon: "/partners/appscadd.png",
testimonial:
@@ -23,132 +22,75 @@ const testimonials: Testimonial[] = [
{
name: "Yoran Bosman",
role: "Partner & Software Architect",
+ profileUrl: "https://www.linkedin.com/in/yoranbosman/",
profilePicture: "/testimonials/yoran.jpg",
companyIcon: "/partners/ditt.png",
testimonial:
"The DevSH team transformed our CPU render farm for architectural visualization into a scalable GPU-based system with outstanding performance and reliability. Their expertise and commitment to achieving the best results were clear throughout the project. They maintained full backward compatibility, ensuring a smooth transition with minimal disruption to our workflows.",
- }
+ },
];
export default function TestimonialsSection() {
- const scrollContainerRef = useRef
(null);
- const [showLeftArrow, setShowLeftArrow] = useState(false);
- const [showRightArrow, setShowRightArrow] = useState(false);
-
- const checkScroll = () => {
- if (scrollContainerRef.current) {
- const { scrollLeft, scrollWidth, clientWidth } = scrollContainerRef.current;
- setShowLeftArrow(scrollLeft > 0);
- setShowRightArrow(Math.ceil(scrollLeft + clientWidth) < scrollWidth);
- }
- };
-
- useEffect(() => {
- checkScroll();
- window.addEventListener("resize", checkScroll);
- return () => window.removeEventListener("resize", checkScroll);
- }, []);
-
- const scroll = (direction: "left" | "right") => {
- if (scrollContainerRef.current) {
- const { clientWidth } = scrollContainerRef.current;
- const scrollAmount = direction === "left" ? -(clientWidth * 0.8) : clientWidth * 0.8;
- scrollContainerRef.current.scrollBy({ left: scrollAmount, behavior: "smooth" });
- }
- };
-
return (
-
+
-
+
What our partners say
-
- {/* Left Navigation Arrow */}
- {showLeftArrow && (
-