/* =============================================================================
   Shared card grid — used by viomedspa/vio-cards (standalone block) and by
   fifty-fifty-flex's "cards" side type. Both render through the same
   vio_render_cards_grid() PHP helper (inc/cards-render.php), so this one
   stylesheet is the single source of truth for how a card looks everywhere.
   ============================================================================= */

.vio-cards__grid {
  display: grid;
  /* Column count comes from the `vio-cards__grid--cols-N` modifier class
     below (set by vio_render_cards_grid()'s `columns` arg) - NOT a custom
     property, since nothing ever actually set --vio-cards-cols, which
     silently left every grid at the var()'s fallback of 3 regardless of
     the requested column count (e.g. 2 cards in a 3-col grid, leaving a
     third of the row empty). */
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2vw, 32px);
  width: 100%;
}
.vio-cards__grid--cols-1 { grid-template-columns: repeat(1, 1fr); }
.vio-cards__grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
.vio-cards__grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
.vio-cards__grid--cols-4 { grid-template-columns: repeat(4, 1fr); }

@media (max-width: 900px) {
  .vio-cards__grid {
    grid-template-columns: repeat(2, 1fr);
  }
  /* A genuinely single-column grid (e.g. one card, or an intentional
     one-per-row layout) stays 1 column instead of being forced to 2. */
  .vio-cards__grid--cols-1 {
    grid-template-columns: repeat(1, 1fr);
  }
}

@media (max-width: 600px) {
  .vio-cards__grid {
    grid-template-columns: 1fr;
  }
}

/* ── Mobile carousel variant ─────────────────────────────────────────
   Opt-in (vio_render_cards_grid()'s `mobile_carousel` arg) - below the
   breakpoint, the grid becomes a horizontal scroll-snap row (one full
   card + a peek of the next) instead of stacking every card full-width,
   with arrows + a progress bar below. Desktop is untouched: the
   `--mobile-carousel` modifier only takes effect inside this same
   max-width:600px query the plain single-column stack already uses. */
@media (max-width: 600px) {
  .vio-cards__grid--mobile-carousel {
    display: flex;
    grid-template-columns: none;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    gap: 16px;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .vio-cards__grid--mobile-carousel::-webkit-scrollbar {
    display: none;
  }
  .vio-cards__grid--mobile-carousel .vio-cards__card {
    flex: 0 0 88%;
    scroll-snap-align: start;
  }
}

/* ── Mobile compact variant ──────────────────────────────────────────
   Opt-in (vio_render_cards_grid()'s `mobile_compact` arg) - stays a plain
   single-column stack (unlike --mobile-carousel above), just with much
   tighter padding and a shorter image, so a long grid takes less vertical
   space without switching to a horizontal-scroll interaction. Desktop is
   untouched - same max-width:600px query the plain stack already uses. */
@media (max-width: 600px) {
  .vio-cards__grid--mobile-compact .vio-cards__card {
    --vio-cards-pad: 14px;
    gap: 0;
  }
  .vio-cards__grid--mobile-compact .vio-cards__media {
    aspect-ratio: 16 / 9;
  }
  .vio-cards__grid--mobile-compact .vio-cards__description {
    font-size: 0.85rem;
  }
  .vio-cards__grid--mobile-compact .vio-cards__details {
    margin-top: 0;
    padding-top: 4px;
    gap: 0;
  }
  /* Compact's whole point is a short card - the CTA's normal margin-top:auto
     (bottom-aligns it to match taller siblings in the same grid row) fights
     that, so this variant alone drops it back to flush-against-the-content-
     above (0/0), instead of just a smaller gap. */
  .vio-cards__grid--mobile-compact .vio-cards__cta {
    margin-top: 0;
    padding-top: 0;
  }
  /* A "hide until location is chosen" CTA (see vio_build_cta_button_html())
     renders a <p class="vio-dyn-cta-prompt"> immediately before the <a>,
     hidden via the `hidden` attribute when a location's already resolved -
     but the global "p + *" content-spacing rule (viomedspa-global.css)
     still matches the <a> by DOM structure regardless of that attribute,
     adding 20px margin-top back even after the overrides above. */
  .vio-cards__grid--mobile-compact .vio-cards__cta a {
    margin-top: 0;
  }
}

.vio-cards__mobile-nav {
  display: none;
}

@media (max-width: 600px) {
  .vio-cards__mobile-nav {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-top: 20px;
  }
}

.vio-cards__mobile-progress-track {
  flex: 1;
  height: 4px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.12);
  position: relative;
}

