Homepage UI Update

This commit is contained in:
2026-01-12 09:47:34 +00:00
parent d97513bc67
commit 93e6ff23ee
7 changed files with 151 additions and 7645 deletions

3
.gitignore vendored
View File

@@ -26,3 +26,6 @@ pnpm-debug.log*
# pagefind # pagefind
public/pagefind public/pagefind
pnpm-lock.yaml
bun.lock

1429
bun.lock

File diff suppressed because it is too large Load Diff

View File

@@ -14,33 +14,33 @@
}, },
"dependencies": { "dependencies": {
"@astrojs/rss": "^4.0.14", "@astrojs/rss": "^4.0.14",
"@astrojs/sitemap": "^3.6.0", "@astrojs/sitemap": "^3.6.1",
"@resvg/resvg-js": "^2.6.2", "@resvg/resvg-js": "^2.6.2",
"@tailwindcss/vite": "^4.1.17", "@tailwindcss/vite": "^4.1.18",
"astro": "^5.16.3", "astro": "^5.16.8",
"dayjs": "^1.11.19", "dayjs": "^1.11.19",
"lodash.kebabcase": "^4.1.1", "lodash.kebabcase": "^4.1.1",
"remark-collapse": "^0.1.2", "remark-collapse": "^0.1.2",
"remark-toc": "^9.0.0", "remark-toc": "^9.0.0",
"satori": "^0.15.2", "satori": "^0.15.2",
"sharp": "^0.34.5", "sharp": "^0.34.5",
"tailwindcss": "^4.1.17" "tailwindcss": "^4.1.18"
}, },
"devDependencies": { "devDependencies": {
"@astrojs/check": "^0.9.6", "@astrojs/check": "^0.9.6",
"@pagefind/default-ui": "^1.4.0", "@pagefind/default-ui": "^1.4.0",
"@shikijs/transformers": "^3.17.0", "@shikijs/transformers": "^3.21.0",
"@tailwindcss/typography": "^0.5.19", "@tailwindcss/typography": "^0.5.19",
"@types/lodash.kebabcase": "^4.1.9", "@types/lodash.kebabcase": "^4.1.9",
"@typescript-eslint/parser": "^8.48.0", "@typescript-eslint/parser": "^8.52.0",
"eslint": "^9.39.1", "eslint": "^9.39.2",
"eslint-plugin-astro": "^1.5.0", "eslint-plugin-astro": "^1.5.0",
"globals": "^16.5.0", "globals": "^16.5.0",
"pagefind": "^1.4.0", "pagefind": "^1.4.0",
"prettier": "^3.7.3", "prettier": "^3.7.4",
"prettier-plugin-astro": "^0.14.1", "prettier-plugin-astro": "^0.14.1",
"prettier-plugin-tailwindcss": "^0.6.14", "prettier-plugin-tailwindcss": "^0.6.14",
"typescript": "^5.9.3", "typescript": "^5.9.3",
"typescript-eslint": "^8.48.0" "typescript-eslint": "^8.52.0"
} }
} }

6065
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -17,9 +17,7 @@ const { noMarginTop = false } = Astro.props;
> >
<Socials centered /> <Socials centered />
<div class="my-2 flex flex-col items-center whitespace-nowrap sm:flex-row"> <div class="my-2 flex flex-col items-center whitespace-nowrap sm:flex-row">
<span><a href={SITE.website} rel="noopener noreferrer" target="_blank" <span>{SITE.author}</span>
>{SITE.author}</a
></span>
</div> </div>
</div> </div>
</footer> </footer>

View File

