diff --git a/index.html b/index.html index fe97e2b5..cf9151c7 100644 --- a/index.html +++ b/index.html @@ -1245,7 +1245,7 @@ function renderChips(containerId, values, filterKey, initialLimit = null) { const container = document.getElementById(containerId); - container.innerHTML = ''; + container.replaceChildren(); const toShow = initialLimit ? values.slice(0, initialLimit) : values; const rest = initialLimit ? values.slice(initialLimit) : []; @@ -1309,13 +1309,18 @@ // ── Rendering ────────────────────────────────────── function renderGrid() { - gridEl.innerHTML = ''; + gridEl.replaceChildren(); const slice = state.filtered.slice(0, state.pageSize); if (slice.length === 0) { const empty = document.createElement('div'); empty.className = 'empty-state'; - empty.innerHTML = '

🔍

No exercises found

'; + const icon = document.createElement('p'); + icon.textContent = '🔍'; + const message = document.createElement('p'); + message.textContent = 'No exercises found'; + empty.appendChild(icon); + empty.appendChild(message); gridEl.appendChild(empty); spinnerEl.classList.remove('visible'); return; @@ -1397,17 +1402,24 @@ } function renderSkeletons(count) { - gridEl.innerHTML = ''; + gridEl.replaceChildren(); const frag = document.createDocumentFragment(); for (let i = 0; i < count; i++) { const card = document.createElement('div'); card.className = 'skeleton-card'; - card.innerHTML = ` -
-
-
-
-
`; + const media = document.createElement('div'); + media.className = 'skeleton-media'; + const body = document.createElement('div'); + body.className = 'skeleton-body'; + const line = document.createElement('div'); + line.className = 'skeleton-line'; + const shortLine = document.createElement('div'); + shortLine.className = 'skeleton-line short'; + + body.appendChild(line); + body.appendChild(shortLine); + card.appendChild(media); + card.appendChild(body); frag.appendChild(card); } gridEl.appendChild(frag); @@ -1423,7 +1435,7 @@ } function updateActiveBadges() { - activeFilEl.innerHTML = ''; + activeFilEl.replaceChildren(); const { category, equipment, target } = state.filters; let hasAny = false; @@ -1432,7 +1444,15 @@ hasAny = true; const badge = document.createElement('span'); badge.className = 'active-badge'; - badge.innerHTML = `${val}`; + const removeBtn = document.createElement('button'); + removeBtn.className = 'active-badge-remove'; + removeBtn.dataset.filter = key; + removeBtn.dataset.value = val; + removeBtn.setAttribute('aria-label', `Remove ${val}`); + removeBtn.textContent = '×'; + + badge.appendChild(document.createTextNode(val)); + badge.appendChild(removeBtn); activeFilEl.appendChild(badge); }); }; @@ -1473,7 +1493,7 @@ modalGif.alt = ex.name; // Meta chips - modalMeta.innerHTML = ''; + modalMeta.replaceChildren(); const metaItems = [ { label: 'Body Part', value: ex.body_part || ex.category }, { label: 'Equipment', value: ex.equipment }, @@ -1482,12 +1502,20 @@ metaItems.forEach(({ label, value }) => { const chip = document.createElement('div'); chip.className = 'meta-chip'; - chip.innerHTML = `${label}${value}`; + const labelEl = document.createElement('span'); + labelEl.className = 'meta-chip-label'; + labelEl.textContent = label; + const valueEl = document.createElement('span'); + valueEl.className = 'meta-chip-value'; + valueEl.textContent = value; + + chip.appendChild(labelEl); + chip.appendChild(valueEl); modalMeta.appendChild(chip); }); // Muscles - modalMuscles.innerHTML = ''; + modalMuscles.replaceChildren(); const primaryMuscles = ex.target ? [ex.target] : []; const secondaryRaw = ex.secondary_muscles || (ex.muscle_group ? [ex.muscle_group] : []); const secondaryMuscles = secondaryRaw.filter(m => m !== ex.target); @@ -1524,7 +1552,7 @@ if (primaryMuscles.length > 0 || secondaryMuscles.length > 0) modalMuscles.appendChild(musclesGrid); // Instructions — format is always { en: [...], es: [...], it: [...], tr: [...], ru: [...] } - modalInstr.innerHTML = ''; + modalInstr.replaceChildren(); const LANG_LABELS = { en: 'English', es: 'Español', it: 'Italiano', tr: 'Türkçe', ru: 'Русский', zh: '简体中文' }; const langs = ['en', 'es', 'it', 'tr', 'ru', 'zh'] .map(code => ({ code, steps: ex.instruction_steps?.[code] ?? [] })) @@ -1540,11 +1568,19 @@ list.className = 'instructions-list'; function renderSteps(steps) { - list.innerHTML = ''; + list.replaceChildren(); steps.forEach((step, i) => { const li = document.createElement('li'); li.className = 'instruction-step'; - li.innerHTML = `${i + 1}${step}`; + const stepNum = document.createElement('span'); + stepNum.className = 'step-num'; + stepNum.textContent = String(i + 1); + const stepText = document.createElement('span'); + stepText.className = 'step-text'; + stepText.textContent = step; + + li.appendChild(stepNum); + li.appendChild(stepText); list.appendChild(li); }); } diff --git a/setup.html b/setup.html index 7a5b82d9..69fe13bd 100644 --- a/setup.html +++ b/setup.html @@ -1638,6 +1638,32 @@

Ask Your LLM

const llmPromptBox = document.getElementById('llm-prompt'); const copyPromptBtn = document.getElementById('copy-prompt-btn'); +function setCopyPromptButtonDefault() { + const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + svg.setAttribute('width', '14'); + svg.setAttribute('height', '14'); + svg.setAttribute('viewBox', '0 0 16 16'); + svg.setAttribute('fill', 'none'); + svg.setAttribute('stroke', 'currentColor'); + svg.setAttribute('stroke-width', '1.8'); + svg.setAttribute('stroke-linecap', 'round'); + svg.setAttribute('stroke-linejoin', 'round'); + + const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect'); + rect.setAttribute('x', '4'); + rect.setAttribute('y', '4'); + rect.setAttribute('width', '9'); + rect.setAttribute('height', '11'); + rect.setAttribute('rx', '1.5'); + + const path = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + path.setAttribute('d', 'M11 4V3a1 1 0 0 0-1-1H3a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h1'); + + svg.appendChild(rect); + svg.appendChild(path); + copyPromptBtn.replaceChildren(svg, document.createTextNode(' Copy Prompt')); +} + function renderLlmPrompt() { llmPromptBox.value = buildLlmPrompt(currentFw, currentLlmDb); } @@ -1665,7 +1691,7 @@

Ask Your LLM

copyPromptBtn.textContent = '✓ Copied!'; copyPromptBtn.classList.add('copied'); setTimeout(() => { - copyPromptBtn.innerHTML = ` Copy Prompt`; + setCopyPromptButtonDefault(); copyPromptBtn.classList.remove('copied'); }, 2500); });