/* EV Speakers

Portrait cards with name, role and short bio. The card's "Read bio" control
stretches to cover the whole card and opens the full-page bio modal at that
speaker; the LinkedIn icon is raised above it so both remain independently
clickable. LinkedIn is the only social on the card - the modal carries the rest.

The modal holds every speaker as a slide in one horizontal scroll-snap track, so
it can be paged through without closing. Its styles start at "Bio modal" below.
*/

/* The section sits on white with dark cards, which is the inverse of the other
   event sections. The cards keep their dark fill in both themes. */

.m-evSpeakers {
  position: relative;
  background-color: var(--white);
  color: var(--brand_dark);
}

.m-evSpeakers--dark {
  background-color: var(--grey_30);
  color: var(--white);
}

.m-evSpeakers .o-wrapper--module {
  padding-inline: var(--grid_margins);
}

.m-evSpeakers__intro {
  margin-bottom: var(--spacing_10);
}

.m-evSpeakers__eyebrow {
  margin-bottom: var(--spacing_5);
}

.m-evSpeakers__heading {
  margin: 0;
  font-size: clamp(var(--h1_min), 4vw + 1rem, var(--h1_max));
  line-height: 125%;
  font-weight: var(--font_regular);
}

.m-evSpeakers__grid {
  display: grid;
  gap: var(--spacing_5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.m-evSpeakers__item {
  display: flex;
  margin: 0;
  padding: 0;
}

.m-evSpeakers__card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  background-color: var(--grey_30);
  border: var(--integers_1) solid var(--grey_30);
  color: var(--white);
  transition: border-color var(--transitionSpeed) var(--transitionStyle);
}

.m-evSpeakers__card:hover,
.m-evSpeakers__card:focus-within {
  border-color: var(--brand_orange);
}

.m-evSpeakers__portrait {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
}

.m-evSpeakers__body {
  display: flex;
  flex-direction: column;
  flex-grow: 1;
  padding: var(--spacing_5);
}

.m-evSpeakers__name {
  display: flex;
  align-items: center;
  gap: var(--integers_8);
  margin: 0;
  font-size: var(--p_base);
  font-weight: var(--font_semibold);
  line-height: 140%;
}

.m-evSpeakers__linkedin {
  position: relative;
  z-index: 2;
  flex-shrink: 0;
  width: calc((14 / var(--root_font_size)) * 1rem);
  height: calc((14 / var(--root_font_size)) * 1rem);
  background: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' fill='%23FF6B00'%3E%3Cpath d='M2.8 5.2H.6V14h2.2V5.2ZM1.7 0A1.4 1.4 0 1 0 1.7 2.8 1.4 1.4 0 0 0 1.7 0ZM14 9.3c0-2.6-1.4-3.8-3.2-3.8-1.5 0-2.2.8-2.5 1.4V5.2H6.1c0 .6 0 8.8 0 8.8h2.2V9.1c0-.2 0-.5.1-.7.2-.5.6-1 1.3-1 1 0 1.4.7 1.4 1.8V14H14V9.3Z'/%3E%3C/svg%3E");
}

.m-evSpeakers__linkedin:focus-visible {
  outline: var(--integers_2) solid var(--brand_orange);
  outline-offset: var(--integers_2);
}

.m-evSpeakers__role {
  margin: var(--spacing_3) 0 0;
  font-family: var(--font_mono);
  font-size: var(--p_sm);
  line-height: 140%;
}

.m-evSpeakers__bio {
  margin: var(--spacing_4) 0 0;
  font-size: var(--p_sm);
  line-height: 150%;
  color: var(--brand_mediumgrey);
  white-space: pre-line;
}

/* Modal trigger. Stretched to cover the card, with the label collapsed until
   hover so the arrow sits flush left and is then pushed across. Animating
   max-width keeps the label in the accessible name at all times. */

.m-evSpeakers__link {
  display: inline-flex;
  align-items: center;
  margin-top: auto;
  padding: var(--spacing_6) 0 0;
  border: 0;
  background: none;
  color: currentColor;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.m-evSpeakers__link:before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
}

.m-evSpeakers__link:hover,
.m-evSpeakers__link:focus {
  text-decoration: none;
}

.m-evSpeakers__link:focus-visible {
  outline: var(--integers_2) solid var(--brand_orange);
  outline-offset: var(--integers_2);
}

.m-evSpeakers__linkLabel {
  max-width: 0;
  margin-right: 0;
  opacity: 0;
  overflow: hidden;
  white-space: nowrap;
  font-size: var(--p_sm);
  text-decoration: underline;
  transition:
    max-width var(--transitionSpeed) var(--transitionStyle),
    margin-right var(--transitionSpeed) var(--transitionStyle),
    opacity var(--transitionSpeed) var(--transitionStyle);
}

.m-evSpeakers__card:hover .m-evSpeakers__linkLabel,
.m-evSpeakers__card:focus-within .m-evSpeakers__linkLabel {
  max-width: calc((200 / var(--root_font_size)) * 1rem);
  margin-right: var(--integers_8);
  opacity: 1;
}

.m-evSpeakers__linkArrow {
  flex-shrink: 0;
  width: calc((18 / var(--root_font_size)) * 1rem);
  height: calc((13 / var(--root_font_size)) * 1rem);
  background: no-repeat center / contain url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='17' height='12' fill='none'%3E%3Cpath d='M10.7 1 16 6l-5.3 5M15.4 6H0' stroke='%23FF6B00' stroke-width='1.4'/%3E%3C/svg%3E");
}

/* Touch devices never hover, so the label stays visible there. */

@media (hover: none) {

  .m-evSpeakers__linkLabel {
    max-width: none;
    margin-right: var(--integers_8);
    opacity: 1;
  }

}

@media (prefers-reduced-motion: reduce) {

  .m-evSpeakers__card,
  .m-evSpeakers__linkLabel {
    transition: none;
  }

}

@media (min-width: 576px) {

  .m-evSpeakers__grid--cols2,
  .m-evSpeakers__grid--cols3,
  .m-evSpeakers__grid--cols4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

}

@media (min-width: 992px) {

  .m-evSpeakers__grid--cols3 {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  .m-evSpeakers__grid--cols4 {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

}

/* ==========================================================================
   Bio modal
   ========================================================================== */

/* The theme's global `dialog` rule is a small centred panel, so nearly every
   box property here is an override rather than a fresh declaration. A class
   beats the bare element selector, so no !important is needed. */

.m-evSpeakers__modal {
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  overflow: hidden;
  background-color: var(--grey_30);
  color: var(--white);
}

.m-evSpeakers__modal::backdrop {
  background-color: rgba(3, 13, 17, 0.92);
}

/* Set on <html> while the modal is open. A modal dialog makes the page inert but
   does not stop it scrolling behind the top layer. */

.m-evSpeakers-modalOpen {
  overflow: hidden;
}

/* Broad brand glow behind the content, brightest around the portrait. Sits in
   its own element so the track above it stays a clean scroll container. */

.m-evSpeakers__modalGlow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(65% 55% at 50% 58%, rgba(126, 0, 178, 0.55) 0%, rgba(75, 0, 215, 0.26) 45%, transparent 76%),
    radial-gradient(40% 45% at 20% 66%, rgba(255, 0, 217, 0.20) 0%, transparent 72%);
}

.m-evSpeakers__modalClose {
  position: absolute;
  top: var(--spacing_5);
  right: var(--spacing_5);
  z-index: 3;
  width: var(--integers_40);
  height: var(--integers_40);
  padding: 0;
  border: 0;
  background: no-repeat center / calc((20 / var(--root_font_size)) * 1rem) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' stroke='%23fff' stroke-width='1.6'%3E%3Cpath d='M3 3l14 14M17 3 3 17'/%3E%3C/svg%3E");
  cursor: pointer;
  transition: opacity var(--transitionSpeed) var(--transitionStyle);
}

.m-evSpeakers__modalClose:hover {
  opacity: 0.7;
}

.m-evSpeakers__modalClose:focus-visible {
  outline: var(--integers_2) solid var(--brand_orange);
  outline-offset: var(--integers_2);
}

/* Slide track. Swipes sideways on mobile and scrolls top to bottom under the
   wheel on desktop - see the axis switch in the desktop block. The pager is the
   visible affordance, so the native scrollbar is hidden; keyboard and swipe still
   drive it. Containment stops a snap overshoot scrolling the page behind. */

.m-evSpeakers__track {
  position: relative;
  z-index: 1;
  display: flex;
  height: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior: contain;
}

.m-evSpeakers__track::-webkit-scrollbar {
  display: none;
}

/* The slide is only a snap target and a positioning context - it never scrolls
   itself, so the socials pinned to it stay put while the copy moves. */

.m-evSpeakers__slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
  overflow: hidden;
  scroll-snap-align: center;
  scroll-snap-stop: always;
}

/* Long bios scroll here. overflow-x has to be stated too: left as `visible`
   against an `auto` sibling axis it would compute to `auto`, giving every slide a
   horizontal scroll container that competes with the track's. */

.m-evSpeakers__slideScroll {
  display: flex;
  flex-direction: column;
  gap: var(--spacing_6);
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
  padding: calc(var(--integers_96) + var(--spacing_5)) var(--grid_margins) var(--integers_72);
}

/* Portrait, with a soft brand glow behind it and a hard L-shaped gradient rule
   offset off its bottom-left corner - the same accent language as the feature
   panels. */

.m-evSpeakers__slideMedia {
  position: relative;
  flex-shrink: 0;
  align-self: center;
  width: 100%;
  max-width: calc((320 / var(--root_font_size)) * 1rem);
}

.m-evSpeakers__slideFrame {
  position: absolute;
  inset: -8%;
  background: radial-gradient(closest-side, rgba(255, 0, 217, 0.55) 0%, rgba(255, 107, 0, 0.35) 55%, transparent 100%);
  filter: blur(calc((28 / var(--root_font_size)) * 1rem));
}

.m-evSpeakers__slideMedia:before,
.m-evSpeakers__slideMedia:after {
  content: '';
  position: absolute;
  z-index: 1;
}

.m-evSpeakers__slideMedia:before {
  left: calc((-8 / var(--root_font_size)) * 1rem);
  bottom: calc((-8 / var(--root_font_size)) * 1rem);
  width: var(--integers_2);
  height: 55%;
  background: linear-gradient(180deg, var(--brand_blurple) 0%, var(--brand_pink) 45%, var(--brand_orange) 100%);
}

.m-evSpeakers__slideMedia:after {
  left: calc((-8 / var(--root_font_size)) * 1rem);
  bottom: calc((-8 / var(--root_font_size)) * 1rem);
  width: 55%;
  height: var(--integers_2);
  background: linear-gradient(90deg, var(--brand_orange) 0%, var(--brand_pink) 65%, transparent 100%);
}

.m-evSpeakers__slidePortrait {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.m-evSpeakers__slideBody {
  min-width: 0;
}

.m-evSpeakers__slideName {
  margin: 0;
  font-size: clamp(var(--h2_min), 3vw + 1rem, var(--h2_max));
  line-height: 120%;
  font-weight: var(--font_regular);
}

.m-evSpeakers__slideRole {
  margin: var(--spacing_4) 0 0;
  font-family: var(--font_mono);
  font-size: var(--p_sm);
  line-height: 150%;
}

.m-evSpeakers__slideBio {
  margin-top: var(--spacing_6);
  font-size: var(--p_base);
  line-height: 150%;
}

.m-evSpeakers__slideBio p + p {
  margin-top: var(--spacing_4);
}

/* Date and time. The icon hangs in the gutter created by the row's padding, so
   the label and value stay aligned with each other. */

.m-evSpeakers__meta {
  margin: var(--spacing_8) 0 0;
}

.m-evSpeakers__metaRow {
  position: relative;
  padding-left: var(--integers_32);
}

.m-evSpeakers__metaRow + .m-evSpeakers__metaRow {
  margin-top: var(--spacing_4);
}

.m-evSpeakers__metaLabel {
  font-family: var(--font_mono);
  font-size: calc((11 / var(--root_font_size)) * 1rem);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brand_mediumgrey);
}

.m-evSpeakers__metaLabel:before {
  content: '';
  position: absolute;
  left: 0;
  top: calc((2 / var(--root_font_size)) * 1rem);
  width: var(--integers_16);
  height: var(--integers_16);
  background: no-repeat center / contain;
}

.m-evSpeakers__metaLabel--date:before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23FF6B00' stroke-width='1.4'%3E%3Crect x='1.7' y='3' width='12.6' height='11.3' rx='1.2'/%3E%3Cpath d='M1.7 6.6h12.6M5 1.7v2.6M11 1.7v2.6'/%3E%3C/svg%3E");
}

