/* ============================================================
   Klasa w chmurze: diagram grammar
   Level A: background construction sketches (.c-sketch)
   Level B: information diagrams (.c-diagram, dg-* vocabulary)
   ============================================================ */

/* ---- Level A: background sketches ---- */

.c-sketch {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: var(--z-sketch);
  pointer-events: none;
}

.c-sketch svg {
  position: absolute;
}

.c-sketch .dg-node,
.c-sketch .dg-edge,
.c-sketch .dg-boundary,
.c-sketch .dg-inset {
  fill: none;
  stroke: var(--line-primary);
  stroke-width: 1;
  stroke-dasharray: none;
  opacity: 0.055;
}

.c-sketch .dg-boundary {
  stroke-dasharray: 6 4;
}

.c-sketch .dg-label {
  fill: var(--line-sketch-label);
  stroke: none;
}

@media (max-width: 640px) {
  .c-sketch {
    display: none;
  }
}

/* ---- Level B: information diagrams ---- */

.c-diagram {
  margin: 0;
}

.c-diagram svg {
  width: 100%;
  height: auto;
}

.c-diagram figcaption {
  margin-top: var(--space-12);
  padding-top: var(--space-8);
  border-top: var(--stroke-hair) solid var(--line-subtle);
}

/* ---- Shared vocabulary ---- */

.dg-node {
  fill: var(--surface-paper);
  stroke: var(--text-primary);
  stroke-width: var(--stroke-tech);
}

.dg-node--fill {
  fill: var(--surface-technical);
}

.dg-node--key {
  stroke: var(--accent);
  fill: var(--accent-wash);
}

.dg-inset {
  fill: none;
  stroke: var(--text-muted);
  stroke-width: var(--stroke-construction);
}

.dg-edge {
  fill: none;
  stroke: var(--text-primary);
  stroke-width: var(--stroke-tech);
}

.dg-edge--key {
  stroke: var(--accent);
  stroke-width: var(--stroke-emph);
}

.dg-edge--construction {
  stroke: var(--text-muted);
  stroke-width: var(--stroke-construction);
  stroke-dasharray: 2 4;
}

.dg-boundary {
  fill: none;
  stroke: var(--text-muted);
  stroke-width: var(--stroke-construction);
  stroke-dasharray: 6 4;
}

.dg-boundary--key {
  stroke: var(--accent);
}

.dg-label {
  font-family: var(--font-mono);
  font-weight: 500;
  font-size: 10px;
  letter-spacing: 0.1em;
  fill: var(--text-secondary);
}

.dg-label--muted {
  fill: var(--text-muted);
  font-weight: 400;
}

.dg-label--accent {
  fill: var(--accent);
}

.dg-marker {
  fill: none;
  stroke: var(--text-primary);
  stroke-width: var(--stroke-tech);
}

.dg-marker--accent {
  stroke: var(--accent);
  stroke-width: var(--stroke-emph);
}

.dg-dot {
  fill: var(--accent);
  stroke: none;
}

/* ---- One-time draw-in (motion-safe, JS-gated) ----
   Fail-safe model: the BASE state is fully visible. Animation
   only starts when .is-inview lands; `backwards` fill shows the
   hidden "from" state during each element's stagger delay.
   If JS or IntersectionObserver never runs, nothing is hidden.
   Solid/key edges carry pathLength="1" (geometry-free dash math);
   construction edges do NOT (it would destroy their dash pattern). */

@media (prefers-reduced-motion: no-preference) {
  .js .c-diagram.is-inview [pathLength] {
    stroke-dasharray: 1;
    animation: dg-draw var(--dur-draw) var(--ease) backwards;
    animation-delay: calc(var(--d, 0) * 120ms);
  }

  @keyframes dg-draw {
    from {
      stroke-dashoffset: 1;
    }

    to {
      stroke-dashoffset: 0;
    }
  }

  .js .c-diagram.is-inview .dg-node,
  .js .c-diagram.is-inview .dg-inset,
  .js .c-diagram.is-inview .dg-label,
  .js .c-diagram.is-inview .dg-boundary,
  .js .c-diagram.is-inview .dg-dot,
  .js .c-diagram.is-inview .dg-edge--construction {
    animation: dg-fade var(--dur-slow) var(--ease) backwards;
    animation-delay: calc(var(--d, 0) * 120ms);
  }

  @keyframes dg-fade {
    from {
      opacity: 0;
    }

    to {
      opacity: 1;
    }
  }
}
