feat: refine mobile visual presentation

This commit is contained in:
Fi3w0 2026-08-11 16:33:26 +02:00
parent 66b9ea6054
commit e3970d3480
3 changed files with 141 additions and 6 deletions

View file

@ -105,6 +105,10 @@ code {
font-weight: 600;
}
.nav-toggle {
display: none;
}
.site-nav > a:not(.nav-pill)::after {
bottom: -0.25rem;
height: 3px;
@ -1578,6 +1582,79 @@ code {
padding-left: 1rem;
}
.nav-toggle {
display: inline-flex;
align-items: center;
gap: 0.8rem;
padding: 0.7rem 0;
border: 0;
background: transparent;
color: var(--text);
font: 600 0.75rem var(--mono);
letter-spacing: 0.08em;
text-transform: uppercase;
}
.nav-toggle span:last-child {
color: var(--coral);
font-size: 1rem;
transition: transform 180ms ease;
}
.site-header.is-nav-open .nav-toggle span:last-child {
transform: rotate(45deg);
}
.site-nav {
position: absolute;
top: 100%;
right: 0;
left: 0;
display: grid;
padding: 0 1rem 1rem;
transform: translateY(-0.5rem);
border-bottom: 2px solid var(--line);
background: var(--bg);
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 0;
opacity: 0;
pointer-events: none;
transition: opacity 160ms ease, transform 160ms ease, visibility 160ms;
visibility: hidden;
}
.site-header.is-nav-open .site-nav {
transform: translateY(0);
opacity: 1;
pointer-events: auto;
visibility: visible;
}
.site-nav > a:not(.nav-pill) {
display: flex;
min-height: 3.25rem;
align-items: center;
border-bottom: 1px solid var(--line);
color: var(--text);
}
.site-nav > a:nth-of-type(even):not(.nav-pill) {
padding-left: 1rem;
border-left: 1px solid var(--line);
}
.site-nav .nav-pill {
min-height: 3.25rem;
padding: 0;
border: 0;
border-bottom: 1px solid var(--line);
grid-column: 1 / -1;
}
.nav-gooey {
display: none;
}
.nav-pill {
padding-left: 0.8rem;
}
@ -1591,6 +1668,14 @@ code {
font-size: clamp(3.7rem, 17vw, 6rem);
}
.hero-liquid-pre {
color: rgba(143, 212, 208, 0.32);
}
.hero-copy {
text-shadow: 0 1px 1px rgba(16, 26, 33, 0.55);
}
.hero-signals {
grid-template-columns: 1fr;
}
@ -1635,6 +1720,12 @@ code {
font-size: clamp(2.8rem, 13vw, 4.8rem);
}
.stack-intro {
max-width: 36rem;
margin-top: 1.5rem;
grid-column: 1;
}
.about-layout {
grid-template-columns: 1fr;
}

View file

@ -19,8 +19,8 @@
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Archivo+Black&amp;family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,600;1,400&amp;display=swap" rel="stylesheet">
<link rel="stylesheet" href="css/style.css?v=4">
<link rel="stylesheet" href="css/editorial.css?v=4">
<link rel="stylesheet" href="css/style.css?v=5">
<link rel="stylesheet" href="css/editorial.css?v=5">
<link rel="icon" href="/favicon.ico" sizes="any">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
@ -39,7 +39,11 @@
<span>fi3w0</span>
</a>
<nav class="site-nav" aria-label="Primary navigation">
<button class="nav-toggle" type="button" aria-expanded="false" aria-controls="primary-navigation">
<span>Menu</span><span aria-hidden="true">+</span>
</button>
<nav class="site-nav" id="primary-navigation" aria-label="Primary navigation">
<span class="nav-gooey" aria-hidden="true">
<span class="nav-gooey-blob nav-gooey-blob--trail"></span>
<span class="nav-gooey-blob nav-gooey-blob--lead"></span>
@ -414,7 +418,7 @@
<p>&copy; <span id="year">2026</span> Alex / Fi3w0</p>
</footer>
<script src="js/app.js?v=4" defer></script>
<script src="js/app.js?v=5" defer></script>
</body>
</html>

View file

@ -118,7 +118,7 @@ if (scrambleHeadings.length && !reducedMotion && "IntersectionObserver" in windo
heading.dataset.finalText = heading.textContent ?? "";
});
const decryptHeading = (heading, duration = 600, steps = 14) => {
const decryptHeading = (heading, duration = 420, steps = 10) => {
const finalText = heading.dataset.finalText ?? "";
const totalChars = finalText.length;
let frame = 0;
@ -149,12 +149,52 @@ if (scrambleHeadings.length && !reducedMotion && "IntersectionObserver" in windo
observer.unobserve(entry.target);
});
},
{ rootMargin: "0px 0px -10%", threshold: 0.4 },
{ rootMargin: "0px 0px -4%", threshold: 0.2 },
);
scrambleHeadings.forEach((heading) => scrambleObserver.observe(heading));
}
const siteHeader = document.querySelector(".site-header");
const navToggle = document.querySelector(".nav-toggle");
const primaryNav = document.querySelector("#primary-navigation");
if (siteHeader && navToggle && primaryNav) {
const mobileNavQuery = window.matchMedia("(max-width: 52rem)");
const setNavOpen = (open) => {
siteHeader.classList.toggle("is-nav-open", open);
navToggle.setAttribute("aria-expanded", String(open));
primaryNav.toggleAttribute("inert", mobileNavQuery.matches && !open);
};
const syncNavMode = () => {
siteHeader.classList.remove("is-nav-open");
navToggle.setAttribute("aria-expanded", "false");
primaryNav.toggleAttribute("inert", mobileNavQuery.matches);
};
navToggle.addEventListener("click", () => {
setNavOpen(!siteHeader.classList.contains("is-nav-open"));
});
primaryNav.querySelectorAll("a").forEach((link) => {
link.addEventListener("click", () => {
if (mobileNavQuery.matches) setNavOpen(false);
});
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && siteHeader.classList.contains("is-nav-open")) {
setNavOpen(false);
navToggle.focus();
}
});
mobileNavQuery.addEventListener("change", syncNavMode);
syncNavMode();
}
const gooeyNav = document.querySelector(".nav-gooey");
const gooeyLinks = document.querySelectorAll(".site-nav > a:not(.nav-pill)");