7fbe9a3e43
CI / ci (push) Successful in 28s
Harden nginx: add CSP, HSTS, Referrer-Policy and Permissions-Policy; include image/svg+xml in gzip types; set X-Content-Type-Options on static assets; change try_files to return =404. Add Nav component and wire into BaseLayout; add About and Projects pages with projects.json, an initial blog post, and small layout/padding adjustments (removed redundant back links).
90 lines
2.1 KiB
Plaintext
90 lines
2.1 KiB
Plaintext
---
|
|
const currentPath = Astro.url.pathname;
|
|
|
|
const links = [
|
|
{ href: "/", label: "home" },
|
|
{ href: "/about", label: "about" },
|
|
{ href: "/projects", label: "projects" },
|
|
{ href: "/blog", label: "blog" },
|
|
];
|
|
|
|
function isActive(href: string, current: string): boolean {
|
|
if (href === "/") return current === "/";
|
|
return current.startsWith(href);
|
|
}
|
|
---
|
|
|
|
<nav class="nav" aria-label="Main navigation">
|
|
<div class="nav-inner">
|
|
{links.map((link, i) => (
|
|
<>
|
|
{i > 0 && <span class="nav-sep" aria-hidden="true">·</span>}
|
|
<a
|
|
href={link.href}
|
|
class:list={["nav-link", { active: isActive(link.href, currentPath) }]}
|
|
aria-current={isActive(link.href, currentPath) ? "page" : undefined}
|
|
>
|
|
~/{link.label}
|
|
</a>
|
|
</>
|
|
))}
|
|
</div>
|
|
</nav>
|
|
|
|
<style>
|
|
.nav {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
z-index: 100;
|
|
padding: var(--space-sm) var(--space-md);
|
|
background: rgba(30, 30, 46, 0.85);
|
|
backdrop-filter: blur(8px);
|
|
border-bottom: 1px solid var(--color-surface);
|
|
}
|
|
|
|
.nav-inner {
|
|
max-width: 700px;
|
|
margin: 0 auto;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: var(--space-xs);
|
|
font-size: 0.85rem;
|
|
}
|
|
|
|
.nav-sep {
|
|
color: var(--color-surface);
|
|
user-select: none;
|
|
}
|
|
|
|
.nav-link {
|
|
color: var(--color-text-dim);
|
|
text-decoration: none;
|
|
padding: 2px 4px;
|
|
border-radius: 3px;
|
|
transition: color 0.2s ease;
|
|
}
|
|
|
|
.nav-link:hover {
|
|
color: var(--color-accent-bright);
|
|
}
|
|
|
|
.nav-link.active {
|
|
color: var(--color-accent);
|
|
text-decoration: underline;
|
|
text-underline-offset: 3px;
|
|
}
|
|
|
|
@media (max-width: 600px) {
|
|
.nav {
|
|
padding: var(--space-xs) var(--space-sm);
|
|
}
|
|
|
|
.nav-inner {
|
|
font-size: 0.8rem;
|
|
}
|
|
}
|
|
</style>
|