.m-evSpeakers__metaLabel--time:before {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%23FF6B00' stroke-width='1.4'%3E%3Ccircle cx='8' cy='8' r='6.3'/%3E%3Cpath d='M8 4.4V8l2.6 1.8'/%3E%3C/svg%3E");
}

.m-evSpeakers__metaValue {
  margin: 0;
  font-size: var(--p_sm);
  line-height: 150%;
}

/* Socials and pager both sit on a hairline rule that runs to the edge of the
   modal on either side, drawn with the flex pseudo elements. */

.m-evSpeakers__socials,
.m-evSpeakers__pager {
  display: flex;
  align-items: center;
  gap: var(--spacing_5);
  margin: 0;
  padding: 0;
  list-style: none;
}

.m-evSpeakers__socials:before,
.m-evSpeakers__socials:after,
.m-evSpeakers__pager:before,
.m-evSpeakers__pager:after {
  content: '';
  flex: 1 1 0;
  height: var(--integers_1);
  background-color: rgba(255, 255, 255, 0.25);
}

/* Pinned to the slide rather than sitting in its scroll flow: a row under the
   close button on mobile, a column against the right edge on desktop. */

.m-evSpeakers__socials {
  position: absolute;
  left: var(--grid_margins);
  right: var(--grid_margins);
  top: calc(var(--integers_64) + var(--spacing_5));
  z-index: 2;
}

