<div style="padding:24px 32px 24px">
<!-- ═══ EDITORIAL TILE ═══════════════════════════════════════ -->
<div class="tile" id="editorialTile">

  
    <span style="font-size:16px;color:#888" id="tileChev">∧</span>
  </div>

  <div id="tileContent">

    <!-- ── PREFERRED HANDLING EDITOR ────────────────────── -->
    <div class="block-top">
      <div class="title-form">Preferred handling editor</div>
      <div class="trigger-ae">
        <div class="ae-msg">Please select your preferred handling editor. We have pre-selected the top handling editor recommended for your manuscript. Use the 'change' button to view the full list of available editors, and modify your selection.</div>
        <button type="button" class="btn btn-outline" onclick="openModal()">
          <svg width="13" height="13" viewBox="0 0 20 20" fill="currentColor"><path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"/></svg>
          Change
        </button>
      </div>

      <div class="ae-grid" id="editorGrid">
        <?php foreach (array_slice($preferredEditors,0,6) as $e): ?>
        <div class="ae-card" data-eid="<?= $e['editor_id'] ?>">
          <div class="ae-top">
            <?php if (!empty($e['profile_photo_url'])): ?>
              <img src="<?= htmlspecialchars($e['profile_photo_url']) ?>" class="ae-photo" alt=""
                   onerror="this.style.display='none';this.nextElementSibling.style.display='flex'">
              <div class="ae-ph" style="display:none"><?= strtoupper(substr($e['name'],0,1)) ?></div>
            <?php else: ?>
              <div class="ae-ph"><?= strtoupper(substr($e['name'],0,1)) ?></div>
            <?php endif; ?>
            <div>
              <div class="ae-name"><?= htmlspecialchars($e['name']) ?></div>
              <div class="ae-loc"><?= htmlspecialchars(implode(', ', array_filter([$e['university']??'',$e['city']??'',$e['country']??'']))) ?></div>
            </div>
          </div>
          <?php if (!empty($e['loop_profile_url'])): ?>
            <a href="<?= htmlspecialchars($e['loop_profile_url']) ?>" target="_blank" class="ae-link">VIEW PROFILE</a>
          <?php else: ?>
            <span class="ae-link">VIEW PROFILE</span>
          <?php endif; ?>
        </div>
        <?php endforeach; ?>
      </div>

      <div class="info-block">
        <div class="ib-title">ℹ Handling editor selection</div>
        Avoid selecting an editor who might have a potential conflict of interest with any of the authors, or the work presented. This includes any personal (e.g. family member), professional (e.g. co-authorship or same affiliation) or financial relationships (e.g. funding or other incentives).
        <br><br>Please note that should your first choice(s) not be available, other editors on the editorial board may be invited. If the assigned editor should happen to have a conflict of interest with you or your work, please contact the editorial office
        <a href="mailto:editorial.office@communeglobalin.org">(editorial.office@communeglobalin.org)</a> providing details on the situation.
      </div>
    </div>

    <!-- ── REVIEWER COLUMNS ──────────────────────────────── -->
    <div class="block-bottom">

      <div class="col-l" id="divSuggestedRe">
        <div class="title-form">Recommend reviewers (optional)
          <span style="display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;background:#E5E7EB;color:#777;font-size:9px;font-weight:700;cursor:default;flex-shrink:0" title="You may suggest potential reviewers">i</span>
        </div>
        <fieldset>
          <ul class="rv-list" id="recList">
            <?php foreach ($recRv as $i => $rv) echo rvBlock('rec', $i, $rv, count($recRv)); ?>
          </ul>
        </fieldset>
        <fieldset>
          <div class="add-row">
            <div class="line"></div>
            <button type="button" class="btn btn-outline btn-add-rv" onclick="addRv('rec')">
              <svg width="12" height="12" viewBox="0 0 20 20" fill="currentColor"><path d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z"/></svg>
              Suggest another reviewer
            </button>
            <div class="line"></div>
          </div>
        </fieldset>
      </div>

      <div class="col-r" id="divExcludedRe">
        <div class="title-form">Suggest reviewers to exclude (optional)
          <span style="display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;background:#E5E7EB;color:#777;font-size:9px;font-weight:700;cursor:default;flex-shrink:0" title="You may recommend excluding certain reviewers">i</span>
        </div>
        <fieldset>
          <ul class="rv-list" id="exclList">
            <?php foreach ($exclRv as $i => $rv) echo rvBlock('excl', $i, $rv, count($exclRv)); ?>
          </ul>
        </fieldset>
        <fieldset>
          <div class="add-row">
            <div class="line"></div>
            <button type="button" class="btn btn-outline btn-add-rv" onclick="addRv('excl')">
              <svg width="12" height="12" viewBox="0 0 20 20" fill="currentColor"><path d="M10 3a1 1 0 011 1v5h5a1 1 0 110 2h-5v5a1 1 0 11-2 0v-5H4a1 1 0 110-2h5V4a1 1 0 011-1z"/></svg>
              Exclude reviewers
            </button>
            <div class="line"></div>
          </div>
        </fieldset>
      </div>

    </div><!-- /block-bottom -->

    <div class="info-alert">
      <a href="https://www.communeglobalin.org/about/author-guidelines" target="_blank">Author guidelines</a>
    </div>

    
    </div>
  </div><!-- /tileContent -->
