/*
 * doc-mermaid-spectrum.css — Spectrum, Glow and Weight: colour that follows a diagram's flow, a
 * soft light along it, and how heavy its lines are (CH-REQ-20260929-A §10).
 *
 * The runtime (src/modules/markdown-engine/elements/mermaid/spectrum.js) gives each node a
 * `--spectrum` hue from where it stands along the diagram, each edge a gradient from its source's hue
 * to its target's as `--spectrum-stroke` (with `--spectrum-from` / `--spectrum-to` for its particles),
 * and each edge a halo copy behind it for Glow. Everything visual is here, so the workspace, an
 * exported page and /help draw the same colours.
 *
 * Part of the diagram's frame, like doc-mermaid.css, but dark wherever the diagram is drawn dark: under
 * `data-mermaid-scheme`, which every renderer sets, as well as `data-doc-scheme`. The blog and /help
 * set only the first, and a tint keyed on the second alone mixed white into a dark diagram's boxes,
 * under its white words (CH-REQ-20260929-A §30). Every rule beats Mermaid's own through `!important`,
 * since Mermaid's <style> reaches its shapes by the diagram's #id. What counts as a node's body was
 * measured on every graph type in every view.
 */

.doc-mermaid-viewer {
  --mermaid-spectrum-ground: #ffffff;
  --mermaid-spectrum-bead: #1e293b;
}

/* A bead is its edge's hue lifted toward the canvas's opposite, or it would vanish on its own line. */
:root:is([data-mermaid-scheme='dark'], [data-doc-scheme='dark']) .doc-mermaid-viewer {
  --mermaid-spectrum-ground: #0d1117;
  --mermaid-spectrum-bead: #ffffff;
}

/* A node: its outline in its hue, its body a tint of it. A label's own background, and a state's start
   and end dots, are not the body. Hand-drawn bodies are hatching, so they take the hue, not a fill. */
svg[data-spectrum] [data-spectrum-node] :is(.label-container, .label-container > path, .outer-path > path, .row-rect-odd > path, .divider > path),
svg[data-spectrum] [data-spectrum-node] rect.actor,
svg[data-spectrum] line.actor-line[data-spectrum-node] {
  stroke: var(--spectrum) !important;
}

svg[data-spectrum] :is(g.node, g.cluster)[data-spectrum-node] :is(.label-container, .outer-path > path),
svg[data-spectrum] [data-spectrum-node] rect.actor {
  fill: color-mix(in oklab, var(--spectrum) 16%, var(--mermaid-spectrum-ground)) !important;
  stroke-width: 2px !important;
}

svg[data-spectrum] g.node[data-spectrum-node] .row-rect-odd > path {
  fill: color-mix(in oklab, var(--spectrum) 8%, var(--mermaid-spectrum-ground)) !important;
}

/* Hand-drawn (CH-REQ-20260929-A §14). A body there is hatching: every shape draws it first, as thick
   strokes, and its outline second (measured on every Hand-drawn shape). In the full hue the hatching
   was louder than the words on it, so it takes a light mix of the hue and the outline keeps the hue.
   Outline has no hatching at all (doc-mermaid-finish.css): this, more specific, must not bring it back. */
svg[data-spectrum]:not([data-fill='outline']) [data-spectrum-node][data-look='handDrawn'] :is(.label-container, .outer-path) > path:first-child,
svg[data-spectrum]:not([data-fill='outline']) g.cluster[data-spectrum-node][data-look='handDrawn'] > g > path:first-child {
  stroke: color-mix(in oklab, var(--spectrum) 42%, var(--mermaid-spectrum-ground)) !important;
}

/* And a label on hatching sits on a plate of the canvas's own colour, as Mermaid's edge labels do: the
   hatch shows around the words, never through them. */
svg[data-spectrum] :is(g.rough-node, g.cluster[data-look='handDrawn']) foreignObject > div {
  background-color: color-mix(in oklab, var(--mermaid-spectrum-ground) 90%, transparent) !important;
  border-radius: 3px !important;
}

svg[data-spectrum] :is(g.rough-node, g.cluster[data-look='handDrawn']) text {
  paint-order: stroke fill !important;
  stroke: var(--mermaid-spectrum-ground, Canvas) !important;
  stroke-width: 4px !important;
  stroke-linejoin: round !important;
}

/* A subgraph, faintly in the hue of where it stands. */
svg[data-spectrum] g.cluster[data-spectrum-node] > rect {
  fill: color-mix(in oklab, var(--spectrum) 5%, var(--mermaid-spectrum-ground)) !important;
  stroke: color-mix(in oklab, var(--spectrum) 70%, var(--mermaid-spectrum-ground)) !important;
}

/* An edge in Flow: the gradient from where it leaves to where it arrives. In Mosaic a line keeps the
   theme's colour, and only what moves along it takes a hue. */
svg[data-spectrum='flow'] [data-spectrum-edge] {
  stroke: var(--spectrum-stroke, none) !important;
}

svg[data-spectrum='flow'] [data-spectrum-edge]:is(.edge-thickness-normal, .messageLine0, .messageLine1) {
  stroke-width: 2px !important;
}

