/* ==========================================================================
   Cloudpilar — native animated SVG diagrams
   Ported from cloudpilar-native-diagrams.html. Every selector is scoped under
   .cp-diagram so the generic class names inside (.node, .title, .copy...)
   never leak onto unrelated WordPress core or plugin markup. Colour and font
   custom properties are the theme's own tokens, not the demo's standalone
   values, so a diagram sitting next to a .cp-card is unmistakably the same
   product rather than a pasted-in artefact.
   ========================================================================== */

.cp-diagram {
  --cp-diagram-cyan: var(--wp--preset--color--accent);
  --cp-diagram-border: var(--cp-rule);

  position: relative;
  width: 100%;
  overflow: hidden;
  border: 1px solid var(--cp-diagram-border);
  border-radius: var(--wp--custom--radius--xl);
  background:
    radial-gradient(circle at 85% 15%, color-mix(in srgb, var(--cp-diagram-cyan) 8%, transparent), transparent 28%),
    linear-gradient(180deg, var(--wp--preset--color--white), var(--wp--preset--color--paper));
  margin-block: clamp(1.75rem, 3.5vw, 2.75rem);
}

/* -- Responsive layout swap ------------------------------------------------
   A 1200-unit viewBox scaled into a 375px phone is a ~0.27 factor, which
   renders 16px labels at about 4.4px. Rather than shrink the wrapper and
   leave unreadable text, small screens get a purpose-built 360-unit vertical
   stack that renders close to 1:1. The wide layout returns at 1000px, the
   point where it is comfortably legible again. */

/* These selectors must out-rank `.cp-diagram svg { display: block }` below,
   which is specificity (0,1,1) — a bare `.cp-diagram__svg-mobile` at (0,1,0)
   loses to it and BOTH layouts render at once. Qualifying with svg makes
   these (0,2,1). */
.cp-diagram svg.cp-diagram__svg-desktop {
  display: none;
}

.cp-diagram svg.cp-diagram__svg-mobile {
  display: block;
  /* Held close to the 360-unit viewBox width so the stack renders near 1:1.
     At 440px it magnified by 22% and pushed tablet labels past 20px, which
     read as clumsy rather than compact. Phones sit below this cap anyway, so
     this only governs the tablet range. */
  max-width: 380px;
  margin-inline: auto;
}

@media (min-width: 1000px) {
  .cp-diagram svg.cp-diagram__svg-desktop {
    display: block;
  }

  .cp-diagram svg.cp-diagram__svg-mobile {
    display: none;
  }
}

/* Type inside the stack is near 1:1, so these are close to rendered pixels.
   The extra .cp-diagram on each selector is load-bearing: the base
   `.cp-diagram .node-title` rule further down this file has identical
   specificity, and being later would otherwise win. */
.cp-diagram .cp-diagram__svg-mobile .node-title {
  font-size: 17px;
}

.cp-diagram .cp-diagram__svg-mobile .node-title.is-compact {
  font-size: 14px;
}

.cp-diagram .cp-diagram__svg-mobile .node-sub {
  font-size: 12px;
}

.cp-diagram .cp-diagram__svg-mobile .node-sub.is-compact {
  font-size: 11px;
}

.cp-diagram .cp-diagram__svg-mobile .node-num {
  font-size: 11px;
}

.cp-diagram.dark {
  --cp-diagram-border: var(--cp-rule-ink);

  border-color: var(--cp-diagram-border);
  background:
    radial-gradient(circle at 75% 10%, color-mix(in srgb, var(--cp-diagram-cyan) 10%, transparent), transparent 30%),
    var(--cp-ink);
  color: var(--wp--preset--color--on-ink);
}

.cp-diagram .cp-inner {
  padding: clamp(16px, 3vw, 30px);
}

/* The heading here sits inside a section that already has its own heading, so
   it reads as a caption rather than a page-level title — smaller than the
   section h2 on purpose, and tight to the copy beneath it. */
.cp-diagram .title {
  margin: 0;
  max-width: 720px;
  font-family: var(--wp--preset--font-family--display);
  font-weight: 500;
  font-size: clamp(1.1875rem, 1.05rem + 0.7vw, 1.75rem);
  line-height: 1.18;
  letter-spacing: -0.025em;
  color: var(--wp--preset--color--ink);
}

