/*
 * Network Graphics System - Mesh component styles.
 *
 * Unlike Stream (this family's other SVG component), Mesh's SVG content
 * (points and edges) is entirely generated and mutated at runtime by
 * components/mesh.js - there is no hand-authored markup to colocate a
 * template with (a graph of ~30-60 randomly placed, slowly drifting points
 * with distance-based connectivity can't be hand-authored the way Stream's
 * fixed grid can - see mesh.js's own docstring). This file therefore owns
 * paint only: colour, line weight, point radius (all from variables.css)
 * and, on .mesh-edge, a `transition` on opacity - the *value* mesh.js
 * writes every frame (a continuous function of each edge's live length,
 * close pairs reading clearer and far pairs fainter) is still entirely
 * its concern, this file only owns turning those discrete every-frame
 * writes into a smooth glide, appear/disappear included (see .mesh-edge
 * below and addEdge's docstring in mesh.js for why a CSS transition, not
 * a WAAPI animation, is what makes that correct). Position is animated
 * even less here - mesh.js writes every point's cx/cy and every edge's
 * x1/y1/x2/y2 directly, every frame, as a continuous function of time (see
 * its docstring for why a CSS transition on SVG geometry doesn't work for
 * that). No other brightness animation exists in this component: points
 * render at a fixed resting opacity (below) and nothing else moves or
 * pulses. Position and light are always two separate concerns here, never
 * driven by the same mechanism.
 */

.network-mesh {
  display: block;
  width: 100%;
  height: 100%;
  /* Mesh's points are deliberately smaller than the shared
     --network-point-radius token used elsewhere in the system (Sphere,
     Stream, DNA Helix, ...) - half that size, since Mesh's ~30-60 points
     read as a dense field rather than a handful of distinct nodes, so
     each one stays small and neat instead of standing out individually.
     --network-point-radius is stored unitless (see variables.css - JS
     reads it via parseFloat), so this multiplies by `1px` to produce an
     actual `<length>` - a bare `var(--network-point-radius)` alone
     resolves to a bare number, which Chromium tolerates as a CSS
     `r`/`cx`/`cy` value but Firefox does not (it drops the declaration,
     leaving `r` at its 0 initial value - a real bug this fix corrects).
     Every consumer
     of --mesh-point-radius below inherits a valid length from this one
     multiplication, so neither needs its own `* 1px`. */
  --mesh-point-radius: calc(var(--network-point-radius) * 0.5 * 1px);
}

.mesh-point {
  fill: rgba(var(--network-point-rgb), 1);
  opacity: 0.85;
  r: var(--mesh-point-radius);
}

/* Depth cue: mesh.js assigns each point one of three size tiers at random
   (see buildMesh's SIZE_TIERS) - most points stay at the base radius
   above, a smaller share render at 1.5x and fewer still at 2x, reading
   as "nearer" points in an otherwise flat field rather than a uniform
   grid of identical dots. Declared after .mesh-point so equal-specificity
   cascade order lets these win on the points that get one of them. */
.mesh-point--md {
  r: calc(var(--mesh-point-radius) * 1.5);
}

.mesh-point--lg {
  r: calc(var(--mesh-point-radius) * 2);
}

.mesh-edge {
  fill: none;
  stroke: rgba(var(--network-line-rgb), 1);
  stroke-width: var(--network-line-width);
  stroke-linecap: round;
  /* No resting opacity value declared here - components/mesh.js writes it
     inline on every edge, every frame, as a function of the live distance
     between its two points (close = clearer, far = fainter; see
     EDGE_MIN_OPACITY / EDGE_MAX_OPACITY / computeEdgeOpacity there). This
     transition is what turns those discrete, every-~33ms writes into a
     smooth glide instead of a series of tiny steps - and, just as
     importantly, it keeps tracking correctly even when mesh.js changes
     the target again before a previous change has finished settling
     (appear/disappear included, both driven the same way): a CSS
     transition always retargets smoothly from whatever it's currently
     showing, unlike a one-shot WAAPI animation to a value fixed at the
     moment it started, which can only ever be as correct as it was back
     then. Duration matches EDGE_FADE_DURATION in mesh.js - keep both in
     sync if this changes. */
  transition: opacity 700ms ease-out;
}
