This commit is contained in:
@@ -24,6 +24,8 @@ export default function ConnectPage() {
|
||||
width={128}
|
||||
height={128}
|
||||
className="rounded-full border shadow-sm"
|
||||
sizes="128px"
|
||||
priority
|
||||
/>
|
||||
</BlurFade>
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function Page() {
|
||||
<div className="flex flex-col items-center gap-y-2">
|
||||
<BlurFade delay={BLUR_FADE_DELAY}>
|
||||
<Avatar className="size-28 border">
|
||||
<AvatarImage alt={DATA.name} src={DATA.avatarUrl} />
|
||||
<AvatarImage alt={DATA.name} src={DATA.avatarUrl} fetchPriority="high" />
|
||||
<AvatarFallback>{DATA.initials}</AvatarFallback>
|
||||
</Avatar>
|
||||
</BlurFade>
|
||||
|
||||
@@ -54,6 +54,7 @@ export function ResearchCard({
|
||||
src={image}
|
||||
alt={title}
|
||||
fill
|
||||
sizes="160px"
|
||||
className="object-cover object-center"
|
||||
/>
|
||||
</div>
|
||||
@@ -69,8 +70,10 @@ export function ResearchCard({
|
||||
{venue && <span>•</span>}
|
||||
<time>{dates}</time>
|
||||
</div>
|
||||
<div className="prose max-w-full text-pretty font-normal text-xs text-foreground dark:prose-invert">
|
||||
<Markdown>{description}</Markdown>
|
||||
<div className="prose max-w-full text-pretty font-sans text-xs text-muted-foreground dark:prose-invert">
|
||||
<Markdown>
|
||||
{description}
|
||||
</Markdown>
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
@@ -52,6 +52,8 @@ export function Header() {
|
||||
width={40}
|
||||
height={40}
|
||||
className="rounded-full"
|
||||
sizes="40px"
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -48,6 +48,7 @@ export function ResearchListItem({
|
||||
alt={title}
|
||||
width={200}
|
||||
height={150}
|
||||
sizes="120px"
|
||||
className="max-h-30 h-full w-full object-contain p-2"
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -15,14 +15,7 @@ interface Props {
|
||||
description: string;
|
||||
dates: string;
|
||||
tags: readonly string[];
|
||||
link?: string;
|
||||
image?: string;
|
||||
video?: string;
|
||||
links?: readonly {
|
||||
icon: React.ReactNode;
|
||||
type: string;
|
||||
href: string;
|
||||
}[];
|
||||
className?: string;
|
||||
}
|
||||
|
||||
@@ -32,7 +25,6 @@ export function ExperienceCard({
|
||||
description,
|
||||
dates,
|
||||
image,
|
||||
links,
|
||||
className,
|
||||
}: Props) {
|
||||
return (
|
||||
@@ -43,7 +35,6 @@ export function ExperienceCard({
|
||||
, className
|
||||
)}
|
||||
>
|
||||
{/* 3. The Card component now has its conflicting shadow removed. */}
|
||||
<Card className="flex flex-row items-center p-4 shadow-none">
|
||||
<div className="flex-none flex-shrink-0 size-12">
|
||||
<Avatar className="h-full w-full rounded-md bg-muted-background">
|
||||
@@ -52,6 +43,8 @@ export function ExperienceCard({
|
||||
src={image}
|
||||
alt={title}
|
||||
className="object-contain"
|
||||
fetchPriority="low"
|
||||
sizes="48"
|
||||
/>
|
||||
)}
|
||||
<AvatarFallback>{title[0]}</AvatarFallback>
|
||||
@@ -63,19 +56,6 @@ export function ExperienceCard({
|
||||
<div className="flex items-center justify-between gap-x-2 text-base">
|
||||
<h3 className="inline-flex items-center justify-center gap-x-2 font-semibold leading-none text-xs sm:text-sm">
|
||||
{title}
|
||||
{links && links.length > 0 && (
|
||||
<span className="inline-flex gap-x-1">
|
||||
{links.map((link, idx) => (
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className="align-middle text-xs"
|
||||
key={idx}
|
||||
>
|
||||
{link.type}
|
||||
</Badge>
|
||||
))}
|
||||
</span>
|
||||
)}
|
||||
<ChevronRightIcon className="size-4 shrink-0 translate-x-0 transform opacity-0 transition-all duration-300 ease-out group-hover:translate-x-1 group-hover:opacity-100" />
|
||||
</h3>
|
||||
<div className="text-xs sm:text-sm tabular-nums text-muted-foreground text-right whitespace-nowrap">
|
||||
|
||||
@@ -20,6 +20,7 @@ export const ModeToggle = React.forwardRef<
|
||||
size="icon"
|
||||
className={className}
|
||||
ref={ref}
|
||||
aria-label="Toogle theme"
|
||||
{...props}
|
||||
onClick={() => setTheme(theme === "light" ? "dark" : "light")}
|
||||
>
|
||||
|
||||
@@ -15,9 +15,9 @@ import Link from "next/link";
|
||||
|
||||
export default function Navbar() {
|
||||
return (
|
||||
<div className="pointer-events-auto fixed inset-x-0 bottom-0 z-30 mx-auto mb-4 flex origin-bottom">
|
||||
<div className="pointer-events-auto mx-auto max-w-max">
|
||||
<Dock direction="middle" className="bg-background backdrop-blur-none border">
|
||||
<div className="pointer-events-auto fixed inset-x-0 bottom-0 z-30 mx-auto mb-6 flex origin-bottom mt-0">
|
||||
<div className="pointer-events-auto mx-auto max-w-max mt-0">
|
||||
<Dock direction="middle" className=" shadow-lg bg-background border mt-0">
|
||||
{DATA.navbar.map((item) => (
|
||||
<DockIcon key={item.href}>
|
||||
<Tooltip>
|
||||
@@ -28,6 +28,7 @@ export default function Navbar() {
|
||||
buttonVariants({ variant: "ghost", size: "icon" }),
|
||||
"size-12",
|
||||
)}
|
||||
aria-label={item.label}
|
||||
>
|
||||
<item.icon className="size-4" />
|
||||
</Link>
|
||||
|
||||
@@ -60,7 +60,7 @@ export function ProjectCard({
|
||||
loop
|
||||
muted
|
||||
playsInline
|
||||
className="pointer-events-none mx-auto max-h-40 h-full object-cover object-top" // needed because random black line at bottom of video
|
||||
className="pointer-events-none mx-auto max-h-40 h-full object-cover object-top"
|
||||
/>
|
||||
)}
|
||||
{image && (
|
||||
@@ -69,6 +69,7 @@ export function ProjectCard({
|
||||
alt={title}
|
||||
width={500}
|
||||
height={300}
|
||||
sizes="240"
|
||||
className="m-auto h-full max-h-40 min-h-40 max-w-60 overflow-hidden object-scale-down object-center place-content-center"
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -51,6 +51,7 @@ export const ResumeCard = ({
|
||||
src={logoUrl}
|
||||
alt={altText}
|
||||
className="object-contain"
|
||||
fetchPriority="high"
|
||||
/>
|
||||
<AvatarFallback>{altText[0]}</AvatarFallback>
|
||||
</Avatar>
|
||||
|
||||
14
package.json
14
package.json
@@ -19,10 +19,10 @@
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"gray-matter": "^4.0.3",
|
||||
"lucide-react": "^0.543.0",
|
||||
"lucide-react": "^0.544.0",
|
||||
"mdx-bundler": "^10.1.1",
|
||||
"motion": "^12.23.12",
|
||||
"next": "15.5.2",
|
||||
"motion": "^12.23.14",
|
||||
"next": "15.5.3",
|
||||
"next-themes": "^0.4.6",
|
||||
"react": "19.1.1",
|
||||
"react-dom": "19.1.1",
|
||||
@@ -44,17 +44,17 @@
|
||||
"devDependencies": {
|
||||
"@eslint/eslintrc": "^3.3.1",
|
||||
"@tailwindcss/postcss": "^4.1.13",
|
||||
"@types/node": "^24.3.1",
|
||||
"@types/react": "^19.1.12",
|
||||
"@types/node": "^24.5.2",
|
||||
"@types/react": "^19.1.13",
|
||||
"@types/react-dom": "^19.1.9",
|
||||
"eslint": "^9.35.0",
|
||||
"eslint-config-next": "15.5.2",
|
||||
"eslint-config-next": "15.5.3",
|
||||
"tailwindcss": "^4.1.13",
|
||||
"tw-animate-css": "^1.3.8",
|
||||
"typescript": "^5.9.2"
|
||||
},
|
||||
"pnpm": {
|
||||
"trustedDependencies": [
|
||||
"onlyBuiltDependencies": [
|
||||
"@tailwindcss/oxide",
|
||||
"esbuild",
|
||||
"sharp",
|
||||
|
||||
806
pnpm-lock.yaml
generated
806
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user