EDS 2.0 / Introduction
● v2.0.0
Publish Ready
🌍 Expedia Design System — EDS 2.0

One design language.
Every journey.

EDS 2.0 is the comprehensive design system powering Expedia's global travel products — from search to checkout, web to native.

🎨
34
Components
🔑
180+
Design Tokens
AA+
WCAG Level
🌙
100%
Dark Mode Support

What's in EDS 2.0

🏗️
Foundations
Color system, typography scale, 12-column grid, 8px spacing, elevation, and radius tokens — all built for global scale.
🧩
Components
34 production-ready components with full state coverage, anatomy diagrams, usage guidelines, and accessibility specs.
🔧
Developer Guide
Token integration for CSS, React, React Native, and iOS/Android. Installation, theming, and contribution guide.

Design Principles

The philosophy that guides every decision in EDS — from a single icon to a global checkout flow.

🧭
1. Clarity First

Every element earns its place. Travelers are in high-stakes decision moments — our UI must eliminate cognitive friction, not add to it. Hierarchy, contrast, and language must be instantly legible.

Contrast ratios ≥ 4.5:1
Single primary action per screen
2. Purposeful Delight

Motion and personality should serve a purpose — confirming actions, communicating state, guiding attention. Never decoration at the cost of performance or accessibility.

≤ 200ms transitions
Prefers-reduced-motion
🌍
3. Globally Inclusive

Expedia serves 180+ countries. EDS components support RTL, i18n text expansion, screen readers, keyboard navigation, and low-bandwidth contexts by default.

WCAG 2.2 AA
RTL support
🏎️
4. Scalable Consistency

A traveler using Hotels.com and Expedia.com should feel at home in both. Token-driven consistency enables brand sibling theming without code duplication.

Single token source
Multi-brand theming

Brand Voice in UI

✅ Confident
Use declarative copy. "Find your hotel" not "Search for hotels that might be available."
✅ Warm
Treat travelers as capable adults. Celebrate milestones. Acknowledge friction moments with empathy.
✅ Transparent
Show prices with taxes early. Make cancellation policy prominent. No dark patterns.

Color System

A purposeful palette built for travel — trust, energy, and clarity across every surface.

Primary — Expedia Blue

50
100
200
300
400
500 ★
600
700
800
900
★ Blue 500 is the primary brand color. WCAG AA contrast on white: 5.2:1

Brand — Expedia Yellow

