/* =============================================================================
   10B. SITE — SERVICES (new)
   Hub-and-node network diagram: animated SVG connector paths radiate from a
   central "NeuroSoft" hub to six floating glass-panel service modules. Reuses
   existing keyframes (glow-pulse, float-a/b, core-ring) and shadow/glass
   tokens from the Platform orchestration diagram so it reads as native to
   the system rather than a new visual language. Collapses to a stacked
   list below 900px — same markup, CSS-only reflow (no absolute positioning,
   no SVG connectors), mirroring the workflow section's mobile fallback.
   ============================================================================= */
/* Depends on: tokens.css, base/motion.css (glow-pulse, float-a/b, core-ring, services-dash-flow keyframes). */
.services {
  position: relative;
  overflow: hidden;
}

.services__glow {
  position: absolute;
  border-radius: 50%;
  pointer-events: none;
}

.services__glow--a {
  top: -14%;
  left: -8%;
  width: 46%;
  aspect-ratio: 1 / 1;
  background: radial-gradient(circle, var(--color-accent-soft) 0%, transparent 72%);
  filter: blur(8px);
  animation: glow-pulse 7s ease-in-out infinite;
}

.services__glow--b {
  bottom: -16%;
  right: -6%;
  width: 40%;
  aspect-ratio: 1 / 1;
  background: radial-gradient(circle, var(--color-accent-soft) 0%, transparent 70%);
  filter: blur(8px);
  animation: glow-pulse 8s 1s ease-in-out infinite;
}

.services__heading {
  font-size: var(--text-heading-sm);
  line-height: var(--lh-heading-snug);
}

.services__lead {
  font-size: var(--text-lead-sm);
  line-height: var(--lh-body);
  max-width: 52ch;
}

/* --- Network diagram: mobile-first stacked list ---------------------------- */
.services__network {
  position: relative;
  margin-top: var(--space-content-gap);
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.services__connectors,
.services__hub {
  display: none;
}

/* The hub-and-node diagram only has room to breathe once the container is
   wide (≥1280px) — real text cards are ~280-330px tall and don't shrink
   with the container the way the aspect-ratio box does, so below this
   width the rows start overlapping. Narrower viewports (which covers
   every phone AND most tablets/small laptops) get the plain stacked list
   instead, which has no such constraint. */
@media (min-width: 1280px) {
  .services__network {
    display: block;
    max-width: 1180px;
    aspect-ratio: 1000 / 600;
    margin-inline: auto;
  }

  .services__connectors {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
  }

  .services__hub {
    display: block;
    position: absolute;
    left: 50%;
    top: 50%;
    width: 14%;
    aspect-ratio: 1 / 1;
    transform: translate(-50%, -50%);
    z-index: 2;
  }
}

/* --- Connector lines --------------------------------------------------------
   Two layers per connector, sharing one 'd' and one gradient:
   `.services__line` is a clean, static, low-opacity stroke so the diagram
   reads calmly at rest. `.services__pulse` is a short bright dash on a
   long dash-cycle, animated to march outward — a single soft "pulse of
   energy" per line rather than the busier marching-ants look. -------------- */
.services__stop-a {
  stop-color: var(--color-accent);
  stop-opacity: 0.9;
}

.services__stop-b {
  stop-color: var(--color-accent-strong);
  stop-opacity: 0;
}

.services__line {
  stroke-width: 1.5;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  opacity: 0.32;
}

.services__pulse {
  stroke-width: 3;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  stroke-dasharray: 24 500;
  filter: drop-shadow(0 0 4px var(--color-accent-border));
  animation: services-dash-flow 3.4s linear infinite;
}

/* SVG connector gradients are token-driven already; dark mode only raises
   their quiet baseline contrast so the network remains legible on navy. */
:root[data-theme="dark"] .services__stop-a {
  stop-color: var(--color-glow);
  stop-opacity: 0.78;
}

:root[data-theme="dark"] .services__stop-b {
  stop-color: var(--color-accent-strong);
  stop-opacity: 0.08;
}

:root[data-theme="dark"] .services__line {
  opacity: 0.46;
}

:root[data-theme="dark"] .services__pulse {
  filter: drop-shadow(0 0 4px oklch(68% 0.18 215 / 0.38));
}

:root[data-theme="dark"] .services__hub-core,
:root[data-theme="dark"] .services__node-icon {
  border-color: color-mix(in oklch, var(--color-glow), transparent 62%);
}

/* --- Hub: pulsing ring + glass core, styled after .platform__core-ring ----- */
.services__hub-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: 2px solid var(--color-accent-border);
  animation: core-ring 3.2s ease-in-out infinite;
}

