Page heading and result count. H1 built from location and filters, e.g. 'Dance teachers near Manchester'. Count comes from the search index. Canonical strips filter params except location and category. Pages with filters are noindex,follow.
Filters sidebar. All filters from the spec: location/postcode, travel distance, event type, age group, dance style, date/availability, in-person/online, group size, price range, accessibility, verified badges, rating. Multi-select uses checkboxes; applying updates URL query params and results without a full reload. Analytics: filter_applied with filter name.
Sort. Options: Best match, Rating, Price low to high, Price high to low, Newest, Nearest. Default Best match (relevance, distance, rating, response rate). Sponsored never outranks organic without the label.
List / map toggle. Map shows pins within the viewport; moving the map updates results. Consent required for map tiles. Selecting a pin highlights the card.
Result cards. Teacher cards link to 06-teacher-profile.html, service cards to 07-service-detail.html. Show photo, name, town, styles, rating and count, badges, from-price (example). Heart icon to save (prompts login if logged out).
Pagination. 24 per page, numbered pager with prev/next. rel=prev/next not required; each page self-canonical.
General request. Prompts users who cannot find a match. Links to 20-booking-request.html in multi-teacher mode.
Empty state. Shown when zero results. Suggest removing the most restrictive filter, show nearby areas and the post-a-request route. Log zero-result searches for the content team.
Mobile
Filters collapse into a 'Filters' button opening a full-screen drawer with a sticky 'Show results' button. Cards one per row. Map becomes a separate full-screen view toggled from the sort bar.
States
Loading: skeleton cards and disabled sort. Error: 'We could not load teachers. Try again.' with retry button, filters retained. Empty: see section above. Logged-out users can browse; saving a teacher triggers login modal. Sponsored cards carry a visible 'Sponsored' badge.