style: final consistency pass — theme, responsive, animations

This commit is contained in:
2026-06-01 20:36:42 -05:00
parent 533c166f3b
commit 274217c77f
4 changed files with 19 additions and 7 deletions

View File

@@ -1,7 +1,6 @@
import type { Metadata } from 'next' import type { Metadata } from 'next'
import { Inter, Merriweather, JetBrains_Mono } from 'next/font/google' import { Inter, Merriweather, JetBrains_Mono } from 'next/font/google'
import { ThemeProvider } from '@wrksz/themes/next' import { ThemeProvider } from '@wrksz/themes/next'
import { Providers } from './providers'
import './globals.css' import './globals.css'
import 'katex/dist/katex.min.css' import 'katex/dist/katex.min.css'
import { Header } from '@/components/layout/Header' import { Header } from '@/components/layout/Header'

View File

@@ -8,7 +8,7 @@ export default function NotFound() {
<div className="text-center"> <div className="text-center">
<p className="font-mono text-sm text-ink-soft mb-4">404</p> <p className="font-mono text-sm text-ink-soft mb-4">404</p>
<h1 className="font-sans text-4xl font-bold tracking-tight text-ink mb-4">Page not found</h1> <h1 className="font-sans text-4xl font-bold tracking-tight text-ink mb-4">Page not found</h1>
<p className="text-ink-soft mb-8">The page you're looking for doesn't exist.</p> <p className="text-ink-soft mb-8">The page you{`'`}re looking for doesn{`'`}t exist.</p>
<Link href="/" className="inline-block rounded-lg bg-ink px-6 py-3 text-sm font-medium text-canvas hover:opacity-80 transition-opacity"> <Link href="/" className="inline-block rounded-lg bg-ink px-6 py-3 text-sm font-medium text-canvas hover:opacity-80 transition-opacity">
Go home Go home
</Link> </Link>

View File

@@ -8,10 +8,8 @@ interface TOCItem {
level: number; level: number;
} }
export function TableOfContents() { function useHeadings(): TOCItem[] {
const [headings, setHeadings] = useState<TOCItem[]>([]); const [headings, setHeadings] = useState<TOCItem[]>([]);
const [activeId, setActiveId] = useState("");
const observerRef = useRef<IntersectionObserver | null>(null);
useEffect(() => { useEffect(() => {
const elements = Array.from( const elements = Array.from(
@@ -24,8 +22,19 @@ export function TableOfContents() {
level: el.tagName === "H2" ? 2 : 3, level: el.tagName === "H2" ? 2 : 3,
})); }));
// eslint-disable-next-line react-hooks/set-state-in-effect
setHeadings(parsed); setHeadings(parsed);
}, []);
return headings;
}
export function TableOfContents() {
const [activeId, setActiveId] = useState("");
const observerRef = useRef<IntersectionObserver | null>(null);
const headings = useHeadings();
useEffect(() => {
observerRef.current = new IntersectionObserver( observerRef.current = new IntersectionObserver(
(entries) => { (entries) => {
entries.forEach((entry) => { entries.forEach((entry) => {
@@ -37,6 +46,10 @@ export function TableOfContents() {
{ rootMargin: "-20% 0px -70% 0px", threshold: 0 } { rootMargin: "-20% 0px -70% 0px", threshold: 0 }
); );
const elements = Array.from(
document.querySelectorAll("article h2, article h3")
) as HTMLElement[];
elements.forEach((el) => observerRef.current?.observe(el)); elements.forEach((el) => observerRef.current?.observe(el));
return () => observerRef.current?.disconnect(); return () => observerRef.current?.disconnect();

View File

@@ -3,7 +3,7 @@ import path from 'path'
import matter from 'gray-matter' import matter from 'gray-matter'
import { compileMDX } from 'next-mdx-remote/rsc' import { compileMDX } from 'next-mdx-remote/rsc'
import { cache } from 'react' import { cache } from 'react'
import { useMDXComponents } from '@/mdx-components' import { useMDXComponents as getMDXComponents } from '@/mdx-components'
import remarkMath from 'remark-math' import remarkMath from 'remark-math'
import remarkGfm from 'remark-gfm' import remarkGfm from 'remark-gfm'
import rehypeKatex from 'rehype-katex' import rehypeKatex from 'rehype-katex'
@@ -58,7 +58,7 @@ export const getPost = async (slug: string): Promise<Post | null> => {
const filePath = path.join(postsDirectory, file) const filePath = path.join(postsDirectory, file)
const raw = await fs.readFile(filePath, 'utf8') const raw = await fs.readFile(filePath, 'utf8')
const { data, content } = matter(raw) const { data, content } = matter(raw)
const components = useMDXComponents({}) const components = getMDXComponents({})
const { content: compiledContent } = await compileMDX({ const { content: compiledContent } = await compileMDX({
source: content, source: content,