/* ==========================================================================
   Euromonitor homepage takeover — block styles
   --------------------------------------------------------------------------
   Every selector is namespaced `hp-` so nothing can leak into, or be
   overridden by, the host Optimizely site's Bootstrap 5 styles. It also keeps
   this page completely separate from the Passport landing page, which uses
   `pp-`.
   Design tokens are mirrored from Figma file "EMI website" page 10204:10139,
   desktop frame 13488:18776 and mobile frame 13631:24595.
   ========================================================================== */

.hp-block {
  /* --- brand palette (Figma: emi_*) ------------------------------------- */
  --hp-linen: #f2f2f5;
  --hp-yellow: #ff9e1b;
  --hp-yellow-hover: #f08d00;
  --hp-cyan: #00aed9;
  --hp-cyan-sat: #0fd0ff;
  /* emi_core/cyan_saturated */
  --hp-dark-cyan: #1070a3;
  /* emi_secondary/dark-cyan_saturated — the active filter pill */
  --hp-royal-blue: #1e22aa;
  --hp-royal-blue-sat: #0006c8;
  /* emi_secondary/royal-blue_saturated */
  --hp-periwinkle: #8394f2;
  --hp-pink: #f73081;
  /* Frosted tint used behind icons and chips (Figma: cyan_saturated @ 10%). */
  --hp-tint: rgba(15, 208, 255, 0.1);

  /* --- text (Figma: text/*) --------------------------------------------- */
  --hp-ink: #222426;
  /* text/headlines/text_headline */
  --hp-body: #313335;
  /* text/body/text_body */
  --hp-ink-contrast: #f9f9fa;

  /* --- gradients --------------------------------------------------------- */
  /* Headline accent: cyan_saturated -> royal-blue_saturated. */
  --hp-grad-accent: linear-gradient(90deg, #0fd0ff 0%, #0006c8 100%);
  /* 1px hairlines between the Why Euromonitor rows. */
  --hp-grad-divider: linear-gradient(90deg, #8394f2 0%, #3c41b4 32.55%, #8c43ac 98.12%);

  /* --- shape ------------------------------------------------------------- */
  --hp-radius-xs: 4px;
  --hp-radius-sm: 8px;
  --hp-radius: 16px;
  --hp-radius-lg: 24px;
  --hp-radius-pill: 1024px;
  --hp-shadow: 0 22px 26px rgba(85, 105, 135, 0.28);

  /* --- rhythm ------------------------------------------------------------ */
  --hp-max: 1320px;
  --hp-gutter: clamp(20px, 4vw, 48px);

  /* --- type -------------------------------------------------------------- */
  /* The host site already loads Proxima Nova; `inherit` lets live typography
     win. Preview pages set --hp-font to a close substitute. */
  --hp-font: inherit;
  /* Figma token `font/button/family` is Roboto, not the heading family. */
  --hp-font-btn: Roboto, var(--hp-font);
  --hp-fs-giga: clamp(2.25rem, 1.35rem + 2.9vw, 3.625rem);
  /* 58px */
  --hp-fs-mega: clamp(2rem, 1.32rem + 2.2vw, 3.25rem);
  /* 52px */
  --hp-fs-h2: clamp(1.5rem, 1.29rem + 0.7vw, 2.0625rem);
  /* 33px */
  --hp-fs-h3: clamp(1.25rem, 1.13rem + 0.4vw, 1.625rem);
  /* 26px */
  --hp-fs-lg: 1.25rem;
  /* 20px */
  --hp-fs-md: 1.125rem;
  /* 18px */
  --hp-fs-sm: 1rem;
  /* 16px */

  position: relative;
  /* `clip` (not `hidden`) so descendant position:sticky keeps working. */
  overflow: clip;
  color: var(--hp-body);
  font-family: var(--hp-font);
  font-size: var(--hp-fs-md);
  line-height: 1.5;
  background: var(--hp-linen);
}

.hp-block *,
.hp-block *::before,
.hp-block *::after {
  box-sizing: border-box;
}

.hp-block img {
  max-width: 100%;
}

/* `:where()` contributes no specificity, so these resets clear the host site's
   UA/Bootstrap margins without outranking the `.hp-*` rules further down —
   `.hp-block p` (0,1,1) would silently beat every `.hp-card__go`-style rule. */
.hp-block :where(p) {
  margin: 0;
}

.hp-block :where(ul) {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The host footer rounds its top-right corner by 30px and the page background
   shows through the notch. The Optimizely body is white, which reads as a
   stray white triangle against our linen page, so assert the page colour.
   Literal value: custom properties are scoped to .hp-block, not to <body>. */
body:has(.hp-block) {
  background-color: #f2f2f5;
}

/* --------------------------------------------------------------------------
   Layout helpers
   -------------------------------------------------------------------------- */

.hp-container {
  width: 100%;
  max-width: calc(var(--hp-max) + var(--hp-gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--hp-gutter);
}

/* These all carry a `&nbsp;` in the markup, because Optimizely's sanitiser
   deletes any element with no content. Zeroing the font keeps the filler out
   of the layout. */
.hp-ribbon,
.hp-hero__art,
.hp-folio__art,
.hp-folio__person,
.hp-route__bar,
.hp-video__play,
.hp-dot {
  font-size: 0;
  line-height: 0;
}

/* The soft arch "ribbon" artwork that drifts behind two of the sections.
   Painted as a background rather than an <img>: Optimizely's server-side
   handler rewrites every <img src> inside a CMS block to
   `?width=1024&quality=80`, which visibly softens art this large. Backgrounds
   are left untouched by that handler.

   Every url() here is bare filename only. Relative URLs in CSS resolve against
   the stylesheet, and the stylesheet ships in the same flat folder as the
   artwork, so the whole folder can be moved or renamed without editing a line
   of this file. */
.hp-ribbon {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.hp-ribbon::before {
  content: "";
  position: absolute;
  background: url("ribbon.png") center / contain no-repeat;
  /* The artwork sits on a white ground, so `multiply` drops the ground into
     the linen page colour and no mask is needed. */
  mix-blend-mode: multiply;
}

/* Figma runs the ribbon well outside the section box so only its arcs show.
   ribbon.png is 2400x1600 with the artwork itself occupying 1702x817 at
   (276,544); these offsets put that artwork at x=1108, y=77 on a 1600 frame,
   which is where Figma draws it. */
.hp-ribbon--story::before {
    inset: -5.9% 9.1% auto auto;
    width: 45.8%;
    aspect-ratio: 2 / 2;
    opacity: 0.65;
    transform: rotate(-45deg);
    background-size: 200%;
}

/* Figma fades the arcs out as they rise towards the top of the section rather
   than cropping them against its edge.

   The fade has to sit on the container, not on the artwork: the artwork is
   rotated 45 degrees, so a mask applied there would tilt with it. The blend
   moves up with the mask because masking makes the artwork an isolated group —
   left on the child it would have nothing to multiply against. On the
   container the masked result still composites against the page, so the white
   ground drops out exactly as before, and the transparent top simply leaves
   the page colour untouched.

   The stop is a length, not a percentage: percentages would resolve against
   the section's height, which runs far past the artwork because the three
   routes sit in the same section. Figma clears the fade 200px into a 1600px
   frame, and the artwork is sized off the width too, so both scale together. */
.hp-ribbon--story {
  mix-blend-mode: multiply;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 12.5vw);
  mask-image: linear-gradient(to bottom, transparent 0, #000 12.5vw);
}

.hp-ribbon--story::before {
  mix-blend-mode: normal;
}

/* A second copy of the same artwork, anchored to the routes grid rather than
   to the section. Figma 14125:27747 keeps a ribbon on mobile but moves it: it
   no longer sits up by the intro, it sweeps behind the screen. Two elements
   rather than one overridden element, because the anchors are different boxes
   — and they are never both on, so only one ribbon is ever visible. */
.hp-ribbon--routes {
  display: none;
}

/* Upper right, alongside the heading. Anchored low it read as decoration for
   the next section rather than this one. */
/* Figma draws the artwork at 0.72x its native 4096px width, offset -635/-470
   inside the 1600px section. Percentage translate resolves against the
   element's own box, so the placement scales with the section width. */
.hp-ribbon--insights::before {
  inset: 0 auto auto 0;
  width: 184.3%;
  aspect-ratio: 3 / 2;
  transform: translate(-21.53%, -26.51%);
}

@media (max-width: 768px) {
  .hp-ribbon--insights::before {
    inset: 20% auto auto -115%;
    width: 375%;
  }
}

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */

.hp-eyebrow {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 0;
  color: var(--hp-ink);
  font-size: var(--hp-fs-md);
  font-weight: 500;
  line-height: 1.5;
}

/* Figma ships this as a 7x16 svg with a 7px dot whose centre sits 12.5px down,
   i.e. it hangs off the baseline rather than centring on the cap height. */
.hp-eyebrow::before {
  content: "";
  flex: 0 0 auto;
  width: 7px;
  height: 7px;
  margin-top: 9px;
  border-radius: 50%;
  background: var(--hp-yellow);
}

.hp-eyebrow--center {
  justify-content: center;
}

.hp-mega,
.hp-h2,
.hp-h3,
.hp-giga {
  margin: 0;
  color: var(--hp-ink);
  font-family: var(--hp-font);
  font-weight: 600;
}

.hp-giga {
  font-size: var(--hp-fs-giga);
  line-height: 1.2;
  letter-spacing: -0.02em;
}

.hp-mega {
  font-size: var(--hp-fs-mega);
  line-height: 1.2;
  /* Figma token `Display/mega` tracks -2px at 52px. */
  letter-spacing: -0.0385em;
}

.hp-h2 {
  font-size: var(--hp-fs-h2);
  line-height: 1.3;
}

.hp-h3 {
  font-size: var(--hp-fs-h3);
  line-height: 1.3;
}

/* Gradient-filled accent words, exactly as in Figma. */
.hp-accent {
  background: var(--hp-grad-accent);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}

.hp-lead {
  font-size: var(--hp-fs-lg);
  line-height: 1.5;
  color: var(--hp-ink);
}

.hp-body {
  font-size: var(--hp-fs-md);
  line-height: 1.5;
  color: var(--hp-body);
}

.hp-center {
  text-align: center;
}

/* Flips the whole type scale to the light ink for a block that sits on a dark
   panel, so the individual elements inside need no colour of their own. */
.hp-on-dark,
.hp-on-dark .hp-h2,
.hp-on-dark .hp-h3,
.hp-on-dark .hp-mega,
.hp-on-dark .hp-giga,
.hp-on-dark .hp-eyebrow,
.hp-on-dark .hp-lead,
.hp-on-dark .hp-body {
  color: var(--hp-ink-contrast);
}

/* --------------------------------------------------------------------------
   Buttons, pills, tags, dividers
   -------------------------------------------------------------------------- */

.hp-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 48px;
  padding-inline: 40px;
  border: 0;
  border-radius: var(--hp-radius-pill);
  color: var(--hp-body);
  font-family: var(--hp-font-btn);
  font-size: var(--hp-fs-md);
  font-weight: 500;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, transform 0.18s ease;
}

.hp-btn:hover {
  transform: translateY(-1px);
  text-decoration: none;
}

.hp-btn:focus-visible {
  outline: 3px solid var(--hp-royal-blue);
  outline-offset: 3px;
}

.hp-btn--primary {
  background: var(--hp-yellow);
  color: var(--hp-body);
}

.hp-btn--primary:hover {
  background: var(--hp-yellow-hover);
  color: var(--hp-body);
}

.hp-btn--outline {
  background: #fff;
  border: 2px solid var(--hp-yellow);
  color: var(--hp-body);
}

.hp-btn--outline:hover {
  background: var(--hp-yellow);
  color: var(--hp-body);
}

/* The call to action on a dark panel, where the brand yellow would vibrate. */
.hp-btn--light {
  background: var(--hp-linen);
  color: var(--hp-ink);
}

.hp-btn--light:hover {
  background: #fff;
  color: var(--hp-ink);
}

.hp-btns {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.hp-filters {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 8px;
}

.hp-filter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 29px;
  padding-inline: 16px;
  border: 1px solid var(--hp-cyan-sat);
  border-radius: var(--hp-radius-pill);
  background: transparent;
  color: var(--hp-body);
  font-family: var(--hp-font-btn);
  font-size: var(--hp-fs-sm);
  font-weight: 500;
  line-height: 1.3;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}

.hp-filter:hover {
  background: var(--hp-tint);
}

.hp-filter.is-active {
  background: var(--hp-dark-cyan);
  border-color: var(--hp-dark-cyan);
  color: var(--hp-ink-contrast);
}

.hp-filter:focus-visible {
  outline: 3px solid var(--hp-royal-blue);
  outline-offset: 2px;
}

.hp-tag {
  display: inline-flex;
  align-items: center;
  padding: 6px 10px;
  border-radius: var(--hp-radius-xs);
  background: #dfecf5;
  color: var(--hp-body);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.5;
}

.hp-divider {
  width: 100%;
  height: 1px;
  border: 0;
  margin: 0;
  opacity: 0.5;
  background: var(--hp-grad-divider);
}

/* --------------------------------------------------------------------------
   Scroll reveal. The class is applied in the markup and removed by the script
   on intersection, so a visitor with JavaScript disabled still sees content:
   the hidden state only applies once the script has flagged the page.
   -------------------------------------------------------------------------- */

.hp-js .hp-reveal {
  opacity: 0;
  transform: translate3d(0, 18px, 0);
  transition: opacity 0.6s ease var(--hp-delay, 0ms), transform 0.6s ease var(--hp-delay, 0ms);
}

.hp-js .hp-reveal.is-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {

  .hp-js .hp-reveal,
  .hp-js .hp-reveal.is-in {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ==========================================================================
   01 — Hero banner
   Figma 13402:24765 — 1600x768, content block 353 tall, vertically centred.
   ========================================================================== */

.hp-hero {
  display: flex;
  align-items: center;
  /* 768 on the 1600 frame. Past 1600 the height keeps the frame's 48% ratio so
     the loop behind it is only ever scaled, never cropped top and bottom — the
     arches need their full height for the fade along the bottom edge to land
     inside the section. Below 1600 the loop is cropped left and right instead,
     which is what the design does as the frame narrows. */
  min-height: max(768px, 48vw);
}

/* Full-bleed arch artwork. Figma puts the left edge of the pink arch at 63.63%
   of the frame; that edge is 41.27% into the artwork. Percentages in
   `background-position` resolve against (container - image), which cannot
   express that, so the art goes on a pseudo-element instead: `left` is a true
   percentage of the hero, and the transform percentage is of the art itself. */
.hp-hero__art {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.hp-hero__art::before {
  content: "";
  position: absolute;
  inset-block: 0;
  left: 63.63%;
  aspect-ratio: 2212 / 936;
  transform: translateX(-41.27%);
  background: url("hero-arches.png") center / 100% 100% no-repeat;
  mix-blend-mode: darken;
  transition: opacity 0.6s ease;
}

/* The loop is rendered at the full 1600x768 of the Figma frame, so it fills the
   hero edge to edge rather than being placed like the still. The hero holds
   that same ratio (see `.hp-hero`), so `cover` scales the loop by its height at
   every desktop width: the bottom fade is always in shot, and the pink arch
   edge stays on the design's 63.63% mark. */
.hp-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  mix-blend-mode: darken;
  opacity: 0;
  transition: opacity 0.6s ease;
}

/* Cross-faded rather than swapped, so the hero never flashes an empty frame
   while the first video frame decodes. Without JavaScript — or under reduced
   motion, or when a browser blocks autoplay — `is-playing` never lands and the
   still simply stays. */
.hp-hero__art.is-playing::before {
  opacity: 0;
}

.hp-hero__video.is-playing {
  opacity: 1;
}

.hp-hero__inner {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}

.hp-hero__title {
  max-width: 1094px;
}

.hp-hero__lead {
  /* 800px on the 1600 frame, where it clears the arches by 78px. Narrowing it
     with the viewport keeps that clearance on smaller desktops. */
  max-width: min(800px, 50vw);
}

.hp-hero__btns {
  margin-top: 16px;
}

/* ==========================================================================
   02 — Proof points
   Figma 13503:22317 + 13402:25777.
   ========================================================================== */

.hp-proof {
  padding-block: 62px 48px;
}

.hp-proof__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 40px;
}

.hp-proof__head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  max-width: 897px;
}

.hp-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  width: 100%;
}

/* One continuous gradient runs across all three cards. Each card paints the
   same image at three times its own width plus the two gaps, then shows its
   own slice of it — `left`, `center` and `right` land exactly on the three
   column offsets for any container width, so the seam is invisible. */
.hp-stat {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 200px;
  padding: 16px 24px 24px;
  border-radius: var(--hp-radius);
  background-image: linear-gradient(90deg,
      rgba(15, 208, 255, 0.5) 0%,
      rgba(0, 6, 200, 0.5) 100%);
  background-repeat: no-repeat;
  background-size: calc(300% + 48px) 100%;
}

.hp-stat--1 {
  background-position: left center;
}

.hp-stat--2 {
  background-position: center;
}

.hp-stat--3 {
  background-position: right center;
}

.hp-stat__value {
  color: var(--hp-ink);
  /* Larger than Display/mega — the Figma figures measure 64px, not 52px. */
  font-size: clamp(2.25rem, 1.4rem + 2.6vw, 4rem);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -0.0385em;
  font-variant-numeric: tabular-nums;
}

.hp-stat__label {
  margin-top: auto;
  color: var(--hp-ink);
  font-size: var(--hp-fs-lg);
  line-height: 1.5;
}

/* ==========================================================================
   03 — Client logos
   Figma 13488:18758 — a 141-tall strip.
   ========================================================================== */

.hp-logos {
  padding-block: 16px 40px;
}

.hp-logos__viewport {
  display: flex;
  width: 100%;
  overflow: hidden;
  /* Softens both ends so logos enter and leave rather than cutting off. */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
}

.hp-logos__track {
  display: flex;
  flex: 0 0 auto;
  align-items: center;
  gap: 84px;
  padding-right: 84px;
  animation: hp-marquee 40s linear infinite;
}

.hp-logos__viewport:hover .hp-logos__track {
  animation-play-state: paused;
}

.hp-logos__item {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 150px;
  height: 85px;
}

.hp-logos__item img {
  max-width: 100%;
  max-height: 72px;
  object-fit: contain;
  mix-blend-mode: multiply;
}

@media (max-width: 767.98px) {
  .hp-logos__track {
    gap: 48px;
    padding-right: 48px;
  }

  .hp-logos__item {
    width: 108px;
    height: 60px;
  }

  .hp-logos__item img {
    max-height: 44px;
  }
}

@keyframes hp-marquee {
  to {
    transform: translate3d(-100%, 0, 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .hp-logos__track {
    animation: none;
  }
}

/* ==========================================================================
   04 — Video CTA
   Figma 14125:26678 — a rounded panel on the arch artwork, holding a 536 copy
   column against a 648 media column inside the 1320 content width.
   ========================================================================== */

.hp-vcta {
  padding: clamp(48px, 6vw, 80px) clamp(16px, 2vw, 32px);
}

.hp-vcta__panel {
  position: relative;
  padding: clamp(48px, 6vw, 96px) clamp(24px, 4vw, 108px);
  border-radius: clamp(24px, 4vw, 64px);
  overflow: hidden;
  /* One flattened export from Figma: the arch artwork with the navy-to-teal
     wash already composited into it, so no blend layers are needed here. */
  background: #0c2643 url("vcta-panel.webp") center / cover no-repeat;
}

/* Once the two columns sit side by side the panel is close to the artwork's own
   2.3:1 ratio, so stretch it to the box instead of cropping — that keeps the
   whole arch composition inside the rounded corners. Below this the panel is
   portrait and `cover` is the only sensible fit. */
@media (min-width: 1200px) {
  .hp-vcta__panel {
    background-size: 100% 100%;
  }
}

/* Figma: a 536px copy column and a 648px media column. Expressed as fr so the
   ratio survives narrow viewports — fixed px tracks would shrink to the same
   width once space ran out. */
.hp-vcta__grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 536fr) minmax(0, 648fr);
  align-items: center;
  gap: clamp(40px, 6vw, 136px);
  max-width: var(--hp-max);
  margin-inline: auto;
}

.hp-vcta__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
}

/* The dot stays brand yellow here; the eyebrow's own rule already sets it, but
   spelled out so a future `.hp-on-dark` tweak cannot whiten it by accident. */
.hp-vcta .hp-eyebrow::before {
  background: var(--hp-yellow);
}

/* Only the headline carries weight in this panel — the semi-bold the design
   system defaults to reads too heavy against the dark ground. */
.hp-vcta__copy .hp-eyebrow,
.hp-vcta__copy .hp-lead {
  font-weight: 400;
}

.hp-vcta__copy .hp-btn {
  height: 64px;
  margin-top: 8px;
}

.hp-vcta__media {
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.hp-vcta__author {
  display: flex;
  align-items: center;
  gap: 16px;
}

.hp-vcta__avatar {
  flex: 0 0 auto;
  width: 72px;
  height: 72px;
  border-radius: 50%;
  object-fit: cover;
  /* Portrait source, so bias the crop towards the head rather than the middle. */
  object-position: top center;
}

.hp-vcta__byline {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.hp-vcta__byline .hp-h3,
.hp-vcta__role {
  margin: 0;
  color: var(--hp-ink-contrast);
  line-height: 1.3;
}

.hp-vcta__byline .hp-h3 {
  font-weight: 500;
}

.hp-vcta__role {
  font-size: var(--hp-fs-lg);
  font-weight: 400;
}

/* Click-to-load embed: the still frame stands in until the visitor presses
   play, at which point the provider's iframe replaces it. */
.hp-video {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--hp-radius-lg);
  overflow: hidden;
  background: #0d1b26;
}

.hp-video__poster {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hp-video__frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}

.hp-video__play {
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 72px;
  height: 72px;
  padding: 8px;
  border: 6px solid rgba(255, 255, 255, 0.4);
  border-radius: 999px;
  background: var(--hp-yellow);
  backdrop-filter: blur(4px);
  cursor: pointer;
  transition: transform 0.18s ease, background-color 0.18s ease;
}

/* Background rather than <img>: the CMS handler rasterises SVGs at their
   intrinsic size, which leaves the glyph blurry on retina screens. */
.hp-video__play::before {
  content: "";
  width: 48px;
  height: 48px;
  margin-left: 3px;
  background: url("icon-play.svg") center / contain no-repeat;
}

.hp-video__play:hover {
  transform: scale(1.07);
  background: var(--hp-yellow-hover);
}

.hp-video__play:focus-visible {
  outline: 3px solid #fff;
  outline-offset: 3px;
}

/* ==========================================================================
   05 — The Passport story
   Figma 13503:22642 — intro pt112 / pb88, then a 1320 row with an 80 gutter
   between a 512 route column and a 728 product frame.
   ========================================================================== */

/* Figma stacks an 88px intro gap and the 48px padding of the routes row, so
   the section's own bottom padding is the routes row's 48 alone. */
.hp-story {
  padding-block: 112px 48px;
}

.hp-story__intro {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding-bottom: 136px;
}

.hp-story__title {
  max-width: 1000px;
}

.hp-story__lead {
  max-width: 800px;
}

.hp-story__intro .hp-btn {
  margin-top: 16px;
}

.hp-routes {
  position: relative;
  display: grid;
  grid-template-columns: 512px minmax(0, 1fr);
  gap: 80px;
  align-items: center;
}

.hp-routes__list {
  display: flex;
  flex-direction: column;
  gap: 32px;
}

.hp-route__btn {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
}

.hp-route__btn:focus-visible {
  outline: 3px solid var(--hp-royal-blue);
  outline-offset: 4px;
}

/* The label of a closed route is the dimmed text alone; the open one gains the
   orange dot. Drawn with a pseudo-element rather than a <span>, because
   Optimizely's sanitiser deletes empty inline elements. */
.hp-route__label {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  color: var(--hp-ink);
  font-size: var(--hp-fs-md);
  font-weight: 500;
  line-height: 1.5;
  opacity: 0.5;
  transition: opacity 0.25s ease;
}

.hp-route__label::before {
  content: "";
  flex: 0 0 auto;
  width: 0;
  height: 7px;
  margin-top: 9px;
  border-radius: 50%;
  background: var(--hp-yellow);
  transition: width 0.25s ease;
}

.hp-route.is-active .hp-route__label {
  opacity: 1;
}

.hp-route.is-active .hp-route__label::before {
  width: 7px;
}

/* Closed routes collapse to nothing; `grid-template-rows` animates cleanly
   between 0fr and 1fr without needing a measured pixel height. The panel holds
   a single wrapper so the whole body sits in that one sized row — separate
   children would land in auto-sized implicit rows and never collapse. */
.hp-route__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.4s ease, margin-top 0.4s ease;
  margin-top: 0;
}

.hp-route.is-active .hp-route__panel {
  grid-template-rows: 1fr;
  margin-top: 16px;
}

.hp-route__panelinner {
  min-height: 0;
  overflow: hidden;
}

.hp-route__heading {
  transition: opacity 0.3s ease;
}

.hp-route__body {
  margin-top: 16px;
  color: var(--hp-body);
}

/* The progress rail under the open route. It fills over the dwell time and
   restarts whenever the active route changes. */
.hp-route__bar {
  position: relative;
  height: 2px;
  margin-top: 16px;
  border-radius: 999px;
  /* Figma draws the fill alone — there is no track behind it. */
  background: transparent;
}

.hp-route__bar::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 8px;
  border-radius: 999px;
  background: var(--hp-grad-accent);
}

.hp-route.is-active .hp-route__bar::after {
  animation: hp-route-bar var(--hp-route-dwell, 7s) linear forwards;
}

/* Off screen or in a background tab, the fill holds where it is rather than
   running down with nobody watching. */
.hp-routes.is-paused .hp-route.is-active .hp-route__bar::after {
  animation-play-state: paused;
}

/* Once the visitor has picked a route, auto-advance is over for good. The rail
   becomes a static marker under the open route instead of a countdown to
   something that is no longer going to happen. */
.hp-routes.is-stopped .hp-route.is-active .hp-route__bar::after {
  animation: none;
  width: 100%;
}

@keyframes hp-route-bar {
  from {
    width: 8px;
  }

  to {
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hp-route.is-active .hp-route__bar::after {
    animation: none;
    width: 100%;
  }

  .hp-route__panel {
    transition: none;
  }
}

/* The frosted product frame: Figma gives it a 0.949px periwinkle stroke, a
   22.78px radius and 14.429px of padding at 728 wide. Expressed as ratios so
   it holds its proportions when the column narrows. */
.hp-routes__stage {
  position: relative;
  aspect-ratio: 728 / 605;
  padding: 1.98%;
  border: 1px solid var(--hp-periwinkle);
  border-radius: 3.13%;
  background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(13px);
}

.hp-routes__shot {
  position: absolute;
  inset: 1.98%;
  opacity: 0;
  transition: opacity 0.45s ease;
}

.hp-routes__shot.is-active {
  opacity: 1;
}

.hp-routes__shot img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top left;
  border-radius: 2%;
}

/* ==========================================================================
   06 — The wider portfolio
   Figma 13402:26680 + 13631:24498 — 648x450 media against a 520 copy column.
   ========================================================================== */

.hp-folio {
  padding-block: 64px 0;
}

.hp-folio__intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding-bottom: 64px;
}

