:root {
–brand-green: #41A380;
–brand-green-glow: rgba(65, 163, 128, 0.4);
–brand-navy: #0B1E2E;
–brand-navy-light: #163654;
–brand-red: #C0392B;
–brand-gold: #D4AF37;
–brand-yellow: #F5B041;
–bg-light: #F7F9FC;
–glass-bg: rgba(255, 255, 255, 0.85);
–glass-border: rgba(255, 255, 255, 0.5);
–shadow-soft: 0 10px 40px -10px rgba(11, 30, 46, 0.08);
–shadow-hover: 0 20px 50px -10px rgba(11, 30, 46, 0.15);
}
#bwp-tool-container {
display: block;
background: transparent;
padding: 20px 0;
max-width: 680px;
margin: 50px auto;
font-family: ‘Inter’, sans-serif;
color: #334155;
position: relative;
box-sizing: border-box;
}
/* All direct children need z-index to sit above the glow */
#bwp-tool-container>div {
position: relative;
z-index: 1;
}
#bwp-tool-container h2 {
font-family: ‘Playfair Display’, serif;
font-weight: 700;
color: var(–brand-navy);
font-size: 38px;
margin-bottom: 15px;
text-align: center;
line-height: 1.2;
margin-top: 0;
letter-spacing: -0.5px;
}
.bwp-intro {
text-align: center;
color: #475569;
margin-bottom: 25px;
font-size: 16px;
line-height: 1.6;
}
.bwp-intro-highlight {
background: #ffffff;
padding: 20px;
border-radius: 16px;
font-size: 15px;
color: var(–brand-navy);
margin-bottom: 35px;
text-align: center;
border: 1px solid rgba(0, 0, 0, 0.04);
box-shadow: var(–shadow-soft);
border-left: 4px solid var(–brand-green);
}
.bwp-section {
display: none;
animation: smoothFadeUp 0.6s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.bwp-section.active {
display: block;
}
/* Buttons */
.bwp-cta-btn {
display: inline-block;
background: linear-gradient(135deg, var(–brand-navy) 0%, var(–brand-navy-light) 100%);
color: white !important;
padding: 16px 40px;
text-decoration: none;
font-family: ‘Inter’, sans-serif;
font-weight: 600;
font-size: 15px;
border-radius: 50px;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
border: none;
cursor: pointer;
box-shadow: 0 10px 25px rgba(11, 30, 46, 0.2);
width: 100%;
max-width: 320px;
text-align: center;
margin: 10px 0;
position: relative;
overflow: hidden;
}
.bwp-cta-btn::after {
content: ”;
position: absolute;
top: 0;
left: -100%;
width: 50%;
height: 100%;
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0) 100%);
transform: skewX(-25deg);
animation: shineBtn 4s infinite;
}
.bwp-cta-btn:hover {
transform: translateY(-3px);
box-shadow: 0 15px 35px rgba(11, 30, 46, 0.3);
background: #163654;
}
.bwp-secondary-btn {
background: rgba(15, 41, 64, 0.04);
color: var(–brand-navy) !important;
border: 1px solid rgba(15, 41, 64, 0.1);
box-shadow: none;
}
.bwp-secondary-btn::after {
display: none;
}
.bwp-secondary-btn:hover {
background: rgba(15, 41, 64, 0.08);
transform: translateY(-2px);
box-shadow: none;
}
.bwp-restart-btn-bottom {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
background: transparent;
color: var(–brand-navy) !important;
padding: 16px 40px;
font-family: ‘Inter’, sans-serif;
font-weight: 600;
font-size: 15px;
border-radius: 50px;
transition: all 0.3s ease;
border: 2px solid rgba(65, 163, 128, 0.35);
cursor: pointer;
text-align: center;
margin-top: 40px;
width: 100%;
max-width: 320px;
letter-spacing: 0.3px;
}
.bwp-restart-btn-bottom:hover {
background: var(–brand-green);
border-color: var(–brand-green);
color: #ffffff !important;
transform: translateY(-2px);
box-shadow: 0 12px 30px rgba(65, 163, 128, 0.3);
}
.bwp-back-link {
display: block;
margin-top: 30px;
text-align: center;
font-size: 13px;
color: #94a3b8;
cursor: pointer;
transition: color 0.2s;
}
.bwp-restart-link:hover,
.bwp-back-link:hover {
color: var(–brand-navy);
}
/* Upload */
.bwp-file-input {
display: none;
}
.bwp-upload-label {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 50px 40px;
border: 2px dashed rgba(65, 163, 128, 0.4);
border-radius: 16px;
cursor: pointer;
background: rgba(65, 163, 128, 0.02);
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
margin-bottom: 20px;
}
.bwp-upload-label:hover {
border-color: var(–brand-green);
background: rgba(65, 163, 128, 0.06);
transform: scale(1.02);
}
.bwp-upload-icon {
font-size: 42px;
margin-bottom: 15px;
}
/* Results */
/* Results Redesign */
.bwp-result-container {
padding: 0;
background: transparent;
}
.bwp-result-header {
text-align: center;
padding-bottom: 35px;
border-bottom: 1px solid rgba(0, 0, 0, 0.08);
margin-bottom: 35px;
}
.bwp-score-huge {
font-size: 64px;
font-family: ‘Playfair Display’, serif;
font-weight: 700;
line-height: 1;
margin-bottom: 10px;
}
.bwp-verdict-text {
font-weight: 700;
letter-spacing: 1.5px;
font-size: 15px;
text-transform: uppercase;
}
.bwp-ai-content {
font-size: 16px;
line-height: 1.8;
color: #334155;
text-align: left;
}
.bwp-ai-content h3 {
font-family: ‘Playfair Display’, serif;
font-size: 22px;
color: var(–brand-navy);
margin-top: 40px;
margin-bottom: 15px;
font-weight: 700;
border-bottom: 2px solid rgba(65, 163, 128, 0.15);
padding-bottom: 8px;
display: block;
}
.bwp-ai-content p {
margin-bottom: 20px;
}
.bwp-ai-content strong {
color: var(–brand-navy);
font-weight: 600;
background: rgba(65, 163, 128, 0.05);
padding: 0 4px;
border-radius: 4px;
}
/* Hook Box – Animated Gradient Background */
.bwp-hook-box {
margin-top: 60px;
padding: 45px 30px 35px;
border-radius: 24px;
position: relative;
overflow: hidden;
background: linear-gradient(135deg, #e8f5f0, #f0f7ff, #e8f5f0, #f7fdf7);
background-size: 300% 300%;
animation: gradientShift 8s ease infinite;
box-shadow: 0 20px 60px rgba(65, 163, 128, 0.1);
}
@keyframes gradientShift {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
/* Styles to FORCE MailPoet to look good inside the box */
.bwp-hook-box .mailpoet_form,
.bwp-hook-box .mailpoet_form_inner {
background: transparent !important;
border: none !important;
box-shadow: none !important;
padding: 0 !important;
margin: 0 auto !important;
width: 100% !important;
}
.bwp-hook-box .mailpoet_paragraph {
margin-bottom: 15px !important;
}
/* Keep MailPoet text on-brand without overriding font-weight (which would kill MailPoet bold) */
.bwp-hook-box .mailpoet_text,
.bwp-hook-box p.bwp-hook-subtext {
color: #475569 !important;
font-family: ‘Inter’, sans-serif !important;
text-align: center !important;
font-size: 15px !important;
font-weight: 400 !important;
line-height: 1.6 !important;
}
/* Target the email input */
.bwp-hook-box input[type=”email”],
.bwp-hook-box input[type=”text”] {
width: 100% !important;
padding: 18px 20px !important;
border-radius: 16px !important;
border: 1px solid rgba(15, 41, 64, 0.15) !important;
text-align: center !important;
font-size: 16px !important;
font-family: ‘Inter’, sans-serif !important;
background: #ffffff !important;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.03) !important;
margin-bottom: 15px !important;
}
.bwp-hook-box input[type=”email”]:focus,
.bwp-hook-box input[type=”text”]:focus {
border-color: var(–brand-green) !important;
outline: none !important;
box-shadow: 0 0 0 3px rgba(65, 163, 128, 0.2) !important;
}
/* Target the submit button */
.bwp-hook-box input[type=”submit”] {
width: 100% !important;
padding: 18px 20px !important;
border-radius: 16px !important;
background: linear-gradient(135deg, var(–brand-green) 0%, #175e46 100%) !important;
color: #ffffff !important;
font-weight: 700 !important;
font-size: 16px !important;
border: none !important;
cursor: pointer !important;
text-transform: uppercase !important;
letter-spacing: 1px !important;
transition: all 0.2s !important;
box-shadow: 0 10px 25px rgba(65, 163, 128, 0.3) !important;
}
.bwp-hook-box input[type=”submit”]:hover {
transform: translateY(-2px) !important;
box-shadow: 0 12px 25px rgba(65, 163, 128, 0.35) !important;
}
.spinner {
border: 4px solid rgba(65, 163, 128, 0.1);
border-top: 4px solid var(–brand-green);
border-radius: 50%;
width: 48px;
height: 48px;
animation: spin 1s linear infinite;
margin: 0 auto 20px auto;
}
/* Animations */
@keyframes smoothFadeUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes shineBtn {
0% {
left: -100%;
}
20% {
left: 200%;
}
100% {
left: 200%;
}
}
.bwp-question-title {
font-family: ‘Playfair Display’, serif;
font-weight: 700;
font-size: 28px;
color: var(–brand-navy);
margin-bottom: 15px;
text-align: center;
line-height: 1.3;
}
.bwp-question-text {
font-size: 16px;
margin-bottom: 35px;
color: #475569;
text-align: center;
max-width: 90%;
margin-left: auto;
margin-right: auto;
line-height: 1.5;
}
.bwp-options {
display: flex;
gap: 15px;
flex-direction: column;
perspective: 1000px;
}
.bwp-btn {
padding: 18px 25px;
border: 1px solid rgba(0, 0, 0, 0.06);
background: #fff;
border-radius: 16px;
cursor: pointer;
text-align: left;
font-weight: 600;
color: #334155;
font-family: ‘Inter’, sans-serif;
font-size: 15px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.02);
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
transform-style: preserve-3d;
}
.bwp-btn:hover {
border-color: rgba(65, 163, 128, 0.4);
color: var(–brand-green);
transform: translateY(-4px) rotateX(2deg);
box-shadow: 0 10px 25px rgba(65, 163, 128, 0.1);
}
/* Accessibility text box */
#error-message-box {
display: none;
background: rgba(192, 57, 43, 0.05);
border: 1px solid rgba(192, 57, 43, 0.2);
color: var(–brand-red);
padding: 15px;
border-radius: 12px;
margin-top: 15px;
font-size: 14px;
text-align: center;
}
@media (max-width: 600px) {
#bwp-tool-container {
padding: 40px 25px;
}
#bwp-tool-container h2 {
font-size: 32px;
}
.bwp-score-huge {
font-size: 52px;
}
}
#loading-hint {
transition: opacity 0.2s ease;
}
/* Share button */
.bwp-share-btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
background: transparent;
color: var(–brand-navy) !important;
padding: 10px 28px;
font-family: ‘Inter’, sans-serif;
font-weight: 600;
font-size: 14px;
border-radius: 50px;
transition: all 0.25s ease;
border: 1.5px solid rgba(15, 41, 64, 0.18);
cursor: pointer;
margin-top: 14px;
}
.bwp-share-btn:hover {
background: var(–brand-navy);
color: #fff !important;
border-color: var(–brand-navy);
}
/* Category cards */
.bwp-category-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
margin-bottom: 30px;
}
.bwp-category-card {
background: #fff;
border: 1.5px solid rgba(0, 0, 0, 0.06);
border-radius: 16px;
padding: 22px 12px;
text-align: center;
cursor: pointer;
transition: all 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275);
font-family: ‘Inter’, sans-serif;
font-size: 14px;
font-weight: 600;
color: var(–brand-navy);
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.02);
}
.bwp-category-card:hover,
.bwp-category-card.selected {
border-color: var(–brand-green);
background: rgba(65, 163, 128, 0.04);
transform: translateY(-3px);
box-shadow: 0 10px 25px rgba(65, 163, 128, 0.12);
}
.bwp-category-card .cat-icon {
font-size: 30px;
display: block;
margin-bottom: 8px;
}
/* Recent scans */
.bwp-history-wrap {
margin-top: 30px;
padding-top: 24px;
border-top: 1px solid rgba(0, 0, 0, 0.07);
}
.bwp-history-title {
font-size: 12px;
font-weight: 700;
letter-spacing: 1px;
text-transform: uppercase;
color: #94a3b8;
margin-bottom: 12px;
text-align: center;
}
.bwp-history-item {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 14px;
background: #fff;
border-radius: 12px;
margin-bottom: 8px;
font-size: 14px;
font-family: ‘Inter’, sans-serif;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.bwp-history-grade {
font-family: ‘Playfair Display’, serif;
font-weight: 700;
font-size: 22px;
min-width: 32px;
text-align: center;
}
.bwp-history-meta {
flex: 1;
color: #475569;
line-height: 1.4;
}
.bwp-history-meta strong {
display: block;
color: var(–brand-navy);
}
How This Ingredient Safety Checker Works
This free ingredient safety
checker uses AI to analyze product labels in seconds. Take a photo of any ingredient list โ skincare,
cleaning products, baby items, or food โ and get an honest safety assessment grounded in current toxicology
research. No app download needed.
Prefer not to use the
camera? Our 4-question manual checker screens for the most common red flags: vague label claims, missing
third-party certifications, hidden fragrances, and irresponsible packaging. Either way, you’ll know more
than most shoppers ever do.
Want to go deeper? Read our research and guides
on the Live with
Peace blog.
; (function () {
document.addEventListener(“DOMContentLoaded”, function () {
let manualScore = 0;
let scoreHistory = [0];
const apiEndpoint = window.BWP_SCANNER_ENDPOINT || ‘/wp-admin/admin-ajax.php?action=bwp_scanner_proxy’;
// ROTATING LOADING HINTS
const loadingHints = [
“Checking for hidden fragrance compounds…”,
“Scanning for endocrine disruptors…”,
“Cross-referencing third-party certifications…”,
“Looking for greenwashing patterns…”,
“Analyzing preservatives and synthetic additives…”,
“Reviewing ingredient transparency…”
];
let loadingHintInterval = null;
function startLoadingHints() {
const el = document.getElementById(‘loading-hint’);
if (!el) return;
let i = 0;
el.textContent = loadingHints[i];
loadingHintInterval = setInterval(() => {
i = (i + 1) % loadingHints.length;
el.style.opacity = 0;
setTimeout(() => { el.textContent = loadingHints[i]; el.style.opacity = 1; }, 200);
}, 2200);
}
function stopLoadingHints() {
if (loadingHintInterval) { clearInterval(loadingHintInterval); loadingHintInterval = null; }
}
// HELPERS
function addSafeListener(id, event, handler) {
const el = document.getElementById(id);
if (el) {
el.addEventListener(event, handler);
// For accessibility on keyboard focus (Enter key)
if (el.tagName === ‘A’ || el.tagName === ‘LABEL’) {
el.addEventListener(‘keydown’, function (e) {
if (e.key === ‘Enter’ || e.key === ‘ ‘) {
e.preventDefault();
handler(e);
}
});
}
}
}
function showError(msg) {
const errorBox = document.getElementById(‘error-message-box’);
if (errorBox) {
errorBox.innerHTML = msg;
errorBox.style.display = ‘block’;
}
}
function hideError() {
const errorBox = document.getElementById(‘error-message-box’);
if (errorBox) errorBox.style.display = ‘none’;
}
// NAVIGATION
function showScreen(id) {
const sections = document.querySelectorAll(‘.bwp-section’);
sections.forEach(el => el.classList.remove(‘active’));
const target = document.getElementById(id);
if (target) target.classList.add(‘active’);
}
function resetState() {
manualScore = 0;
scoreHistory = [0];
hideError();
const imgInputCam = document.getElementById(‘image-input-camera’);
if (imgInputCam) imgInputCam.value = ”;
const imgInputGal = document.getElementById(‘image-input-gallery’);
if (imgInputGal) imgInputGal.value = ”;
// Clear dynamic AI text
const aiBox = document.getElementById(‘ai-analysis-text’);
if (aiBox) {
aiBox.style.display = ‘none’;
aiBox.innerHTML = ”;
}
}
// EVENT LISTENERS
addSafeListener(‘btn-start-ai’, ‘click’, () => { resetState(); showScreen(‘screen-upload’); });
addSafeListener(‘btn-start-manual’, ‘click’, () => { resetState(); showScreen(‘screen-category’); });
addSafeListener(‘nav-back-start-1’, ‘click’, () => { resetState(); showScreen(‘screen-start’); });
addSafeListener(‘nav-back-start-2’, ‘click’, () => { resetState(); showScreen(‘screen-category’); });
addSafeListener(‘nav-back-cat’, ‘click’, () => { resetState(); showScreen(‘screen-start’); });
addSafeListener(‘nav-scan-another-bottom’, ‘click’, () => { resetState(); showScreen(‘screen-start’); renderHistory(); });
// CATEGORY SELECTION
let selectedCategory = ‘General’;
document.querySelectorAll(‘.bwp-category-card’).forEach(card => {
card.addEventListener(‘click’, () => {
selectedCategory = card.getAttribute(‘data-cat’) || ‘General’;
resetState();
showScreen(‘screen-q1’);
});
});
addSafeListener(‘nav-back-q1’, ‘click’, () => prevQ(‘q1’));
addSafeListener(‘nav-back-q2’, ‘click’, () => prevQ(‘q2’));
addSafeListener(‘nav-back-q3’, ‘click’, () => prevQ(‘q3’));
addSafeListener(‘btn-q1-yes’, ‘click’, () => nextQ(‘q2’, 0));
addSafeListener(‘btn-q1-no’, ‘click’, () => nextQ(‘q2’, 1));
addSafeListener(‘btn-q2-yes’, ‘click’, () => nextQ(‘q3’, 1));
addSafeListener(‘btn-q2-no’, ‘click’, () => nextQ(‘q3’, 0));
addSafeListener(‘btn-q3-no’, ‘click’, () => nextQ(‘q4’, 1));
addSafeListener(‘btn-q3-yes’, ‘click’, () => nextQ(‘q4’, 0));
addSafeListener(‘btn-q4-yes’, ‘click’, () => nextQ(‘finish’, 0));
addSafeListener(‘btn-q4-no’, ‘click’, () => nextQ(‘finish’, 1));
// Share removed โ no unique URL per result possible
let lastResultText = ”;
const imgInputCam = document.getElementById(‘image-input-camera’);
if (imgInputCam) {
imgInputCam.addEventListener(‘change’, function () {
if (this.files && this.files[0]) {
processImage(this.files[0]);
}
});
}
const imgInputGal = document.getElementById(‘image-input-gallery’);
if (imgInputGal) {
imgInputGal.addEventListener(‘change’, function () {
if (this.files && this.files[0]) {
processImage(this.files[0]);
}
});
}
function nextQ(nextScreen, points) {
manualScore += points;
scoreHistory.push(points);
if (nextScreen === ‘finish’) {
displayFinalResult(manualScore, null);
} else {
showScreen(‘screen-‘ + nextScreen);
}
}
function prevQ(prevScreen) {
let last = scoreHistory.pop();
if (last !== undefined) manualScore -= last;
showScreen(‘screen-‘ + prevScreen);
}
function processImage(file) {
const reader = new FileReader();
showScreen(‘screen-loading’);
startLoadingHints();
reader.onload = function (e) {
const base64 = e.target.result.split(‘,’)[1];
callGemini(base64, file.type);
};
reader.onerror = function () {
showError(“Image read error. Please try again or use Manual Mode.”);
showScreen(‘screen-start’);
}
reader.readAsDataURL(file);
}
async function callGemini(base64, mimeType) {
try {
const prompt = ‘Act as an expert toxicologist and consumer advocate. Analyze this product label. 1. Identify brand and product name. 2. Check for toxicity (endocrine disruptors, neurotoxins, hidden fragrances, harsh preservatives) AND ethical concerns (animal-derived ingredients, cruelty-free status), maintaining a helpful, non-judgmental tone. If the product appears free from animal-derived ingredients, say that clearly and also note, in a brief factual way, that products without animal-derived ingredients generally carry a significantly lower environmental footprint than animal-based alternatives. Do not mention bone char, sugar processing edge cases, or cross-contamination unless they are explicitly visible on the label. 3. Identify greenwashing. 4. If the score is 2 or lower, briefly suggest looking for safer alternatives (do NOT include any links). 5. Format analysis using HTML: for headers,
for paragraphs, for ingredients. Return ONLY valid JSON: { “score”: (0 to 4), “verdict”: “string”, “productName”: “string”, “analysis”: “HTML string” }. IMPORTANT: If the photo is a Nutrition Facts panel or unreadable, return score: -1 and a VERY SHORT analysis (1-2 sentences max, NO roleplay introduction) stating e.g., “This looks like a Nutrition Facts panel. Please close this and photograph the actual Ingredient List.”‘;
const response = await fetch(apiEndpoint, {
method: ‘POST’,
headers: { ‘Content-Type’: ‘application/json’ },
body: JSON.stringify({
prompt: prompt,
mimeType: mimeType,
imageData: base64
})
});
const data = await response.json();
if (!response.ok || data.error) {
throw new Error(data.error.message || “API Execution Error”);
}
const text = data.candidates[0].content.parts[0].text;
// JSON is guaranteed by the API config, but wrapping in try-catch as a failsafe
let json;
try {
json = JSON.parse(text);
} catch (parseEx) {
// If formatting glitch happens
json = JSON.parse(text.replace(/(“`json|“`)/g, ”).trim());
}
if (json.score === -1) {
const errorReason = (json.analysis && json.analysis !== “Image unreadable.”) ? json.analysis : “The label was unreadable. Please ensure the text is clear and well-lit.”;
showError(errorReason);
showScreen(‘screen-start’);
return;
}
displayFinalResult(json.score, json.analysis, json.productName || ‘Unknown Product’);
} catch (e) {
console.error(“Gemini API Error:”, e);
showError(‘AI Error: ‘ + e.message + ‘.
Falling back to Manual Mode.’);
// Proceed to manual mode gently
setTimeout(() => { showScreen(‘screen-q1’); }, 2500);
}
}
function displayFinalResult(score, aiAnalysisText, productName) {
stopLoadingHints();
showScreen(‘screen-result’);
const scoreDisplay = document.getElementById(‘score-display’);
const verdictDisplay = document.getElementById(‘verdict-display’);
const aiBox = document.getElementById(‘ai-analysis-text’);
const hookText = document.getElementById(‘hook-text’);
// Manual mode: inject a rich, educational summary into the analysis box
const manualSummaries = {
‘4’: `What This Means
This product passed all four of our key screening signals. It avoids vague marketing language, shows real third-party certifications, doesn’t rely on hidden fragrance compounds, and uses responsible packaging materials. That’s a clean sweep – relatively rare.
Keep an eye on the full ingredient list for anything unfamiliar, but based on these signals, you’re looking at one of the more transparent products out there.
`,
‘3’: `What This Means
This product does most things right. It scored well on the most critical indicators – likely has real certifications or clear ingredient transparency – but flagged one area worth a closer look.
A single red flag doesn’t necessarily make a product unsafe, but it’s worth checking what that specific concern is. Consider it a B – good, not perfect.
`,
‘2’: `What This Means
This product shows mixed signals. It passed some checks but failed others. This is common with “natural” or “clean” brands that invest in marketing language without the third-party verification to back it up.
A C score doesn’t mean it’s toxic – but it means you can’t fully trust the label claims. We’d recommend digging into the full ingredient list or switching to a verified alternative.
`,
‘1’: `What This Means
This product raised multiple red flags. It likely uses vague environmental or wellness language, relies on self-created icons instead of independent certifications, and may contain concerning ingredients hiding behind umbrella terms like “Fragrance.”
Products at this score often rely on consumer trust without earning it. We’d encourage you not to give it the benefit of the doubt – safer alternatives exist.
`,
‘0’: `What This Means
This product failed every screening signal. It uses unverified marketing language, lacks real certifications, likely contains hidden fragrance compounds or harsh preservatives, and uses difficult-to-recycle packaging.
This is a textbook example of greenwashing – the gap between how a product presents itself and what it actually contains. We strongly recommend switching to a rigorously vetted alternative.
`
};
// Inject AI text if present; otherwise inject manual summary
if (aiAnalysisText) {
aiBox.style.display = ‘block’;
const leadMagnetCTA = ‘Want to stop guessing?
Sign up for our newsletter below to access the Live with Peace Verified Protocolโour exclusive, curated set of safe recommendations.
‘;
aiBox.innerHTML = ‘Findings
‘ + aiAnalysisText + leadMagnetCTA;
} else {
const certBlock = ‘What to look for instead:
Look for products with EWG Verified, USDA Organic, or B-Corp certification – these require independent audits and are not self-awarded.
‘;
const key = String(Math.min(score, 4));
const summaryData = {
‘4’: manualSummaries[‘4’],
‘3’: manualSummaries[‘3’],
‘2’: manualSummaries[‘2’],
‘1’: manualSummaries[‘1’] + certBlock,
‘0’: manualSummaries[‘0’] + certBlock
};
aiBox.style.display = ‘block’;
aiBox.innerHTML = summaryData[key] || summaryData[‘0’];
}
// Honest, easy-to-understand copywriting based on score (A+, B, C, D, F)
let gradeLabel = ‘F’, verdictLabel = ‘HIGH GREENWASHING RISK’, gradeColor = ‘var(–brand-red)’;
let hookMsg = ‘Potential toxins and greenwashing detected.’;
if (score >= 4) {
gradeLabel = ‘A+’; verdictLabel = ‘VERIFIED CLEAR’; gradeColor = ‘var(–brand-green)’;
hookMsg = ‘This formulation looks great! Build the rest of your safe routines.’;
// Confetti!
if (typeof confetti === ‘function’) {
confetti({ particleCount: 100, spread: 70, origin: { y: 0.6 }, colors: [‘#41A380’, ‘#0B1E2E’, ‘#D4AF37’] });
}
} else if (score === 3) {
gradeLabel = ‘B’; verdictLabel = ‘MOSTLY CLEAN’; gradeColor = ‘#2ecc71’;
hookMsg = ‘Pretty good – with a couple things worth knowing.’;
} else if (score === 2) {
gradeLabel = ‘C’; verdictLabel = ‘PROCEED WITH CAUTION’; gradeColor = ‘var(–brand-yellow)’;
hookMsg = ‘Mixed signals detected. Stop the guesswork.’;
} else if (score === 1) {
gradeLabel = ‘D’; verdictLabel = ‘SEVERAL CONCERNS FOUND’; gradeColor = ‘#e67e22’;
hookMsg = ‘This one has real red flags. Discover genuinely safer alternatives.’;
}
scoreDisplay.innerHTML = gradeLabel;
scoreDisplay.style.color = gradeColor;
verdictDisplay.innerHTML = verdictLabel;
verdictDisplay.style.color = gradeColor;
hookText.innerHTML = hookMsg;
// Note for history
lastResultText = gradeLabel + ‘ – ‘ + verdictLabel;
saveToHistory(gradeLabel, gradeColor, verdictLabel, selectedCategory, hookMsg, productName || (selectedCategory + ‘ product’));
}
// โโ HISTORY โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
function saveToHistory(grade, color, verdict, category, hook, name) {
try {
const scans = JSON.parse(localStorage.getItem(‘bwp_scans’) || ‘[]’);
scans.unshift({ grade, color, verdict, category, hook: hook || ”, name: name || category, date: new Date().toLocaleDateString(‘en-US’, { month: ‘short’, day: ‘numeric’ }) });
localStorage.setItem(‘bwp_scans’, JSON.stringify(scans.slice(0, 5)));
} catch (e) { }
}
function renderHistory() {
try {
const scans = JSON.parse(localStorage.getItem(‘bwp_scans’) || ‘[]’);
const panel = document.getElementById(‘history-panel’);
const list = document.getElementById(‘history-list’);
if (!panel || !list || scans.length === 0) return;
let htmlStr = ”;
for (let i = 0; i < scans.length; i++) {
const s = scans[i];
const nameLabel = s.name || s.category;
const hookLine = s.hook ? '‘ + s.hook + ‘
‘ : ”;
htmlStr += ``
+ ‘
‘
+ ‘
‘ + s.grade + ‘
‘
+ ‘
‘
+ ‘‘ + nameLabel + ‘‘
+ ‘‘ + s.category + ‘ – ‘ + s.date + ‘‘
+ ‘
‘
+ ‘
⌄‘
+ ‘
‘
+ ‘
‘
+ ‘
‘ + s.verdict + ‘
‘
+ hookLine
+ ‘
‘
+ ‘
‘;
}
list.innerHTML = htmlStr;
// Handle expand/collapse via event delegation
list.querySelectorAll(‘.bwp-history-item’).forEach(function (item) {
item.addEventListener(‘click’, function () {
const detail = this.querySelector(‘.bwp-hist-detail’);
const arrow = this.querySelector(‘.bwp-hist-arrow’);
if (detail) {
const isOpen = detail.style.display !== ‘none’;
detail.style.display = isOpen ? ‘none’ : ‘block’;
if (arrow) arrow.style.transform = isOpen ? ” : ‘rotate(180deg)’;
}
});
});
panel.style.display = ‘block’;
} catch (e) { }
}
// Render on load
renderHistory();
});
})();