SPB Git

spb/spboucher.ai Public

spboucher.ai — personal website of Simon-Pierre Boucher.

TypeScript 93.4% HTML 5.5% CSS 1%

Apps: real project logos + Metrika DMG download button

Replace generic emoji tiles with real 512px app logos for VQuant,
AI Risk Index, Metrika and Zyquo Cloud Web (sourced from each repo's
icon assets). Add Download DMG button on Metrika (v1.0.1 release,
latest/download URL). Emoji tile remains the fallback for projects
without a logo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Simon-Pierre Boucher committed 6 days ago (Aug 5, 2026) parent 48bfd66

Showing 6 changed files with +34 and −7

modified components/project-card.tsx +27 −7
@@ -5,7 +5,8 @@
5 5 Mail: contact@spboucher.ai
6 6 */
7 7
8 import { ExternalLink, Github } from "lucide-react";
8 +import Image from "next/image";
9 +import { Download, ExternalLink, Github } from "lucide-react";
9 10
10 11 import type { OpenSourceProject } from "@/lib/apps";
11 12 import { buttonVariants } from "@/components/ui/button";
@@ -23,12 +24,22 @@ export function ProjectCard({ project }: { project: OpenSourceProject }) {
23 24 return (
24 25 <Card className="flex h-full flex-col hover:-translate-y-1 hover:shadow-[var(--shadow-lift)]">
25 26 <CardHeader className="flex-row items-center gap-4 space-y-0">
26 <div
27 aria-hidden="true"
28 className="flex h-16 w-16 shrink-0 items-center justify-center rounded-2xl bg-muted text-3xl shadow-sm"
29 >
30 {project.emoji}
31 </div>
27 + {project.icon ? (
28 + <Image
29 + src={project.icon}
30 + alt={`${project.name} logo`}
31 + width={64}
32 + height={64}
33 + className="h-16 w-16 shrink-0 rounded-2xl shadow-sm"
34 + />
35 + ) : (
36 + <div
37 + aria-hidden="true"
38 + className="flex h-16 w-16 shrink-0 items-center justify-center rounded-2xl bg-muted text-3xl shadow-sm"
39 + >
40 + {project.emoji}
41 + </div>
42 + )}
32 43 <div className="min-w-0">
33 44 <CardTitle className="text-lg">{project.name}</CardTitle>
34 45 <CardDescription className="mt-1">{project.tagline}</CardDescription>
@@ -58,6 +69,15 @@ export function ProjectCard({ project }: { project: OpenSourceProject }) {
58 69 Live Demo
59 70 </a>
60 71 ) : null}
72 + {project.dmg ? (
73 + <a
74 + href={project.dmg}
75 + className={cn(buttonVariants({ variant: "default", size: "sm" }))}
76 + >
77 + <Download aria-hidden="true" />
78 + Download DMG
79 + </a>
80 + ) : null}
61 81 <span className="ml-auto rounded-full border px-2.5 py-0.5 text-xs text-muted-foreground">
62 82 {project.language}
63 83 </span>
modified lib/apps.ts +7 −0
@@ -26,11 +26,14 @@ export interface OpenSourceProject {
26 26 language: string;
27 27 repo: string;
28 28 demo?: string;
29 + icon?: string;
30 + dmg?: string;
29 31 }
30 32
31 33 export const openSourceProjects: OpenSourceProject[] = [
32 34 {
33 35 slug: "vquant",
36 + icon: "/icons/vquant.png",
34 37 name: "VQuant",
35 38 emoji: "📈",
36 39 tagline: "AI financial intelligence platform",
@@ -42,6 +45,7 @@ export const openSourceProjects: OpenSourceProject[] = [
42 45 },
43 46 {
44 47 slug: "airiskindex",
48 + icon: "/icons/airiskindex.png",
45 49 name: "AI Risk Index",
46 50 emoji: "🤖",
47 51 tagline: "Task-based AI job-exposure index",
@@ -53,6 +57,8 @@ export const openSourceProjects: OpenSourceProject[] = [
53 57 },
54 58 {
55 59 slug: "metrika",
60 + icon: "/icons/metrika.png",
61 + dmg: "https://github.com/spboucher-ai/metrika/releases/latest/download/Metrika.dmg",
56 62 name: "Metrika",
57 63 emoji: "📊",
58 64 tagline: "GPU-accelerated statistics for macOS",
@@ -73,6 +79,7 @@ export const openSourceProjects: OpenSourceProject[] = [
73 79 },
74 80 {
75 81 slug: "zyquo-cloud-web",
82 + icon: "/icons/zyquo-cloud-web.png",
76 83 name: "Zyquo Cloud Web",
77 84 emoji: "🌐",
78 85 tagline: "Browser edition of Zyquo Cloud",
added public/icons/airiskindex.png +0 −0

Binary file not shown.

added public/icons/metrika.png +0 −0

Binary file not shown.

added public/icons/vquant.png +0 −0

Binary file not shown.

added public/icons/zyquo-cloud-web.png +0 −0

Binary file not shown.