.hp-folio__title {
  max-width: 1094px;
}

.hp-folio__lead {
  max-width: 800px;
}

.hp-folio__row {
  display: grid;
  grid-template-columns: 648px minmax(0, 520px);
  justify-content: space-between;
  align-items: center;
  gap: 48px;
  padding-bottom: 136px;
}

.hp-folio__row--flip {
  grid-template-columns: minmax(0, 520px) 648px;
}

/* The last row butts straight onto the next section in Figma. */
.hp-folio__row:last-of-type {
  padding-bottom: 0;
}

.hp-folio__copy {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.hp-folio__cta {
  margin-top: 16px;
}

.hp-folio__media {
  position: relative;
  aspect-ratio: 648 / 450;
  border-radius: var(--hp-radius-lg);
}

/* Both media panels are decorative artwork carried on backgrounds rather than
   <img>, so Optimizely's image handler cannot downsample or re-label them. A
   div has no intrinsic size, so each one declares its own box. */
.hp-folio__art {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}

.hp-folio__media--consulting .hp-folio__art {
  background-image: url("svc-consulting-bg.png");
}

.hp-folio__media--reports .hp-folio__art {
  background-image: url("cards-bg.png");
}

/* Figma places the cut-out at 40.74% from the left, 6.89% down, 57.17% wide. */
.hp-folio__person {
  position: absolute;
  top: 6.89%;
  left: 40.74%;
  width: 57.17%;
  height: 93.56%;
  background: url("svc-consulting-person.png") bottom center / contain no-repeat;
}

/* Floating capability chips, hanging 22px off the left edge of the panel.
   Each one is a link to its own Custom Research page, so the <li> is bare and
   the chip styling lands on the <a> — the whole pill is the hit area. */
.hp-chips {
  position: absolute;
  top: 50%;
  left: -22px;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  transform: translateY(-50%);
}

.hp-chip {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px;
  padding-right: 16px;
  border-radius: 999px;
  background: #fff;
  box-shadow: 0 14px 20px rgba(85, 105, 135, 0.28);
  color: var(--hp-body);
  font-size: var(--hp-fs-sm);
  font-weight: 500;
  line-height: 1.3;
  white-space: nowrap;
  text-decoration: none;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}

.hp-chip:hover {
  color: var(--hp-body);
  text-decoration: none;
  transform: translateX(4px);
  box-shadow: 0 18px 26px rgba(85, 105, 135, 0.34);
}

.hp-chip:focus-visible {
  outline: 3px solid var(--hp-royal-blue);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .hp-chip {
    transition: none;
  }

  .hp-chip:hover {
    transform: none;
  }
}

.hp-chip__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 28px;
  height: 28px;
  border: 0.75px solid var(--hp-cyan-sat);
  border-radius: 50%;
  background: var(--hp-tint);
}

