diff --git a/css/style.css b/css/style.css index 8f8118c..243ceb1 100644 --- a/css/style.css +++ b/css/style.css @@ -40,8 +40,8 @@ body { --bg-soft: oklch(1 0 0 / 0.05); --line-soft: oklch(0.9 0.03 85 / 0.12); --line-strong: oklch(0.85 0.1 85 / 0.3); - --text-main: oklch(0.95 0.01 85); - --text-muted: oklch(0.8 0.02 250); + --text-main: oklch(0.98 0.01 85); + --text-muted: oklch(0.85 0.02 250); --text-soft: oklch(0.65 0.03 250); --accent: oklch(0.78 0.14 85); --accent-strong: oklch(0.85 0.12 85); @@ -386,7 +386,7 @@ button:active { } .grid { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 24px; } .card, @@ -571,7 +571,7 @@ button:active { padding: 40px; } .hero-aside { - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); } } @media (max-width: 760px) { @@ -999,7 +999,7 @@ button:active { } .footer-nav { display: grid; - grid-template-columns: repeat(3, 1fr); + grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 40px; } .footer-group h3 { @@ -1530,3 +1530,53 @@ body.menu-open .mobile-nav { z-index: 999; } } + +/* Mode Switcher Styles */ +.mode-switcher { display: flex; background: var(--bg-soft); padding: 4px; border-radius: 100px; border: 1px solid var(--line-soft); } +.mode-btn { display: flex; align-items: center; gap: 8px; padding: 8px 16px; border: none; background: transparent; color: var(--text-muted); border-radius: 100px; cursor: pointer; font-size: 0.9rem; font-weight: 600; transition: all 0.2s ease; } +.mode-btn i { font-size: 0.85rem; } +.mode-btn.active { background: var(--accent); color: white; box-shadow: var(--shadow-sm); } +.mode-btn:hover:not(.active) { background: var(--bg-elevated); color: var(--text-main); } + +/* Breadcrumbs Styles */ +.studio-breadcrumbs { font-size: 0.85rem; color: var(--text-soft); margin-bottom: 1.5rem; font-weight: 500; letter-spacing: 0.02em; } +.studio-breadcrumbs span { color: var(--text-muted); } +.studio-breadcrumbs .current { color: var(--accent); } + +/* Project Progress Stepper */ +.project-progress-stepper { display: flex; align-items: center; justify-content: space-between; position: relative; gap: 2rem; padding: 0 1rem; flex: 1; max-width: 600px; } +.stepper-track { position: absolute; top: 12px; left: 2rem; right: 2rem; height: 2px; background: var(--line-soft); z-index: 0; } +.progress-step { display: flex; flex-direction: column; align-items: center; gap: 8px; position: relative; z-index: 1; } +.step-node { width: 24px; height: 24px; border-radius: 50%; background: var(--bg-canvas); border: 2px solid var(--line-strong); transition: all 0.3s ease; } +.step-label { font-size: 0.75rem; font-weight: 600; color: var(--text-soft); white-space: nowrap; } +.progress-step.active .step-node { background: var(--accent); border-color: var(--accent); box-shadow: 0 0 15px var(--accent); } +.progress-step.active .step-label { color: var(--text-main); } +.progress-step.completed .step-node { background: var(--accent-deep); border-color: var(--accent-deep); } + +/* Kanban Styles */ +.view-controls { display: flex; gap: 8px; margin-bottom: 1.5rem; } +.kanban-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.5rem; align-items: start; } +.kanban-column { background: var(--bg-soft); border-radius: var(--radius-md); padding: 1rem; min-height: 400px; } +.kanban-column h3 { font-size: 0.9rem; color: var(--text-muted); margin-bottom: 1rem; text-transform: uppercase; letter-spacing: 0.05em; display: flex; justify-content: space-between; } +.kanban-count { background: var(--line-soft); padding: 2px 8px; border-radius: 10px; font-size: 0.75rem; } +.kanban-cards { display: flex; flex-direction: column; gap: 1rem; } +.kanban-card { background: var(--bg-elevated); border: 1px solid var(--line-soft); border-radius: var(--radius-sm); padding: 1rem; cursor: pointer; transition: transform 0.2s ease; } +.kanban-card:hover { transform: translateY(-2px); border-color: var(--accent); } + +/* Mapping Popup */ +.mapping-popup { position: absolute; background: var(--bg-panel); border: 1px solid var(--accent); padding: 5px; border-radius: 8px; box-shadow: var(--shadow-md); z-index: 1000; display: none; } +.mapping-popup button { background: var(--accent); color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; font-size: 0.8rem; font-weight: 600; display: flex; align-items: center; gap: 5px; } +.mapping-popup button:hover { background: var(--accent-strong); } + +/* SEO Heatmap */ +.seo-heatmap-container { margin-top: 1rem; padding: 1rem; background: var(--bg-soft); border-radius: var(--radius-sm); } +.heatmap-label { display: flex; justify-content: space-between; font-size: 0.8rem; margin-bottom: 0.5rem; color: var(--text-muted); } +.heatmap-bar { height: 8px; background: var(--line-soft); border-radius: 4px; overflow: hidden; position: relative; } +.heatmap-fill { height: 100%; width: 0%; transition: all 0.5s ease; background: #ff4d4d; } +.heatmap-fill.low { background: #ff4d4d; } +.heatmap-fill.mid { background: #ffcc00; } +.heatmap-fill.high { background: #00cc66; } + +@keyframes skeleton-shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } +.skeleton-card { position: relative; overflow: hidden; background: var(--bg-elevated); border-radius: var(--radius-md); border: 1px solid var(--line-soft); } +.skeleton-card::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, transparent, oklch(1 0 0 / 0.05), transparent); animation: skeleton-shimmer 1.5s infinite; } diff --git a/index.html b/index.html index 4710387..e7a15df 100644 --- a/index.html +++ b/index.html @@ -107,11 +107,16 @@

Ruh Al Tarikh

Dashboard - +
+ + +
Creator Workspace
+ -
- Researching - - Writing - - Recording - - Editing - - Published +
+
+
+
+ Researching +
+
+
+ Writing +
+
+
+ Recording +
+
+
+ Editing +
+
+
+ Published +
@@ -373,6 +391,7 @@

Untitled Video

Your Projects

Manage your upcoming and past videos.

+
diff --git a/js/app.js b/js/app.js index a073a53..4d1b664 100644 --- a/js/app.js +++ b/js/app.js @@ -9,7 +9,7 @@ THEME_KEY: 'ui_theme', SEARCH_HISTORY_KEY: 'search_history', PROGRESS_KEY: 'watch_progress', - ITEMS_PER_PAGE: 12, + ITEMS_PER_PAGE: 15, API_CONFIG: { timeout: 1e4, retries: 3, backoff: 1.5, delay: 500 }, }, a = [ @@ -82,7 +82,7 @@ continueRow: r('continue-row'), emptyHistory: r('empty-history'), clearFilters: r('clearFilters'), - studioToggleBtn: r('studioToggleBtn'), + modeSwitcher: r('modeSwitcher'), modeBtns: document.querySelectorAll('.mode-btn'), studioBreadcrumbs: r('studioBreadcrumbs'), appRoot: r('app-root'), studioRoot: r('studio-root'), heroSection: r('hero'), @@ -112,6 +112,8 @@ searchHistory: JSON.parse(localStorage.getItem(i.SEARCH_HISTORY_KEY) || '[]'), progress: JSON.parse(localStorage.getItem(i.PROGRESS_KEY) || '{}'), ytPlayer: null, + isPlaying: false, + isMuted: false, }, l = { sanitize: (e) => @@ -153,31 +155,60 @@ function d(e) { return n.progress[e] || null; } + function updateBreadcrumbs(path) { + if (!s.studioBreadcrumbs) return; + const parts = path.split(' > '); + s.studioBreadcrumbs.innerHTML = parts.map((p, i) => + i === parts.length - 1 ? `${p}` : `${p}` + ).join(' '); + } + let currentView = 'list'; + function renderKanban(projects) { + const grid = document.getElementById("studioProjectsList"); + if (!grid) return; + const columns = ['Research', 'Writing', 'Editing', 'Published']; + grid.className = 'kanban-grid'; + grid.innerHTML = columns.map(col => { + const colProjects = projects.filter(p => p.status === col || (col === 'Research' && p.status === 'Researching')); + return `

${col} ${colProjects.length}

${colProjects.map(p => `

${p.title}

${p.progress}%${p.date}
`).join("")}
`; + }).join(""); + grid.querySelectorAll(".resume-project-btn").forEach(btn => { + btn.addEventListener("click", (e) => { + const id = e.currentTarget.dataset.id; + const project = projects.find(p => p.id === id); + if (project) { + s.studioViews.forEach(v => v.style.display = "none"); + if (s.activeProjectView) s.activeProjectView.style.display = "block"; + if (r("current-project-title")) r("current-project-title").textContent = project.title; + updateBreadcrumbs('Studio > Projects > ' + project.title); + if (s.projectTabBtns[0]) s.projectTabBtns[0].click(); + } + }); + }); + } function renderProjects() { const grid = document.getElementById("studioProjectsList"); if (!grid) return; const saved = localStorage.getItem(i.PROJECTS_KEY); const projects = saved ? JSON.parse(saved) : [ { id: "p1", title: "The Fall of the Abbasids", status: "Writing", progress: 65, date: "2024-05-10" }, - { id: "p2", title: "Prophecy & Modernity", status: "Research", progress: 30, date: "2024-05-12" }, - { id: "p3", title: "The Silent Silk Road", status: "Editing", progress: 90, date: "2024-05-08" } + { id: "p2", title: "Prophecy & Modernity", status: "Researching", progress: 30, date: "2024-05-12" }, + { id: "p3", title: "The Silent Silk Road", status: "Editing", progress: 90, date: "2024-05-08" }, + { id: "p4", title: "The Golden Age", status: "Published", progress: 100, date: "2024-05-01" } ]; - grid.innerHTML = projects.map(p => ` -
-
- ${p.status} - ${p.date} -
-

${p.title}

-
-
-
- -
- `).join(""); + const listViewBtn = document.getElementById('listViewBtn'); + const kanbanViewBtn = document.getElementById('kanbanViewBtn'); + if (listViewBtn && !listViewBtn.hasListener) { + listViewBtn.addEventListener('click', () => { currentView = 'list'; listViewBtn.classList.add('active'); kanbanViewBtn.classList.remove('active'); renderProjects(); }); + listViewBtn.hasListener = true; + } + if (kanbanViewBtn && !kanbanViewBtn.hasListener) { + kanbanViewBtn.addEventListener('click', () => { currentView = 'kanban'; kanbanViewBtn.classList.add('active'); listViewBtn.classList.remove('active'); renderProjects(); }); + kanbanViewBtn.hasListener = true; + } + if (currentView === 'kanban') { renderKanban(projects); return; } + grid.className = 'studio-projects-grid'; + grid.innerHTML = projects.map(p => `
${p.status}${p.date}

${p.title}

`).join(""); grid.querySelectorAll(".resume-project-btn").forEach(btn => { btn.addEventListener("click", (e) => { const id = e.currentTarget.dataset.id; @@ -186,6 +217,7 @@ s.studioViews.forEach(v => v.style.display = "none"); if (s.activeProjectView) s.activeProjectView.style.display = "block"; if (r("current-project-title")) r("current-project-title").textContent = project.title; + updateBreadcrumbs('Studio > Projects > ' + project.title); if (s.projectTabBtns[0]) s.projectTabBtns[0].click(); } }); @@ -238,6 +270,7 @@ }, }))), (s.modal.style.display = 'flex'), + n.isPlaying = true, s.modal.setAttribute('aria-hidden', 'false'), (s.body.style.overflow = 'hidden'), s.body.classList.add('modal-open'), @@ -430,29 +463,41 @@ ); } function k() { - let a = n.search.toLowerCase(); - ((n.filtered = n.videos.filter((e) => { - var t = n.categories.includes('all') || n.categories.includes(e.category), - e = !a || e.title.toLowerCase().includes(a); - return t && e; - })), - s.clearFilters && (s.clearFilters.style.display = n.categories.includes('all') ? 'none' : 'inline-flex'), - s.resultsMeta && (s.resultsMeta.textContent = n.filtered.length + ' episode' + (1 === n.filtered.length ? '' : 's') + ' found')); - var e = n.filtered.slice(0, i.ITEMS_PER_PAGE * (n.page + 1)); - (s.grid && - (0 === n.filtered.length - ? (s.grid.innerHTML = ` -
- -

No results found

-

Try different keywords or browse by category to find what you're looking for.

- -
- `) - : (s.grid.innerHTML = e.map(L).join(''))), - s.loadMoreContainer && (s.loadMoreContainer.style.display = e.length < n.filtered.length ? 'block' : 'none')); + function getFuzzyScore(text, query) { + if (!query) return 1; + text = text.toLowerCase(); + if (text.includes(query)) return 10; + let score = 0, qIdx = 0; + for (let i = 0; i < text.length && qIdx < query.length; i++) { + if (text[i] === query[qIdx]) { score++; qIdx++; } + } + return score / query.length; + } + const searchLower = n.search.toLowerCase(); + n.filtered = n.videos.filter(v => { + const categoryMatch = n.categories.includes('all') || n.categories.includes(v.category); + if (!categoryMatch) return false; + if (!searchLower) return true; + return Math.max(getFuzzyScore(v.title, searchLower), getFuzzyScore(v.description || '', searchLower), v.category.includes(searchLower) ? 0.8 : 0) > 0.6; + }); + if (searchLower) { + n.filtered.sort((a, b) => { + const scoreA = Math.max(getFuzzyScore(a.title, searchLower), getFuzzyScore(a.description || '', searchLower)); + const scoreB = Math.max(getFuzzyScore(b.title, searchLower), getFuzzyScore(b.description || '', searchLower)); + return scoreB - scoreA; + }); + } + const visibleVideos = n.filtered.slice(0, i.ITEMS_PER_PAGE * (n.page + 1)); + if (s.clearFilters) s.clearFilters.style.display = n.categories.includes('all') ? 'none' : 'inline-flex'; + if (s.resultsMeta) s.resultsMeta.textContent = n.filtered.length + ' episode' + (n.filtered.length === 1 ? '' : 's') + ' found'; + if (s.grid) { + if (n.filtered.length === 0) { + s.grid.innerHTML = `

No results found

Try different keywords or browse by category to find what you're looking for.

`; + } else { + s.grid.innerHTML = visibleVideos.map(L).join(''); + } + } + if (s.loadMoreContainer) s.loadMoreContainer.style.display = visibleVideos.length < n.filtered.length ? 'block' : 'none'; } function E() { (s.statTotal && (s.statTotal.textContent = n.videos.length), @@ -707,6 +752,10 @@ ? 'Escape' === e.key && e.target.blur() : '/' === (t = e.key.toLowerCase()) ? (e.preventDefault(), s.search && s.search.focus()) + : ' ' === t && n.current + ? (e.preventDefault(), s.player && s.player.contentWindow.postMessage('{"event":"command","func":"' + (n.isPlaying ? 'pauseVideo' : 'playVideo') + '","args":""}', '*'), n.isPlaying = !n.isPlaying) + : 'm' === t && n.current + ? (e.preventDefault(), s.player && s.player.contentWindow.postMessage('{"event":"command","func":"' + (n.isMuted ? 'unMute' : 'mute') + '","args":""}', '*'), n.isMuted = !n.isMuted) : 'escape' === t ? (h(), y(), @@ -734,36 +783,37 @@ }); // Studio Logic - s.studioToggleBtn && s.studioToggleBtn.addEventListener('click', () => { - const isStudioOpen = s.studioRoot.style.display === 'block'; - if (isStudioOpen) { - s.studioRoot.style.display = 'none'; - s.appRoot.style.display = 'block'; - if(s.heroSection) s.heroSection.style.display = 'block'; - if(s.continueBlockSec && n.videos.some(v => d(v.id))) s.continueBlockSec.style.display = 'block'; - s.studioToggleBtn.classList.remove('active'); - s.studioToggleBtn.querySelector('span').textContent = 'Studio'; - } else { - s.studioRoot.style.display = 'block'; - s.appRoot.style.display = 'none'; - if(s.heroSection) s.heroSection.style.display = 'none'; - if(s.continueBlockSec) s.continueBlockSec.style.display = 'none'; - s.studioToggleBtn.classList.add('active'); - s.studioToggleBtn.querySelector('span').textContent = 'Exit Studio'; - } + s.modeBtns && s.modeBtns.forEach(btn => { + btn.addEventListener('click', () => { + const mode = btn.dataset.mode; + s.modeBtns.forEach(b => b.classList.remove('active')); + btn.classList.add('active'); + if (mode === 'creator') { + s.studioRoot.style.display = 'block'; + s.appRoot.style.display = 'none'; + if(s.heroSection) s.heroSection.style.display = 'none'; + if(s.continueBlockSec) s.continueBlockSec.style.display = 'none'; + updateBreadcrumbs('Studio > Projects'); + } else { + s.studioRoot.style.display = 'none'; + s.appRoot.style.display = 'block'; + if(s.heroSection) s.heroSection.style.display = 'block'; + if(s.continueBlockSec && n.videos.some(v => d(v.id))) s.continueBlockSec.style.display = 'block'; + } + }); }); const startScriptBtn = document.getElementById("startScriptBtn"); const openDemoBtn = document.getElementById("openDemoBtn"); if (startScriptBtn) { startScriptBtn.addEventListener("click", () => { - if (s.studioToggleBtn) s.studioToggleBtn.click(); + const creatorBtn = Array.from(s.modeBtns).find(b => b.dataset.mode === 'creator'); if (creatorBtn) creatorBtn.click(); if (s.newProjectBtn) s.newProjectBtn.click(); }); } if (openDemoBtn) { openDemoBtn.addEventListener("click", () => { - if (s.studioToggleBtn) s.studioToggleBtn.click(); + const creatorBtn = Array.from(s.modeBtns).find(b => b.dataset.mode === 'creator'); if (creatorBtn) creatorBtn.click(); const resumeBtns = document.querySelectorAll(".resume-project-btn"); if (resumeBtns.length > 0) resumeBtns[0].click(); }); @@ -787,12 +837,14 @@ s.studioViews.forEach(v => v.style.display = 'none'); s.activeProjectView.style.display = 'block'; r('current-project-title').textContent = 'New Untitled Video'; + updateBreadcrumbs('Studio > Projects > New Untitled Video'); s.projectTabBtns[0].click(); // open research tab }); s.backToProjectsBtn && s.backToProjectsBtn.addEventListener('click', () => { s.activeProjectView.style.display = 'none'; r('studio-view-projects').style.display = 'block'; + updateBreadcrumbs('Studio > Projects'); s.studioNavBtns.forEach(b => { b.classList.remove('active'); if(b.dataset.tab === 'projects') b.classList.add('active'); @@ -819,7 +871,7 @@ .fill(0) .map( () => ` -
+
diff --git a/js/script.js b/js/script.js index 2ace577..ac021da 100644 --- a/js/script.js +++ b/js/script.js @@ -1,100 +1,24 @@ // Tamil Script Studio - -const SCRIPT_HTML = ` -
-
-
-
-

Script Studio

-

Draft your documentary script with structured sections.

-
-
- - - -
-
- -
-
- - -
-
- - -
-
- - -
-
- - -
-
-
- - -
- - - -`; - +const SCRIPT_HTML = `

Script Studio

Draft your documentary script with structured sections.

`; export function initScriptStudio() { const container = document.getElementById('ptab-script'); if (!container) return; - container.innerHTML = SCRIPT_HTML; - const textareas = container.querySelectorAll('.script-textarea'); textareas.forEach(ta => { ta.addEventListener('input', updateMetrics); + ta.addEventListener('mouseup', () => { + const selectedText = ta.value.substring(ta.selectionStart, ta.selectionEnd).trim(); + if (selectedText.length > 5) showMappingPopup(ta, selectedText); + else hideMappingPopup(); + }); }); - document.getElementById('insertPauseBtn')?.addEventListener('click', () => insertAtCursor(' [PAUSE] ')); document.getElementById('insertEmphasisBtn')?.addEventListener('click', () => insertAtCursor(' ** **')); - const focusOverlay = document.getElementById('focusModeOverlay'); const focusTextArea = document.getElementById('focusTextArea'); const focusTitle = document.getElementById('focusTitle'); let activeSourceTA = null; - document.getElementById('toggleFocusMode')?.addEventListener('click', () => { const focused = document.activeElement; if (focused && focused.classList.contains('script-textarea')) { @@ -105,11 +29,8 @@ export function initScriptStudio() { focusOverlay.classList.add('show'); focusTextArea.focus(); updateFocusMetrics(); - } else { - alert('Please click inside a section to focus.'); - } + } else alert('Please click inside a section to focus.'); }); - document.getElementById('exitFocusMode')?.addEventListener('click', () => { if (activeSourceTA) { activeSourceTA.value = focusTextArea.value; @@ -118,49 +39,56 @@ export function initScriptStudio() { focusOverlay.setAttribute('aria-hidden', 'true'); focusOverlay.classList.remove('show'); }); - focusTextArea.addEventListener('input', updateFocusMetrics); - updateMetrics(); } - +function showMappingPopup(ta, text) { + let popup = document.getElementById('mappingPopup'); + if (!popup) { + popup = document.createElement('div'); + popup.id = 'mappingPopup'; + popup.className = 'mapping-popup'; + popup.innerHTML = ``; + document.body.appendChild(popup); + } + const rect = ta.getBoundingClientRect(); + popup.style.display = 'block'; + popup.style.top = `${window.scrollY + rect.top - 40}px`; + popup.style.left = `${window.scrollX + rect.left + 20}px`; + document.getElementById('linkRefBtn').onclick = () => { + const refTab = document.querySelector('.studio-nav-btn[data-tab="islamic"]'); + if (refTab) refTab.click(); + hideMappingPopup(); + }; +} +function hideMappingPopup() { + const popup = document.getElementById('mappingPopup'); + if (popup) popup.style.display = 'none'; +} function updateMetrics() { const textareas = document.querySelectorAll('.script-textarea'); let totalText = ''; textareas.forEach(ta => totalText += ta.value + ' '); - const words = totalText.trim().split(/\s+/).filter(w => w.length > 0).length; const countEl = document.getElementById('scriptWordCount'); if(countEl) countEl.textContent = words; - - // Rough estimate: 130 words per minute for Tamil/English narration const minutes = Math.floor(words / 130); const seconds = Math.floor((words % 130) / (130 / 60)); - const durEl = document.getElementById('scriptDuration'); if(durEl) durEl.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; } - function updateFocusMetrics() { - const focusTextArea = document.getElementById("focusTextArea"); - const words = (window.activeFocusTextArea || document.getElementById("focusTextArea")).value.trim().split(/\s+/).filter(w => w.length > 0).length; + const words = document.getElementById("focusTextArea").value.trim().split(/\s+/).filter(w => w.length > 0).length; document.getElementById('focusMetrics').textContent = `${words} words`; } - function insertAtCursor(text) { const activeEl = document.activeElement; if (activeEl && (activeEl.classList.contains('script-textarea') || activeEl.classList.contains('focus-textarea'))) { - const start = activeEl.selectionStart; - const end = activeEl.selectionEnd; - const val = activeEl.value; + const start = activeEl.selectionStart, end = activeEl.selectionEnd, val = activeEl.value; activeEl.value = val.substring(0, start) + text + val.substring(end); activeEl.selectionStart = activeEl.selectionEnd = start + text.length; activeEl.focus(); updateMetrics(); - } else { - alert('Please focus on a text area first to insert markers.'); - } + } else alert('Please focus on a text area first to insert markers.'); } - -// Auto-init on load document.addEventListener('DOMContentLoaded', initScriptStudio); diff --git a/js/seo.js b/js/seo.js index 2b59419..5374aeb 100644 --- a/js/seo.js +++ b/js/seo.js @@ -1,130 +1,52 @@ // YouTube SEO Toolkit - -const SEO_HTML = ` -
-
-
-

SEO & Metadata

-

Optimize your title, description, and tags for YouTube search.

-
- -
-
- -
- - -
-
- -
- - -
- -
- - -
-
-
- - -
-`; - +const SEO_HTML = `

SEO & Metadata

Optimize your title, description, and tags for YouTube search.

`; export function initSEO() { const container = document.getElementById('ptab-seo'); if (!container) return; container.innerHTML = SEO_HTML; - const titleInput = document.getElementById('seoTitle'); const thumbTitle = document.getElementById('thumbTitle'); const previewTitle = document.getElementById('previewTitle'); const titleCount = document.getElementById('titleCount'); const scoreTitle = document.getElementById('scoreTitle'); const scoreKeywords = document.getElementById('scoreKeywords'); - + const updateHeatmap = () => { + const title = titleInput.value.toLowerCase(), desc = document.getElementById('seoDesc').value.toLowerCase(); + const heatmapFill = document.getElementById('seoHeatmapFill'), heatmapStatus = document.getElementById('heatmapStatus'); + if (!heatmapFill || !heatmapStatus) return; + const keywords = ['quran', 'history', 'truth', 'secret', 'mystery', 'islam', 'prophecy', 'documentary']; + let count = 0; + keywords.forEach(k => { if (title.includes(k)) count += 2; if (desc.includes(k)) count += 1; }); + const score = Math.min(100, count * 10); + heatmapFill.style.width = `${score}%`; + if (score < 30) { heatmapFill.className = 'heatmap-fill low'; heatmapStatus.textContent = 'Low Optimization'; } + else if (score < 70) { heatmapFill.className = 'heatmap-fill mid'; heatmapStatus.textContent = 'Good Progress'; } + else { heatmapFill.className = 'heatmap-fill high'; heatmapStatus.textContent = 'Highly Optimized'; } + }; titleInput.addEventListener('input', (e) => { const val = e.target.value; previewTitle.textContent = val || 'Your Title Will Appear Here'; thumbTitle.textContent = val || 'Your Title'; titleCount.textContent = `${val.length}/100`; - - if (val.length < 20) { - scoreTitle.textContent = 'Too Short'; - scoreTitle.className = 'score-badge warning'; - } else if (val.length > 70) { - scoreTitle.textContent = 'Too Long'; - scoreTitle.className = 'score-badge warning'; - } else { - scoreTitle.textContent = 'Optimal'; - scoreTitle.className = 'score-badge good'; - } - - // Mock keyword strength + if (val.length < 20) { scoreTitle.textContent = 'Too Short'; scoreTitle.className = 'score-badge warning'; } + else if (val.length > 70) { scoreTitle.textContent = 'Too Long'; scoreTitle.className = 'score-badge warning'; } + else { scoreTitle.textContent = 'Optimal'; scoreTitle.className = 'score-badge good'; } const keywords = ['quran', 'history', 'truth', 'secret', 'mystery', 'islam']; const hasKeyword = keywords.some(k => val.toLowerCase().includes(k)); - if (hasKeyword) { - scoreKeywords.textContent = 'Strong'; - scoreKeywords.className = 'score-badge excellent'; - } else { - scoreKeywords.textContent = 'Low'; - scoreKeywords.className = 'score-badge warning'; - } + if (hasKeyword) { scoreKeywords.textContent = 'Strong'; scoreKeywords.className = 'score-badge excellent'; } + else { scoreKeywords.textContent = 'Low'; scoreKeywords.className = 'score-badge warning'; } + updateHeatmap(); }); - document.getElementById('seoDesc')?.addEventListener('input', (e) => { document.getElementById('descCount').textContent = `${e.target.value.length}/5000`; + updateHeatmap(); }); - document.getElementById('seoTags')?.addEventListener('input', (e) => { document.getElementById('tagCount').textContent = `${e.target.value.length}/500`; }); - document.getElementById('aiTitleBtn')?.addEventListener('click', () => { const modal = document.getElementById('aiModal'); - if(modal) { - document.getElementById('aiActionSelect').value = 'title'; - modal.classList.add('show'); - modal.setAttribute('aria-hidden', 'false'); - } + if(modal) { document.getElementById('aiActionSelect').value = 'title'; modal.classList.add('show'); modal.setAttribute('aria-hidden', 'false'); } }); } - document.addEventListener('DOMContentLoaded', initSEO);