.cp-diagram.dark .title {
  color: var(--wp--preset--color--on-ink);
}

.cp-diagram .copy {
  max-width: 680px;
  margin: 7px 0 0;
  color: var(--wp--preset--color--text-muted);
  font-family: var(--wp--preset--font-family--body);
  font-size: clamp(0.875rem, 0.83rem + 0.2vw, 0.9688rem);
  line-height: 1.5;
}

.cp-diagram.dark .copy {
  color: var(--wp--preset--color--on-ink-muted);
}

/* Text block and canvas should read as one unit, not two stacked blocks. */
.cp-diagram .canvas {
  margin-top: clamp(14px, 2vw, 22px);
}

/* With no heading of its own, a bare diagram is pure canvas — it only needs
   enough padding to keep the artwork off the border. */
.cp-diagram--bare .cp-inner {
  padding: clamp(12px, 2vw, 22px);
}

.cp-diagram--bare .canvas {
  margin-top: 0;
}

/* The capability map is the widest of the set and was rendering ~765px tall
   at desktop, reading as the page's main event rather than support for it.
   Capping the whole component (not just the SVG) keeps it a centred figure
   inside the column instead of a full-bleed band. */
@media (min-width: 1000px) {
  .cp-diagram--capability {
    max-width: 850px;
    margin-inline: auto;
  }

  .cp-diagram--capability .cp-inner {
    padding: 20px 26px 22px;
  }

  .cp-diagram--capability .canvas {
    margin-top: 12px;
  }

  .cp-diagram--capability .copy {
    margin-top: 5px;
  }
}

.cp-diagram svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* -- Nodes ---------------------------------------------------------------- */

.cp-diagram .node rect,
.cp-diagram .node circle.bg {
  fill: var(--wp--preset--color--white);
  stroke: var(--cp-diagram-border);
  stroke-width: 1.4;
  vector-effect: non-scaling-stroke;
}

.cp-diagram.dark .node rect,
.cp-diagram.dark .node circle.bg {
  fill: rgba(255, 255, 255, 0.045);
  stroke: rgba(255, 255, 255, 0.16);
}

.cp-diagram .node[data-accent="true"] rect,
.cp-diagram .node[data-accent="true"] circle.bg {
  fill: color-mix(in srgb, var(--cp-diagram-cyan) 9%, transparent);
  stroke: color-mix(in srgb, var(--cp-diagram-cyan) 48%, transparent);
}

.cp-diagram.dark .node[data-accent="true"] rect,
.cp-diagram.dark .node[data-accent="true"] circle.bg {
  fill: color-mix(in srgb, var(--cp-diagram-cyan) 10%, transparent);
  stroke: color-mix(in srgb, var(--cp-diagram-cyan) 48%, transparent);
}

.cp-diagram .node-title {
  fill: var(--wp--preset--color--ink);
  font-family: var(--wp--preset--font-family--display);
  font-weight: 600;
  font-size: 16px;
}

.cp-diagram.dark .node-title {
  fill: var(--wp--preset--color--on-ink);
}

.cp-diagram .node-sub {
  fill: var(--wp--preset--color--text-muted);
  font-family: var(--wp--preset--font-family--body);
  font-size: 12px;
}

.cp-diagram.dark .node-sub {
  fill: var(--wp--preset--color--on-ink-muted);
}

.cp-diagram .node-num {
  fill: var(--cp-diagram-cyan);
  font-family: var(--wp--preset--font-family--body);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.08em;
}