.hp-chip__icon img {
  width: 18px;
  height: 18px;
}

/* Three report covers in a straight, staggered row — Figma draws them upright
   and clear of one another, not fanned out.

   The row is wider than the panel and overhangs it on both sides: on the
   648-wide frame the first cover starts 55px before the panel's left edge and
   the last ends 49px past its right. Every offset here is a percentage, and
   the panel holds a fixed 648/450 ratio, so the whole cluster scales with it
   instead of drifting out of register as the column narrows. */
.hp-reports {
  position: absolute;
  inset: 0 -7.56% 0 -8.49%;
  display: flex;
  align-items: flex-start;
  /* 16px of the 752px row. Three equal flex items then land on the design's
     240px covers exactly. */
  gap: 2.13%;
}

.hp-report {
  flex: 1 1 0;
  border-radius: var(--hp-radius-sm);
  background: #fff;
  box-shadow: var(--hp-shadow);
  /* The cover runs to the card edge, so it needs the corners clipping. */
  overflow: hidden;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}

/* The whole card is the hit area, so the link fills it rather than wrapping
   the title alone. */
.hp-report__link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.hp-report:hover,
.hp-report:focus-within {
  transform: translateY(-4px);
  box-shadow: 0 30px 34px rgba(85, 105, 135, 0.34);
}