.m-evSpeakers__socialItem {
  margin: 0;
  padding: 0;
}

.m-evSpeakers__social {
  display: block;
  width: var(--integers_20);
  height: var(--integers_20);
  background: no-repeat center / contain;
  transition: opacity var(--transitionSpeed) var(--transitionStyle);
}

.m-evSpeakers__social:hover {
  opacity: 0.6;
}

.m-evSpeakers__social:focus-visible {
  outline: var(--integers_2) solid var(--brand_orange);
  outline-offset: var(--integers_4);
}

.m-evSpeakers__social--instagram {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' stroke='%23fff' stroke-width='1.5'%3E%3Crect x='2.6' y='2.6' width='14.8' height='14.8' rx='4.4'/%3E%3Ccircle cx='10' cy='10' r='3.7'/%3E%3Ccircle cx='14.4' cy='5.6' r='.85' fill='%23fff' stroke='none'/%3E%3C/svg%3E");
}

.m-evSpeakers__social--linkedin {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='%23fff'%3E%3Cpath d='M4 7.4H1.9V18H4V7.4ZM2.95 2.2a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3ZM18.1 12.2c0-3-1.6-4.4-3.75-4.4-1.75 0-2.55.95-2.95 1.65V7.4H9.3V18h2.1v-5.7c0-.25 0-.55.1-.8.25-.6.75-1.2 1.6-1.2 1.15 0 1.65.85 1.65 2.1V18h2.1c0-.05 1.25 0 1.25 0v-5.8Z'/%3E%3C/svg%3E");
}

