/* ========================================
   ENGAGEMENT TOOLBAR — Subscribe + Share buttons
   Rendered as a DOM child of .video-card beneath the player when
   the video's position is `large_top` (the engage-toolbar template
   is hooked into ctf_after_video_card, which fires from inside
   template-parts/video-card.php just before its closing </div>).
   Because the toolbar lives INSIDE .video-card it inherits the
   card's max-width / column / padding automatically — no extra
   horizontal alignment CSS needed here. See
   template-parts/video-engage-toolbar.php for markup + behaviour.
======================================== */

.ctf-engage-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  margin: 1rem 0 0.25rem;
  /* NOTE on CSS containment: an earlier revision applied
     `contain: layout style;` here as a render-perf hint. We
     reverted it because `contain: layout` (and also `contain: paint`)
     creates a new stacking context, which TRAPS the absolutely
     positioned .ctf-share-menu popover inside that context. With
     the toolbar now nested inside .video-card, a later DOM
     sibling (e.g. the petition question block below the video)
     ended up painting on TOP of the open popover and intercepted
     menu-item clicks (Playwright caught this as "subtree
     intercepts pointer events"). Containment without an
     accompanying `position` + high `z-index` discipline isn't
     worth the foot-gun for a toolbar this small. */
}

/* Block wrappers exist so the share-feedback live region can be
   positioned relative to the Share button without affecting the
   Subscribe button's vertical rhythm. The Share block is the
   positioning context for the popover menu (position:absolute
   inside). */
.ctf-subscribe-block,
.ctf-share-block {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}
.ctf-share-block {
  position: relative;
}

/* Subscribe — red-on-white, takes the visual lead (matches YouTube's
   own button colour so it reads as "this is the YouTube subscribe
   action" without further labelling). */
.ctf-subscribe-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1.1rem;
  background: #cc0000;
  color: #ffffff;
  border: 1px solid #cc0000;
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1;
  text-decoration: none;
  transition: background-color 0.15s ease, border-color 0.15s ease;
  /* Reset link defaults — many themes underline links inside .card */
  outline-offset: 2px;
}

.ctf-subscribe-btn:hover,
.ctf-subscribe-btn:focus-visible {
  background: #a30000;
  border-color: #a30000;
  color: #ffffff;
  text-decoration: none;
}

.ctf-subscribe-btn .ctf-yt-icon {
  flex-shrink: 0;
}

/* Share — neutral / secondary. Visual weight lower than Subscribe so
   the eye lands on the YouTube CTA first; Share is the supporting
   action. */
.ctf-share-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 1.1rem;
  background: #ffffff;
  color: #1f2d3d;
  border: 1px solid #cbd5e1;
  border-radius: 999px;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
  outline-offset: 2px;
}

.ctf-share-btn:hover,
.ctf-share-btn:focus-visible {
  background: #f1f5f9;
  border-color: #94a3b8;
  color: #1f2d3d;
}

.ctf-share-btn .ctf-share-icon {
  flex-shrink: 0;
}

/* Share popover menu — opens beneath the Share button on desktop
   when navigator.share() isn't available. Anchored via the
   .ctf-share-block { position: relative } container so it tracks the
   button on resize. Hidden by default via the [hidden] attribute the
   script toggles. */
.ctf-share-menu {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 50%;
  /* Default closed-state transform: translateX(-50%) for horizontal
     centering, translateY(-4px) so the open animation slides DOWN
     into place. The open state below resets the Y component. */
  transform: translateX(-50%) translateY(-4px);
  opacity: 0;
  /* High z-index because the toolbar is rendered INSIDE .video-card
     and the popover extends below the card, visually overlapping
     downstream content (e.g. petition question blocks). The popover
     must paint above any sibling DOM nodes that come after the
     video card. 1000 stays well below modal/overlay tiers but
     comfortably above any in-flow content z-index we use. */
  z-index: 1000;
  min-width: 200px;
  padding: 0.35rem;
  background: #ffffff;
  border: 1px solid #d1d5db;
  border-radius: 12px;
  box-shadow: 0 10px 24px rgba(15, 23, 42, 0.18), 0 2px 6px rgba(15, 23, 42, 0.08);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  /* Enter/exit transition. Fast (140ms) and small movement so it
     feels responsive — popover menus that linger feel laggy. The
     `transform` curve uses a slight overshoot (cubic-bezier with
     overshoot-y) for a small bounce-into-place effect; opacity is
     plain ease so the fade is monotonic.
     prefers-reduced-motion override below kills the transitions
     entirely for users who've opted out. */
  transition:
    opacity 140ms ease,
    transform 140ms cubic-bezier(0.2, 0.8, 0.4, 1);
  /* Stop the user from being able to tab into menu items while the
     popover is in its closed (opacity:0) state. visibility:hidden
     is the trick — it suspends pointer events + tab order without
     using `display:none` (which would cancel the transition). */
  visibility: hidden;
}