/* Drawn inside the card, since `overflow: hidden` would clip an outset ring. */
.hp-report__link:focus-visible {
  outline: 3px solid var(--hp-royal-blue);
  outline-offset: -3px;
}

@media (prefers-reduced-motion: reduce) {
  .hp-report {
    transition: none;
  }

  .hp-report:hover,
  .hp-report:focus-within {
    transform: none;
  }
}

/* The stagger: each cover sits 24px higher than the one before it. Percentage
   margins resolve against the row's width, which is itself a fixed multiple of
   the panel width, so the steps hold at any size. */
.hp-report--1 {
  margin-top: 16.36%;
}

.hp-report--2 {
  margin-top: 13.17%;
}

.hp-report--3 {
  margin-top: 9.98%;
}

.hp-report__img {
  display: block;
  width: 100%;
  /* 240x127.6 in Figma — wider than the 3:2 of the source photographs, which
     `cover` crops to. */
  aspect-ratio: 240 / 127.6;
  object-fit: cover;
}

.hp-report__body {
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
}

.hp-report__title {
  color: var(--hp-ink);
  font-size: var(--hp-fs-md);
  font-weight: 600;
  line-height: 1.5;
}

.hp-report__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

/* Figma outlines these rather than filling them, unlike the solid tags on the
   insight cards. */