/* Particles change colour as they travel: the fill itself is animated. Not through `color`, which the
   frame pins inside every drawing (`.doc-mermaid svg * { color: unset !important }`), and with no
   `!important` fill of its own, which would stop the animation. */
@supports (offset-path: path("M 0 0 L 1 1")) {
  svg[data-spectrum] [data-spectrum-motion] .doc-mermaid-motion-dot {
    fill: color-mix(in oklab, var(--spectrum-from, currentColor) 50%, var(--mermaid-spectrum-bead));
    animation:
      doc-mermaid-motion var(--mermaid-motion-duration, 0s) linear var(--mermaid-motion-delay, 0s) infinite,
      doc-mermaid-spectrum var(--mermaid-motion-duration, 0s) linear var(--mermaid-motion-delay, 0s) infinite;
  }

  svg[data-spectrum] [data-spectrum-motion][data-reverse] .doc-mermaid-motion-dot {
    animation-direction: reverse;
  }

  /* Mosaic: a particle keeps one hue, near its full strength — its line is in the theme's colour, not
     its own, so it needs lifting only a little to stand out. */
  svg[data-spectrum='mosaic'] [data-spectrum-motion] .doc-mermaid-motion-dot {
    fill: color-mix(in oklab, var(--spectrum-from, currentColor) 82%, var(--mermaid-spectrum-bead));
    animation: doc-mermaid-motion var(--mermaid-motion-duration, 0s) linear var(--mermaid-motion-delay, 0s) infinite;
  }

  svg[data-spectrum='mosaic'] [data-spectrum-motion][data-reverse] .doc-mermaid-motion-dot {
    animation-direction: reverse;
  }

  /* Current and Signal in the line's colours lifted toward the canvas's opposite, like a bead: in the
     line's own they vanished into it (found filming GIFs, CH-REQ-20260929-C). */
  svg[data-spectrum] [data-spectrum-motion] :is(.doc-mermaid-motion-current, .doc-mermaid-motion-signal) {
    stroke: var(--spectrum-stroke-lit, var(--spectrum-stroke, none)) !important;
  }
}

@keyframes doc-mermaid-spectrum {
  from {
    fill: color-mix(in oklab, var(--spectrum-from, currentColor) 50%, var(--mermaid-spectrum-bead));
  }
  to {
    fill: color-mix(in oklab, var(--spectrum-to, currentColor) 50%, var(--mermaid-spectrum-bead));
  }
}

/* Glow: a soft, wider copy of each edge behind it; a node's outline casts light of its own colour. */
.doc-mermaid-halo {
  display: none;
}

svg[data-glow] .doc-mermaid-halo {
  display: inline;
  fill: none !important;
  stroke-width: 8px !important;
  stroke-dasharray: none !important;
  stroke-linecap: round;
  opacity: 0.34;
  pointer-events: none;
}

svg[data-glow][data-spectrum='flow'] .doc-mermaid-halo {
  stroke: var(--spectrum-stroke, none) !important;
}

/* In Hand-drawn only the outline shines: a shape's first path is its hatching, and light cast from every
   hatch line behind the words was texture to read them through (§14). */
svg[data-glow] :is(g.node, g.rough-node):not([data-look='handDrawn']) :is(.label-container, .outer-path > path),
svg[data-glow] :is(g.node, g.rough-node)[data-look='handDrawn'] :is(.label-container, .outer-path) > path:not(:first-child),
svg[data-glow] rect.actor {
  filter: drop-shadow(0 0 6px color-mix(in oklab, var(--spectrum, var(--mermaid-motion-dot, currentColor)) 70%, transparent));
}

:root:not([data-mermaid-scheme='dark'], [data-doc-scheme='dark']) svg[data-glow] .doc-mermaid-halo {
  opacity: 0.14;
}

/* Weight: every line finer or heavier. Widths only — an author's dotted or dashed edge keeps its
   pattern — and a thick (`==>`) edge stays thicker than a normal one. */
svg[data-weight='fine'] :is(.edgePaths > path, path.flowchart-link, .messageLine0, .messageLine1, .architecture-edges path.edge):not(.edge-thickness-thick):not(.doc-mermaid-halo) {
  stroke-width: 1px !important;
}

svg[data-weight='fine'] :is(.edgePaths > path, path.flowchart-link).edge-thickness-thick {
  stroke-width: 2.5px !important;
}

svg[data-weight='bold'] :is(.edgePaths > path, path.flowchart-link, .messageLine0, .messageLine1, .architecture-edges path.edge):not(.edge-thickness-thick):not(.doc-mermaid-halo) {
  stroke-width: 3px !important;
}

svg[data-weight='bold'] :is(.edgePaths > path, path.flowchart-link).edge-thickness-thick {
  stroke-width: 5px !important;
}

svg[data-weight='bold'] .doc-mermaid-halo {
  stroke-width: 11px !important;
}

/* Paper takes the colours, but not the light. */
@media print {
  svg[data-glow] .doc-mermaid-halo {
    display: none !important;
  }

  svg[data-glow] :is(g.node, g.rough-node) :is(.label-container, .outer-path > path),
  svg[data-glow] :is(g.node, g.rough-node) :is(.label-container, .outer-path) > path,
  svg[data-glow] rect.actor {
    filter: none !important;
  }
}
