diff --git a/src/media/css/template.css b/src/media/css/template.css index d3f0ca8..4d2a3dc 100644 --- a/src/media/css/template.css +++ b/src/media/css/template.css @@ -15844,6 +15844,39 @@ body:not(.has-sidebar-right) .site-grid .container-component { grid-area: side-r; } +/* Sidebar accordion on mobile */ +@media (max-width: 991.98px) { + .container-sidebar-left.accordion .card, + .container-sidebar-right.accordion .card { + border: none; + border-bottom: 1px solid var(--border-color, #dee2e6); + border-radius: 0; + } + + .container-sidebar-left.accordion .card-header, + .container-sidebar-right.accordion .card-header { + padding: 0; + background: none; + border: none; + } + + .container-sidebar-left.accordion .accordion-button, + .container-sidebar-right.accordion .accordion-button { + padding: .75rem 1rem; + font-weight: 600; + font-size: .95rem; + background: var(--bs-body-bg, #fff); + color: var(--body-font-color, #444); + } + + .container-sidebar-left.accordion .accordion-button:not(.collapsed), + .container-sidebar-right.accordion .accordion-button:not(.collapsed) { + background: var(--bs-body-bg, #fff); + color: var(--link-color, #3565e5); + box-shadow: none; + } +} + .container-main-top { grid-area: main-t; } diff --git a/src/media/js/template.js b/src/media/js/template.js index 2958bae..34beca6 100644 --- a/src/media/js/template.js +++ b/src/media/js/template.js @@ -488,6 +488,98 @@ return doc.body.getAttribute('data-theme-fab-enabled') === '1'; } + /** + * Convert sidebar card modules into accordion on mobile. + * On screens <= 991px each card collapses; on desktop they revert. + */ + function initSidebarAccordion() { + var BREAKPOINT = 992; + var sidebars = doc.querySelectorAll(".container-sidebar-left, .container-sidebar-right"); + if (!sidebars.length) return; + + var accordionised = false; + + function apply() { + var isMobile = win.innerWidth < BREAKPOINT; + + if (isMobile && !accordionised) { + sidebars.forEach(function (sidebar, si) { + var accId = "sidebarAcc-" + si; + sidebar.setAttribute("id", accId); + sidebar.classList.add("accordion"); + + var cards = sidebar.querySelectorAll(":scope > .card"); + cards.forEach(function (card, ci) { + var collapseId = accId + "-c" + ci; + card.classList.add("accordion-item"); + + var header = card.querySelector(".card-header"); + var body = card.querySelector(".card-body"); + if (!header || !body) return; + + // Turn header into accordion button + header.classList.add("accordion-header"); + var btn = doc.createElement("button"); + btn.className = "accordion-button collapsed"; + btn.type = "button"; + btn.setAttribute("data-bs-toggle", "collapse"); + btn.setAttribute("data-bs-target", "#" + collapseId); + btn.setAttribute("aria-expanded", "false"); + btn.setAttribute("aria-controls", collapseId); + btn.textContent = header.textContent; + header.textContent = ""; + header.appendChild(btn); + header.setAttribute("data-moko-original-text", btn.textContent); + + // Wrap body in collapse + var wrapper = doc.createElement("div"); + wrapper.id = collapseId; + wrapper.className = "accordion-collapse collapse"; + wrapper.setAttribute("data-bs-parent", "#" + accId); + card.insertBefore(wrapper, body); + wrapper.appendChild(body); + body.classList.add("accordion-body"); + }); + }); + accordionised = true; + } else if (!isMobile && accordionised) { + // Revert to plain cards + sidebars.forEach(function (sidebar) { + sidebar.classList.remove("accordion"); + sidebar.removeAttribute("id"); + + var cards = sidebar.querySelectorAll(":scope > .card"); + cards.forEach(function (card) { + card.classList.remove("accordion-item"); + + var header = card.querySelector(".card-header"); + var btn = header ? header.querySelector(".accordion-button") : null; + if (header && btn) { + var text = header.getAttribute("data-moko-original-text") || btn.textContent; + header.removeAttribute("data-moko-original-text"); + header.classList.remove("accordion-header"); + header.textContent = text; + } + + var wrapper = card.querySelector(".accordion-collapse"); + if (wrapper) { + var body = wrapper.querySelector(".card-body"); + if (body) { + body.classList.remove("accordion-body"); + card.appendChild(body); + } + wrapper.parentNode.removeChild(wrapper); + } + }); + }); + accordionised = false; + } + } + + apply(); + win.addEventListener("resize", apply); + } + /** * Run all template JS initializations */ @@ -512,6 +604,7 @@ // Init features initDrawers(); initBackTop(); + initSidebarAccordion(); } if (doc.readyState === "loading") {