</div><!-- /tile -->


<!-- ═══ CHANGE EDITOR MODAL ══════════════════════════════════ -->
<div class="modal-overlay hidden" id="modalOverlay">
  <div class="modal-box" onclick="event.stopPropagation()">
    <button class="modal-x" onclick="closeModal()">✕</button>
    <div class="modal-top">
      <div class="modal-top-title">Select Preferred Handling Editors <span style="font-weight:400;font-size:14px">(select at least 1)</span></div>
      <div id="modalSlots" class="modal-slots"></div>
    </div>
    <div class="modal-hint">
      <strong>Drag and Drop Handling Editors</strong>
      <span>from the list below to your top selection</span>
    </div>
    <div class="modal-board">
      <div class="modal-board-title">Editorial Board Members</div>
      <div class="board-grid" id="boardGrid"></div>
    </div>
    <div class="modal-footer">
      <button type="button" class="btn btn-grey" onclick="closeModal()">Cancel</button>
      <button type="button" class="btn btn-green" style="padding:9px 32px;font-size:14px" onclick="applyEditors()">Apply</button>
    </div>
  </div>
</div>

<!-- ═══ ADD AFFILIATION MINI MODAL ═══════════════════════════ -->
<div class="mini-modal hidden" id="addAffilModal">
  <div class="mini-box" onclick="event.stopPropagation()">
    <div class="mini-title">Add New Affiliation</div>
    <div class="mini-field">
      <label class="mini-label">Institution Name *</label>
      <input type="text" class="mini-input" id="newAffilName" placeholder="Full institution name">
    </div>
    <div class="mini-field">
      <label class="mini-label">Department <span style="color:var(--muted)">(optional)</span></label>
      <input type="text" class="mini-input" id="newAffilDept" placeholder="Department">
    </div>
    <div class="mini-field" style="display:grid;grid-template-columns:1fr 1fr;gap:10px">
      <div>
        <label class="mini-label">City</label>
        <input type="text" class="mini-input" id="newAffilCity" placeholder="City">
      </div>
      <div>
        <label class="mini-label">Country</label>
        <input type="text" class="mini-input" id="newAffilCountry" placeholder="Country">
      </div>
    </div>
    <div class="mini-actions">
      <button type="button" class="btn btn-grey" onclick="closeAddAffil()">Cancel</button>
      <button type="button" class="btn btn-fill" onclick="submitNewAffil()">Save &amp; Select</button>
    </div>
  </div>
</div>

<!-- ═══ CONFIRM REMOVE POPUP ════════════════════════════════ -->
<div class="confirm-overlay hidden" id="confirmOverlay">
  <div class="confirm-box">
    <button class="confirm-x" onclick="closeConfirm()">✕</button>
    <div class="confirm-msg">Are you sure you want to remove this reviewer?</div>
    <div class="confirm-acts">
      <button type="button" class="btn btn-grey" onclick="closeConfirm()">Cancel</button>
      <button type="button" class="btn btn-fill" onclick="doRemove()">Remove</button>
    </div>
  </div>
</div>

<!-- Bottom bar -->
<div class="bottom-bar">
  <div class="btm-fee">Preliminary fees: <strong><?= $fee ?> CHF</strong><br><span style="font-size:11px">Payment after acceptance</span></div>
  <div class="btm-quality">Submission quality: <strong>90%</strong> <span style="font-size:11.5px;color:var(--muted)">ℹ 1 suggested action</span></div>
  <div class="btm-actions">
    <button class="btn btn-outline">Preview</button>
    <button class="btn btn-fill">🔵 Submit</button>
  </div>
</div>


