import InfoBox from '../components/InfoBox.astro';
import PullQuote from '../components/PullQuote.astro';

Leaderboard entries display status chips for game language, turn limits, and player roles across all four challenge tabs. These chips relied on native HTML `title` attributes to explain what each label meant. While hover tooltips work on desktop browsers, mobile viewports provide no hover state, leaving touch users unable to inspect chip meanings or understand abbreviated game settings.

## Extracting a dedicated chip component

Replacing native `title` attributes required moving chip markup into a unified `LeaderboardChip.svelte` component. Rather than repeating popover state across each tab template, the new component wraps its content in the shared `DetailTooltip` system originally established for [stat chip tooltips](/posts/detail-tooltips#explanation-on-demand). Tapping or clicking a chip opens an accessible popover containing bilingual explanatory copy.

```svelte
<!-- LeaderboardChip.svelte -->
<DetailTooltip text={tooltipText}>
  <span class="chip {chipClass}">
    {chipText}
  </span>
</DetailTooltip>
```

The component accepts `tooltipText` as a localized string parameter, binding English and Norwegian descriptors directly to the active interface locale.

<InfoBox variant="note" title="Touch interaction parity">
DetailTooltip handles pointer tap events and keyboard focus toggles, ensuring touch users, screen readers, and desktop mouse users receive identical context explanations.
</InfoBox>

## Dismissing popovers on table scroll

Leaderboard tables render inside scrollable containers (`overflow-x: auto`) to accommodate narrow mobile screens. A floating tooltip opened near the edge of a scroll container can drift away from its origin chip when a player scrolls horizontally. To prevent detached popovers, `LeaderboardChip` binds a passive scroll event listener to its parent container, automatically closing any active tooltip as soon as scrolling begins.

<PullQuote attribution="Leaderboard navigation">
Scrolling a table dismisses open popovers immediately, preventing floating tooltips from detaching from their origin chips.
</PullQuote>

Mirroring the scroll-listener pattern established in earlier component passes, the listener detaches automatically when the component unmounts.

## Verifying touch interactions with TDD

Unit testing for `LeaderboardChip.svelte` was implemented test-first using Svelte Testing Library. Six dedicated test cases verify that tapping toggles popover visibility, that `aria-expanded` attributes reflect the open state correctly, and that dispatching a parent container scroll event fires the dismiss handler cleanly.

```typescript
it('dismisses tooltip when parent container scrolls', async () => {
  const { container } = render(LeaderboardChip, { props: { tooltipText: 'Language: English' } });
  const chip = container.querySelector('.chip')!;
  await fireEvent.click(chip);
  expect(screen.getByText('Language: English')).toBeInTheDocument();

  await fireEvent.scroll(container.parentElement!);
  expect(screen.queryByText('Language: English')).not.toBeInTheDocument();
});
```

Integrating `LeaderboardChip` across Daily, Duel, and PvP leaderboard tabs unifies contextual help across the entire stats interface without adding custom popover logic to individual pages.