<div class="modal modal-overlay" id="new-deck-modal" role="dialog" aria-modal="true" aria-labelledby="newDeckTitle">
  <div class="modal-backdrop"></div>
  <div class="modal-content">
    <div class="modal-header">
  <h3 id="newDeckTitle">Build a New Deck</h3>
    </div>
    {% if error %}
    <div class="error my-2" role="alert">{{ error }}</div>
    {% endif %}
  <form hx-post="/build/new" hx-target="#wizard" hx-swap="innerHTML" hx-on="htmx:afterRequest: (function(evt){ try{ if(evt && evt.detail && evt.detail.elt === this){ var m=this.closest('.modal'); if(m){ m.remove(); } } }catch(_){} }).call(this, event)" autocomplete="off">
      <fieldset>
        <legend>Basics</legend>
  <div class="basics-grid grid grid-cols-[2fr_1fr] gap-4 items-start">
          <div>
            <label class="form-label">
              <span class="muted">Optional name (used for file names)</span>
              <input type="text" name="name" placeholder="e.g., Inti Discard Tempo" autocomplete="off" autocapitalize="off" spellcheck="false" />
            </label>
            <label class="form-label">
              <span>Commander</span>
    <input type="text" name="commander" required placeholder="Type a commander name" value="{{ form.commander if form else '' }}" autofocus autocomplete="off" autocapitalize="off" spellcheck="false"
      role="combobox" aria-autocomplete="list" aria-controls="newdeck-candidates"
      hx-get="/build/new/candidates" hx-trigger="input changed delay:220ms, change" hx-target="#newdeck-candidates" hx-sync="this:replace" />
            </label>
            <small class="muted block mt-1">Start typing to see matches, then select one to load themes.</small>
            <div id="newdeck-candidates" class="muted text-xs min-h-[1.1em]"></div>
          </div>
          <div id="newdeck-commander-slot" class="muted max-w-[230px]">
            <em class="text-xs">Pick a commander to preview here.</em>
          </div>
        </div>
      </fieldset>
      <fieldset>
        <legend>Themes</legend>
        <div id="newdeck-tags-slot"{% if not tag_slot_html %} class="muted"{% endif %}>
          {% if tag_slot_html %}
            {{ tag_slot_html | safe }}
          {% else %}
            <em>Select a commander to see theme recommendations and choices.</em>
            <input type="hidden" name="primary_tag" />
            <input type="hidden" name="secondary_tag" />
            <input type="hidden" name="tertiary_tag" />
            <input type="hidden" name="tag_mode" value="AND" />
          {% endif %}
        </div>
  <div id="newdeck-multicopy-slot" class="muted mt-2 min-h-[1rem]"></div>
        {% if enable_custom_themes %}
        {% include "build/_new_deck_additional_themes.html" %}
        {% endif %}
        <div class="mt-2" id="newdeck-bracket-slot">
          <label><span style="display:inline-flex; align-items:center; gap:4px;">Bracket <span class="help-tip"><button type="button" class="help-tip-btn" data-tip="Restricts deck picks to the power-level rules for that bracket tier." data-tip-href="/help/bracket_compliance#bracket-tiers" aria-label="Bracket compliance help"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true" width="11" height="11"><circle cx="8" cy="8" r="6.5"/><line x1="8" y1="7" x2="8" y2="10.5" stroke-linecap="round"/><circle cx="8" cy="4.5" r="0.75" fill="currentColor" stroke="none"/></svg></button></span></span>
            <select name="bracket">
              {% for b in brackets %}
                {% if not gc_commander or b.level >= 3 %}
                <option value="{{ b.level }}" {% if (form and form.bracket and form.bracket == b.level) or (not form and b.level == 3) %}selected{% endif %}>Bracket {{ b.level }}: {{ b.name }}</option>
                {% endif %}
              {% endfor %}
            </select>
          </label>
        </div>
      </fieldset>
      <fieldset>
        <legend>Preferences</legend>
        <div class="text-left">
          <div class="mb-4 flex flex-col gap-3">
            <label for="pref-combos-chk" class="form-checkbox-label" title="When enabled, the builder will try to auto-complete missing combo partners near the end of the build (respecting owned-only and locks).">
              <input type="checkbox" name="prefer_combos" id="pref-combos-chk" value="1" {% if form and form.prefer_combos %}checked{% endif %} />
              <span>Prioritize combos</span>
            </label>
            <div id="pref-combos-config" class="mt-2 ml-6 p-2 border border-[var(--border)] rounded-lg hidden">
              <div class="flex gap-4 items-center flex-wrap">
                <label>
                  <span>How many combos?</span>
                  <input type="number" name="combo_count" min="0" max="10" step="1" value="{{ form.combo_count if form and form.combo_count is not none else 2 }}" class="w-24 ml-2" />
                </label>
                <div>
                  <div class="muted text-xs mb-1">Balance of early vs late-game</div>
                  <label class="inline-flex items-center gap-1 mr-2">
                    <input type="radio" name="combo_balance" value="early" {% if form and form.combo_balance == 'early' %}checked{% endif %} /> Early
                  </label>
                  <label class="inline-flex items-center gap-1 mr-2">
                    <input type="radio" name="combo_balance" value="late" {% if form and form.combo_balance == 'late' %}checked{% endif %} /> Late
                  </label>
                  <label class="inline-flex items-center gap-1">
                    <input type="radio" name="combo_balance" value="mix" {% if not form or (form and (not form.combo_balance or form.combo_balance == 'mix')) %}checked{% endif %} /> Mix
                  </label>
                </div>
              </div>
            </div>
            <label for="pref-mc-chk" class="form-checkbox-label" title="When enabled, include a Multi-Copy package for matching archetypes (e.g., tokens/tribal).">
              <input type="checkbox" name="enable_multicopy" id="pref-mc-chk" value="1" {% if form and form.enable_multicopy %}checked{% endif %} />
              <span>Enable Multi-Copy package <span class="help-tip"><button type="button" class="help-tip-btn" data-tip="Includes multiple copies of a single archetype card (tokens, slivers, etc.)." data-tip-href="/help/multi_copy" aria-label="Multi-Copy package help"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true" width="11" height="11"><circle cx="8" cy="8" r="6.5"/><line x1="8" y1="7" x2="8" y2="10.5" stroke-linecap="round"/><circle cx="8" cy="4.5" r="0.75" fill="currentColor" stroke="none"/></svg></button></span></span>
            </label>
            <div class="flex flex-col gap-2">
              <label for="use-owned-chk" class="form-checkbox-label" title="Limit the pool to cards you already own. Cards outside your owned library will be skipped.">
                <input type="checkbox" name="use_owned_only" id="use-owned-chk" value="1" {% if form and form.use_owned_only %}checked{% endif %} />
                <span>Use only owned cards <span class="help-tip"><button type="button" class="help-tip-btn" data-tip="Limits card picks to your uploaded owned-card library only." data-tip-href="/help/owned_cards#build-modes" aria-label="Owned cards help"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true" width="11" height="11"><circle cx="8" cy="8" r="6.5"/><line x1="8" y1="7" x2="8" y2="10.5" stroke-linecap="round"/><circle cx="8" cy="4.5" r="0.75" fill="currentColor" stroke="none"/></svg></button></span></span>
              </label>
              <label for="prefer-owned-chk" class="form-checkbox-label" title="Still allow unowned cards, but rank owned cards higher when choosing picks.">
                <input type="checkbox" name="prefer_owned" id="prefer-owned-chk" value="1" {% if form and form.prefer_owned %}checked{% endif %} />
                <span>Prefer owned cards (allow unowned fallback)</span>
              </label>
              <label for="swap-mdfc-chk" class="form-checkbox-label" title="When enabled, modal DFC lands will replace a matching basic land as they are added so land counts stay level without manual trims.">
                <input type="checkbox" name="swap_mdfc_basics" id="swap-mdfc-chk" value="1" {% if form and form.swap_mdfc_basics %}checked{% endif %} />
                <span>Swap basics for MDFC lands</span>
              </label>
              <label for="smart-lands-chk" class="form-checkbox-label" title="When enabled, the builder automatically adjusts the land count and mana-base profile based on your commander's speed and color complexity.">
                <input type="checkbox" name="enable_smart_lands" id="smart-lands-chk" value="1" {% if form and form.enable_smart_lands %}checked{% endif %} />
                <span>Smart Land Bases <span class="help-tip"><button type="button" class="help-tip-btn" data-tip="Auto-adjusts land count and mana profile based on commander speed and color complexity." data-tip-href="/help/land_bases#speed-categories-land-counts" aria-label="Smart Land Bases help"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true" width="11" height="11"><circle cx="8" cy="8" r="6.5"/><line x1="8" y1="7" x2="8" y2="10.5" stroke-linecap="round"/><circle cx="8" cy="4.5" r="0.75" fill="currentColor" stroke="none"/></svg></button></span></span>
              </label>
            </div>
          </div>
        </div>
      </fieldset>
      {% include "build/_new_deck_ideals.html" %}
      {% if allow_must_haves %}
      <fieldset>
        <legend>Include/Exclude Cards <span class="help-tip"><button type="button" class="help-tip-btn" data-tip="Force specific cards into or out of your deck before the build runs." data-tip-href="/help/include_exclude#adding-cards" aria-label="Include/Exclude help"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true" width="11" height="11"><circle cx="8" cy="8" r="6.5"/><line x1="8" y1="7" x2="8" y2="10.5" stroke-linecap="round"/><circle cx="8" cy="4.5" r="0.75" fill="currentColor" stroke="none"/></svg></button></span></legend>
        <div class="include-exclude-grid">
          <!-- Include Cards Column (Left, Green) -->
          <div>
            <label class="card-list-label">
              <span class="card-list-label-include">✓ Must Include Cards</span>
              <small class="muted block text-xs mt-1">Cards that must appear in your deck</small>
            </label>
            <textarea name="include_cards" id="include_cards_textarea" 
              placeholder="Lightning Bolt&#10;Counterspell&#10;Swords to Plowshares" 
              class="include-textarea"
              autocomplete="off" autocapitalize="off" spellcheck="false">{{ form.include_cards if form and form.include_cards else '' }}</textarea>
            <!-- Include Cards Chips Container -->
            <div id="include_chips_container" class="include-chips-container">
              <div id="include_chips" class="chips-inner"></div>
              <div class="chips-placeholder" id="include_chips_placeholder">Enter card names above to see them as removable tags</div>
            </div>
            <div class="card-list-controls">
              <label for="include_file_upload" class="btn btn-upload-include">
                📄 Upload .txt
              </label>
              <input type="file" id="include_file_upload" accept=".txt" class="hidden" 
                onchange="handleIncludeFileUpload(this)" />
              <button type="button" onclick="clearIncludes()" class="btn btn-clear">
                🗑 Clear All
              </button>
              <div id="include_count" class="muted card-list-count">0/10</div>
              <div id="include_badges" class="card-list-badges"></div>
            </div>
            <div id="include_validation" class="card-list-validation"></div>
          </div>
          <!-- Exclude Cards Column (Right, Red) -->
          <div>
            <label class="card-list-label">
              <span class="card-list-label-exclude">✗ Must Exclude Cards</span>
              <small class="muted block text-xs mt-1">Cards to avoid in your deck</small>
            </label>
            <textarea name="exclude_cards" id="exclude_cards_textarea" 
              placeholder="Sol Ring&#10;Rhystic Study&#10;Smothering Tithe" 
              class="exclude-textarea"
              autocomplete="off" autocapitalize="off" spellcheck="false">{{ form.exclude_cards if form and form.exclude_cards else '' }}</textarea>
            <!-- Exclude Cards Chips Container -->
            <div id="exclude_chips_container" class="exclude-chips-container">
              <div id="exclude_chips" class="chips-inner"></div>
              <div class="chips-placeholder" id="exclude_chips_placeholder">Enter card names above to see them as removable tags</div>
            </div>
            <div class="card-list-controls">
              <label for="exclude_file_upload" class="btn btn-upload-exclude">
                📄 Upload .txt
              </label>
              <input type="file" id="exclude_file_upload" accept=".txt" class="hidden" 
                onchange="handleExcludeFileUpload(this)" />
              <button type="button" onclick="clearExcludes()" class="btn btn-clear">
                🗑 Clear All
              </button>
              <div id="exclude_count" class="muted card-list-count">0/15</div>
              <div id="exclude_badges" class="card-list-badges"></div>
            </div>
            <div id="exclude_validation" class="card-list-validation"></div>
          </div>
        </div>
        <div class="info-panel">
          <details>
            <summary>Advanced Options</summary>
            <div class="info-panel-content">
              <div class="mb-2">
                <label class="form-checkbox-label">
                  <input type="radio" name="enforcement_mode" value="warn" {% if not form or (form and (not form.enforcement_mode or form.enforcement_mode == 'warn')) %}checked{% endif %} />
                  <span>Warn mode <small class="muted ml-1">(proceed if cards missing)</small></span>
                </label>
                <label class="form-checkbox-label">
                  <input type="radio" name="enforcement_mode" value="strict" {% if form and form.enforcement_mode == 'strict' %}checked{% endif %} />
                  <span>Strict mode <small class="muted ml-1">(abort if cards missing)</small></span>
                </label>
              </div>
              <div>
                <label class="form-checkbox-label">
                  <input type="checkbox" name="allow_illegal" {% if form and form.allow_illegal %}checked{% endif %} />
                  <span>Allow illegal cards</span>
                </label>
                <!-- Fuzzy matching always enabled - hidden field -->
                <input type="hidden" name="fuzzy_matching" value="1" />
              </div>
            </div>
          </details>
        </div>
        <small class="muted block mt-2 text-xs text-center">
          Enter one card name per line. Cards are validated with fuzzy name matching.
        </small>
      </fieldset>
        {% if not show_must_have_buttons %}
      <div class="muted text-xs mt-3">
        Step 5 quick-add buttons are hidden (<code>SHOW_MUST_HAVE_BUTTONS=0</code>), but you can still seed must include/exclude lists here.
      </div>
        {% endif %}
      {% endif %}
      {% include "build/_new_deck_skip_controls.html" %}
      {% if enable_budget_mode %}
      <fieldset>
        <legend>Budget <span class="help-tip"><button type="button" class="help-tip-btn" data-tip="Set deck and per-card price ceilings. Over-budget cards are flagged during the build." data-tip-href="/help/budget_mode#setting-a-budget" aria-label="Budget mode help"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true" width="11" height="11"><circle cx="8" cy="8" r="6.5"/><line x1="8" y1="7" x2="8" y2="10.5" stroke-linecap="round"/><circle cx="8" cy="4.5" r="0.75" fill="currentColor" stroke="none"/></svg></button></span></legend>
        <div class="flex flex-col gap-3">
          <label class="block">
            <span>Total budget ($)</span>
            <small class="muted block text-xs mt-1">Set a deck cost ceiling — cards over budget will be flagged</small>
            <input type="number" name="budget_total" id="budget_total" min="0" step="0.01"
              placeholder="e.g. 150.00"
              value="{{ form.budget_total if form and form.budget_total else '' }}" />
          </label>
          <label class="block">
            <span>Per-card ceiling ($) <small class="muted">(optional)</small></span>
            <small class="muted block text-xs mt-1">Flag individual cards above this price</small>
            <input type="number" name="card_ceiling" id="card_ceiling" min="0" step="0.01"
              placeholder="e.g. 10.00"
              value="{{ form.card_ceiling if form and form.card_ceiling else '' }}" />
          </label>
          <label class="block">
            <span>Pool filter tolerance (%)</span>
            <small class="muted block text-xs mt-1">Cards exceeding the per-card ceiling by more than this % are excluded from the card pool. Set to 0 to hard-cap at the ceiling exactly.</small>
            <input type="number" name="pool_tolerance" id="pool_tolerance" min="0" max="100" step="1"
              value="{{ form.pool_tolerance if form is not none else '15' }}" />
          </label>

        </div>
      </fieldset>
      {% endif %}
      {% if enable_batch_build %}
      <fieldset>
        <legend>Build Options</legend>
        <div class="flex flex-col gap-3">
          <label class="block">
            <span>Number of decks to build</span>
            <small class="muted block text-xs mt-1">Run the same configuration multiple times to see variance in results</small>
          </label>
          {% if ideals_ui_mode == 'slider' %}
          <div class="flex items-center gap-4">
            <input type="range" name="build_count" id="build_count_slider" min="1" max="10" value="{{ form.build_count if form and form.build_count else 1 }}" class="flex-1" 
              oninput="document.getElementById('build_count_value').textContent = this.value; updateBuildCountLabel(this.value); updateButtonState(this.value);" />
            <span id="build_count_value" class="min-w-[2.5rem] text-center font-medium text-lg">{{ form.build_count if form and form.build_count else 1 }}</span>
          </div>
          <small id="build_count_label" class="muted text-xs text-center">Build 1 deck (normal build)</small>
          {% else %}
          <input type="number" name="build_count" id="build_count_input" min="1" max="10" value="{{ form.build_count if form and form.build_count else 1 }}" class="w-24" 
            oninput="updateButtonState(this.value);" />
          <small class="muted text-xs">Enter 1 for normal build, 2-10 to compare multiple results</small>
          {% endif %}
        </div>
      </fieldset>
      {% else %}
      {# Hidden input to always send build_count=1 when feature disabled #}
      <input type="hidden" name="build_count" value="1" />
      {% endif %}
      <div class="modal-footer">
        <button type="button" class="btn" onclick="this.closest('.modal').remove()">Cancel</button>
        <div class="modal-footer-left">
          <button type="submit" name="quick_build" value="1" class="btn-continue" id="quick-build-btn" title="Build entire deck automatically without approval steps">Quick Build</button>
          <span class="help-tip" style="margin-left:6px;"><button type="button" class="help-tip-btn" data-tip="Builds the complete deck in one step without step-by-step approval prompts." data-tip-href="/help/quick_build_skip_controls#quick-build" aria-label="Quick Build help"><svg viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true" width="11" height="11"><circle cx="8" cy="8" r="6.5"/><line x1="8" y1="7" x2="8" y2="10.5" stroke-linecap="round"/><circle cx="8" cy="4.5" r="0.75" fill="currentColor" stroke="none"/></svg></button></span>
          <button type="submit" class="btn-continue" id="create-btn">Build Deck</button>
        </div>
      </div>
      {% if allow_must_haves and multi_copy_archetypes_js %}
      {# Multi-copy archetype confirmation dialog — shown when user types an archetype in must-include #}
      <div id="mc-include-confirm" role="dialog" aria-modal="true" aria-labelledby="mc-confirm-title"
           style="display:none; position:fixed; inset:0; z-index:10000; align-items:center; justify-content:center;">
        <div style="position:absolute; inset:0; background:rgba(0,0,0,.6);" onclick="window._mcConfirmClose()"></div>
        <div style="position:relative; max-width:420px; width:clamp(290px,90vw,420px);
                     background:var(--surface,#0f1115); border:1px solid var(--border,#333);
                     border-radius:10px; box-shadow:0 10px 30px rgba(0,0,0,.5); padding:1.25rem;">
          <h3 id="mc-confirm-title" style="margin:0 0 .5rem; font-size:1rem;">Multi-copy package detected</h3>
          <p id="mc-confirm-msg" class="muted" style="font-size:13px; margin:0 0 .75rem;"></p>
          <div style="display:flex; align-items:center; gap:.5rem; flex-wrap:wrap; margin-bottom:.5rem;">
            <label style="display:flex; align-items:center; gap:.35rem;">
              Copies
              <input type="number" id="mc-confirm-count" min="1" value="25"
                     style="width:5rem; margin-left:.25rem;">
            </label>
            <small id="mc-confirm-hint" class="muted"></small>
          </div>
          <div id="mc-confirm-thrumming-row" style="margin-bottom:.75rem;">
            <label style="display:flex; align-items:center; gap:.4rem; font-size:13px; cursor:pointer;">
              <input type="checkbox" id="mc-confirm-thrumming" checked>
              Include <em>Thrumming Stone</em>
            </label>
          </div>
          <div style="display:flex; gap:.5rem; justify-content:flex-end; flex-wrap:wrap;">
            <button type="button" class="btn" onclick="window._mcConfirmClose()">Cancel</button>
            <button type="button" class="btn-continue" onclick="window._mcConfirmSubmit()">Add to must-include</button>
          </div>
        </div>
      </div>
      {# Conflict dialog — shown when a selected multicopy archetype also appears in the exclude list #}
      <div id="mc-exclude-conflict" role="dialog" aria-modal="true" aria-labelledby="mc-conflict-title"
           style="display:none; position:fixed; inset:0; z-index:10001; align-items:center; justify-content:center;">
        <div style="position:absolute; inset:0; background:rgba(0,0,0,.6);" onclick="window._mcConflictClose()"></div>
        <div style="position:relative; max-width:440px; width:clamp(290px,90vw,440px);
                     background:var(--surface,#0f1115); border:1px solid var(--border,#333);
                     border-radius:10px; box-shadow:0 10px 30px rgba(0,0,0,.5); padding:1.25rem;">
          <h3 id="mc-conflict-title" style="margin:0 0 .5rem; font-size:1rem;">Multi-copy / Exclude conflict</h3>
          <p id="mc-conflict-msg" class="muted" style="font-size:13px; margin:0 0 1rem;"></p>
          <div style="display:flex; flex-direction:column; gap:.5rem;">
            <button type="button" class="btn-continue" onclick="window._mcConflictKeepMulti()">Keep multi-copy (remove from excludes)</button>
            <button type="button" class="btn-continue" onclick="window._mcConflictKeepExcludes()">Keep excludes (remove multi-copy)</button>
            <button type="button" class="btn" onclick="window._mcConflictClose()">Cancel</button>
          </div>
        </div>
      </div>
      <script>
        window._MC_ARCHETYPES = {{ multi_copy_archetypes_js | tojson }};
      </script>
      {% endif %}
    </form>
  </div>
</div>

<script>
  // Quick Build confirmation for mobile devices
  (function() {
    var quickBuildBtn = document.getElementById('quick-build-btn');
    if (quickBuildBtn) {
      // Detect mobile/tablet device (true touch-primary devices)
      // Check for touch AND small screen or mobile user agent
      var isMobile = ('ontouchstart' in window) && 
                     (window.innerWidth <= 1024 || /Mobi|Android|iPhone|iPad|iPod/i.test(navigator.userAgent));
      
      if (isMobile) {
        quickBuildBtn.addEventListener('click', function(e) {
          var confirmed = confirm('Quick Build will create a complete deck automatically without approval steps. Continue?');
          if (!confirmed) {
            e.preventDefault();
            e.stopPropagation();
            return false;
          }
        });
      }
    }
  })();
  
  // Update build count label based on slider value
  function updateBuildCountLabel(count) {
    var label = document.getElementById('build_count_label');
    if (!label) return;
    
    count = parseInt(count);
    if (count === 1) {
      label.textContent = 'Build 1 deck (normal build)';
      label.className = 'muted';
    } else {
      label.textContent = 'Build ' + count + ' decks and compare results';
      label.className = 'muted';
      label.style.color = '#60a5fa';
      label.style.fontWeight = '500';
    }
  }
  
  // Update button state based on build count
  function updateButtonState(count) {
    var quickBuildBtn = document.getElementById('quick-build-btn');
    var createBtn = document.getElementById('create-btn');
    
    count = parseInt(count);
    
    if (count > 1) {
      // Multi-build: force Quick Build, hide Create button
      if (createBtn) {
        createBtn.style.display = 'none';
      }
      if (quickBuildBtn) {
        quickBuildBtn.textContent = 'Build ' + count + ' Decks';
        quickBuildBtn.title = 'Build ' + count + ' decks automatically and compare results';
      }
    } else {
      // Single build: show both buttons normally
      if (createBtn) {
        createBtn.style.display = '';
      }
      if (quickBuildBtn) {
        quickBuildBtn.textContent = 'Quick Build';
        quickBuildBtn.title = 'Build entire deck automatically without approval steps';
      }
    }
  }
  
  // Initialize label and button state on page load
  (function() {
    var slider = document.getElementById('build_count_slider');
    var input = document.getElementById('build_count_input');
    var initialValue = slider ? slider.value : (input ? input.value : 1);
    
    if (slider) {
      updateBuildCountLabel(initialValue);
    }
    updateButtonState(initialValue);
  })();
  
  // Utility function for parsing card lists
  function parseCardList(content) {
    const newlineRegex = /\r?\n/;
    return content.split(newlineRegex)
      .map(function(line) { return line.trim(); })
      .filter(function(line) { return line; });
  }

  // Handle include cards file upload
  function handleIncludeFileUpload(input) {
    if (input.files && input.files[0]) {
      const file = input.files[0];
      if (!file.name.toLowerCase().endsWith('.txt')) {
        alert('Please select a .txt file');
        input.value = '';
        return;
      }
      
      const reader = new FileReader();
      reader.onload = function(e) {
        const textarea = document.getElementById('include_cards_textarea');
        const fileContent = e.target.result;
        const lines = parseCardList(fileContent);
        
        // Merge with existing content (if any)
        const existingContent = textarea.value.trim();
        const existingLines = existingContent ? parseCardList(existingContent) : [];
        
        // Combine and deduplicate
        const allLinesSet = new Set([].concat(existingLines).concat(lines));
        const allLines = Array.from(allLinesSet);
        textarea.value = allLines.join('\n');
        
        // Show feedback and update count
        const validation = document.getElementById('include_validation');
        if (validation) {
          validation.innerHTML = '<span style="color: #4ade80;">✓ Loaded ' + lines.length + ' cards from file</span>';
          setTimeout(function() { validation.innerHTML = ''; }, 3000);
        }
        updateIncludeCount();
        updateChips('include');
        
        // Clear file input for re-upload
        input.value = '';
        
        // Trigger validation
        validateIncludeExcludeCards();
      };
      reader.readAsText(file);
    }
  }

  // Handle exclude cards file upload
  function handleExcludeFileUpload(input) {
    if (input.files && input.files[0]) {
      const file = input.files[0];
      if (!file.name.toLowerCase().endsWith('.txt')) {
        alert('Please select a .txt file');
        input.value = '';
        return;
      }
      
      const reader = new FileReader();
      reader.onload = function(e) {
        const textarea = document.getElementById('exclude_cards_textarea');
        const fileContent = e.target.result;
        const lines = parseCardList(fileContent);
        
        // Merge with existing content (if any)
        const existingContent = textarea.value.trim();
        const existingLines = existingContent ? parseCardList(existingContent) : [];
        
        // Combine and deduplicate
        const allLinesSet = new Set([].concat(existingLines).concat(lines));
        const allLines = Array.from(allLinesSet);
        textarea.value = allLines.join('\n');
        
        // Show feedback and update count
        const validation = document.getElementById('exclude_validation');
        if (validation) {
          validation.innerHTML = '<span style="color: #4ade80;">✓ Loaded ' + lines.length + ' cards from file</span>';
          setTimeout(function() { validation.innerHTML = ''; }, 3000);
        }
        updateExcludeCount();
        updateChips('exclude');
        
        // Clear file input for re-upload
        input.value = '';
        
        // Trigger validation
        validateIncludeExcludeCards();
      };
      reader.readAsText(file);
    }
  }

  // Clear all includes
  function clearIncludes() {
    const textarea = document.getElementById('include_cards_textarea');
    const validation = document.getElementById('include_validation');
    if (textarea) {
      textarea.value = '';
      updateIncludeCount();
      updateChips('include');
    }
    if (validation) {
      validation.innerHTML = '';
    }
    validateIncludeExcludeCards();
  }

  // Clear all excludes
  function clearExcludes() {
    const textarea = document.getElementById('exclude_cards_textarea');
    const validation = document.getElementById('exclude_validation');
    if (textarea) {
      textarea.value = '';
      updateExcludeCount();
      updateChips('exclude');
    }
    if (validation) {
      validation.innerHTML = '';
    }
    validateIncludeExcludeCards();
  }

  // Chips Management Functions
  function createChip(cardName, type) {
    const chip = document.createElement('div');
    chip.className = 'card-chip';
    chip.setAttribute('data-card-name', cardName);
    chip.style.cssText = `
      display: inline-flex;
      align-items: center;
      gap: 0.25rem;
      padding: 0.25rem 0.5rem;
      font-size: 11px;
      border-radius: 12px;
      cursor: default;
      user-select: none;
      ${type === 'include' ? 
        'background: #dcfce7; border: 1px solid #4ade80; color: #166534;' : 
        'background: #fef2f2; border: 1px solid #ef4444; color: #991b1b;'
      }
    `;
    
    const cardText = document.createElement('span');
    cardText.textContent = cardName;
    
    const removeBtn = document.createElement('button');
    removeBtn.textContent = '×';
    removeBtn.type = 'button';
    removeBtn.style.cssText = `
      background: none;
      border: none;
      font-size: 14px;
      font-weight: bold;
      cursor: pointer;
      padding: 0;
      margin: 0;
      width: 16px;
      height: 16px;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 50%;
      color: ${type === 'include' ? '#166534' : '#991b1b'};
    `;
    removeBtn.title = 'Remove ' + cardName;
    removeBtn.onmouseover = () => removeBtn.style.background = type === 'include' ? '#bbf7d0' : '#fee2e2';
    removeBtn.onmouseout = () => removeBtn.style.background = 'none';
    removeBtn.onclick = () => removeChip(cardName, type);
    
    chip.appendChild(cardText);
    chip.appendChild(removeBtn);
    return chip;
  }

  function removeChip(cardName, type) {
    const textareaId = type === 'include' ? 'include_cards_textarea' : 'exclude_cards_textarea';
    const textarea = document.getElementById(textareaId);
    if (!textarea) return;
    
    const cards = parseCardList(textarea.value);
    const filtered = cards.filter(card => card.toLowerCase() !== cardName.toLowerCase());
    textarea.value = filtered.join('\n');
    
    updateChips(type);
    if (type === 'include') {
      updateIncludeCount();
    } else {
      updateExcludeCount();
    }
    validateIncludeExcludeCards();
  }

  function updateChips(type) {
    const textareaId = type === 'include' ? 'include_cards_textarea' : 'exclude_cards_textarea';
    const chipsId = type === 'include' ? 'include_chips' : 'exclude_chips';
    const placeholderId = type === 'include' ? 'include_chips_placeholder' : 'exclude_chips_placeholder';
    
    const textarea = document.getElementById(textareaId);
    const chipsContainer = document.getElementById(chipsId);
    const placeholder = document.getElementById(placeholderId);
    
    if (!textarea || !chipsContainer || !placeholder) return;
    
    const cards = parseCardList(textarea.value);
    
    // Clear existing chips
    chipsContainer.innerHTML = '';
    
    if (cards.length === 0) {
      placeholder.style.display = 'block';
    } else {
      placeholder.style.display = 'none';
      cards.forEach(cardName => {
        if (cardName.trim()) {
          const chip = createChip(cardName.trim(), type);
          chipsContainer.appendChild(chip);
        }
      });
    }
  }

  function initializeChips() {
    updateChips('include');
    updateChips('exclude');
  }

  // Update include count display
  function updateIncludeCount() {
    const textarea = document.getElementById('include_cards_textarea');
    const counter = document.getElementById('include_count');
    if (!textarea || !counter) return;
    
    const content = textarea.value.trim();
    const count = content ? parseCardList(content).length : 0;
    const limit = 10;
    
    let warningIcon = '';
    let warningClass = '';
    
    if (count > limit) {
      warningIcon = '⚠️ ';
      warningClass = 'color: #ef4444; font-weight: bold;';
    } else if (count > limit * 0.8) {
      warningIcon = '⚡ ';
      warningClass = 'color: #f59e0b; font-weight: 500;';
    } else {
      warningClass = 'color: #6b7280;';
    }
    
    counter.innerHTML = `${warningIcon}${count}/${limit}`;
    counter.style.cssText = `font-size:11px; ${warningClass}`;
  }

  // Update exclude count display
  function updateExcludeCount() {
    const textarea = document.getElementById('exclude_cards_textarea');
    const counter = document.getElementById('exclude_count');
    if (!textarea || !counter) return;
    
    const content = textarea.value.trim();
    const count = content ? parseCardList(content).length : 0;
    const limit = 15;
    
    let warningIcon = '';
    let warningClass = '';
    
    if (count > limit) {
      warningIcon = '⚠️ ';
      warningClass = 'color: #ef4444; font-weight: bold;';
    } else if (count > limit * 0.8) {  // 12+ excludes
      warningIcon = '⚡ ';
      warningClass = 'color: #f59e0b; font-weight: 500;';
    } else {
      warningClass = 'color: #6b7280;';
    }
    
    counter.innerHTML = `${warningIcon}${count}/${limit}`;
    counter.style.cssText = `font-size:11px; ${warningClass}`;
  }

  // Update include validation badges
  function updateIncludeBadges(includeData) {
    const badgeContainer = document.getElementById('include_badges');
    if (!badgeContainer || !includeData) return;
    
    let badges = '';
    
    if (includeData.count === 0) {
      badgeContainer.innerHTML = '';
      return;
    }
    
    // Legal cards badge
    if (includeData.legal && includeData.legal.length > 0) {
      badges += `<span style="background:#dcfce7; color:#166534; padding:2px 6px; border-radius:12px; border:1px solid #bbf7d0;">✓ ${includeData.legal.length} legal</span>`;
    }
    
    // Invalid cards badge (includes color mismatches and not found cards)
    if (includeData.illegal && includeData.illegal.length > 0) {
      badges += `<span style="background:#fee2e2; color:#dc2626; padding:2px 6px; border-radius:12px; border:1px solid #fecaca;">✗ ${includeData.illegal.length} illegal</span>`;
    }
    
    // Duplicates badge
    if (includeData.duplicates && Object.keys(includeData.duplicates).length > 0) {
      const dupeCount = Object.keys(includeData.duplicates).length;
      badges += `<span style="background:#e0e7ff; color:#3730a3; padding:2px 6px; border-radius:12px; border:1px solid #c7d2fe;">📋 ${dupeCount} dupes</span>`;
    }
    
    badgeContainer.innerHTML = badges;
    
    // Update chip colors based on validation status
    updateChipColors('include', includeData);
  }

  // Update chip colors based on validation status
  function updateChipColors(type, validationData) {
    if (!validationData) return;
    
    const container = document.getElementById(`${type}_chips`);
    if (!container) return;
    
    const chips = container.querySelectorAll('.card-chip');
    chips.forEach(chip => {
      const cardName = chip.getAttribute('data-card-name');
      if (!cardName) return;
      
      // Determine status
      let isLegal = false;
      let isIllegal = false;
      
      if (validationData.legal && validationData.legal.includes(cardName)) {
        isLegal = true;
      }
      if (validationData.illegal && validationData.illegal.includes(cardName)) {
        isIllegal = true;
      }
      
      // Apply styling based on status (prioritize illegal over legal)
      if (isIllegal) {
        // Red styling for illegal cards
        chip.style.background = '#fee2e2';
        chip.style.border = '1px solid #fecaca';
        chip.style.color = '#dc2626';
        
        // Update remove button color too
        const removeBtn = chip.querySelector('button');
        if (removeBtn) {
          removeBtn.style.color = '#dc2626';
          removeBtn.onmouseover = () => removeBtn.style.background = '#fee2e2';
        }
      } else if (isLegal) {
        // Green styling for legal cards
        chip.style.background = '#dcfce7';
        chip.style.border = '1px solid #bbf7d0';
        chip.style.color = '#166534';
        
        // Update remove button color too
        const removeBtn = chip.querySelector('button');
        if (removeBtn) {
          removeBtn.style.color = '#166534';
          removeBtn.onmouseover = () => removeBtn.style.background = '#bbf7d0';
        }
      }
      // If no status info, keep default styling
    });
  }

  // Update exclude validation badges
  function updateExcludeBadges(excludeData) {
    const badgeContainer = document.getElementById('exclude_badges');
    if (!badgeContainer || !excludeData) return;
    
    let badges = '';
    
    if (excludeData.count === 0) {
      badgeContainer.innerHTML = '';
      return;
    }
    
    // Legal cards badge
    if (excludeData.legal && excludeData.legal.length > 0) {
      badges += `<span style="background:#dcfce7; color:#166534; padding:2px 6px; border-radius:12px; border:1px solid #bbf7d0;">✓ ${excludeData.legal.length} legal</span>`;
    }
    
    // Invalid cards badge
    if (excludeData.illegal && excludeData.illegal.length > 0) {
      badges += `<span style="background:#fee2e2; color:#dc2626; padding:2px 6px; border-radius:12px; border:1px solid #fecaca;">✗ ${excludeData.illegal.length} invalid</span>`;
    }
    
    // Duplicates badge
    if (excludeData.duplicates && Object.keys(excludeData.duplicates).length > 0) {
      const dupeCount = Object.keys(excludeData.duplicates).length;
      badges += `<span style="background:#e0e7ff; color:#3730a3; padding:2px 6px; border-radius:12px; border:1px solid #c7d2fe;">📋 ${dupeCount} dupes</span>`;
    }
    
    badgeContainer.innerHTML = badges;
    
    // Update chip colors based on validation status
    updateChipColors('exclude', excludeData);
  }

  // Comprehensive validation for both include and exclude cards
  function validateIncludeExcludeCards() {
    console.log('validateIncludeExcludeCards called');
    const includeTextarea = document.getElementById('include_cards_textarea');
    const excludeTextarea = document.getElementById('exclude_cards_textarea');
    const includeValidation = document.getElementById('include_validation');
    const excludeValidation = document.getElementById('exclude_validation');
    
    if (!includeTextarea || !excludeTextarea) {
      console.log('Missing textareas');
      return;
    }
    
    const includeContent = includeTextarea.value.trim();
    const excludeContent = excludeTextarea.value.trim();
    
    console.log('Include content:', includeContent);
    console.log('Exclude content:', excludeContent);
    
    // Update counts
    updateIncludeCount();
    updateExcludeCount();
    
    // If both are empty, clear validations
    if (!includeContent && !excludeContent) {
      console.log('Both empty, clearing validation');
      if (includeValidation) includeValidation.innerHTML = '';
      if (excludeValidation) excludeValidation.innerHTML = '';
      
      // Clear badges
      const includeBadges = document.getElementById('include_badges');
      const excludeBadges = document.getElementById('exclude_badges');
      if (includeBadges) includeBadges.innerHTML = '';
      if (excludeBadges) excludeBadges.innerHTML = '';
      return;
    }
    
    // Show loading state
    console.log('Setting loading state');
    if (includeValidation) includeValidation.innerHTML = '<span style="color: #6b7280;">Validating...</span>';
    if (excludeValidation) excludeValidation.innerHTML = '<span style="color: #6b7280;">Validating...</span>';
    
    // Get commander for advanced validation
    const commanderInput = document.querySelector('input[name="commander"]');
    const commander = commanderInput ? commanderInput.value.trim() : '';
    
    // Get advanced options
    const enforcementMode = document.querySelector('input[name="enforcement_mode"]:checked');
    const allowIllegal = document.querySelector('input[name="allow_illegal"]');
    const fuzzyMatching = document.querySelector('input[name="fuzzy_matching"]');
    
    // Build form data
    const formData = new FormData();
    formData.append('include_cards', includeContent);
    formData.append('exclude_cards', excludeContent);
    formData.append('commander', commander);
    formData.append('enforcement_mode', enforcementMode ? enforcementMode.value : 'warn');
    formData.append('allow_illegal', allowIllegal ? allowIllegal.checked : false);
    // For hidden input, use .value instead of .checked (hidden inputs don't have checked property)
    formData.append('fuzzy_matching', fuzzyMatching ? (fuzzyMatching.value || 'true') : 'true');
    
    console.log('Making fetch request to /build/validate/include_exclude');
    fetch('/build/validate/include_exclude', {
      method: 'POST',
      body: formData
    })
    .then(response => {
      console.log('Received response:', response);
      return response.json();
    })
    .then(data => {
      console.log('Validation response data:', data);
      if (data.error) {
        if (includeValidation) includeValidation.innerHTML = '<span style="color: #ef4444;">Error: ' + data.error + '</span>';
        if (excludeValidation) excludeValidation.innerHTML = '<span style="color: #ef4444;">Error: ' + data.error + '</span>';
        return;
      }
      
      // Update include validation and badges
      updateIncludeBadges(data.includes);
      if (includeValidation) {
        let html = '';
        const includeData = data.includes;
        
        if (includeData.count === 0) {
          html = '';
        } else {
          if (includeData.warnings && includeData.warnings.length > 0) {
            html += '<span style="color: #f59e0b;">⚠ ' + includeData.warnings[0] + '</span>';
          }
        }
        includeValidation.innerHTML = html;
      }
      
      // Update exclude validation and badges  
      updateExcludeBadges(data.excludes);
      if (excludeValidation) {
        let html = '';
        const excludeData = data.excludes;
        
        if (excludeData.count === 0) {
          html = '';
        } else {
          if (excludeData.warnings && excludeData.warnings.length > 0) {
            html += '<span style="color: #f59e0b;">⚠ ' + excludeData.warnings[0] + '</span>';
          }
        }
        excludeValidation.innerHTML = html;
      }
      
      // Show conflicts if any
      if (data.conflicts && data.conflicts.length > 0) {
        const conflictMsg = '<span style="color: #f59e0b;">⚠ Conflict: ' + data.conflicts.slice(0, 2).join(', ') + (data.conflicts.length > 2 ? '...' : '') + '</span>';
        if (includeValidation && includeValidation.innerHTML) {
          includeValidation.innerHTML += '<br>' + conflictMsg;
        }
        if (excludeValidation && excludeValidation.innerHTML) {
          excludeValidation.innerHTML += '<br>' + conflictMsg;
        }
      }
      
      // Handle fuzzy match confirmations
      if (data.confirmation_needed && data.confirmation_needed.length > 0) {
        showFuzzyMatchConfirmationModal(data.confirmation_needed);
      }
    })
    .catch(error => {
      console.error('Validation fetch error:', error);
      if (includeValidation) includeValidation.innerHTML = '<span style="color: #ef4444;">Validation failed</span>';
      if (excludeValidation) excludeValidation.innerHTML = '<span style="color: #ef4444;">Validation failed</span>';
    });
  }
  
  // Set up event listeners when page loads
  document.addEventListener('DOMContentLoaded', function() {
    console.log('DOMContentLoaded fired');
    // Initialize chips on page load
    initializeChips();
    
    // Set up live validation on textarea changes
    const includeTextarea = document.getElementById('include_cards_textarea');
    const excludeTextarea = document.getElementById('exclude_cards_textarea');
    
    console.log('Include textarea found:', includeTextarea);
    console.log('Exclude textarea found:', excludeTextarea);
    
    let validationTimer;
    
    if (includeTextarea) {
      console.log('Setting up include textarea event listener');
      includeTextarea.addEventListener('input', function() {
        console.log('Include textarea input event fired');
        clearTimeout(validationTimer);
        updateIncludeCount(); // Update count immediately
        console.log('Setting validation timer for 500ms');
        // Delay chips update until typing pauses
        validationTimer = setTimeout(function() {
          updateChips('include');
          validateIncludeExcludeCards();
        }, 500);
      });
      
      // Update chips immediately on Enter
      includeTextarea.addEventListener('keyup', function(e) {
        if (e.key === 'Enter') {
          console.log('Enter pressed - updating chips immediately');
          clearTimeout(validationTimer);
          updateChips('include');
          updateIncludeCount();
          // Still validate after Enter
          validationTimer = setTimeout(validateIncludeExcludeCards, 300);
        }
      });
      
      // Initial count and validation if there's content
      if (includeTextarea.value.trim()) {
        updateIncludeCount();
        validateIncludeExcludeCards();
      }
    }
    
    if (excludeTextarea) {
      console.log('Setting up exclude textarea event listener');
      excludeTextarea.addEventListener('input', function() {
        console.log('Exclude textarea input event fired');
        clearTimeout(validationTimer);
        updateExcludeCount(); // Update count immediately
        // Delay chips update until typing pauses
        validationTimer = setTimeout(function() {
          updateChips('exclude');
          validateIncludeExcludeCards();
        }, 500);
      });
      
      // Update chips immediately on Enter
      excludeTextarea.addEventListener('keyup', function(e) {
        if (e.key === 'Enter') {
          console.log('Enter pressed - updating chips immediately');
          clearTimeout(validationTimer);
          updateChips('exclude');
          updateExcludeCount();
          // Still validate after Enter
          validationTimer = setTimeout(validateIncludeExcludeCards, 300);
        }
      });
      
      // Initial count and validation if there's content
      if (excludeTextarea.value.trim()) {
        updateExcludeCount();
        validateIncludeExcludeCards();
      }
    }
    
    // Listen for changes in advanced options
    const advancedOptions = document.querySelectorAll('input[name="enforcement_mode"], input[name="allow_illegal"], input[name="fuzzy_matching"]');
    advancedOptions.forEach(function(input) {
      input.addEventListener('change', function() {
        clearTimeout(validationTimer);
        validationTimer = setTimeout(validateIncludeExcludeCards, 200);
      });
    });
    
    // Set up combo config toggle
    const comboChk = document.getElementById('pref-combos-chk');
    const comboConfig = document.getElementById('pref-combos-config');
    if (comboChk && comboConfig) {
      function syncComboConfig() {
        console.log('Combo checkbox changed:', comboChk.checked); // Debug log
        comboConfig.style.display = comboChk.checked ? 'block' : 'none';
      }
      comboChk.addEventListener('change', syncComboConfig);
      // Set initial state
      syncComboConfig();
    } else {
      console.log('Combo elements not found:', { comboChk, comboConfig }); // Debug log
    }
  });

  //Additional standalone combo toggle (backup)
  (function() {
    function setupComboToggle() {
      const chk = document.getElementById('pref-combos-chk');
      const config = document.getElementById('pref-combos-config');
      if (chk && config) {
        console.log('Setting up combo toggle (standalone)'); // Debug log
        function toggle() {
          console.log('Combo toggle triggered:', chk.checked); // Debug log
          config.style.display = chk.checked ? 'block' : 'none';
        }
        chk.addEventListener('change', toggle);
        toggle(); // Set initial state
      } else {
        console.log('Combo elements missing:', { chk, config }); // Debug log
      }
    }
    
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', setupComboToggle);
    } else {
      setupComboToggle();
    }
  })();
  
  // Auto deck name generation on commander change
  (function(){
    try{
      var modal = document.currentScript && document.currentScript.previousElementSibling ? document.currentScript.previousElementSibling.previousElementSibling : document.querySelector('.modal');
      var backdrop = modal ? modal.querySelector('.modal-backdrop') : null;
      if (backdrop){ backdrop.addEventListener('click', function(){ try{ modal.remove(); }catch(_){} }); }
    }catch(_){ }
    var modal = document.currentScript && document.currentScript.previousElementSibling ? document.currentScript.previousElementSibling.previousElementSibling : document.querySelector('.modal');
    // Prevent Enter in text inputs from submitting the form
    try {
      var form = modal ? modal.querySelector('form') : document.querySelector('.modal form');
      if (form){
        // Form-level Enter: if suggestions exist, pick the first by default
        form.addEventListener('keydown', function(e){
          try{
            if (e.key !== 'Enter' || e.shiftKey || e.altKey || e.ctrlKey || e.metaKey) return;
            // Allow Enter in include/exclude textareas for newlines
            if (document.activeElement && 
                (document.activeElement.id === 'include_cards_textarea' || 
                 document.activeElement.id === 'exclude_cards_textarea')) {
              return;
            }
            var list = document.getElementById('newdeck-candidates');
            var first = list && list.querySelector('button.candidate-btn');
            if (first){
              e.preventDefault(); e.stopPropagation(); first.click();
            } else {
              // No suggestions: allow normal form submit
            }
          }catch(_){ }
        }, true);
        // Name field: only block Enter if suggestions exist; otherwise allow submit
        var nameEl = form.querySelector('input[name="name"]');
        if (nameEl){
          nameEl.addEventListener('keydown', function(e){
            if (e.key !== 'Enter') return;
            try{
              var list = document.getElementById('newdeck-candidates');
              var hasBtns = !!(list && list.querySelector('button.candidate-btn'));
              if (hasBtns){ e.preventDefault(); e.stopPropagation(); }
            }catch(_){ }
          });
        }
        // In commander field, Enter picks the first candidate (if any) without closing the modal
        var cmdEl = form.querySelector('input[name=\"commander\"]');
        if (cmdEl){
          function handleEnterNav(e){
            // Enter selects the highlighted (or first) suggestion
            var list = document.getElementById('newdeck-candidates');
            var btns = list ? Array.prototype.slice.call(list.querySelectorAll('button.candidate-btn')) : [];
            var getActiveIndex = function(){ return btns.findIndex(function(b){ return b.classList.contains('active'); }); };
            if (!btns.length) return; // nothing to do, but we've already prevented default
            // Skip if a request is in-flight to avoid fighting with swap timing
            try{ if (cmdEl.matches('.htmx-request') || list.matches('.htmx-request')) return; }catch(_){ }
            if (e.key === 'Enter'){
              var idx = getActiveIndex();
              var target = btns[(idx >= 0 ? idx : 0)];
              if (target) { target.click(); }
            }
          }
          // Capture keydown early to prevent submit on Enter (arrows left to default behavior)
          cmdEl.addEventListener('keydown', function(e){
            if (e.key === 'Enter'){
              var list = document.getElementById('newdeck-candidates');
              var hasBtns = !!(list && list.querySelector('button.candidate-btn'));
              if (hasBtns){
                e.preventDefault();
                e.stopPropagation();
                handleEnterNav(e);
              }
            }
          }, true);
          // Defensive: also block Enter on keyup (in case a browser tries to submit on keyup)
          cmdEl.addEventListener('keyup', function(e){ if (e.key === 'Enter'){ e.preventDefault(); e.stopPropagation(); } });
      // Global fallback: capture keydown at the document level so Enter never slips through when the commander input is focused
          document.addEventListener('keydown', function(e){
            try{
              // Allow Enter in include/exclude textareas for newlines
              if (document.activeElement && 
                  (document.activeElement.id === 'include_cards_textarea' || 
                   document.activeElement.id === 'exclude_cards_textarea')) {
                return;
              }
              if (document.activeElement !== cmdEl) return;
        if (e.key !== 'Enter') return;
              var list = document.getElementById('newdeck-candidates');
              var hasBtns = !!(list && list.querySelector('button.candidate-btn'));
              if (!hasBtns) return;
              e.preventDefault();
              e.stopPropagation();
              handleEnterNav(e);
            }catch(_){ }
          }, true);
          // Reset candidate highlight when the list updates
          document.body.addEventListener('htmx:afterSwap', function(ev){
            try {
              var tgt = ev && ev.detail && ev.detail.target ? ev.detail.target : null;
              if (!tgt) return;
              if (tgt.id === 'newdeck-candidates'){
                var first = tgt.querySelector('button.candidate-btn');
                if (first){
                  // Clear any lingering active classes, then set the first as active for immediate Enter selection
                  tgt.querySelectorAll('button.candidate-btn').forEach(function(b){ b.classList.remove('active'); b.setAttribute('aria-selected','false'); });
                  first.classList.add('active');
                  first.setAttribute('aria-selected','true');
                  try{ cmdEl.setAttribute('aria-activedescendant', first.id || ''); }catch(_){ }
                }
              }
            } catch(_){}
          });
        }
      }
    } catch(_){ }
    // Close on Escape
    function closeModal(){ try{ var m = document.querySelector('.modal'); if(m){ m.remove(); document.removeEventListener('keydown', onKey); } }catch(_){} }
    function onKey(e){ if (e.key === 'Escape'){ e.preventDefault(); closeModal(); } }
    document.addEventListener('keydown', onKey);
  })();



  // Integrated Multi-Copy: fetch suggestions once commander + tags are present
  (function(){
    function fetchMulti(){
      try{
        var slot = document.getElementById('newdeck-multicopy-slot');
        var form = document.querySelector('.modal form');
        if (!slot || !form) return;
        var enable = form.querySelector('#pref-mc-chk');
        if (!enable || !enable.checked){ slot.innerHTML = ''; return; }
        var cmd = form.querySelector('input[name="commander"]').value.trim();
        var p = form.querySelector('input[name="primary_tag"]').value.trim();
        var s = form.querySelector('input[name="secondary_tag"]').value.trim();
        var t = form.querySelector('input[name="tertiary_tag"]').value.trim();
        var mode = form.querySelector('input[name="tag_mode"]').value.trim() || 'AND';
        if (!cmd) { slot.innerHTML = ''; return; }
        // Only fetch if at least one tag is present (to avoid noise)
        if (!(p || s || t)) { slot.innerHTML = ''; return; }
        var params = new URLSearchParams({ commander: cmd, tag_mode: mode });
        if (p) params.append('primary_tag', p); if (s) params.append('secondary_tag', s); if (t) params.append('tertiary_tag', t);
        fetch('/build/new/multicopy?' + params.toString(), { headers: { 'HX-Request': 'true' } })
          .then(function(r){ return r.text(); })
          .then(function(html){ slot.innerHTML = html; })
          .catch(function(){ slot.innerHTML = ''; });
      }catch(e){ }
    }
    // Listen for OOB updates to the tags slot to trigger fetch
    document.body.addEventListener('htmx:afterSwap', function(ev){
      try{
        var tgt = ev && ev.detail && ev.detail.target ? ev.detail.target : null;
        if (tgt && tgt.id === 'newdeck-tags-slot'){ fetchMulti(); }
      }catch(_){ }
    });
  // Respond to explicit tag-change signal from the tags partial
  try{ document.addEventListener('newdeck:tagsChanged', fetchMulti); }catch(_){ }
    // Also debounce on commander input changes
    try{
      var cmdEl = document.querySelector('.modal form input[name="commander"]');
      var timer;
      if (cmdEl){ cmdEl.addEventListener('input', function(){ clearTimeout(timer); timer = setTimeout(fetchMulti, 300); }); }
    }catch(_){ }
    // React to preference toggle
    try{
      var mcChk = document.querySelector('.modal form #pref-mc-chk');
      if (mcChk){ mcChk.addEventListener('change', fetchMulti); }
    }catch(_){ }
    
    // Immediate setup for include/exclude textareas (fallback if DOMContentLoaded already fired)
    try {
      console.log('Attempting immediate textarea setup');
      const includeTextarea = document.getElementById('include_cards_textarea');
      const excludeTextarea = document.getElementById('exclude_cards_textarea');
      
      console.log('Immediate - Include textarea found:', includeTextarea);
      console.log('Immediate - Exclude textarea found:', excludeTextarea);
      
      if (includeTextarea && !includeTextarea.hasAttribute('data-events-attached')) {
        console.log('Setting up immediate include textarea event listener');
        includeTextarea.setAttribute('data-events-attached', 'true');
        let validationTimer;
        
        includeTextarea.addEventListener('input', function() {
          console.log('Immediate - Include textarea input event fired');
          clearTimeout(validationTimer);
          updateIncludeCount(); // Update count immediately
          // Delay chips update until typing pauses
          validationTimer = setTimeout(function() {
            updateChips('include');
            validateIncludeExcludeCards();
          }, 500);
        });
        
        includeTextarea.addEventListener('keyup', function(e) {
          if (e.key === 'Enter') {
            console.log('Enter pressed - updating chips immediately');
            clearTimeout(validationTimer);
            updateChips('include');
            updateIncludeCount();
            // Still validate after Enter
            validationTimer = setTimeout(validateIncludeExcludeCards, 300);
          }
        });
      }
      
      if (excludeTextarea && !excludeTextarea.hasAttribute('data-events-attached')) {
        console.log('Setting up immediate exclude textarea event listener');
        excludeTextarea.setAttribute('data-events-attached', 'true');
        let validationTimer;
        
        excludeTextarea.addEventListener('input', function() {
          console.log('Immediate - Exclude textarea input event fired');
          clearTimeout(validationTimer);
          updateExcludeCount(); // Update count immediately
          // Delay chips update until typing pauses
          validationTimer = setTimeout(function() {
            updateChips('exclude');
            validateIncludeExcludeCards();
          }, 500);
        });
        
        excludeTextarea.addEventListener('keyup', function(e) {
          if (e.key === 'Enter') {
            console.log('Enter pressed - updating chips immediately');
            clearTimeout(validationTimer);
            updateChips('exclude');
            updateExcludeCount();
            // Still validate after Enter
            validationTimer = setTimeout(validateIncludeExcludeCards, 300);
          }
        });
      }
      
      // Initialize chips immediately if textareas exist
      if (includeTextarea || excludeTextarea) {
        initializeChips();
      }
    } catch(e) {
      console.error('Immediate textarea setup failed:', e);
    }
  })();

  // Fuzzy match confirmation modal
  function showFuzzyMatchConfirmationModal(confirmationItems) {
    if (!confirmationItems || confirmationItems.length === 0) return;
    
    const item = confirmationItems[0]; // Process one at a time
    const modal = document.createElement('div');
    modal.className = 'fuzzy-confirmation-modal';
    modal.innerHTML = `
      <div class="fuzzy-confirmation-overlay">
        <div class="fuzzy-confirmation-content">
          <h3>Card Match Confirmation</h3>
          <p>Did you mean one of these cards?</p>
          <div class="fuzzy-input-card">
            <strong>You typed:</strong> "${item.input}"
          </div>
          <div class="fuzzy-suggestions">
            ${item.suggestions.map((suggestion, index) => `
              <div class="fuzzy-suggestion" data-card="${suggestion}">
                <span class="suggestion-name">${suggestion}</span>
                <span class="suggestion-confidence">${Math.round(item.confidence * 100)}% match</span>
              </div>
            `).join('')}
          </div>
          <div class="fuzzy-actions">
            <button class="fuzzy-btn fuzzy-btn-cancel">Skip This Card</button>
            <button class="fuzzy-btn fuzzy-btn-none">None of These</button>
          </div>
        </div>
      </div>
    `;
    
    // Add dark theme compatible styles
    const style = document.createElement('style');
    style.textContent = `
      .fuzzy-confirmation-modal {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 10000;
      }
      .fuzzy-confirmation-overlay {
        background: rgba(0, 0, 0, 0.7);
        width: 100%;
        height: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 20px;
      }
      .fuzzy-confirmation-content {
        background: var(--bg-color, #1a1a1a);
        color: var(--text-color, #e5e5e5);
        border: 1px solid var(--border-color, #404040);
        border-radius: 8px;
        padding: 24px;
        max-width: 500px;
        width: 100%;
        box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.4);
      }
      .fuzzy-confirmation-content h3 {
        margin: 0 0 12px 0;
        font-size: 18px;
        font-weight: 600;
        color: var(--text-color, #e5e5e5);
      }
      .fuzzy-confirmation-content p {
        margin: 0 0 16px 0;
        color: var(--text-muted, #a0a0a0);
      }
      .fuzzy-input-card {
        background: var(--input-bg, #2a2a2a);
        color: var(--text-color, #e5e5e5);
        padding: 12px;
        border-radius: 6px;
        margin-bottom: 16px;
        font-family: monospace;
        border: 1px solid var(--border-color, #404040);
      }
      .fuzzy-suggestions {
        margin-bottom: 20px;
      }
      .fuzzy-suggestion {
        border: 2px solid var(--border-color, #404040);
        background: var(--card-bg, #2a2a2a);
        color: var(--text-color, #e5e5e5);
        border-radius: 6px;
        padding: 12px;
        margin-bottom: 8px;
        cursor: pointer;
        transition: all 0.2s;
        display: flex;
        justify-content: space-between;
        align-items: center;
      }
      .fuzzy-suggestion:hover {
        border-color: var(--primary-color, #3b82f6);
        background: var(--hover-bg, #3a3a3a);
      }
      .fuzzy-suggestion.selected {
        border-color: var(--success-color, #10b981);
        background: var(--success-bg, #064e3b);
      }
      .suggestion-name {
        font-weight: 500;
        color: var(--text-color, #e5e5e5);
      }
      .suggestion-confidence {
        color: var(--text-muted, #a0a0a0);
        font-size: 14px;
      }
      .fuzzy-actions {
        display: flex;
        gap: 12px;
        justify-content: flex-end;
      }
      .fuzzy-btn {
        padding: 8px 16px;
        border-radius: 6px;
        border: none;
        cursor: pointer;
        font-weight: 500;
        transition: all 0.2s;
      }
      .fuzzy-btn-cancel {
        background: var(--secondary-bg, #4a4a4a);
        color: var(--text-color, #e5e5e5);
      }
      .fuzzy-btn-cancel:hover {
        background: var(--secondary-hover, #5a5a5a);
      }
      .fuzzy-btn-none {
        background: var(--danger-color, #ef4444);
        color: white;
      }
      .fuzzy-btn-none:hover {
        background: var(--danger-hover, #dc2626);
      }
      .fuzzy-btn-accept {
        background: var(--success-color, #10b981);
        color: white;
      }
      .fuzzy-btn-accept:hover {
        background: var(--success-hover, #059669);
      }
      /* Enhanced mobile responsive styles (M3: Mobile Responsive Testing) */
      @media (max-width: 520px) {
        .fuzzy-confirmation-overlay {
          padding: 10px;
        }
        .fuzzy-confirmation-content {
          margin: 0;
          max-width: none;
          padding: 16px;
          max-height: 90vh;
          overflow-y: auto;
        }
        .fuzzy-confirmation-content h3 {
          font-size: 16px;
        }
        .fuzzy-suggestion {
          flex-direction: column;
          align-items: flex-start;
          text-align: left;
        }
        .suggestion-confidence {
          margin-top: 4px;
        }
        .fuzzy-actions {
          flex-direction: column;
          gap: 8px;
        }
        .fuzzy-btn {
          width: 100%;
          padding: 12px 16px;
          text-align: center;
        }
      }
      @media (max-width: 380px) {
        .fuzzy-confirmation-content {
          padding: 12px;
        }
        .fuzzy-input-card {
          padding: 8px;
          font-size: 14px;
        }
        .fuzzy-suggestion {
          padding: 8px;
        }
        .suggestion-name {
          font-size: 14px;
        }
        .suggestion-confidence {
          font-size: 12px;
        }
      }
    `;
    
    document.head.appendChild(style);
    document.body.appendChild(modal);
    
    // Add click handlers for suggestions
    const suggestions = modal.querySelectorAll('.fuzzy-suggestion');
    let selectedCard = null;
    
    suggestions.forEach(suggestion => {
      suggestion.addEventListener('click', () => {
        // Clear previous selection
        suggestions.forEach(s => s.classList.remove('selected'));
        suggestion.classList.add('selected');
        selectedCard = suggestion.dataset.card;
        
        // Add/update accept button
        let acceptBtn = modal.querySelector('.fuzzy-btn-accept');
        if (!acceptBtn) {
          acceptBtn = document.createElement('button');
          acceptBtn.className = 'fuzzy-btn fuzzy-btn-accept';
          modal.querySelector('.fuzzy-actions').appendChild(acceptBtn);
        }
        acceptBtn.textContent = `Use "${selectedCard}"`;
        
        acceptBtn.onclick = () => {
          acceptFuzzyMatch(item, selectedCard);
          closeFuzzyModal(modal, style);
          // Process remaining items
          if (confirmationItems.length > 1) {
            showFuzzyMatchConfirmationModal(confirmationItems.slice(1));
          }
        };
      });
    });
    
    // Cancel button
    modal.querySelector('.fuzzy-btn-cancel').onclick = () => {
      closeFuzzyModal(modal, style);
      // Process remaining items
      if (confirmationItems.length > 1) {
        showFuzzyMatchConfirmationModal(confirmationItems.slice(1));
      }
    };
    
    // None of these button
    modal.querySelector('.fuzzy-btn-none').onclick = () => {
      closeFuzzyModal(modal, style);
      // Process remaining items  
      if (confirmationItems.length > 1) {
        showFuzzyMatchConfirmationModal(confirmationItems.slice(1));
      }
    };
    
    // Close on overlay click
    modal.querySelector('.fuzzy-confirmation-overlay').onclick = (e) => {
      if (e.target === e.currentTarget) {
        closeFuzzyModal(modal, style);
        // Process remaining items
        if (confirmationItems.length > 1) {
          showFuzzyMatchConfirmationModal(confirmationItems.slice(1));
        }
      }
    };
  }
  
  function closeFuzzyModal(modal, style) {
    document.body.removeChild(modal);
    document.head.removeChild(style);
  }
  
  function acceptFuzzyMatch(item, selectedCard) {
    const isInclude = item.type === 'include';
    const textarea = isInclude ? 
      document.getElementById('include_cards_textarea') : 
      document.getElementById('exclude_cards_textarea');
    
    if (textarea) {
      // Replace the original input with the selected card
      let content = textarea.value;
      content = content.replace(item.input, selectedCard);
      textarea.value = content;
      
      // Update chips and validation
      if (isInclude) {
        updateIncludeChips();
      } else {
        updateExcludeChips();
      }
      
      // Re-validate after a short delay
      setTimeout(() => {
        validateIncludeExcludeCards();
      }, 100);
    }
  }
</script>

<style>
/* Modal responsive tweaks (scoped) */
@media (max-width: 600px){
  .modal .basics-grid{ grid-template-columns: 1fr !important; }
  #newdeck-commander-slot{ max-width: 100% !important; }
  #newdeck-commander-slot aside.card-preview{ max-width: 100% !important; }
  #newdeck-commander-slot img{ width: 100% !important; max-width: 260px; height: auto; margin: 0 auto; display: block; }
  .modal .modal-content{ width: min(95vw, 560px) !important; }
}
/* Keep grid layout on tablet and desktop */
@media (min-width: 601px){
  .modal .basics-grid{ 
    display: grid !important; 
    grid-template-columns: 2fr 1fr !important;
  }
}
</style>

<script>
// Remove any existing modal to prevent duplicates
(function() {
  // Find all modals with the same ID
  var allModals = document.querySelectorAll('#new-deck-modal');
  // If there's more than one, remove all but the last (newest) one
  if (allModals.length > 1) {
    for (var i = 0; i < allModals.length - 1; i++) {
      allModals[i].remove();
    }
  }
})();
</script>

<script>
// Multi-copy archetype popups — include-confirm and exclude-conflict
(function(){
  if (!window._MC_ARCHETYPES) return;

  var _pending = null;
  var _pendingConflict = null;

  // --- Include-confirm dialog ---
  window._mcConfirmClose = function(){
    var dlg = document.getElementById('mc-include-confirm');
    if (dlg) dlg.style.display = 'none';
    _pending = null;
  };

  window._mcConfirmSubmit = function(){
    if (!_pending) return;
    var form = _pending.form;
    var archetype = _pending.archetype;
    form.querySelectorAll('[data-mc-injected]').forEach(function(el){ el.remove(); });
    function inj(name, value){
      var h = document.createElement('input');
      h.type = 'hidden'; h.name = name; h.value = value;
      h.setAttribute('data-mc-injected', '1');
      form.appendChild(h);
    }
    inj('enable_multicopy', '1');
    inj('multi_choice_id', archetype.id);
    inj('multi_count', document.getElementById('mc-confirm-count').value || archetype.default_count);
    var thrum = document.getElementById('mc-confirm-thrumming');
    if (thrum && thrum.checked) inj('multi_thrumming', '1');
    window._mcConfirmClose();
    form.requestSubmit();
  };

  // --- Exclude-conflict dialog ---
  window._mcConflictClose = function(){
    var dlg = document.getElementById('mc-exclude-conflict');
    if (dlg) dlg.style.display = 'none';
    _pendingConflict = null;
  };

  window._mcConflictKeepMulti = function(){
    if (!_pendingConflict) return;
    var form = _pendingConflict.form;
    var archetype = _pendingConflict.archetype;
    // Remove archetype name from exclude textarea
    var exTa = document.getElementById('exclude_cards_textarea');
    if (exTa) {
      var exName = archetype.name.toLowerCase();
      var filtered = exTa.value.split(/\n/).filter(function(line){
        return line.trim().replace(/^\d+[x\s]+/i, '').toLowerCase() !== exName;
      });
      exTa.value = filtered.join('\n');
    }
    window._mcConflictClose();
    form.requestSubmit();
  };

  window._mcConflictKeepExcludes = function(){
    if (!_pendingConflict) return;
    var form = _pendingConflict.form;
    // Uncheck the multicopy enable checkbox so the server ignores it
    var mcChk = form.querySelector('#pref-mc-chk');
    if (mcChk) mcChk.checked = false;
    window._mcConflictClose();
    form.requestSubmit();
  };

  // Helper: show include-confirm dialog
  function showIncludeConfirm(form, found){
    _pending = { form: form, archetype: found };
    document.getElementById('mc-confirm-msg').textContent =
      '"' + found.name + '" is a multi-copy archetype card. How many copies should be included?';
    var countIn = document.getElementById('mc-confirm-count');
    countIn.value = found.default_count || 25;
    if (found.printed_cap) countIn.max = found.printed_cap;
    else countIn.removeAttribute('max');
    var hint = document.getElementById('mc-confirm-hint');
    if (found.printed_cap) hint.textContent = 'Max ' + found.printed_cap;
    else if (found.rec_window) hint.textContent = 'Suggested ' + found.rec_window[0] + '\u2013' + found.rec_window[1];
    else hint.textContent = '';
    var thrumRow = document.getElementById('mc-confirm-thrumming-row');
    var thrumChk = document.getElementById('mc-confirm-thrumming');
    if (thrumRow) thrumRow.style.display = found.thrumming_stone_synergy ? '' : 'none';
    if (thrumChk) thrumChk.checked = found.thrumming_stone_synergy;
    var dlg = document.getElementById('mc-include-confirm');
    if (dlg) dlg.style.display = 'flex';
  }

  // Intercept form submit in capture phase so we run before HTMX
  document.addEventListener('submit', function(e){
    try {
      var form = e.target;
      if (!form) return;
      if (form.getAttribute('hx-post') !== '/build/new') return;
      // Skip if hidden fields already injected (re-submit after a dialog confirm)
      if (form.querySelector('input[data-mc-injected]')) return;

      var mcChk = form.querySelector('#pref-mc-chk');

      if (mcChk && mcChk.checked) {
        // User is using the explicit multicopy selector — check for exclude conflict
        var choiceRadio = form.querySelector('input[name="multi_choice_id"]:checked');
        if (choiceRadio) {
          var choiceId = choiceRadio.value;
          var choiceArchetype = null;
          var allA = window._MC_ARCHETYPES;
          for (var ak in allA) { if (allA[ak].id === choiceId) { choiceArchetype = allA[ak]; break; } }
          if (choiceArchetype) {
            var exTa = document.getElementById('exclude_cards_textarea');
            if (exTa && exTa.value.trim()) {
              var exName = choiceArchetype.name.toLowerCase();
              var exLines = exTa.value.split(/[\n,]+/);
              for (var j = 0; j < exLines.length; j++) {
                var exLine = exLines[j].trim().replace(/^\d+[x\s]+/i, '').toLowerCase();
                if (exLine === exName) {
                  e.preventDefault();
                  e.stopImmediatePropagation();
                  _pendingConflict = { form: form, archetype: choiceArchetype };
                  document.getElementById('mc-conflict-msg').textContent =
                    '"' + choiceArchetype.name + '" is selected as your multi-copy archetype but also appears in your Exclude list. How would you like to proceed?';
                  var cdlg = document.getElementById('mc-exclude-conflict');
                  if (cdlg) cdlg.style.display = 'flex';
                  return;
                }
              }
            }
          }
        }
        return; // no conflict — let HTMX handle it
      }

      // Scan the include_cards textarea for archetype names
      var ta = document.getElementById('include_cards_textarea');
      if (!ta || !ta.value.trim()) return;
      var lines = ta.value.split(/[\n,]+/);
      var found = null;
      for (var i = 0; i < lines.length; i++){
        var key = lines[i].trim().toLowerCase();
        if (key && window._MC_ARCHETYPES[key]){ found = window._MC_ARCHETYPES[key]; break; }
      }
      if (!found) return;
      e.preventDefault();
      e.stopImmediatePropagation();
      showIncludeConfirm(form, found);
    } catch(err){ /* never block submit on errors */ }
  }, true);
})();
</script>