{# Cellular badge defs — per-variant rim/seam/canvas gradients + pattern pulse.

   Invariant 11: zero specimen hex fallbacks. All colors flow from genome
   fields validated at load time by validate_genome_against_paradigms.
   Path B grammar (v0.2.19): variant lookup via dynamic key interpolation
   on _genome_raw, never string comparison branches. Adding a new variant
   to automata.json's `variants` list + a new `variant_<name>_*` block
   requires zero template edits. #}
<clipPath id="{{ uid }}-clip">
  <rect width="{{ width }}" height="{{ height }}"/>
</clipPath>
{# v0.3.0: cellular_palette.primary holds the resolved tone dict (8 fields).
   Solo and paired variants both populate primary; badges only consume it. #}
{% set rim_stops = cellular_palette.primary.rim_stops %}
{% set seam_mid = cellular_palette.primary.seam_mid %}
{% set seam_anchor = cellular_palette.primary.cellular_cells[0] %}
{% set canvas_top = cellular_palette.primary.canvas_top %}
{% set canvas_bottom = cellular_palette.primary.canvas_bottom %}
<linearGradient id="{{ uid }}-rim" x1="0" y1="0" x2="0" y2="1">
  {% for stop in rim_stops %}
  <stop offset="{{ stop.offset }}" stop-color="{{ stop.color }}"/>
  {% endfor %}
</linearGradient>
<linearGradient id="{{ uid }}-vb" x1="0" y1="0" x2="0" y2="1">
  <stop offset="0%" stop-color="{{ canvas_top }}"/>
  <stop offset="100%" stop-color="{{ canvas_bottom }}"/>
</linearGradient>
<linearGradient id="{{ uid }}-seam" x1="0" y1="0" x2="0" y2="1">
  <stop offset="0%"   stop-color="{{ seam_anchor }}" stop-opacity="0"/>
  <stop offset="18%"  stop-color="{{ seam_anchor }}" stop-opacity="0.55"/>
  <stop offset="50%"  stop-color="{{ seam_mid }}" stop-opacity="0.82"/>
  <stop offset="82%"  stop-color="{{ seam_anchor }}" stop-opacity="0.55"/>
  <stop offset="100%" stop-color="{{ seam_anchor }}" stop-opacity="0"/>
</linearGradient>
<filter id="{{ uid }}-lift" x="-4%" y="-12%" width="108%" height="130%">
  <feDropShadow dx="0" dy="{{ 0.4 if compact else 0.5 }}" stdDeviation="{{ 0.4 if compact else 0.6 }}" flood-color="var(--dna-shadow-color, black)" flood-opacity="0.32"/>
</filter>
<style>{{ font_faces | safe }}
.cz1{animation:czp {{ cellular_pulse_base_duration }} ease-in-out infinite;will-change:opacity}
.cz2{animation:czp {{ cellular_pulse_base_duration }} ease-in-out infinite 1.5s;will-change:opacity}
.cz3{animation:czp {{ cellular_pulse_base_duration }} ease-in-out infinite 3s;will-change:opacity}
.cz4{animation:czp {{ cellular_pulse_base_duration }} ease-in-out infinite 4.5s;will-change:opacity}
.czf{animation:czp {{ cellular_pulse_fast_duration }} ease-in-out infinite 0.5s;will-change:opacity}
.czd{opacity:.07}
@keyframes czp{0%,100%{opacity:.04}30%{opacity:.7}50%{opacity:.2}70%{opacity:.55}}
@media(prefers-reduced-motion:reduce){.cz1,.cz2,.cz3,.cz4,.czf{animation:none!important;opacity:.25!important}}
{% if is_state_badge %}{% include "partials/state-signal-cascade.j2" %}{% endif %}
</style>