.cp-diagram .icon {
  fill: none;
  stroke: var(--wp--preset--color--ink-3);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.cp-diagram.dark .icon {
  stroke: rgba(255, 255, 255, 0.68);
}

.cp-diagram .node[data-accent="true"] .icon {
  stroke: var(--cp-diagram-cyan);
}

/* -- Connectors, tracks, labels -------------------------------------------- */

.cp-diagram .connector {
  fill: none;
  stroke: var(--cp-diagram-border);
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

.cp-diagram.dark .connector {
  stroke: rgba(255, 255, 255, 0.24);
}

.cp-diagram .connector.accent {
  stroke: color-mix(in srgb, var(--cp-diagram-cyan) 72%, transparent);
}

.cp-diagram.dark .connector.accent {
  stroke: color-mix(in srgb, var(--cp-diagram-cyan) 75%, transparent);
}

.cp-diagram .track {
  fill: none;
  stroke: rgba(11, 16, 32, 0.08);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

.cp-diagram.dark .track {
  stroke: rgba(255, 255, 255, 0.08);
}

.cp-diagram .flow-dot {
  fill: var(--cp-diagram-cyan);
}

.cp-diagram .label {
  fill: var(--wp--preset--color--text-muted);
  font-family: var(--wp--preset--font-family--body);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.02em;
}

.cp-diagram.dark .label {
  fill: var(--wp--preset--color--on-ink-muted);
}

.cp-diagram .ring {
  fill: none;
  stroke: color-mix(in srgb, var(--cp-diagram-cyan) 22%, transparent);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

/* -- Reveal-on-scroll animation --------------------------------------------
   Scoped to .cp-diagram-anim — armed inline in <head> alongside (but
   independently of) the generic .cp-anim gate used for .cp-reveal elements,
   with its own failsafe in diagrams.js. Diagrams have a separate script and
   a separate IntersectionObserver from the rest of the theme, so they need
   their own kill-switch: if theme.js loads but diagrams.js does not, .cp-anim
   would already be cleared and would wrongly leave diagram nodes governed by
   a gate nobody is going to satisfy. Two independent gates, two independent
   failsafes — each script only answers for its own animation system. */

.cp-diagram-anim .cp-diagram[data-animated="true"] .node,
.cp-diagram-anim .cp-diagram[data-animated="true"] .reveal {
  opacity: 0;
  transform: translateY(10px);
  transform-box: fill-box;
  transform-origin: center;
}

.cp-diagram-anim .cp-diagram[data-animated="true"] .connector {
  stroke-dasharray: var(--len, 1000);
  stroke-dashoffset: var(--len, 1000);
}

.cp-diagram-anim .cp-diagram.is-visible .node,
.cp-diagram-anim .cp-diagram.is-visible .reveal {
  animation: cp-diagram-node-in 420ms cubic-bezier(0.2, 0.7, 0.2, 1) forwards;
  animation-delay: var(--delay, 0ms);
}

.cp-diagram-anim .cp-diagram.is-visible .connector {
  animation: cp-diagram-line-in var(--dur, 760ms) cubic-bezier(0.25, 0.6, 0.25, 1) forwards;
  animation-delay: var(--delay, 0ms);
}

.cp-diagram-anim .cp-diagram.is-complete [data-pulse="true"] {
  animation: cp-diagram-pulse 4.8s ease-in-out infinite 1.4s;
}

.cp-diagram-anim .cp-diagram.is-complete .ring[data-pulse-ring="true"] {
  animation: cp-diagram-ring-pulse 4.8s ease-in-out infinite 1.4s;
}

@keyframes cp-diagram-node-in {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.985);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes cp-diagram-line-in {
  to {
    stroke-dashoffset: 0;
  }
}

@keyframes cp-diagram-pulse {
  0%, 82%, 100% {
    opacity: 1;
  }
  90% {
    opacity: 0.78;
  }
}

@keyframes cp-diagram-ring-pulse {
  0%, 82%, 100% {
    opacity: 0.25;
    transform: scale(1);
  }
  90% {
    opacity: 0.55;
    transform: scale(1.05);
  }
}

@media (max-width: 640px) {
  .cp-diagram {
    border-radius: 16px;
  }

  .cp-diagram .cp-inner {
    padding: 16px 14px;
  }

  .cp-diagram .canvas {
    margin-top: 14px;
  }
}

/* Without scripting (.cp-anim absent, see header.php's failsafe), or with
   reduced motion requested, every diagram must render fully built. */
@media (prefers-reduced-motion: reduce) {
  .cp-diagram[data-animated="true"] .node,
  .cp-diagram[data-animated="true"] .reveal,
  .cp-diagram[data-animated="true"] .connector,
  .cp-diagram[data-animated="true"] [data-pulse="true"],
  .cp-diagram[data-animated="true"] .ring {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    stroke-dashoffset: 0 !important;
  }
}