<!-- ═══ REVIEWER TEMPLATE ════════════════════════════════════ -->
<template id="tmplRv">
<li class="reviewer-block">
  <div class="rv-forms">
    <div class="rv-row rv-row-2">
      <div class="rv-field">
        <input type="email" class="rv-input rv-email" placeholder="Start by entering the email address" oninput="edt_dirty()" maxlength="150">
        <div class="rv-err" style="display:none"><span class="err-x">⊗</span> Please enter a valid email address</div>
      </div>
      <div class="rv-field">
        <div class="rv-dd" tabindex="0" onkeydown="ddKey(event,this)">
          <div class="rv-dd-face" onclick="toggleDd(this.parentElement)">
            <span class="rv-dd-val"></span>
            <span class="rv-dd-ph">Title</span>
            <span class="rv-dd-arrow">▾</span>
          </div>
          <ul class="rv-dd-list">
            <li class="rv-dd-opt" onclick="pickTitle(this,'Dr')">Dr</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'Prof')">Prof</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'Mr')">Mr</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'Mrs')">Mrs</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'Ms')">Ms</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'Miss')">Miss</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'Mx')">Mx</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'Judge')">Judge</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'MD')">MD</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'MD, PhD')">MD, PhD</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'PhD')">PhD</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'DVM')">DVM</li>
            <li class="rv-dd-opt" onclick="pickTitle(this,'DVM, PhD')">DVM, PhD</li>
          </ul>
        </div>
        <div class="rv-err" style="display:none"><span class="err-x">⊗</span> Please fill this field to continue</div>
      </div>
    </div>
    <div class="rv-row rv-row-3">
      <div class="rv-field">
        <input type="text" class="rv-input rv-fname" placeholder="First name" oninput="edt_dirty()" maxlength="150">
        <div class="rv-err" style="display:none"><span class="err-x">⊗</span> Please fill this field to continue</div>
      </div>
      <div class="rv-field">
        <input type="text" class="rv-input rv-mname" placeholder="Middle name (optional)" oninput="edt_dirty()" maxlength="50">
      </div>
      <div class="rv-field">
        <input type="text" class="rv-input rv-lname" placeholder="Last name" oninput="edt_dirty()" maxlength="150">
        <div class="rv-err" style="display:none"><span class="err-x">⊗</span> Please fill this field to continue</div>
      </div>
    </div>
    <div class="rv-row rv-row-1">
      <div class="rv-field rv-affil-wrap">
        <div class="affil-input-row">
          <input type="text" class="rv-input rv-affil-text" placeholder="Affiliation" autocomplete="off"
                 oninput="onAffilInput(this)" onfocus="onAffilFocus(this)" onblur="onAffilBlur(this)" maxlength="300">
        </div>
        <input type="hidden" class="rv-affil-id" value="">
        <div class="affil-dropdown" style="display:none">
          <div class="affil-tip">Type at least 2 characters to search</div>
          <div class="affil-spinner" style="display:none"><span class="spin"></span> Searching...</div>
          <ul class="affil-list" style="display:none"></ul>
          <div class="affil-no-result" style="display:none">
            Can't find your affiliation?
            <span class="affil-link" onclick="openAddAffil(this)">Add new</span>
            <span style="color:#ccc"> | </span>
            <span class="affil-link" onclick="noAffil(this)">No current affiliation</span>
          </div>
        </div>
        <div class="rv-err" style="display:none"><span class="err-x">⊗</span> Please select one affiliation</div>
      </div>
    </div>
    <div class="rv-row rv-row-1">
      <div class="rv-field">
        <input type="text" class="rv-input rv-dept" placeholder="Department (optional)" oninput="edt_dirty()" maxlength="300">
      </div>
    </div>
    <div class="rv-row rv-row-1">
      <div class="rv-field">
        <textarea class="rv-input rv-comment" placeholder="Additional comment (optional)" oninput="edt_dirty()" maxlength="2000"></textarea>
      </div>
    </div>
  </div>
  <div class="rv-actions">
    <button type="button" class="btn-rv move-up disabled" onclick="moveRv(this,true)" disabled>Move up</button>
    <button type="button" class="btn-rv move-down" onclick="moveRv(this,false)">Move down</button>
    <button type="button" class="btn-rv remove-rv" onclick="openConfirm(this)">
      <svg width="13" height="13" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z" clip-rule="evenodd"/></svg>
    </button>
  </div>
</li>
</template>

<script>
const SID = <?= $sid ?>;
const ALL_EDITORS = <?= json_encode(array_values($allEditors)) ?>;
let preferredIds = <?= json_encode(array_values($preferredIds)) ?>;
let modalSelIds  = [...preferredIds];
let isDirty = false, autoTimer = null;
let _pendingRemoveBtn = null;
let _pendingAffilWrap = null; // which affil wrap triggered "Add new"
let _affilTimers = new WeakMap();

/* ─── Tile toggle ───────────────────────────────── */
function toggleTile() {
  const c = document.getElementById('tileContent');
  const open = c.style.display !== 'none';
  c.style.display = open ? 'none' : '';
  document.getElementById('tileChev').textContent = open ? '∨' : '∧';
}

