<div style="padding:24px 32px 24px">
<!-- ═══════════════════════ TOPBAR ═══════════════════════════ -->


<!-- ══════════════════ MAIN PAGE CONTENT ════════════════════ -->
<div class="page-wrap">

  <!-- Breadcrumb -->
  

  <div class="page-header">
    <h1 class="page-title">📄 Manuscript Information</h1>
    <p class="page-subtitle">Provide your article title, abstract, and keywords for your submission</p>
  </div>

  <!-- Progress Bar -->
  
    </div>
    <span class="progress-pct" id="progressPct"><?= $score ?>%</span>
    <span class="save-indicator" id="saveIndicator">
      <span class="save-dot"></span> Saved
    </span>
  </div>

  <div class="main-grid">

    <!-- ════ LEFT — FORM ════ -->
    <div>
      <form id="manuscriptForm" novalidate>
        <input type="hidden" id="submissionId" value="<?= $submission_id ?>">
        <input type="hidden" id="manuscriptId" value="<?= $minfo['manuscript_id'] ?? '' ?>">

        <!-- SECTION 1: Journal context mini card -->
        <div class="journal-mini">
          <div class="journal-mini-icon">📚</div>
          <div>
            <div class="journal-mini-name">
              <?= htmlspecialchars('communeglobal in ' . ($submission['journal_name'] ?? '')) ?>
            </div>
            <div class="journal-mini-spec">
              <?= htmlspecialchars($submission['specialty_name'] ?? '') ?>
              <?php if ($submission['article_type_name']): ?>
                · <?= htmlspecialchars($submission['article_type_name']) ?>
              <?php endif; ?>
            </div>
          </div>
        </div>

        <!-- ═══ CARD 1: Article Title ═══ -->
        <div class="card">
          <div class="card-header">
            <span class="card-title">✏️ Article Title</span>
            <span class="card-badge <?= $titleFilled ? 'badge-complete' : 'badge-incomplete' ?>" id="titleBadge">
              <?= $titleFilled ? '✓ Completed' : '⚠ Incomplete' ?>
            </span>
          </div>
          <div class="card-body">

            <!-- Article Title -->
            <div class="form-group">
              <label class="form-label" for="articleTitle">
                Article Title
                <span class="info-icon" title="Enter the full title of your article. Avoid abbreviations.">i</span>
              </label>
              <input type="text" class="form-input" id="articleTitle"
                     placeholder="Enter the full title of your article..."
                     maxlength="1000"
                     value="<?= htmlspecialchars($minfo['article_title'] ?? '') ?>"
                     oninput="onTitleInput(this)">
              <div class="char-counter" id="titleCounter">
                <span id="titleCount"><?= mb_strlen($minfo['article_title'] ?? '') ?></span>/1000 characters
              </div>
              <div class="form-hint">Avoid abbreviations and formulae where possible. The title should be clear and concise.</div>
            </div>

            <!-- Running Title -->
            <div class="form-group" style="margin-bottom:0">
              <label class="form-label" for="runningTitle">
                Running Title
                <span class="optional">(optional)</span>
                <span class="info-icon" title="A short version of the title, max 5 words, used in headers/footers">i</span>
              </label>
              <input type="text" class="form-input" id="runningTitle"
                     placeholder="Short title, max 5 words..."
                     maxlength="255"
                     value="<?= htmlspecialchars($minfo['running_title'] ?? '') ?>"
                     oninput="onRunningTitleInput(this)">
              <div class="word-counter" id="runningTitleWords">
                <span id="runningTitleWordCount"><?= str_word_count($minfo['running_title'] ?? '') ?></span>/5 words recommended
              </div>
            </div>

          </div><!-- /card-body -->
        </div><!-- /card -->

        <!-- ═══ CARD 2: Abstract ═══ -->
        <div class="card">
          <div class="card-header">
            <span class="card-title">📝 Abstract</span>
            <span class="card-badge <?= $abstractFilled ? 'badge-complete' : 'badge-incomplete' ?>" id="abstractBadge">
              <?= $abstractFilled ? '✓ Completed' : '⚠ Incomplete' ?>
            </span>
          </div>
          <div class="card-body">
            <div class="form-group" style="margin-bottom:0">
              <label class="form-label" for="abstract">
                Abstract
                <span class="info-icon" title="Plain text abstract only. No HTML, no references, no footnotes.">i</span>
              </label>
              <textarea class="form-textarea" id="abstract"
                        placeholder="Write a concise summary of your research. Plain text only — no formatting, references, or footnotes..."
                        rows="8"
                        oninput="onAbstractInput(this)"><?= htmlspecialchars($minfo['abstract'] ?? '') ?></textarea>
              <div class="abstract-limit-bar">
                <div class="abstract-limit-fill" id="abstractBar" style="width:0%"></div>
              </div>
              <div style="display:flex;justify-content:space-between;align-items:center;margin-top:5px">
                <div class="form-hint">Plain text only. No HTML tags, references, or footnotes.</div>
                <div class="char-counter" id="abstractCounter">
                  <span id="abstractCount"><?= mb_strlen($minfo['abstract'] ?? '') ?></span> characters
                  <?php if ($submission['summary_length']): ?>
                    · <span id="abstractWordCount">0</span>/<?= $submission['summary_length'] ?> words
                  <?php endif; ?>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- ═══ CARD 3: Keywords ═══ -->
        <div class="card">
          <div class="card-header">
            <span class="card-title">🏷️ Keywords</span>
            <span class="card-badge <?= $kwValid ? 'badge-complete' : 'badge-incomplete' ?>" id="kwBadge">
              <?= $kwValid ? '✓ Completed' : '⚠ Incomplete' ?>
            </span>
          </div>
          <div class="card-body">
            <div class="form-group" style="margin-bottom:0">
              <label class="form-label">
                Keywords
                <span class="info-icon" title="Minimum 5, maximum 8 keywords. Type to search existing or press Enter to add new.">i</span>
              </label>

              <!-- Keyword tag input -->
              <div class="kw-wrap-outer">
                <div class="kw-wrap" id="kwWrap" onclick="focusKwInput()">
                  <!-- Existing tags -->
                  <?php foreach ($existingKeywords as $kw): ?>
                  <span class="kw-tag" data-id="<?= $kw['keyword_id'] ?>" data-keyword="<?= htmlspecialchars($kw['keyword']) ?>">
                    <?= htmlspecialchars($kw['keyword']) ?>
                    <button type="button" class="kw-tag-remove" onclick="removeKeyword(<?= $kw['keyword_id'] ?>,this)" title="Remove">×</button>
                  </span>
                  <?php endforeach; ?>
                  <input type="text" class="kw-input" id="kwInput"
                         placeholder="<?= count($existingKeywords) === 0 ? 'Type to search keywords...' : '' ?>"
                         autocomplete="off"
                         oninput="onKwInput(this)"
                         onkeydown="onKwKeydown(event)">
                </div>
                <!-- Dropdown -->
                <div class="kw-dropdown" id="kwDropdown" style="display:none"></div>
              </div>

              <!-- Count status -->
              <div class="kw-count <?= $kwValid ? 'kw-ok' : ($kwCount > 0 ? 'kw-warn' : '') ?>" id="kwCount">
                <?php
                  $kwMsg = match(true) {
                      $kwCount === 0  => 'Add at least 5 keywords (minimum 5, maximum 8)',
                      $kwCount < 5    => $kwCount . '/5 added — need ' . (5 - $kwCount) . ' more',
                      $kwCount <= 8   => '✓ ' . $kwCount . ' keywords added',
                      default         => $kwCount . ' keywords — maximum is 8, please remove ' . ($kwCount - 8),
                  };
                  echo $kwMsg;
                ?>
              </div>
              <div class="form-hint" style="margin-top:6px">
                Search existing keywords or press <strong>Enter</strong> to create a new one.
                Min 5, max 8 keywords per submission.
              </div>
            </div>
          </div>
        </div>

        <!-- Form Actions -->
        <div class="form-actions">
          <a href="submission.php?id=<?= $submission_id ?>" class="btn btn-back">
            ← Back
          </a>
          <button type="button" class="btn btn-outline" onclick="saveManuscript(false)" id="saveBtn">
            💾 Save
          </button>
          <button type="button" class="btn btn-primary" onclick="saveManuscript(true)" id="saveContinueBtn">
            Save &amp; Continue →
          </button>
        </div>

      </form>
    </div><!-- /left -->

    <!-- ════ RIGHT — SIDEBAR ════ -->
    <div>

      <!-- Guidelines -->
      <div class="sidebar-card">
        <div class="sidebar-title">📋 Writing Tips</div>
        <div style="font-size:12.5px;color:var(--text-muted);line-height:1.8">
          <div style="margin-bottom:10px">
            <strong style="color:var(--text)">Title</strong><br>
            Clear, specific, and free of abbreviations. Max 1000 characters.
          </div>
          <div style="margin-bottom:10px">
            <strong style="color:var(--text)">Running Title</strong><br>
            Short version for headers. Keep under 5 words.
          </div>
          <div style="margin-bottom:10px">
            <strong style="color:var(--text)">Abstract</strong><br>
            Plain text only. No HTML, no references.
            <?php if ($submission['summary_length']): ?>
              Max <?= $submission['summary_length'] ?> words for this article type.
            <?php endif; ?>
          </div>
          <div>
            <strong style="color:var(--text)">Keywords</strong><br>
            Min 5, max 8. Choose terms that best describe your research topic.
          </div>
        </div>
      </div>

      <!-- Submission Steps -->
      <div class="sidebar-card">
        <div class="sidebar-title">📋 Submission Steps</div>
        <ul class="steps-list">
          <?php
          $steps = [
            ['Submission details',    'done',   'Done',        'submission.php?id='.$submission_id],
            ['Manuscript information','active', 'Active',      '#'],
            ['Related articles',      'pending','To complete', '#'],
            ['Authors & contributors','pending','To complete', '#'],
            ['Editorial',             'pending','To complete', '#'],
            ['Statements',            'pending','To complete', '#'],
            ['Payment',               'pending','To complete', '#'],
          ];
          foreach ($steps as $i => [$sname,$sstate,$sstatus,$slink]):
          ?>
          <li>
            <span class="step-num step-<?= $sstate ?>"><?= $sstate === 'done' ? '✓' : $i+1 ?></span>
            <?php if ($sstate !== 'pending'): ?>
              <a href="<?= $slink ?>" class="step-name" style="color:var(--<?= $sstate==='done'?'success':'primary' ?>);text-decoration:none;font-weight:600"><?= $sname ?></a>
            <?php else: ?>
              <span class="step-name"><?= $sname ?></span>
            <?php endif; ?>
            <span class="step-status step-status-<?= $sstate ?>"><?= $sstatus ?></span>
          </li>
          <?php endforeach; ?>
        </ul>
      </div>

      <!-- Author Guidelines -->
      <div class="sidebar-card" style="text-align:center">
        <div style="font-size:32px;margin-bottom:8px">📖</div>
        <a href="#" style="color:var(--primary);font-weight:700;font-size:13px;text-decoration:none">
          Author Guidelines ↗
        </a>
        <p style="font-size:12px;color:var(--text-muted);margin-top:4px">Read before submitting your manuscript</p>
      </div>

    </div><!-- /sidebar -->
  </div><!-- /main-grid -->