.vio-cards__mobile-progress-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  transition: left 0.4s ease, width 0.4s ease;
}

/* Scoped under .vio-cards__mobile-nav (2 classes) to beat the global
   `body [class$="__prev"], body [class$="__next"]` override in
   viomedspa-global.css, which otherwise matches ANY class ending in
   __prev/__next - including these - and forces them to 42px/82px (same
   fix as tab-carousel's own arrows). */
.vio-cards__mobile-nav .vio-cards__mobile-nav-btn {
  flex: 0 0 auto;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity 0.2s ease;
  width: 32px;
  height: 32px;
  min-width: 0;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--wp--preset--color--vio-ink, #030303);
}
.vio-cards__mobile-nav .vio-cards__mobile-nav-btn:hover {
  opacity: 1;
}
.vio-cards__mobile-nav .vio-cards__mobile-nav-btn:focus-visible {
  opacity: 1;
  outline: 2px solid var(--wp--preset--color--vio-ink, #030303);
  outline-offset: 2px;
  border-radius: 4px;
}
.vio-cards__mobile-nav .vio-cards__mobile-nav-btn svg {
  display: block;
  pointer-events: none;
  width: 18px;
  height: 18px;
  min-width: 0;
  min-height: 0;
  flex-shrink: 0;
}

.vio-cards__card {
  --vio-cards-pad: clamp(20px, 2.4vw, 32px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: var(--vio-cards-pad);
  background: var(--wp--preset--color--vio-lotion, #FEFFF9);
  /* Force dark text regardless of the section's own color scheme - a card
     always has a light background, so it must never inherit the white
     text a dark section (e.g. vio-ink) applies to everything inside it
     (that would make the card's text invisible against its light bg). */
  color: var(--wp--preset--color--vio-ink, #1a1a1a);
  border-radius: var(--vio-img-radius, 12px);
  /* Needed so the full-bleed media block below gets clipped to this
     card's own rounded corners instead of poking out past them. */
  overflow: hidden;
}

.vio-cards__card--highlight {
  background: var(--wp--preset--color--vio-blue-dark, #3A4A52);
  color: var(--wp--preset--color--vio-lotion, #FEFFF9);
}

.vio-cards__media {
  /* Bleeds past the card's own padding so the image touches the card's
     left/right/top edges, matching the mockup (only the text below stays
     inset). The card's overflow:hidden + border-radius above clip this
     back to the card's rounded corners - no radius needed here. */
  position: relative;
  width: calc(100% + 2 * var(--vio-cards-pad));
  margin: calc(-1 * var(--vio-cards-pad)) calc(-1 * var(--vio-cards-pad)) 0;
  aspect-ratio: 1 / 1;
  background: #fff;
  flex: 0 0 auto;
}

.vio-cards__media-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Zooms/crops to fill the square rather than letterboxing a non-square
     source - intentional trade-off vs. the mockup's own `contain` (which
     never crops), chosen so every card fills edge-to-edge regardless of
     the uploaded photo's aspect ratio. */
  object-fit: cover;
}

/* Stacked layout's badge - a plain uppercase eyebrow label above the
   heading (e.g. a product's brand above its name), same weight/tracking
   convention as .vio-cards__detail-label, instead of the inline layout's
   pill. */
.vio-cards__eyebrow {
  display: block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--wp--preset--color--vio-blue-dark, #3A4A52);
}

.vio-cards__card--highlight .vio-cards__eyebrow {
  color: var(--wp--preset--color--vio-blue-light, #7C95A2);
}

.vio-cards__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.vio-cards__heading {
  margin: 0;
  font-size: calc(1.05rem * var(--vio-cards-heading-mult, 1));
}

/* Heading/figure size overrides - same xs..3xl multiplier scale as every
   other "Title Size" control site-wide (viomedspa-global.css's
   .vio-section__title.size-* pattern). */
.vio-cards__heading.size-xs  { --vio-cards-heading-mult: 0.64; }
.vio-cards__heading.size-sm  { --vio-cards-heading-mult: 0.8; }
.vio-cards__heading.size-lg  { --vio-cards-heading-mult: 1.25; }
.vio-cards__heading.size-xl  { --vio-cards-heading-mult: 1.56; }
.vio-cards__heading.size-xxl { --vio-cards-heading-mult: 1.95; }
.vio-cards__heading.size-3xl { --vio-cards-heading-mult: 3.0; }

.vio-cards__badge {
  flex: 0 0 auto;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.08);
  white-space: nowrap;
}

.vio-cards__card--highlight .vio-cards__badge {
  background: rgba(255, 255, 255, 0.16);
}

.vio-cards__figure {
  margin: 0;
  font-size: calc(clamp(1.8rem, 3vw, 2.4rem) * var(--vio-cards-figure-mult, 1));
  line-height: 1.1;
  font-family: var(--wp--preset--font-family--heading, inherit);
}
.vio-cards__figure.size-xs  { --vio-cards-figure-mult: 0.64; }
.vio-cards__figure.size-sm  { --vio-cards-figure-mult: 0.8; }
.vio-cards__figure.size-lg  { --vio-cards-figure-mult: 1.25; }
.vio-cards__figure.size-xl  { --vio-cards-figure-mult: 1.56; }
.vio-cards__figure.size-xxl { --vio-cards-figure-mult: 1.95; }
.vio-cards__figure.size-3xl { --vio-cards-figure-mult: 3.0; }

.vio-cards__description {
  margin: 0;
  font-size: 0.9rem;
  opacity: 0.8;
}

/* Job Tag - short eyebrow-style label under the description (e.g. "Clear
   pores"), same weight/tracking convention as .vio-cards__eyebrow. */
.vio-cards__job-tag {
  display: block;
  margin-top: 8px;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.6;
}

.vio-cards__details {
  list-style: none;
  margin: 8px 0 0;
  padding: 12px 0 0;
  border-top: 1px solid currentColor;
  border-top-color: rgba(0, 0, 0, 0.1);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.vio-cards__card--highlight .vio-cards__details {
  border-top-color: rgba(255, 255, 255, 0.18);
}

.vio-cards__detail {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.vio-cards__detail-label {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* Default (no Detail label color set) keeps the muted look. A color picked in
   the editor is inline-styled and shows at full strength instead, so the
   contrast matches the picked color. */
.vio-cards__detail-label:not([style]) {
  opacity: 0.65;
}

.vio-cards__detail-text {
  font-size: 0.9rem;
}

.vio-cards__cta {
  margin-top: auto;
  padding-top: 8px;
}

/* ── Package offers card style ──────────────────────────────────────────
   Opt-in via the 50/50 Flex copy side's "Card style: Package offers" (grid
   gets .vio-cards__grid--offer). Card anatomy, all from existing card
   fields: photo, heading, Detail rows (row 1 = member offer on a plum
   block, later rows = non-member row, each with an optional big figure),
   and the CTA as a full-width bar. The whole card is clickable via the
   CTA link's stretched ::after. Colors come only from the site palettes:
   BF Plum / BF Pale Bronze (Promo Colors) plus Vio Ink, Vio Alabaster and
   Vio Lotion (theme). Light card sections are Vio Lotion. Every pair used is WCAG AA
   (pale bronze / alabaster on plum, ink on lotion, alabaster on ink). Card corners keep the site's own
   radius. */
.vio-cards__grid--offer .vio-cards__card {
  --vio-offer-plum: var(--wp--preset--color--promo-bf-plum);
  --vio-offer-graphite: var(--wp--preset--color--vio-ink);
  --vio-offer-pale-gold: var(--wp--preset--color--promo-bf-pale-bronze);
  --vio-offer-alabaster: var(--wp--preset--color--vio-alabaster);
  --vio-offer-lotion: var(--wp--preset--color--vio-lotion);
  position: relative;
  padding: 0;
  gap: 0;
  background: var(--vio-offer-lotion);
  color: var(--vio-offer-graphite);
  border: 1px solid color-mix(in srgb, var(--vio-offer-graphite) 10%, transparent);
}
.vio-cards__grid--offer .vio-cards__media {
  width: 100%;
  margin: 0;
  aspect-ratio: 1 / 1;
}
.vio-cards__grid--offer .vio-cards__media-img {
  object-position: center 30%;
}
.vio-cards__grid--offer .vio-cards__head {
  padding: 18px 18px 16px;
}
.vio-cards__grid--offer .vio-cards__heading {
  font-family: var(--vio-bf-display, inherit);
  font-weight: 500;
  font-size: calc(22px * var(--vio-cards-heading-mult, 1));
  letter-spacing: -0.01em;
  line-height: 1.1;
  margin: 0;
}
.vio-cards__grid--offer .vio-cards__details {
  /* auto top margin pins the offer rows + CTA bar to the card bottom, so
     cards in a row line up even when their descriptions differ in length. */
  margin: auto 0 0;
  padding: 0;
  border-top: 0;
  gap: 0;
}
.vio-cards__grid--offer .vio-cards__detail {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  column-gap: 12px;
  row-gap: 4px;
  padding: 18px;
}
.vio-cards__grid--offer .vio-cards__detail-label {
  font-family: var(--vio-bf-italic, Georgia, serif);
  font-style: italic;
  font-weight: 300;
  font-size: 22px;
  letter-spacing: 0;
  text-transform: none;
  opacity: 1;
}
.vio-cards__grid--offer .vio-cards__detail-text {
  font-size: 14px;
}
.vio-cards__grid--offer .vio-cards__detail-figure {
  flex: 1 0 100%;
  font-family: var(--vio-bf-display, inherit);
  font-weight: 500;
  letter-spacing: -0.03em;
  line-height: 0.95;
  text-transform: uppercase;
  overflow-wrap: anywhere;
}
/* Member offer: plum block. */
.vio-cards__grid--offer .vio-cards__detail--member {
  background: var(--vio-offer-plum);
  color: var(--vio-offer-alabaster);
}
.vio-cards__grid--offer .vio-cards__detail--member .vio-cards__detail-label {
  font-size: 26px;
  color: var(--vio-offer-pale-gold);
}
.vio-cards__grid--offer .vio-cards__detail--member .vio-cards__detail-figure {
  font-size: clamp(44px, 4.5vw, 64px);
}
/* Non-member row: outlined, quieter. */
.vio-cards__grid--offer .vio-cards__detail--nonmember {
  color: var(--vio-offer-graphite);
  border-top: 1px solid color-mix(in srgb, var(--vio-offer-graphite) 10%, transparent);
}
.vio-cards__grid--offer .vio-cards__detail--nonmember .vio-cards__detail-figure {
  font-size: 32px;
  color: var(--vio-offer-graphite);
}
/* CTA: full-width bar; stretched link makes the whole card clickable. */
.vio-cards__grid--offer .vio-cards__cta {
  margin: 0;
  padding: 0;
}
.vio-cards__grid--offer .vio-cards__cta a {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 54px;
  margin: 0;
  border-radius: 0;
  background: var(--vio-offer-graphite);
  color: var(--vio-offer-alabaster);
  border: 0;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}
.vio-cards__grid--offer .vio-cards__cta a::after {
  content: '';
  position: absolute;
  inset: 0;
}
.vio-cards__grid--offer .vio-cards__cta a:focus-visible {
  outline: 3px solid var(--vio-offer-pale-gold);
  outline-offset: -6px;
}

/* ── Date band card style ───────────────────────────────────────────────
   Opt-in via the 50/50 Flex copy side's "Card style: Date bands". Flat,
   compact cards for short "who / when" blocks (e.g. Members Nov 16-30,
   Everyone Nov 23-30): italic label, small line, big uppercase figure.
   Background and text color come from each card's own Background / Text
   color settings (inline), so contrast is set per card. */
.vio-cards__grid--band {
  gap: 8px;
}
.vio-cards__grid--band .vio-cards__card {
  padding: 18px 20px;
  gap: 8px;
  border-radius: var(--vio-img-radius, 12px);
}
.vio-cards__grid--band .vio-cards__head {
  display: block;
}
.vio-cards__grid--band .vio-cards__heading {
  font-family: var(--vio-bf-italic, Georgia, serif);
  font-style: italic;
  font-weight: 300;
  font-size: calc(clamp(32px, 3vw, 42px) * var(--vio-cards-heading-mult, 1));
  line-height: 1;
  letter-spacing: 0;
  margin: 0;
}
.vio-cards__grid--band .vio-cards__description {
  font-size: 16px;
  margin: 0;
  opacity: 1;
}
.vio-cards__grid--band .vio-cards__figure {
  font-family: var(--vio-bf-display, inherit);
  font-weight: 500;
  font-size: calc(clamp(36px, 3.4vw, 48px) * var(--vio-cards-figure-mult, 1));
  line-height: 1;
  letter-spacing: -0.03em;
  text-transform: uppercase;
  margin: 0;
}

.vio-cards__grid--band .vio-cards__head { order: 1; }
.vio-cards__grid--band .vio-cards__description { order: 2; }
.vio-cards__grid--band .vio-cards__figure { order: 3; }

/* "30% OFF": the renderer wraps a trailing OFF in .vio-cards__off so the
   percent stays big and OFF sits smaller beside it. */
.vio-cards__grid--offer .vio-cards__off {
  font-size: 0.4em;
  letter-spacing: 0;
  margin-left: 0.15em;
}
/* Included-items line under the package name. */
.vio-cards__grid--offer .vio-cards__description {
  margin: 0;
  padding: 0 18px 16px;
  font-size: 0.85rem;
  line-height: 1.4;
  opacity: 0.8;
}

/* ── Rows card style ────────────────────────────────────────────────────
   Opt-in via "Card style: Rows". A flat label / value list, e.g. membership
   tiers: the card heading on the left, its figure (bold) on the right, a
   hairline above each row and under the last. Always one column. Text and
   hairline color follow the surrounding section (currentColor), so it works
   on light and dark sections without any color of its own. Only heading and
   figure are shown; badge, description, details and images are not part of
   this look. */
.vio-cards__grid.vio-cards__grid--rows {
  grid-template-columns: 1fr;
  gap: 0;
}
.vio-cards__grid--rows .vio-cards__card {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
  padding: 14px 0;
  background: transparent;
  color: inherit;
  border: 0;
  border-top: 1px solid color-mix(in srgb, currentColor 15%, transparent);
  border-radius: 0;
}
.vio-cards__grid--rows .vio-cards__card:last-child {
  border-bottom: 1px solid color-mix(in srgb, currentColor 15%, transparent);
}
.vio-cards__grid--rows .vio-cards__media,
.vio-cards__grid--rows .vio-cards__badge,
.vio-cards__grid--rows .vio-cards__eyebrow,
.vio-cards__grid--rows .vio-cards__description,
.vio-cards__grid--rows .vio-cards__job-tag,
.vio-cards__grid--rows .vio-cards__details {
  display: none;
}
.vio-cards__grid--rows .vio-cards__head {
  flex: 1 1 auto;
  display: block;
}
.vio-cards__grid--rows .vio-cards__heading {
  margin: 0;
  font-family: inherit;
  font-weight: 400;
  font-size: calc(1rem * var(--vio-cards-heading-mult, 1));
  line-height: 1.3;
  letter-spacing: 0;
}
.vio-cards__grid--rows .vio-cards__figure {
  margin: 0;
  font-family: inherit;
  font-weight: 700;
  font-size: calc(1rem * var(--vio-cards-figure-mult, 1));
  line-height: 1.3;
  text-align: right;
}

/* Heading weight (headingWeight / cardHeadingWeight) - opt-in classes only. */
.vio-cards__card .vio-cards__heading.weight-normal   { font-weight: 400; }
.vio-cards__card .vio-cards__heading.weight-semibold { font-weight: 600; }
.vio-cards__card .vio-cards__heading.weight-bold     { font-weight: 700; }

/* ── Per-card video (mediaType = video) ──────────────────────────────────────── */
.vio-cards__media--video { position: relative; aspect-ratio: 16 / 9; overflow: hidden; background: #000; }
.vio-cards__media--video video,
.vio-cards__media--video iframe,
.vio-cards__media--video .vio-cards__media-img {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0; object-fit: cover; display: block;
}
.vio-cards__media--video video { object-fit: contain; background: #000; }
.vio-cards__play {
  position: absolute; top: 50%; left: 50%; z-index: 2; transform: translate(-50%, -50%);
  width: 72px; height: 72px; display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: rgba(41, 41, 41, 0.65); color: var(--wp--preset--color--vio-lotion, #FEFFF9);
  text-decoration: none; transition: transform 0.2s ease;
}
.vio-cards__media--video .vio-cards__play svg { margin-left: 6%; }
.vio-cards__play:hover { transform: translate(-50%, -50%) scale(1.06); }
.vio-cards__play:focus-visible { outline: 3px solid var(--wp--preset--color--vio-lotion, #FEFFF9); outline-offset: 4px; }

/* ── Flat cards (cardStyle = flat) + centered text (cardsTextAlign = center) ─── */
.vio-cards__grid--flat .vio-cards__card { background: transparent; padding: 0; border: 0; box-shadow: none; border-radius: 0; }
.vio-cards__grid--flat .vio-cards__media { margin: 0 0 16px; }
.vio-cards__grid--align-center .vio-cards__card { text-align: center; }
.vio-cards__grid--align-center .vio-cards__head { justify-content: center; }

/* Optional description / badge / detail-text sizes (same scale as heading + figure sizes). */
.vio-cards__description.size-xs { font-size: calc(0.9rem * 0.64); }
.vio-cards__description.size-sm { font-size: calc(0.9rem * 0.8); }
.vio-cards__description.size-lg { font-size: calc(0.9rem * 1.25); }
.vio-cards__description.size-xl { font-size: calc(0.9rem * 1.56); }
.vio-cards__description.size-xxl { font-size: calc(0.9rem * 1.95); }
.vio-cards__description.size-3xl { font-size: calc(0.9rem * 3.0); }
.vio-cards__badge.size-xs, .vio-cards__eyebrow.size-xs { font-size: calc(0.7rem * 0.64); }
.vio-cards__badge.size-sm, .vio-cards__eyebrow.size-sm { font-size: calc(0.7rem * 0.8); }
.vio-cards__badge.size-lg, .vio-cards__eyebrow.size-lg { font-size: calc(0.7rem * 1.25); }
.vio-cards__badge.size-xl, .vio-cards__eyebrow.size-xl { font-size: calc(0.7rem * 1.56); }
.vio-cards__badge.size-xxl, .vio-cards__eyebrow.size-xxl { font-size: calc(0.7rem * 1.95); }
.vio-cards__badge.size-3xl, .vio-cards__eyebrow.size-3xl { font-size: calc(0.7rem * 3.0); }
.vio-cards__detail-text.size-xs { font-size: calc(0.9rem * 0.64); }
.vio-cards__detail-text.size-sm { font-size: calc(0.9rem * 0.8); }
.vio-cards__detail-text.size-lg { font-size: calc(0.9rem * 1.25); }
.vio-cards__detail-text.size-xl { font-size: calc(0.9rem * 1.56); }
.vio-cards__detail-text.size-xxl { font-size: calc(0.9rem * 1.95); }
.vio-cards__detail-text.size-3xl { font-size: calc(0.9rem * 3.0); }

/* Optional text transform + letter spacing on card text parts (vio-tt-* / vio-ls-*). */
.vio-cards__card .vio-tt-uppercase { text-transform: uppercase; }
.vio-cards__card .vio-tt-none { text-transform: none; }
.vio-cards__card .vio-ls-tight { letter-spacing: -0.02em; }
.vio-cards__card .vio-ls-normal { letter-spacing: normal; }
.vio-cards__card .vio-ls-wide { letter-spacing: 0.05em; }
.vio-cards__card .vio-ls-wider { letter-spacing: 0.1em; }

/* Card subheading (under the heading), media caption overlay, and the optional play ring. */
.vio-cards__card .vio-cards__subheading { margin: 4px 0 0; font-size: 0.875rem; line-height: 1.4; opacity: 0.75; }
.vio-cards__card .vio-cards__subheading.weight-normal { font-weight: 400; }
.vio-cards__card .vio-cards__subheading.weight-semibold { font-weight: 600; }
.vio-cards__card .vio-cards__subheading.weight-bold { font-weight: 700; }
.vio-cards__card .vio-cards__subheading.size-xs { font-size: calc(0.875rem * 0.64); }
.vio-cards__card .vio-cards__subheading.size-sm { font-size: calc(0.875rem * 0.8); }
.vio-cards__card .vio-cards__subheading.size-lg { font-size: calc(0.875rem * 1.25); }
.vio-cards__card .vio-cards__subheading.size-xl { font-size: calc(0.875rem * 1.56); }
.vio-cards__card .vio-cards__subheading.size-xxl { font-size: calc(0.875rem * 1.95); }
.vio-cards__card .vio-cards__subheading.size-3xl { font-size: calc(0.875rem * 3.0); }

.vio-cards__media:has(.vio-cards__media-caption) { position: relative; }
.vio-cards__media-caption {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1; pointer-events: none;
  padding: 28px 14px 10px; font-size: 0.8125rem; line-height: 1.3; color: #fff;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0));
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); text-align: left;
}
.vio-cards__media.is-playing .vio-cards__media-caption { display: none; }
.vio-cards__media-caption.size-xs { font-size: calc(0.8125rem * 0.64); }
.vio-cards__media-caption.size-sm { font-size: calc(0.8125rem * 0.8); }
.vio-cards__media-caption.size-lg { font-size: calc(0.8125rem * 1.25); }
.vio-cards__media-caption.size-xl { font-size: calc(0.8125rem * 1.56); }
.vio-cards__media-caption.size-xxl { font-size: calc(0.8125rem * 1.95); }
.vio-cards__media-caption.size-3xl { font-size: calc(0.8125rem * 3.0); }

/* Play ring (cardPlayButtonStyle = ring): outlined circle, 1px ring, ~70px, plain triangle. */
.vio-cards__grid--play-ring .vio-cards__media--video .vio-cards__play {
  width: 70px; height: 70px; background: transparent; box-shadow: none;
  border: 1px solid var(--vio-cards-play-color, #fff); color: var(--vio-cards-play-color, #fff);
}

/* Optional figure weight (cardFigureWeight / figureWeight). */
.vio-cards__card .vio-cards__figure.weight-normal   { font-weight: 400; }
.vio-cards__card .vio-cards__figure.weight-semibold { font-weight: 600; }
.vio-cards__card .vio-cards__figure.weight-bold     { font-weight: 700; }
