@@ -283,6 +283,140 @@ body::before {
283283 right : -16px ;
284284 letter-spacing : 0.04em ;
285285}
286+
287+ /*
288+ * Product dropdown — CSS-only, no JS. The submenu is hidden by default and
289+ * revealed on `:hover` of the parent `li.has-dropdown`, or on `:focus-within`
290+ * for keyboard navigation. This keeps the static export self-contained.
291+ */
292+ .nav-links li .has-dropdown {
293+ position : relative;
294+ }
295+ .nav-links .dropdown-caret {
296+ display : inline-block;
297+ margin-left : 4px ;
298+ font-size : 10px ;
299+ color : var (--ink-faint );
300+ transition : transform 0.18s ease;
301+ }
302+ .nav-links li .has-dropdown : hover .dropdown-caret ,
303+ .nav-links li .has-dropdown : focus-within .dropdown-caret {
304+ transform : translateY (1px );
305+ color : var (--coral );
306+ }
307+ .nav-dropdown {
308+ position : absolute;
309+ top : 100% ;
310+ left : -16px ;
311+ margin : 0 ;
312+ padding : 10px ;
313+ list-style : none;
314+ min-width : 320px ;
315+ background : var (--paper );
316+ border : 1px solid rgba (26 , 26 , 26 , 0.12 );
317+ border-radius : 8px ;
318+ box-shadow : 0 12px 36px rgba (26 , 26 , 26 , 0.08 );
319+ opacity : 0 ;
320+ visibility : hidden;
321+ transform : translateY (-4px );
322+ transition : opacity 0.18s ease, transform 0.18s ease, visibility 0.18s ;
323+ z-index : 50 ;
324+ }
325+ .nav-links li .has-dropdown : hover .nav-dropdown ,
326+ .nav-links li .has-dropdown : focus-within .nav-dropdown {
327+ opacity : 1 ;
328+ visibility : visible;
329+ transform : translateY (0 );
330+ }
331+ /* invisible bridge so cursor can travel from trigger to menu without
332+ * crossing a gap that closes the menu mid-traverse */
333+ .nav-dropdown ::before {
334+ content : '' ;
335+ position : absolute;
336+ top : -10px ;
337+ left : 0 ;
338+ right : 0 ;
339+ height : 10px ;
340+ }
341+ .nav-dropdown a {
342+ display : block;
343+ padding : 10px 12px ;
344+ border-radius : 6px ;
345+ color : var (--ink );
346+ text-decoration : none;
347+ transition : background 0.12s ease;
348+ }
349+ .nav-dropdown a : hover {
350+ background : rgba (255 , 122 , 89 , 0.08 );
351+ color : var (--ink );
352+ }
353+ .nav-dropdown a .is-active {
354+ background : rgba (26 , 26 , 26 , 0.04 );
355+ }
356+ .nav-dropdown .dropdown-name {
357+ display : block;
358+ font-family : var (--sans );
359+ font-size : 14px ;
360+ font-weight : 600 ;
361+ margin-bottom : 2px ;
362+ }
363+ .nav-dropdown .dropdown-blurb {
364+ display : block;
365+ font-size : 12px ;
366+ color : var (--ink-faint );
367+ line-height : 1.4 ;
368+ }
369+
370+ /*
371+ * Hamburger toggle. Hidden at desktop widths (≥1080px). At narrower
372+ * viewports it replaces the inline nav-links and toggles a panel
373+ * underneath the header bar via a small handler in `header-enhancer`.
374+ */
375+ .nav-toggle {
376+ display : none;
377+ align-items : center;
378+ justify-content : center;
379+ width : 38px ;
380+ height : 38px ;
381+ margin-left : auto;
382+ padding : 0 ;
383+ background : transparent;
384+ border : 1px solid rgba (26 , 26 , 26 , 0.18 );
385+ border-radius : 8px ;
386+ cursor : pointer;
387+ color : var (--ink );
388+ transition : background 0.18s ease, border-color 0.18s ease;
389+ }
390+ .nav-toggle : hover {
391+ background : rgba (26 , 26 , 26 , 0.04 );
392+ border-color : rgba (26 , 26 , 26 , 0.32 );
393+ }
394+ .nav-toggle-icon ,
395+ .nav-toggle-icon ::before ,
396+ .nav-toggle-icon ::after {
397+ display : block;
398+ width : 18px ;
399+ height : 2px ;
400+ background : currentColor;
401+ border-radius : 2px ;
402+ transition : transform 0.18s ease, opacity 0.18s ease;
403+ }
404+ .nav-toggle-icon {
405+ position : relative;
406+ }
407+ .nav-toggle-icon ::before ,
408+ .nav-toggle-icon ::after {
409+ content : '' ;
410+ position : absolute;
411+ left : 0 ;
412+ }
413+ .nav-toggle-icon ::before { top : -6px ; }
414+ .nav-toggle-icon ::after { top : 6px ; }
415+ /* When open, morph into an "X" */
416+ .nav .is-open .nav-toggle-icon { background : transparent; }
417+ .nav .is-open .nav-toggle-icon ::before { top : 0 ; transform : rotate (45deg ); }
418+ .nav .is-open .nav-toggle-icon ::after { top : 0 ; transform : rotate (-45deg ); }
419+
286420.nav-side {
287421 display : inline-flex;
288422 align-items : center;
@@ -1936,14 +2070,94 @@ footer {
19362070@media (max-width : 1200px ) {
19372071 .topbar-inner .mid { display : none; }
19382072}
1939- /* nav: between 1080 and 1180 the brand tail + 5 nav links + 2 CTAs + dot
2073+ /* nav: between 1080 and 1180 the brand tail + nav links + 2 CTAs + dot
19402074 * crowd the row. Drop the brand sub-meta first, then tighten link spacing,
19412075 * so the Star CTA never has to compress. */
19422076@media (max-width : 1180px ) {
19432077 .nav-inner { gap : 18px ; }
19442078 .brand-meta { display : none; }
19452079 .nav-links { gap : 28px ; }
19462080}
2081+
2082+ /* nav: at ≤1080px there's no clean way to fit Product · Skills · Systems ·
2083+ * Templates · Craft · Blog · Contact + Download + Star + dot in one row,
2084+ * so swap to a hamburger panel. Star CTA stays visible in the bar (it's
2085+ * the social-proof CTA); Download moves into the panel. The Product
2086+ * submenu flattens from a hover-popup to an always-expanded inline list,
2087+ * since hover doesn't translate to touch.
2088+ */
2089+ @media (max-width : 1080px ) {
2090+ .nav-toggle { display : inline-flex; }
2091+ .brand { white-space : nowrap; }
2092+ /* Hide Download from the bar (Star stays). */
2093+ .nav-side .nav-cta .ghost { display : none; }
2094+ /* Collapse the nav <ul> into a panel that drops below the header bar.
2095+ * The header is `position: sticky`, so absolute-positioning the panel
2096+ * relative to the header element keeps it pinned correctly. */
2097+ .nav { position : sticky; }
2098+ .nav > .nav-inner > nav [data-nav-primary ] {
2099+ position : absolute;
2100+ top : 100% ;
2101+ left : 0 ;
2102+ right : 0 ;
2103+ margin : 0 ;
2104+ padding : 0 ;
2105+ pointer-events : none;
2106+ opacity : 0 ;
2107+ visibility : hidden;
2108+ transform : translateY (-6px );
2109+ transition : opacity 0.2s ease, transform 0.2s ease, visibility 0.2s ;
2110+ background : var (--paper );
2111+ border-top : 1px solid rgba (26 , 26 , 26 , 0.08 );
2112+ box-shadow : 0 12px 32px rgba (26 , 26 , 26 , 0.06 );
2113+ }
2114+ .nav .is-open > .nav-inner > nav [data-nav-primary ] {
2115+ pointer-events : auto;
2116+ opacity : 1 ;
2117+ visibility : visible;
2118+ transform : translateY (0 );
2119+ }
2120+ .nav-links {
2121+ flex-direction : column;
2122+ align-items : stretch;
2123+ gap : 0 ;
2124+ padding : 12px 24px 20px 24px ;
2125+ }
2126+ .nav-links li {
2127+ border-bottom : 1px solid rgba (26 , 26 , 26 , 0.06 );
2128+ }
2129+ .nav-links li : last-child { border-bottom : none; }
2130+ .nav-links a {
2131+ display : block;
2132+ padding : 14px 0 ;
2133+ font-size : 16px ;
2134+ }
2135+ .nav-links a .num {
2136+ position : static;
2137+ margin-left : 6px ;
2138+ font-size : 11px ;
2139+ }
2140+ /* Product dropdown flattens — always show OD + HA as nested static items. */
2141+ .nav-links li .has-dropdown { position : static; }
2142+ .nav-links .dropdown-caret { display : none; }
2143+ .nav-dropdown {
2144+ position : static;
2145+ opacity : 1 ;
2146+ visibility : visible;
2147+ transform : none;
2148+ margin : 0 0 4px 0 ;
2149+ padding : 0 0 4px 16px ;
2150+ border : none;
2151+ border-left : 2px solid rgba (26 , 26 , 26 , 0.08 );
2152+ border-radius : 0 ;
2153+ box-shadow : none;
2154+ background : transparent;
2155+ min-width : 0 ;
2156+ }
2157+ .nav-dropdown ::before { display : none; }
2158+ .nav-dropdown a { padding : 8px 8px ; border-radius : 4px ; }
2159+ .nav-dropdown .dropdown-blurb { display : none; }
2160+ }
19472161@media (max-width : 1080px ) {
19482162 .container { padding : 0 32px ; }
19492163 .hero h1 { font-size : clamp (36px , 4.6vw , 54px ); }
@@ -2024,9 +2238,12 @@ footer {
20242238 .foot-grid { grid-template-columns : 1fr 1fr ; gap : 32px ; }
20252239 .foot-bottom { flex-direction : column; align-items : flex-start; gap : 12px ; }
20262240 .foot-bottom .right { flex-wrap : wrap; gap : 12px 20px ; }
2027- /* nav */
2241+ /* nav — at ≤880px tighten padding; nav-links stay reachable through
2242+ * the hamburger panel introduced at ≤1080px. Brand meta and Download
2243+ * stay hidden; Star CTA still pings in the bar. */
20282244 .nav { padding : 16px 0 ; }
2029- .nav-links , .brand-meta , .nav-cta { display : none; }
2245+ .brand-meta { display : none; }
2246+ .nav-side .nav-cta .ghost { display : none; }
20302247}
20312248@media (max-width : 640px ) {
20322249 .topbar-inner { gap : 14px ; }
0 commit comments