{# Cellular stats card v4b — compact 530×233 with three vertical zones.

   Replaces the v0.3.0-Round-9 5-slot vertical stack (header / hero /
   secondary / heatmap / language) with three zones:

     1. HEADER BAND (y=0..39) — gradient-filled rect with username + bio inline,
        HYPERWEAVE brand stamp top-right, accent hairline at y=39
     2. METRIC STRIP (y≈73) — single-row hierarchy: hero (mvh, 26px white),
        medium (mvm, 20px gray), small (mvs, 15px gray), streak (mvg, 15px
        green). Five values: STARS · COMMITS · PRS · CONTRIB · STREAK
     3. HEATMAP + LEGEND + LANGUAGE (y=101..221) — year label + 5-tier legend
        column at top, 7×42 square heatmap below, 5-segment language bar
        with inline labels at the bottom

   The card outline (rounded rect at info_accent @ 10% alpha) frames the
   composition. Heatmap level 0..4 maps to area_tiers[4..0] (darkest →
   brightest); active levels carry b1/b2/b3/b4 phase-staggered breathe. #}

{% set _surface = surface_0 | default('var(--dna-surface)') %}
{% set area_tiers = cellular_palette.primary.area_tiers %}
{% set _accent = stats_info_accent %}

{# Card clip — masks rendering to the rounded rect so the breathing heatmap
   and language bar can't bleed past the corners. #}
<g clip-path="url(#{{ uid }}-card-clip)">

{# Void ground — full canvas. #}
<rect width="{{ stats_layout.width }}" height="{{ stats_layout.height }}" fill="{{ _surface }}"/>

{# ZONE 1: HEADER BAND (y=0..39) — gradient fill, username + bio inline at
   y=24, HYPERWEAVE brand stamp top-right, accent hairline at y=39. #}
<rect x="{{ stats_layout.rects.cellular_header_band.x }}" y="{{ stats_layout.rects.cellular_header_band.y }}"
      width="{{ stats_layout.rects.cellular_header_band.w }}" height="{{ stats_layout.rects.cellular_header_band.h }}"
      fill="url(#{{ uid }}-top-grad)"/>
<line x1="{{ stats_layout.lines.cellular_header_rule.x1 }}" y1="{{ stats_layout.lines.cellular_header_rule.y1 }}"
      x2="{{ stats_layout.lines.cellular_header_rule.x2 }}" y2="{{ stats_layout.lines.cellular_header_rule.y2 }}"
      stroke="{{ _accent }}" stroke-opacity="0.10" stroke-width="1"/>
<text x="{{ stats_layout.texts.cellular_identity.x }}" y="{{ stats_layout.texts.cellular_identity.y }}" class="{{ uid }}-username"
  {%- if identity_text_length %} textLength="{{ identity_text_length }}" lengthAdjust="spacingAndGlyphs"{%- endif %}>{{ stats_username | upper | xml_escape }}</text>
{% if stats_bio or stats_repo_label %}
{# v0.3.9 algorithmic: identity_x + bio_x come from the cellular paradigm's
   stats config (cellular.yaml: identity_x=20, bio_x=110). identity_zone_width
   is derived in compose/resolvers/stats.py as bio_x - identity_x - padding.
   bio_text_length is emitted by the same resolver when the bio's natural
   width would visually collide with the right-edge HYPERWEAVE branding —
   prevents karpathy-length bios from bleeding into the branding zone. #}
<text x="{{ stats_layout.texts.cellular_bio.x }}" y="{{ stats_layout.texts.cellular_bio.y }}" class="{{ uid }}-bio"
  {%- if bio_text_length %} textLength="{{ bio_text_length }}" lengthAdjust="spacingAndGlyphs"{%- endif %}>{% if stats_repo_label %}{{ stats_repo_label | xml_escape }}{% endif %}{% if stats_repo_label and stats_bio %} · {% endif %}{% if stats_bio %}{{ stats_bio | xml_escape }}{% endif %}</text>
{% endif %}
{# v0.3.9 Bug A + Bug #5: HYPERWEAVE branding lives in the footer band
   on the same baseline as the language labels (y=221). Sharing the
   baseline produces visual alignment between the right-anchored
   HYPERWEAVE text and the left-packed language pills, both rendering
   small monospace text in the same footer band y=216-221. #}
<text x="{{ stats_layout.texts.cellular_brand.x }}" y="{{ stats_layout.texts.cellular_brand.y }}" class="{{ uid }}-brand" text-anchor="{{ stats_layout.texts.cellular_brand.anchor }}">HYPERWEAVE</text>

{# ZONE 2: METRIC STRIP (y≈73). v0.3.9 Bug B: x positions computed
   algorithmically in compose/resolvers/stats.py by measuring each value
   at its CSS class font (.mvh/.mvm/.mvs/.mvg via Chakra Petch) and each
   label at .mlb (JBM 6.5/500/0.22em). Left four metrics pack left-to-right
   from x=20 with inter-slot gap; STREAK right-anchored so a "1000d" value
   floats left of the STREAK label rather than overflowing into it. The
   prior hardcoded x positions broke for value widths beyond ~3 chars. #}
{% for slot in metric_layouts %}
<text x="{{ slot.value_x }}" y="{{ metric_y }}" class="{{ uid }}-{{ slot.css_value }}">{{ slot.value_display | default('--') | xml_escape }}</text>
<text x="{{ slot.label_x }}" y="{{ metric_y }}" class="{{ uid }}-mlb">{{ slot.label_text | xml_escape }}</text>
{% endfor %}

{# ZONE 3a: YEAR LABEL + LEGEND COLUMN (y=101..108).
   Year (e.g. "2026") at left x=20; 5-tier legend rects at right side
   showing the heatmap palette in tier order (empty→brightest). Cell positions
   match prototype literals: x=467/476/485/494/503. #}
{% if heatmap_cells %}
<text x="{{ stats_layout.texts.cellular_year.x }}" y="{{ stats_layout.texts.cellular_year.y }}" class="{{ uid }}-cyr">{{ stats_heatmap_year }}</text>
{% for cell in heatmap_legend_cells %}
<rect x="{{ cell.x }}" y="{{ cell.y }}" width="{{ cell.w }}" height="{{ cell.h }}" rx="{{ cell.rx }}" fill="{{ cell.fill }}"/>
{% endfor %}

{# ZONE 3b: HEATMAP (y=114..198) — 7 rows × 42 cols of square 11.080px cells
   with 1.2px gap (stride 12.28). Cells start at x=20 and end at
   x=20 + 41*12.28 + 11.08 = 514.56. Height fills 84.76px (7×11.080 +
   6×1.2). Active cells (level >= 1) carry b1/b2/b3/b4 phase-staggered
   breathe; level-0 cells stay static at the darkest tier (area_tiers[4]). #}
<g data-hw-zone="heatmap">
  {% for cell in heatmap_cells %}
    <rect x="{{ cell.x }}" y="{{ cell.y }}" width="{{ cell.w }}" height="{{ cell.h }}" rx="{{ cell.rx }}" fill="{{ cell.fill }}"{% if cell.css_class %} class="{{ cell.css_class }}"{% endif %}/>
  {% endfor %}
</g>
{% endif %}

{# ZONE 3c: LANGUAGE FOOTER — inline swatch + label pairs at y=217.

   v0.3.0 polish replaces the proportional bar with a single row of
   "swatch label pct%" entries spread across the heatmap's content zone.
   The bar communicated nothing the swatches don't already convey (segment
   colors equal swatch colors), and squeezed labels into ~132px causing
   right-edge overflow on long names like "Jupyter Notebook".

   Layout positions are computed by the resolver via measure_text against
   JBM 7px so each label's pixel width is known precisely. Languages are
   pre-sorted by descending pct; if all four don't fit in the available
   zone, the resolver drops from the end (lowest pct first). Full canonical
   names are preserved — no aliasing, no truncation.

   Swatches use the same area_tiers cycle the bar segments used so the
   chromatic identity carries through the redesign unchanged. The .lt
   class (mid_accent at opacity 0.6) keeps labels quiet — the heatmap
   above remains the visual focus of the bottom half of the card. #}
<g data-hw-zone="languages">
  {% if proportional_bar %}
  {% for entry in language_layout | default([]) %}
  <rect x="{{ entry.swatch_x }}" y="{{ entry.swatch_y }}" width="{{ entry.swatch_w }}" height="{{ entry.swatch_h }}" rx="{{ entry.swatch_rx }}" fill="{{ entry.swatch_color }}"/>
  <text x="{{ entry.label_x }}" y="{{ entry.label_y }}" class="{{ uid }}-lt">{{ entry.label_text | xml_escape }}</text>
  {% endfor %}
  {% endif %}
</g>

</g>{# end card-clip #}

{# Card outline — drawn OUTSIDE the clip so the rounded rect stroke isn't
   itself clipped. info_accent at 10% alpha frames the composition without
   competing with the heatmap. #}
<rect x="{{ stats_layout.cellular_outer_rect.x }}" y="{{ stats_layout.cellular_outer_rect.y }}"
      width="{{ stats_layout.cellular_outer_rect.w }}" height="{{ stats_layout.cellular_outer_rect.h }}"
      rx="{{ stats_layout.cellular_outer_rect.rx }}" fill="none" stroke="{{ _accent }}" stroke-opacity="0.10" stroke-width="1"/>
