.srv.v8 {

   /* Background (Figma 15301-27872): the room photo sits at 60% over the section's
      own surface, then a top-down gradient takes it back to that surface by 37.5%
      down — so the windows read behind the header column and the card tops, and the
      cards' yellow bands land on flat color. --img-bg-o is the framework's own
      background-image dimmer (make.css ships 0.2 site-wide); the comp is lighter on
      the photo than that default. The wash goes on the .bg wrapper, matching the
      MainstageV6 `> .bg::after` idiom, and derives from --background so a palette
      swap carries the fade with it. */
   --img-bg-o: 0.6;

   > .bg::after {
      content: '';
      position: absolute;
      inset: 0;
      background: linear-gradient(to bottom,
                  hsl(from var(--background) h s l / 0) 0%,
                  var(--background) 37.5%);
   }

   /* Design (Figma 15301-27872): the service cards crop square here, not to the
      16:9 the shared ServiceItem markup asks for. Targeted by the aspect-utility
      hook rather than the .asp_16-9 name, so it survives a markup change. */
   [data-role="item"] picture[class*="asp_"] :where(img, video) {
      aspect-ratio: 1 / 1;
   }

   /* The comp caps each card with a solid button-yellow band carrying the title.
      Same tokens .btn-clr resolves, so the band follows a palette swap; the inner
      arrow chip then sits yellow-on-yellow and reads as a bare glyph, as designed. */
   [data-role="item"] .crd > .ato {
      --background: var(--btn-pry);
      --text-color: var(--btn-pry-txt);
      background-color: var(--background);
      color: var(--text-color);

      /* The arrow chip is .btn-clr, whose --text-color is white in this palette.
         On the yellow band that glyph vanishes, so pin it to the button text token. */
      .btn-clr {
         --background: transparent;
         --text-color: var(--btn-pry-txt);
         color: var(--text-color);
      }
   }

   /* Hover: the catalog pairs hvr_op-lst (every sibling fades to 50%) with hvr_zm
      (the hovered card's photo scales inside its frame). Here the sibling fade is
      the loud half — it reads as the OTHER cards reacting while the one under the
      cursor sits still. Siblings stay put; the hovered card answers on its own with
      a slightly deeper photo zoom and the button arrow-travel.

      The arrow rule is the theme's .btn behaviour (themes/CastleWindows/theme.css)
      re-pointed at the card: the chip here is .btn-clr furniture, not a .btn, so the
      theme's own selector deliberately skips it. Same token, same easing. */
   [data-role="item"] .crd {
      --hvr-zm-amt: 1.08;
   }

   @media (hover: hover) and (pointer: fine) {

      ul:has(.hvr_op-lst:is(:hover, :focus-visible)) .hvr_op-lst:not(:is(:hover, :focus-visible)) {
         opacity: 1;
      }

      [data-role="item"] > a:is(:hover, :focus-visible) .btn-arw-trk {
         transform: translateX(var(--btn-arw-trv));
      }

   }

   @media screen and (min-width: 1280px) {
      .fifth {
         width: 22%;
      }

      /* Card titles run fnt_t-2 per the comp, but its 1.875rem desktop step is set for
         full-width headings — in a quarter-width card it crowds the arrow chip. Rebinding
         the token rather than setting font-size keeps the rest of the type declaration
         (family, weight, leading, tracking) on fnt_t-2 and leaves the class free to
         re-resolve. Same breakpoint font-declaration.css swaps in the -d desktop step at,
         so below 1280 the card keeps the stock mobile size. */
      [data-role="item"] .fnt_t-2 {
         --fnt-t-2-s: 1.475rem; /* { min: 1, max: 2, step: 0.025, friendly: 'Service Card Title Size Desktop' } */
      }

    .grd.mx-4 {
         --itm-val: 25;
      }
   }

}
