Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< section >
2025-08-26 20:00:07 -07:00
{% set step_index = 5 %}{% set step_total = 5 %}
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< h3 > Step 5: Build< / h3 >
< div class = "two-col two-col-left-rail" >
< aside class = "card-preview" >
< a href = "https://scryfall.com/search?q={{ commander|urlencode }}" target = "_blank" rel = "noopener" >
Web UI polish: thumbnail-hover preview, white thumbnail selection, Themes bullet list; global Scryfall image retry (thumbs+previews) with fallbacks and cache-bust; standardized data-card-name. Deck Summary alignment overhaul (count//name/owned grid, tabular numerals, inset highlight, tooltips, starts under header). Added diagnostics (health + logs pages, error pages, request-id propagation), global HTMX error toasts, and docs updates. Update DOCKER guide and add run-web scripts. Update CHANGELOG and release notes template.
2025-08-27 11:21:46 -07:00
< img src = "https://api.scryfall.com/cards/named?fuzzy={{ commander|urlencode }}&format=image&version=normal" alt = "{{ commander }} card image" data-card-name = "{{ commander }}" / >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / a >
{% if status and status.startswith('Build complete') %}
< div style = "margin-top:.75rem; display:flex; gap:.35rem; flex-wrap:wrap;" >
{% if csv_path %}
< form action = "/files" method = "get" target = "_blank" style = "display:inline; margin:0;" >
< input type = "hidden" name = "path" value = "{{ csv_path }}" / >
< button type = "submit" > Download CSV< / button >
< / form >
{% endif %}
{% if txt_path %}
< form action = "/files" method = "get" target = "_blank" style = "display:inline; margin:0;" >
< input type = "hidden" name = "path" value = "{{ txt_path }}" / >
< button type = "submit" > Download TXT< / button >
< / form >
{% endif %}
< / div >
{% endif %}
< / aside >
2025-08-26 20:00:07 -07:00
< div class = "grow" data-skeleton >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< div hx-get = "/build/banner?step=Build&i=5&n=5" hx-trigger = "load" > < / div >
2025-08-26 20:00:07 -07:00
{% include "build/_stage_navigator.html" %}
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< p > Commander: < strong > {{ commander }}< / strong > < / p >
< p > Tags: {{ tags|default([])|join(', ') }}< / p >
2025-08-26 16:25:34 -07:00
< div style = "margin:.35rem 0; color: var(--muted); display:flex; gap:.5rem; align-items:center; flex-wrap:wrap;" >
< span > Owned-only: < strong > {{ 'On' if owned_only else 'Off' }}< / strong > < / span >
< div style = "display:flex;align-items:center;gap:1rem;" >
< button type = "button" hx-get = "/build/step4" hx-target = "#wizard" hx-swap = "innerHTML" style = "background:#374151; color:#e5e7eb; border:none; border-radius:6px; padding:.25rem .5rem; cursor:pointer; font-size:12px;" title = "Change owned settings in Review" > Edit in Review< / button >
< div > Prefer-owned: < strong > {{ 'On' if prefer_owned else 'Off' }}< / strong > < / div >
< / div >
2025-08-26 20:00:07 -07:00
< span style = "margin-left:auto;" > < a href = "/owned" target = "_blank" rel = "noopener" class = "btn" > Manage Owned Library< / a > < / span >
2025-08-26 16:25:34 -07:00
< / div >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< p > Bracket: {{ bracket }}< / p >
2025-08-26 20:00:07 -07:00
< div style = "display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; margin:.25rem 0 .5rem 0;" >
{% if i and n %}
< span class = "chip" > < span class = "dot" > < / span > Stage {{ i }}/{{ n }}< / span >
{% endif %}
{% set deck_count = (total_cards if total_cards is not none else 0) %}
< span class = "chip" > < span class = "dot" style = "background: var(--green-main);" > < / span > Deck {{ deck_count }}/100< / span >
{% if added_total is not none %}
< span class = "chip" > < span class = "dot" style = "background: var(--blue-main);" > < / span > Added {{ added_total }}< / span >
{% endif %}
< / div >
{% set pct = ((deck_count / 100.0) * 100.0) if deck_count else 0 %}
{% set pct_clamped = (pct if pct < = 100 else 100) %}
{% set pct_int = pct_clamped|int %}
< div class = "progress{% if added_cards is defined and added_cards is not none and (added_cards|length == 0) and (status and not status.startswith('Build complete')) %} flash{% endif %}" aria-label = "Deck progress" title = "{{ deck_count }} of 100 cards" style = "margin:.25rem 0 1rem 0;" data-pct = "{{ pct_int }}" >
< div class = "bar" > < / div >
< / div >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
{% if status %}
< div style = "margin-top:1rem;" >
< strong > Status:< / strong > {{ status }}{% if stage_label %} — < em > {{ stage_label }}< / em > {% endif %}
< / div >
{% endif %}
2025-08-26 20:00:07 -07:00
<!-- Filters toolbar -->
< div class = "cards-toolbar" >
< input type = "text" name = "filter_query" placeholder = "Filter by name, role, or tag" data-pref = "cards:filter_q" / >
< select name = "filter_owned" data-pref = "cards:owned" >
< option value = "all" > All< / option >
< option value = "owned" > Owned< / option >
< option value = "not" > Not owned< / option >
< / select >
< label style = "display:flex;align-items:center;gap:.35rem;" >
< input type = "checkbox" name = "show_reasons" data-pref = "cards:show_reasons" checked / > Show reasons
< / label >
< label style = "display:flex;align-items:center;gap:.35rem;" >
< input type = "checkbox" name = "collapse_groups" data-pref = "cards:collapse" / > Collapse groups
< / label >
< select name = "filter_sort" data-pref = "cards:sort" aria-label = "Sort" >
< option value = "az" > A– Z< / option >
< option value = "owned" > Owned first< / option >
< option value = "gc" > Game-changers first< / option >
< / select >
< span class = "sep" > < / span >
< span class = "hint" > Visible: < strong data-results > 0< / strong > < / span >
< span class = "sep" > < / span >
< div class = "chips-inline" >
< span class = "chip" data-chip-owned = "all" > All< / span >
< span class = "chip" data-chip-owned = "owned" > Owned< / span >
< span class = "chip" data-chip-owned = "not" > Not owned< / span >
< span class = "chip" data-chip-clear > Clear< / span >
< / div >
< / div >
<!-- Sticky build controls on mobile -->
< div class = "build-controls" style = "position:sticky; top:0; z-index:5; background:linear-gradient(180deg, rgba(15,17,21,.95), rgba(15,17,21,.85)); border:1px solid var(--border); border-radius:10px; padding:.5rem; margin-top:1rem; display:flex; gap:.5rem; flex-wrap:wrap; align-items:center;" >
< form hx-post = "/build/step5/start" hx-target = "#wizard" hx-swap = "innerHTML" style = "display:inline; margin-right:.5rem; display:flex; align-items:center; gap:.5rem;" onsubmit = "try{ toast('Starting build…'); }catch(_){}" >
2025-08-26 16:25:34 -07:00
< input type = "hidden" name = "show_skipped" value = "{{ '1' if show_skipped else '0' }}" / >
2025-08-26 20:00:07 -07:00
< button type = "submit" class = "btn-continue" data-action = "continue" > Start Build< / button >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / form >
2025-08-26 20:00:07 -07:00
< form hx-post = "/build/step5/continue" hx-target = "#wizard" hx-swap = "innerHTML" style = "display:inline; display:flex; align-items:center; gap:.5rem;" onsubmit = "try{ toast('Continuing…'); }catch(_){}" >
2025-08-26 16:25:34 -07:00
< input type = "hidden" name = "show_skipped" value = "{{ '1' if show_skipped else '0' }}" / >
2025-08-26 20:00:07 -07:00
< button type = "submit" class = "btn-continue" data-action = "continue" { % if status and status . startswith ( ' Build complete ' ) % } disabled { % endif % } > Continue< / button >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / form >
2025-08-26 20:00:07 -07:00
< form hx-post = "/build/step5/rerun" hx-target = "#wizard" hx-swap = "innerHTML" style = "display:inline; display:flex; align-items:center; gap:.5rem;" onsubmit = "try{ toast('Rerunning stage…'); }catch(_){}" >
2025-08-26 16:25:34 -07:00
< input type = "hidden" name = "show_skipped" value = "{{ '1' if show_skipped else '0' }}" / >
2025-08-26 20:00:07 -07:00
< button type = "submit" class = "btn-rerun" data-action = "rerun" { % if status and status . startswith ( ' Build complete ' ) % } disabled { % endif % } > Rerun Stage< / button >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / form >
2025-08-26 16:25:34 -07:00
< label class = "muted" style = "display:flex; align-items:center; gap:.35rem; margin-left: .5rem;" >
2025-08-26 20:00:07 -07:00
< input type = "checkbox" name = "__toggle_show_skipped" data-pref = "build:show_skipped" { % if show_skipped % } checked { % endif % }
2025-08-26 16:25:34 -07:00
onchange="const val=this.checked?'1':'0'; for(const f of this.closest('section').querySelectorAll('form')){ const h=f.querySelector('input[name=show_skipped]'); if(h) h.value=val; }" />
Show skipped stages
< / label >
2025-08-26 20:00:07 -07:00
< button type = "button" class = "btn-back" data-action = "back" hx-get = "/build/step4" hx-target = "#wizard" hx-swap = "innerHTML" > Back< / button >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / div >
2025-08-26 16:25:34 -07:00
{% if added_cards is not none %}
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< h4 style = "margin-top:1rem;" > Cards added this stage< / h4 >
2025-08-26 16:25:34 -07:00
{% if skipped and (not added_cards or added_cards|length == 0) %}
< div class = "muted" style = "margin:.25rem 0 .5rem 0;" > No cards added in this stage.< / div >
{% endif %}
< div class = "muted" style = "font-size:12px; margin:.15rem 0 .4rem 0; display:flex; gap:.75rem; align-items:center; flex-wrap:wrap;" >
< span > < span style = "display:inline-block; border:1px solid var(--border); background:rgba(17,24,39,.9); color:#e5e7eb; border-radius:12px; font-size:12px; line-height:18px; height:18px; min-width:18px; padding:0 6px; text-align:center;" > ✔< / span > Owned< / span >
< span > < span style = "display:inline-block; border:1px solid var(--border); background:rgba(17,24,39,.9); color:#e5e7eb; border-radius:12px; font-size:12px; line-height:18px; height:18px; min-width:18px; padding:0 6px; text-align:center;" > ✖< / span > Not owned< / span >
< / div >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
{% if stage_label and stage_label.startswith('Creatures') %}
{% set groups = added_cards|groupby('sub_role') %}
{% for g in groups %}
{% set role = g.grouper %}
{% if role %}
{% set heading = 'Theme: ' + role.title() %}
{% else %}
{% set heading = 'Additional Picks' %}
{% endif %}
2025-08-26 20:00:07 -07:00
< div class = "group" data-group-key = "{{ (role or 'other')|lower|replace(' ', '-') }}" >
< div class = "group-header" >
< h5 style = "margin:.5rem 0 .25rem 0;" > {{ heading }}< / h5 >
< span class = "count" > (< span data-count > {{ g.list|length }}< / span > )< / span >
< button type = "button" class = "toggle" title = "Collapse/Expand" > Toggle< / button >
< / div >
< div class = "card-grid group-grid" data-skeleton >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
{% for c in g.list %}
2025-08-26 16:25:34 -07:00
{% set owned = (owned_set is defined and c.name and (c.name|lower in owned_set)) %}
2025-08-26 20:00:07 -07:00
< div class = "card-tile{% if game_changers and (c.name in game_changers) %} game-changer{% endif %}" data-card-name = "{{ c.name }}" data-role = "{{ c.role or c.sub_role or '' }}" data-tags = "{{ (c.tags|join(', ')) if c.tags else '' }}" data-owned = "{{ '1' if owned else '0' }}" >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< a href = "https://scryfall.com/search?q={{ c.name|urlencode }}" target = "_blank" rel = "noopener" >
Web UI polish: thumbnail-hover preview, white thumbnail selection, Themes bullet list; global Scryfall image retry (thumbs+previews) with fallbacks and cache-bust; standardized data-card-name. Deck Summary alignment overhaul (count//name/owned grid, tabular numerals, inset highlight, tooltips, starts under header). Added diagnostics (health + logs pages, error pages, request-id propagation), global HTMX error toasts, and docs updates. Update DOCKER guide and add run-web scripts. Update CHANGELOG and release notes template.
2025-08-27 11:21:46 -07:00
< img src = "https://api.scryfall.com/cards/named?fuzzy={{ c.name|urlencode }}&format=image&version=normal" alt = "{{ c.name }} image" width = "160" data-card-name = "{{ c.name }}" / >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / a >
2025-08-26 16:25:34 -07:00
< div class = "owned-badge" title = "{{ 'Owned' if owned else 'Not owned' }}" aria-label = "{{ 'Owned' if owned else 'Not owned' }}" > {% if owned %}✔{% else %}✖{% endif %}< / div >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< div class = "name" > {{ c.name }}{% if c.count and c.count > 1 %} × {{ c.count }}{% endif %}< / div >
2025-08-26 20:00:07 -07:00
{% if c.reason %}
< div style = "display:flex; justify-content:center; margin-top:.25rem;" >
< button type = "button" class = "btn-why" aria-expanded = "false" > Why?< / button >
< / div >
< div class = "reason" role = "region" aria-label = "Reason" > {{ c.reason }}< / div >
{% endif %}
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / div >
{% endfor %}
2025-08-26 20:00:07 -07:00
< / div >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / div >
{% endfor %}
{% else %}
2025-08-26 20:00:07 -07:00
< div class = "card-grid" data-skeleton >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
{% for c in added_cards %}
2025-08-26 16:25:34 -07:00
{% set owned = (owned_set is defined and c.name and (c.name|lower in owned_set)) %}
2025-08-26 20:00:07 -07:00
< div class = "card-tile{% if game_changers and (c.name in game_changers) %} game-changer{% endif %}" data-card-name = "{{ c.name }}" data-role = "{{ c.role or c.sub_role or '' }}" data-tags = "{{ (c.tags|join(', ')) if c.tags else '' }}" data-owned = "{{ '1' if owned else '0' }}" >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< a href = "https://scryfall.com/search?q={{ c.name|urlencode }}" target = "_blank" rel = "noopener" >
Web UI polish: thumbnail-hover preview, white thumbnail selection, Themes bullet list; global Scryfall image retry (thumbs+previews) with fallbacks and cache-bust; standardized data-card-name. Deck Summary alignment overhaul (count//name/owned grid, tabular numerals, inset highlight, tooltips, starts under header). Added diagnostics (health + logs pages, error pages, request-id propagation), global HTMX error toasts, and docs updates. Update DOCKER guide and add run-web scripts. Update CHANGELOG and release notes template.
2025-08-27 11:21:46 -07:00
< img src = "https://api.scryfall.com/cards/named?fuzzy={{ c.name|urlencode }}&format=image&version=normal" alt = "{{ c.name }} image" width = "160" data-card-name = "{{ c.name }}" / >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / a >
2025-08-26 16:25:34 -07:00
< div class = "owned-badge" title = "{{ 'Owned' if owned else 'Not owned' }}" aria-label = "{{ 'Owned' if owned else 'Not owned' }}" > {% if owned %}✔{% else %}✖{% endif %}< / div >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< div class = "name" > {{ c.name }}{% if c.count and c.count > 1 %} × {{ c.count }}{% endif %}< / div >
2025-08-26 20:00:07 -07:00
{% if c.reason %}
< div style = "display:flex; justify-content:center; margin-top:.25rem;" >
< button type = "button" class = "btn-why" aria-expanded = "false" > Why?< / button >
< / div >
< div class = "reason" role = "region" aria-label = "Reason" > {{ c.reason }}< / div >
{% endif %}
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
< / div >
{% endfor %}
< / div >
{% endif %}
2025-08-26 20:00:07 -07:00
< div data-empty hidden role = "status" aria-live = "polite" class = "muted" style = "margin:.5rem 0 0;" >
No cards match your filters.
< / div >
Web UI: setup progress + logs folding, Finished Decks library, commander search UX (debounce, keyboard, highlights, color chips), ranking fixes (first-word priority, substring include), optional auto-select; setup start reliability (POST+GET), force runs, status with percent/ETA/timestamps; stepwise builder with added stage reporting and sidecar summaries; keyboard grid wrap-around; restrict commander search to eligible rows
2025-08-26 09:48:25 -07:00
{% endif %}
{% if show_logs and log %}
< details style = "margin-top:1rem;" >
< summary > Show logs< / summary >
< pre style = "margin-top:.5rem; white-space:pre-wrap; background:#0f1115; border:1px solid var(--border); padding:1rem; border-radius:8px; max-height:40vh; overflow:auto;" > {{ log }}< / pre >
< / details >
{% endif %}
<!-- controls now above -->
{% if status and status.startswith('Build complete') %}
{% if summary %}
{% include "partials/deck_summary.html" %}
{% endif %}
{% endif %}
< / div >
< / div >
< / section >