Pagination
Page-range selector for long lists. Use when you have more than 10–12 items that users need to browse rather than search. For open-ended feeds (social, news), prefer infinite scroll instead. Active page uses primary action styling.
a11y (built in): the host is a <nav aria-label="Pagination"> landmark and every control is a real <button> with an explicit aria-label — Previous page, Page 4, Next page — while the current page also carries aria-current="page" and the … gap is a <span aria-hidden="true">, so it is neither focusable nor announced. Prev/next take the native disabled attribute at the first and last page, and every button shows a :focus-visible outline.
Usage: Ship the <nav class="lb-pagination" data-lb-pagination> empty — the controller owns its contents and renders every button from data-lb-total-pages + data-lb-current-page (or totalPages / currentPage / siblingCount / onChange passed to new LB.Pagination(el, options)). Every accepted change re-renders and dispatches lb-page-change with detail.page; out-of-range and same-page requests are silently ignored. The component only tracks the page number — fetching and redrawing the actual list is the consumer's job, driven by that event or onChange(page); jump programmatically with el._lbPagination.goTo(page).