</div><!-- /page-wrap -->

<!-- Toast container -->
<div class="toast-container" id="toastContainer"></div>

<script>
/* ════════════════════════════════════════════════════════════
   STATE
════════════════════════════════════════════════════════════ */
const SUBMISSION_ID   = <?= $submission_id ?>;
const MAX_WORD_LIMIT  = <?= $submission['summary_length'] ?: 'null' ?>;
let autoSaveTimer     = null;
let kwDebounceTimer   = null;
let dropdownActive    = 0; // active dropdown item index

// Current keywords array (synced with DOM tags)
let keywords = <?= json_encode(array_map(fn($k) => ['id' => (int)$k['keyword_id'], 'keyword' => $k['keyword']], $existingKeywords)) ?>;

/* ════════════════════════════════════════════════════════════
   TITLE
════════════════════════════════════════════════════════════ */
function onTitleInput(el) {
    const len = el.value.length;
    const counter = document.getElementById('titleCounter');
    const count   = document.getElementById('titleCount');
    count.textContent = len;
    counter.className = 'char-counter' + (len > 950 ? ' warn' : '') + (len >= 1000 ? ' over' : '');
    updateTitleBadge();
    scheduleAutoSave();
}

function updateTitleBadge() {
    const filled = document.getElementById('articleTitle').value.trim().length > 0;
    const badge  = document.getElementById('titleBadge');
    badge.textContent  = filled ? '✓ Completed' : '⚠ Incomplete';
    badge.className = 'card-badge ' + (filled ? 'badge-complete' : 'badge-incomplete');
}

