feat: add version history drawer with release notes

Introduce a footer-triggered Version History drawer with categorized release notes, hardcoded release data, and semver tracking at v0.3.0. Also ships blog blockquote/table styling, site-wide typography, home page image updates, header refinements, and related bug fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
alirez.br
2026-07-02 02:46:20 +03:30
co-authored by Cursor
parent 62163c4ab9
commit a47ec493c5
92 changed files with 4574 additions and 507 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ const buttonVariants = cva(
ghost:
"hover:bg-accent hover:text-foreground dark:hover:bg-[#FCC61D] dark:hover:text-foreground",
link:
"text-primary underline-offset-4 hover:text-accent hover:underline dark:hover:text-[#FCC61D]",
"text-accent underline-offset-4 hover:underline",
},
size: {
default: "h-9 px-4 text-sm has-[>svg]:px-3",
+3 -2
View File
@@ -1,6 +1,7 @@
import * as React from "react"
import { cn } from "@/lib/utils"
import { type as typeScale } from "@/lib/typography"
function Card({ className, ...props }: React.ComponentProps<"div">) {
return (
@@ -32,7 +33,7 @@ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-title"
className={cn("leading-none font-semibold", className)}
className={cn(typeScale["card-title"], className)}
{...props}
/>
)
@@ -42,7 +43,7 @@ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="card-description"
className={cn("text-muted-foreground text-sm", className)}
className={cn(typeScale["card-desc"], className)}
{...props}
/>
)
+1 -1
View File
@@ -73,7 +73,7 @@ function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
<div
data-slot="empty-description"
className={cn(
"text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4",
"text-muted-foreground [&>a]:text-accent text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4 hover:[&>a]:no-underline",
className
)}
{...props}
+1 -1
View File
@@ -145,7 +145,7 @@ function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
className={cn(
"text-muted-foreground text-sm leading-normal font-normal group-has-[[data-orientation=horizontal]]/field:text-balance",
"last:mt-0 nth-last-2:-mt-1 [[data-variant=legend]+&]:-mt-1.5",
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
"[&>a]:text-accent [&>a]:underline [&>a]:underline-offset-4 hover:[&>a]:no-underline",
className
)}
{...props}
+1 -1
View File
@@ -135,7 +135,7 @@ function ItemDescription({ className, ...props }: React.ComponentProps<"p">) {
data-slot="item-description"
className={cn(
"text-muted-foreground line-clamp-2 text-sm leading-normal font-normal text-balance",
"[&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
"[&>a]:text-accent [&>a]:underline [&>a]:underline-offset-4 hover:[&>a]:no-underline",
className
)}
{...props}
+9 -1
View File
@@ -48,9 +48,12 @@ function SheetContent({
className,
children,
side = "right",
closePosition = "end",
...props
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
side?: "top" | "right" | "bottom" | "left"
/** Physical corner for the close button. Use `start` for left in LTR / RTL layouts. */
closePosition?: "start" | "end"
}) {
return (
<SheetPortal>
@@ -72,7 +75,12 @@ function SheetContent({
{...props}
>
{children}
<SheetPrimitive.Close className="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none">
<SheetPrimitive.Close
className={cn(
"ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none",
closePosition === "start" ? "left-4" : "right-4"
)}
>
<XIcon className="size-4" />
<span className="sr-only">Close</span>
</SheetPrimitive.Close>
+126
View File
@@ -0,0 +1,126 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import {
typographyVariants,
type TypographyVariant,
} from "@/lib/typography";
import { cn } from "@/lib/utils";
const defaultElement: Record<TypographyVariant, React.ElementType> = {
display: "h1",
h1: "h1",
h2: "h2",
h3: "h3",
h4: "h4",
"body-lg": "p",
body: "p",
"body-sm": "p",
caption: "span",
eyebrow: "p",
label: "span",
nav: "span",
"nav-mobile": "span",
"card-title": "h3",
"card-desc": "p",
chat: "p",
code: "code",
stat: "span",
link: "span",
"section-intro": "p",
emphasis: "p",
"list-title": "span",
"cta-title": "h2",
"display-mono": "span",
};
export type TypographyProps = {
variant: TypographyVariant;
as?: React.ElementType;
asChild?: boolean;
className?: string;
children?: React.ReactNode;
} & React.HTMLAttributes<HTMLElement>;
export function Typography({
variant,
as,
asChild = false,
className,
children,
...props
}: TypographyProps) {
const Comp = asChild ? Slot : (as ?? defaultElement[variant] ?? "p");
return (
<Comp
className={cn(typographyVariants({ variant }), className)}
{...props}
>
{children}
</Comp>
);
}
export {
Display,
PageTitle,
SectionTitle,
SubsectionTitle,
SmallHeading,
BodyLarge,
BodyText,
BodySmall,
Caption,
Eyebrow,
CardTitleText,
CardDescText,
};
function Display(props: Omit<TypographyProps, "variant">) {
return <Typography variant="display" {...props} />;
}
function PageTitle(props: Omit<TypographyProps, "variant">) {
return <Typography variant="h1" {...props} />;
}
function SectionTitle(props: Omit<TypographyProps, "variant">) {
return <Typography variant="h2" {...props} />;
}
function SubsectionTitle(props: Omit<TypographyProps, "variant">) {
return <Typography variant="h3" {...props} />;
}
function SmallHeading(props: Omit<TypographyProps, "variant">) {
return <Typography variant="h4" {...props} />;
}
function BodyLarge(props: Omit<TypographyProps, "variant">) {
return <Typography variant="body-lg" {...props} />;
}
function BodyText(props: Omit<TypographyProps, "variant">) {
return <Typography variant="body" {...props} />;
}
function BodySmall(props: Omit<TypographyProps, "variant">) {
return <Typography variant="body-sm" {...props} />;
}
function Caption(props: Omit<TypographyProps, "variant">) {
return <Typography variant="caption" {...props} />;
}
function Eyebrow(props: Omit<TypographyProps, "variant">) {
return <Typography variant="eyebrow" {...props} />;
}
function CardTitleText(props: Omit<TypographyProps, "variant">) {
return <Typography variant="card-title" {...props} />;
}
function CardDescText(props: Omit<TypographyProps, "variant">) {
return <Typography variant="card-desc" {...props} />;
}