---
version: alpha
name: Marriott Bonvoy
website: "https://www.marriott.com"
description: >-
  A photography-led hospitality booking interface anchored on a pure white canvas ("#ffffff") and near-black ink ("#1c1c1c"), with Bonvoy coral ("#ff8d6b") scoped to just two CSS variables — `--t-accent-color` and `--t-icon-color-decorative` — never the primary CTA. The system runs Swiss-721 across every size from the 12px uppercase overline to the 40px hero headline, with only weight and tracking changing the voice. The signature geometric move is the 52px pill button radius (`--t-button-border-radius: 52px`) sitting beside 16px rounded property cards, while the inverted "Find Hotels" CTA renders dark-on-dark (#1c1c1c fill, white text) — a hotel-lobby move where the chrome recedes and the destination photography carries every editorial moment.

seo:
  title: "Marriott Bonvoy Design System for React — Swiss-721, 52px pill CTAs, 18 components"
  metaDescription: "Marriott Bonvoy's hospitality design system as a DESIGN.md file. Swiss-721, near-black ink #1c1c1c, coral #ff8d6b accent, 52px pill CTAs. For React and AI tools."
  highlights:
    - "Inverted primary CTA — Find Hotels renders #1c1c1c fill with white text at 52px pill radius, the opposite of the bright-accent CTA convention"
    - "Coral as decorative scarcity — Bonvoy #ff8d6b lives in only 2 CSS variables (`--t-accent-color`, `--t-icon-color-decorative`) and 12 page occurrences, never load-bearing"
    - "Single-typeface system — Swiss-721 carries every tier from 12px uppercase overline (1.296px tracking) to 40px hero h2, only weight 400/500/700 changes"
    - "Two-radius rhythm — 52px pill on every button and 16px card corner (23 occurrences); the rest of the page is 0px right-angle"
    - "Inverted form fields — the search dropdown input renders #1c1c1c background with white foreground, mirroring the CTA so search reads as a primary action band"
  tags:
    - "Travel & Hospitality"
  lastUpdated: "2026-05-13"
  author:
    name: "Dov Azencot"
    url: "https://x.com/dovazencot"
  opening: |
    Marriott Bonvoy's homepage is built around an inversion most hospitality brands resist: the primary action button ("Find Hotels") renders dark-on-dark — #1c1c1c fill, #ffffff text, 52px pill radius — not the bright coral the brand owns. Coral (#ff8d6b) appears in only 12 page occurrences and is declared in just two CSS custom properties: `--t-accent-color` and `--t-icon-color-decorative`. The voltage is a decorative ornament, not a load-bearing CTA color. The system trusts destination photography (alternating amber sunsets, navy oceans, palm-shaded resort decks) to do the marketing work that competitors hand to colored CTAs.

    This page captures the Bonvoy chrome as a DESIGN.md file — Google Labs' open spec for machine-readable design tokens. Inside: 18 color tokens covering the inverted CTA fill, the cool-gray hairline rule (#c4c4c4), form label gray (#707070), the scarce coral accent, plus alpha-overlay scrim tokens lifted from `--t-color-scrim-100` and `--t-color-control-background-overlay`. 13 typography tokens run entirely on Swiss-721 across 12–40px with the only humanist tracking move reserved for 12px uppercase overlines at 1.296px. The radius scale resolves to two anchors — 52px pill for every button, 16px card corner appearing 23 times — and 19 components covering the dark CTA, search dropdown, property tile, vacation-rental card, points stat block, and the editorial logo-strip footer.

    Drop this file into Claude, Cursor, or any AI assistant that reads structured design tokens. The agent reproduces Marriott's hospitality discipline — inverted primary CTAs, 52px pill geometry, decorative-only accent voltage, photography-first tiles — instead of a generic travel theme. Reference tokens directly in Tailwind config or CSS variables, audit an existing hospitality storefront against this baseline, or use the file as a teaching artifact for what restraint looks like when the brand's color owner is asked to recede in favor of the destination.
  related:
    - href: "/design"
      title: "Browse all design systems"
      description: "The full directory of DESIGN.md files on shadcn.io, with live mockups for each."
    - href: "https://www.marriott.com"
      title: "Marriott Bonvoy — official site"
      description: "The global hospitality brand's booking interface — the source for this design system."
    - href: "https://github.com/google-labs-code/design.md"
      title: "The DESIGN.md specification"
      description: "Google Labs' open spec for machine-readable design system files."
  questions:
    - id: "primary-color"
      title: "What is Marriott Bonvoy's primary brand color?"
      answer: "Marriott's load-bearing color is not the coral most associate with Bonvoy — it is the near-black ink #1c1c1c, declared in 18 CSS custom properties including `--t-button-primary-bg-color`, `--t-brand-fg-color`, `--t-interactive-accent-color`, and `--t-link-text-color`, with 757 total occurrences across text, borders, and the inverted CTA fill. The Bonvoy coral #ff8d6b lives only in `--t-accent-color` and `--t-icon-color-decorative`, with just 12 total page occurrences — a deliberately scarce decorative voltage. The dominant contrast is dark ink (#1c1c1c, 757 occurrences) against pure white (#ffffff, 828 occurrences) — a near-monochrome chrome that lets destination photography carry every brand moment."
    - id: "typography"
      title: "What typography does Marriott use, and what should I use if Swiss-721 is unavailable?"
      answer: "The site runs Swiss-721 across every tier from 12px uppercase overlines to the 40px hero h2 — there is no display family separate from text. Weight 400 carries inline links, 500 carries nav and body, and 700 carries every heading and CTA. The only tracking departure from `normal` is the 12px uppercase overline at 1.296px (and a sibling label at 1.2px). If Swiss-721 is unavailable, Helvetica Now or Inter at weight 400/500/700 are the closest open-source substitutes; Akzidenz-Grotesk is a closer historical match but is a licensed face. Never substitute Roboto or Open Sans — both are humanist grotesques and will shift the brand from Swiss-modernist hospitality to generic SaaS."
    - id: "inverted-cta"
      title: "Why is the primary CTA dark instead of using the Bonvoy coral?"
      answer: "The Find Hotels CTA renders #1c1c1c fill, #ffffff text, at 52px pill radius and 18px / 700 Swiss-721 — the opposite of the bright-accent CTA convention used by Booking, Expedia, and Airbnb. Marriott treats coral #ff8d6b as a decorative ornament, not a load-bearing action color, so it appears in icon strokes and small accent moments rather than on buttons. The dark CTA reads as hotel-lobby restraint: confident enough to stay quiet while destination photography (amber sunsets, palm decks, navy oceans) carries the marketing voltage. Reproducing this without the photography assets will under-perform — the inversion only works when the surrounding imagery is doing the persuasion."
    - id: "radii"
      title: "What is Marriott's corner-radius philosophy?"
      answer: "Two anchors. Every button — primary, secondary, tertiary — resolves to a 52px pill via `--t-button-border-radius: 52px`, which at typical button heights produces a fully rounded capsule. Property tiles and vacation-rental cards sit at 16px (23 occurrences in the extraction) with a 14px sibling (20 occurrences) for inset image plates. The remaining 15px / 22px / 50% values are scoped to micro-elements (avatar dots, search-suggest pills). The pill-and-card combination is the brand's geometric signature; copying the system without preserving the 52px button radius loses the hotel-lobby cadence and reads as a generic SaaS card grid."
    - id: "use-in-project"
      title: "Can I use this DESIGN.md to build my own React hospitality site?"
      answer: "Yes — the file is structured to feed into Claude, Cursor, or any AI tool that reads design tokens. The agent reproduces Marriott's hospitality discipline (inverted CTA, 52px pill buttons, 16px card corners, Swiss-721 grotesque, decorative-only coral accent) rather than a generic travel theme. Every color, type style, radius, and spacing value is a quoted token you can paste into Tailwind config, CSS variables, or your own component library. The 52px pill radius is preserved literally — substituting 9999px will render visually identical at 52px button heights but breaks the token-trace audit if you later ladder buttons taller than 52px."
    - id: "known-gaps"
      title: "What's missing from this DESIGN.md spec?"
      answer: "Several items documented in the Known Gaps section. The signed-in Bonvoy member dashboard (points-balance hero, stay-history calendar, status-tier badges) is gated behind authentication and not captured. Property-detail pages (room-type stepper, rate-comparison grid, amenity matrix) live one click below the homepage and were not extracted. Marriott's sub-brand wordmarks — Ritz-Carlton, St. Regis, JW, Edition, Westin, W, Sheraton, Aloft — each carry typographic overrides on their property pages; only the parent Bonvoy chrome is captured here. Motion (the destination-tile carousel auto-advance, search-dropdown reveal) and the mobile booking widget collapse are undocumented."

colors:
  primary: "#1c1c1c"
  primary-on-light: "#1c1c1c"
  ink: "#1c1c1c"
  ink-overlay: "#1c1c1c"
  surface-control-dark: "#1c1c1c"
  canvas: "#ffffff"
  surface-card: "#ffffff"
  on-primary: "#ffffff"
  on-dark: "#ffffff"
  scrim-overlay: "#000000"
  shadow-base: "#000000"
  ink-muted: "#707070"
  form-label: "#707070"
  hairline: "#c4c4c4"
  border-rule: "#c4c4c4"
  surface-soft: "#eeeeee"
  icon-button-fill: "#eeeeee"
  accent-coral: "#ff8d6b"
  accent-icon: "#ff8d6b"
  carousel-blue: "#007aff"
  error: "#d0021b"

typography:
  display-hero:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 40px
    fontWeight: 700
    lineHeight: 1.15
    letterSpacing: 0
  heading-xl:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 29px
    fontWeight: 700
    lineHeight: 1.2
    letterSpacing: 0
  heading-lg:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 22px
    fontWeight: 700
    lineHeight: 1.2
    letterSpacing: 0
  heading-md:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 18px
    fontWeight: 700
    lineHeight: 1.25
    letterSpacing: 0
  heading-sm:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 700
    lineHeight: 1.375
    letterSpacing: 0
  input-display:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 22px
    fontWeight: 400
    lineHeight: 1.09
    letterSpacing: 0
  body-md:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 16px
    fontWeight: 500
    lineHeight: 1.375
    letterSpacing: 0
  body-sm:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 14px
    fontWeight: 500
    lineHeight: 1.5
    letterSpacing: 0
  caption:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 12px
    fontWeight: 500
    lineHeight: 1.5
    letterSpacing: 0
  overline-md:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 12px
    fontWeight: 500
    lineHeight: 1.33
    letterSpacing: "1.296px"
    textTransform: uppercase
  overline-sm:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 12px
    fontWeight: 700
    lineHeight: 1.0
    letterSpacing: "1.2px"
    textTransform: uppercase
  button-primary:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 18px
    fontWeight: 700
    lineHeight: 1.33
    letterSpacing: 0
  nav-link:
    fontFamily: "Swiss-721, Helvetica, Arial, sans-serif"
    fontSize: 14px
    fontWeight: 400
    lineHeight: 1.14
    letterSpacing: 0

rounded:
  none: "0px"
  card-inset: "14px"
  card-md: "15px"
  card-lg: "16px"
  pill-md: "22px"
  pill-cta: "52px"
  full: "9999px"

spacing:
  xxs: "4px"
  xs: "8px"
  sm: "12px"
  base: "16px"
  md: "24px"
  lg: "32px"
  xl: "40px"
  xxl: "52px"

components:
  button-primary:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    borderColor: "{colors.primary}"
    typography: "{typography.button-primary}"
    rounded: "{rounded.pill-cta}"
    padding: "0px 24px"
    height: "52px"
    border: "1px solid {colors.primary}"
  button-primary-hover:
    backgroundColor: "{colors.primary}"
    textColor: "{colors.on-primary}"
    opacity: "0.92"
    rounded: "{rounded.pill-cta}"
  button-secondary:
    backgroundColor: "transparent"
    textColor: "{colors.ink}"
    borderColor: "{colors.ink}"
    typography: "{typography.button-primary}"
    rounded: "{rounded.pill-cta}"
    padding: "0px 24px"
    height: "52px"
    border: "1px solid {colors.ink}"
  button-secondary-hover:
    backgroundColor: "{colors.ink}"
    textColor: "{colors.on-dark}"
    borderColor: "{colors.ink}"
    rounded: "{rounded.pill-cta}"
  button-tertiary-text:
    backgroundColor: "transparent"
    textColor: "{colors.ink}"
    typography: "{typography.body-sm}"
    rounded: "{rounded.none}"
    border: "0"
  top-nav:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink}"
    typography: "{typography.nav-link}"
    height: "64px"
    padding: "0px 24px"
  nav-link:
    backgroundColor: "transparent"
    textColor: "{colors.on-dark}"
    typography: "{typography.nav-link}"
    padding: "4px 0px"
  search-input-dropdown:
    backgroundColor: "{colors.surface-control-dark}"
    textColor: "{colors.on-dark}"
    borderColor: "{colors.ink}"
    typography: "{typography.input-display}"
    rounded: "{rounded.none}"
    padding: "0px 24px 0px 0px"
    height: "52px"
    border: "0"
  text-input:
    backgroundColor: "{colors.canvas}"
    textColor: "{colors.ink}"
    borderColor: "{colors.hairline}"
    typography: "{typography.body-md}"
    rounded: "{rounded.card-inset}"
    padding: "16px 16px"
    height: "52px"
    border: "1px solid {colors.hairline}"
  form-label:
    backgroundColor: "transparent"
    textColor: "{colors.form-label}"
    typography: "{typography.overline-sm}"
    padding: "0px"
    border: "0"
  hero-banner:
    backgroundColor: "{colors.ink}"
    textColor: "{colors.on-dark}"
    typography: "{typography.display-hero}"
    rounded: "{rounded.none}"
    padding: "32px 24px"
    border: "0"
  destination-tile:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.ink}"
    borderColor: "{colors.hairline}"
    typography: "{typography.heading-md}"
    rounded: "{rounded.card-lg}"
    padding: "16px"
    border: "0"
  property-card:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.ink}"
    borderColor: "{colors.hairline}"
    typography: "{typography.body-md}"
    rounded: "{rounded.card-lg}"
    padding: "24px 0px 24px 24px"
    border: "1px solid {colors.hairline}"
  vacation-rental-card:
    backgroundColor: "{colors.surface-card}"
    textColor: "{colors.ink}"
    typography: "{typography.heading-md}"
    rounded: "{rounded.card-lg}"
    padding: "16px"
    border: "0"
  rate-stat-block:
    backgroundColor: "transparent"
    textColor: "{colors.ink}"
    typography: "{typography.heading-xl}"
    rounded: "{rounded.none}"
    padding: "8px 0px"
    border: "0"
  overline-tag:
    backgroundColor: "transparent"
    textColor: "{colors.ink-muted}"
    typography: "{typography.overline-md}"
    padding: "0px"
    border: "0"
  brand-strip-logo:
    backgroundColor: "transparent"
    textColor: "{colors.ink}"
    typography: "{typography.caption}"
    rounded: "{rounded.none}"
    padding: "8px 16px"
    border: "0"
  divider-rule:
    backgroundColor: "{colors.hairline}"
    textColor: "{colors.ink}"
    rounded: "{rounded.none}"
    padding: "0"
    height: "1px"
    border: "0"
  icon-button-circle:
    backgroundColor: "{colors.surface-soft}"
    textColor: "{colors.ink}"
    rounded: "{rounded.full}"
    height: "40px"
    padding: "0"
    border: "0"
  carousel-dot-active:
    backgroundColor: "{colors.carousel-blue}"
    textColor: "{colors.on-dark}"
    rounded: "{rounded.full}"
    height: "8px"
    padding: "0"
    border: "0"
