Tabs

A .joy-tabs-nav with buttons, plus sibling content panels. Only the panel with .is-active is visible.

joy.js doesn't ship a ready-made tabs API — toggling .is-active is written by hand on each page. It's only a few lines, shown below.

Profile content
Security content
<div class="joy-tabs-nav">
    <button type="button" class="joy-tab-btn is-active" data-tab="profile"><i class="ph ph-user"></i><span>Profile</span></button>
    <button type="button" class="joy-tab-btn" data-tab="security"><i class="ph ph-shield"></i><span>Security</span></button>
</div>
<div class="joy-tab-panel is-active" id="tab-profile">Profile content</div>
<div class="joy-tab-panel" id="tab-security">Security content</div>
document.querySelectorAll('.joy-tab-btn').forEach(btn => {
    btn.addEventListener('click', () => {
        document.querySelectorAll('.joy-tab-btn').forEach(b => b.classList.toggle('is-active', b === btn));
        document.querySelectorAll('.joy-tab-panel').forEach(p => p.classList.toggle('is-active', p.id === 'tab-' + btn.dataset.tab));
    });
});

For tabs synced with the URL (#hash plus history.pushState), read the initial hash on page load and listen for window.addEventListener('popstate', ...) to react to the browser's back button.