// ── Tabs, bundled rather than borrowed ──────────────────────────────────── // // The shared kit is nine members and it is CLOSED (MODULE_API.md §3.4): layout, // headings, the three data-page states, the fetch hook, the session, the site // and `Slot`. A tab strip is not in it, so it is here — which is the kit working // as designed rather than a gap in it. What the kit guarantees is that a module // page looks like the site while it loads and while it fails; everything a page // builds on top of that is the module's own. // // It is styled with core's CSS VARIABLES and its `.pill` class rather than with // colours of its own, so it re-themes with the instance (THEMING_AND_NAV.md). // The one class this module must never write by hand is the shell wrapper — // `PublicLayout`'s `shell` prop exists precisely so that one stays core's. // // **The selected tab lives in the URL, not in this component.** A tab strip that // owned its own state would make every panel on this page unlinkable: "look at // the leaderboard for this server" would be a sentence rather than a link, back // would leave the page entirely, and a refresh would land on the first tab. So // this is a controlled component and `ServerDetail` keeps the state in a search // parameter. export default function Tabs({ tabs, active, onSelect, label = 'Sections' }) { return (