---

## Overview

Marriott Bonvoy's homepage is an inversion of the hospitality-booking convention. **Inverted primary**: the load-bearing CTA ("Find Hotels") renders #1c1c1c fill with #ffffff text at 52px pill radius (`{rounded.pill-cta}`) and 18px / 700 Swiss-721 — the opposite of the bright-accent CTAs Booking, Expedia, and Airbnb use to anchor their search bars. The coral that most people associate with Bonvoy (`{colors.accent-coral}` — #ff8d6b) is scoped to just two CSS custom properties — `--t-accent-color` and `--t-icon-color-decorative` — and renders only 12 times across the page, used as small icon strokes and decorative ornaments rather than on any button surface.

Type runs **Swiss-721** for everything — display, body, navigation, captions, microcopy. There is no separate display family. The variable comes from three weight steps (400, 500, 700) and one tracking departure: the 12px uppercase overline at `letterSpacing: 1.296px` (the next-most-tracked label sits at 1.2px). The hero h2 at 40px / 700 ("Explore the Beauty of Spring with SIXT") works because the photography behind it — sunset desert highway, woman driving with hair in the wind — is doing the persuasion. The chrome stays quiet.

The geometric language resolves to **two corner anchors**. Every button — primary, secondary, tertiary — uses the 52px pill (`{rounded.pill-cta}`) declared as `--t-button-border-radius`. Cards and tiles sit at 16px (23 occurrences) with a 14px sibling (20 occurrences) for inset image plates inside cards. Where most travel marketplaces lean on rounded-rectangle CTAs at 8–12px, Marriott picks a fully-capsule pill and pairs it with squarer 14–16px cards — the contrast reads as hotel-lobby signage paired with editorial property tiles.

