KKUONIDesign System

Foundations

Motion

Transition timing tokens, easing functions, and the rules that keep animation purposeful rather than distracting.

Motion in a travel product carries weight. A traveller comparing holidays is making a significant decision; distracting animation erodes trust. The Kuoni approach is purposeful restraint: transitions communicate state change (hover lift, menu open, modal appear), never decorate for decoration's sake.

Three transition tokens cover every situation. They are the only values that should appear in transition-* CSS properties across the system.


Transition tokens

transition.fast

120ms ease

Micro-interactions — hover colour changes, focus ring appearance, icon state flips, toggle thumb movement

transition.normal

200ms ease

Component-level transitions — shadow lift on card hover, dropdown open/close, accordion expand, sidebar collapse

transition.slow

300ms ease-in-out

Large surface transitions — Modal open/close, Drawer slide, full-page route changes, image fade-in on load


Token reference

TokenValueTailwindWhen to use
transition.fast120ms easeduration-[120ms] ease-inColour, opacity, border-colour, text-colour changes on hover/focus
transition.normal200ms easeduration-200 ease-in-outShadow lift, width/height, visibility, position within a component
transition.slow300ms ease-in-outduration-300 ease-in-outOverlay appear/disappear, page-level enter/exit, large layout shifts

The ease function (fast/normal) accelerates out of the resting state smoothly. ease-in-out (slow) is symmetric — used for reversible transitions that must feel equally natural in both directions (modal open and modal close).


What to animate

Animate these properties

  • box-shadow — card hover lift from shadow-kuoni-sm to shadow-kuoni-md
  • background-color / color — hover state on buttons, links and nav items
  • border-color — focus ring appearance on inputs and interactive controls
  • opacity — overlay backdrops, tooltip/popover fade-in
  • transform: translateY — Drawer slide up/down, Modal slight upward enter
  • max-height / height — accordion expand/collapse

Use Tailwind transition utilities

{/* Card hover lift — transition.normal */}
<div className="rounded-md bg-white shadow-kuoni-sm transition-shadow duration-200 hover:shadow-kuoni-md">
  ...
</div>

{/* Button colour change — transition.fast */}
<button className="bg-kuoni-yellow transition-colors duration-[120ms] hover:bg-kuoni-yellow500">
  ...
</button>

What NOT to animate

Do

Animate shadow and background-color on interactive cards.

Shadow and colour transitions give clear hover feedback without moving content.

Don't

Animate transform: scale(1.05) on a TripCard or DestinationCard.

Moving card content on hover is disorienting and interferes with reading.

Do

Animate a Modal entrance with a 300ms opacity + slight translateY.

300ms is the right budget for an overlay; it feels deliberate but not slow.

Don't

Apply transition.slow to micro-interactions like checkbox toggle or button press.

Slow transitions on small UI — a checkbox taking 300ms to check — feel broken.

Never animate these

  • Layout shifts (width/height of content containers that cause reflow)
  • Font size or font weight (causes text reflow and looks broken)
  • Z-index (stacking order cannot be interpolated meaningfully)
  • Content that has already loaded — images, text, prices must not fade in after mount in production; this hides content from users on slow connections

Reduced motion

Always respect the prefers-reduced-motion media query. Users who have requested reduced motion in their operating system — often people with vestibular disorders — should see no transitional animation.

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
  }
}

This rule is already in the global stylesheet. Do not write animation code that works around it. If a state change is purely informational (a filter chip selecting, a toggle switching), the end state is sufficient — the transition is enhancement, not communication.


Animation in components

The table below lists every component that uses motion and its timing.

ComponentProperty animatedToken
Card, TripCard, DestinationCardbox-shadow on hovernormal
Buttonbackground-color on hoverfast
Togglethumb translateX, track background-colorfast
Modalopacity + translateY on open/closeslow
DrawertranslateX on open/closeslow
Sidebar sectionmax-height on accordion opennormal
ChevronDown in dropdownsrotate 0° → 180°normal
Popoveropacity on appearfast
BannertranslateY on dismissalnormal
ProgressBarwidth on value changeslow