/* ═══════════════════════════════════════════════════
   TITLE DROPDOWN
═══════════════════════════════════════════════════ */
function toggleDd(dd) {
  const wasOpen = dd.classList.contains('open');
  closeAllDd();
  if (!wasOpen) dd.classList.add('open');
}
function closeAllDd() {
  document.querySelectorAll('.rv-dd.open').forEach(d => d.classList.remove('open'));
}
function pickTitle(li, val) {
  const dd  = li.closest('.rv-dd');
  dd.querySelector('.rv-dd-val').textContent = val;
  dd.querySelector('.rv-dd-ph').style.display = 'none';
  dd.querySelectorAll('.rv-dd-opt').forEach(o => o.classList.remove('sel'));
  li.classList.add('sel');
  dd.classList.remove('open');
  dirty();
}
function ddKey(e, dd) {
  if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggleDd(dd); }
  if (e.key === 'Escape') dd.classList.remove('open');
}
document.addEventListener('click', e => {
  if (!e.target.closest('.rv-dd')) closeAllDd();
  if (!e.target.closest('.rv-affil-wrap')) closeAffilDropdown(e.target);
});

/* ═══════════════════════════════════════════════════
   AFFILIATION TYPEAHEAD
═══════════════════════════════════════════════════ */
function onAffilInput(inp) {
  const wrap = inp.closest('.rv-affil-wrap');
  const drop = wrap.querySelector('.affil-dropdown');
  const q    = inp.value.trim();

  // Clear hidden id when user types
  wrap.querySelector('.rv-affil-id').value = '';

  // Show clear btn
  let clrBtn = wrap.querySelector('.affil-clear');
  if (!clrBtn) {
    clrBtn = document.createElement('button');
    clrBtn.type = 'button';
    clrBtn.className = 'affil-clear';
    clrBtn.textContent = '✕';
    clrBtn.onclick = () => clearAffil(clrBtn);
    inp.parentElement.appendChild(clrBtn);
  }
  clrBtn.style.display = q ? '' : 'none';

  if (q.length < 2) {
    drop.style.display = 'none';
    return;
  }
  drop.style.display = '';
  showAffilTip(wrap, 'tip');

  clearTimeout(_affilTimers.get(inp));
  _affilTimers.set(inp, setTimeout(() => searchAffil(inp, q), 300));
  dirty();
}

function onAffilFocus(inp) {
  const wrap = inp.closest('.rv-affil-wrap');
  const q = inp.value.trim();
  if (q.length >= 2) {
    wrap.querySelector('.affil-dropdown').style.display = '';
  }
}
function onAffilBlur(inp) {
  // Delay to allow click on dropdown items
  setTimeout(() => {
    const wrap = inp.closest('.rv-affil-wrap');
    if (!wrap.matches(':hover') && !wrap.querySelector('.affil-dropdown:hover')) {
      wrap.querySelector('.affil-dropdown').style.display = 'none';
    }
  }, 200);
}
function closeAffilDropdown(el) {
  document.querySelectorAll('.affil-dropdown').forEach(d => {
    if (!d.parentElement.contains(el)) d.style.display = 'none';
  });
}

function showAffilTip(wrap, which) {
  wrap.querySelector('.affil-tip').style.display    = which==='tip'    ? '' : 'none';
  wrap.querySelector('.affil-spinner').style.display= which==='spin'   ? '' : 'none';
  wrap.querySelector('.affil-list').style.display   = which==='list'   ? '' : 'none';
  wrap.querySelector('.affil-no-result').style.display = which==='none' ? '' : 'none';
}

function searchAffil(inp, q) {
  const wrap = inp.closest('.rv-affil-wrap');
  showAffilTip(wrap, 'spin');
  fetch('ajax/search_affiliations_rv.php?q=' + encodeURIComponent(q))
    .then(r => r.json())
    .then(d => {
      const list = wrap.querySelector('.affil-list');
      list.innerHTML = '';
      if (!d.results || !d.results.length) {
        showAffilTip(wrap, 'none');
        return;
      }
      showAffilTip(wrap, 'list');
      d.results.forEach(a => {
        const li = document.createElement('li');
        li.className = 'affil-item';
        const sub = [a.department, a.city, a.country].filter(Boolean).join(', ');
        const badge = a.is_institutional_partner == 1
          ? '<span class="affil-partner">✓ Partner</span>' : '';
        li.innerHTML = `<div class="affil-item-name">${xe(a.name)}${badge}</div>`
          + (sub ? `<div class="affil-item-sub">${xe(sub)}</div>` : '');
        li.addEventListener('mousedown', e => {
          e.preventDefault();
          selectAffil(wrap, a.affiliation_id, a.name, a.department);
        });
        list.appendChild(li);
      });
    })
    .catch(() => showAffilTip(wrap, 'none'));
}

