/*! WindspeedSEO Visual System v1.0.0
 * Shader layers, product graphics and the motion system for the public site.
 * Companion to the kit's ws-* global classes (structure/colour/type live there);
 * this sheet carries what a global class cannot: @keyframes, layered pseudo-elements,
 * data-URI graphics (ws-visual-assets.css), mask icons and the reduced-motion contract.
 * Motion tokens follow Figma page 09 (Motion + Hero System): entrances cubic-bezier(.22,1,.36,1),
 * settle pulses cubic-bezier(.65,0,.35,1); transform/opacity/clip-path only.
 */
:root {
  --ws-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ws-ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
  --ws-reveal-dur: 560ms;
  --ws-reveal-y: 16px;
  --ws-stagger: 90ms;
  --ws-mono: ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace;
  --ws-flow-x: calc(50% + 60px);
}

/* Instrument type (labels, timestamps, readouts) */
.elementor .ws-mono { font-family: var(--ws-mono); font-variant-numeric: tabular-nums; }
.elementor .ws-count, .elementor .ws-count-anim { font-variant-numeric: tabular-nums; }

/* ============================================================ CONVERGENCE FIELD */
.elementor .ws-flow { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.elementor .ws-flow-layer {
  position: absolute; inset: 0;
  background-repeat: no-repeat; background-size: 1280px 900px;
  background-position: var(--ws-flow-x) 50%;
}
.elementor .ws-flow-layer--far      { background-image: var(--ws-asset-field-far);      opacity: .3; animation: ws-drift-far 18s var(--ws-ease-inout) infinite alternate, ws-breathe-far 10s ease-in-out infinite alternate; }
.elementor .ws-flow-layer--far-b    { background-image: var(--ws-asset-field-far-b);    opacity: .2; animation: ws-drift-farb 14s var(--ws-ease-inout) infinite alternate, ws-breathe-farb 12.5s ease-in-out infinite alternate; }
.elementor .ws-flow-layer--filtered { background-image: var(--ws-asset-field-filtered); opacity: .06; animation: ws-drift-filtered 11s var(--ws-ease-inout) infinite alternate, ws-breathe-filtered 7s ease-in-out infinite alternate; }
.elementor .ws-flow-layer--mid      { background-image: var(--ws-asset-field-mid);      opacity: .6; animation: ws-drift-mid 13s var(--ws-ease-inout) infinite alternate, ws-breathe-mid 8s ease-in-out infinite alternate; }
.elementor .ws-flow-layer--near     { background-image: var(--ws-asset-field-near);     opacity: .85; animation: ws-drift-near 9.5s var(--ws-ease-inout) infinite alternate, ws-breathe-near 11s ease-in-out infinite alternate; }
.elementor .ws-flow-layer--lens     { background-image: var(--ws-asset-field-lens); transform-origin: calc(50% + 160px) 50%; animation: ws-lens 4.6s ease-in-out infinite alternate; }
.elementor .ws-flow-layer--out      { background-image: var(--ws-asset-field-outputs); clip-path: inset(0 calc(50% - 262px) 0 0); }

/* travelling ticks: a sparse band pattern sweeping through a strand-shaped mask */
.elementor .ws-flow-layer--sweep-mid,
.elementor .ws-flow-layer--sweep-near {
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 1280px 900px; mask-size: 1280px 900px;
  -webkit-mask-position: var(--ws-flow-x) 50%; mask-position: var(--ws-flow-x) 50%;
  overflow: hidden;
}
.elementor .ws-flow-layer--sweep-mid  { -webkit-mask-image: var(--ws-asset-field-mid);  mask-image: var(--ws-asset-field-mid);  animation: ws-drift-mid 13s var(--ws-ease-inout) infinite alternate; }
.elementor .ws-flow-layer--sweep-near { -webkit-mask-image: var(--ws-asset-field-near); mask-image: var(--ws-asset-field-near); animation: ws-drift-near 9.5s var(--ws-ease-inout) infinite alternate; }
.elementor .ws-flow-layer--sweep-mid::before,
.elementor .ws-flow-layer--sweep-near::before {
  content: ""; position: absolute; top: -20%; bottom: -20%; left: -400px; width: 3200px;
  background-repeat: repeat-x; background-size: 260px 100%;
  background-image: linear-gradient(90deg, rgba(191,221,237,0) 0, rgba(191,221,237,0) 232px, rgba(191,221,237,.55) 240px, rgba(214,235,246,.95) 246px, rgba(191,221,237,.55) 252px, rgba(191,221,237,0) 260px);
  transform: skewX(-16deg);
  animation: ws-sweep 3.4s linear infinite;
}
.elementor .ws-flow-layer--sweep-near::before { background-size: 340px 100%; background-image: linear-gradient(90deg, rgba(214,235,246,0) 0, rgba(214,235,246,0) 306px, rgba(214,235,246,.6) 316px, #EAF5FA 323px, rgba(214,235,246,.6) 330px, rgba(214,235,246,0) 340px); animation: ws-sweep-near 2.5s linear infinite; }

/* the single active output node: the only pulse on the page */
.elementor .ws-flow-node {
  position: absolute; width: 12px; height: 12px; border-radius: 9999px;
  left: calc(var(--ws-flow-x) - 640px + var(--ws-node-x, 768px)); top: calc(50% - 450px + var(--ws-node-y, 462px)); /* on the green output, just before the panel edge */
  background-color: #A1CB45; box-shadow: 0 0 0 0 rgba(161,203,69,.45), 0 0 18px 2px rgba(161,203,69,.35);
  animation: ws-node-pulse 3.2s ease-in-out infinite;
}
/* headline legibility scrim (safe zone A) */
.elementor .ws-flow::after {
  content: ""; position: absolute; inset: 0; right: calc(50% - 310px); width: auto;
  background-image: linear-gradient(90deg, rgba(14,21,31,.93) 0%, rgba(14,21,31,.80) 34%, rgba(14,21,31,.30) 68%, rgba(14,21,31,0) 100%);
}
/* band variant (tablet/mobile): the field sits between the copy and the panel */
.elementor .ws-flow--band { position: relative; inset: auto; height: 230px; --ws-flow-x: calc(50% - 16px);
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%); mask-image: linear-gradient(180deg, transparent 0, #000 22%, #000 78%, transparent 100%); }
.elementor .ws-flow--band .ws-flow-node { --ws-node-x: 792px; --ws-node-y: 490px; }
.elementor .ws-flow--band::after { right: auto; width: 42%; background-image: linear-gradient(90deg, rgba(14,21,31,.9) 0%, rgba(14,21,31,0) 100%); }
@media (max-width: 767px) {
  .elementor .ws-flow--band { height: 190px; --ws-flow-x: calc(50% - 52px); }
}

@keyframes ws-drift-far      { to { transform: translateX(26px); } }
@keyframes ws-drift-farb     { to { transform: translateX(17px); } }
@keyframes ws-drift-filtered { to { transform: translate(6px, 15px); } }
@keyframes ws-drift-mid      { to { transform: translateX(44px); } }
@keyframes ws-drift-near     { to { transform: translateX(64px); } }
@keyframes ws-breathe-far      { from { opacity: .24; } to { opacity: .34; } }
@keyframes ws-breathe-farb     { from { opacity: .16; } to { opacity: .26; } }
@keyframes ws-breathe-filtered { from { opacity: .10; } to { opacity: .02; } }
@keyframes ws-breathe-mid      { from { opacity: .5; } to { opacity: .68; } }
@keyframes ws-breathe-near     { from { opacity: .72; } to { opacity: .92; } }
@keyframes ws-lens { from { transform: scale(.94); } to { transform: scale(1.06); } }
@keyframes ws-sweep      { from { transform: skewX(-16deg) translateX(0); }  to { transform: skewX(-16deg) translateX(260px); } }
@keyframes ws-sweep-near { from { transform: skewX(-16deg) translateX(0); }  to { transform: skewX(-16deg) translateX(340px); } }
@keyframes ws-node-pulse {
  0%, 100% { opacity: .85; box-shadow: 0 0 0 0 rgba(161,203,69,.45), 0 0 14px 2px rgba(161,203,69,.30); }
  50%      { opacity: 1;   box-shadow: 0 0 0 6px rgba(161,203,69,0),  0 0 36px 6px rgba(161,203,69,.42); }
}

/* ================================================================ ATMOSPHERE */
/* dark sections: two slow glows + a vignette (restrained: threshold high, radius small) */
.elementor .ws-atmosphere { position: relative; isolation: isolate; overflow: hidden; }
.elementor .ws-atmosphere::before,
.elementor .ws-atmosphere::after { content: ""; position: absolute; z-index: -1; border-radius: 9999px; pointer-events: none; filter: blur(48px); }
.elementor .ws-atmosphere::before { width: 720px; height: 520px; left: -160px; top: -200px; background: radial-gradient(closest-side, rgba(76,156,200,.28), rgba(76,156,200,0)); animation: ws-glow-a 22s ease-in-out infinite alternate; }
.elementor .ws-atmosphere::after  { width: 640px; height: 480px; right: -180px; bottom: -220px; background: radial-gradient(closest-side, rgba(131,180,34,.16), rgba(131,180,34,0)); animation: ws-glow-b 26s ease-in-out infinite alternate; }
.elementor .ws-atmosphere--soft::before { opacity: .7; }
.elementor .ws-atmosphere--soft::after { opacity: .6; }
@keyframes ws-glow-a { to { transform: translate(60px, 40px) scale(1.08); } }
@keyframes ws-glow-b { to { transform: translate(-50px, -30px) scale(1.06); } }

/* ============================================================ PRODUCT GRAPHICS */
.elementor .ws-chart-plot { position: relative; width: 100%; aspect-ratio: 640 / 220; background-repeat: no-repeat; background-size: 100% 100%; }
.elementor .ws-chart-plot--visibility { background-image: var(--ws-asset-chart-visibility); }
.elementor .ws-chart-plot--visibility-light { background-image: var(--ws-asset-chart-visibility-light); }

.elementor .ws-spark { width: 120px; max-width: 100%; height: 36px; background-repeat: no-repeat; background-size: contain; background-position: right center; }
.elementor .ws-spark--up-green   { background-image: var(--ws-asset-spark-up-green); }
.elementor .ws-spark--up-blue    { background-image: var(--ws-asset-spark-up-blue); }
.elementor .ws-spark--flat-blue  { background-image: var(--ws-asset-spark-flat-blue); }
.elementor .ws-spark--up-blue-light  { background-image: var(--ws-asset-spark-up-blue-light); }
.elementor .ws-spark--up-green-light { background-image: var(--ws-asset-spark-up-green-light); }
.elementor .ws-spark--flat-light { background-image: var(--ws-asset-spark-flat-light); }
.elementor .ws-spark--bars-light { background-image: var(--ws-asset-spark-bars-light); }
.elementor .ws-spark--bars-dark  { background-image: var(--ws-asset-spark-bars-dark); }
.elementor .ws-spark--bars-green-light { background-image: var(--ws-asset-spark-bars-green-light); }
.elementor .ws-spark--dots-health { background-image: var(--ws-asset-spark-dots-health); }
.elementor .ws-spark--dots-blue  { background-image: var(--ws-asset-spark-dots-blue); }
.elementor .ws-spark--rank       { background-image: var(--ws-asset-spark-rank); }

/* score ring: conic progress on a track, value in the middle */
.elementor .ws-ring { --ws-ring-p: 92; --ws-ring-color: #A1CB45; --ws-ring-track: rgba(255,255,255,.08); position: relative; width: 84px; height: 84px; border-radius: 9999px; display: grid; place-items: center;
  background: conic-gradient(var(--ws-ring-color) calc(var(--ws-ring-p) * 1%), var(--ws-ring-track) 0); }
.elementor .ws-ring::before { content: ""; position: absolute; inset: 7px; border-radius: 9999px; background-color: var(--ws-ring-inner, #172130); }
.elementor .ws-ring--light { --ws-ring-color: #83B422; --ws-ring-track: #EDF1F4; --ws-ring-inner: #FFFFFF; }

/* mask icons (Lucide-style line icons tinted by currentColor) */
.elementor .ws-icon { display: inline-block; width: 22px; height: 22px; flex: 0 0 auto; background-color: currentColor;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-size: contain; mask-size: contain; -webkit-mask-position: center; mask-position: center; }
.elementor .ws-icon--search       { -webkit-mask-image: var(--ws-asset-icon-search); mask-image: var(--ws-asset-icon-search); }
.elementor .ws-icon--trending-up  { -webkit-mask-image: var(--ws-asset-icon-trending-up); mask-image: var(--ws-asset-icon-trending-up); }
.elementor .ws-icon--users        { -webkit-mask-image: var(--ws-asset-icon-users); mask-image: var(--ws-asset-icon-users); }
.elementor .ws-icon--layers       { -webkit-mask-image: var(--ws-asset-icon-layers); mask-image: var(--ws-asset-icon-layers); }
.elementor .ws-icon--activity     { -webkit-mask-image: var(--ws-asset-icon-activity); mask-image: var(--ws-asset-icon-activity); }
.elementor .ws-icon--link         { -webkit-mask-image: var(--ws-asset-icon-link); mask-image: var(--ws-asset-icon-link); }
.elementor .ws-icon--sparkles     { -webkit-mask-image: var(--ws-asset-icon-sparkles); mask-image: var(--ws-asset-icon-sparkles); }
.elementor .ws-icon--file-text    { -webkit-mask-image: var(--ws-asset-icon-file-text); mask-image: var(--ws-asset-icon-file-text); }
.elementor .ws-icon--wrench       { -webkit-mask-image: var(--ws-asset-icon-wrench); mask-image: var(--ws-asset-icon-wrench); }
.elementor .ws-icon--check        { -webkit-mask-image: var(--ws-asset-icon-check); mask-image: var(--ws-asset-icon-check); }
.elementor .ws-icon--refresh      { -webkit-mask-image: var(--ws-asset-icon-refresh); mask-image: var(--ws-asset-icon-refresh); }
.elementor .ws-icon--book-open    { -webkit-mask-image: var(--ws-asset-icon-book-open); mask-image: var(--ws-asset-icon-book-open); }
.elementor .ws-icon--dashboard    { -webkit-mask-image: var(--ws-asset-icon-layout-dashboard); mask-image: var(--ws-asset-icon-layout-dashboard); }
.elementor .ws-icon--bot          { -webkit-mask-image: var(--ws-asset-icon-bot); mask-image: var(--ws-asset-icon-bot); }
.elementor .ws-icon--arrow-right  { -webkit-mask-image: var(--ws-asset-icon-arrow-right); mask-image: var(--ws-asset-icon-arrow-right); }
.elementor .ws-icon--return       { -webkit-mask-image: var(--ws-asset-icon-corner-return); mask-image: var(--ws-asset-icon-corner-return); }

/* live indicator */
.elementor .ws-live-dot { animation: ws-live 1.8s ease-in-out infinite; }
@keyframes ws-live { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

/* return rail dash travel (operating loop) */
.elementor .ws-loop-return-line { background-image: repeating-linear-gradient(90deg, rgba(150,200,225,.55) 0 8px, transparent 8px 16px); background-size: 16px 1px; animation: ws-dash 1.1s linear infinite; }
@keyframes ws-dash { to { background-position-x: -16px; } }

/* ============================================================ STICKY HEADER (glass) */
/* The kit class ws-site-header carries the glass itself (rgba white + backdrop-filter); the sticky element is Elementor's
   location wrapper (kit custom CSS P4/P4b). This block adds the scrolled state: html.ws-scrolled is set by ws-visual.js once the
   page has moved, and only then does the header cast a shadow and thin its tint so the hero shows through the frost. */
.elementor .ws-site-header { transition: background-color 240ms var(--ws-ease-out), box-shadow 240ms var(--ws-ease-out), border-color 240ms var(--ws-ease-out); }
.ws-scrolled .elementor .ws-site-header { background-color: rgba(255, 255, 255, .78); border-color: rgba(23, 33, 48, .10); box-shadow: 0 1px 0 rgba(255, 255, 255, .55) inset, 0 12px 32px -18px rgba(23, 33, 48, .28); }
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .elementor .ws-site-header, .ws-scrolled .elementor .ws-site-header { background-color: rgba(255, 255, 255, .96); }
}

/* ================================================================ MOTION SYSTEM */
/* Every state below is gated on .ws-js so the page is complete without JavaScript.
   Transitions are declared on the ENTERED state only: the resting (hidden) state must never animate in. */
.ws-js .ws-reveal { opacity: 0; transform: translateY(var(--ws-reveal-y)); }
.ws-js .ws-reveal--left  { transform: translateX(-20px); }
.ws-js .ws-reveal--right { transform: translateX(20px); }
.ws-js .ws-reveal--scale { transform: translateY(12px) scale(.985); }
.ws-js .ws-reveal.ws-in, .ws-js .ws-in .ws-reveal { opacity: 1; transform: none; transition: opacity var(--ws-reveal-dur) var(--ws-ease-out) var(--ws-delay, 0ms), transform var(--ws-reveal-dur) var(--ws-ease-out) var(--ws-delay, 0ms); }
.ws-js .ws-stagger > * { --ws-delay: calc(var(--ws-i, 0) * var(--ws-stagger)); }
.ws-js .ws-stagger--slow > * { --ws-delay: calc(var(--ws-i, 0) * 160ms); }
.ws-js .ws-stagger--fast > * { --ws-delay: calc(var(--ws-i, 0) * 55ms); }
.ws-js .ws-delay-1 { --ws-delay: 150ms; } .ws-js .ws-delay-2 { --ws-delay: 300ms; } .ws-js .ws-delay-3 { --ws-delay: 450ms; } .ws-js .ws-delay-4 { --ws-delay: 600ms; }

.ws-js .ws-grow { transform: scaleX(0); transform-origin: left center; }
.ws-js .ws-in .ws-grow, .ws-js .ws-grow.ws-in { transform: scaleX(1); transition: transform 750ms var(--ws-ease-out) calc(var(--ws-delay, 0ms) + 120ms); }
.ws-js .ws-wipe { clip-path: inset(0 100% 0 0); }
.ws-js .ws-in .ws-wipe, .ws-js .ws-wipe.ws-in { clip-path: inset(0 0 0 0); transition: clip-path 1100ms var(--ws-ease-out) calc(var(--ws-delay, 0ms) + 180ms); }

/* dashboard float: on the translate property so it composes with transform-based entrances */
.elementor .ws-float { animation: ws-float 9s ease-in-out infinite alternate; }
@keyframes ws-float { from { translate: 0 0; } to { translate: 0 -8px; } }

/* hover lift (hover-capable pointers only) */
@media (hover: hover) and (pointer: fine) {
  .elementor .ws-lift { transition: transform 180ms var(--ws-ease-out), box-shadow 180ms var(--ws-ease-out), border-color 120ms var(--ws-ease-out); }
  .ws-js .ws-lift.ws-reveal.ws-in, .ws-js .ws-in .ws-lift.ws-reveal { transition: opacity var(--ws-reveal-dur) var(--ws-ease-out) var(--ws-delay, 0ms), transform var(--ws-reveal-dur) var(--ws-ease-out) var(--ws-delay, 0ms), box-shadow 180ms var(--ws-ease-out), border-color 120ms var(--ws-ease-out); }
  .elementor .ws-lift:hover, .ws-js .ws-in .ws-lift.ws-reveal:hover { transform: translateY(-2px); box-shadow: 0 12px 30px rgba(23,33,48,.12); transition-delay: 0ms; transition-duration: 180ms; }
}

/* ============================================================== HERO AUTOPLAY */
/* Figma H2 "Hero, on load": eyebrow .10s, H1 .22s, lede .42s, actions .60s, sources .78s; panel .30s; rows .90/1.70/2.50/3.30s; cue 4.0s. */
.ws-js .ws-hero--field .ws-hero-seq { opacity: 0; transform: translateY(14px); }
.ws-js .ws-hero--field .ws-hero-eyebrow.ws-hero-seq { transform: translateY(10px); }
.ws-js .ws-hero--field .ws-hero-title.ws-hero-seq   { transform: translateY(18px); }
.ws-js .ws-hero--field .ws-btn-row.ws-hero-seq      { transform: translateY(12px); }
.ws-js .ws-hero--field .ws-hero-proof.ws-hero-seq   { transform: translateY(10px); }
.ws-js .ws-hero--field .ws-hero-cue.ws-hero-seq     { transform: none; }
.ws-js .ws-hero--field .ws-telemetry.ws-hero-seq    { transform: translateX(20px); }
.ws-js .ws-hero--field .ws-telemetry-row { opacity: 0; transform: translateX(-14px); }
.ws-js .ws-hero--field .ws-telemetry-bar { transform: scaleX(0); transform-origin: left center; }
.ws-js .ws-hero--field .ws-telemetry-proof { opacity: 0; }
.ws-js .ws-hero--field .ws-flow-layer--out { clip-path: inset(0 calc(50% - 160px) 0 0); }
.ws-js .ws-hero--field .ws-flow-node { opacity: 0; transform: scale(.35); animation-delay: 4200ms; }
.ws-js .ws-hero--field .ws-flow { opacity: 0; }
.ws-js .ws-hero--field .ws-flow-layer, .ws-js .ws-hero--field .ws-flow-layer::before { animation-play-state: paused; }

.ws-js .ws-hero--field.ws-hero-in .ws-hero-seq { opacity: 1; transform: none; transition: opacity 600ms var(--ws-ease-out), transform 600ms var(--ws-ease-out); }
.ws-js .ws-hero--field.ws-hero-in .ws-hero-eyebrow.ws-hero-seq { transition-delay: 100ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-hero-title.ws-hero-seq   { transition-delay: 220ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-hero-lede.ws-hero-seq    { transition-delay: 420ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-btn-row.ws-hero-seq      { transition-delay: 600ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-hero-proof.ws-hero-seq   { transition-delay: 780ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-hero-cue.ws-hero-seq     { transition-delay: 4000ms; transition-duration: 500ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-telemetry.ws-hero-seq    { transition-delay: 300ms; transition-duration: 700ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-telemetry-row { opacity: 1; transform: none; transition: opacity 450ms var(--ws-ease-out), transform 450ms var(--ws-ease-out); }
.ws-js .ws-hero--field.ws-hero-in .ws-telemetry-row { transition-delay: calc(900ms + var(--ws-i, 0) * 800ms); } /* --ws-i is the row index, set by ws-visual.js */
.ws-js .ws-hero--field.ws-hero-in .ws-telemetry-bar { transform: scaleX(1); transition: transform 750ms var(--ws-ease-out) calc(1000ms + var(--ws-i, 0) * 800ms); }
.ws-js .ws-hero--field.ws-hero-in .ws-telemetry-proof { opacity: 1; transition: opacity 500ms var(--ws-ease-out) 3900ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-flow-layer--out { clip-path: inset(0 calc(50% - 262px) 0 0); transition: clip-path 800ms var(--ws-ease-out) 2900ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-flow-node { opacity: 1; transform: scale(1); transition: opacity 250ms var(--ws-ease-out) 3600ms, transform 420ms var(--ws-ease-out) 3600ms; }
.ws-js .ws-hero--field.ws-hero-in .ws-flow { opacity: 1; transition: opacity 1200ms ease-out; }
.ws-js .ws-hero--field.ws-hero--calm.ws-hero-in .ws-flow { opacity: .6; } /* secondary heroes: the field recedes behind the copy */
.ws-js .ws-hero--field.ws-hero-in .ws-flow-layer, .ws-js .ws-hero--field.ws-hero-in .ws-flow-layer::before { animation-play-state: running; }
.ws-js .ws-hero--field.ws-hero-in .ws-telemetry-row--active .ws-telemetry-value { transform: scale(1.05); transform-origin: right center; transition: transform 600ms var(--ws-ease-inout) 4000ms; }

/* ================================================================= LOOP SEQUENCE */
/* On first view: the track fills, stages light in order (blue then green from Act), the return rail closes last. */
.ws-js .ws-loop .ws-loop-track-fill { transform: scaleX(0); transform-origin: left center; }
.ws-js .ws-loop.ws-in .ws-loop-track-fill { transform: scaleX(1); transition: transform 2400ms linear 200ms; }
.ws-js .ws-loop .ws-loop-node { border-color: rgba(255,255,255,.12); color: #98A3AF; box-shadow: none; }
.ws-js .ws-loop .ws-loop-stage-title, .ws-js .ws-loop .ws-loop-stage-body { opacity: 0; transform: translateY(8px); }
.ws-js .ws-loop.ws-in .ws-loop-node { border-color: #4C9CC8; color: #FFFFFF; box-shadow: 0 0 0 4px rgba(76,156,200,.12); transition: border-color 320ms var(--ws-ease-out) var(--ws-delay, 0ms), color 320ms var(--ws-ease-out) var(--ws-delay, 0ms), box-shadow 320ms var(--ws-ease-out) var(--ws-delay, 0ms); }
.ws-js .ws-loop.ws-in .ws-loop-node--green { border-color: #A1CB45; box-shadow: 0 0 0 4px rgba(161,203,69,.14), 0 0 24px rgba(161,203,69,.25); }
.ws-js .ws-loop.ws-in .ws-loop-stage-title, .ws-js .ws-loop.ws-in .ws-loop-stage-body { opacity: 1; transform: none; transition: opacity 420ms var(--ws-ease-out) var(--ws-delay, 0ms), transform 420ms var(--ws-ease-out) var(--ws-delay, 0ms); }
.ws-js .ws-loop .ws-loop-stage { --ws-delay: calc(var(--ws-i, 1) * 420ms - 120ms); } /* stages carry --ws-i 1..6 (ws-stagger on .ws-loop-stages; the track line is child 0) */
.ws-js .ws-loop .ws-loop-return { opacity: 0; }
.ws-js .ws-loop.ws-in .ws-loop-return { opacity: 1; transition: opacity 500ms var(--ws-ease-out) 2900ms; }
.ws-js .ws-loop .ws-loop-return-line { animation-play-state: paused; }
.ws-js .ws-loop.ws-in .ws-loop-return-line { animation-play-state: running; }

/* ============================================================ PAUSE OFFSCREEN */
.ws-offscreen, .ws-offscreen *, .ws-offscreen::before, .ws-offscreen::after, .ws-offscreen *::before, .ws-offscreen *::after,
.ws-hidden .ws-flow *, .ws-hidden .ws-float, .ws-hidden .ws-atmosphere::before, .ws-hidden .ws-atmosphere::after { animation-play-state: paused !important; }

/* ================================================================ REDUCED MOTION */
/* The static composition is the design (Figma 09 · E/H7): render the end state, remove the journey. */
@media (prefers-reduced-motion: reduce) {
  .elementor .ws-flow-layer, .elementor .ws-flow-node, .elementor .ws-atmosphere::before, .elementor .ws-atmosphere::after,
  .elementor .ws-live-dot, .elementor .ws-loop-return-line, .elementor .ws-float { animation: none !important; }
  .elementor .ws-flow-layer--sweep-mid, .elementor .ws-flow-layer--sweep-near { display: none; }
  .elementor .ws-flow-layer--sweep-mid::before, .elementor .ws-flow-layer--sweep-near::before { animation: none !important; }
  .ws-js .ws-reveal, .ws-js .ws-grow, .ws-js .ws-wipe, .ws-js .ws-hero--field .ws-hero-seq, .ws-js .ws-hero--field .ws-telemetry-row,
  .ws-js .ws-hero--field .ws-telemetry-bar, .ws-js .ws-hero--field .ws-telemetry-proof, .ws-js .ws-hero--field .ws-flow, .ws-js .ws-hero--field .ws-flow-node,
  .ws-js .ws-hero--field .ws-flow-layer--out, .ws-js .ws-loop .ws-loop-track-fill, .ws-js .ws-loop .ws-loop-stage-title, .ws-js .ws-loop .ws-loop-stage-body,
  .ws-js .ws-loop .ws-loop-return { opacity: 1 !important; transform: none !important; clip-path: none !important; transition: none !important; }
  .ws-js .ws-hero--field .ws-flow-layer--out { clip-path: inset(0 calc(50% - 262px) 0 0) !important; }
  .ws-js .ws-hero--field.ws-hero--calm .ws-flow { opacity: .6 !important; }
  .ws-js .ws-loop .ws-loop-node { border-color: #4C9CC8; color: #FFFFFF; box-shadow: 0 0 0 4px rgba(76,156,200,.12); transition: none; }
  .ws-js .ws-loop .ws-loop-node--green { border-color: #A1CB45; box-shadow: 0 0 0 4px rgba(161,203,69,.14); }
  .elementor .ws-lift:hover { transform: none; }
}
.ws-reduced .ws-reveal, .ws-reduced .ws-hero-seq, .ws-reduced .ws-telemetry-row, .ws-reduced .ws-telemetry-proof { opacity: 1 !important; transform: none !important; transition: none !important; }
.ws-reduced .ws-telemetry-bar, .ws-reduced .ws-grow { transform: scaleX(1) !important; transition: none !important; }
.ws-reduced .ws-wipe { clip-path: none !important; }

/* editor safety: inside the Elementor editor nothing is hidden and nothing moves */
.elementor-editor-active .ws-reveal, .elementor-editor-active .ws-hero-seq, .elementor-editor-active .ws-telemetry-row { opacity: 1 !important; transform: none !important; }

/* field variants: the background field is desktop-only, the band replaces it below 1024px */
@media (max-width: 1023px) { .elementor .ws-flow--desk { display: none; } }
@media (min-width: 1024px) { .elementor .ws-flow--band { display: none; } }

/* ================================================== HERO FIELD ↔ TELEMETRY PANEL (v1.1.2) */
/* The field was positioned from the page centre while the panel sits at the content column's right
   edge, so below ~1400px the convergence point and node slid under the panel, and the near/mid drift
   (up to +64px) pushed the strands through the node at every width. Anchor the field to the panel:
   panel left edge = 50% + min(width, 1240px)/2 - 416px (1240px container, 32px padding, 384px panel);
   the field centre sits 144px left of it, which equals the original 50% + 60px at full width.
   100cqw is the full-bleed field's own width. Scoped to heroes that carry the panel. */
.elementor .ws-hero--field:has(.ws-telemetry) .ws-flow--desk {
  container-type: inline-size;
  --ws-flow-x: calc(50% + min(100cqw, 1240px) / 2 - 560px);
}
.elementor .ws-hero--field:has(.ws-telemetry) .ws-flow--desk .ws-flow-layer--lens { transform-origin: calc(var(--ws-flow-x) + 100px) 50%; }
/* output strands end at the panel edge instead of smearing under the frosted glass */
.elementor .ws-hero--field:has(.ws-telemetry) .ws-flow--desk .ws-flow-layer--out { clip-path: inset(0 calc(50% - min(100cqw, 1240px) / 2 + 416px) 0 0); }
.ws-js .ws-hero--field:has(.ws-telemetry) .ws-flow--desk .ws-flow-layer--out { clip-path: inset(0 calc(50% - min(100cqw, 1240px) / 2 + 460px) 0 0); }
.ws-js .ws-hero--field.ws-hero-in:has(.ws-telemetry) .ws-flow--desk .ws-flow-layer--out { clip-path: inset(0 calc(50% - min(100cqw, 1240px) / 2 + 416px) 0 0); }
/* drift sways mostly away from the panel so the strands never overrun the node */
.elementor .ws-hero--field:has(.ws-telemetry) .ws-flow-layer--near       { animation-name: ws-hero-drift-near, ws-breathe-near; }
.elementor .ws-hero--field:has(.ws-telemetry) .ws-flow-layer--sweep-near { animation-name: ws-hero-drift-near; }
.elementor .ws-hero--field:has(.ws-telemetry) .ws-flow-layer--mid        { animation-name: ws-hero-drift-mid, ws-breathe-mid; }
.elementor .ws-hero--field:has(.ws-telemetry) .ws-flow-layer--sweep-mid  { animation-name: ws-hero-drift-mid; }
@keyframes ws-hero-drift-near { from { transform: translateX(-26px); } to { transform: translateX(8px); } }
@keyframes ws-hero-drift-mid  { from { transform: translateX(-18px); } to { transform: translateX(6px); } }
@media (prefers-reduced-motion: reduce) {
  .ws-js .ws-hero--field:has(.ws-telemetry) .ws-flow--desk .ws-flow-layer--out { clip-path: inset(0 calc(50% - min(100cqw, 1240px) / 2 + 416px) 0 0) !important; }
}
