diff --git a/public/css/sub-pages.css b/public/css/sub-pages.css index f5348c857..a6e209cfd 100644 --- a/public/css/sub-pages.css +++ b/public/css/sub-pages.css @@ -361,6 +361,17 @@ main#main { padding-right: var(--spacing-md); } +/* Mobile menu toggle. Hidden on desktop. */ +.skills-sidebar-toggle { + display: none; +} + +.skills-sidebar-toggle-chevron { + transition: transform var(--duration-base) var(--ease-out); + flex-shrink: 0; + color: var(--color-ash); +} + /* Label at the top of the sidebar — hidden visually, kept for a11y tree. */ .skills-sidebar-label { position: absolute; @@ -397,7 +408,12 @@ main#main { letter-spacing: 0.14em; color: var(--color-ash); margin-bottom: 6px; + /* Links use margin-left: -14px + border (2) + padding-left (12) to + end with text at the column edge (0). Group titles have no border, + so a small left margin matches the link text position without the + extra padding math. */ padding: 0; + margin-left: 0; } .skills-sidebar-list { @@ -412,13 +428,13 @@ main#main { .skills-sidebar-list a { display: block; - /* No left padding: text starts at the column edge so it lines up with - the header logo. The 2px active accent lives 2px to the left via a - negative margin, sitting in the layout's horizontal padding gutter. */ - padding: 4px 0; - margin-left: -2px; + /* Negative left margin pulls the 2px active accent into the layout + gutter, out from under the text. Padding-left then pushes the text + itself 12px further right for breathing room, so the text reads + with comfortable space from the active bar. */ + padding: 4px 0 4px 12px; + margin-left: -14px; border-left: 2px solid transparent; - padding-left: 2px; font-family: var(--font-mono); font-size: 0.875rem; font-weight: 500; @@ -963,7 +979,7 @@ main#main { } /* ============================================ - MOBILE: collapse sidebar into inline block + MOBILE: collapsible sidebar behind a toggle ============================================ */ @media (max-width: 920px) { @@ -977,13 +993,48 @@ main#main { max-height: none; overflow: visible; border-right: none; - border-bottom: 1px solid var(--color-mist); - padding: var(--spacing-md) 0 var(--spacing-lg); + padding: var(--spacing-md) 0; margin-bottom: var(--spacing-lg); } + /* Show the toggle button and collapse the menu by default. */ + .skills-sidebar-toggle { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--spacing-sm); + width: 100%; + padding: 12px 16px; + background: var(--color-cream); + border: 1px solid var(--color-mist); + border-radius: 8px; + cursor: pointer; + font-family: var(--font-mono); + font-size: 0.8125rem; + font-weight: 600; + color: var(--color-ink); + text-align: left; + transition: border-color var(--duration-fast) var(--ease-out); + } + + .skills-sidebar-toggle:hover { + border-color: var(--color-ink); + } + + .skills-sidebar-toggle[aria-expanded="true"] .skills-sidebar-toggle-chevron { + transform: rotate(180deg); + } + .skills-sidebar-inner { + display: none; padding-right: 0; + padding-top: var(--spacing-md); + border-top: 1px solid var(--color-mist); + margin-top: var(--spacing-md); + } + + .skills-sidebar-toggle[aria-expanded="true"] + .skills-sidebar-inner { + display: block; } .skills-sidebar-group { diff --git a/scripts/build-sub-pages.js b/scripts/build-sub-pages.js index 48d35ae71..e2670218c 100644 --- a/scripts/build-sub-pages.js +++ b/scripts/build-sub-pages.js @@ -155,9 +155,23 @@ ${bodyHtml} * null (no current page) */ function renderDocsSidebar(skillsByCategory, tutorials, current = null) { + // Label the toggle button with the current page so mobile users know + // where they are at a glance, then open the menu to switch. + let currentLabel = 'Docs menu'; + if (current?.kind === 'skill') { + currentLabel = `/${current.id}`; + } else if (current?.kind === 'tutorial') { + const t = tutorials.find((x) => x.slug === current.slug); + if (t) currentLabel = t.title; + } + let html = `