function selectAffil(wrap, id, name, dept) {
  const inp = wrap.querySelector('.rv-affil-text');
  const hiddenId = wrap.querySelector('.rv-affil-id');
  inp.value = name;
  hiddenId.value = id;
  // Auto-fill department if empty
  const deptInp = wrap.closest('.rv-forms')?.querySelector('.rv-dept');
  if (deptInp && !deptInp.value && dept) deptInp.value = dept;
  wrap.querySelector('.affil-dropdown').style.display = 'none';
  // Show/update clear button
  let clr = wrap.querySelector('.affil-clear');
  if (!clr) {
    clr = document.createElement('button');
    clr.type='button'; clr.className='affil-clear'; clr.textContent='✕';
    clr.onclick = () => clearAffil(clr);
    inp.parentElement.appendChild(clr);
  }
  clr.style.display = '';
  // Hide error
  const err = wrap.querySelector('.rv-err');
  if (err) err.style.display = 'none';
  dirty();
}

function clearAffil(btn) {
  const wrap = btn.closest('.rv-affil-wrap');
  wrap.querySelector('.rv-affil-text').value = '';
  wrap.querySelector('.rv-affil-id').value   = '';
  wrap.querySelector('.affil-dropdown').style.display = 'none';
  btn.style.display = 'none';
  dirty();
}

function noAffil(span) {
  const wrap = span.closest('.rv-affil-wrap');
  selectAffil(wrap, 0, 'No current affiliation', '');
}

/* ─── "Add new affiliation" mini modal ─────────── */
function openAddAffil(span) {
  _pendingAffilWrap = span.closest('.rv-affil-wrap');
  document.getElementById('newAffilName').value    = _pendingAffilWrap.querySelector('.rv-affil-text').value.trim();
  document.getElementById('newAffilDept').value    = '';
  document.getElementById('newAffilCity').value    = '';
  document.getElementById('newAffilCountry').value = '';
  document.getElementById('addAffilModal').classList.remove('hidden');
}
function closeAddAffil() {
  document.getElementById('addAffilModal').classList.add('hidden');
  _pendingAffilWrap = null;
}
function submitNewAffil() {
  const name = document.getElementById('newAffilName').value.trim();
  if (!name) { toast('Please enter institution name','e'); return; }
  const payload = {
    name, department: document.getElementById('newAffilDept').value.trim(),
    city: document.getElementById('newAffilCity').value.trim(),
    country: document.getElementById('newAffilCountry').value.trim(),
  };
  fetch('ajax/create_affiliation.php', {
    method:'POST', headers:{'Content-Type':'application/json'},
    body: JSON.stringify(payload)
  }).then(r=>r.json()).then(d => {
    if (d.success) {
      if (_pendingAffilWrap) selectAffil(_pendingAffilWrap, d.affiliation_id, d.name, '');
      toast('Affiliation added!','s');
      closeAddAffil();
    } else toast(d.message||'Error saving','e');
  }).catch(() => toast('Network error','e'));
}

/* ═══════════════════════════════════════════════════
   MODAL — editor selection
═══════════════════════════════════════════════════ */
function openModal() {
  modalSelIds = [...preferredIds];
  renderModal();
  document.getElementById('modalOverlay').classList.remove('hidden');
  document.body.style.overflow = 'hidden';
}
function closeModal() {
  document.getElementById('modalOverlay').classList.add('hidden');
  document.body.style.overflow = '';
}
document.getElementById('modalOverlay').addEventListener('click', function(e){
  if (e.target===this) closeModal();
});

function renderModal() { renderSlots(); renderBoard(); }

function renderSlots() {
  const wrap = document.getElementById('modalSlots');
  wrap.innerHTML = '';
  const total = Math.min(6, Math.max(3, modalSelIds.length + 1));
  for (let i = 0; i < total; i++) {
    const eid = modalSelIds[i];
    const e   = eid ? ALL_EDITORS.find(x => +x.editor_id === +eid) : null;
    wrap.appendChild(e ? makeSelCard(e, i) : makeEmptySlot(i));
  }
}

