kairix
{% if step is defined %}
{% for i in range(1, total_steps + 1) %} {% if i < step %} {% elif i == step %}{{ i }} {% else %}{{ i }} {% endif %} {% if not loop.last %}{% endif %} {% endfor %}
{% endif %} {% block content %}{% endblock %} {# Shared layout primitive (#488): card → content → banner slot → action row, on every screen. Async results (validation, scan, handshake, search, progress) render INTO this always-present fixed-size slot, which always sits ABOVE the action row — so no interactive element ever moves when a result arrives. #}
{%- block actions -%}{%- endblock -%}
{% block scripts %}{% endblock %}