{# HyperWeave Horizontal Marquee — paradigm-driven scrolling band.

   v0.3.12: scroll-item layout is dispatched by the CONFIG VALUE item_layout
   (ribbon | module), never a `paradigm == ...` branch — chrome + cellular
   share item-ribbon.j2, brutalist uses item-module.j2. Category grouping,
   per-cell state colors (via the state-signal-cascade bridge), and role-based
   hero are all computed in the resolver from the existing ?data= tokens.

   Scroll items carry ABSOLUTE x positions (and, for module layout, divider x)
   computed by the resolver from font metrics, so text never overlaps
   regardless of content length. Set-A and Set-B duplicate the same items;
   Set-B is offset by scroll_distance so the SMIL animateTransform produces a
   seamless loop. Per-paradigm DECORATIVE liveness (chrome diamond+LIVE,
   brutalist strobe-cube cap, cellular wave-rail) lives in {paradigm}-content/
   overlay/defs.j2 with its OWN @keyframes — never the state cascade.

   Profile-dispatched: paradigm context var routes
     {paradigm}-defs.j2     — paradigm-specific gradients/filters/liveness defs
     {paradigm}-content.j2  — frame chrome BELOW the scroll text
     {paradigm}-overlay.j2  — frame chrome + liveness ABOVE the scroll text

   Extends document.svg.j2. Context: compose/resolver.py:_resolve_horizontal.
#}
{% extends "document.svg.j2" %}

{% block defs %}
{% set mw = width | default(800) %}
{% set mh = height | default(40) %}
  {# Scroll-track clip — paradigm-inset rect that excludes the perimeter
     zones (chrome bezel, accent bar, hairlines, brutalist end-caps). #}
  <clipPath id="{{ uid }}-scroll-clip">
    <rect x="{{ clip_x | default(0) }}" y="{{ clip_y | default(0) }}"
          width="{{ clip_w | default(mw) }}" height="{{ clip_h | default(mh) }}"
          rx="{{ clip_rx | default(0) }}"/>
  </clipPath>
  {# State-signal cascade — binds data-hw-status → var(--hw-state-value) from
     the genome's state_* hexes so stateful (activity) cells tint their value.
     Wrapped in <style> because the partial emits bare CSS rules. #}
  <style>{% include "partials/state-signal-cascade.j2" %}</style>
{% include "frames/marquee-horizontal/" ~ (paradigm | default("default")) ~ "-defs.j2" %}
{% endblock %}

{% block content %}
{% set mw = width | default(800) %}
{% set mh = height | default(40) %}
{% set sd = scroll_distance | default(1000) %}
{% set dur = scroll_dur | default(11.09) %}
{% set fs = font_size | default(13) %}
{% set lfs = label_font_size | default(fs) %}
{% set fw = font_weight | default('') %}
{% set ls = letter_spacing | default('.5') %}
{% set ff = scroll_font_family | default('var(--dna-font-mono, ui-monospace, monospace)') %}
{% set sk = separator_kind | default('glyph') %}
{% set ssz = separator_size | default(6) %}
{% set sg = separator_glyph | default('■') %}
{# Separator/divider color cascades through --dna-signal so each variant's
   accent flows naturally into the bullet / module divider. #}
{% set sc = separator_fill | default('var(--dna-signal, var(--dna-border))') %}
{% set tfid = text_fill_gradient_id | default('') %}
{# Ribbon vertical centering: dominant-baseline=central + y=mh/2. #}
{% set baseline_y = marquee_baseline_y %}
{% set sep_rect_y = separator_rect_y %}

{# Frame chrome BACKGROUND — paradigm-dispatched. Renders the layers BELOW the
   scroll text (envelope+well for chrome, flat slab + engineering grid for
   brutalist, void ground for cellular). PERIMETER + liveness layers render
   AFTER the scroll text via {paradigm}-overlay.j2. #}
{% include "frames/marquee-horizontal/" ~ (paradigm | default("default")) ~ "-content.j2" %}

{# Scrolling track — clipped; SMIL translate from 0 to -scroll_distance over
   scroll_dur seconds, infinite loop. The Set-A/Set-B groups are rendered by
   the item-layout partial selected by item_layout (ribbon | module) — two
   paradigms may resolve to the same partial; the layout is a data value, not
   a paradigm-slug branch (Invariant 12). #}
<g clip-path="url(#{{ uid }}-scroll-clip)">
  <g data-hw-zone="scroll-track">
    <animateTransform attributeName="transform" type="translate"
        from="0 0" to="-{{ sd }} 0"
        dur="{{ dur }}s" repeatCount="indefinite"/>
{% include "frames/marquee-horizontal/item-" ~ (item_layout | default("ribbon")) ~ ".j2" %}
  </g>
</g>

{# Frame chrome + liveness OVERLAY — paradigm-dispatched, ABOVE the scroll
   text so passing text slides UNDER the perimeter and the liveness markup. #}
{% include "frames/marquee-horizontal/" ~ (paradigm | default("default")) ~ "-overlay.j2" ignore missing %}
{% endblock %}
