spb/spboucher.ai Public
spboucher.ai — personal website of Simon-Pierre Boucher.
TypeScript 93.4%
HTML 5.5%
CSS 1%
1/*2 page.tsx3 spboucher.ai Web4 Author: Simon-Pierre Boucher5 Mail: contact@spboucher.ai6*/78import type { Metadata } from "next";9import Image from "next/image";10import Link from "next/link";11import { ArrowRight, CalendarDays, Clock, PenTool } from "lucide-react";1213import { Badge } from "@/components/ui/badge";14import { Card, CardContent, CardHeader } from "@/components/ui/card";15import { Reveal } from "@/components/reveal";16import { SectionHeading } from "@/components/section-heading";17import { getBlogPosts } from "@/lib/blog";1819export const metadata: Metadata = {20 title: "Blog — Essays on AI & Economics",21 description:22 "Essays by Simon-Pierre Boucher on the economics of artificial intelligence: the collapsing cost of intelligence, the ownership of AI-generated wealth, and the data limits of the singularity.",23};2425export default function BlogPage() {26 const posts = getBlogPosts();2728 return (29 <div className="mx-auto max-w-5xl px-4 py-16 sm:px-6">30 <Reveal>31 <SectionHeading32 as="h1"33 eyebrow="Writing"34 title="Blog"35 icon={PenTool}36 description="Essays on the economics of artificial intelligence — intelligence as an industrial input, the ownership of machine-generated wealth, and the informational limits of recursive self-improvement."37 />38 </Reveal>3940 <div className="mt-10 space-y-6">41 {posts.map((post, i) => (42 <Reveal key={post.slug} delay={i * 0.08}>43 <Link href={`/blog/${post.slug}`} className="group block">44 <Card className="relative overflow-hidden hover:-translate-y-1 hover:border-primary/25 hover:shadow-[var(--shadow-lift)]">45 <span46 aria-hidden="true"47 className="pointer-events-none absolute inset-y-6 left-0 w-1 rounded-r-full bg-gradient-to-b from-primary/70 to-primary/10 opacity-0 transition-opacity duration-300 group-hover:opacity-100"48 />49 <CardHeader className="gap-3">50 <div className="flex flex-wrap items-center gap-x-4 gap-y-2 text-xs font-medium text-muted-foreground">51 <span className="inline-flex items-center gap-1.5">52 <CalendarDays53 className="h-3.5 w-3.5 text-primary/70"54 aria-hidden="true"55 />56 {post.dateLabel}57 </span>58 <span className="inline-flex items-center gap-1.5">59 <Clock60 className="h-3.5 w-3.5 text-primary/70"61 aria-hidden="true"62 />63 {post.readingMinutes} min read64 </span>65 <span className="flex flex-wrap gap-1.5">66 {post.tags.map((tag) => (67 <Badge key={tag} variant="outline">68 {tag}69 </Badge>70 ))}71 </span>72 </div>73 <h2 className="font-display text-xl font-bold leading-snug tracking-tight transition-colors group-hover:text-primary sm:text-2xl">74 {post.title}75 </h2>76 </CardHeader>77 <CardContent className="flex flex-col gap-5">78 <p className="max-w-3xl text-sm leading-relaxed text-muted-foreground">79 {post.excerpt}80 </p>81 <div className="flex items-center justify-between gap-4">82 <span className="inline-flex items-center gap-2 text-xs text-muted-foreground">83 <Image84 src="/profile/simon-pierre-boucher.jpeg"85 alt=""86 aria-hidden="true"87 width={48}88 height={48}89 className="h-6 w-6 rounded-full object-cover object-top ring-1 ring-border/60"90 />91 Simon-Pierre Boucher92 </span>93 <span className="inline-flex items-center gap-1 text-sm font-medium text-primary">94 Read essay95 <ArrowRight96 className="h-4 w-4 transition-transform duration-300 group-hover:translate-x-1"97 aria-hidden="true"98 />99 </span>100 </div>101 </CardContent>102 </Card>103 </Link>104 </Reveal>105 ))}106 </div>107 </div>108 );109}110