diff --git a/website/public/images/portrait-cian-byrne.jpg b/website/public/images/portrait-cian-byrne.jpg new file mode 100644 index 000000000..bf1933d24 Binary files /dev/null and b/website/public/images/portrait-cian-byrne.jpg differ diff --git a/website/public/images/portrait-james-winegar.png b/website/public/images/portrait-james-winegar.png new file mode 100644 index 000000000..f7d1fbdc4 Binary files /dev/null and b/website/public/images/portrait-james-winegar.png differ diff --git a/website/public/images/portrait-mark-sim.jpg b/website/public/images/portrait-mark-sim.jpg new file mode 100644 index 000000000..36e27a3e6 Binary files /dev/null and b/website/public/images/portrait-mark-sim.jpg differ diff --git a/website/public/images/portrait-robert-buisman.png b/website/public/images/portrait-robert-buisman.png new file mode 100644 index 000000000..029439dfb Binary files /dev/null and b/website/public/images/portrait-robert-buisman.png differ diff --git a/website/src/app/globals.css b/website/src/app/globals.css index 24c77e334..c87e7c7b7 100644 --- a/website/src/app/globals.css +++ b/website/src/app/globals.css @@ -27,4 +27,49 @@ *:is(code) { @apply overflow-x-auto rounded text-sm; } + + /* For WebKit browsers (Chrome, Safari) */ + .dark-scroll::-webkit-scrollbar { + width: 12px; /* Adjust the width of the scrollbar */ + } + + .dark-scroll::-webkit-scrollbar-button { + height: 0; + width: 0; + display: none; + } + + .dark-scroll::-webkit-scrollbar-thumb { + background-color: #666; /* White color at 20% opacity */ + border-radius: 10px; /* Optional: Rounds the corners of the scrollbar thumb */ + } + + .dark-scroll::-webkit-scrollbar-track { + background-color: #222; /* White color at 40% opacity */ + border-radius: 10px; /* Optional: Rounds the corners of the scrollbar track */ + } + + /* For Firefox */ + * .dark-scroll { + scrollbar-width: thin; + scrollbar-color: #666 #222; + } + + .dark-scroll::-ms-scrollbar { + width: 12px; /* Adjust the width of the scrollbar */ + } + + .dark-scroll::-ms-scrollbar-thumb { + background-color: rgba(255, 255, 255, 0.2); /* White color at 20% opacity */ + border-radius: 10px; /* Optional: Rounds the corners of the scrollbar thumb */ + } + + .dark-scroll::-ms-scrollbar-track { + background-color: rgba(255, 255, 255, 0.4); /* White color at 40% opacity */ + border-radius: 10px; /* Optional: Rounds the corners of the scrollbar track */ + } + + .dark-scroll::-ms-scrollbar-button { + display: none; + } } diff --git a/website/src/app/page.tsx b/website/src/app/page.tsx index 62da116c6..efb7a7d63 100644 --- a/website/src/app/page.tsx +++ b/website/src/app/page.tsx @@ -35,6 +35,7 @@ import ComplianceDiagram from "@/components/Animations/ComplianceDiagram"; import SimpleArchitecture from "@/components/Animations/SimpleArchitecture"; import { manrope } from "@/lib/fonts"; import "@/styles/hero.css"; +import CustomerTestimonials from "@/components/CustomerTestimonials"; import FeatureCards from "@/components/FeatureCards"; import SingleFeature from "@/components/SingleFeature"; @@ -116,6 +117,8 @@ export default function Page() { + + {/* Feature section 2: Achieve compliance in minutes, not weeks. */}
diff --git a/website/src/components/Carousel/index.tsx b/website/src/components/Carousel/index.tsx new file mode 100644 index 000000000..26707e589 --- /dev/null +++ b/website/src/components/Carousel/index.tsx @@ -0,0 +1,45 @@ +import type { CustomFlowbiteTheme } from "flowbite-react"; +import { Carousel as FlowbiteCarousel } from "flowbite-react"; + +const theme: CustomFlowbiteTheme["carousel"] = { + root: { + base: "relative h-full w-full", + leftControl: + "absolute left-0 bottom-4 flex items-end justify-center px-4 focus:outline-none", + rightControl: + "absolute right-0 bottom-4 flex items-end justify-center px-4 focus:outline-none", + }, + indicators: { + active: { + off: "bg-white/50 hover:bg-white dark:bg-gray-800/50 dark:hover:bg-gray-800", + on: "bg-white dark:bg-gray-800", + }, + base: "h-3 w-3 rounded-full", + wrapper: "absolute bottom-7 left-1/2 flex -translate-x-1/2 space-x-3", + }, + item: { + base: "absolute left-1/2 block w-full -translate-x-1/2", + wrapper: { + off: "w-full flex-shrink-0 transform cursor-default snap-center", + on: "w-full flex-shrink-0 transform cursor-grab snap-center", + }, + }, + control: { + base: "inline-flex h-8 w-8 items-center justify-center rounded-full bg-white/30 group-hover:bg-white/50 group-focus:outline-none group-focus:ring-4 group-focus:ring-white dark:bg-gray-800/30 dark:group-hover:bg-gray-800/60 dark:group-focus:ring-gray-800/70 sm:h-10 sm:w-10", + icon: "h-5 w-5 text-white dark:text-gray-800 sm:h-6 sm:w-6", + }, + scrollContainer: { + base: "flex h-full snap-mandatory overflow-y-hidden overflow-x-scroll scroll-smooth rounded-lg", + snap: "snap-x", + }, +}; + +export default function Carousel({ children }: { children: React.ReactNode }) { + return ( +
+ + {children} + +
+ ); +} diff --git a/website/src/components/CustomerTestimonials/index.tsx b/website/src/components/CustomerTestimonials/index.tsx new file mode 100644 index 000000000..ef5e65fcb --- /dev/null +++ b/website/src/components/CustomerTestimonials/index.tsx @@ -0,0 +1,109 @@ +import Carousel from "@/components/Carousel"; +import Image from "next/image"; +import Link from "next/link"; +import { HiArrowLeft, HiArrowRight } from "react-icons/hi2"; +import { FaHeart } from "react-icons/fa"; +import { manrope } from "@/lib/fonts"; + +const customerData = [ + { + desc: `When producing live broadcasts for Fortune 500 companies security is of + the utmost importance. We therefore selected Firezone for its robust + WireGuard-based architecture. The flexible policy system and simple & + clean user experience make Firezone the best fitting product for us in + the market after trying several other solutions like Tailscale, OpenVPN, + and Nebula.`, + authorName: "Robert Buisman", + authorImage: "/images/portrait-robert-buisman.png", + authorTitle: "CEO, NOMOBO", + }, + { + desc: `Firezone's easy-to-setup, sleek, and simple interface makes management + effortless. It perfectly met our zero-trust security needs without the + complexity found in other products we tested.`, + authorName: "Mark Sim", + authorImage: "/images/portrait-mark-sim.jpg", + authorTitle: "Technical Account Manager, Beakon", + }, + { + desc: `After comparing Tailscale, we ultimately chose Firezone to secure access + to our data warehouses. Firezone's ease of configuration and robust + policy-based access system made it the clear choice for our needs.`, + authorName: "James Winegar", + authorImage: "/images/portrait-james-winegar.png", + authorTitle: "CEO, Corrdyn", + }, + { + desc: `At Strong Compute, we have been using Firezone for over 3 years and it + is still the most stable and best VPN solution we tested for remote access.`, + authorName: "Cian Byrne", + authorImage: "/images/portrait-cian-byrne.jpg", + authorTitle: "Founding Engineer, Strong Compute", + }, +]; + +interface TestimonialBoxProps { + desc: string; + authorImage: string; + authorName: string; + authorTitle: string; +} + +const TestimonialBox = ({ + desc, + authorImage, + authorName, + authorTitle, +}: TestimonialBoxProps) => { + return ( +
+
+

+ "{desc}" +

+
+
+ author portrait +
+

{authorName}

+

{authorTitle}

+
+
+
+ ); +}; + +export default function CustomerTestimonials() { + return ( +
+
+

+ Customers{" "} + us +

+

+ (and we love them back) +

+ + {customerData.map((item, index) => ( + + ))} + +
+
+ ); +}