/* ==========================================================================
   XlabMW — "What We Do" services section (home variant 14)
   Layout, panel interaction, viewport reveal and all SVG visual motion.
   Brand tokens (--xlab-accent, --xlab-ink, --xlab-muted) come from
   xlab-focus-hero.css.
   ========================================================================== */

.xlab-services {
    --xlab-ease: cubic-bezier(.22, 1, .36, 1);
    position: relative;
    isolation: isolate;
    overflow: hidden;
    padding: clamp(64px, 8vw, 110px) 0 clamp(56px, 7vw, 96px);
    background: #fff;
    scroll-margin-top: 88px;
}

.xlab-services > .container {
    position: relative;
    z-index: 1;
}

.xlab-services__texture {
    position: absolute;
    inset: 0;
    z-index: 0;
    background-image: url("../img/xlab/atmosphere-hex.png");
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    opacity: .12;
    mix-blend-mode: multiply;
    pointer-events: none;
}

.xlab-services__figure {
    position: absolute;
    right: -8%;
    top: 4%;
    z-index: 0;
    width: min(64vw, 860px);
    height: 78%;
    background: url("../img/xlab/atmosphere-network.png") right center / cover no-repeat;
    opacity: .34;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 32%, #000 78%, transparent 100%), linear-gradient(180deg, transparent, #000 16%, #000 84%, transparent);
    mask-image: linear-gradient(90deg, transparent 0%, #000 32%, #000 78%, transparent 100%), linear-gradient(180deg, transparent, #000 16%, #000 84%, transparent);
    -webkit-mask-composite: source-in;
    mask-composite: intersect;
}

/* Background network pattern — must never compete with the panels */
.xlab-services__bg {
    position: absolute;
    inset: 0;
    z-index: 0;
    width: 100%;
    height: 100%;
    color: var(--xlab-ink, #11131a);
    opacity: .55;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(180deg, transparent, #000 18%, #000 82%, transparent);
    mask-image: linear-gradient(180deg, transparent, #000 18%, #000 82%, transparent);
}

.xlab-services__bg-link {
    fill: none;
    stroke: var(--xlab-accent, #a384fb);
    stroke-opacity: .12;
    stroke-width: 1;
}

.xlab-services__bg-node {
    fill: var(--xlab-accent, #a384fb);
    opacity: .22;
    animation: xlabBgDrift 24s ease-in-out infinite alternate;
    animation-delay: calc(var(--i, 0) * -5s);
}

/* Header ------------------------------------------------------------------ */
.xlab-services__head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 32px;
    margin-bottom: clamp(40px, 5vw, 64px);
}

.xlab-services__intro {
    max-width: 660px;
}

.xlab-services__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 18px;
    color: #7458dc;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .18em;
    line-height: 1.6;
    text-transform: uppercase;
}

.xlab-services__eyebrow::before {
    content: "";
    width: 22px;
    height: 2px;
    border-radius: 2px;
    background: var(--xlab-accent, #a384fb);
}

.xlab-services__title {
    margin: 0;
    color: var(--xlab-ink, #11131a);
    font-size: clamp(34px, 3.6vw, 52px);
    font-weight: 700;
    letter-spacing: -.035em;
    line-height: 1.05;
}

.xlab-services__lead {
    max-width: 580px;
    margin: 18px 0 0;
    color: var(--xlab-muted, #626878);
    font-size: 17px;
    line-height: 1.7;
}

.xlab-services__all {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 10px;
    min-height: 48px;
    padding: 12px 20px;
    border: 1px solid #d9dce6;
    border-radius: 999px;
    background: rgba(255, 255, 255, .8);
    color: var(--xlab-ink, #11131a);
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
    transition: border-color .3s ease, color .3s ease, transform .3s var(--xlab-ease), box-shadow .3s ease;
}

.xlab-services__all span {
    display: inline-block;
    font-size: 17px;
    line-height: 1;
    transition: transform .3s var(--xlab-ease);
}

.xlab-services__all:hover,
.xlab-services__all:focus-visible {
    border-color: var(--xlab-accent, #a384fb);
    color: #6346c8;
    transform: translateY(-2px);
    box-shadow: 0 10px 26px rgba(46, 38, 77, .1);
}

.xlab-services__all:hover span,
.xlab-services__all:focus-visible span {
    transform: translateX(4px);
}

/* Grid & panels ----------------------------------------------------------- */
.xlab-services__grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 22px;
}

.xlab-service-cell {
    min-width: 0;
}

.xlab-service {
    --xlab-panel-tint: #f6f3ff;
    --xlab-icon-bg: #f3efff;
    --xlab-icon-fg: #6c4dd4;
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
    border: 1px solid rgba(80, 84, 105, .13);
    border-radius: 22px;
    background: linear-gradient(180deg, #fff 0%, #fff 52%, var(--xlab-panel-tint) 100%);
    box-shadow: 0 10px 30px rgba(30, 33, 46, .05);
    transition: transform .45s var(--xlab-ease), border-color .35s ease, box-shadow .45s ease;
}

.xlab-service[data-visual="web"]            { --xlab-panel-tint: #f6f3ff; }
.xlab-service[data-visual="automation"]     { --xlab-panel-tint: #f0f6ff; --xlab-icon-bg: #eaf3ff; --xlab-icon-fg: #3775d6; }
.xlab-service[data-visual="ecommerce"]      { --xlab-panel-tint: #fff5ee; --xlab-icon-bg: #fff1e6; --xlab-icon-fg: #d97a3a; }
.xlab-service[data-visual="infrastructure"] { --xlab-panel-tint: #eefaf6; --xlab-icon-bg: #e6f7f2; --xlab-icon-fg: #1f9c86; }
.xlab-service[data-visual="database"]       { --xlab-panel-tint: #f0f4ff; --xlab-icon-bg: #e9efff; --xlab-icon-fg: #3f6fe0; }
.xlab-service[data-visual="marketing"]      { --xlab-panel-tint: #fff1f7; --xlab-icon-bg: #ffe9f2; --xlab-icon-fg: #d84f8f; }
.xlab-service[data-visual="security"]       { --xlab-panel-tint: #f4f1ff; }
.xlab-service[data-visual="data"]           { --xlab-panel-tint: #eef8fc; --xlab-icon-bg: #e6f5fa; --xlab-icon-fg: #1f8fb0; }

.xlab-service:hover,
.xlab-service:focus-within {
    transform: translateY(-4px);
    border-color: rgba(163, 132, 251, .55);
    box-shadow: 0 22px 50px rgba(46, 38, 77, .12), 0 0 0 1px rgba(163, 132, 251, .08);
}

.xlab-service__body {
    padding: 26px 24px 18px;
}

.xlab-service__icon {
    display: inline-flex;
    width: 46px;
    height: 46px;
    align-items: center;
    justify-content: center;
    margin-bottom: 20px;
    border-radius: 14px;
    background: var(--xlab-icon-bg);
    color: var(--xlab-icon-fg);
    font-size: 20px;
    transition: transform .4s var(--xlab-ease), background-color .3s ease;
}

.xlab-service__icon i {
    font-size: inherit;
    line-height: 1;
}

.xlab-service__icon i::before {
    font-size: inherit;
    line-height: 1;
    margin: 0;
}

.xlab-service__icon img {
    width: 22px;
    height: 22px;
    object-fit: contain;
}

.xlab-service:hover .xlab-service__icon,
.xlab-service:focus-within .xlab-service__icon {
    transform: translateY(-2px) rotate(-4deg);
}

.xlab-service__title {
    margin: 0 0 10px;
    color: var(--xlab-ink, #11131a);
    font-size: 19px;
    font-weight: 700;
    letter-spacing: -.02em;
    line-height: 1.25;
    transition: color .3s ease;
}

.xlab-service:hover .xlab-service__title {
    color: #5a3fc4;
}

.xlab-service__excerpt {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    margin: 0 0 16px;
    color: var(--xlab-muted, #626878);
    font-size: 14px;
    line-height: 1.6;
}

.xlab-service__link {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    color: #6c4dd4;
    font-size: 13px;
    font-weight: 700;
    outline: none;
}

/* Whole panel is clickable through the single accessible link */
.xlab-service__link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
}

.xlab-service__link:hover,
.xlab-service__link:focus {
    color: #5a3fc4;
}

.xlab-service__link span {
    display: inline-block;
    font-size: 16px;
    line-height: 1;
    transition: transform .3s var(--xlab-ease);
}

.xlab-service:hover .xlab-service__link span,
.xlab-service:focus-within .xlab-service__link span {
    transform: translateX(4px);
}

.xlab-service__visual {
    margin-top: auto;
    padding: 0 14px 14px;
}

.xlab-service__visual-frame {
    position: relative;
    overflow: hidden;
    aspect-ratio: 16 / 10;
    border: 1px solid rgba(80, 84, 105, .09);
    border-radius: 16px;
    background: linear-gradient(160deg, #fff 0%, var(--xlab-panel-tint) 100%);
    transition: border-color .35s ease;
}

.xlab-service:hover .xlab-service__visual-frame {
    border-color: rgba(163, 132, 251, .3);
}

/* Viewport reveal --------------------------------------------------------- */
/* [data-reveal] is set by JS, so without JS everything is visible at once. */
.xlab-services[data-reveal] .xlab-services__head,
.xlab-services[data-reveal] .xlab-service-cell {
    opacity: 0;
}

.xlab-services[data-reveal].is-inview .xlab-services__head {
    animation: xlabReveal .8s var(--xlab-ease) both;
}

.xlab-services[data-reveal].is-inview .xlab-service-cell {
    animation: xlabReveal .8s var(--xlab-ease) both;
    animation-delay: var(--xlab-delay, 0ms);
}

/* Hold SVG motion until the section has entered the viewport */
.xlab-services[data-reveal]:not(.is-inview) .xlab-visual [class*="xv-"] {
    animation-play-state: paused;
}

/* ==========================================================================
   SVG visuals — shared palette
   ========================================================================== */
.xlab-visual {
    --xv-accent: var(--xlab-accent, #a384fb);
    --xv-accent-deep: #7458dc;
    --xv-ink: #1d2030;
    --xv-muted: #c9ccd8;
    --xv-soft: #eef0f6;
    --xv-border: #dfe2ec;
    --xv-tint: #efeaff;
    --xv-tint-b: #e6f7f2;
    --xv-tint-c: #fff1e6;
    --xv-secondary: #2bb5a0;
    --xv-speed: 1;
    display: block;
    width: 100%;
    height: 100%;
    overflow: visible;
    font-family: inherit;
}

.xlab-visual--database .xv-surface {
    stroke: rgba(80, 84, 105, .22);
}

.xlab-visual--database .xv-cyl-top {
    fill: #dce6ff;
}
.xlab-visual--automation     { --xv-secondary: #3a9be6; }
.xlab-visual--ecommerce      { --xv-secondary: #f2994a; }
.xlab-visual--infrastructure { --xv-secondary: #22b3a2; }
.xlab-visual--database       { --xv-secondary: #4f8ff7; }
.xlab-visual--marketing      { --xv-secondary: #ec6aa8; }
.xlab-visual--security       { --xv-secondary: #f08a4b; }
.xlab-visual--data           { --xv-secondary: #2bb1d6; }

/* Hover: visuals become slightly more active */
.xlab-service:hover .xlab-visual,
.xlab-service:focus-within .xlab-visual {
    --xv-speed: .72;
}

.xlab-visual text {
    fill: var(--xv-ink);
    font-family: inherit;
    font-weight: 600;
}

.xv-surface,
.xv-card {
    fill: #fff;
    stroke: var(--xv-border);
    stroke-width: 1;
}

.xv-stroke {
    fill: none;
    stroke: var(--xv-border);
    stroke-width: 1;
}

.xv-stroke--faint { stroke-opacity: .55; }

.xv-soft        { fill: var(--xv-soft); }
.xv-line-fill   { fill: var(--xv-muted); }
.xv-ink-fill    { fill: var(--xv-ink); }
.xv-accent-fill { fill: var(--xv-accent); }
.xv-secondary-fill { fill: var(--xv-secondary); }
.xv-tint-fill   { fill: var(--xv-tint); }
.xv-tint-fill--b { fill: var(--xv-tint-b); }
.xv-tint-fill--c { fill: var(--xv-tint-c); }

.xv-accent-stroke,
.xv-secondary-stroke,
.xv-ink-stroke {
    fill: none;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.xv-accent-stroke    { stroke: var(--xv-accent); }
.xv-secondary-stroke { stroke: var(--xv-secondary); }
.xv-ink-stroke       { stroke: var(--xv-ink); stroke-width: 1.5; }
.xv-ink-stroke--line { stroke: var(--xv-accent-deep); stroke-width: 2; }

.xv-dot--a { fill: #f2994a; }
.xv-dot--b { fill: #f5c542; }
.xv-dot--c { fill: #2bb5a0; }

.xv-label {
    font-size: 10px;
    fill: var(--xv-ink);
}

.xv-label--small { font-size: 8.5px; }

.xv-label--muted {
    font-size: 8px;
    font-weight: 600;
    fill: #8c91a0;
}

.xv-stat {
    font-size: 13px;
    font-weight: 700;
    letter-spacing: -.02em;
    fill: var(--xv-ink);
}

.xv-code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    font-weight: 700;
    fill: #fff;
}

.xv-code--small { font-size: 7px; letter-spacing: .04em; }

.xv-code--mono {
    font-size: 7px;
    font-weight: 600;
    fill: #9a9fb0;
}

.xv-badge {
    font-size: 8px;
    font-weight: 700;
    fill: #fff;
}

.xv-connector {
    fill: none;
    stroke: var(--xv-border);
    stroke-width: 1.5;
    stroke-linecap: round;
}

.xv-connector--return {
    stroke-dasharray: 3 4;
    stroke-opacity: .7;
}

.xv-node {
    stroke: var(--xv-border);
}

.xv-node-box {
    fill: #fff;
    stroke: inherit;
    stroke-width: 1;
}

.xv-node-dot {
    fill: #fff;
    stroke: var(--xv-accent);
    stroke-width: 1.5;
}

.xv-cloud { fill: #e9e2ff; }

.xv-cloud-line {
    fill: none;
    stroke: var(--xv-accent);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-opacity: .6;
}

.xv-cyl-top {
    fill: var(--xv-tint);
    stroke: var(--xv-border);
    stroke-width: 1;
}

.xv-led { fill: var(--xv-secondary); }

.xv-online { fill: var(--xv-secondary, #22b3a2); }

.xv-online-ring {
    fill: none;
    stroke: var(--xv-secondary, #22b3a2);
    stroke-width: 1;
}

.xv-query {
    fill: none;
    stroke: var(--xv-accent);
    stroke-width: 1.5;
    stroke-linecap: round;
}

.xv-status--pending { fill: #fff1e3; }
.xv-status--paid    { fill: #e3f7f1; }
.xv-status-dot--pending { fill: #f2994a; }

.xv-status-text {
    font-size: 7.5px;
    font-weight: 700;
}

.xv-status-text--pending { fill: #d97a3a; }
.xv-status-text--paid    { fill: #1f9c86; }

.xv-check {
    fill: none;
    stroke: #1f9c86;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.xv-check--light { stroke: #fff; stroke-width: 2; }
.xv-check-badge  { fill: #1fa77e; }

.xv-notify {
    fill: #fff;
    stroke: rgba(163, 132, 251, .45);
    stroke-width: 1;
}

.xv-point { fill: var(--xv-accent-deep); }
.xv-spark { stroke-width: 1.6; }

.xv-ring {
    fill: none;
    stroke: var(--xv-accent);
    stroke-width: 1.2;
    stroke-dasharray: 4 8;
    stroke-linecap: round;
    stroke-opacity: .7;
}

.xv-shield {
    fill: #fff;
    stroke: var(--xv-accent);
    stroke-width: 1.6;
    stroke-linejoin: round;
}

.xv-threat { fill: var(--xv-secondary); }

.xv-donut-track {
    fill: none;
    stroke: var(--xv-soft);
    stroke-width: 6;
}

.xv-donut {
    fill: none;
    stroke: var(--xv-accent);
    stroke-width: 6;
    stroke-linecap: round;
    stroke-dasharray: 100;
    stroke-dashoffset: 100;
    transform: rotate(-90deg);
    transform-box: fill-box;
    transform-origin: center;
}

.xv-cursor {
    fill: var(--xv-ink);
    stroke: #fff;
    stroke-width: 1;
    stroke-linejoin: round;
}

.xv-particle,
.xv-seq,
.xv-fly {
    fill: var(--xv-accent);
}

.xv-particle--secondary { fill: var(--xv-secondary); }

/* ==========================================================================
   SVG motion utilities (longhand so classes never clobber each other)
   ========================================================================== */
.xv-enter {
    animation-name: xvEnter;
    animation-duration: .7s;
    animation-timing-function: var(--xlab-ease, ease-out);
    animation-fill-mode: both;
    animation-delay: calc(var(--d, 0) * 1s);
}

.xv-slide-in {
    animation-name: xvSlideIn;
    animation-duration: .7s;
    animation-timing-function: var(--xlab-ease, ease-out);
    animation-fill-mode: both;
    animation-delay: calc(var(--d, 0) * 1s);
}

.xv-draw {
    stroke-dasharray: 1;
    stroke-dashoffset: 1;
    animation-name: xvDraw;
    animation-duration: 1.1s;
    animation-timing-function: ease-out;
    animation-fill-mode: both;
    animation-delay: calc(var(--d, 0) * 1s);
}

.xv-grow {
    transform-box: fill-box;
    transform-origin: 50% 100%;
    animation-name: xvGrow;
    animation-duration: .9s;
    animation-timing-function: var(--xlab-ease, ease-out);
    animation-fill-mode: both;
    animation-delay: calc(var(--d, 0) * 1s);
}

.xv-donut {
    animation-name: xvDonut;
    animation-duration: 1.6s;
    animation-timing-function: ease-out;
    animation-fill-mode: both;
    animation-delay: calc(var(--d, 0) * 1s);
}

.xv-pulse,
.xv-pulse-soft {
    transform-box: fill-box;
    transform-origin: center;
    animation-name: xvPulseSoft;
    animation-duration: calc(3.6s * var(--xv-speed, 1));
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}

.xv-pulse { animation-name: xvPulse; }

.xv-float {
    transform-box: fill-box;
    transform-origin: center;
    animation-name: xvFloat;
    animation-duration: calc(4.4s * var(--xv-speed, 1));
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-delay: calc(var(--i, 0) * -1.3s);
}

.xv-blink {
    animation-name: xvBlink;
    animation-duration: calc(1.8s * var(--xv-speed, 1));
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-delay: calc(var(--i, 0) * -.45s);
}

.xv-blink-slow {
    animation-name: xvBlinkSlow;
    animation-duration: calc(5s * var(--xv-speed, 1));
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-delay: calc(var(--i, 0) * -.9s);
}

/* Nodes that also enter: entrance owns the animation, blink is applied after */
.xv-node-dot.xv-enter.xv-blink-slow {
    animation-name: xvEnter, xvBlinkSlow;
    animation-duration: .7s, calc(5s * var(--xv-speed, 1));
    animation-timing-function: var(--xlab-ease, ease-out), ease-in-out;
    animation-iteration-count: 1, infinite;
    animation-fill-mode: both, none;
    animation-delay: calc(var(--d, 0) * 1s), calc(var(--d, 0) * 1s + .7s);
}

.xv-fade-loop {
    animation-name: xvFadeLoop;
    animation-duration: calc(6s * var(--xv-speed, 1));
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
    animation-delay: calc(var(--i, 0) * -1s);
}

.xv-rotate {
    transform-origin: 160px 100px;
    animation-name: xvRotate;
    animation-duration: calc(30s * var(--xv-speed, 1));
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

.xv-ring-pulse {
    transform-box: fill-box;
    transform-origin: center;
    animation-name: xvRingPulse;
    animation-duration: calc(2.4s * var(--xv-speed, 1));
    animation-timing-function: ease-out;
    animation-iteration-count: infinite;
}

.xv-dash-flow {
    stroke-dasharray: 5 7;
    animation-name: xvDashFlow;
    animation-duration: calc(1.4s * var(--xv-speed, 1));
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

.xv-progress {
    transform-box: fill-box;
    transform-origin: 0 50%;
    animation-name: xvProgress;
    animation-duration: 6s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}

.xv-particle {
    r: 3px;
    offset-rotate: 0deg;
    animation-name: xvTravel;
    animation-duration: calc(var(--t, 3s) * var(--xv-speed, 1));
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-delay: calc(var(--i, 0) * 1s);
    transition: r .3s ease;
}

.xlab-service:hover .xv-particle,
.xlab-service:focus-within .xv-particle {
    r: 3.6px;
}

.xv-seq {
    offset-rotate: 0deg;
    animation-name: xvSeq;
    animation-duration: 6s;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-delay: calc(var(--i, 0) * 1s + 1s);
}

.xv-node-pulse {
    transform-box: fill-box;
    transform-origin: center;
    animation-name: xvEnter, xvNodePulse;
    animation-duration: .7s, 6s;
    animation-timing-function: var(--xlab-ease, ease-out), ease-out;
    animation-iteration-count: 1, infinite;
    animation-fill-mode: both, none;
    animation-delay: calc(var(--d, 0) * 1s), calc(var(--p, 0) * 1s + 1.85s);
}

.xv-cursor {
    animation-name: xvCursor;
    animation-duration: calc(7s * var(--xv-speed, 1));
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}

.xv-fly {
    offset-rotate: 0deg;
    animation-name: xvFly;
    animation-duration: 4s;
    animation-timing-function: ease-in-out;
    animation-iteration-count: infinite;
}

/* Cart counter: three stacked digits, each visible for a 4s window of a 12s cycle
   (negative delays offset the windows; +1s lets the first product land first). */
.xv-count {
    opacity: 0;
    animation-name: xvCount;
    animation-duration: 12s;
    animation-timing-function: step-end;
    animation-iteration-count: infinite;
    animation-delay: calc(var(--i, 0) * -8s + 1s);
}

.xv-toggle-a,
.xv-toggle-b {
    animation-duration: 6s;
    animation-timing-function: step-end;
    animation-iteration-count: infinite;
}

.xv-toggle-a { animation-name: xvToggleA; }
.xv-toggle-b { animation-name: xvToggleB; opacity: 0; }

.xv-threat {
    offset-rotate: 0deg;
    transform-box: fill-box;
    transform-origin: center;
    animation-name: xvThreat;
    animation-duration: 5.4s;
    animation-timing-function: ease-in;
    animation-iteration-count: infinite;
    animation-delay: calc(var(--i, 0) * 1s + 1.5s);
    opacity: 0;
}

/* ==========================================================================
   Keyframes
   ========================================================================== */
@keyframes xlabReveal {
    from { opacity: 0; transform: translate3d(0, 18px, 0); }
    to   { opacity: 1; transform: translate3d(0, 0, 0); }
}

@keyframes xlabBgDrift {
    from { transform: translate(0, 0); }
    to   { transform: translate(38px, -26px); }
}

@keyframes xvEnter {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: translateY(0); }
}

@keyframes xvSlideIn {
    from { opacity: 0; transform: translateX(14px); }
    to   { opacity: 1; transform: translateX(0); }
}

@keyframes xvDraw {
    to { stroke-dashoffset: 0; }
}

@keyframes xvGrow {
    from { transform: scaleY(0); }
    to   { transform: scaleY(1); }
}

@keyframes xvDonut {
    to { stroke-dashoffset: 34; }
}

@keyframes xvPulse {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.045); }
}

@keyframes xvPulseSoft {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.02); }
}

@keyframes xvFloat {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-2.5px); }
}

@keyframes xvBlink {
    0%, 100% { opacity: .3; }
    50%      { opacity: 1; }
}

@keyframes xvBlinkSlow {
    0%, 100% { opacity: .2; }
    50%      { opacity: 1; }
}

@keyframes xvFadeLoop {
    0%, 100% { opacity: .25; }
    50%      { opacity: 1; }
}

@keyframes xvRotate {
    to { transform: rotate(360deg); }
}

@keyframes xvRingPulse {
    0%   { transform: scale(1); opacity: .8; }
    100% { transform: scale(2.8); opacity: 0; }
}

@keyframes xvDashFlow {
    to { stroke-dashoffset: -24; }
}

@keyframes xvProgress {
    0%   { transform: scaleX(.06); }
    48%  { transform: scaleX(1); }
    96%  { transform: scaleX(1); }
    100% { transform: scaleX(.06); }
}

@keyframes xvTravel {
    0%   { offset-distance: 0%;   opacity: 0; }
    10%  { opacity: 1; }
    90%  { opacity: 1; }
    100% { offset-distance: 100%; opacity: 0; }
}

@keyframes xvSeq {
    0%   { offset-distance: 0%;   opacity: 1; }
    14%  { offset-distance: 100%; opacity: 1; }
    15%  { offset-distance: 100%; opacity: 0; }
    100% { offset-distance: 100%; opacity: 0; }
}

@keyframes xvNodePulse {
    0%   { transform: scale(1);    stroke: var(--xv-border); }
    3%   { transform: scale(1.06); stroke: var(--xv-accent); }
    12%  { transform: scale(1);    stroke: var(--xv-accent); }
    22%  { stroke: var(--xv-border); }
    100% { transform: scale(1);    stroke: var(--xv-border); }
}

@keyframes xvCursor {
    0%   { transform: translate(150px, 112px); }
    38%  { transform: translate(256px, 64px); }
    44%  { transform: translate(256px, 64px) scale(.85); }
    50%  { transform: translate(256px, 64px); }
    100% { transform: translate(150px, 112px); }
}

@keyframes xvFly {
    0%   { offset-distance: 0%;   opacity: 0; }
    6%   { opacity: 1; }
    22%  { offset-distance: 100%; opacity: 1; }
    25%  { offset-distance: 100%; opacity: 0; }
    100% { offset-distance: 100%; opacity: 0; }
}

@keyframes xvCount {
    0%       { opacity: 1; }
    33.333%  { opacity: 0; }
    100%     { opacity: 0; }
}

@keyframes xvToggleA {
    0%   { opacity: 1; }
    50%  { opacity: 0; }
    100% { opacity: 0; }
}

@keyframes xvToggleB {
    0%   { opacity: 0; }
    50%  { opacity: 1; }
    100% { opacity: 1; }
}

@keyframes xvThreat {
    0%   { offset-distance: 0%;   opacity: 0; transform: scale(1); }
    8%   { opacity: 1; }
    55%  { offset-distance: 100%; opacity: 1; transform: scale(1); }
    66%  { offset-distance: 100%; opacity: 0; transform: scale(.2); }
    100% { offset-distance: 100%; opacity: 0; transform: scale(.2); }
}

/* Translate-based particle motion (no offset-path) -------------------------- */
.xv-bar {
    transform-box: fill-box;
    transform-origin: 50% 100%;
    animation-name: xvGrow;
    animation-duration: .9s;
    animation-timing-function: var(--xlab-ease, ease-out);
    animation-fill-mode: both;
    animation-delay: .45s;
}

.xv-orbit {
    transform-origin: 160px 100px;
    animation-name: xvRotate;
    animation-duration: calc(28s * var(--xv-speed, 1));
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}

.xv-orbit-ring {
    fill: none;
    stroke: var(--xv-accent);
    stroke-width: 1.2;
    stroke-dasharray: 4 8;
    stroke-linecap: round;
    stroke-opacity: .7;
}

.xv-lock { fill: var(--xv-accent); }

.xv-lock-shackle {
    fill: none;
    stroke: var(--xv-accent);
    stroke-width: 1.8;
    stroke-linecap: round;
}

.xv-check-pop {
    transform-box: fill-box;
    transform-origin: center;
    animation-name: xvCheckPop;
    animation-duration: .55s;
    animation-timing-function: var(--xlab-ease, ease-out);
    animation-fill-mode: both;
    animation-delay: 1.7s;
}

.xv-label--tiny {
    font-size: 7px;
    font-weight: 600;
    fill: #8c91a0;
}

.xv-packet {
    fill: var(--xv-accent);
    opacity: 0;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-fill-mode: both;
}

.xv-seq.xv-seq--1,
.xv-seq.xv-seq--2,
.xv-seq.xv-seq--3,
.xv-seq.xv-seq--4,
.xv-seq.xv-seq--5 {
    animation-name: xvHop;
    animation-duration: calc(6s * var(--xv-speed, 1));
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-fill-mode: both;
    opacity: 0;
}

.xv-seq--1 { --dx: 32px; --dy: 0;    animation-delay: 1s; }
.xv-seq--2 { --dx: 32px; --dy: 0;    animation-delay: 2s; }
.xv-seq--3 { --dx: 0;    --dy: 62px; animation-delay: 3s; }
.xv-seq--4 { --dx: -32px; --dy: 0;   animation-delay: 4s; }
.xv-seq--5 { --dx: -32px; --dy: 0;   animation-delay: 5s; }

.xv-fly {
    opacity: 0;
    animation-name: xvFlyCart;
    animation-duration: calc(4s * var(--xv-speed, 1));
    animation-timing-function: cubic-bezier(.22, .61, .36, 1);
    animation-iteration-count: infinite;
    animation-fill-mode: both;
}

.xv-packet--a {
    animation-name: xvPktA;
    animation-duration: calc(2.8s * var(--xv-speed, 1));
}

.xv-packet--b {
    animation-name: xvPktB;
    animation-duration: calc(2.8s * var(--xv-speed, 1));
    animation-delay: 1.1s;
}

.xv-packet--c {
    animation-name: xvPktC;
    animation-duration: calc(2.2s * var(--xv-speed, 1));
    animation-delay: .6s;
}

.xv-packet--d {
    animation-name: xvPktD;
    animation-duration: calc(2.6s * var(--xv-speed, 1));
    animation-delay: 1.8s;
}

.xv-packet--db-a {
    animation-name: xvPktDbA;
    animation-duration: calc(2.6s * var(--xv-speed, 1));
}

.xv-packet--db-b {
    animation-name: xvPktDbB;
    animation-duration: calc(2.6s * var(--xv-speed, 1));
    animation-delay: 1.3s;
}

.xv-packet--db-c {
    animation-name: xvPktDbC;
    animation-duration: calc(2s * var(--xv-speed, 1));
    animation-delay: .6s;
}

.xv-packet--data {
    animation-name: xvPktData;
    animation-duration: calc(2.4s * var(--xv-speed, 1));
}

.xv-threat.xv-threat--a,
.xv-threat.xv-threat--b,
.xv-threat.xv-threat--c {
    animation-name: xvThreatMove;
    animation-duration: calc(5.4s * var(--xv-speed, 1));
    animation-timing-function: ease-in;
    animation-iteration-count: infinite;
    animation-fill-mode: both;
    opacity: 0;
}

.xv-threat--a { --dx: 92px;  --dy: 46px; animation-delay: 1.5s; }
.xv-threat--b { --dx: -92px; --dy: 36px; animation-delay: 2.9s; }
.xv-threat--c { --dx: 88px;  --dy: -44px; animation-delay: 4.1s; }

@keyframes xvHop {
    0%   { transform: translate(0, 0); opacity: 0; }
    4%   { opacity: 1; }
    16%  { transform: translate(var(--dx), var(--dy)); opacity: 1; }
    20%  { opacity: 0; }
    100% { transform: translate(var(--dx), var(--dy)); opacity: 0; }
}

@keyframes xvFlyCart {
    0%   { transform: translate(0, 0); opacity: 0; }
    8%   { opacity: 1; }
    28%  { transform: translate(132px, -97px); opacity: 1; }
    34%  { opacity: 0; }
    100% { transform: translate(132px, -97px); opacity: 0; }
}

@keyframes xvPktA {
    0%   { transform: translate(0, 0); opacity: 0; }
    8%   { opacity: 1; }
    40%  { transform: translate(0, 24px); opacity: 1; }
    90%  { transform: translate(-82px, 46px); opacity: 1; }
    100% { transform: translate(-82px, 46px); opacity: 0; }
}

@keyframes xvPktB {
    0%   { transform: translate(0, 0); opacity: 0; }
    8%   { opacity: 1; }
    40%  { transform: translate(0, 24px); opacity: 1; }
    90%  { transform: translate(82px, 46px); opacity: 1; }
    100% { transform: translate(82px, 46px); opacity: 0; }
}

@keyframes xvPktC {
    0%   { transform: translate(0, 0); opacity: 0; }
    12%  { opacity: 1; }
    88%  { transform: translate(0, 63px); opacity: 1; }
    100% { transform: translate(0, 63px); opacity: 0; }
}

@keyframes xvPktD {
    0%   { transform: translate(0, 0); opacity: 0; }
    10%  { opacity: 1; }
    40%  { transform: translate(0, -22px); opacity: 1; }
    90%  { transform: translate(82px, -46px); opacity: 1; }
    100% { transform: translate(82px, -46px); opacity: 0; }
}

@keyframes xvPktDbA {
    0%   { transform: translate(0, 0); opacity: 0; }
    10%  { opacity: 1; }
    90%  { transform: translate(0, 68px); opacity: 1; }
    100% { transform: translate(0, 68px); opacity: 0; }
}

@keyframes xvPktDbB {
    0%   { transform: translate(0, 0); opacity: 0; }
    10%  { opacity: 1; }
    90%  { transform: translate(0, -66px); opacity: 1; }
    100% { transform: translate(0, -66px); opacity: 0; }
}

@keyframes xvPktDbC {
    0%   { transform: translate(0, 0); opacity: 0; }
    12%  { opacity: 1; }
    88%  { transform: translate(-36px, 0); opacity: 1; }
    100% { transform: translate(-36px, 0); opacity: 0; }
}

@keyframes xvPktData {
    0%   { transform: translate(0, 0); opacity: 0; }
    8%   { opacity: 1; }
    20%  { transform: translate(24px, -12px); }
    36%  { transform: translate(44px, -8px); }
    54%  { transform: translate(68px, -22px); }
    72%  { transform: translate(92px, -16px); }
    90%  { transform: translate(120px, -26px); opacity: 1; }
    100% { transform: translate(120px, -26px); opacity: 0; }
}

@keyframes xvThreatMove {
    0%   { transform: translate(0, 0) scale(1); opacity: 0; }
    8%   { opacity: 1; }
    55%  { transform: translate(var(--dx), var(--dy)) scale(1); opacity: 1; }
    66%  { transform: translate(var(--dx), var(--dy)) scale(.2); opacity: 0; }
    100% { transform: translate(var(--dx), var(--dy)) scale(.2); opacity: 0; }
}

@keyframes xvCheckPop {
    from { opacity: 0; transform: scale(.55); }
    to   { opacity: 1; transform: scale(1); }
}

/* ==========================================================================
   Responsive
   ========================================================================== */
@media only screen and (max-width: 1199px) {
    .xlab-services__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .xlab-services__figure {
        width: min(80vw, 640px);
        height: 64%;
        opacity: .26;
    }
}

@media only screen and (max-width: 991px) {
    .xlab-services__head {
        flex-direction: column;
        align-items: flex-start;
        gap: 22px;
    }
}

@media only screen and (max-width: 575px) {
    .xlab-services__grid {
        grid-template-columns: minmax(0, 1fr);
        gap: 16px;
    }

    .xlab-services__eyebrow {
        margin-bottom: 14px;
        font-size: 10px;
        letter-spacing: .14em;
    }

    .xlab-services__title {
        font-size: clamp(30px, 8.5vw, 38px);
    }

    .xlab-services__lead {
        margin-top: 14px;
        font-size: 15px;
        line-height: 1.65;
    }

    .xlab-services__all {
        min-height: 44px;
        padding: 10px 16px;
        font-size: 13px;
    }

    .xlab-service {
        border-radius: 18px;
    }

    .xlab-service__body {
        padding: 22px 20px 14px;
    }

    .xlab-service__icon {
        width: 42px;
        height: 42px;
        margin-bottom: 16px;
        font-size: 18px;
    }

    .xlab-service__title {
        font-size: 18px;
    }

    .xlab-service__visual {
        padding: 0 12px 12px;
    }

    .xlab-service__visual-frame {
        aspect-ratio: 16 / 9;
        border-radius: 13px;
    }

    /* Lighter idle animation on small screens */
    .xv-particle--extra {
        display: none;
    }
}

/* ==========================================================================
   Reduced motion: static visuals, design preserved
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    .xlab-services__head,
    .xlab-service-cell,
    .xlab-services__bg-node,
    .xlab-visual [class*="xv-"] {
        animation: none !important;
    }

    .xlab-services[data-reveal] .xlab-services__head,
    .xlab-services[data-reveal] .xlab-service-cell {
        opacity: 1;
    }

    .xlab-service,
    .xlab-service__icon,
    .xlab-service__link span,
    .xlab-services__all,
    .xlab-services__all span,
    .xv-particle {
        transition: none;
    }

    .xlab-service:hover,
    .xlab-service:focus-within,
    .xlab-services__all:hover {
        transform: none;
    }

    .xlab-service:hover .xlab-service__icon,
    .xlab-service:focus-within .xlab-service__icon {
        transform: none;
    }

    .xv-draw {
        stroke-dasharray: none;
        stroke-dashoffset: 0;
    }

    .xv-connector--return {
        stroke-dasharray: 3 4;
    }

    .xv-dash-flow {
        stroke-dasharray: 5 7;
    }

    .xv-grow,
    .xv-progress,
    .xv-enter,
    .xv-slide-in {
        transform: none;
        opacity: 1;
    }

    .xv-donut {
        stroke-dashoffset: 34;
    }

    .xv-particle,
    .xv-packet,
    .xv-seq,
    .xv-fly,
    .xv-threat,
    .xv-cursor,
    .xv-online-ring,
    .xv-count--1,
    .xv-count--2,
    .xv-toggle-a {
        display: none;
    }

    .xv-bar {
        transform: none;
    }

    .xv-count--3,
    .xv-toggle-b,
    .xv-blink,
    .xv-blink-slow,
    .xv-fade-loop {
        opacity: 1;
    }
}