**Key Characteristics:**
- Inverted primary CTA: `{component.button-primary}` is #1c1c1c fill, white text — declared by `--t-button-primary-bg-color: #1c1c1c` and used across "Find Hotels", "Book Now", "Search Rates".
- Single-typeface system: Swiss-721 carries every tier; weight 400/500/700 and tracking (normal, 1.2px, 1.296px) are the only voice levers.
- Scarcity coral: `{colors.accent-coral}` (#ff8d6b) appears in 12 page occurrences as decorative icon strokes — never as a CTA background, never as link text.
- Two-radius rhythm: 52px pill on every button, 16px card corner across destination tiles, property cards, and vacation-rental tiles.
- Inverted search dropdown: `{component.search-input-dropdown}` uses #1c1c1c background with #ffffff foreground — the search field reads as a primary action band rather than a passive form input.
- Hairline-led rules: a single 1px #c4c4c4 line (`--t-horizontal-vertical-rule`) carries every section separator and form-field underline — no shadow, no card border, no gradient.
- Photography-first tiles: destination cards present a full-bleed image with a 16px corner, a 16px label band beneath, no overlay text, no shadow — the image alone carries the visual weight.
- 16px base spacing rhythm: 23 occurrences of 16px gaps, 19 of 8px, 17 of 4px; section bands run 32px vertical, generous-but-tight for a marketplace that wants density per scroll.

## Colors

### Brand & Accent
- **Accent Coral** (`{colors.accent-coral}` — #ff8d6b): frequency 12. Used as text (6), border (6). Declared in `--t-accent-color` and `--t-icon-color-decorative`. The Bonvoy voltage — scoped to icon strokes and small ornament moments, never a CTA background.
- **Accent Icon** (`{colors.accent-icon}` — #ff8d6b): same hex, semantic alias for icon-color-decorative usage in the points-icon, the Bonvoy ribbon glyph, and the rate-promo asterisk.

### Surface
- **Canvas** (`{colors.canvas}` — #ffffff): frequency 828. Used as text-on-dark (405), border (403), gradient (10), background (10). The dominant surface — the homepage is 80%+ white, with `--t-brand-bg-color` declared as pure white globally.
- **Surface Card** (`{colors.surface-card}` — #ffffff): same hex, semantic alias for the destination tile, property card, and vacation-rental tile base.
- **Surface Soft** (`{colors.surface-soft}` — #eeeeee): frequency 3. Used as background (1), border (2). Scoped to `--t-icon-btn-focus-bg-color` and `--t-icon-btn-primary-bg-color` — the circular icon-button rest state.
- **On Primary / On Dark** (`{colors.on-primary}` / `{colors.on-dark}` — #ffffff): white text on every dark surface — the inverted CTA, the search dropdown input, the hero overlay text.

### Ink & Surface-Control
- **Primary / Ink** (`{colors.primary}` — #1c1c1c): frequency 757. Used as text (366), border (356), background (35). Declared in 18 CSS variables including `--t-button-primary-bg-color`, `--t-brand-fg-color`, `--t-interactive-accent-color`, `--t-link-text-color`. The load-bearing color of the system — not coral.
- **Surface Control Dark** (`{colors.surface-control-dark}` — #1c1c1c): same hex, semantic alias for `--t-color-control-background` — the dark fill of the search input dropdown and the inverted CTA backplate.
- **Ink Overlay** (`{colors.ink-overlay}` — #1c1c1c): same hex, semantic alias for the 52% scrim declared at `--t-color-control-background-overlay: rgba(28,28,28,.52)` — applied as a dark wash over hero photography to keep white headlines readable.

### Hairlines & Borders
- **Hairline** (`{colors.hairline}` — #c4c4c4): frequency 71. Used as text (33), border (33), gradient (5). Declared in `--t-horizontal-vertical-rule` — the single hairline tone for section separators, form-field underlines, and card 1px borders.
- **Border Rule** (`{colors.border-rule}` — #c4c4c4): same hex, semantic alias for the divider-rule component.

### Text
- **Ink Muted** (`{colors.ink-muted}` — #707070): frequency 64. Used as text (32), border (32). Declared in `--t-form-label-color`, `--t-brand-alt-color`, `--t-overline-normal-color`. Form labels, overline meta text, "View all" links.
- **Form Label** (`{colors.form-label}` — #707070): same hex, semantic alias for the uppercase 12px form-label component above input fields.

### Scrim & Shadow
- **Scrim Overlay** (`{colors.scrim-overlay}` — #000000): frequency 40. Used as shadow (14), gradient (22), text (2), border (2). The black-base for the 52% dark scrim wash applied over hero photography, declared as `rgba(28,28,28,.52)` at render time.
- **Shadow Base** (`{colors.shadow-base}` — #000000): same hex, semantic alias for the rare drop-shadow on dropdown menus (`--t-icon-btn-hover-bg-color` resolves to pure black).

### Semantic
- **Error** (`{colors.error}` — #d0021b): zero page occurrences in the captured surfaces. Declared in `--t-form-error-color`; reserved for form-validation messages on the booking flow.
- **Carousel Blue** (`{colors.carousel-blue}` — #007aff): zero page occurrences. Declared in `--swiper-theme-color`; reserved for active-dot color in the destination-tile carousel. Not part of the brand voltage — it inherits from the Swiper.js default.

## Typography

### Font Family
The system runs **Swiss-721** for everything — display, body, navigation, captions, microcopy. The CSS declares it as `--t-title-font-family`, `--t-font-family`, and `--t-base-font-family`, all pointing at the same family. Fallbacks walk `Helvetica, Arial, sans-serif`. There is no separate display face; the variable comes from weight and tracking, not from family swap.

### Hierarchy

| Token | Size | Weight | Line Height | Letter Spacing | Use |
|---|---|---|---|---|---|
| `{typography.display-hero}` | 40px | 700 | 1.15 | 0 | Hero h2 ("Explore the Beauty of Spring with SIXT") over destination photography |
| `{typography.heading-xl}` | 29px | 700 | 1.2 | 0 | Section heads ("Get Away, Get More", "Vacation Home Rentals") |
| `{typography.heading-lg}` | 22px | 700 | 1.2 | 0 | Destination-tile headlines, property-card titles |
| `{typography.input-display}` | 22px | 400 | 1.09 | 0 | The search dropdown input value at rest |
| `{typography.heading-md}` | 18px | 700 | 1.25 | 0 | Sub-section heads, "Best Rates" card title |
| `{typography.heading-sm}` | 16px | 700 | 1.375 | 0 | Card meta strong labels, "Discover" link emphasis |
| `{typography.body-md}` | 16px | 500 | 1.375 | 0 | Default running-text inside body bands and card descriptions |
| `{typography.button-primary}` | 18px | 700 | 1.33 | 0 | Primary CTA button labels ("Find Hotels", "Book Now") |
| `{typography.body-sm}` | 14px | 500 | 1.5 | 0 | Card meta lines, dates, "Member rates from" prefixes |
| `{typography.nav-link}` | 14px | 400 | 1.14 | 0 | Top-nav labels (Book, Shop, My Trips, Find a Reservation) |
| `{typography.caption}` | 12px | 500 | 1.5 | 0 | Footer copyright, micro-help text, brand-strip captions |
| `{typography.overline-md}` | 12px | 500 | 1.33 | 1.296px (uppercase) | Section overlines ("OUR DESTINATIONS", "MEMBER BENEFITS") |
| `{typography.overline-sm}` | 12px | 700 | 1.0 | 1.2px (uppercase) | Form labels above input fields ("DESTINATION", "CHECK-IN") |

### Principles
**Weight as voice**: Marriott runs only three weights — 400, 500, 700 — and skips the 600 that most type ladders include. The result is a visible step from body (500) to heading (700) with no soft middle tier. Where most marketplaces use a 500/600/700 ladder for hierarchical comfort, Marriott picks the contrast move — body recedes, headings declare.

**Tracking as overline**: the only place tracking departs from `normal` is the 12px uppercase overline at 1.296px (`{typography.overline-md}`) and the 12px form label at 1.2px (`{typography.overline-sm}`). Both function as small-caps substitutes — the Swiss-721 grotesque doesn't ship a small-caps cut, so tracking carries the typographic role that a serif system would hand to small caps.

### Note on Font Substitutes
If Swiss-721 is unavailable, **Helvetica Now** is the closest licensed match (it's the contemporary Swiss-721 sibling) and **Inter** at weight 400/500/700 is the closest open-source substitute. Akzidenz-Grotesk is a closer historical match but is a licensed face. Never substitute Roboto or Open Sans — both are humanist grotesques and will shift the brand from Swiss-modernist hospitality to generic SaaS.

## Layout

### Spacing System
- **Base unit:** 4px (with 8px micro-step).
- **Tokens:** `{spacing.xxs}` 4px · `{spacing.xs}` 8px · `{spacing.sm}` 12px · `{spacing.base}` 16px · `{spacing.md}` 24px · `{spacing.lg}` 32px · `{spacing.xl}` 40px · `{spacing.xxl}` 52px.
- **Dominant rhythm:** 16px (23 occurrences) for card internal padding and inter-tile gutters; 8px (19 occurrences) for inline element gaps; 4px (17 occurrences) for chip and tag micro-padding.
- **Property-card padding:** the asymmetric `24px 0px 24px 24px` (11 occurrences in the extraction) — top-bottom-left padding on the content panel, with the right edge flush so the image plate can run edge-to-edge inside the card's 16px rounded clip.

### Grid & Container
- **Max content width:** the homepage centers a ~1280px container with full-bleed hero photography behind it; the hero h2 and search dropdown sit on a 770px reading column inside the 1440px viewport.
- **Destination-tile grid:** 4-column at desktop with a 16px gutter; each cell holds a full-bleed photo, a 22px h3 destination label, and a single-line rate caption.
- **Property-card grid:** 3-up at desktop, 2-up at tablet, 1-up at mobile; the asymmetric card padding (24px on three sides, 0px right) keeps the rounded photo plate visually connected to the card edge.
- **Vacation-rental rail:** horizontal scroll with 3 tiles visible above the fold; each tile carries a 16px rounded photo, a 22px destination name, and a "from $X / night" line.

### Whitespace Philosophy
Marriott runs 32px section bands (10 occurrences) between major content rails — tighter than the 64–80px most SaaS marketing pages use, but wider than the 16–24px most marketplace listing pages use. The result is a hybrid: the homepage reads like editorial (generous between sections) but the property grids inside each section read like a marketplace (dense, with 16px gutters).

## Elevation & Depth

The system has **no shadow tier**. Depth comes from three moves:

- **Inversion** — the dark CTA (`{component.button-primary}`) on a white canvas reads as elevated through pure tonal contrast.
- **Hairline borders** — 1px `{colors.hairline}` rules separate sections and underline form fields, doing the work that drop shadows handle in shadow-heavy systems.
- **Photography overlay** — hero bands apply a 52% `{colors.ink-overlay}` scrim wash (`--t-color-control-background-overlay: rgba(28,28,28,.52)`) over destination photography so that white headlines (`{typography.display-hero}` at 40px / 700) remain readable. The scrim is the only "elevation" device in the homepage chrome.

There is essentially no `box-shadow` on cards, on buttons, or on dropdowns. The single shadow-base hex (`{colors.shadow-base}` — #000000, 14 shadow occurrences) is reserved for the icon-button hover state (`--t-icon-btn-hover-bg-color` resolves to pure black), which is a fill, not a shadow.

## Shapes

The corner-radius scale resolves to **two anchors and a pill**:

- **0px** (`{rounded.none}`): the hero band, the search dropdown input, every divider rule, the brand-strip footer logo cells.
- **14px** (`{rounded.card-inset}`): inset image plates inside cards (20 occurrences) — when a property card holds a rounded photo within a larger rounded card edge.
- **15–16px** (`{rounded.card-md}`, `{rounded.card-lg}`): the dominant card corner — 23 occurrences of 16px on destination tiles, vacation-rental tiles, and the "Best Rates" card; 7 occurrences of 15px on micro-card variants.
- **22px** (`{rounded.pill-md}`): the secondary-pill corner on small chip buttons (2 occurrences).
- **52px** (`{rounded.pill-cta}`): the brand's signature — every CTA button via `--t-button-border-radius: 52px`. At typical button heights (44–52px), this renders as a fully-rounded capsule.
- **9999px** (`{rounded.full}`): avatar dots, the circular icon buttons, the carousel-dot indicators.

The 14/16/52 ladder is the system's typographic geometry — squarer cards, fully pill buttons, with the rest of the page held at right-angle 0px corners.

## Components

### Buttons

**`button-primary`** — #1c1c1c fill, white text, 52px pill radius, 0×24px padding, 52px height, 18px / 700 Swiss-721. The most common CTA across the site: "Find Hotels", "Book Now", "Search Rates", "View Hotel". The inverted move is load-bearing — copying this token onto a light-coral background defeats the brand's restraint.

**`button-primary-hover`** — same dark fill, 92% opacity. No transform, no shadow change, no color shift.

**`button-secondary`** — Transparent fill with #1c1c1c text and a 1px #1c1c1c outline. 52px pill radius. Used for "Cancel", "Continue browsing", and inverse CTAs on dark surfaces.

**`button-secondary-hover`** — flips to a #1c1c1c fill with white text — the same dark look as `{component.button-primary}` but reached through state, not default.

**`button-tertiary-text`** — Plain ink text, no surface, no border. Underlined on hover. Used for "Show more" and "View all" links in card rails.

### Navigation

**`top-nav`** — White surface, 64px height, 0×24px horizontal padding. The Marriott Bonvoy wordmark sits flush left, the four top-level utility links (Book, Shop, My Trips, Find a Reservation) sit center-right, and the sign-in / register dropdown sits flush right. No bottom border at rest; a 1px `{colors.hairline}` rule appears on scroll.

**`nav-link`** — 14px / 400 Swiss-721 in ink (or white on dark backgrounds). 4px vertical padding. Active state is underline-only, no color shift.

### Search

**`search-input-dropdown`** — The signature inverted form field. #1c1c1c background, #ffffff text, 22px / 500 Swiss-721, 52px height. The "Where to?" combobox sits at the center of the hero photo band — the dark fill on top of dimmed destination photography is the visual moment that signals "you are about to book a hotel."

**`text-input`** — White fill, 1px `{colors.hairline}` outline, 14px rounded corner, 52px height, 16×16px padding. Used inside the booking-detail accordion on property pages. Stacked above with a `{component.form-label}` in `{typography.overline-sm}`.

**`form-label`** — Uppercase 12px / 700 Swiss-721 in #707070, 1.2px tracking. The grotesque-doesn't-ship-small-caps move — tracking carries the small-caps role.

### Hero

**`hero-banner`** — #1c1c1c surface (visually muted via 52% `{colors.ink-overlay}` scrim over destination photography), white text, 0px corners, 32×24px padding. Holds the hero h2 (`{typography.display-hero}` — 40px / 700) and a one-line tagline beneath. No CTA inside the hero band — the search dropdown carries the action.

### Tiles & Cards

**`destination-tile`** — White card surface, 16px `{rounded.card-lg}` corner, 16px internal padding. Full-bleed photo above, a single-line `{typography.heading-md}` destination label below, no shadow, no border. Used in the "Ready When You Are" and "Get Away, Get More" rails.

**`property-card`** — White surface, 16px rounded corner, 1px `{colors.hairline}` border, asymmetric `24px 0px 24px 24px` padding. The right edge runs flush so the image plate inside (rounded at 14px via `{rounded.card-inset}`) reaches the card's 16px outer corner — a 2px corner-stack visible at the photo edge. Used for the featured property tiles ("The Best Rates Are Always Here").

**`vacation-rental-card`** — Similar to property card but without the 1px border — the photo plate carries the visual edge. Used in the "Vacation Home Rentals" horizontal scroll rail.

**`rate-stat-block`** — Plain text, no surface — a 29px / 700 rate number ("$199") above a 12px overline label ("AVG NIGHTLY"). Used inside the "Best Rates Are Always Here" card.

**`overline-tag`** — Uppercase 12px / 500 Swiss-721 at 1.296px tracking, #707070. The category label above section heads — "OUR DESTINATIONS", "MEMBER BENEFITS".

**`brand-strip-logo`** — A footer band cell holding a sub-brand wordmark (Ritz-Carlton, JW Marriott, Westin, etc.) at `{typography.caption}`. 8×16px padding, no border, no surface — the wordmarks rest directly on the white canvas.

**`divider-rule`** — A 1px `{colors.hairline}` line. Section separator, form-field underline, footer column splitter. The single elevation alternative in the system.

**`icon-button-circle`** — A 40×40px circular button at `{rounded.full}` with a #eeeeee fill — the only place `{colors.surface-soft}` appears. Used for the search-suggest close icon, the carousel control arrows, and the dropdown caret triggers.

**`carousel-dot-active`** — The Swiper.js inherited carousel indicator at #007aff. Sits in the destination-tile rail beneath the photo strip. Not part of the brand voltage — it inherits from the library default and was not overridden.

## Do's and Don'ts

**Do** use #1c1c1c (`{colors.primary}`) on every primary CTA background. The dark-on-white inversion is the brand's load-bearing chrome move. Switching this to coral (`{colors.accent-coral}`) reads as a generic travel marketplace, not Marriott.

**Do** preserve the 52px pill radius (`{rounded.pill-cta}`) on every button regardless of size. At small buttons (32–40px height), 52px renders as fully rounded; at 52px height the corner reaches the height itself. Substituting `{rounded.full}` (9999px) is visually identical but breaks the token-trace audit.

**Do** scope the coral accent (`{colors.accent-coral}` — #ff8d6b) to icon strokes and decorative ornaments only. It is declared in only two CSS variables (`--t-accent-color`, `--t-icon-color-decorative`) — keep that semantic boundary in your component code.

**Do** use uppercase overlines (`{typography.overline-md}`, `{typography.overline-sm}`) with their respective tracking values (1.296px and 1.2px). The tracking is the small-caps substitute — without it, the overlines collapse into ordinary 12px captions.

**Don't** use `{colors.accent-coral}` as a button background. It has 0 background occurrences in the extracted CSS — every coral instance is a `text` or `border` color. For a CTA, use `{colors.primary}` (#1c1c1c).

**Don't** use `{colors.carousel-blue}` (#007aff) anywhere outside the destination-tile carousel dots. It is inherited from `--swiper-theme-color` and is not a Marriott brand color — putting it on a link or button breaks the monochrome chrome.

**Don't** add a `box-shadow` on cards, buttons, or dropdowns. The system runs zero shadow tiers — depth comes from the dark CTA on white canvas, 1px `{colors.hairline}` rules, and the 52% ink overlay (`{colors.ink-overlay}`) over hero photography. Adding shadow reads as Material Design contamination.

**Don't** use weight 600 anywhere. The system runs only 400 / 500 / 700; the visible gap between body (500) and heading (700) is intentional. Filling that gap with 600 softens the typographic step the brand owns.

**Don't** use #c4c4c4 (`{colors.hairline}`) as a background or text fill. It is a 1px border-only token (33 border occurrences, 33 text occurrences as the same hairline glyph color on icon strokes). For a light surface fill, use `{colors.surface-soft}` (#eeeeee).

## Known Gaps

- **Authenticated dashboard**: the signed-in Bonvoy member chrome (points-balance hero, stay-history calendar, status-tier badges, member-rate strikethrough) is gated and not captured.
- **Property detail pages**: the room-type stepper, rate-comparison grid, amenity matrix, and review module live one click below the homepage; not extracted.
- **Sub-brand overrides**: Ritz-Carlton, St. Regis, JW, Edition, Westin, W, Sheraton, and Aloft each carry typographic and color overrides on their dedicated property pages. Only the parent Bonvoy chrome is captured.
- **Booking flow**: rate-quote, payment, and confirmation pages carry form-error states (`{colors.error}` — #d0021b) that were not visible in the homepage extraction.
- **Motion**: the destination-tile carousel auto-advance, search-dropdown reveal, and mobile booking widget collapse are undocumented.
- **Mobile breakpoint**: the mobile booking widget renders as a sticky bottom bar with a different CTA layout; only the desktop chrome at 1440px is captured here.