function onRunningTitleInput(el) {
    const words = el.value.trim() ? el.value.trim().split(/\s+/).length : 0;
    const wc = document.getElementById('runningTitleWordCount');
    wc.textContent = words;
    wc.parentElement.className = 'word-counter' + (words > 5 ? ' warn' : '');
    scheduleAutoSave();
}

/* ════════════════════════════════════════════════════════════
   ABSTRACT
════════════════════════════════════════════════════════════ */
function onAbstractInput(el) {
    const len   = el.value.length;
    const words = el.value.trim() ? el.value.trim().split(/\s+/).length : 0;

    document.getElementById('abstractCount').textContent = len;
    const wcEl = document.getElementById('abstractWordCount');
    if (wcEl) wcEl.textContent = words;

    // Progress bar (word limit or char limit 3000)
    const limit = MAX_WORD_LIMIT || 600;
    const pct   = Math.min(100, Math.round((words / limit) * 100));
    const bar   = document.getElementById('abstractBar');
    bar.style.width = pct + '%';
    bar.style.background = pct >= 100
        ? 'var(--error)'
        : pct >= 90
        ? 'var(--warning)'
        : 'var(--success)';

    // Badge
    const filled = el.value.trim().length > 50;
    const badge  = document.getElementById('abstractBadge');
    badge.textContent = filled ? '✓ Completed' : '⚠ Incomplete';
    badge.className = 'card-badge ' + (filled ? 'badge-complete' : 'badge-incomplete');

    scheduleAutoSave();
}

