KKUONIDesign System

Components

Activity Card

Beta

ActivityCard presents an excursion, tour, or experience with difficulty level, duration, price, and a booking CTA — used in destination activity grids and holiday extras.

Moderate

Maasai Mara Sunrise Safari

Board a 4x4 at first light for the most rewarding game-viewing window of the day. Your expert guide will navigate the Mara triangle in search of the Big Five.

Maasai Mara, Kenya4 hours

From

£195

per person

Book now

Purpose

ActivityCard surfaces excursions, tours, and experiences that a traveller can add to their holiday. It appears in the "Things to do" section of destination pages, in the "Add extras" step of the booking funnel, and in curated experience guides ("Best of Kenya", "Maldives activities").

The component answers four questions that determine whether a traveller will book an activity:

  • What is it? — title and description
  • Where? — location with a map pin
  • How long and how hard? — duration and difficulty
  • How much? — price with a clear "Book now" CTA

The difficulty badge is the most distinctive element of ActivityCard compared to other card types. It uses semantic colour (green / amber / red) to convey physical demand at a glance — critical for safari walks, trekking excursions, or ski touring where the physical demand is a genuine filter criterion.

Usage

Reach for ActivityCard when presenting a bookable excursion, tour, or experience — as opposed to AccommodationCard (a property) or a TripCard (a full package). The distinguishing signal is the difficulty pill, so use ActivityCard specifically when physical demand is a meaningful filter criterion for the traveller.

It typically appears in a grid within the "Things to do" section of a destination page, in the "Add extras" step of a booking funnel, or within curated experience guides.

Anatomy

PopularEasy

Coral Reef Snorkel Tour

Explore the vibrant house reef at North Malé Atoll with a marine biologist guide who reveals the hidden life between the corals.

North Malé Atoll, Maldives2 hours

From

£85

per person

Book now
  1. 1
    Image3:2 aspect ratio, object-cover. Optional badge pill in teal sits absolute top-left (e.g. "Popular", "Bestseller"). Difficulty pill sits absolute top-right in green/amber/red depending on value.
  2. 2
    Title16px bold. The activity name. Not a link — the "Book now" CTA and the href carry the interaction.
  3. 3
    Description14px grey, clamped to 2 lines. A short sentence or two about what the activity involves. Full detail is on the activity page.
  4. 4
    Meta rowLocation (MapPin icon) and duration (Clock icon) in 13px grey, separated by a middle dot.
  5. 5
    Price block"From £X" in 18px bold. "per person" in 12px grey below.
  6. 6
    CTA"Book now" teal button linking to href. Full width on mobile, right-aligned on desktop.

Variants

Easy — green difficulty badge

difficulty="Easy" renders a green pill. Use for activities accessible to all fitness levels and ages: boat trips, guided tours, beach walks, snorkelling on calm reefs.

PopularEasy

Glass-Bottom Boat Reef Tour

Float over the coral gardens of the South Malé Atoll in a traditional dhoni fitted with a glass viewing panel. No swimming required.

South Malé Atoll, Maldives1.5 hours

From

£65

per person

Book now

Moderate — amber difficulty badge

difficulty="Moderate" renders an amber pill. Use for activities that require some fitness or capability but are achievable for most adults: safari game walks, half-day bike rides, snorkelling in current, introductory diving.

Moderate

Serengeti Walking Safari

Leave the vehicle behind and track wildlife on foot with an armed ranger. A transformative perspective on the bush — you will notice details invisible from a 4x4.

Serengeti, Tanzania3 hours

From

£220

per person

Book now

Challenging — red difficulty badge

difficulty="Challenging" renders a red pill. Use for activities with genuine physical demands or technical requirements: gorilla trekking through steep forest, ski touring, summit hikes, advanced diving. The red pill is a clear pre-filter — travellers self-select before clicking through.

Challenging

Mountain Gorilla Trek

Trek through the dense rainforest of the Volcanoes National Park to spend one unforgettable hour with a wild gorilla family. Altitude 2,500–4,500m. Fitness required.

Volcanoes National Park, RwandaFull day

From

£1,500

per person

Book now

With teal badge

The optional badge prop renders a teal pill on the top-left of the image. Use for editorial signals like "Popular", "Bestseller", or "Limited spaces". The teal badge coexists with the difficulty pill on the opposite corner.

BestsellerEasy

Private Sunset Dhow Cruise

Sail the sheltered waters of Stone Town harbour aboard a traditional wooden dhow as the sun sets over the Indian Ocean. Canapés and sundowners included.

Stone Town, Zanzibar2 hours

From

£145

per person

Book now

Without difficulty

When difficulty is omitted the difficulty pill is hidden. Use this for activities where difficulty is not a relevant concept — city tours, cultural experiences, spa treatments, cookery classes.

Galle Spice and Cooking Class

Learn to prepare a three-course Sri Lankan feast from a local chef in a heritage kitchen in Galle Fort. All spices are sourced from the herb garden outside.

Galle Fort, Sri Lanka3 hours

From

£95

per person

Book now

Ski activity

ActivityCard works equally well for ski and alpine experiences. Difficulty maps naturally to ski grading conventions.

Challenging

Ski Touring — Haute Route

Follow in the footsteps of the legendary Chamonix to Zermatt high route with a IFMGA-certified mountain guide. Seven days of glacier travel and untracked powder.

Chamonix, French Alps7 days

From

£3,200

per person

Book now

States

Default

Card rests with a light shadow and #E5E5E5 border. The "Book now" button is teal/filled. The description is clamped to 2 lines.

Hover