.m-evSpeakers__social--telegram {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='none' stroke='%23fff' stroke-width='1.5' stroke-linejoin='round'%3E%3Cpath d='M18.2 2.9 2.4 9.2l4.7 1.8L18.2 2.9Z'/%3E%3Cpath d='M18.2 2.9l-3 14.2-8.1-6.1'/%3E%3Cpath d='M7.1 11v4.6l3-2.5'/%3E%3C/svg%3E");
}

.m-evSpeakers__social--facebook {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' fill='%23fff'%3E%3Cpath d='M10 1.6a8.4 8.4 0 0 0-1.3 16.7v-5.9H6.55V9.9H8.7V8.05c0-2.15 1.3-3.35 3.25-3.35.95 0 1.9.15 1.9.15v2.1h-1.05c-1.05 0-1.35.65-1.35 1.3V9.9h2.35l-.4 2.5h-1.95v5.9A8.4 8.4 0 0 0 10 1.6Z'/%3E%3C/svg%3E");
}

/* Pager. The current slide's marker stretches into a bar, matching the design's
   "bar plus dots" indicator, and stays a 44px hit target either way. */

.m-evSpeakers__pager {
  position: absolute;
  left: var(--grid_margins);
  right: var(--grid_margins);
  bottom: var(--spacing_6);
  z-index: 2;
  gap: var(--spacing_4);
}