// Init abstract bar on load
(function initAbstract() {
    const el = document.getElementById('abstract');
    if (el && el.value) onAbstractInput(el);
})();

/* ════════════════════════════════════════════════════════════
   KEYWORDS
════════════════════════════════════════════════════════════ */
function focusKwInput() {
    document.getElementById('kwInput').focus();
}

function onKwInput(el) {
    clearTimeout(kwDebounceTimer);
    const q = el.value.trim();

    if (!q) {
        closeKwDropdown();
        return;
    }

    kwDebounceTimer = setTimeout(() => searchKeywords(q), 280);
}

function searchKeywords(q) {
    fetch('ajax/search_keywords.php?q=' + encodeURIComponent(q))
    .then(r => r.json())
    .then(data => {
        if (!data.success) return;
        renderKwDropdown(q, data.keywords);
    })
    .catch(() => closeKwDropdown());
}

function renderKwDropdown(q, results) {
    const dd = document.getElementById('kwDropdown');
    const existingIds = keywords.map(k => k.id);

    // Filter out already-added keywords
    const filtered = results.filter(k => !existingIds.includes(k.keyword_id));

    let html = '';
    filtered.forEach((k, i) => {
        html += `<div class="kw-dropdown-item" data-id="${k.keyword_id}" data-kw="${escHtml(k.keyword)}"
                      onclick="addKeywordById(${k.keyword_id}, '${man_escAttr(k.keyword)}')"
                      onmouseover="setDropdownActive(${i})">
                   <span>${escHtml(highlightMatch(k.keyword, q))}</span>
                   <span class="kw-add-hint">+ Add</span>
                 </div>`;
    });

    // "Create new" option — only if not exact match
    const exactMatch = results.find(k => k.keyword.toLowerCase() === q.toLowerCase());
    if (!exactMatch && keywords.length < 8) {
        html += `<div class="kw-dropdown-create"
                      onclick="createAndAddKeyword('${man_escAttr(q)}')">
                   ✚ Create new keyword: "<strong>${escHtml(q)}</strong>"
                 </div>`;
    }

    if (!html) {
        html = `<div class="kw-dropdown-item" style="color:var(--text-muted);cursor:default">No results for "${escHtml(q)}"</div>`;
        if (keywords.length < 8) {
            html += `<div class="kw-dropdown-create"
                          onclick="createAndAddKeyword('${man_escAttr(q)}')">
                       ✚ Create new keyword: "<strong>${escHtml(q)}</strong>"
                     </div>`;
        }
    }

    dd.innerHTML = html;
    dd.style.display = 'block';
    dropdownActive = -1;
}

function setDropdownActive(i) {
    dropdownActive = i;
    document.querySelectorAll('.kw-dropdown-item').forEach((el, idx) => {
        el.classList.toggle('active', idx === i);
    });
}

function closeKwDropdown() {
    document.getElementById('kwDropdown').style.display = 'none';
    document.getElementById('kwInput').value = '';
}

