Patterns
Booking CTA
CTA hierarchy across the Kuoni booking funnel. How Button variants map to Browse → Enquire → Book stages, price display and CTA pairing rules, and placement guidelines.
- 1Browse stage — TripCard with an outline/ghost "View details" button. Low-commitment — the user is still scanning. Price shown as "from £N pp".
- 2Enquire stage — BookingCard or side panel with a primary yellow "Enquire now" button. Full price breakdown visible. User has expressed clear intent.
- 3Book stage — Checkout summary card with a maximum-weight primary "Book now — secure your holiday" button. Total price (not per-person) is the primary figure.
- 4Price display rule — The price label escalates across stages: "from £N pp" → "£N pp / £N total" → "£N total · £N pp". Always show the per-person figure — never total-only in early stages.
- 5CTA button mapping — Ghost / Outline = Browse. Primary (Yellow) = Enquire and Book. Never use a primary CTA in the browse stage — it collapses the funnel by pushing users to commit too early.
Pattern overview
Every Kuoni page that drives toward a sale uses a three-stage CTA hierarchy. The hierarchy maps to the user's level of intent:
- Browse — scanning, comparing, low commitment → Ghost or outline button
- Enquire — showing intent, requesting more detail → Primary yellow button
- Book — committing, paying → Primary yellow button at maximum visual weight
This distinction matters because travel purchases are high-consideration: the average Kuoni customer views 8–12 holidays before enquiring and takes 3–7 days from first visit to booking. Premature commitment pressure increases bounce rates.
Funnel stage detail
Stage 1 — Browse
The browse CTA must not pressure users who are still comparing options.
- Button variant: Ghost (border + transparent bg) or Outline (border + white bg)
- Label:
"View details"— describes the action, not the outcome - Placement: bottom of TripCard, full-width within the card
- Price:
from £3,299 pp— "from" prefix is mandatory at this stage
<Button variant="outline" size="sm">View details</Button>
A primary yellow button on a browse card signals urgency the user doesn't feel. It trains users to ignore yellow buttons across the site.
Stage 2 — Enquire
Once the user has opened a specific holiday and is reviewing it, the primary CTA appears.
- Button variant: Primary (Kuoni Yellow, dark text)
- Label:
"Enquire now"— not"Book"— because no payment is taken at this step - Placement: full-width at the bottom of the BookingCard side panel
- Price: full breakdown visible — per-person price + total price
A secondary action ("Call us" with phone icon) can appear below the primary button. It must always be lower visual weight — outlined or ghost.
<Button variant="primary">Enquire now</Button>
<Button variant="ghost" size="sm">
<Phone className="mr-2 h-4 w-4" />
Call us
</Button>
Stage 3 — Book
At checkout, the user has confirmed party size, dates, and total cost. The CTA reflects full commitment.
- Button variant: Primary (Kuoni Yellow) with
shadow-kuoni-smadded - Label:
"Book now — secure your holiday"— more specific than"Enquire now", signals that this action creates a booking reference - Placement: below the full price summary, full-width
- Price: total price as the primary figure, per-person as secondary
<Button variant="primary" className="shadow-kuoni-sm w-full">
Book now — secure your holiday
</Button>
The copy "secure your holiday" reassures users that clicking does not mean immediate payment — Kuoni's typical flow takes a deposit or is payment-on-collection. This reduces abandonment at the final step.
Price display and CTA pairing
The price escalation rule
The price label format changes across funnel stages to match what the user needs at each point:
| Stage | Price format | Rationale |
|---|---|---|
| Browse (TripCard) | from £3,299 pp | Lowest anchor price; "from" signals price may be higher |
| Enquire (BookingCard) | £3,299 pp · £6,598 total | User needs the actual cost for 2+ adults |
| Book (Checkout) | £6,598 total · £3,299 pp | Total is the commitment figure; pp is reassurance |
Never show total-only in browse. A £6,598 total looks expensive against a competitor's £2,199 per-person price. Always show the per-person figure in the first touchpoint.
Always show total at book. At checkout, the user is authorising a total spend. Per-person-only at this stage causes confusion about the actual amount being committed.
PriceDisplay component usage
{/* Browse stage */}
<PriceDisplay amount={3299} prefix="from" suffix="pp" />
{/* Enquire stage */}
<PriceDisplay amount={3299} suffix="pp" />
<PriceDisplay amount={6598} prefix="Total:" size="sm" />
{/* Book stage */}
<PriceDisplay amount={6598} size="lg" />
<PriceDisplay amount={3299} prefix="£" suffix="pp" size="sm" muted />
Button placement rules
One primary CTA per view
There is never more than one primary (yellow) button visible on screen at the same time. The BookingCard side panel contains the primary "Enquire now" — this means the browse grid cards behind it must use ghost/outline CTAs.
CTA stacking order
When multiple actions are available, stack them in this order (top to bottom):
- Primary — the recommended action for this funnel stage
- Secondary — an alternative route (
"Call us","Add to wishlist") - Tertiary — a navigation escape (
"Back to results","View similar holidays")
Never reverse this order. Never show two primary buttons in a stack.
Full-width vs auto-width
| Context | Width |
|---|---|
| Inside a card (TripCard, BookingCard, checkout summary) | w-full |
| Inline in body text (e.g. a Callout) | Auto-width |
Alongside a sibling button ("Enquire" + "Call us") | Both auto-width, flex gap-3 |
Usage
Use ghost/outline for browse-stage CTAs and primary yellow only for enquiry and booking commitment.
A ghost 'View details' on the browse card and a yellow 'Enquire now' on the booking panel — users understand the escalation.
Use a primary yellow button on browse-stage cards.
A yellow 'Book now' button on every TripCard in the results grid trains users to treat yellow as the default colour — not a signal to act.
Show the per-person price first in browse and enquiry stages, with "from" prefix at browse.
'from £3,299 pp' anchors the per-person cost in the user's mental model from the first touchpoint. The total at checkout is then unsurprising.
Show total-party price as the primary price figure in the browse or enquiry stage.
'£6,598' as the only figure on a TripCard looks twice as expensive as a competitor's '£3,299 pp' — even though they're the same holiday.
Limit primary (yellow) buttons to one per visible screen state.
One primary CTA per screen means the user's eye knows exactly where to look.
Show two primary buttons simultaneously on the same screen.
'Enquire now' and 'Book now' both yellow on the same screen creates a false choice — the user doesn't know which to click first.
Use stage-accurate CTA labels: 'View details' (browse), 'Enquire now' (intent), 'Book now' (commitment).
'Enquire now' sets accurate expectations — no payment, just a consultation. Users who might hesitate at 'Book' will click 'Enquire'.
Label the enquiry CTA 'Book now' when no payment or confirmation is taken at that step.
'Book now' on the holiday detail page before the user has seen pricing, dates, or room options is misleading and creates drop-off.
Worked example — holiday detail page
A holiday detail page holds all three funnel stages simultaneously. The pattern resolves the conflict:
- Above the fold — hero image, title, star rating. No CTA yet.
- Key facts section — nights, dates, board basis, departure airports. Ghost "Check availability" button.
- BookingCard (sticky side panel) — full price breakdown, party selector (CounterInput), and primary
"Enquire now"button. This is the only primary CTA on the page. - Similar holidays — TripCards at the bottom of the page use outline
"View details"— never primary.
This means a user scrolling the page sees: no CTA → ghost CTA → primary CTA (in the sticky panel). The escalation is natural.
Components used
| Component | Role in pattern |
|---|---|
| Button | All CTAs — variant drives funnel stage |
| PriceDisplay | Price figures at all funnel stages |
| TripCard | Browse-stage card with outline CTA |
| BookingCard | Enquiry-stage panel with primary CTA |
| CounterInput | Party size selection on BookingCard |
Accessibility
Button labels must include the holiday name for screen readers
Generic labels like "View details" and "Book now" repeat across multiple cards on the same page. Screen reader users navigating by buttons hear "View details, View details, View details" without context.
Add an aria-label that includes the holiday name:
<Button
variant="outline"
aria-label={`View details — ${holiday.name}`}
>
View details
</Button>
Price changes must be announced
When the total price updates (e.g. the user changes party size in CounterInput), announce the new total:
<p aria-live="polite" aria-atomic="true">
Total: £6,598 for 2 adults
</p>
Focus management at stage transitions
When the user moves from browse → enquire (e.g. clicks "View details" and the BookingCard panel opens), move focus to the panel heading. This ensures keyboard users are not left at the card CTA while the panel is open off-screen.