.m-evSpeakers__pagerList {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  gap: var(--spacing_4);
  margin: 0;
  padding: 0;
  list-style: none;
}

.m-evSpeakers__pagerItem {
  display: flex;
  margin: 0;
  padding: 0;
}

.m-evSpeakers__pagerDot {
  display: flex;
  align-items: center;
  justify-content: center;
  width: var(--integers_20);
  height: var(--integers_20);
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  transition: width var(--transitionSpeed) var(--transitionStyle);
}

/* The marker fills the button, so growing the button is what turns the dot into
   a bar - and the hit target grows with it rather than being outrun by it. */

.m-evSpeakers__pagerDot:before {
  content: '';
  display: block;
  width: var(--integers_4);
  height: var(--integers_4);
  border-radius: var(--integers_4);
  background-color: rgba(255, 255, 255, 0.45);
  transition:
    width var(--transitionSpeed) var(--transitionStyle),
    height var(--transitionSpeed) var(--transitionStyle),
    background-color var(--transitionSpeed) var(--transitionStyle);
}

.m-evSpeakers__pagerDot:hover:before {
  background-color: var(--white);
}

.m-evSpeakers__pagerDot[aria-current="true"] {
  width: calc((72 / var(--root_font_size)) * 1rem);
}

.m-evSpeakers__pagerDot[aria-current="true"]:before {
  width: 100%;
  height: var(--integers_2);
  background-color: var(--white);
}

.m-evSpeakers__pagerDot:focus-visible {
  outline: var(--integers_2) solid var(--brand_orange);
  outline-offset: 0;
}

@media (prefers-reduced-motion: reduce) {

  .m-evSpeakers__modalClose,
  .m-evSpeakers__social,
  .m-evSpeakers__pagerDot:before {
    transition: none;
  }

}

@media (min-width: 768px) {

  .m-evSpeakers__slideMedia {
    max-width: calc((420 / var(--root_font_size)) * 1rem);
  }

}

/* Desktop reflows the modal into three columns: pager, content, socials - with
   the pager and socials rules turning vertical against the modal edges - and
   turns the track itself top-to-bottom so the wheel pages through speakers. */

