SPB Git

Repository Public

platform-links.tsx 3.0 KB 102 lines tsx

1/*2  platform-links.tsx3  spboucher.ai Web4  Author: Simon-Pierre Boucher5  Mail: contact@spboucher.ai6*/78import { Cpu, Library, PenLine, Sparkles, type LucideIcon } from "lucide-react";910import { cn } from "@/lib/utils";1112/** Sister sites, shown as icon links on the home page and in the footer. */13export const platformLinks: {14  href: string;15  label: string;16  hint: string;17  icon: LucideIcon;18}[] = [19  {20    href: "https://maclustr.spboucher.ai",21    label: "MacLustr",22    hint: "Apple Silicon compute cluster",23    icon: Cpu,24  },25  {26    href: "https://wp.spboucher.ai",27    label: "Papers",28    hint: "Research observatory and interactive reader",29    icon: Library,30  },31  {32    href: "https://htr.spboucher.ai",33    label: "HTR",34    hint: "Human Text Reconstruction",35    icon: PenLine,36  },37  {38    href: "https://skills.spboucher.ai",39    label: "Skills",40    hint: "Skills library",41    icon: Sparkles,42  },43];4445/** `tiles`: labelled icon tiles (home hero). `icons`: compact icon-only squares (footer). */46export function PlatformLinks({47  variant = "tiles",48  className,49}: {50  variant?: "tiles" | "icons";51  className?: string;52}) {53  if (variant === "icons") {54    return (55      <>56        {platformLinks.map(({ href, label, hint, icon: Icon }) => (57          <a58            key={href}59            href={href}60            target="_blank"61            rel="noopener noreferrer"62            aria-label={`${label} — ${hint}`}63            title={`${label} — ${hint}`}64            className="inline-flex h-8 w-8 items-center justify-center border border-foreground/15 bg-card text-muted-foreground transition-all hover:-translate-y-px hover:border-foreground/50 hover:text-foreground"65          >66            <Icon className="h-3.5 w-3.5" aria-hidden="true" />67          </a>68        ))}69      </>70    );71  }72  return (73    <nav74      aria-label="Platforms"75      className={cn("grid grid-cols-2 gap-2 sm:grid-cols-4", className)}76    >77      {platformLinks.map(({ href, label, hint, icon: Icon }) => (78        <a79          key={href}80          href={href}81          target="_blank"82          rel="noopener noreferrer"83          title={hint}84          className="group flex items-center gap-2.5 border border-foreground/15 bg-card px-3 py-2.5 transition-all hover:-translate-y-px hover:border-primary/60 hover:shadow-sm"85        >86          <span className="inline-flex h-8 w-8 shrink-0 items-center justify-center border border-primary/25 bg-primary/5 text-primary transition-colors group-hover:bg-primary group-hover:text-primary-foreground">87            <Icon className="h-4 w-4" aria-hidden="true" />88          </span>89          <span className="min-w-0">90            <span className="block truncate text-sm font-medium leading-tight">91              {label}92            </span>93            <span className="block truncate font-mono text-[0.6rem] uppercase tracking-[0.12em] text-muted-foreground">94              {href.replace("https://", "").replace(".spboucher.ai", "")}95            </span>96          </span>97        </a>98      ))}99    </nav>100  );101}102
Files main
Menu

Theme