.hp-report__tags .hp-tag {
  padding: 2px 10px;
  border: 1px solid var(--hp-cyan-sat);
  border-radius: var(--hp-radius-pill);
  background: transparent;
  font-weight: 400;
}

/* ==========================================================================
   07 — Insights
   Figma 13402:26826 — pill filters over a rail of 424-wide cards.
   ========================================================================== */

.hp-insights {
  padding-block: 128px;
}

.hp-insights__intro {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
}

.hp-insights__title {
  max-width: 1150px;
}

.hp-carousel {
  position: relative;
  padding-block: 40px;
}

.hp-carousel__track {
  display: flex;
  gap: 24px;
  /* The rail extends past the container on both sides so a card can sit
     half-visible at the edge, the way it does in the design. */
  margin-inline: calc(var(--hp-gutter) * -1);
  padding: 8px var(--hp-gutter) 32px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.hp-carousel__track::-webkit-scrollbar {
  display: none;
}

.hp-carousel__track.is-dragging {
  scroll-snap-type: none;
  cursor: grabbing;
}

.hp-carousel__track:focus-visible {
  outline: 3px solid var(--hp-royal-blue);
  outline-offset: 2px;
}

.hp-card {
  display: flex;
  flex: 0 0 424px;
  flex-direction: column;
  gap: 16px;
  max-width: 85vw;
  padding: 24px;
  border-radius: var(--hp-radius-lg);
  background: #fff;
  box-shadow: var(--hp-shadow);
  scroll-snap-align: start;
}

.hp-card[hidden] {
  display: none;
}

.hp-card__media {
  position: relative;
}

.hp-card__media img {
  display: block;
  width: 100%;
  aspect-ratio: 376 / 220;
  object-fit: cover;
  border-radius: var(--hp-radius-sm);
}

.hp-card__kind {
  position: absolute;
  top: 8px;
  right: 8px;
  padding: 6px 10px;
  border-radius: var(--hp-radius-xs);
  background: #dfecf5;
  color: var(--hp-body);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.5;
}

.hp-card__title {
  margin: 0;
  color: var(--hp-ink);
  font-size: var(--hp-fs-md);
  font-weight: 600;
  line-height: 1.3;
}

/* Clamped so a long excerpt cannot make one card taller than its neighbours. */
.hp-card__body {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  color: var(--hp-body);
  font-size: var(--hp-fs-sm);
  line-height: 1.5;
}

.hp-card__tags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.hp-card__go {
  display: flex;
  justify-content: flex-end;
  margin-top: auto;
}

.hp-card__go a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: var(--hp-tint);
}