@media (min-width: 992px) {

  .m-evSpeakers__modalClose {
    top: var(--spacing_8);
    right: var(--spacing_8);
  }

  .m-evSpeakers__track {
    flex-direction: column;
    overflow-x: hidden;
    overflow-y: auto;
    scroll-snap-type: y mandatory;
  }

  /* The slide reserves the pager and socials columns as padding.

  Both the slide and its scroll wrapper go back to `visible` here, which is what
  lets the parallax below work: `view()` resolves against the nearest scrollport
  ancestor, so any clipping element between a layer and the track would capture
  the timeline and freeze the animation. Long bios scroll in the text column
  instead, which keeps the portrait still while the copy moves. */

  .m-evSpeakers__slide {
    overflow: visible;
    padding-inline: var(--integers_80);
  }

  .m-evSpeakers__slideScroll {
    flex-direction: row;
    align-items: center;
    justify-content: center;
    gap: var(--spacing_20);
    overflow: visible;
    padding: var(--spacing_20) var(--grid_margins);
  }

  .m-evSpeakers__slideMedia {
    flex: 0 1 calc((420 / var(--root_font_size)) * 1rem);
    max-width: calc((420 / var(--root_font_size)) * 1rem);
    align-self: center;
  }

  .m-evSpeakers__slideBody {
    flex: 0 1 calc((520 / var(--root_font_size)) * 1rem);
    max-height: 100%;
    overflow-y: auto;
  }

  .m-evSpeakers__socials,
  .m-evSpeakers__pager {
    position: absolute;
    top: 0;
    bottom: 0;
    flex-direction: column;
    gap: var(--spacing_6);
  }

  .m-evSpeakers__socials:before,
  .m-evSpeakers__socials:after,
  .m-evSpeakers__pager:before,
  .m-evSpeakers__pager:after {
    width: var(--integers_1);
    height: auto;
  }

  .m-evSpeakers__socials {
    left: auto;
    right: var(--grid_margins);
    top: 0;
    padding-block: var(--spacing_10);
  }

  .m-evSpeakers__pager {
    left: var(--grid_margins);
    right: auto;
    bottom: 0;
    padding-block: var(--spacing_10);
  }

  .m-evSpeakers__pagerList {
    flex-direction: column;
    gap: var(--spacing_6);
  }

  /* Same marker, rotated: the button grows downwards instead of across. */

  .m-evSpeakers__pagerDot {
    transition: height var(--transitionSpeed) var(--transitionStyle);
  }

  .m-evSpeakers__pagerDot[aria-current="true"] {
    width: var(--integers_20);
    height: calc((72 / var(--root_font_size)) * 1rem);
  }

  .m-evSpeakers__pagerDot[aria-current="true"]:before {
    width: var(--integers_2);
    height: 100%;
  }

  /* Parallax, desktop only - mobile keeps the plain sideways swipe.

  The portrait and the copy are carried along by the track's scroll, and these
  add a second, smaller movement on top of it. Because the copy shifts further
  than the portrait, the two separate as a slide passes and read as layers at
  different depths rather than one flat panel.

  Each slide is exactly the height of the track, so its cover range spans twice
  the track height and it rests at the 50% mark. One notch of paging therefore
  moves the outgoing slide 50%-100% and the incoming one 0%-50%, which is why the
  curves are symmetrical about the middle. The travel stays inside the slide's
  block padding, so nothing bleeds into its neighbour. */

  @keyframes m-evSpeakers-parallaxMedia {

    0% {
      opacity: 0;
      transform: translateY(calc((-28 / var(--root_font_size)) * 1rem)) scale(0.94);
    }

    50% {
      opacity: 1;
      transform: none;
    }

    100% {
      opacity: 0;
      transform: translateY(calc((28 / var(--root_font_size)) * 1rem)) scale(0.94);
    }

  }

  @keyframes m-evSpeakers-parallaxBody {

    0% {
      opacity: 0;
      transform: translateY(calc((-56 / var(--root_font_size)) * 1rem));
    }

    40%,
    60% {
      opacity: 1;
      transform: none;
    }

    100% {
      opacity: 0;
      transform: translateY(calc((56 / var(--root_font_size)) * 1rem));
    }

  }

  @supports (animation-timeline: view()) {

    .m-evSpeakers__slideMedia {
      animation: m-evSpeakers-parallaxMedia linear both;
      animation-timeline: view();
    }

    .m-evSpeakers__slideBody {
      animation: m-evSpeakers-parallaxBody linear both;
      animation-timeline: view();
    }

  }

}

/* Killed rather than shortened: the parallax exists only to convey depth, so
   there is nothing left to keep once the movement goes. */

@media (prefers-reduced-motion: reduce) and (min-width: 992px) {

  .m-evSpeakers__slideMedia,
  .m-evSpeakers__slideBody {
    animation: none;
    opacity: 1;
    transform: none;
  }

}
