| 1 |
(function () { |
| 2 |
function halfStarHTML(color) { |
| 3 |
return '<span style="position:relative;display:inline-block;color:#d1d5db;line-height:1;">� |
| 4 |
<span style="position:absolute;left:0;top:0;width:50%;overflow:hidden;color:' + color + ';">� |
| 5 |
</span></span>'; |
| 6 |
} |
| 7 |
|
| 8 |
function buildStars(rating, starColor) { |
| 9 |
var out = ''; |
| 10 |
for (var i = 1; i <= 5; i++) { |
| 11 |
if (rating >= i) out += '<span style="color:' + starColor + '">� |
| 12 |
</span>'; |
| 13 |
else if (rating >= i - 0.5) out += halfStarHTML(starColor); |
| 14 |
else out += '<span style="color:#d1d5db">☆</span>'; |
| 15 |
} |
| 16 |
return out; |
| 17 |
} |
| 18 |
|
| 19 |
function init() { |
| 20 |
document.querySelectorAll('.bkbg-tlc-app').forEach(function (el) { |
| 21 |
if (el.dataset.rendered) return; |
| 22 |
el.dataset.rendered = '1'; |
| 23 |
|
| 24 |
var opts; |
| 25 |
try { opts = JSON.parse(el.dataset.opts || '{}'); } catch (e) { opts = {}; } |
| 26 |
|
| 27 |
var o = Object.assign({ |
| 28 |
toolName: 'Notion', tagline: 'All-in-one workspace for notes, wikis, and projects', |
| 29 |
logoUrl: '', logoAlt: '', rating: 4.5, ratingCount: '2,300+ reviews', |
| 30 |
showRating: true, pricing: 'freemium', pricingNote: 'Free plan available · Paid from $8/mo', |
| 31 |
showPricing: true, description: 'Notion is a flexible all-in-one workspace that replaces your notes, wikis, tasks, and databases.', |
| 32 |
features: ['Unlimited pages and blocks', 'Real-time collaboration', 'Database views', 'API and integrations'], |
| 33 |
ctaLabel: 'Try Notion Free', ctaUrl: '#', badgeText: "Editor's Pick", showBadge: true, |
| 34 |
layout: 'horizontal', borderRadius: 12, |
| 35 |
bgColor: '#ffffff', borderColor: '#e2e8f0', accentColor: '#6366f1', |
| 36 |
nameColor: '#111827', taglineColor: '#6b7280', descColor: '#374151', featureColor: '#374151', |
| 37 |
starColor: '#f59e0b', pricingColor: '#374151', |
| 38 |
badgeBg: '#fef3c7', badgeColor: '#92400e', ctaBg: '#6366f1', ctaColor: '#ffffff' |
| 39 |
}, opts); |
| 40 |
|
| 41 |
var card = document.createElement('div'); |
| 42 |
card.className = 'bkbg-tlc-card layout-' + o.layout; |
| 43 |
card.style.cssText = 'background:' + o.bgColor + ';border-color:' + o.borderColor + ';border-radius:' + o.borderRadius + 'px;'; |
| 44 |
|
| 45 |
/* Sidebar */ |
| 46 |
var sidebar = document.createElement('div'); |
| 47 |
sidebar.className = 'bkbg-tlc-sidebar'; |
| 48 |
|
| 49 |
if (o.logoUrl) { |
| 50 |
var logo = document.createElement('img'); |
| 51 |
logo.className = 'bkbg-tlc-logo'; logo.src = o.logoUrl; logo.alt = o.logoAlt; |
| 52 |
logo.style.borderColor = o.borderColor; |
| 53 |
sidebar.appendChild(logo); |
| 54 |
} else { |
| 55 |
var placeholder = document.createElement('div'); |
| 56 |
placeholder.className = 'bkbg-tlc-logo-placeholder'; |
| 57 |
placeholder.style.background = o.accentColor + '22'; |
| 58 |
placeholder.textContent = '🔧'; |
| 59 |
sidebar.appendChild(placeholder); |
| 60 |
} |
| 61 |
|
| 62 |
if (o.showRating && o.layout !== 'compact') { |
| 63 |
var ratingDiv = document.createElement('div'); ratingDiv.className = 'bkbg-tlc-rating'; |
| 64 |
var stars = document.createElement('span'); stars.className = 'bkbg-tlc-stars'; stars.innerHTML = buildStars(o.rating, o.starColor); |
| 65 |
var rc = document.createElement('span'); rc.className = 'bkbg-tlc-rating-count'; rc.style.color = o.taglineColor; rc.textContent = o.ratingCount; |
| 66 |
ratingDiv.appendChild(stars); ratingDiv.appendChild(rc); |
| 67 |
sidebar.appendChild(ratingDiv); |
| 68 |
} |
| 69 |
|
| 70 |
if (o.showPricing && o.layout !== 'compact') { |
| 71 |
var pill = document.createElement('div'); pill.className = 'bkbg-tlc-pricing-pill'; |
| 72 |
pill.style.cssText = 'background:' + o.bgColor + ';border:1px solid ' + o.borderColor + ';'; |
| 73 |
var pModel = document.createElement('span'); pModel.className = 'bkbg-tlc-pricing-model'; pModel.style.color = o.accentColor; pModel.textContent = o.pricing; |
| 74 |
var pNote = document.createElement('span'); pNote.className = 'bkbg-tlc-pricing-note'; pNote.style.color = o.pricingColor; pNote.textContent = o.pricingNote; |
| 75 |
pill.appendChild(pModel); pill.appendChild(pNote); |
| 76 |
sidebar.appendChild(pill); |
| 77 |
} |
| 78 |
|
| 79 |
var cta = document.createElement('a'); cta.className = 'bkbg-tlc-cta-btn'; |
| 80 |
cta.href = o.ctaUrl; cta.textContent = o.ctaLabel; |
| 81 |
cta.style.cssText = 'background:' + o.ctaBg + ';color:' + o.ctaColor; |
| 82 |
sidebar.appendChild(cta); |
| 83 |
card.appendChild(sidebar); |
| 84 |
|
| 85 |
/* Content */ |
| 86 |
var content = document.createElement('div'); |
| 87 |
content.className = 'bkbg-tlc-content'; |
| 88 |
|
| 89 |
var header = document.createElement('div'); header.className = 'bkbg-tlc-header'; |
| 90 |
var name = document.createElement('h3'); name.className = 'bkbg-tlc-name'; name.style.color = o.nameColor; name.textContent = o.toolName; |
| 91 |
header.appendChild(name); |
| 92 |
if (o.showBadge && o.badgeText) { |
| 93 |
var badge = document.createElement('span'); badge.className = 'bkbg-tlc-badge'; |
| 94 |
badge.style.cssText = 'background:' + o.badgeBg + ';color:' + o.badgeColor; |
| 95 |
badge.textContent = o.badgeText; |
| 96 |
header.appendChild(badge); |
| 97 |
} |
| 98 |
content.appendChild(header); |
| 99 |
|
| 100 |
var tagline = document.createElement('p'); tagline.className = 'bkbg-tlc-tagline'; tagline.style.color = o.taglineColor; tagline.textContent = o.tagline; |
| 101 |
content.appendChild(tagline); |
| 102 |
|
| 103 |
var desc = document.createElement('p'); desc.className = 'bkbg-tlc-desc'; desc.style.color = o.descColor; desc.textContent = o.description; |
| 104 |
content.appendChild(desc); |
| 105 |
|
| 106 |
var ul = document.createElement('ul'); ul.className = 'bkbg-tlc-features'; |
| 107 |
(o.features || []).forEach(function (f) { |
| 108 |
var li = document.createElement('li'); li.style.color = o.featureColor; |
| 109 |
var check = document.createElement('span'); check.className = 'bkbg-tlc-check'; check.style.color = o.accentColor; check.textContent = '✓'; |
| 110 |
li.appendChild(check); li.appendChild(document.createTextNode(f)); |
| 111 |
ul.appendChild(li); |
| 112 |
}); |
| 113 |
content.appendChild(ul); |
| 114 |
card.appendChild(content); |
| 115 |
|
| 116 |
el.appendChild(card); |
| 117 |
}); |
| 118 |
} |
| 119 |
|
| 120 |
if (document.readyState !== 'loading') { init(); } |
| 121 |
else { document.addEventListener('DOMContentLoaded', init); } |
| 122 |
})(); |
| 123 |
|