diff --git a/.cursor/rules/css.mdc b/.cursor/rules/css.mdc
new file mode 100644
index 00000000..40df6f11
--- /dev/null
+++ b/.cursor/rules/css.mdc
@@ -0,0 +1,11 @@
+---
+description:
+globs: *.tsx,app/globals.css
+alwaysApply: false
+---
+This rule provides standards for frontend components, ensuring consistent styling and animations:
+
+- Use Tailwind CSS v4 and shadcn/ui (with Radix primitives) for components and styling.
+- Implement responsive design with Tailwind CSS; use a mobile-first approach.
+- Dynamic theme switching (light/dark mode) is supported through CSS variables. See [globals.css](mdc:app/globals.css).
+- Import and use `cn()` utility from [utils.ts](mdc:lib/utils.ts) for conditional class names.
diff --git a/.cursor/rules/nextjs.mdc b/.cursor/rules/nextjs.mdc
new file mode 100644
index 00000000..93389535
--- /dev/null
+++ b/.cursor/rules/nextjs.mdc
@@ -0,0 +1,18 @@
+---
+description:
+globs:
+alwaysApply: true
+---
+This rule provides standards for using Next.js features:
+
+- Project uses latest Next.js features like App Router, Partial Prerendering. See [next.config.ts](mdc:next.config.ts).
+- Always choose React Server Components (RSC) when possible, use Client Components only when necessary (minimize `use client`, `useEffect`, and `setState`).
+- Always prefer Server Actions over API routes.
+- Environment variables must be validated and imported from [env.ts](mdc:lib/env.ts). Never use `process.env` directly; always from [env.ts](mdc:lib/env.ts).
+- Use MDX for content-heavy pages. Also supports third-party embeds like YouTube videos, Tweets, etc; see [mdx-components.tsx](mdc:mdx-components.tsx).
+- Always use Next.js' optimized `` tag for images, never `
`.
+- Performance optimization is a priority (bundle sizes, image optimization, etc.)
+- Use Next.js caching and revalidation strategies (`revalidate`, `tags`) for all data fetching.
+- Store and retrieve data from Upstash Redis as the primary data store.
+- Ensure all features and APIs are compatible with Vercel's serverless environment.
+- Accessibility is important. Maintain proper heading levels, skip links, etc.
diff --git a/.cursorignore b/.cursorignore
new file mode 100644
index 00000000..3e4b1f1d
--- /dev/null
+++ b/.cursorignore
@@ -0,0 +1,4 @@
+# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
+
+/notes/
+/public/
diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
deleted file mode 100644
index a2fd2023..00000000
--- a/.github/copilot-instructions.md
+++ /dev/null
@@ -1,59 +0,0 @@
-# Project Information for GitHub Copilot
-
-This repository contains the source code for [jarv.is](https://jarv.is/), a personal website for Jake Jarvis built with Next.js.
-
-## Project Overview
-
-- **Type**: Personal website with blog
-- **Framework**: Next.js (uses latest features like App Router, Partial Prerendering)
-- **Primary Language**: TypeScript
-- **Styling**: Tailwind CSS
-- **Data Storage**: Upstash Redis
-- **Content**: MDX for blog posts with custom components
-- **Deployment**: Vercel
-
-## Project Structure
-
-```
-/
-├── app/ # Pages and layouts using Next.js App Router
-├── components/ # Reusable React components
-├── lib/ # Utility functions, configurations, and helpers
-├── notes/ # Blog posts written in MDX format along with any images
-└── public/ # Static assets
-```
-
-## Code Style & Conventions
-
-- **Formatting**: Prettier is used for code formatting
-- **Linting**: ESLint with custom configuration
-- **JavaScript/TypeScript**:
- - Use double quotes for strings
- - 2-space indentation (no tabs)
- - Trailing commas in objects and arrays
- - Maximum line length of 120 characters
- - TypeScript is strictly typed
-- **React Components**:
- - Prefer function components with hooks
- - Use named exports for components
- - Client components are marked with "use client" directive
-- **CSS**:
- - Use Tailwind utility classes
- - Custom CSS variables for theming (light/dark mode)
- - `cn()` from `lib/utils.ts` utility for conditional class names
-
-## Preferred Solutions
-
-- When suggesting code changes, maintain the existing patterns and structure
-- **React Server Components when possible, Client Components when necessary**
-- MDX for content-heavy pages
-- Image optimization through Next.js Image component
-- Cache and revalidate data appropriately with tags
-
-## Other Notes
-
-- Dynamic theme switching (light/dark mode) is supported
-- Accessibility is important - maintain proper heading levels, skip links, etc.
-- Performance optimization is a priority (bundle sizes, image optimization, etc.)
-
-This document should be updated when significant architectural or dependency changes are made to the project.
diff --git a/mdx-components.tsx b/mdx-components.tsx
index fef2fda6..8aa26af1 100644
--- a/mdx-components.tsx
+++ b/mdx-components.tsx
@@ -24,8 +24,10 @@ export const useMDXComponents = (components: MDXComponents): MDXComponents => {
{...rest}
/>
),
- img: ({ className, ...rest }) => (
+ img: ({ src, className, ...rest }) => (
896 ? 896 : undefined} // => var(--container-4xl)
className={cn(
"mx-auto my-8 block h-auto max-w-full rounded-md",
"[&+em]:text-muted-foreground [&+em]:-mt-4 [&+em]:block [&+em]:text-center [&+em]:text-[0.875em] [&+em]:leading-normal [&+em]:font-medium [&+em]:not-italic",
diff --git a/package.json b/package.json
index ba466138..5968ff68 100644
--- a/package.json
+++ b/package.json
@@ -42,7 +42,7 @@
"feed": "^4.2.2",
"geist": "^1.4.2",
"html-entities": "^2.6.0",
- "lucide-react": "0.507.0",
+ "lucide-react": "0.508.0",
"next": "15.4.0-canary.23",
"prop-types": "^15.8.1",
"react": "19.1.0",
@@ -95,7 +95,7 @@
"cross-env": "^7.0.3",
"eslint": "^9.26.0",
"eslint-config-next": "15.4.0-canary.23",
- "eslint-config-prettier": "^10.1.2",
+ "eslint-config-prettier": "^10.1.3",
"eslint-plugin-css-modules": "^2.12.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index f0ffcb07..d7c17c58 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -81,8 +81,8 @@ importers:
specifier: ^2.6.0
version: 2.6.0
lucide-react:
- specifier: 0.507.0
- version: 0.507.0(react@19.1.0)
+ specifier: 0.508.0
+ version: 0.508.0(react@19.1.0)
next:
specifier: 15.4.0-canary.23
version: 15.4.0-canary.23(@babel/core@7.26.10)(babel-plugin-react-compiler@19.0.0-beta-af1b7da-20250417)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@@ -235,8 +235,8 @@ importers:
specifier: 15.4.0-canary.23
version: 15.4.0-canary.23(eslint@9.26.0(jiti@2.4.2))(typescript@5.8.3)
eslint-config-prettier:
- specifier: ^10.1.2
- version: 10.1.2(eslint@9.26.0(jiti@2.4.2))
+ specifier: ^10.1.3
+ version: 10.1.3(eslint@9.26.0(jiti@2.4.2))
eslint-plugin-css-modules:
specifier: ^2.12.0
version: 2.12.0(eslint@9.26.0(jiti@2.4.2))
@@ -251,7 +251,7 @@ importers:
version: 3.4.1(eslint@9.26.0(jiti@2.4.2))
eslint-plugin-prettier:
specifier: ^5.4.0
- version: 5.4.0(eslint-config-prettier@10.1.2(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2))(prettier@3.5.3)
+ version: 5.4.0(eslint-config-prettier@10.1.3(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2))(prettier@3.5.3)
eslint-plugin-react:
specifier: ^7.37.5
version: 7.37.5(eslint@9.26.0(jiti@2.4.2))
@@ -1962,8 +1962,8 @@ packages:
typescript:
optional: true
- eslint-config-prettier@10.1.2:
- resolution: {integrity: sha512-Epgp/EofAUeEpIdZkW60MHKvPyru1ruQJxPL+WIycnaPApuseK0Zpkrh/FwL9oIpQvIhJwV7ptOy0DWUjTlCiA==}
+ eslint-config-prettier@10.1.3:
+ resolution: {integrity: sha512-vDo4d9yQE+cS2tdIT4J02H/16veRvkHgiLDRpej+WL67oCfbOb97itZXn8wMPJ/GsiEBVjrjs//AVNw2Cp1EcA==}
hasBin: true
peerDependencies:
eslint: '>=7.0.0'
@@ -2863,8 +2863,8 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
- lucide-react@0.507.0:
- resolution: {integrity: sha512-XfgE6gvAHwAtnbUvWiTTHx4S3VGR+cUJHEc0vrh9Ogu672I1Tue2+Cp/8JJqpytgcBHAB1FVI297W4XGNwc2dQ==}
+ lucide-react@0.508.0:
+ resolution: {integrity: sha512-gcP16PnexqtOFrTtv98kVsGzTfnbPekzZiQfByi2S89xfk7E/4uKE1USZqccIp58v42LqkO7MuwpCqshwSrJCg==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
@@ -6048,7 +6048,7 @@ snapshots:
- eslint-plugin-import-x
- supports-color
- eslint-config-prettier@10.1.2(eslint@9.26.0(jiti@2.4.2)):
+ eslint-config-prettier@10.1.3(eslint@9.26.0(jiti@2.4.2)):
dependencies:
eslint: 9.26.0(jiti@2.4.2)
@@ -6180,14 +6180,14 @@ snapshots:
- remark-lint-file-extension
- supports-color
- eslint-plugin-prettier@5.4.0(eslint-config-prettier@10.1.2(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2))(prettier@3.5.3):
+ eslint-plugin-prettier@5.4.0(eslint-config-prettier@10.1.3(eslint@9.26.0(jiti@2.4.2)))(eslint@9.26.0(jiti@2.4.2))(prettier@3.5.3):
dependencies:
eslint: 9.26.0(jiti@2.4.2)
prettier: 3.5.3
prettier-linter-helpers: 1.0.0
synckit: 0.11.4
optionalDependencies:
- eslint-config-prettier: 10.1.2(eslint@9.26.0(jiti@2.4.2))
+ eslint-config-prettier: 10.1.3(eslint@9.26.0(jiti@2.4.2))
eslint-plugin-react-compiler@19.0.0-beta-af1b7da-20250417(eslint@9.26.0(jiti@2.4.2)):
dependencies:
@@ -7137,7 +7137,7 @@ snapshots:
dependencies:
yallist: 3.1.1
- lucide-react@0.507.0(react@19.1.0):
+ lucide-react@0.508.0(react@19.1.0):
dependencies:
react: 19.1.0