function onKwKeydown(e) {
    const dd = document.getElementById('kwDropdown');
    const items = dd.querySelectorAll('.kw-dropdown-item');
    const input = document.getElementById('kwInput');

    if (e.key === 'Enter') {
        e.preventDefault();
        const q = input.value.trim();
        if (!q) return;
        if (dropdownActive >= 0 && items[dropdownActive]) {
            items[dropdownActive].click();
        } else {
            createAndAddKeyword(q);
        }
    } else if (e.key === 'ArrowDown') {
        e.preventDefault();
        setDropdownActive(Math.min(dropdownActive + 1, items.length - 1));
    } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        setDropdownActive(Math.max(dropdownActive - 1, 0));
    } else if (e.key === 'Escape') {
        closeKwDropdown();
    } else if (e.key === 'Backspace' && !input.value && keywords.length > 0) {
        // Remove last keyword on backspace
        const last = keywords[keywords.length - 1];
        removeKeyword(last.id, null);
    }
}

// Close dropdown on outside click
document.addEventListener('click', e => {
    if (!document.getElementById('kwWrap').contains(e.target)) {
        closeKwDropdown();
    }
});

function addKeywordById(id, keyword) {
    if (keywords.length >= 8) {
        showToast('Maximum 8 keywords allowed', 'error'); return;
    }
    if (keywords.find(k => k.id === id)) {
        showToast('"' + keyword + '" already added', 'info'); closeKwDropdown(); return;
    }
    keywords.push({ id, keyword });
    renderKwTags();
    closeKwDropdown();
    updateKwCount();
    saveKeywords();
    scheduleAutoSave();
}

function createAndAddKeyword(text) {
    text = text.trim();
    if (!text) return;
    if (keywords.length >= 8) {
        showToast('Maximum 8 keywords allowed', 'error'); return;
    }
    if (keywords.find(k => k.keyword.toLowerCase() === text.toLowerCase())) {
        showToast('"' + text + '" already added', 'info'); closeKwDropdown(); return;
    }

    closeKwDropdown();

    // Create keyword via AJAX then add
    const fd = new FormData();
    fd.append('keyword', text);
    fetch('ajax/create_keyword.php', { method: 'POST', body: fd })
    .then(r => r.json())
    .then(data => {
        if (data.success) {
            addKeywordById(data.keyword_id, text);
        } else {
            showToast('Could not create keyword: ' + data.message, 'error');
        }
    });
}

function removeKeyword(id, btnEl) {
    keywords = keywords.filter(k => k.id !== id);
    renderKwTags();
    updateKwCount();
    saveKeywords();
    scheduleAutoSave();
}

function renderKwTags() {
    const wrap  = document.getElementById('kwWrap');
    const input = document.getElementById('kwInput');
    // Remove old tags
    wrap.querySelectorAll('.kw-tag').forEach(t => t.remove());
    // Re-add in order
    keywords.forEach(k => {
        const tag = document.createElement('span');
        tag.className = 'kw-tag';
        tag.dataset.id = k.id;
        tag.dataset.keyword = k.keyword;
        tag.innerHTML = `${escHtml(k.keyword)}<button type="button" class="kw-tag-remove" onclick="removeKeyword(${k.id},this)">×</button>`;
        wrap.insertBefore(tag, input);
    });
    input.placeholder = keywords.length === 0 ? 'Type to search keywords...' : '';
}

function updateKwCount() {
    const n    = keywords.length;
    const el   = document.getElementById('kwCount');
    const badge = document.getElementById('kwBadge');
    let msg = '', cls = '';
    if (n === 0)      { msg = 'Add at least 5 keywords (minimum 5, maximum 8)'; cls = ''; }
    else if (n < 5)   { msg = n + '/5 added — need ' + (5-n) + ' more'; cls = 'kw-warn'; }
    else if (n <= 8)  { msg = '✓ ' + n + ' keywords added'; cls = 'kw-ok'; }
    else              { msg = n + ' keywords — max is 8, remove ' + (n-8); cls = 'kw-error'; }
    el.textContent = msg;
    el.className   = 'kw-count ' + cls;

    const valid = n >= 5 && n <= 8;
    badge.textContent = valid ? '✓ Completed' : '⚠ Incomplete';
    badge.className   = 'card-badge ' + (valid ? 'badge-complete' : 'badge-incomplete');
    updateProgress();
}

function saveKeywords() {
    const fd = new FormData();
    fd.append('submission_id', SUBMISSION_ID);
    fd.append('keyword_ids', JSON.stringify(keywords.map(k => k.id)));
    fetch('ajax/save_keywords.php', { method: 'POST', body: fd })
    .catch(err => console.error('saveKeywords error:', err));
}