/* Open state — class added by the toolbar JS as it removes the
   [hidden] attribute, then immediately before the closing call it
   removes this class and waits for transitionend before re-adding
   [hidden]. The .is-open class is a no-op visually unless it's
   layered on top of the menu being attached and visible. */
.ctf-share-menu.is-open {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  visibility: visible;
}

/* Honour the hidden attribute. The UA stylesheet's `[hidden] {
   display: none }` rule has specificity (0,1,0) — identical to a
   class selector — so the `display: flex` above wins on source
   order, and the menu would stay visible despite the JS toggling
   the attribute. This explicit override has higher specificity
   (0,2,0: class + attribute) and keeps the attribute-based hide
   working. Without it, the popover would be permanently visible
   on every page load. */
.ctf-share-menu[hidden] {
  display: none;
}

/* Respect the user's motion preference — skip the slide/fade
   entirely for users who've opted out of animations. They get an
   instant show/hide, which is still correct semantically. */
@media (prefers-reduced-motion: reduce) {
  .ctf-share-menu {
    transition: none;
  }
}

/* Tiny caret pointing up at the Share button — purely decorative,
   reinforces the "this menu belongs to the button above" anchoring. */
.ctf-share-menu::before {
  content: "";
  position: absolute;
  top: -7px;
  left: 50%;
  transform: translateX(-50%) rotate(45deg);
  width: 12px;
  height: 12px;
  background: #ffffff;
  border-left: 1px solid #d1d5db;
  border-top: 1px solid #d1d5db;
}

.ctf-share-menu-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.55rem 0.85rem;
  background: transparent;
  border: 0;
  border-radius: 8px;
  color: #1f2d3d;
  font-family: inherit;
  font-size: 0.92rem;
  font-weight: 500;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  /* Reset link colour so the brand red of the Subscribe button doesn't
     leak in via a theme-level a:visited rule. */
  transition: background-color 0.12s ease, color 0.12s ease;
}

.ctf-share-menu-item:hover,
.ctf-share-menu-item:focus-visible {
  background: #f1f5f9;
  color: #1f2d3d;
  text-decoration: none;
  outline: none;
}

.ctf-share-menu-item:focus-visible {
  /* Restore a visible focus ring inside the menu for keyboard users —
     the background change alone isn't enough for accessibility. */
  box-shadow: 0 0 0 2px #2563eb inset;
}

.ctf-share-menu-icon {
  flex-shrink: 0;
}

/* Brand-tinted icons, button background stays neutral so the menu
   reads as a list (not as four competing CTAs). */
