<!-- HTMX fragment: replaces #job-status-poll while still processing -->
{% set stage = job.progress_stage or 'analyzing' %}
{% set stages = ['analyzing', 'rendering', 'finalizing'] %}
{% set stage_labels = {'analyzing': 'Analyzing', 'rendering': 'Rendering', 'finalizing': 'Finalizing'} %}
<div hx-get="/plan-jobs/{{ job.job_id }}/status"
hx-trigger="every 3s"
hx-swap="outerHTML"
id="job-status-poll">
<style nonce="{{ csp_nonce }}">
.step-indicator { display: flex; align-items: center; justify-content: center; gap: 0; max-width: 400px; margin: 0 auto 16px; }
.step-dot {
width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--border, #333); background: transparent;
flex-shrink: 0; transition: all 0.3s;
}
.step-dot.completed { background: var(--accent, #2563eb); border-color: var(--accent, #2563eb); }
.step-dot.active { border-color: var(--accent, #2563eb); background: var(--accent, #2563eb); animation: step-pulse 1.5s ease-in-out infinite; }
.step-line { flex: 1; height: 2px; background: var(--border, #333); transition: background 0.3s; }
.step-line.completed { background: var(--accent, #2563eb); }
.step-label { font-size: 0.75rem; color: var(--text-muted, #999); margin-top: 6px; text-align: center; }
.step-label.active { color: var(--accent, #2563eb); font-weight: 600; }
.step-label.completed { color: var(--text-muted, #999); }
.step-group { display: flex; flex-direction: column; align-items: center; min-width: 70px; }
.step-detail { font-size: 0.85rem; color: var(--text-muted, #999); text-align: center; margin-top: 4px; }
@keyframes step-pulse {
0%, 100% { box-shadow: 0 0 0 0 rgba(37, 99, 235, 0.4); }
50% { box-shadow: 0 0 0 6px rgba(37, 99, 235, 0); }
}
</style>
<div class="step-indicator">
{% for s in stages %}
{% set idx = loop.index0 %}
{% set stage_idx = stages.index(stage) if stage in stages else 0 %}
<div class="step-group">
<div class="step-dot {% if idx < stage_idx %}completed{% elif idx == stage_idx %}active{% endif %}"></div>
<div class="step-label {% if idx < stage_idx %}completed{% elif idx == stage_idx %}active{% endif %}">{{ stage_labels[s] }}</div>
</div>
{% if not loop.last %}
<div class="step-line {% if idx < stage_idx %}completed{% endif %}"></div>
{% endif %}
{% endfor %}
</div>
<div class="step-detail">{{ job.progress_detail or 'Processing...' }}</div>
<div style="margin-top: var(--space-4);">
<button hx-post="/plan-jobs/{{ job.job_id }}/cancel"
hx-target="#job-status-poll"
hx-swap="outerHTML"
class="obsidian-btn obsidian-btn-outline">
Cancel Analysis
</button>
</div>
{% if elapsed_s is defined and elapsed_s is not none %}
<div style="font-size: 0.78rem; color: var(--text-muted, #666); text-align: center; margin-top: 8px;">
Elapsed: {{ elapsed_s // 60 }}m {{ elapsed_s % 60 }}s
{% if elapsed_s < 30 %}
{% set mode = job.analysis_mode or 'sample' %}
{% if mode == 'compliance' %}
· Typical: 30–60 sec
{% elif mode == 'full' %}
· Typical: 2–5 min
{% else %}
· Typical: 1–3 min
{% endif %}
{% endif %}
</div>
{% endif %}
</div>