.services__hub-core {
  position: absolute;
  inset: 14%;
  border-radius: 50%;
  background: var(--color-glass-strong);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border: 1px solid var(--color-accent);
  box-shadow: var(--shadow-node);
  display: flex;
  align-items: center;
  justify-content: center;
}

.services__hub-label {
  font-family: var(--font-mono);
  font-size: var(--text-label-2xs);
  letter-spacing: var(--ls-label-md);
  color: var(--color-accent-strong);
  font-weight: var(--fw-medium);
  white-space: nowrap;
}

/* --- Service modules: glass panels, absolute + floating at ≥900px --------- */
.services__node {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  background: var(--color-glass-medium);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-panel);
  overflow: hidden;
  /* `opacity` is included here (not just in the .reveal utility) so the
     scroll-reveal fade-in and the hover lift/glow below share one
     transition list instead of one clobbering the other. */
  transition: opacity 0.7s var(--ease-out-expo), transform var(--transition-card),
    box-shadow var(--transition-card), border-color var(--transition-base);
}

.services__node:hover,
.services__node:focus-within {
  transform: translateY(-6px);
  box-shadow: var(--shadow-panel-hover);
  border-color: var(--color-accent-border);
}

.services__node-status {
  position: absolute;
  top: var(--space-4);
  right: var(--space-4);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--color-accent);
  box-shadow: 0 0 8px 1px var(--color-accent-border);
  animation: glow-pulse 2.6s ease-in-out infinite;
}

.services__node-glow {
  position: absolute;
  top: -30%;
  right: -20%;
  width: 55%;
  height: 55%;
  border-radius: 50%;
  background: radial-gradient(circle, var(--color-accent-soft) 0%, transparent 75%);
  opacity: 0.5;
  pointer-events: none;
}

.services__node-header {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;
}

.services__node-icon {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--radius-md);
  background: var(--color-accent-soft);
  border: 1px solid color-mix(in oklch, var(--color-accent), transparent 75%);
  flex-shrink: 0;
}

.services__node-tag {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: var(--ls-label-md);
  text-transform: uppercase;
  color: var(--color-accent-strong);
  background: color-mix(in oklch, var(--color-accent-soft), transparent 30%);
  padding: 0.2rem 0.5rem;
  border-radius: var(--radius-pill);
  border: 1px solid color-mix(in oklch, var(--color-accent-border), transparent 60%);
}

.services__node-title {
  position: relative;
  font-size: var(--text-heading-card);
}

.services__node-body {
  position: relative;
  font-size: var(--text-xs);
  line-height: var(--lh-body-sm);
}

.services__node-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.725rem;
  font-weight: var(--fw-semibold);
  color: var(--color-accent-strong);
  text-decoration: none;
  margin-top: 0.25rem;
  transition: color var(--transition-base), transform var(--transition-base);
}

.services__node-link span {
  transition: transform var(--transition-base);
}

.services__node:hover .services__node-link {
  color: var(--color-glow);
}

.services__node:hover .services__node-link span {
  transform: translateX(4px);
}

/* Three independent transform layers, each owning one concern, so none of
   them silently overwrite each other's `transform`:
     .services__node-position → static centering (translate -50%/-50%)
     .services__node-float    → continuous idle float (transform: translateY)
     .services__node          → hover lift + glow (its own transition)
   A single element carrying both the idle float animation and a hover
   transition on `transform` would have the animation's per-frame value
   win every time, making the hover lift invisible/jittery. */
.services__node-float {
  display: contents;
}

@media (min-width: 1280px) {
  .services__node-position {
    position: absolute;
    width: clamp(180px, 15vw, 214px);
    transform: translate(-50%, -50%);
    z-index: 2;
  }

  .services__node-position--1 { left: 16%; top: 10%; }
  .services__node-position--2 { left: 84%; top: 10%; }
  .services__node-position--3 { left: 8%;  top: 50%; }
  .services__node-position--4 { left: 92%; top: 50%; }
  .services__node-position--5 { left: 16%; top: 90%; }
  .services__node-position--6 { left: 84%; top: 90%; }

  .services__node-float {
    display: block;
    animation: float-a 7.4s ease-in-out infinite;
    animation-delay: calc(var(--node-index, 0) * 0.4s);
  }

  .services__node-position--2 .services__node-float,
  .services__node-position--4 .services__node-float,
  .services__node-position--6 .services__node-float {
    animation-name: float-b;
  }
}

@media (max-width: 480px) {
  .services__node {
    padding: var(--space-5);
  }
}