Shadow deepens. Image zooms slightly (scale(1.02)) within its clipped container. The card does not scale. "Book now" button background darkens by 10% to indicate readiness.

Focus

A visible teal focus ring appears on the "Book now" button when focused via keyboard. The card itself is not a link — only the "Book now" button is interactive, so focus lands precisely on the action.

Sold out / unavailable (future)

When availability data indicates the activity is sold out, the "Book now" button renders as disabled with aria-disabled="true" and a "Sold out" label. The card otherwise displays normally — the image and information remain visible.

Best practices

Do

Write descriptions that are specific and sensory — what will the traveller actually experience? What should they know before booking?

Two lines of description give enough context for the traveller to decide whether to click through.

Don't

Write placeholder or SEO-generic descriptions that do not help the traveller decide whether the activity suits them.

A generic description ('A great excursion for the whole family') gives no decision-making information.

Do

Grade difficulty accurately. If gorilla trekking takes 6 hours at altitude, it is Challenging even if the experience itself is slow-paced.

The difficulty badge is a pre-filter — honest grading means fewer unsuitable bookings.

Don't

Default to Easy for all activities to make them appear accessible to the broadest audience.

Under-grading creates disappointed customers and costly support requests.

Do

Write duration as a plain human string that matches how travellers think about time: '2 hours', 'Half day', 'Full day', '3 days'.

'Full day' and '3 hours' are clear, human-readable durations that answer the planning question.

Don't

Pass duration as an ISO 8601 duration string or a raw minute count without a label.

'PT3H30M' or '210 minutes' requires calculation — the traveller cannot quickly visualise it.

Do

Use the teal badge prop for editorial labels ('Popular', 'Bestseller', 'Limited spaces') and leave difficulty for the physical grading.

Teal badge for editorial signal, difficulty badge for physical demand — each serves a distinct purpose.

Don't

Use the badge prop to convey difficulty information that is already shown in the difficulty pill.

Using the teal badge to repeat the difficulty ('Hard activity') makes both badges redundant.

Props

PropTypeDefaultDescription
title*stringActivity name. Rendered as the primary heading in 16px bold.
image{ src: string; alt: string }Card hero image at 3:2 aspect ratio. The alt text should describe the scene depicted, not just repeat the title.
descriptionstringShort description clamped to 2 lines. Gives the traveller enough context to decide whether to view the full activity page.
locationstringActivity location shown with a MapPin icon. e.g. 'Maasai Mara, Kenya', 'Stone Town, Zanzibar'.
durationstringHuman-readable duration shown with a Clock icon. e.g. '2 hours', 'Half day', 'Full day', '3 days'.
difficulty'Easy' | 'Moderate' | 'Challenging'Physical difficulty level. 'Easy' renders a green pill, 'Moderate' an amber pill, 'Challenging' a red pill. When omitted, no difficulty pill is shown.
priceFromnumberLead price numeral. Displayed as 'From [currency][priceFrom]'.
currencystring'£'Currency symbol prepended to the price numeral.
priceBasisstring'per person'Suffix below the price. e.g. 'per person', 'per group', 'per couple'.
hrefstringURL for the activity detail page. The "Book now" button links here.
badgestringEditorial label rendered in a teal pill on the top-left of the image. e.g. 'Popular', 'Bestseller', 'Limited spaces'.
classNamestringAdditional Tailwind classes on the root element.

Accessibility

Interactive structure

Unlike AccommodationCard (where the whole card is a link), ActivityCard uses a button-based CTA model. The card root is a <div> — not an <a>. Only the "Book now" <button> (or <a>) is interactive. This is appropriate because activity cards are frequently displayed inside a booking flow where the card itself may also have a "select" checkbox or toggle state.

If the card is used in a pure listing context with no secondary state, you may wrap the card in an <a> and make the "Book now" button aria-hidden with tabIndex={-1} to avoid duplicate tab stops — the same pattern as AccommodationCard.

Difficulty badge colour

The difficulty pill uses three colours: green, amber, red. Colour alone is not sufficient — the pill always renders its text label ("Easy", "Moderate", "Challenging"). This means travellers who cannot distinguish the colours can still read the difficulty level.

The pill also has an aria-label of "Difficulty: [value]" for screen readers, so the context is not lost when the label is read in isolation from the visual pill shape.

Description clamp

The description is visually clamped to 2 lines with line-clamp-2. The full text is available in the DOM and is readable by screen readers. The truncation is purely visual — no content is hidden from assistive technology.

Image alt text

Describe the activity in progress, not just the location. "Land Rover crossing the Mara at sunrise" is better than "Kenya safari".

{/* ✅ Scene-descriptive */}
image={{ alt: 'Trekkers climbing through bamboo forest toward gorilla habitat, Rwanda' }}

{/* ❌ Title repetition — screen reader would hear title twice */}
image={{ alt: 'Mountain Gorilla Trek Rwanda' }}

"Book now" button label

The button label "Book now" is not descriptive in isolation — screen reader users scanning a page by interactive elements would hear "Book now, Book now, Book now" for every activity card. The button should have aria-label="Book [title]" so each button is uniquely identified:

{/* The component renders this internally */}
<a href={href} aria-label={`Book ${title}`} className="...">
  Book now
</a>

Focus order

Within the card, focus order is: image (skipped — not focusable) → title (heading, not focusable) → description (not focusable) → "Book now" button. A single Tab stop per card keeps navigation efficient in a grid of activities.

  • AccommodationCard — the equivalent card pattern for hotel properties rather than excursions.
  • Card — the generic container this component specialises for activity content.