50
100
200
300
400 ★
500
600
700
800
900
★ Yellow 400 is the CTA / accent. Never use on white backgrounds without dark text (#0D1320 or #523C00).

Neutral — Gray Scale

50
100
200
300
400
500
600
700
800
900

Semantic Colors

Success
#00875A
WCAG AA: 4.8:1 on white
Warning
#E67E00
WCAG AA: 4.6:1 on white
Error
#D4002A
WCAG AA: 4.7:1 on white
Info
#0068EF
WCAG AA: 5.2:1 on white

Dark Mode Surfaces

bg-primary
#0D1320
bg-secondary
#1E2636
bg-tertiary
#2A3347
bg-elevated
#343D4F
♿ Accessibility Rule: All text/background combinations must pass WCAG 2.2 AA (4.5:1 for normal text, 3:1 for large text ≥18pt). Never use semantic colors (success, error) as the sole indicator of state — always pair with an icon or text label.

Color Usage Guidelines

✅ Do
✓ Confirmed
✗ Cancelled

Use primary blue for main CTAs; semantic colors paired with icons/text.

❌ Don't
Error

Never use color alone to convey status, or low-contrast combos.

Typography

A 9-level type scale with responsive behavior, built for clarity at every screen size and locale.

Type Stack

Display / Headings
Sora
Aa Bb Cc 0123
Weights: 300 400 500 600 700 800
Body / UI
DM Sans
Aa Bb Cc 0123
Weights: 300 400 500 600
Code / Mono
DM Mono
Aa Bb Cc 0123
Weights: 400 500

9-Level Type Scale

LevelTokenSizeLine HeightWeightSample
Display XL text-4xl 56px / 3.5rem 1.1 800 Book your trip
Display L text-3xl 40px / 2.5rem 1.2 700 Find a hotel
Heading 1 text-2xl 32px / 2rem 1.25 700 Search results
Heading 2 text-xl 24px / 1.5rem 1.3 700 Hotel details
Heading 3 text-lg 20px / 1.25rem 1.35 600 Room options
Body L text-md 18px / 1.125rem 1.6 400 Guest reviews and ratings
Body M (Base) text-base 16px / 1rem 1.5 400 Primary body text for most UI content
Body S text-sm 14px / 0.875rem 1.5 400 Labels, captions, metadata, chip text
Caption / Label text-xs 12px / 0.75rem 1.5 500 Micro-labels, legal, timestamps

Responsive Scale

Display sizes scale down on mobile to maintain reading comfort and visual hierarchy.
Level Desktop Tablet Mobile
Display XL56px44px36px
Display L40px32px28px
H132px28px24px
H224px22px20px
♿ Typography Accessibility: Minimum body text size is 14px. Line height for body text must be ≥ 1.5. Letter-spacing for uppercase labels must be ≥ 0.06em. Never use italic as the sole differentiator. Text must reflow at 400% zoom.

Grid & Layout

A fluid 12-column grid system with defined gutters, margins, and breakpoints.

12-Column Grid

Desktop — 12 columns, 16px gutter, 24px margin
1
2
3
4
5
6
7
8
9
10
11
12
Common column spans — Content layout examples
8 cols — Main Content
4 cols — Sidebar
4 cols — Card
4 cols — Card
4 cols — Card
2 cols
10 cols — Full-bleed hero

Breakpoints

Name Token Range Cols Gutter Margin
📱 Mobile Ssm0 – 375px416px16px
📱 Mobile Lmd376 – 767px416px16px
💻 Tabletlg768 – 1023px816px24px
🖥️ Desktop Sxl1024 – 1279px1216px24px
🖥️ Desktop L2xl1280px+1224px40px

Spacing System

An 8px base unit spacing scale used for padding, margin, gap, and positioning across all components.

8px Base Scale

sp-1
4px — Micro gaps, icon padding
0.25rem
sp-2
8px — Tight component spacing
0.5rem
sp-3
12px — Between inline elements
0.75rem
sp-4
16px — Default component padding
1rem
sp-6
24px — Card padding, section gaps
1.5rem
sp-8
32px — Between page sections
2rem
sp-12
48px — Large section dividers
3rem
sp-16
64px — Page-level vertical rhythm
4rem
sp-20
80px — Hero spacing, major breaks
5rem

Spacing in Context

padding-top: 24px (sp-6)
Card Title
Supporting body text with sp-2 (8px) margin-bottom between title and body, sp-6 (24px) padding on all sides.

Elevation & Radius

Consistent depth cues and corner radii to establish visual hierarchy and surface identity.

Shadow / Elevation Scale

Level 0
Flat
Borders only
Level 1 — sm
shadow-sm
Cards, inputs
Level 2 — md
shadow-md
Dropdowns, popovers
Level 4 — xl
shadow-xl
Modals, dialogs

Border Radius Scale

radius-sm
4px
radius-md
8px
radius-lg
12px
radius-xl
16px
radius-2xl
24px
radius-full
9999px

Actions

Buttons, icon buttons, and link components — the primary drivers of user interaction.

Button
Stable
5 variants
5 sizes
Sizes
States
Icon Buttons
Anatomy
[Leading Icon?][Label][Trailing Icon / Loading Spinner?]
Accessibility: All buttons must have visible focus rings. Icon-only buttons require aria-label. Loading state must announce via aria-live="polite". Disabled buttons retain focusability with aria-disabled="true" (not HTML disabled) for screen reader context.
// React usage <Button variant="primary" size="md" onClick={handleBooking}> Book Now </Button> <Button variant="primary" size="md" loading={isBooking} aria-label="Booking..."> Confirm Booking </Button>
Chips & Tags
Stable
All
Hotels
Flights
Cars
Activities
Badges / Status indicators
New
✓ Confirmed
⚠ Pending
✗ Cancelled
🔥 Hot deal
Past trip

Inputs & Forms

All form components for collecting traveler data — booking flows, accounts, search.

Text Input
Stable
🔍
Try "New York" or "Times Square Hotel"
✓ Valid email
⚠ Invalid or expired promo code
Accessibility: All inputs require a visible <label> or aria-label. Error messages must use role="alert". Required fields use aria-required="true". Never rely solely on placeholder text for labeling.
Select, Textarea & Range
Stable
Checkbox, Radio & Toggle
Stable
Free cancellation
Breakfast included
Pool access
Economy
Business
First class
Email notifications
SMS alerts
Price drop alerts

Feedback

Alerts, toasts, loading states, and progress indicators to communicate system status.

Alerts & Banners
Stable
ℹ️
Flight updates available
Your flight LAX→JFK has a gate change. Please check your boarding pass.
Booking confirmed!
Your reservation at The Grand Hotel is confirmed. Confirmation #EXP-83921.
⚠️
Only 2 rooms left
At current prices. Book now to secure your rate before it's gone.
Payment failed
Your card was declined. Please check your billing details and try again.
Toast Notifications
✓ Added to wishlist
🎉 Booking complete!
⚠ Connection lost
Accessibility: Alert containers use role="alert" or aria-live="assertive". Toasts use role="status" and aria-live="polite". Auto-dismiss toasts allow manual close and pause on hover. Never auto-dismiss error alerts.
Loading & Skeleton States
Stable
Spinner
Large
Card skeleton
Text skeleton
Progress Bars
Booking step 2 of 450%
Price loaded
Partial availability

Navigation

Headers, tabs, breadcrumbs, pagination, and menus for wayfinding.

Global Navigation Header
Brand Component
Tabs
Stable
Underline + Pill
All results
Hotels
42
Apartments
Resorts
Round trip
One way
Multi-city
Accessibility: Tab containers use role="tablist", each tab has role="tab" and aria-selected. Arrow keys navigate between tabs. Active panel uses role="tabpanel". Keyboard: ← → to move, Enter/Space to select.
Breadcrumb & Pagination
Stable
Dropdown Menu
Stable
Dropdown trigger
Booking Stepper
Stable
Search
Select
3
Details
4
Payment
5
Confirm

Display Components

Modal, accordion, tooltip, avatar, and other display primitives.

Modal / Dialog
Stable
Accessibility: Modal uses role="dialog" and aria-modal="true". Focus is trapped inside the modal. ESC closes. Focus returns to trigger on close. Background scrolling is locked while open. Animate with prefers-reduced-motion respect.
Accordion
Stable
What's included in my booking?
Your booking includes accommodation for the selected nights, complimentary breakfast, and access to hotel amenities including pool and gym. Taxes and service charges are already included in the displayed price.
What is the cancellation policy?
Free cancellation available up to 48 hours before check-in. After that, the first night's rate is non-refundable. No-shows are charged the full booking amount.
How do I modify my booking?
Go to My Trips in your account, find your booking, and click "Modify". Changes are subject to availability and may affect your rate.
Tooltip & Avatar
Stable
This rate includes all taxes and fees
4.8 ★
Based on 2,341 verified reviews
JD
JD
JD
JD
🧳
JD
MS
AR
+5
Date Picker
Travel Core
February 2026
Su
Mo
Tu
We
Th
Fr
Sa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Accessibility: Calendar uses role="grid". Days use role="gridcell". Arrow keys navigate days. Enter selects. Unavailable days use aria-disabled. Selected range announces as "Check-in [date] to Check-out [date]".

Travel-Specific Components

Purpose-built components for Expedia's core travel experiences — search, discovery, booking, reviews.

Search Hero Bar
Travel Core
Where to?
New York, NY
United States
Check in
Mar 15
2026
Check out
Mar 20
2026 · 5 nights
Travelers
2 adults
1 room
Property / Hotel Card
Travel Core
🏨
❤️
Free cancel
The Grand Manhattan
Midtown East · 0.3mi from Times Square
$189
per night · taxes incl.
🏖️
🤍
🔥 31% off
Beachfront Paradise Resort
South Beach · Oceanfront
$249
per night
$359
🏨
Midtown Business Hotel
Downtown · 1.2mi center
Sold out for your dates
Rating & Review Display
Travel Core
4.8
★★★★★
Exceptional
Based on 2,341 reviews
5★
78%
4★
14%
3★
5%
2★
2%
1★
1%
4.9
★★★★★
Cleanliness
4.7
★★★★★
Location
4.8
★★★★★
Service
4.6
★★★★☆
Value
Price Display & Filter Panel
Travel Core
Regular price
$189
/night · all taxes included
Sale price
$359
-31%
$249
Save $110 tonight
Filters
Star rating
Any
3★+
4★+
5★
Amenities
🏊 Pool
🅿️ Free parking
🍳 Breakfast
🐾 Pet friendly

Interaction Patterns

Reusable design patterns that solve common travel UX problems.

Search
2
Details
3
Pay
Booking Funnel
Linear flow with clear progress. Each step validates before advancing. Back navigation preserves state.
Hotels
Flights
Cars
Packages
Content Filtering
Chips for primary category switching. Faceted filters in sidepanel. Results update in real-time, no "apply" needed for chips.
Progressive Loading
Skeleton screens replace spinners. Content loads in priority order: structure → prices → images → reviews. Zero layout shift (CLS).
⚠️
2 rooms left!
At this price. Book now.
Urgency & Scarcity
Use warning-level alerts only for factual urgency. Show real availability count. Never manufacture urgency artificially — this erodes trust.
CTA Hierarchy
One primary action per screen. Include price in CTA copy when possible — reduces friction by setting expectations before click.
Or continue with
Social Sign-in
OAuth alternatives always secondary to email. Use dividers with clear label copy. Never stack more than 3 options.

Dos & Don'ts

✅ Do — Clear price transparency
$189
Per night · taxes & fees included

Show taxes in the first price displayed. Confirm total before payment step.

❌ Don't — Hidden fees (dark pattern)
$149
+ taxes, resort fee, service charge added at checkout

Drip pricing destroys trust and increases cart abandonment. Expedia prohibits this pattern.

Dark Mode

A fully supported dark theme using semantic tokens — never hardcoded colors.

E
The Grand Manhattan
Midtown East · New York
✓ Confirmed
Check in
Mar 15, 2026
Check out
Mar 20, 2026
Guests
2 adults

Implementation

/* System preference detection */ @media (prefers-color-scheme: dark) { :root { --bg-primary: #0D1320; --bg-secondary: #1E2636; --text-primary: #F7F8FA; --border-default: #343D4F; } } /* Manual toggle via data attribute */ [data-theme="dark"] { --bg-primary: #0D1320; --text-primary: #F7F8FA; /* ... semantic tokens only */ } // React: useColorScheme hook const { colorScheme, setColorScheme } = useColorScheme();
Dark Mode Rules: All text must maintain ≥ 4.5:1 contrast on dark backgrounds. Never use pure black (#000) or pure white (#FFF) — use the defined surface tokens. Images should reduce brightness by 5-10% in dark mode via CSS filter: brightness(0.9). Never override user preference without explicit action.

Design Tokens JSON

Platform-agnostic token definitions. Single source of truth for CSS, React, React Native, iOS, and Android.

Token Structure

{ "color": { "brand": { "blue": { "50": { "value": "#E8F4FE", "type": "color" }, "500": { "value": "#0068EF", "type": "color", "description": "Primary brand color" }, "600": { "value": "#0057CC", "type": "color" } }, "yellow": { "400": { "value": "#FFCC00", "type": "color", "description": "Brand CTA yellow" } } }, "semantic": { "success": { "value": "#00875A", "type": "color" }, "warning": { "value": "#E67E00", "type": "color" }, "error": { "value": "#D4002A", "type": "color" }, "info": { "value": "#0068EF", "type": "color" } }, "surface": { "light": { "primary": { "value": "#FFFFFF", "type": "color" }, "secondary": { "value": "#F7F8FA", "type": "color" } }, "dark": { "primary": { "value": "#0D1320", "type": "color" }, "secondary": { "value": "#1E2636", "type": "color" } } } }, "typography": { "fontFamily": { "display": { "value": "'Sora', sans-serif" }, "body": { "value": "'DM Sans', sans-serif" }, "mono": { "value": "'DM Mono', monospace" } }, "fontSize": { "xs": { "value": "0.75rem", "type": "dimension" }, "sm": { "value": "0.875rem", "type": "dimension" }, "base": { "value": "1rem", "type": "dimension" }, "4xl": { "value": "3.5rem", "type": "dimension" } } }, "spacing": { "1": { "value": "0.25rem", "type": "dimension" }, "2": { "value": "0.5rem", "type": "dimension" }, "4": { "value": "1rem", "type": "dimension" }, "8": { "value": "2rem", "type": "dimension" } }, "radius": { "sm": { "value": "4px", "type": "dimension" }, "md": { "value": "8px", "type": "dimension" }, "xl": { "value": "16px", "type": "dimension" }, "full": { "value": "9999px", "type": "dimension" } }, "shadow": { "sm": { "value": "0 1px 3px rgba(0,0,0,.08)", "type": "shadow" }, "xl": { "value": "0 20px 50px rgba(0,0,0,.15)", "type": "shadow" } } }

Token Naming Convention

--exp-{category}-{subcategory}-{scale}
Example: --exp-blue-500 | --exp-success-light | --exp-shadow-md
Primitive tokens
Raw values. Referenced only by semantic tokens. Example: --exp-blue-500: #0068EF
Semantic tokens
Reference primitives. Used in components. Example: --color-action-primary: var(--exp-blue-500)
Component tokens
Component-scoped. Example: --btn-bg-primary: var(--color-action-primary)

Developer Guide

Installation, theming, contribution guidelines, and platform-specific implementation notes.

Installation

# npm npm install @expedia/eds-react @expedia/eds-tokens # yarn yarn add @expedia/eds-react @expedia/eds-tokens # Import CSS tokens globally import '@expedia/eds-tokens/css/tokens.css'; # For CSS-in-JS (styled-components / emotion) import { tokens } from '@expedia/eds-tokens';

React Component Usage

import { Button, Input, Modal, PropertyCard, Alert, Badge, Tabs, DatePicker } from '@expedia/eds-react'; // Button with all props <Button variant="primary" // primary | secondary | brand | ghost | danger | link size="md" // xs | sm | md | lg | xl loading={false} disabled={false} iconLeft={<SearchIcon />} fullWidth={false} onClick={handler} > Book Now </Button> // PropertyCard <PropertyCard name="The Grand Manhattan" location="Midtown East, New York" price={189} currency="USD" rating={4.8} reviewCount={2341} imageUrl="..." badges={['free-cancel', 'breakfast']} onWishlist={handleWishlist} />

Theming & Customization

// theme.ts — Override tokens per brand export const hotelsDotComTheme = { colors: { primary: '#C21E0F', // Hotels.com red primaryHover: '#A01A0C', brandAccent: '#FFD200' } }; // Wrap app in ThemeProvider <EDSThemeProvider theme={hotelsDotComTheme}> <App /> </EDSThemeProvider>

CSS Custom Properties Direct Usage

/* Using tokens in custom CSS */ .my-custom-component { background: var(--bg-primary); color: var(--text-primary); border: 1px solid var(--border-default); border-radius: var(--radius-lg); padding: var(--sp-4) var(--sp-6); font-family: var(--font-body); font-size: var(--text-sm); box-shadow: var(--shadow-sm); transition: all var(--dur-base) var(--ease-out); }

Accessibility Checklist

All interactive elements have visible focus rings (min 2px, 2px offset)
All images have meaningful alt text; decorative images use alt=""
Color contrast meets WCAG AA: 4.5:1 body, 3:1 large text, 3:1 UI components
All form inputs have associated labels (not just placeholder text)
Error messages are announced via aria-live, not just visible
Touch targets min 44×44px on mobile (WCAG 2.5.8)
Animations respect prefers-reduced-motion media query
Keyboard navigation works for all interactive states including modals (focus trap)

Contribution Guide

To propose a new component or token change:

  1. Open an RFC in the EDS GitHub repo describing the use case and why existing components don't solve it.
  2. Design review — Figma prototype required with all states, responsive behavior, dark mode, and a11y annotation.
  3. Token audit — All new visual properties must use existing tokens or a new token must be proposed following the naming convention.
  4. Code review — Component must pass accessibility audit (axe), visual regression tests, and storybook coverage for all states.
  5. Approval — Requires sign-off from 1 EDS principal designer + 1 EDS principal engineer.

Figma Export

EDS 2.0 is available as a publish-ready Figma library with auto-connected tokens.

🎨 Figma Community

EDS 2.0 — Expedia Design System

A 34-component Figma library with variables connected to the EDS token structure, responsive frames, dark mode variants, and interaction prototypes.

Figma File Structure

🎨
Page 1: Foundations
Color styles (primitive + semantic), Typography styles (9 levels), Grid styles (3 breakpoints), Spacing reference, Shadow/elevation, Border radius.
🧩
Page 2: Components
All 34 components as auto-layout frames with variants for states, sizes, and dark mode. Named instances follow EDS token naming.
🌙
Page 3: Dark Mode
Full component set in dark mode using Figma Variables. Single toggle switches entire file between light/dark via variable modes.
📐
Page 4: Templates
Hotel search results, property detail page, booking flow (5 steps), checkout, confirmation email, and mobile app key screens.
Page 5: A11y Annotations
Screen reader flow annotations, focus order numbering, ARIA role labels, contrast checker results for every component.
🔑
Page 6: Token Variables
All design tokens as Figma Variables with light/dark modes. Exported via Tokens Studio plugin to JSON for dev handoff.

Figma Variable Modes

EDS 2.0 uses Figma Variables with two modes across three collections:
🎨 Colors
Modes: Light / Dark
Primitive + Semantic sets
180 variables
📏 Spacing
Modes: Default / Dense
8px base scale
10 steps
🔤 Typography
Modes: Desktop / Mobile
9 scale levels
Responsive values

Dev Handoff Setup

# 1. Install Tokens Studio Figma plugin # 2. Connect to EDS GitHub repo token.json via plugin sync # 3. Changes to Figma variables → auto-PR to token.json # 4. CI pipeline transforms tokens to CSS/JS/iOS/Android # Token transform pipeline (Style Dictionary) npx style-dictionary build --config sd.config.json # Output platforms: # ├── dist/css/tokens.css (CSS custom properties) # ├── dist/js/tokens.js (ES Module) # ├── dist/ios/EDSTokens.swift (SwiftUI) # └── dist/android/tokens.xml (Android XML)
🚀 Publish Checklist: Before publishing a new EDS version — all component stories pass visual regression (Chromatic), accessibility audit passes (axe-core, 0 violations), token JSON validates against schema, Figma library is published with changelog, release notes drafted for consuming teams, migration guide written for breaking changes.