/* The swarm page's data visualizations, which shadcn has no component for:
   the force-directed graph (swarms/_graph, drawn by swarm_graph_controller
   with d3) and its key, and the week's drop zones (swarms/_lane, lit by
   swarm_week_controller while a member is dragged over one).

   Exempt from the area rule (test/architecture/area_stylesheets_test.rb) —
   but it reads only the kit's tokens, so the dark theme and Branding reach
   the SVG d3 draws. */
@layer ui {
  /* ---- The graph ---- */

  /* The week's scrubber, in the primary. */
  .swarm-graph__scrubber {
    accent-color: var(--primary);
  }

  /* The key: a dot in each node's colour before its name. */
  .swarm-graph__key {
    align-items: center;
    display: inline-flex;
    gap: 0.25rem;

    &::before {
      background-color: var(--swarm-node);
      block-size: 0.625rem;
      border-radius: 999px;
      content: "";
      inline-size: 0.625rem;
    }
  }

  /* Node colours, shared by the key and the graph: the swarm in the primary,
     its accounts in a quiet ink, an agent by how its last run went. */
  .swarm-graph__key--swarm, .swarm-graph__node--swarm { --swarm-node: var(--primary); }
  .swarm-graph__key--account, .swarm-graph__node--account { --swarm-node: var(--muted-foreground); }
  .swarm-graph__key--agent, .swarm-graph__node--idle, .swarm-graph__node--canceled {
    --swarm-node: color-mix(in oklch, var(--muted-foreground) 50%, var(--background));
  }
  .swarm-graph__key--running, .swarm-graph__node--running { --swarm-node: var(--info); }
  .swarm-graph__node--completed { --swarm-node: var(--success); }
  .swarm-graph__node--pending { --swarm-node: var(--warning); }
  .swarm-graph__node--failed { --swarm-node: var(--destructive); }

  .swarm-graph__svg {
    background: radial-gradient(circle at 50% 45%, var(--muted) 0%, transparent 70%);
    block-size: 32.5rem;
    border-radius: var(--radius-lg);
    cursor: grab;
    display: block;
    inline-size: 100%;
    touch-action: none; /* let d3-zoom own gestures */

    &:active {
      cursor: grabbing;
    }
  }

  /* The SVG's insides, which d3 creates and classes. */
  .swarm-graph__link {
    opacity: 0.5;
    stroke: var(--input);
    transition: opacity 150ms ease-out;

    &.is-active {
      animation: swarm-flow 0.8s linear infinite;
      opacity: 1;
      stroke-dasharray: 5 6;
    }

    &.is-cycle {
      opacity: 1;
      stroke: var(--primary);
    }

    &.is-dim {
      opacity: 0.08;
    }
  }

  .swarm-graph__link--target { stroke-dasharray: 2 5; }
  .swarm-graph__link--work { opacity: 0.7; }
  .swarm-graph__link--completed { stroke: var(--success); }
  .swarm-graph__link--running { stroke: var(--info); }
  .swarm-graph__link--pending { stroke: var(--warning); }
  .swarm-graph__link--failed { stroke: var(--destructive); }
  .swarm-graph__link--canceled { stroke: var(--muted-foreground); }

  .swarm-graph__node {
    cursor: pointer;
    transition: opacity 150ms ease-out;

    &.is-dim { opacity: 0.18; }
    &.is-off { opacity: 0.45; }
  }

  .swarm-graph__dot {
    fill: var(--swarm-node);
    stroke: var(--card);
    stroke-width: 2.5;
  }

  .swarm-graph__halo {
    fill: var(--swarm-node);
    opacity: 0;
    transform-box: fill-box;
    transform-origin: center;

    .is-active > & {
      animation: swarm-pulse 1.7s ease-out infinite;
      opacity: 0.25;
    }

    .is-cycle > & {
      animation: swarm-pulse 1.4s ease-out infinite;
      opacity: 0.32;
    }
  }

  .swarm-graph__node.is-cycle .swarm-graph__dot {
    filter: url(#swarm-glow);
  }

  .swarm-graph__icon {
    fill: var(--card);
    font-size: var(--text-x-small);
    font-weight: 700;
    pointer-events: none;

    .swarm-graph__node--swarm & {
      font-size: var(--text-large);
    }
  }

  .swarm-graph__label {
    fill: var(--foreground);
    font-size: var(--text-x-small);
    font-weight: 500;
    paint-order: stroke;
    pointer-events: none;
    stroke: var(--card);
    stroke-width: 3px;
  }

  @keyframes swarm-pulse {
    0% { opacity: 0.4; transform: scale(0.7); }
    100% { opacity: 0; transform: scale(1.7); }
  }

  @keyframes swarm-flow {
    to { stroke-dashoffset: -22; }
  }

  @media (prefers-reduced-motion: reduce) {
    .swarm-graph__link.is-active,
    .is-active > .swarm-graph__halo,
    .is-cycle > .swarm-graph__halo {
      animation: none;
    }

    .is-active > .swarm-graph__halo,
    .is-cycle > .swarm-graph__halo {
      opacity: 0.28;
    }
  }

  /* ---- The week ---- */

  /* A day's drop zone: an outline that shows only while a member is dragged
     over it. */
  .swarm-lane__drop {
    border: 1px dashed transparent;
    border-radius: var(--radius-lg);
    transition: background-color 150ms ease-out, border-color 150ms ease-out;
  }

  .swarm-lane__drop--over {
    background-color: color-mix(in oklch, var(--primary) 6%, transparent);
    border-color: color-mix(in oklch, var(--primary) 50%, transparent);
  }
}