.hp-card__go img {
  width: 18px;
  height: 18px;
}

.hp-dots {
  display: flex;
  justify-content: center;
  gap: 8px;
}

.hp-dot {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: rgba(34, 36, 38, 0.2);
  cursor: pointer;
  transition: width 0.25s ease, background 0.25s ease;
}

.hp-dot.is-active {
  width: 32px;
  background: var(--hp-grad-accent);
}

.hp-dot:focus-visible {
  outline: 3px solid var(--hp-royal-blue);
  outline-offset: 3px;
}

.hp-insights__cta {
  display: flex;
  justify-content: center;
  margin-top: 40px;
}

/* ==========================================================================
   08 — Why Euromonitor
   Figma 13631:24424 — a 512 column beside four rows split by hairlines.
   ========================================================================== */

.hp-why {
  padding-block: 0 128px;
}

.hp-why__inner {
  display: grid;
  grid-template-columns: 512px minmax(0, 1fr);
  gap: 80px;
}

/* The copy column rides down alongside the four rows rather than scrolling
   away at the top of them.

   `align-self: start` is what makes it work at all: a grid item stretches to
   the full row height by default, which leaves a sticky element nothing to
   travel within. Shrunk to its own height it has the rest of the row to move
   through, and the row ends level with the last USP — so the column releases
   exactly as the list runs out, with no extra scripting.

   The offset clears the host site's fixed header, whose height is only known
   at runtime (see --hp-header-h in homepage.js). The fallback keeps the gap
   sensible if the script never runs. */
