Browse Source

nav: magic-line underline, sub-nav Playfair + underline, drop Now item

- Top nav: floating magic-line underline that slides between items (mirrors the
  main site), resting under the current-page item.
- Sub nav (Who/What/When/Why/How): Playfair Var at 1.35rem to match the top nav,
  with a left-to-right slide-in underline on hover.
- Dropped the redundant Now item now that Now -> Desk on the main site.
windhamdavid 2 weeks ago
parent
commit
db727b7bc1
1 changed files with 73 additions and 2 deletions
  1. 73 2
      index.html

+ 73 - 2
index.html

@@ -111,21 +111,92 @@
   .header-small { pointer-events: none; }
   .header-small { pointer-events: none; }
   .header-small a, .header-small .hamburger { pointer-events: auto; }
   .header-small a, .header-small .hamburger { pointer-events: auto; }
   #worknav .offcanvas-body { padding: 1.1rem 1rem; flex: 0 0 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 { 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; }
   .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>
 </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 offcanvas-top work-nav" tabindex="-1" id="worknav" data-bs-backdrop="false" data-bs-scroll="true" aria-labelledby="worknav-label">
   <div class="offcanvas-body">
   <div class="offcanvas-body">
     <nav class="work-nav-links" aria-label="Main site navigation">
     <nav class="work-nav-links" aria-label="Main site navigation">
       <a href="/about">About</a>
       <a href="/about">About</a>
       <a href="/desk">Desk</a>
       <a href="/desk">Desk</a>
-      <a href="/now">Now</a>
       <a href="/studio">Studio</a>
       <a href="/studio">Studio</a>
       <a href="/work">Work</a>
       <a href="/work">Work</a>
+      <span class="work-nav-underline" aria-hidden="true"></span>
     </nav>
     </nav>
   </div>
   </div>
 </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 ** -->
 <!-- ** TOP NAV ** -->