{# HyperWeave Error Badge -- universal SMPTE NO SIGNAL fallback.

   Rendered by serve/app.py whenever an artifact cannot be composed
   (genome missing, template not found, validation failure, any compose
   exception). Single template -- the HTTP layer parameterizes the
   status code so a missing genome shows ERR_404, a Pydantic validation
   miss shows ERR_422, and a generic compose failure shows ERR_500.

   Required context (passed by `_error_badge` in serve/app.py):
     status_code -- numeric HTTP status (404, 422, 500, ...).
     message     -- human-readable error message (truncated).
                    Goes into <title>/<desc> for screen readers; the
                    visual surface only shows the status code.
     uid         -- short ID prefix (e.g. "hw-err-04321") that scopes
                    every gradient, filter, clip-path, class, and
                    keyframes name. Multiple error badges on the same
                    page render without DOM collisions.

   Aesthetic reference: tier2/genomes/__errors__/404-badge.svg
   SMPTE RP 219 color bars: white/yellow/cyan/green/magenta/red/blue
#}
<svg xmlns="http://www.w3.org/2000/svg"
     xmlns:hw="https://hyperweave.app/hw/v1.0"
     viewBox="{{ error_viewbox }}" width="{{ error_w }}" height="{{ error_h }}"
     role="img" aria-labelledby="{{ uid }}-t {{ uid }}-d"
     data-hw-id="{{ uid }}"
     data-hw-type="badge"
     data-hw-class="error-state"
     data-hw-genome="signal-loss"
     data-hw-profile="memetic-tv"
     data-hw-variant="rainbow-static"
     data-hw-status-code="{{ status_code }}"
     data-hw-label="NO SIGNAL"
     data-hw-value="ERR_{{ status_code }}"
     data-hw-glyph="signal-loss"
     data-hw-fallback="universal"
     data-hw-frame-treatment="chrome-rim-refined-seam"
     style="shape-rendering:geometricPrecision">
  <title id="{{ uid }}-t">NO SIGNAL · ERR_{{ status_code }}</title>
  <desc id="{{ uid }}-d">{{ message | xml_escape }}</desc>
  <metadata>
    <hw:artifact id="{{ uid }}" type="badge" class="error-state"
                 genome="signal-loss" status-code="{{ status_code }}"
                 frame="chrome-rim-refined-seam"/>
    <hw:provenance generator="hyperweave-error-fallback" source="error-badge.svg.j2"/>
    <hw:spec viewBox="{{ error_viewbox }}" theme="dark-only" a11y="WCAG-AA"
             cim-compliant="paint-ok" self-contained="true"/>
  </metadata>
  <defs>
    <linearGradient id="{{ uid }}-rim" x1="0" y1="0" x2="0" y2="1">
{% for stop in error_rim_stops %}
      <stop offset="{{ stop.offset }}" stop-color="{{ stop.color }}"/>
{% endfor %}
    </linearGradient>
    <linearGradient id="{{ uid }}-vb" x1="0" y1="0" x2="0" y2="1">
{% for stop in error_value_stops %}
      <stop offset="{{ stop.offset }}" stop-color="{{ stop.color }}"/>
{% endfor %}
    </linearGradient>
    <linearGradient id="{{ uid }}-seam" x1="0" y1="0" x2="0" y2="1">
{% for stop in error_seam_stops %}
      <stop offset="{{ stop.offset }}" stop-color="{{ stop.color }}" stop-opacity="{{ stop.opacity }}"/>
{% endfor %}
    </linearGradient>
    <filter id="{{ uid }}-lift" x="-4%" y="-12%" width="108%" height="130%">
      <feDropShadow dx="0" dy="0.5" stdDeviation="0.6" flood-color="{{ error_shadow_color }}" flood-opacity="0.32"/>
    </filter>
    <clipPath id="{{ uid }}-bars-clip">
      <rect x="{{ error_rects.bars_clip.x }}" y="{{ error_rects.bars_clip.y }}"
            width="{{ error_rects.bars_clip.w }}" height="{{ error_rects.bars_clip.h }}"/>
    </clipPath>
  </defs>
  <style>
    {{ font_faces | safe }}
    .{{ uid }}-bars{animation:{{ uid }}-bar-shift 4.2s ease-in-out infinite;will-change:filter}
    .{{ uid }}-scan{animation:{{ uid }}-scan 2.6s linear infinite;will-change:transform}
    .{{ uid }}-flick1{animation:{{ uid }}-flick 5.7s ease-in-out infinite}
    .{{ uid }}-flick2{animation:{{ uid }}-flick 4.3s ease-in-out infinite 1.2s}
    .{{ uid }}-glitch{animation:{{ uid }}-glitch 3.8s steps(1,end) infinite;will-change:transform}
    .{{ uid }}-err{animation:{{ uid }}-err-pulse 2.1s ease-in-out infinite;will-change:filter}
    @keyframes {{ uid }}-bar-shift{0%,100%{filter:saturate(1) hue-rotate(0deg)}45%{filter:saturate(1.18) hue-rotate(-3deg)}55%{filter:saturate(.92) hue-rotate(2deg)}}
    @keyframes {{ uid }}-scan{0%{transform:translateY(-2px)}100%{transform:translateY(30px)}}
    @keyframes {{ uid }}-flick{0%,92%,100%{opacity:.18}93%{opacity:0}94%{opacity:.42}95%{opacity:.05}}
    @keyframes {{ uid }}-glitch{0%,93%,100%{transform:translate(0,0)}94%{transform:translate(-1px,0)}95%{transform:translate(1px,0)}96%{transform:translate(0,0)}}
    @keyframes {{ uid }}-err-pulse{0%,100%{filter:drop-shadow(0 0 0 {{ error_pulse_color }})}50%{filter:drop-shadow(0 0 1.4px {{ error_pulse_color }})}}
    @media(prefers-reduced-motion:reduce){.{{ uid }}-bars,.{{ uid }}-scan,.{{ uid }}-flick1,.{{ uid }}-flick2,.{{ uid }}-glitch,.{{ uid }}-err{animation:none!important}}
    @media(forced-colors:active){text{fill:CanvasText!important}rect{stroke:CanvasText}}
  </style>

  {# ============ FRAME ============ #}
  <rect width="{{ error_rects.frame.w }}" height="{{ error_rects.frame.h }}" fill="url(#{{ uid }}-rim)" filter="url(#{{ uid }}-lift)"/>
  <rect x="{{ error_rects.inner_stroke.x }}" y="{{ error_rects.inner_stroke.y }}"
        width="{{ error_rects.inner_stroke.w }}" height="{{ error_rects.inner_stroke.h }}"
        fill="none" stroke="{{ error_inner_stroke }}" stroke-width="0.7"/>
  <rect x="{{ error_rects.body.x }}" y="{{ error_rects.body.y }}"
        width="{{ error_rects.body.w }}" height="{{ error_rects.body.h }}" fill="{{ error_body_fill }}"/>
  <rect x="{{ error_rects.top_highlight.x }}" y="{{ error_rects.top_highlight.y }}"
        width="{{ error_rects.top_highlight.w }}" height="{{ error_rects.top_highlight.h }}"
        fill="{{ error_top_highlight }}" opacity="0.20"/>
  <rect x="{{ error_rects.bottom_shadow.x }}" y="{{ error_rects.bottom_shadow.y }}"
        width="{{ error_rects.bottom_shadow.w }}" height="{{ error_rects.bottom_shadow.h }}"
        fill="{{ error_bottom_shadow }}" opacity="0.55"/>

  {# ============ LABEL SLAB - 7 SMPTE PRIMARIES per RP 219 ============ #}
  <g class="{{ uid }}-bars {{ uid }}-glitch" clip-path="url(#{{ uid }}-bars-clip)">
{% for bar in error_bar_colors %}
    <rect x="{{ bar.x }}" y="{{ bar.y }}" width="{{ bar.width }}" height="{{ bar.height }}" fill="{{ bar.color }}"/>
{% endfor %}
  </g>

  {# scanline + horizontal noise (clipped to bars) #}
  <g clip-path="url(#{{ uid }}-bars-clip)">
    <rect class="{{ uid }}-flick1" x="{{ error_rects.noise_1.x }}" y="{{ error_rects.noise_1.y }}"
          width="{{ error_rects.noise_1.w }}" height="{{ error_rects.noise_1.h }}" fill="{{ error_noise_fill }}"/>
    <rect class="{{ uid }}-flick2" x="{{ error_rects.noise_2.x }}" y="{{ error_rects.noise_2.y }}"
          width="{{ error_rects.noise_2.w }}" height="{{ error_rects.noise_2.h }}" fill="{{ error_noise_fill }}"/>
    <rect class="{{ uid }}-scan" x="{{ error_rects.scan.x }}" y="{{ error_rects.scan.y }}"
          width="{{ error_rects.scan.w }}" height="{{ error_rects.scan.h }}" fill="{{ error_noise_fill }}" opacity="0.22"/>
  </g>

  {# black NO SIGNAL banner (the meme) #}
  <rect x="{{ error_rects.banner.x }}" y="{{ error_rects.banner.y }}"
        width="{{ error_rects.banner.w }}" height="{{ error_rects.banner.h }}" fill="{{ error_banner_fill }}"
        stroke="{{ error_banner_stroke }}" stroke-opacity="0.22" stroke-width="0.5"/>
  <text x="{{ error_texts.signal.x }}" y="{{ error_texts.signal.y }}" text-anchor="middle"
        font-family="'Orbitron',sans-serif" font-size="8.5" font-weight="900"
        fill="{{ error_signal_text }}" letter-spacing="0.18em">NO SIGNAL</text>

  {# ============ REFINED SEAM ============ #}
  <rect x="{{ error_rects.seam.x }}" y="{{ error_rects.seam.y }}"
        width="{{ error_rects.seam.w }}" height="{{ error_rects.seam.h }}" fill="url(#{{ uid }}-seam)"/>
  <rect x="{{ error_rects.seam_gap.x }}" y="{{ error_rects.seam_gap.y }}"
        width="{{ error_rects.seam_gap.w }}" height="{{ error_rects.seam_gap.h }}" fill="{{ error_seam_gap_fill }}"/>

  {# ============ VALUE SLAB - ERROR CODE ============ #}
  <rect x="{{ error_rects.value.x }}" y="{{ error_rects.value.y }}"
        width="{{ error_rects.value.w }}" height="{{ error_rects.value.h }}" fill="url(#{{ uid }}-vb)"/>
  <text class="{{ uid }}-err" x="{{ error_texts.value.x }}" y="{{ error_texts.value.y }}" text-anchor="middle"
        font-family="'Chakra Petch',sans-serif" font-size="12" font-weight="700"
        fill="{{ error_value_text }}" letter-spacing="0.06em">ERR_{{ status_code }}</text>
</svg>