.hp-why__copy {
  position: sticky;
  top: calc(var(--hp-header-h, 0px) + 32px);
  align-self: start;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-right: 80px;
}

.hp-why__cta {
  margin-top: 16px;
}

.hp-why__list {
  display: flex;
  flex-direction: column;
  gap: 48px;
}

.hp-usp {
  display: flex;
  gap: 24px;
  align-items: flex-start;
}

.hp-usp__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 40px;
  height: 40px;
  margin-top: 4px;
  border: 1px solid var(--hp-cyan-sat);
  border-radius: 50%;
  background: var(--hp-tint);
}

.hp-usp__icon img {
  width: 24px;
  height: 24px;
}

.hp-usp__text {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* ==========================================================================
   Responsive
   Breakpoints follow the mobile frame (Figma 13631:24595, 428 wide): the two
   column blocks stack, the product frame moves above its routes, and the
   three figures run down the page instead of across it.
   ========================================================================== */

@media (max-width: 1199px) {

  /* Below the desktop frame the arches stop being a backdrop to the copy and
     become a band across the top of the hero, as they are on the mobile frame
     (Figma 14125:27741, 428 wide, band 320 tall). */
  .hp-hero {
    display: block;
    min-height: 0;
    padding-bottom: 88px;
  }

  .hp-hero__art {
    position: relative;
    inset: auto;
    height: clamp(264px, 74.8vw, 504px);
    /* The frame laps the copy over the last 48px of the band, so the eyebrow
       sits on the artwork's bottom fade rather than below it. Proportional so
       the overlap shrinks with the band, floored so it stops growing once the
       height is capped. */
    margin-bottom: max(-48px, -11.2vw);
  }

  /* The 50vw cap keeps the lead clear of the arches on desktop. Stacked, the
     arches are a band above the copy and there is nothing left to clear — all
     the cap was doing here was squeezing the lead into a 171px column while
     the heading above it ran the full 302px. */
  .hp-hero__lead {
    max-width: none;
  }

  /* Below the desktop frame the band is cropped, not positioned. */
  .hp-hero__art::before {
    left: 0;
    right: 0;
    aspect-ratio: auto;
    transform: none;
    background-position: 66% center;
    background-size: cover;
  }

  .hp-hero__video {
    object-position: 66% center;
  }

  /* Stacked, the copy leads and the film closes the panel, as in the mobile
     frame. Source order already matches, so no reordering is needed. */
  .hp-vcta__grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  .hp-routes,
  .hp-why__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 48px;
  }

  .hp-routes__list {
    order: 2;
  }

  .hp-routes__stage {
    order: 1;
  }

  /* Stacked, the copy sits above the list rather than beside it, so there is
     nothing for it to follow. */
  .hp-why__copy {
    position: static;
    padding-right: 0;
  }

  .hp-folio__row,
  .hp-folio__row--flip {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
    padding-bottom: 88px;
  }

  .hp-folio__row--flip .hp-folio__copy {
    order: 2;
  }

  .hp-folio__row--flip .hp-folio__media {
    order: 1;
  }

  .hp-chips {
    left: 0;
  }
}