@@ -13,156 +13,155 @@ const { pathname } = Astro.url;
// Remove trailing slash from current pathname if exists // Remove trailing slash from current pathname if exists
const currentPath = const currentPath =
pathname.endsWith("/") && pathname !== "/" ? pathname.slice(0, -1) : pathname; pathname.endsWith("/") && pathname !== "/" ? pathname.slice(0, -1) : pathname;
const isActive = (path: string) => { const isActive = (path: string) => {
const currentPathArray = currentPath.split("/").filter(p => p.trim()); const currentPathArray = currentPath.split("/").filter(p => p.trim());
const pathArray = path.split("/").filter(p => p.trim()); const pathArray = path.split("/").filter(p => p.trim());
return currentPath === path || currentPathArray[0] === pathArray[0]; return currentPath === path || currentPathArray[0] === pathArray[0];
}; };
--- ---
<header> <header>
<a <a
id="skip-to-content" id="skip-to-content"
href="#main-content" href="#main-content"
class="absolute start-16 -top-full z-50 bg-background px-3 py-2 text-accent backdrop-blur-lg transition-all focus:top-4" class="absolute start-16 -top-full z-50 bg-background px-3 py-2 text-accent backdrop-blur-lg transition-all focus:top-4"
> >
Skip to content Skip to content
</a> </a>
<div <div
id="nav-container" id="nav-container"
class="mx-auto flex max-w-app flex-col items-center justify-between sm:flex-row" class="mx-auto flex max-w-app flex-col items-center justify-between sm:flex-row"
> >
<div <div
id="top-nav-wrap" id="top-nav-wrap"
class="relative flex w-full items-baseline justify-between bg-background p-4 sm:items-center sm:py-6" class="relative flex w-full items-baseline justify-center bg-background p-4 sm:items-center sm:py-6"
> >
<a <nav
href="/" id="nav-menu"
class="absolute py-1 text-xl leading-8 font-semibold whitespace-nowrap sm:static sm:my-auto sm:text-2xl sm:leading-none" class="flex w-full flex-col items-center sm:flex-row sm:justify-center sm:space-x-4 sm:py-0"
> >
{SITE.title} <button
</a> id="menu-btn"
<nav class="focus-outline self-end p-2 sm:hidden"
id="nav-menu" aria-label="Open Menu"
class="flex w-full flex-col items-center sm:ms-2 sm:flex-row sm:justify-end sm:space-x-4 sm:py-0" aria-expanded="false"
> aria-controls="menu-items"
<button >
id="menu-btn" <IconX id="close-icon" class="hidden" />
class="focus-outline self-end p-2 sm:hidden" <IconMenuDeep id="menu-icon" />
aria-label="Open Menu" </button>
aria-expanded="false" <ul
aria-controls="menu-items" id="menu-items"
> class:list={[
<IconX id="close-icon" class="hidden" /> "mt-4 grid w-44 grid-cols-2 place-content-center gap-2",
<IconMenuDeep id="menu-icon" /> "[&>li>a]:block [&>li>a]:px-4 [&>li>a]:py-3 [&>li>a]:text-center [&>li>a]:font-medium [&>li>a]:hover:text-accent sm:[&>li>a]:px-2 sm:[&>li>a]:py-1",
</button> "hidden",
<ul "sm:mt-0 sm:flex sm:w-auto sm:gap-x-5 sm:gap-y-0",
id="menu-items" ]}
class:list={[ >
"mt-4 grid w-44 grid-cols-2 place-content-center gap-2", <li class="col-span-2">
"[&>li>a]:block [&>li>a]:px-4 [&>li>a]:py-3 [&>li>a]:text-center [&>li>a]:font-medium [&>li>a]:hover:text-accent sm:[&>li>a]:px-2 sm:[&>li>a]:py-1", <a href="/" class:list={{ "active-nav": isActive("/") }}>
"hidden", Home
"sm:mt-0 sm:flex sm:w-auto sm:gap-x-5 sm:gap-y-0", </a>
]} </li>
> <li class="col-span-2">
<li class="col-span-2"> <a href="/posts" class:list={{ "active-nav": isActive("/posts") }}>
<a href="/posts" class:list={{ "active-nav": isActive("/posts") }}> Posts
Posts </a>
</a> </li>
</li> <li class="col-span-2">
<li class="col-span-2"> <a href="/tags" class:list={{ "active-nav": isActive("/tags") }}>
<a href="/tags" class:list={{ "active-nav": isActive("/tags") }}> Tags
Tags </a>
</a> </li>
</li> <li class="col-span-2">
<li class="col-span-2"> <a href="/about" class:list={{ "active-nav": isActive("/about") }}>
<a href="/about" class:list={{ "active-nav": isActive("/about") }}> About
About </a>
</a> </li>
</li> {
{ SITE.showArchives && (
SITE.showArchives && ( <li class="col-span-2">
<li class="col-span-2"> <LinkButton
<LinkButton href="/archives"
href="/archives" class:list={[
class:list={[ "focus-outline flex justify-center p-3 sm:p-1",
"focus-outline flex justify-center p-3 sm:p-1", {
{ "active-nav [&>svg]:stroke-accent": isActive("/archives"),
"active-nav [&>svg]:stroke-accent": isActive("/archives"), },
}, ]}
]} ariaLabel="archives"
ariaLabel="archives" title="Archives"
title="Archives" >
> <IconArchive class="hidden sm:inline-block" />
<IconArchive class="hidden sm:inline-block" /> <span class="sm:sr-only">Archives</span>
<span class="sm:sr-only">Archives</span> </LinkButton>
</LinkButton> </li>
</li> )
) }
} <li class="col-span-1 flex items-center justify-center">
<li class="col-span-1 flex items-center justify-center"> <LinkButton
<LinkButton href="/search"
href="/search" class:list={[
class:list={[ "focus-outline flex p-3 sm:p-1",
"focus-outline flex p-3 sm:p-1", { "[&>svg]:stroke-accent": isActive("/search") },
{ "[&>svg]:stroke-accent": isActive("/search") }, ]}
]} ariaLabel="search"
ariaLabel="search" title="Search"
title="Search" >
> <IconSearch />
<IconSearch /> <span class="sr-only">Search</span>
<span class="sr-only">Search</span> </LinkButton>
</LinkButton> </li>
</li> {
{ SITE.lightAndDarkMode && (
SITE.lightAndDarkMode && ( <li class="col-span-1 flex items-center justify-center">
<li class="col-span-1 flex items-center justify-center"> <button
<button id="theme-btn"
id="theme-btn" class="focus-outline relative size-12 p-4 sm:size-8 hover:[&>svg]:stroke-accent"
class="focus-outline relative size-12 p-4 sm:size-8 hover:[&>svg]:stroke-accent" title="Toggles light & dark"
title="Toggles light & dark" aria-label="auto"
aria-label="auto" aria-live="polite"
aria-live="polite" >
> <IconMoon class="absolute top-[50%] left-[50%] -translate-[50%] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" />
<IconMoon class="absolute top-[50%] left-[50%] -translate-[50%] scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" /> <IconSunHigh class="absolute top-[50%] left-[50%] -translate-[50%] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" />
<IconSunHigh class="absolute top-[50%] left-[50%] -translate-[50%] scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" /> </button>
</button> </li>
</li> )
) }
} </ul>
</ul> </nav>
</nav> </div>
</div> </div>
</div> <Hr />
<Hr />
</header> </header>
<script> <script>
function toggleNav() { function toggleNav() {
const menuBtn = document.querySelector("#menu-btn"); const menuBtn = document.querySelector("#menu-btn");
const menuItems = document.querySelector("#menu-items"); const menuItems = document.querySelector("#menu-items");
const menuIcon = document.querySelector("#menu-icon"); const menuIcon = document.querySelector("#menu-icon");
const closeIcon = document.querySelector("#close-icon"); const closeIcon = document.querySelector("#close-icon");
if (!menuBtn || !menuItems || !menuIcon || !closeIcon) return; if (!menuBtn || !menuItems || !menuIcon || !closeIcon) return;
menuBtn.addEventListener("click", () => { menuBtn.addEventListener("click", () => {
const openMenu = menuBtn.getAttribute("aria-expanded") === "true"; const openMenu = menuBtn.getAttribute("aria-expanded") === "true";
menuBtn.setAttribute("aria-expanded", openMenu ? "false" : "true"); menuBtn.setAttribute("aria-expanded", openMenu ? "false" : "true");
menuBtn.setAttribute("aria-label", openMenu ? "Open Menu" : "Close Menu"); menuBtn.setAttribute("aria-label", openMenu ? "Open Menu" : "Close Menu");
menuItems.classList.toggle("hidden"); menuItems.classList.toggle("hidden");
menuIcon.classList.toggle("hidden"); menuIcon.classList.toggle("hidden");
closeIcon.classList.toggle("hidden"); closeIcon.classList.toggle("hidden");
}); });
} }
toggleNav(); toggleNav();
// Runs on view transitions navigation // Runs on view transitions navigation
document.addEventListener("astro:after-swap", toggleNav); document.addEventListener("astro:after-swap", toggleNav);
</script> </script>

View File

@@ -23,8 +23,8 @@ const recentPosts = sortedPosts.filter(({ data }) => !data.featured);
<Layout> <Layout>
<Header /> <Header />
<main id="main-content" data-layout="index"> <main id="main-content" data-layout="index">
<section id="hero" class="pt-8 pb-6"> <section id="hero" class="pt-2 pb-4">
<h1 class="my-4 inline-block text-4xl font-bold sm:my-8 sm:text-5xl"> <h1 class="my-2 inline-block text-4xl font-bold sm:my-4 sm:text-5xl">
{SITE.title} {SITE.title}
</h1> </h1>
<a <a