function highlightMatch(text, q) {
    if (!q) return text;
    const re = new RegExp('(' + q.replace(/[.*+?^${}()|[\]\\]/g,'\\$&') + ')', 'gi');
    return text.replace(re, '<strong>$1</strong>');
}

/* ════════════════════════════════════════════════════════════
   AUTO-SAVE & MANUAL SAVE
════════════════════════════════════════════════════════════ */
function scheduleAutoSave() {
    clearTimeout(autoSaveTimer);
    autoSaveTimer = setTimeout(() => saveManuscriptSilent(), 1500);
}

function collectData() {
    return {
        submission_id  : SUBMISSION_ID,
        manuscript_id  : document.getElementById('manuscriptId').value,
        article_title  : document.getElementById('articleTitle').value,
        running_title  : document.getElementById('runningTitle').value,
        abstract       : document.getElementById('abstract').value,
    };
}

function saveManuscriptSilent() {
    const fd = new FormData();
    const d  = collectData();
    Object.entries(d).forEach(([k,v]) => fd.append(k, v));
    fd.append('action', 'save');

    fetch('ajax/save_manuscript.php', { method: 'POST', body: fd })
    .then(r => r.json())
    .then(data => {
        if (data.success) {
            document.getElementById('manuscriptId').value = data.manuscript_id;
            showSaveIndicator();
            updateProgress();
        }
    })
    .catch(err => console.error('saveManuscriptSilent error:', err));
}

function saveManuscript(andContinue = false) {
    const btn = andContinue
        ? document.getElementById('saveContinueBtn')
        : document.getElementById('saveBtn');
    btn.disabled = true;
    btn.innerHTML = '<span class="spinner"></span> Saving...';

    const fd = new FormData();
    const d  = collectData();
    Object.entries(d).forEach(([k,v]) => fd.append(k, v));
    fd.append('action', andContinue ? 'save_continue' : 'save');

    fetch('ajax/save_manuscript.php', { method: 'POST', body: fd })
    .then(r => r.json())
    .then(data => {
        btn.disabled = false;
        btn.innerHTML = andContinue ? 'Save &amp; Continue →' : '💾 Save';

        if (data.success) {
            document.getElementById('manuscriptId').value = data.manuscript_id;
            updateProgress();
            showSaveIndicator();
            if (andContinue) {
                showToast('Saved! Opening related articles...', 'success');
                setTimeout(() => {
                    window.location.href = 'related_articles.php?id=' + SUBMISSION_ID;
                }, 800);
            } else {
                showToast('Manuscript information saved!', 'success');
            }
        } else {
            showToast(data.message || 'Save failed. Please try again.', 'error');
        }
    })
    .catch(() => {
        btn.disabled = false;
        btn.innerHTML = andContinue ? 'Save &amp; Continue →' : '💾 Save';
        showToast('Network error. Please check your connection.', 'error');
    });
}

/* ════════════════════════════════════════════════════════════
   PROGRESS
════════════════════════════════════════════════════════════ */
function updateProgress() {
    let filled = 0;
    if (document.getElementById('articleTitle').value.trim()) filled++;
    if (document.getElementById('abstract').value.trim().length > 50) filled++;
    const n = keywords.length;
    if (n >= 5 && n <= 8) filled++;
    const pct = Math.round((filled / 3) * 100);
    document.getElementById('progressFill').style.width = pct + '%';
    document.getElementById('progressPct').textContent  = pct + '%';
}

/* ════════════════════════════════════════════════════════════
   UTILS
════════════════════════════════════════════════════════════ */
function showSaveIndicator() {
    const el = document.getElementById('saveIndicator');
    el.classList.add('show');
    setTimeout(() => el.classList.remove('show'), 2500);
}

function showToast(msg, type = 'info') {
    const container = document.getElementById('toastContainer');
    const toast = document.createElement('div');
    toast.className = 'toast toast-' + type;
    const icons = { success: '✅', error: '❌', info: 'ℹ️' };
    toast.innerHTML = `<span>${icons[type] || ''}</span> ${escHtml(msg)}`;
    container.appendChild(toast);
    setTimeout(() => toast.remove(), 3500);
}

function escHtml(s) {
    return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
}
function escAttr(s) {
    return String(s).replace(/'/g, "\\'").replace(/"/g, '&quot;');
}

// Init progress on load
updateProgress();
</script>
</div>