@media (max-width: 767px) {
  .hp-hero {
    padding-bottom: 72px;
  }

  .hp-hero__btns .hp-btn {
    flex: 1 1 auto;
  }

  .hp-proof {
    padding-block: 40px;
  }

  .hp-stats {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Stacked, the same single gradient now runs top to bottom instead of left
     to right, so the three cards still read as one continuous wash. */
  .hp-stat {
    min-height: 140px;
    background-image: linear-gradient(180deg,
        rgba(15, 208, 255, 0.5) 0%,
        rgba(0, 6, 200, 0.5) 100%);
    background-size: 100% calc(300% + 48px);
  }

  .hp-stat--1 {
    background-position: center top;
  }

  .hp-stat--2 {
    background-position: center;
  }

  .hp-stat--3 {
    background-position: center bottom;
  }

  .hp-logos__item {
    height: 56px;
  }

  .hp-logos__track {
    gap: 40px;
  }

  .hp-story {
    padding-block: 64px 80px;
    padding-bottom: 115px;
  }

  .hp-story__intro {
    padding-bottom: 48px;
  }

  /* Figma 14125:27747 keeps the accordion on a phone — one route open, the
     other two dimmed labels — and closes the block with the screen below the
     list rather than above it.

     Staying on grid matters. The base rule carries `align-items: center`,
     which means vertical centring in a two-column grid but *horizontal*
     centring in a flex column. Switching this to flex therefore shrink-wrapped
     the stage to its content width, and since every shot inside it is
     absolutely positioned that content is nothing: the frame collapsed to
     16x14px. */
  .hp-routes {
    gap: 40px;
  }

  .hp-routes__list {
    order: 1;
    /* The ribbon below is absolutely positioned and comes first in the source,
       so the list has to join the positioned layer to stay on top of it —
       static content always paints under positioned siblings. The stage is
       already `position: relative`. */
    position: relative;
  }

  .hp-routes__stage {
    order: 2;
  }

  /* The mobile frame leaves the top of the section clear and runs the ribbon
     behind the screen instead, so the section-level copy goes and the
     routes-level one arrives. */
  .hp-ribbon--story {
    display: none;
  }

  /* Anchored to the foot of the routes grid — the screen is the last thing in
     it, so this stays put however tall the open route happens to be — and bled
     back out to the viewport edges past the container gutter. The band is the
     480x428 sweep Figma draws, hence the vw height: the artwork is scaled off
     the width, so the two have to track each other. */
  .hp-ribbon--routes {
    display: block;
    inset: 25% calc(var(--hp-gutter) * -1) -21vw;
    height: 154vw;
  }

  /* Same -45deg as the desktop placement: the artwork reads pink-to-cyan left
     to right, so a quarter turn anticlockwise drops the pink tail into the
     bottom left and lifts the cyan hook into the top right, which is what the
     frame shows. Oversized and offset so the ribbon crosses the band
     corner-to-corner with both ends running off the edges; the middle is
     hidden by the screen. */
  .hp-ribbon--routes::before {
    inset: -40.8% auto auto -86.4%;
    width: 280%;
    aspect-ratio: 1;
    transform: rotate(-45deg);
  }

  .hp-folio {
    padding-top: 40px;
  }

  .hp-folio__intro {
    padding-bottom: 40px;
  }

  .hp-folio__row,
  .hp-folio__row--flip {
    padding-bottom: 64px;
  }

  .hp-chips {
      margin-top: 16px;
      transform: none;
      top: 21%;
      gap: 4px;
      left: 10px;
  }

  .hp-chip {
    font-size: 12px;
    padding: 6px 12px;
  }

  .hp-chip__icon {
    width: 20px;
    height: 20px;
  }

  .hp-chip__icon img {
    width: 14px;
    height: 14px;
  }

  /* Figma 14125:27750 keeps the phone panel on the desktop composition: the
     same 1.44 box, the same staggered row of three covers sitting on the
     artwork. Only the numbers change — the row is inset inside the panel here
     rather than overhanging it, and the covers are half size.

     396-wide panel, covers 120 wide at x 10 / 138 / 266, so 10px of clearance
     each side and 8px between. The row is therefore 376 wide, and every offset
     below is a percentage of one or the other so the cluster scales with the
     panel instead of drifting as the screen narrows. */
  .hp-reports {
    inset: 0 2.53%;
  }

  /* Stagger steps of 12px on a 376-wide row. Percentage margins on a flex item
     resolve against the flex container's width, which is that row. */
  .hp-report--1 {
    margin-top: 23.14%;
  }

  .hp-report--2 {
    margin-top: 19.95%;
  }

  .hp-report--3 {
    margin-top: 16.76%;
  }

  /* The covers are half the desktop size, so their insides have to halve too.
     Container units tie them to the panel rather than the viewport, which
     matters because the panel is the viewport less two gutters. */
  .hp-folio__media--reports {
    container-type: inline-size;
  }

  .hp-report {
    border-radius: var(--hp-radius-xs);
    box-shadow: 0 11px 13px rgba(85, 105, 135, 0.28);
  }

  .hp-report__body {
    gap: 2.02cqw;
    padding: 2.02cqw;
  }

  .hp-report__title {
    font-size: 2.27cqw;
  }

  .hp-report__tags .hp-tag {
    padding: 0.25cqw 1.26cqw;
    font-size: 4.05px;
  }

  .hp-insights {
    padding-block: 72px;
  }

  .hp-card {
    flex-basis: 300px;
  }

  .hp-why {
    padding-bottom: 80px;
  }

  .hp-why__list {
    gap: 32px;
  }

  .hp-usp {
    gap: 16px;
  }
}