.ctf-share-menu-item[data-share-method="facebook"] .ctf-share-menu-icon { color: #1877f2; }
.ctf-share-menu-item[data-share-method="twitter"]  .ctf-share-menu-icon { color: #000000; }
.ctf-share-menu-item[data-share-method="email"]    .ctf-share-menu-icon { color: #4b5d6b; }
.ctf-share-menu-item[data-share-method="copy_link"] .ctf-share-menu-icon { color: #4b5d6b; }

/* Live region for the "Link copied to clipboard" confirmation. Sits
   beneath the Share button and only appears (display:block) when the
   inline script flips its `hidden` attribute off. */
.ctf-video-share-feedback {
  font-size: 0.825rem;
  color: #4b5d6b;
  text-align: center;
  min-height: 1.1em; /* Prevent layout shift when the message appears */
}

@media (max-width: 480px) {
  /* On very narrow viewports drop the buttons onto their own row each
     — labels stay readable, no horizontal scroll, taps stay generous.
     The popover menu effectively never opens here because mobile
     browsers expose navigator.share() and the JS takes that path
     before reaching the popover branch. */
  .ctf-engage-toolbar {
    flex-direction: column;
    align-items: stretch;
  }
  .ctf-subscribe-btn,
  .ctf-share-btn {
    width: 100%;
    justify-content: center;
  }
  /* Belt-and-braces: if a mobile browser DID end up rendering the
     popover (e.g. user agent without Web Share API), pin it to the
     full container width so it doesn't blow out the viewport. */
  .ctf-share-menu {
    left: 0;
    right: 0;
    transform: none;
    min-width: 0;
  }
  .ctf-share-menu::before {
    left: 50%;
  }
}

/* ========================================
   VIDEO CARD COMPONENT
======================================== */

.video-card {
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0,0,0,0.07);
  padding: 2rem;
  margin: 2rem auto;
  max-width: 900px;
  width: calc(100% - 2rem);
}

.video-card__title {
  font-size: 1.5rem;
  font-weight: 700;
  color: #1a2a3a;
  margin: 0 0 1.5rem 0;
  text-align: center;
}

.video-card__container {
  position: relative;
  width: 100%;
  padding-bottom: 56.25%; /* 16:9 aspect ratio */
  background: #000;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* Thumbnail Mode */
.video-card__thumbnail {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
  overflow: hidden;
  transition: transform 0.3s ease;
}

.video-card__thumbnail:hover {
  transform: scale(1.02);
}

.video-card__thumbnail-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.video-card__play-button {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 80px;
  height: 80px;
  background: rgba(0, 0, 0, 0.8);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 2;
}

.video-card__play-button:hover {
  background: rgba(221, 35, 15, 0.95);
  transform: translate(-50%, -50%) scale(1.1);
}

.video-card__play-icon {
  width: 68px;
  height: 48px;
  opacity: 0.9;
  transition: opacity 0.3s ease;
}

.video-card__play-button:hover .video-card__play-icon {
  opacity: 1;
}

/* Embed Mode */
.video-card__embed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

.video-card__iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  border: none;
}

/* Description */
.video-card__description {
  margin-top: 1.5rem;
  font-size: 1rem;
  line-height: 1.6;
  color: #4a5568;
}

.video-card__description p {
  margin: 0.5rem 0;
}

.video-card__description a {
  color: #dd230f;
  text-decoration: none;
  transition: color 0.2s ease;
}

.video-card__description a:hover {
  color: #cd3423;
  text-decoration: underline;
}

/* Responsive adjustments */
@media (max-width: 768px) {
  .video-card {
    margin: 1.5rem auto;
    padding: 1.5rem;
  }

  .video-card__title {
    font-size: 1.25rem;
    margin-bottom: 0.75rem;
  }

  .video-card__play-button {
    width: 60px;
    height: 60px;
  }

  .video-card__play-icon {
    width: 51px;
    height: 36px;
  }

  .video-card__description {
    font-size: 0.9rem;
  }
}

@media (max-width: 480px) {
  .video-card {
    padding: 1rem;
  }

  .video-card__title {
    font-size: 1.1rem;
  }

  .video-card__play-button {
    width: 50px;
    height: 50px;
  }

  .video-card__play-icon {
    width: 42px;
    height: 30px;
  }
}

/* When nested inside another card, remove duplicate card styling */
.card .video-card {
  box-shadow: none;
  padding: 1rem 0;
  margin: 1rem 0;
  max-width: 100%;
  width: 100%;
}

/* Loading state */
.video-card__thumbnail::after {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: linear-gradient(
    90deg,
    rgba(0, 0, 0, 0) 0%,
    rgba(0, 0, 0, 0.1) 50%,
    rgba(0, 0, 0, 0) 100%
  );
  animation: shimmer 2s infinite;
  pointer-events: none;
}

@keyframes shimmer {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(100%);
  }
}

.video-card--embed .video-card__thumbnail::after {
  display: none;
}

/* ========================================
   SHARED: Video "with content" layout
   Used by petition and donation templates.
   Video floats left beside main content.
======================================== */

.content-with-video {
  width: 100%;
  max-width: 100%;
}

.content-video-wrapper {
  margin: 0;
  padding: 0;
  width: 400px;
  max-width: 400px;
  position: relative;
}

.content-video-wrapper .video-card {
  margin: 0 !important;
  padding: 0 !important;
}

.content-video-wrapper .video-card__play-button,
.content-with-video .video-card__play-button {
  display: none !important;
  opacity: 0 !important;
  visibility: hidden !important;
  pointer-events: none !important;
}

@media (min-width: 1201px) {
  .content-with-video .content-video-wrapper {
    float: left;
    width: 400px;
    max-width: 400px;
    margin-right: 2rem;
    margin-left: 0;
    margin-top: 0;
    margin-bottom: 0;
  }

  .content-with-video::after {
    content: "";
    display: table;
    clear: both;
  }

  .content-video-wrapper .video-card {
    max-width: 100% !important;
    width: 100% !important;
  }
}

@media (min-width: 901px) and (max-width: 1200px) {
  .content-with-video .content-video-wrapper {
    float: left;
    width: 300px;
    max-width: 300px;
    margin-right: 2rem;
    margin-left: 0;
    margin-top: 0;
    margin-bottom: 0;
  }

  .content-with-video::after {
    content: "";
    display: table;
    clear: both;
  }

  .content-video-wrapper .video-card {
    max-width: 100% !important;
    width: 100% !important;
  }
}

@media (max-width: 900px) {
  .content-with-video .content-video-wrapper {
    float: none;
    width: 100%;
    max-width: 500px;
    margin: 0 auto 2rem;
  }
}

/* On petition / survey / action templates the default
   .content-video-wrapper inside .content-with-video already floats left
   at >=901px. The `--right` modifier flips it to float right with
   mirrored margins so authors can pick either side per page.
   (`--left` is the same as the default, but we accept it for symmetry
   so the petition template renders the same class an author selects.) */
@media (min-width: 1201px) {
  .content-with-video .content-video-wrapper.content-video-wrapper--right {
    float: right;
    margin-right: 0;
    margin-left: 2rem;
  }
}

@media (min-width: 901px) and (max-width: 1200px) {
  .content-with-video .content-video-wrapper.content-video-wrapper--right {
    float: right;
    margin-right: 0;
    margin-left: 2rem;
  }
}

/* ========================================
   "With content - right" / "With content - left" layouts (next_step)
   Small video that sits inside .donation-template.card after the header.
   Desktop (>=901px): floats right (or left) at ~320px, donation toggle /
     amounts / personal-info fields flow around it on the opposite side.
     .payment-section clears the float so Stripe Express Checkout + the
     card iframe always render at the full card width (Stripe is finicky
     about narrow iframes — full-width avoids the EC buttons wrapping
     into a vertical stack and the card iframe sometimes failing to mount).
   Mobile/tablet (<901px): stacks full-width; `--mobile-below` flex-reorders
     intro before video when the author selects that option in ACF.
======================================== */

.content-video-wrapper--right,
.content-video-wrapper--left {
  width: 100%;
  max-width: 100%;
  margin: 0 0 1.5rem 0;
  padding: 0;
  /* Establish a paint context so the wrapper has explicit dimensions for
     the absolutely-positioned .video-card__container (16:9 box). */
  position: relative;
  float: none;
}

.content-video-wrapper--right .video-card,
.content-video-wrapper--left .video-card {
  margin: 0 !important;
  padding: 0 !important;
  max-width: 100% !important;
  width: 100% !important;
  box-shadow: none;
}

/* Show the YouTube-style play button on floated inline videos.
   The base rule `.content-video-wrapper .video-card__play-button {
   display: none !important; }` (above) was hiding it on every wrapper.
   For small floated videos the play button is the primary visual cue
   that "this is a video, not just an image" — without it, the
   thumbnail reads as a static editorial photo and editors reported
   visitors not realising they could play it.
   Higher specificity + matching !important beat the base hide rule.
   Layout is delegated to the play button's own CSS (centred SVG
   inside .video-card__container's 16:9 box).
   Background is forced transparent: the SVG already carries its own
   YouTube-red rounded-rect background, so the default
   rgba(0,0,0,0.8) "black circle" wrapper just stacks a dark ring
   around the SVG and looks doubled-up at small sizes. Hover keeps
   the existing scale(1.1) effect for feedback. */
.content-video-wrapper.content-video-wrapper--right .video-card__play-button,
.content-video-wrapper.content-video-wrapper--left .video-card__play-button {
  display: block !important;
  opacity: 1 !important;
  visibility: visible !important;
  pointer-events: auto !important;
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}

.content-video-wrapper.content-video-wrapper--right .video-card__play-button:hover,
.content-video-wrapper.content-video-wrapper--left .video-card__play-button:hover {
  background: transparent !important;
}

@media (min-width: 901px) and (max-width: 1200px) {
  .donation-template.card .content-video-wrapper--right {
    float: right;
    width: 280px;
    max-width: 40%;
    margin: 0 0 1rem 1.5rem;
  }
  .donation-template.card .content-video-wrapper--left {
    float: left;
    width: 280px;
    max-width: 40%;
    margin: 0 1.5rem 1rem 0;
  }
}

/* Mobile/tablet (<901px): inline videos stack full-width. Default (`above`)
   keeps DOM order: title → video → intro. `--mobile-below` flex-reorders
   so the entire intro block precedes the video (author picks in ACF). */
@media (max-width: 900px) {
  .donation-header:has(.content-video-wrapper--mobile-below),
  .petition-content:has(.content-video-wrapper--mobile-below),
  .survey-content:has(.content-video-wrapper--mobile-below) {
    display: flex;
    flex-direction: column;
  }

  .donation-header:has(.content-video-wrapper--mobile-below) .donation-intro,
  .petition-content:has(.content-video-wrapper--mobile-below) .petition-intro,
  .survey-content:has(.content-video-wrapper--mobile-below) .survey-intro {
    order: 1;
  }

  .content-video-wrapper--mobile-below.content-video-wrapper--right,
  .content-video-wrapper--mobile-below.content-video-wrapper--left {
    order: 2;
  }

  /* All inline wrappers: un-float and span full width on mobile/tablet. */
  .content-video-wrapper--right,
  .content-video-wrapper--left {
    float: none !important;
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    margin: 0 0 1.5rem 0 !important;
  }
}

@media (min-width: 901px) {
  .donation-template.card:has(.content-video-wrapper--right) .payment-section,
  .donation-template.card:has(.content-video-wrapper--left) .payment-section {
    clear: both;
  }
}

@media (min-width: 1201px) {
  .donation-template.card .content-video-wrapper--right {
    float: right;
    width: 340px;
    max-width: 40%;
    margin: 0 0 1rem 1.5rem;
  }
  .donation-template.card .content-video-wrapper--left {
    float: left;
    width: 340px;
    max-width: 40%;
    margin: 0 1.5rem 1rem 0;
  }
}

/* Stripe widgets must render full-width — clear the float before the
   payment section (see :has() rule above at min-width 901px). */

/* ========================================
   Suppress editorial images when a floated video is in play
   The donation featured image, petition image and survey image all
   float right at ~350px by default. When the author has ALSO chosen a
   "With content - right/left" video, both elements compete for the
   same column and the layout falls apart — image squeezed under the
   video, or video pushed below the image, depending on heights.
   Easiest editor-friendly fix: the video wins, the image is hidden.
   Author can still see and edit the featured image in admin — it just
   doesn't render on the frontend until they switch to a video position
   that doesn't conflict (large_top, manual, or no video at all).
   :has() scoped to the nearest shared ancestor of each template's
   image + video pair. Supported in Chrome 105+ / Safari 15.4+ /
   Firefox 121+. Older browsers show both — visually messy but not
   broken.
======================================== */

.donation-header:has(.content-video-wrapper--right, .content-video-wrapper--left) .donation-featured-image {
  display: none !important;
}

/* donation-template.css adds a clearfix ::after on
   .donation-intro.has-featured-image to keep the legacy featured-image
   float from leaking into .donation-options. With the featured image
   hidden by the rule above, that clearfix would still fire and force
   .donation-intro to stretch down to the bottom of our floated video —
   wasting vertical space and breaking the "body wraps next to video"
   intent. Suppress the clearfix when a floated video is in play. */
.donation-header:has(.content-video-wrapper--right, .content-video-wrapper--left) .donation-intro.has-featured-image::after {
  content: none !important;
  display: none !important;
  clear: none !important;
}

.petition-content:has(.content-video-wrapper--right, .content-video-wrapper--left) .petition-image {
  display: none !important;
}

.survey-content:has(.content-video-wrapper--right, .content-video-wrapper--left) .survey-image {
  display: none !important;
}

/* ========================================
   Sticky picture-in-picture (PiP) on scroll
   When a visitor has tapped a floated video and then scrolls past it,
   the .video-card detaches via position:fixed into the bottom-right
   corner so they can keep watching while reading the petition / form
   / donation copy. IntersectionObserver in js/video-card.js toggles
   the .video-card--sticky class (desktop only — PiP is disabled below
   768px so it does not cover donate CTAs). Only triggered for floated
   layouts; large_top videos are the focal point and do not PiP.
======================================== */

.video-card.video-card--sticky {
  position: fixed !important;
  bottom: 1rem;
  right: 1rem;
  /* Override the in-flow card padding/margin/max-width so the PiP is
     compact and not framed in unnecessary whitespace. */
  width: 320px !important;
  max-width: 40vw !important;
  margin: 0 !important;
  padding: 0 !important;
  background: #000 !important;
  border-radius: 8px !important;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.35) !important;
  overflow: hidden !important;
  /* Sit above the sticky header (~1000) and most overlays but below
     true modals (which generally use 10000+). */
  z-index: 9999 !important;
}

/* The PiP frame is for watching, not reading — hide the editorial
   chrome so the iframe gets all the pixels. Gated on
   `prefers-reduced-motion: no-preference` so the reduced-motion path
   (which puts the card back into static flow further down) doesn't
   leave a half-broken card with hidden title/description sitting at
   its original position. The negative-form media query keeps title and
   description visible for reduced-motion users, since their .sticky
   class no longer triggers the position:fixed transformation. */
@media (prefers-reduced-motion: no-preference) {
  .video-card.video-card--sticky .video-card__title,
  .video-card.video-card--sticky .video-card__description {
    display: none !important;
  }
}

@media (max-width: 767px) {
  /* Belt-and-suspenders: js/video-card.js skips PiP below 768px. */
  .video-card.video-card--sticky {
    position: static !important;
    width: auto !important;
    max-width: none !important;
    bottom: auto !important;
    right: auto !important;
    box-shadow: none !important;
    z-index: auto !important;
  }

  .video-card.video-card--sticky .video-card__sticky-close {
    display: none !important;
  }
}

/* Respect users who've asked the OS to minimise motion — fixed
   floating elements appearing/disappearing on scroll can be
   disorienting for vestibular sensitivities. We disable the sticky
   behaviour for them rather than try to animate it gently; the video
   stays inline and they can scroll back to it the normal way. */
@media (prefers-reduced-motion: reduce) {
  .video-card.video-card--sticky {
    position: static !important;
    width: auto !important;
    max-width: 100% !important;
    box-shadow: none !important;
  }
}

.video-card__sticky-close {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 28px;
  height: 28px;
  /* Hidden by default; the .video-card--sticky modifier below reveals
     it. Keeps the in-flow card clean and stops the close button from
     ever flashing into view before the IntersectionObserver decides
     to pin. */
  display: none;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: rgba(0, 0, 0, 0.75);
  color: #fff;
  border: none;
  border-radius: 50%;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  z-index: 10;
}

.video-card.video-card--sticky .video-card__sticky-close {
  display: flex;
}

.video-card__sticky-close:hover,
.video-card__sticky-close:focus-visible {
  background: rgba(0, 0, 0, 0.95);
  outline: 2px solid #fff;
  outline-offset: 1px;
}
