80Carousel
Scroll-snap, no JS required: slides swipe on touch and scroll-wheel on desktop; prev/next are the system's own outline icon buttons wired to scrollBy. Slides hold cards, figures, quotes — the carousel is only the rail.
Use it for
- A shelf of courses/resources wider than the viewport
- Testimonials, related lessons at an article's foot
Not for
- Hero carousels that auto-rotate — nothing in this system moves uninvited
- Content users must not miss — a carousel hides everything after slide two
Card shelf
Snap-start slides; the nav buttons scroll one viewport.
markup
<div class="ns-carousel" style="inline-size:100%">
<div class="ns-carousel__track" tabindex="0" role="region" aria-label="Popular courses">
<div class="ns-carousel__slide ns-card"><div class="ns-card__body"><span class="ns-card__kicker">// Course</span><span class="ns-card__title">Apex basics</span><p class="ns-card__text">The platform's own language from zero.</p></div><div class="ns-card__foot">12 lessons</div></div>
<div class="ns-carousel__slide ns-card"><div class="ns-card__body"><span class="ns-card__kicker">// Course</span><span class="ns-card__title">Flows</span><p class="ns-card__text">Declarative automation, end to end.</p></div><div class="ns-card__foot">9 lessons</div></div>
<div class="ns-carousel__slide ns-card"><div class="ns-card__body"><span class="ns-card__kicker">// Course</span><span class="ns-card__title">Admin cert</span><p class="ns-card__text">The exam path, in order.</p></div><div class="ns-card__foot">14 lessons</div></div>
<div class="ns-carousel__slide ns-card"><div class="ns-card__body"><span class="ns-card__kicker">// Course</span><span class="ns-card__title">LWC</span><p class="ns-card__text">Components the platform way.</p></div><div class="ns-card__foot">11 lessons</div></div>
</div>
<div class="ns-carousel__nav">
<button class="ns-btn ns-btn--outline ns-btn--sm ns-btn--icon" data-dir="prev" aria-label="Previous"><i class="ph ph-caret-left" aria-hidden="true"></i></button>
<button class="ns-btn ns-btn--outline ns-btn--sm ns-btn--icon" data-dir="next" aria-label="Next"><i class="ph ph-caret-right" aria-hidden="true"></i></button>
</div>
</div>Accessibility contract
- The track is keyboard-scrollable (tabindex on the region, arrow keys native)
- Prev/next buttons are real buttons with labels; no dots-only navigation