function makeSelCard(e, slotIdx) {
  const div = document.createElement('div');
  div.className = 'sel-card';
  div.draggable = true;
  div.dataset.eid  = e.editor_id;
  div.dataset.slot = slotIdx;
  const ph = e.profile_photo_url
    ? `<img src="${xe(e.profile_photo_url)}" class="sel-photo" onerror="this.outerHTML='<div class=sel-ph>${edt_xe((e.name||'?')[0].toUpperCase())}</div>'">`
    : `<div class="sel-ph">${xe((e.name||'?')[0].toUpperCase())}</div>`;
  const link = e.loop_profile_url
    ? `<a href="${xe(e.loop_profile_url)}" target="_blank" class="sel-view" onclick="event.stopPropagation()">VIEW PROFILE</a>`
    : '<span class="sel-view">VIEW PROFILE</span>';
  div.innerHTML = `
    <button class="sel-dismiss" onclick="removeFromTop(${e.editor_id})" type="button">✕</button>
    <div class="sel-check">✓</div>
    ${ph}
    <div class="sel-name">${xe(e.name)}</div>
    <div class="sel-loc">${xe([e.city,e.country].filter(Boolean).join(', '))}</div>
    ${link}`;
  div.addEventListener('dragstart', ev => {
    ev.dataTransfer.setData('eid',e.editor_id); ev.dataTransfer.setData('from','top'); ev.dataTransfer.setData('slot',slotIdx);
    ev.dataTransfer.effectAllowed = 'move';
    setTimeout(() => div.classList.add('drag-src'), 0);
  });
  div.addEventListener('dragend', () => div.classList.remove('drag-src'));
  div.addEventListener('dragover', ev => { ev.preventDefault(); div.classList.add('drag-over'); });
  div.addEventListener('dragleave', () => div.classList.remove('drag-over'));
  div.addEventListener('drop', ev => {
    ev.preventDefault(); ev.stopPropagation(); div.classList.remove('drag-over');
    const eid = +ev.dataTransfer.getData('eid'), from = ev.dataTransfer.getData('from'), slot = +ev.dataTransfer.getData('slot');
    if (!eid || eid===+e.editor_id) return;
    if (from==='top') { [modalSelIds[slot],modalSelIds[slotIdx]]=[modalSelIds[slotIdx],modalSelIds[slot]]; }
    else { modalSelIds=modalSelIds.filter(id=>+id!==eid); modalSelIds.splice(slotIdx,0,eid); }
    renderModal();
  });
  return div;
}

function makeEmptySlot(i) {
  const div = document.createElement('div');
  div.className = 'empty-slot'; div.dataset.slot = i;
  div.addEventListener('dragover', ev => { ev.preventDefault(); div.classList.add('drag-over'); });
  div.addEventListener('dragleave', () => div.classList.remove('drag-over'));
  div.addEventListener('drop', ev => {
    ev.preventDefault(); div.classList.remove('drag-over');
    const eid = +ev.dataTransfer.getData('eid'), from = ev.dataTransfer.getData('from'), slot = +ev.dataTransfer.getData('slot');
    if (!eid) return;
    if (from==='top') { modalSelIds=modalSelIds.filter(id=>+id!==eid); modalSelIds.splice(i,0,eid); }
    else if (!modalSelIds.some(id=>+id===eid)) modalSelIds.push(eid);
    renderModal();
  });
  return div;
}

function renderBoard() {
  const grid = document.getElementById('boardGrid');
  grid.innerHTML = '';
  ALL_EDITORS.forEach(e => {
    const inTop = modalSelIds.some(id=>+id===+e.editor_id);
    const card = document.createElement('div');
    card.className = 'board-card' + (inTop?' in-top':'');
    card.dataset.eid = e.editor_id;
    card.draggable = !inTop;
    const ph = e.profile_photo_url
      ? `<img src="${xe(e.profile_photo_url)}" class="board-photo" onerror="this.outerHTML='<div class=board-ph>${(e.name||'?')[0].toUpperCase()}</div>'">`
      : `<div class="board-ph">${(e.name||'?')[0].toUpperCase()}</div>`;
    const badge = e.is_editorial_board ? `<div class="board-badge">✓ Editorial Board</div>` : '';
    const link  = e.loop_profile_url
      ? `<a href="${xe(e.loop_profile_url)}" target="_blank" class="board-view" onclick="event.stopPropagation()">VIEW PROFILE</a>`
      : `<span class="board-view">VIEW PROFILE</span>`;
    card.innerHTML = `${ph}<div class="board-info"><div class="board-name">${xe(e.name)}</div><div class="board-loc">${xe([e.university,e.city,e.country].filter(Boolean).join(', '))}</div>${badge}${link}</div>`;
    if (!inTop) {
      card.onclick = () => addToTop(+e.editor_id);
      card.addEventListener('dragstart', ev => {
        ev.dataTransfer.setData('eid',e.editor_id); ev.dataTransfer.setData('from','board'); ev.dataTransfer.setData('slot','');
        ev.dataTransfer.effectAllowed='copy'; setTimeout(()=>card.style.opacity='.45',0);
      });
      card.addEventListener('dragend', ()=>card.style.opacity='');
    }
    grid.appendChild(card);
  });
}

function addToTop(eid) {
  if (modalSelIds.some(id=>+id===eid)) return;
  if (modalSelIds.length>=6) { toast('Maximum 6 editors','e'); return; }
  modalSelIds.push(eid); renderModal();
}
function removeFromTop(eid) { modalSelIds=modalSelIds.filter(id=>+id!==+eid); renderModal(); }
function applyEditors() {
  if (!modalSelIds.length) { toast('Select at least 1 editor','e'); return; }
  preferredIds=[...modalSelIds]; rebuildAeGrid(); closeModal(); dirty(); toast('Editor selection updated','s');
}

