/* ===== DIAGRAM PRIMITIVES ===== */

svg.diagram {
  font-family: 'Space Grotesk', 'Space Grotesk Fallback', sans-serif;
  color: var(--diag-text);
  width: 100%;
  height: 100%;
}

.diagram-pod-rect,
.diagram-box-rect,
.diagram-cylinder-body,
.diagram-cylinder-cap,
.diagram-node-rect,
.diagram-chip-rect,
.diagram-pod-container {
  transition: fill 0.3s, stroke 0.3s, filter 0.3s, opacity 0.3s;
}

/* Pod */
.diagram-pod-rect {
  fill: var(--diag-fill-soft);
  stroke: var(--workloads-color);
  stroke-width: 1.6;
}
.diagram-pod[data-role="cluster"] .diagram-pod-rect { stroke: var(--cluster-color); }
.diagram-pod[data-role="storage"] .diagram-pod-rect { stroke: var(--storage-color); }
.diagram-pod-label {
  fill: var(--diag-text);
  font-size: 12px;
  font-weight: 600;
}
.diagram-pod-sublabel {
  fill: var(--diag-text-dim);
  font-size: 10px;
  font-family: 'JetBrains Mono', 'JetBrains Mono Fallback', monospace;
}
.diagram-pod-container {
  fill: rgba(79, 229, 255, 0.2);
  stroke: var(--workloads-color);
  stroke-width: 0.8;
  opacity: 0.8;
}
.diagram-pod[data-role="cluster"] .diagram-pod-container {
  fill: rgba(125, 134, 255, 0.18);
  stroke: var(--cluster-color);
}
.diagram-pod[data-role="storage"] .diagram-pod-container {
  fill: rgba(94, 202, 148, 0.2);
  stroke: var(--storage-color);
}

/* Highlight a pod */
.diagram-pod.highlight .diagram-pod-rect {
  filter: drop-shadow(0 0 8px var(--workloads-color));
  stroke-width: 2;
}
.diagram-pod[data-role="cluster"].highlight .diagram-pod-rect {
  filter: drop-shadow(0 0 8px var(--cluster-color));
}
.diagram-pod[data-role="storage"].highlight .diagram-pod-rect {
  filter: drop-shadow(0 0 8px var(--storage-color));
}

/* Generic box (apiserver, scheduler, kube-proxy etc.) */
.diagram-box-rect {
  fill: var(--diag-fill-soft);
  stroke: var(--diag-stroke);
  stroke-width: 1.4;
}
.diagram-box[data-role="cluster"]   .diagram-box-rect { stroke: var(--cluster-color); }
.diagram-box[data-role="network"]   .diagram-box-rect { stroke: var(--network-color); }
.diagram-box[data-role="workloads"] .diagram-box-rect { stroke: var(--workloads-color); }
.diagram-box[data-role="storage"]   .diagram-box-rect { stroke: var(--storage-color); }
.diagram-box-label {
  fill: var(--diag-text);
  font-size: 12px;
  font-weight: 600;
}
.diagram-box-sublabel {
  fill: var(--diag-text-dim);
  font-size: 10px;
  font-family: 'JetBrains Mono', 'JetBrains Mono Fallback', monospace;
}
.diagram-box.highlight .diagram-box-rect {
  filter: drop-shadow(0 0 7px currentColor);
  stroke-width: 2;
}
.diagram-box[data-role="cluster"].highlight   { color: var(--cluster-color); }
.diagram-box[data-role="network"].highlight   { color: var(--network-color); }
.diagram-box[data-role="workloads"].highlight { color: var(--workloads-color); }
.diagram-box[data-role="storage"].highlight   { color: var(--storage-color); }

