updated look
All checks were successful
Deploy Website / build-and-deploy (push) Successful in 2m15s

This commit is contained in:
Akshay Kolli
2026-04-11 23:27:29 -04:00
parent aa7fe8ecc7
commit 382edaab75
21 changed files with 740 additions and 397 deletions

View File

@@ -0,0 +1,7 @@
export function AmbientCanvas() {
return (
<div aria-hidden className="ambient-canvas">
<div className="ambient-canvas__wash" />
</div>
);
}

View File

@@ -1,11 +1,23 @@
export function Footer() {
return (
<footer className="w-full py-8 text-center text-xs text-zinc-400 dark:text-zinc-600 font-mono border-t border-zinc-200/50 dark:border-zinc-800/50 mt-auto">
<div className="max-w-4xl mx-auto px-6 flex flex-col sm:flex-row justify-between items-center gap-4">
<div className="flex gap-4">
<a href="https://x.com/thekolliakshay" className="hover:text-zinc-900 dark:hover:text-zinc-100 transition-colors">Twitter</a>
<a href="https://github.com/akkolli" className="hover:text-zinc-900 dark:hover:text-zinc-100 transition-colors">GitHub</a>
<footer className="mt-auto border-t border-line">
<div className="mx-auto flex max-w-[72rem] flex-col gap-3 px-5 py-6 sm:flex-row sm:items-center sm:justify-between sm:px-6">
<p className="text-[0.82rem] leading-6 text-muted">
Research, writing, and software.
</p>
<div className="flex flex-wrap gap-4 text-[0.82rem] text-ink">
<a href="mailto:akshaykolli@hotmail.com" className="transition-colors hover:text-accent">
Email
</a>
<a href="https://github.com/akkolli" target="_blank" rel="noopener noreferrer" className="transition-colors hover:text-accent">
GitHub
</a>
<a href="https://www.linkedin.com/in/akshay-kolli-/" target="_blank" rel="noopener noreferrer" className="transition-colors hover:text-accent">
LinkedIn
</a>
<a href="https://x.com/thekolliakshay" target="_blank" rel="noopener noreferrer" className="transition-colors hover:text-accent">
X
</a>
</div>
</div>
</footer>

View File

@@ -2,6 +2,7 @@
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { ThemeToggle } from './ThemeToggle';
export function Navbar() {
const pathname = usePathname();
@@ -9,35 +10,49 @@ export function Navbar() {
const isActive = (path: string) => pathname?.startsWith(path);
return (
<nav aria-label="Main navigation" className="fixed top-0 left-0 w-full z-50 backdrop-blur-md bg-zinc-50/80 dark:bg-zinc-950/80 border-b border-zinc-200/50 dark:border-zinc-800/50">
<div className="max-w-4xl mx-auto px-6 h-16 flex items-center justify-between">
<Link href="/" className="font-bold text-lg tracking-tight hover:opacity-70 transition-opacity">
AK
<nav
aria-label="Main navigation"
className="fixed left-0 top-0 z-50 w-full border-b border-line bg-paper-overlay"
>
<div className="mx-auto flex h-14 max-w-[72rem] items-center justify-between gap-6 px-5 sm:px-6">
<Link href="/" className="flex items-baseline gap-2.5 transition-opacity hover:opacity-75">
<span className="text-[0.96rem] font-medium tracking-[-0.03em] text-ink">
Akshay Kolli
</span>
<span className="hidden font-mono text-[0.65rem] uppercase tracking-[0.14em] text-muted-strong sm:inline">
Research
</span>
</Link>
<div className="flex items-center gap-6 text-sm font-medium text-zinc-600 dark:text-zinc-400">
<div className="flex items-center gap-4 text-[0.68rem] font-mono uppercase tracking-[0.14em] text-muted-strong sm:gap-5">
<Link
href="/"
className={`transition-colors ${pathname === '/' ? 'text-ink' : 'hover:text-ink'}`}
>
Home
</Link>
<Link
href="/blog"
className={`transition-colors ${isActive('/blog') ? 'text-zinc-900 dark:text-zinc-100 font-bold' : 'hover:text-zinc-900 dark:hover:text-zinc-100'}`}
className={`transition-colors ${isActive('/blog') ? 'text-ink' : 'hover:text-ink'}`}
>
Blog
Writing
</Link>
<Link
href="/resume"
className={`transition-colors ${isActive('/resume') ? 'text-zinc-900 dark:text-zinc-100 font-bold' : 'hover:text-zinc-900 dark:hover:text-zinc-100'}`}
className={`transition-colors ${isActive('/resume') ? 'text-ink' : 'hover:text-ink'}`}
>
Resume
</Link>
<div className="w-px h-4 bg-zinc-200 dark:bg-zinc-800 hidden sm:block"></div>
<a href="https://code.akkolli.net/lepton" target="_blank" rel="noopener noreferrer" aria-label="Code repositories" className="hover:text-zinc-900 dark:hover:text-zinc-100 transition-colors hidden sm:block">
Code
</a>
<a href="https://github.com/akkolli" target="_blank" rel="noopener noreferrer" aria-label="GitHub profile" className="hover:text-zinc-900 dark:hover:text-zinc-100 transition-colors hidden sm:block">
<a
href="https://github.com/akkolli"
target="_blank"
rel="noopener noreferrer"
aria-label="GitHub profile"
className="hidden transition-colors hover:text-ink sm:block"
>
GitHub
</a>
<a href="https://x.com/thekolliakshay" target="_blank" rel="noopener noreferrer" aria-label="Twitter profile" className="hover:text-zinc-900 dark:hover:text-zinc-100 transition-colors hidden sm:block">
Twitter
</a>
<ThemeToggle />
</div>
</div>
</nav>

View File

@@ -0,0 +1,66 @@
"use client";
type Theme = "light" | "dark";
const STORAGE_KEY = "theme-preference";
function applyTheme(theme: Theme) {
document.documentElement.dataset.theme = theme;
window.localStorage.setItem(STORAGE_KEY, theme);
}
function getCurrentTheme(): Theme {
const currentTheme = document.documentElement.dataset.theme;
if (currentTheme === "light" || currentTheme === "dark") {
return currentTheme;
}
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
}
export function ThemeToggle() {
const toggleTheme = () => {
const nextTheme = getCurrentTheme() === "dark" ? "light" : "dark";
applyTheme(nextTheme);
};
return (
<button
type="button"
onClick={toggleTheme}
title="Toggle color theme"
aria-label="Toggle color theme"
className="theme-toggle inline-flex h-8 w-8 items-center justify-center rounded-full border border-transparent text-muted-strong transition-colors hover:border-line hover:text-ink"
>
<span className="sr-only">Toggle color theme</span>
<svg
aria-hidden="true"
viewBox="0 0 24 24"
className="theme-toggle__sun h-3.5 w-3.5 fill-none stroke-current"
strokeWidth="1.7"
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx="12" cy="12" r="4" />
<path d="M12 2.5v2.2" />
<path d="M12 19.3v2.2" />
<path d="m4.9 4.9 1.6 1.6" />
<path d="m17.5 17.5 1.6 1.6" />
<path d="M2.5 12h2.2" />
<path d="M19.3 12h2.2" />
<path d="m4.9 19.1 1.6-1.6" />
<path d="m17.5 6.5 1.6-1.6" />
</svg>
<svg
aria-hidden="true"
viewBox="0 0 24 24"
className="theme-toggle__moon h-3.5 w-3.5 fill-none stroke-current"
strokeWidth="1.7"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M21 12.8A9 9 0 1 1 11.2 3a7 7 0 0 0 9.8 9.8Z" />
</svg>
</button>
);
}

View File

@@ -3,7 +3,7 @@ export function Citation({ id, index }: { id: string; index: number }) {
<sup id={`cite-ref-${id}`} className="ml-0.5">
<a
href={`#cite-note-${id}`}
className="text-zinc-500 hover:text-zinc-900 dark:hover:text-zinc-100 transition-colors font-mono text-[10px] no-underline"
className="font-mono text-[10px] text-muted-strong transition-colors no-underline hover:text-ink"
>
[{index}]
</a>
@@ -15,13 +15,13 @@ export function Bibliography({ items, children }: { items?: { id: string; conten
if (!items && !children) return null;
return (
<div className="mt-12 pt-8 border-t border-zinc-200 dark:border-zinc-800">
<h3 className="text-sm font-bold uppercase tracking-wider text-zinc-900 dark:text-zinc-100 mb-4">References</h3>
<ol className="list-decimal pl-4 space-y-2 text-sm text-zinc-600 dark:text-zinc-400">
{Array.isArray(items) && items.map((item, i) => (
<div className="mt-12 border-t border-line pt-8">
<h3 className="eyebrow mb-4">References</h3>
<ol className="list-decimal space-y-2 pl-4 text-[0.94rem] leading-7 text-muted">
{Array.isArray(items) && items.map((item) => (
<li key={item.id} id={`cite-note-${item.id}`}>
{item.content}
<a href={`#cite-ref-${item.id}`} className="ml-2 hover:text-zinc-900 dark:hover:text-zinc-100">
<a href={`#cite-ref-${item.id}`} className="ml-2 transition-colors hover:text-ink">
</a>
</li>

View File

@@ -1,7 +1,3 @@
'use client';
import { useState } from 'react';
type Heading = {
id: string;
text: string;
@@ -9,42 +5,28 @@ type Heading = {
};
export function MobileTableOfContents({ headings }: { headings: Heading[] }) {
const [isOpen, setIsOpen] = useState(false);
if (headings.length === 0) return null;
return (
<div className="block xl:hidden mb-8 border border-zinc-200 dark:border-zinc-800 rounded-lg overflow-hidden">
<button
onClick={() => setIsOpen(!isOpen)}
aria-expanded={isOpen}
aria-controls="mobile-toc"
className="w-full flex items-center justify-between p-4 bg-zinc-50 dark:bg-zinc-900 text-sm font-medium text-zinc-900 dark:text-zinc-100"
>
<span>Table of Contents</span>
<span className={`transform transition-transform ${isOpen ? 'rotate-180' : ''}`}>
</span>
</button>
{isOpen && (
<ul id="mobile-toc" className="p-4 bg-white dark:bg-black border-t border-zinc-200 dark:border-zinc-800 space-y-3">
{headings.map((heading) => (
<li
key={heading.id}
style={{ paddingLeft: `${(heading.level - 2) * 12}px` }}
<details className="mb-8 border-y border-line py-4">
<summary className="eyebrow cursor-pointer list-none">
Contents
</summary>
<ul className="mt-4 space-y-2">
{headings.map((heading) => (
<li
key={heading.id}
style={{ paddingLeft: `${(heading.level - 2) * 12}px` }}
>
<a
href={`#${heading.id}`}
className="block text-[0.94rem] leading-7 text-muted transition-colors hover:text-ink"
>
<a
href={`#${heading.id}`}
onClick={() => setIsOpen(false)}
className="block text-sm text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-zinc-100 truncate"
>
{heading.text}
</a>
</li>
))}
</ul>
)}
</div>
{heading.text}
</a>
</li>
))}
</ul>
</details>
);
}

View File

@@ -1,12 +1,8 @@
export function SideNote({ children, title }: { children: React.ReactNode; title?: string }) {
return (
<aside className="my-6 p-4 bg-zinc-50 dark:bg-zinc-900/50 border-l-2 border-zinc-300 dark:border-zinc-700 text-sm text-zinc-600 dark:text-zinc-400 font-light italic rounded-r-lg lg:absolute lg:right-0 lg:w-64 lg:mr-[-20rem] lg:my-0 lg:p-0 lg:bg-transparent lg:dark:bg-transparent lg:border-0 lg:not-italic lg:rounded-none">
{/* Mobile/Tablet view: distinct block */}
{/* Desktop view: Absolute positioning to the right margin */}
<span className="lg:block lg:text-xs lg:leading-relaxed">
{title && <strong className="block mb-1 text-zinc-900 dark:text-zinc-200 not-italic">{title}</strong>}
{children}
</span>
</aside>
<span role="note" className="side-note">
{title ? <strong>{title}</strong> : null}
{children}
</span>
);
}

View File

@@ -54,19 +54,19 @@ export function TableOfContents({ headings }: { headings: Heading[] }) {
if (headings.length === 0) return null;
return (
<nav aria-label="Table of contents" className="text-sm animate-fade-in text-left">
<h4 className="font-bold text-zinc-900 dark:text-zinc-100 mb-4 uppercase tracking-wider text-xs">On this page</h4>
<ul className="space-y-3">
<nav aria-label="Table of contents" className="text-left">
<h4 className="eyebrow mb-4">Contents</h4>
<ul className="space-y-2">
{Array.isArray(headings) && headings.map((heading) => (
<li
key={heading.id}
style={{ paddingRight: `${(heading.level - 2) * 12}px` }}
style={{ paddingLeft: `${(heading.level - 2) * 10}px` }}
>
<a
href={`#${heading.id}`}
className={`block transition-all duration-200 border-l-2 pl-4 ${activeId === heading.id
? 'border-zinc-900 dark:border-zinc-100 text-zinc-900 dark:text-zinc-50 font-bold'
: 'border-transparent text-zinc-500 dark:text-zinc-500 hover:text-zinc-700 dark:hover:text-zinc-300'
className={`block text-[0.82rem] leading-6 transition-colors ${activeId === heading.id
? 'text-ink'
: 'text-muted hover:text-ink'
}`}
>
{heading.text}