function rebuildAeGrid() {
  const grid=document.getElementById('editorGrid'); grid.innerHTML='';
  preferredIds.slice(0,6).forEach(eid=>{
    const e=ALL_EDITORS.find(x=>+x.editor_id===+eid); if(!e) return;
    const ph=e.profile_photo_url
      ?`<img src="${xe(e.profile_photo_url)}" class="ae-photo" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'"><div class="ae-ph" style="display:none">${(e.name||'?')[0].toUpperCase()}</div>`
      :`<div class="ae-ph">${(e.name||'?')[0].toUpperCase()}</div>`;
    const link=e.loop_profile_url?`<a href="${xe(e.loop_profile_url)}" target="_blank" class="ae-link">VIEW PROFILE</a>`:`<span class="ae-link">VIEW PROFILE</span>`;
    const card=document.createElement('div'); card.className='ae-card'; card.dataset.eid=e.editor_id;
    card.innerHTML=`<div class="ae-top">${ph}<div><div class="ae-name">${xe(e.name)}</div><div class="ae-loc">${xe([e.university,e.city,e.country].filter(Boolean).join(', '))}</div></div></div>${link}`;
    grid.appendChild(card);
  });
}

/* ═══════════════════════════════════════════════════
   REVIEWER: ADD / MOVE / REMOVE
═══════════════════════════════════════════════════ */
function addRv(type) {
  const list  = document.getElementById(type==='rec'?'recList':'exclList');
  const tmpl  = document.getElementById('tmplRv');
  const clone = tmpl.content.cloneNode(true);
  list.appendChild(clone);
  refreshBtns(type);
  const newLi = list.lastElementChild;
  newLi.scrollIntoView({behavior:'smooth',block:'nearest'});
  newLi.querySelector('.rv-email')?.focus();
  dirty();
}

function moveRv(btn, up) {
  const li    = btn.closest('.reviewer-block');
  const list  = li.parentElement;
  const items = Array.from(list.children);
  const idx   = items.indexOf(li);
  const tgt   = up ? idx-1 : idx+1;
  if (tgt<0||tgt>=items.length) return;
  if (up) list.insertBefore(li, items[tgt]);
  else    list.insertBefore(items[tgt], li);
  refreshBtns(list.id==='recList'?'rec':'excl');
  dirty();
}

function refreshBtns(type) {
  const list  = document.getElementById(type==='rec'?'recList':'exclList');
  const items = Array.from(list.children);
  items.forEach((li, i) => {
    const up = li.querySelector('.move-up');
    const dn = li.querySelector('.move-down');
    if (up) { up.disabled = i===0;               up.classList.toggle('disabled', i===0); }
    if (dn) { dn.disabled = i===items.length-1;  dn.classList.toggle('disabled', i===items.length-1); }
    if (up) up.onclick = () => moveRv(up, true);
    if (dn) dn.onclick = () => moveRv(dn, false);
    if (li.querySelector('.remove-rv')) li.querySelector('.remove-rv').onclick = () => openConfirm(li.querySelector('.remove-rv'));
  });
}

function openConfirm(btn) {
  const list = btn.closest('ul');
  if (list.children.length <= 1) { toast('At least one form must remain','e'); return; }
  _pendingRemoveBtn = btn;
  document.getElementById('confirmOverlay').classList.remove('hidden');
}
function closeConfirm() { document.getElementById('confirmOverlay').classList.add('hidden'); _pendingRemoveBtn=null; }
function doRemove() {
  if (!_pendingRemoveBtn) return;
  const li   = _pendingRemoveBtn.closest('.reviewer-block');
  const list = li.parentElement;
  const type = list.id==='recList'?'rec':'excl';
  li.remove(); refreshBtns(type); dirty(); closeConfirm();
}