/* Node */
.diagram-node-rect {
  fill: var(--diag-node-fill);
  stroke: var(--diag-node-stroke);
  stroke-width: 1.2;
  stroke-dasharray: 6 4;
}
.diagram-node-label {
  fill: var(--text-dim);
  font-size: 11px;
  font-family: 'JetBrains Mono', 'JetBrains Mono Fallback', monospace;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
/* Highlight a Node frame: the dashed stroke lifts and thickens, with no glow, so the frame still
   reads as a container around the blocks it holds rather than as one more block. */
.diagram-node.highlight .diagram-node-rect {
  stroke: var(--diag-stroke);
  stroke-width: 1.8;
}

/* Cylinder (etcd, PV, volume) */
.diagram-cylinder-body {
  fill: var(--diag-fill-soft);
  stroke: var(--storage-color);
  stroke-width: 1.4;
}
.diagram-cylinder-cap {
  fill: rgba(94, 202, 148, 0.25);
  stroke: var(--storage-color);
  stroke-width: 1.4;
}
.diagram-cylinder[data-role="cluster"] .diagram-cylinder-body { stroke: var(--cluster-color); }
.diagram-cylinder[data-role="cluster"] .diagram-cylinder-cap  { stroke: var(--cluster-color); fill: rgba(125, 134, 255, 0.2); }
.diagram-cylinder-label {
  fill: var(--diag-text);
  font-size: 12px;
  font-weight: 600;
}
.diagram-cylinder.highlight .diagram-cylinder-body,
.diagram-cylinder.highlight .diagram-cylinder-cap {
  filter: drop-shadow(0 0 7px currentColor);
}
.diagram-cylinder[data-role="storage"].highlight { color: var(--storage-color); }
.diagram-cylinder[data-role="cluster"].highlight { color: var(--cluster-color); }

/* Arrows */
.diagram-arrow {
  stroke: var(--diag-arrow);
  stroke-width: 1.6;
  fill: none;
}
/* .diagram-arrow-dim sits ABOVE the three role rules at equal specificity, so the ROLE wins the
   stroke and dim survives only as stroke-width 1.4. All 546 of the catalog's `dim: true` calls pass
   a role, so dim looks like a no-op EVERYWHERE. IT IS NOT A BUG: dim here is a stroke WEIGHT,
   not a lifecycle state, and a wire a ball rides is normally drawn dim. Measured: 710 dim lanes
   carry a packet across 585 steps. DO NOT make dim outrank role: it greys out most route wires and
   breaks the per-category colour identity: the networking exemplar's kube-proxy fan goes cyan
   to grey.
   What actually needed separating was a RELATIONSHIP line from a resting ROUTE wire, below. */
.diagram-arrow-dim { stroke: var(--diag-arrow-dim); stroke-width: 1.4; }
.diagram-arrow-dashed { stroke-dasharray: 5 5; }
.diagram-arrow-network { stroke: var(--network-color); }
.diagram-arrow-storage { stroke: var(--storage-color); }
.diagram-arrow-cluster { stroke: var(--cluster-color); }
/* A relationship line carries no ball on any step, so it must not read as a route. It keeps its
   category hue and sinks behind the live wires instead. stroke-opacity rather than a darker colour:
   the hue then stays one token per category, and an element opacity a card pins still multiplies. */
.diagram-arrow.diagram-arrow-relation { stroke-opacity: 0.45; }
.diagram-arrow.flowing {
  stroke-width: 2;
}

/* Packet */
.diagram-packet {
  fill: var(--network-color);
  filter: drop-shadow(0 0 6px var(--network-color));
}
.diagram-packet[data-role="storage"] {
  fill: var(--storage-color);
  filter: drop-shadow(0 0 6px var(--storage-color));
}
/* Brighter than the base --cluster-color so the ball reads as vividly as a tinted packet does:
   same indigo hue, lighter, the cluster-family bright stop. Tinted dialogs override it. */
.diagram-packet[data-role="cluster"] {
  fill: #abb0f5;
  filter: drop-shadow(0 0 6px #abb0f5);
}
/* A tinted dialog maps --network-color to the pale tint stop, which washes the ball out, so the
   packet is pinned to the saturated network cyan and pops against the paler pod-pulse tint. */
.diagram-packet[data-role="network"] {
  fill: #4fe5ff;
  filter: drop-shadow(0 0 6px #4fe5ff);
}

/* Arrival ripple: one-shot expanding ring at a packet's destination (see packetAlong). */
.diagram-ripple {
  fill: none;
  stroke: var(--network-color);
  stroke-width: 2.5;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 0 4px var(--network-color));
  pointer-events: none;
}
.diagram-ripple[data-role="storage"] { stroke: var(--storage-color); filter: drop-shadow(0 0 4px var(--storage-color)); }
.diagram-ripple[data-role="cluster"] { stroke: #abb0f5; filter: drop-shadow(0 0 4px #abb0f5); }
.diagram-ripple[data-role="network"] { stroke: #4fe5ff; filter: drop-shadow(0 0 4px #4fe5ff); }

/* Label */
.diagram-label {
  fill: var(--diag-text);
  font-size: 12px;
}
.diagram-label.dim { fill: var(--diag-text-dim); }
.diagram-label.code { font-family: 'JetBrains Mono', 'JetBrains Mono Fallback', monospace; font-size: 11px; }

/* Chip */
.diagram-chip-rect {
  fill: var(--diag-fill-soft);
  stroke: var(--diag-stroke-soft);
  stroke-width: 1;
}
.diagram-chip[data-role="network"]  .diagram-chip-rect { stroke: var(--network-color); }
.diagram-chip[data-role="workloads"] .diagram-chip-rect { stroke: var(--workloads-color); }
.diagram-chip[data-role="cluster"]  .diagram-chip-rect { stroke: var(--cluster-color); }
.diagram-chip[data-role="storage"]  .diagram-chip-rect { stroke: var(--storage-color); }
.diagram-chip-text {
  fill: var(--diag-text);
  font-size: 11px;
  font-family: 'JetBrains Mono', 'JetBrains Mono Fallback', monospace;
}
.diagram-chip.highlight .diagram-chip-rect {
  filter: drop-shadow(0 0 6px currentColor);
  stroke-width: 1.8;
}
.diagram-chip[data-role="network"].highlight   { color: var(--network-color); }
.diagram-chip[data-role="cluster"].highlight   { color: var(--cluster-color); }
.diagram-chip[data-role="storage"].highlight   { color: var(--storage-color); }
.diagram-chip[data-role="workloads"].highlight { color: var(--workloads-color); }

/* Outline highlight variant: thin dim baseline, bright clean border on active.
   Opt in per-diagram by adding data-style="outline" on the root <svg>. */
svg.diagram[data-style="outline"] .diagram-box-rect,
svg.diagram[data-style="outline"] .diagram-cylinder-body,
svg.diagram[data-style="outline"] .diagram-cylinder-cap,
svg.diagram[data-style="outline"] .diagram-chip-rect,
svg.diagram[data-style="outline"] .diagram-pod-rect {
  stroke-width: 1.2;
  stroke-opacity: 0.65;
}

svg.diagram[data-style="outline"] .diagram-box.highlight .diagram-box-rect,
svg.diagram[data-style="outline"] .diagram-cylinder.highlight .diagram-cylinder-body,
svg.diagram[data-style="outline"] .diagram-cylinder.highlight .diagram-cylinder-cap,
svg.diagram[data-style="outline"] .diagram-chip.highlight .diagram-chip-rect,
svg.diagram[data-style="outline"] .diagram-pod.highlight .diagram-pod-rect {
  filter: none;
  stroke-width: 2.4;
  stroke-opacity: 1;
}

/* Texture cells (the IPVS hash table): presentation, not a lifecycle shade. */
.diagram-grid-cell { opacity: 0.4; }

@media (prefers-reduced-motion: reduce) {
  .diagram-pod-rect, .diagram-box-rect, .diagram-cylinder-body, .diagram-cylinder-cap, .diagram-node-rect, .diagram-chip-rect, .diagram-pod-container {
    transition: none;
  }
}
