|
|
@@ -111,21 +111,92 @@
|
|
|
.header-small { pointer-events: none; }
|
|
|
.header-small a, .header-small .hamburger { pointer-events: auto; }
|
|
|
#worknav .offcanvas-body { padding: 1.1rem 1rem; flex: 0 0 auto; }
|
|
|
- .work-nav-links { display: flex; justify-content: center; flex-wrap: wrap; gap: 2.2rem; margin: 0; }
|
|
|
+ .work-nav-links { position: relative; display: flex; justify-content: center; flex-wrap: wrap; gap: 2.2rem; margin: 0; }
|
|
|
.work-nav-links a { color: #fff; text-decoration: none; font-family: 'Playfair Var', 'Playfair Display', serif; font-weight: 700; font-size: 1.35rem; }
|
|
|
.work-nav-links a:hover { color: #25c2a0; }
|
|
|
+ /* floating "magic line": one shared underline that slides between the top-nav items (positioned by the script below) */
|
|
|
+ .work-nav-underline {
|
|
|
+ position: absolute; top: 0; left: 0; width: 0; height: 2px;
|
|
|
+ background: #25c2a0; border-radius: 1px; opacity: 0; pointer-events: none;
|
|
|
+ transition: left .4s cubic-bezier(0.785,0.135,0.15,0.86), width .4s cubic-bezier(0.785,0.135,0.15,0.86), top .4s cubic-bezier(0.785,0.135,0.15,0.86), opacity .3s ease;
|
|
|
+ }
|
|
|
+ /* sub nav (Who/What/When/Why/How): match the top-nav font + size, with a different
|
|
|
+ underline effect — a left-to-right slide-in per item (like the main site's footer) */
|
|
|
+ .header-small .header-small-menu a {
|
|
|
+ font-family: 'Playfair Var', 'Playfair Display', serif;
|
|
|
+ font-weight: 700;
|
|
|
+ font-size: 1.35rem;
|
|
|
+ position: relative;
|
|
|
+ }
|
|
|
+ .header-small .header-small-menu a::after {
|
|
|
+ content: ''; position: absolute; left: 12px; bottom: 6px; height: 2px; width: 0;
|
|
|
+ background: #25c2a0; transition: width .35s cubic-bezier(0.785,0.135,0.15,0.86);
|
|
|
+ }
|
|
|
+ .header-small .header-small-menu a:hover { opacity: 1; }
|
|
|
+ .header-small .header-small-menu a:hover::after { width: calc(100% - 41px); }
|
|
|
+ @media (prefers-reduced-motion: reduce) {
|
|
|
+ .work-nav-underline { transition: opacity .3s ease; }
|
|
|
+ .header-small .header-small-menu a::after { transition: none; }
|
|
|
+ }
|
|
|
</style>
|
|
|
<div class="offcanvas offcanvas-top work-nav" tabindex="-1" id="worknav" data-bs-backdrop="false" data-bs-scroll="true" aria-labelledby="worknav-label">
|
|
|
<div class="offcanvas-body">
|
|
|
<nav class="work-nav-links" aria-label="Main site navigation">
|
|
|
<a href="/about">About</a>
|
|
|
<a href="/desk">Desk</a>
|
|
|
- <a href="/now">Now</a>
|
|
|
<a href="/studio">Studio</a>
|
|
|
<a href="/work">Work</a>
|
|
|
+ <span class="work-nav-underline" aria-hidden="true"></span>
|
|
|
</nav>
|
|
|
</div>
|
|
|
</div>
|
|
|
+<script>
|
|
|
+/* Floating "magic line" underline for the top nav (mirrors the main site): one shared
|
|
|
+ underline slides between items on hover and rests under the current-page item.
|
|
|
+ Positions read from offset* (layout geometry), unaffected by the offcanvas transform. */
|
|
|
+(function () {
|
|
|
+ function init() {
|
|
|
+ var nav = document.querySelector('.work-nav-links');
|
|
|
+ if (!nav) return;
|
|
|
+ var line = nav.querySelector('.work-nav-underline');
|
|
|
+ if (!line) return;
|
|
|
+ var links = Array.prototype.slice.call(nav.querySelectorAll('a'));
|
|
|
+ if (!links.length) return;
|
|
|
+ function rel(el) {
|
|
|
+ var left = 0, top = 0, node = el;
|
|
|
+ while (node && node !== nav) { left += node.offsetLeft; top += node.offsetTop; node = node.offsetParent; }
|
|
|
+ return { left: left, top: top, width: el.offsetWidth, height: el.offsetHeight };
|
|
|
+ }
|
|
|
+ function place(el, show) {
|
|
|
+ var r = rel(el);
|
|
|
+ line.style.left = r.left + 'px';
|
|
|
+ line.style.width = r.width + 'px';
|
|
|
+ line.style.top = (r.top + r.height) + 'px';
|
|
|
+ line.style.opacity = show ? '1' : '0';
|
|
|
+ }
|
|
|
+ function activeLink() {
|
|
|
+ var here = location.pathname.replace(/\/+$/, '') || '/';
|
|
|
+ var seg = '/' + (here.split('/')[1] || '');
|
|
|
+ var exact = null, section = null;
|
|
|
+ links.forEach(function (a) {
|
|
|
+ var p = a.pathname.replace(/\/+$/, '') || '/';
|
|
|
+ if (p === here) exact = a;
|
|
|
+ if (p === seg) section = a;
|
|
|
+ });
|
|
|
+ return exact || section;
|
|
|
+ }
|
|
|
+ var active = activeLink();
|
|
|
+ function rest() { if (active) place(active, true); else line.style.opacity = '0'; }
|
|
|
+ links.forEach(function (a) { a.addEventListener('mouseenter', function () { place(a, true); }); });
|
|
|
+ nav.addEventListener('mouseleave', rest);
|
|
|
+ window.addEventListener('resize', rest);
|
|
|
+ if (document.fonts && document.fonts.ready) document.fonts.ready.then(rest);
|
|
|
+ rest();
|
|
|
+ }
|
|
|
+ if (document.readyState !== 'loading') init();
|
|
|
+ else document.addEventListener('DOMContentLoaded', init);
|
|
|
+})();
|
|
|
+</script>
|
|
|
<!-- ** TOP NAV ** -->
|
|
|
|
|
|
|