/* ═══════════════════════════════════════════════════
   DIRTY + SAVE
═══════════════════════════════════════════════════ */
function dirty() {
  isDirty = true; clearTimeout(autoTimer);
  autoTimer = setTimeout(()=>doSave(false,true), 2000);
}
const rvDirty = dirty; // alias used in reviewer form oninput
function collectList(listId, type) {
  return Array.from(document.getElementById(listId).children).map((li,i) => ({
    reviewer_type      : type,
    email              : li.querySelector('.rv-email')?.value.trim()   || '',
    title              : li.querySelector('.rv-dd-val')?.textContent.trim() || '',
    first_name         : li.querySelector('.rv-fname')?.value.trim()   || '',
    middle_name        : li.querySelector('.rv-mname')?.value.trim()   || '',
    last_name          : li.querySelector('.rv-lname')?.value.trim()   || '',
    affiliation_id     : +(li.querySelector('.rv-affil-id')?.value)    || 0,
    affiliation_name   : li.querySelector('.rv-affil-text')?.value.trim() || '',
    department         : li.querySelector('.rv-dept')?.value.trim()    || '',
    additional_comment : li.querySelector('.rv-comment')?.value.trim() || '',
    display_order      : i+1,
  }));
}
function validateAndShowErrors() {
  let hasError = false;
  document.querySelectorAll('.reviewer-block').forEach(li => {
    const email = li.querySelector('.rv-email');
    const fname = li.querySelector('.rv-fname');
    const lname = li.querySelector('.rv-lname');
    const affil = li.querySelector('.rv-affil-text');

    // Only validate if any field has been touched (email or name filled)
    const anyFilled = (email?.value.trim()||fname?.value.trim()||lname?.value.trim());
    if (!anyFilled) return; // Skip completely empty forms

    const emailErr = email?.closest('.rv-field')?.querySelector('.rv-err');
    const fnErr    = fname?.closest('.rv-field')?.querySelector('.rv-err');
    const lnErr    = lname?.closest('.rv-field')?.querySelector('.rv-err');
    const afErr    = affil?.closest('.rv-field')?.querySelector('.rv-err');

    if (email && email.value.trim() && !/\S+@\S+\.\S+/.test(email.value.trim())) {
      if (emailErr) emailErr.classList.add('show'); hasError = true;
    } else if (emailErr) emailErr.classList.remove('show');

    if (fname && !fname.value.trim()) {
      if (fnErr) fnErr.classList.add('show'); hasError = true;
    } else if (fnErr) fnErr.classList.remove('show');

    if (lname && !lname.value.trim()) {
      if (lnErr) lnErr.classList.add('show'); hasError = true;
    } else if (lnErr) lnErr.classList.remove('show');

    if (affil && affil.value.trim() && !li.querySelector('.rv-affil-id')?.value) {
      if (afErr) afErr.classList.add('show'); hasError = true;
    } else if (afErr) afErr.classList.remove('show');
  });
  return !hasError;
}

function doSave(cont=false, silent=false) {
  if (!silent && !validateAndShowErrors()) {
    toast('Please fix the errors before saving','e');
    return;
  }
  const fd = new FormData();
  fd.append('submission_id', SID);
  fd.append('data', JSON.stringify({
    preferred_editor_ids: preferredIds,
    suggested_editors: preferredIds.map((eid, i) => {
      const e = ALL_EDITORS.find(x => +x.editor_id === +eid);
      if (!e) return null;
      return {
        editor_id    : e.editor_id,
        name         : e.name,
        institution  : e.university || '',
        expertise    : e.expertise_areas || '',
        display_order: i + 1,
      };
    }).filter(Boolean),
    reviewers: [...collectList('recList','recommended'), ...collectList('exclList','excluded')],
  }));
  if (!silent) {
    ['saveBtn','saveContinueBtn'].forEach(id => {
      document.getElementById(id).disabled=true;
      document.getElementById(id).innerHTML='<span class="spin" style="border-top-color:#fff;border-color:rgba(255,255,255,.3)"></span>';
    });
  }
  fetch('ajax/save_editorial.php', {method:'POST',body:fd})
    .then(r=>r.json()).then(d => {
      isDirty=false;
      if (!silent) {
        document.getElementById('saveBtn').disabled=false; document.getElementById('saveBtn').textContent='Save';
        document.getElementById('saveContinueBtn').disabled=false; document.getElementById('saveContinueBtn').innerHTML='Save &amp; Continue';
      }
      if (d.success) { if (!silent) toast('Saved!','s'); if (cont&&!silent) setTimeout(()=>location.href='statements.php?id='+SID,700); }
      else if (!silent) toast(d.message||'Save failed','e');
    })
    .catch(()=>{ if(!silent){document.getElementById('saveBtn').disabled=false;document.getElementById('saveBtn').textContent='Save';document.getElementById('saveContinueBtn').disabled=false;document.getElementById('saveContinueBtn').innerHTML='Save &amp; Continue';toast('Network error','e');}});
}

/* ─── Utils ─────────────────────────────────────── */
function toast(msg,type='i'){const w=document.getElementById('toastWrap');const t=document.createElement('div');t.className='toast t'+type;t.innerHTML=(type==='s'?'✅':type==='e'?'❌':'ℹ️')+' '+xe(msg);w.appendChild(t);setTimeout(()=>t.remove(),3500);}
function xe(s){return String(s||'').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');}

// Init
refreshBtns('rec'); refreshBtns('excl');
window.addEventListener('beforeunload',e=>{if(isDirty){e.preventDefault();e.returnValue='';}});
</script>
</div>