/* ============================================================================
   Digital Services — brand-blue field, hexagon mesh, six photo cards.
   ========================================================================= */

.dsx {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background:
    radial-gradient(70% 45% at 50% 0%, rgba(64, 120, 255, .45) 0%, transparent 70%),
    linear-gradient(180deg, #0B3BE3 0%, #1734D8 50%, #2A26C6 100%);
}
.dsx__inner { position: relative; z-index: 1; }

/* --- Background ----------------------------------------------------------- */

.dsx__bg { position: absolute; inset: 0; z-index: 0; pointer-events: none; }

/* A honeycomb laid back in perspective along the lower half, fading out to
   the top and the sides so it reads as a surface, not as a pattern. The
   perspective is on this box; the grid inside only ever translates. */
.dsx__mesh {
  position: absolute;
  left: -20%;
  right: -20%;
  bottom: -18%;
  height: 72%;
  perspective: 900px;
  perspective-origin: 50% 0%;
  -webkit-mask-image: radial-gradient(60% 75% at 50% 70%, #000 0%, rgba(0, 0, 0, .55) 45%, transparent 78%);
  mask-image: radial-gradient(60% 75% at 50% 70%, #000 0%, rgba(0, 0, 0, .55) 45%, transparent 78%);
}
/* Far wider than its box: tilted back in perspective, a grid only as wide as
   the box narrows toward the horizon and showed as a hard-edged trapezoid.
   This wide, its side edges fall outside the mask. */
.dsx__mesh-grid {
  position: absolute;
  inset: -40% -140% -10%;
  transform-origin: 50% 100%;
  transform: rotateX(62deg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='49' viewBox='0 0 28 49'%3E%3Cpath fill='%237FA2FF' fill-opacity='.55' d='M13.99 9.25l13 7.5v15l-13 7.5L1 31.75v-15l12.99-7.5zM3 17.9v12.7l10.99 6.34 11-6.35V17.9l-11-6.34L3 17.9zM0 15l12.98-7.5V0h-2v6.35L0 12.69v2.3zm0 18.5L12.98 41v8h-2v-6.85L0 35.81v-2.3zM15 0v7.5L27.99 15H28v-2.31h-.01L17 6.35V0h-2zm0 49v-8l12.99-7.5H28v2.31h-.01L17 42.15V49h-2z'/%3E%3C/svg%3E");
  background-size: 28px 49px;
  animation: dsx-drift 18s linear infinite;
}
/* One tile height, so the loop is seamless. Transform-only: the tilt is
   repeated in every frame and the grid slides along its own plane. */
@keyframes dsx-drift {
  from { transform: rotateX(62deg) translateY(0); }
  to   { transform: rotateX(62deg) translateY(49px); }
}

.dsx__glow {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(110, 215, 255, .75) 0%, rgba(90, 170, 255, .35) 45%, transparent 72%);
  filter: blur(4px);
  opacity: .7;
  animation: dsx-float 12s ease-in-out infinite alternate;
}
@keyframes dsx-float {
  from { transform: translate3d(0, 0, 0) scale(1); opacity: .45; }
  to   { transform: translate3d(12px, -26px, 0) scale(1.12); opacity: .85; }
}

/* --- Header --------------------------------------------------------------- */

.dsx__head { margin-bottom: clamp(2.25rem, 1.75rem + 2vw, 3.25rem); }
/* The shared header caps titles at 22ch, which stacks this one into four
   lines; the design sets it in two. Set heavy, as the design does. */
.dsx__head .sec-head__title { max-width: 34ch; font-weight: 700; }
.dsx__head .sec-head__body { max-width: 62ch; }
.dsx .sec-head__body .lead { color: rgba(255, 255, 255, .88); }

/* --- Grid ----------------------------------------------------------------- */

/* Flex rather than grid so an incomplete last row centres. Six cards fill
   their rows in threes and twos, but a card added or removed later still
   lands in the middle, as the design sets a lone last card. */
.dsx__grid {
  --gap: clamp(1rem, 0.6rem + 1.2vw, 1.6rem);
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--gap);
  max-width: 74rem;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}
.dsx__item { display: flex; flex: 0 1 100%; min-width: 0; }
@media (min-width: 640px) {
  .dsx__item { flex-basis: calc((100% - var(--gap)) / 2); }
}
@media (min-width: 1000px) {
  .dsx__item { flex-basis: calc((100% - 2 * var(--gap)) / 3); }
}

/* --- Card ----------------------------------------------------------------- */

.ds-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: clamp(0.9rem, 0.75rem + 0.5vw, 1.2rem);
  border-radius: var(--r-lg);
  background: #fff;
  box-shadow: 0 30px 60px -32px rgba(4, 12, 70, .6);
  transition: transform var(--d-base) var(--ease-out-expo),
              box-shadow var(--d-base) var(--ease-out-soft);
}
.ds-card:hover { transform: translateY(-6px); box-shadow: 0 40px 70px -30px rgba(4, 12, 70, .7); }

.ds-card__media {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  border-radius: var(--r-sm);
  background: linear-gradient(135deg, var(--blue-200) 0%, var(--blue-100) 55%, var(--yellow-200) 100%);
}
.ds-card__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: scale 0.9s var(--ease-out-expo);
}
.ds-card:hover .ds-card__media img { scale: 1.05; }

/* Three classes deep on purpose: the section is `.on-ink`, and `.on-ink .h4`
   and `.on-ink .body-sm` repaint headings white and copy pale blue — correct
   on the blue field, invisible on these white cards. */
.dsx .ds-card .ds-card__title {
  margin: 1.1rem 0 0.5rem;
  font-weight: 700;
  color: var(--ink-900);
}
.dsx .ds-card .ds-card__text {
  margin: 0;
  line-height: 1.55;
  color: var(--ink-700);
  text-wrap: pretty;
}
.ds-card__cta { margin-top: auto; padding-top: 1.1rem; }
/* The design's pill is smaller than the site's standard CTA. */
.ds-card__cta .btn { --btn-h: 2.6rem; --btn-pad-x: 1.15rem; --disc: 1.6rem; }

@media (prefers-reduced-motion: reduce) {
  .dsx__mesh-grid, .dsx__glow { animation: none; }
  .ds-card, .ds-card:hover { transition: none; transform: none; }
  .ds-card__media img { transition: none; }
  .ds-card:hover .ds-card__media img { scale: 1; }
}
