Diagnose Your Marketing in 5 Steps
Find and fix the leaks holding your marketing back. In just 5 quick steps, you’ll uncover where results are slipping – and get a personalised solution.
- Pinpoint blind spots across brand, message and funnel
- Get instant insights and tailored fixes
- Built by Mip Phillips – BIG IDEAS. Branding. AI.
(function(){
const CONFIG = {
MAILCHIMP: {
ACTION: ‘https://mipphillips.us12.list-manage.com/subscribe/post?u=15d3d4b49920c96e2f49b3fbe&id=77720160eb&f_id=0084e7e0f0’,
COMPLETED_TAGS: [‘Pain Point Finder’]
},
LINKS: {
BOOK_A_CALL: ‘https://calendly.com/mipphillips/45min’,
PRIVACY: ‘/privacy-policy/’
},
/* On-site AI: same-origin fetch of selected pages (extend SOURCES as needed) */
AI: { ENABLED:true, SOURCES:[‘/’] }
};
const root = document.getElementById(‘mipf-root’);
if(!root) return;
/* ———- State ———- */
const State = {
step: 0, steps: [‘Symptoms’,’Brand’,’Performance’,’AI’,’Details’],
symptoms: new Set(),
brand: {q1:3,q2:3,q3:3,q4:3,q5:3},
perf: {q1:3,q2:3,q3:3,q4:3,q5:3},
ai: {q1:3,q2:3,q3:3,q4:3,q5:3},
user: {fname:”,lname:”,email:”,company:”,wantsEmail:true},
scores:{bigidea:0,branding:0,funnel:0,aienable:0},
siteIndex: null
};
const q = (sel,scope=root)=>scope.querySelector(sel);
const avg = o => Object.values(o).reduce((a,b)=>a+Number(b),0)/Object.keys(o).length;
const pill = (l,v)=>`${l}${v}`;
const scoreLabel = n => n<50?'Needs Focus':(n{
mipfUpdateRangeFill(r);
r.addEventListener(‘input’,()=>mipfUpdateRangeFill(r));
r.addEventListener(‘change’,()=>mipfUpdateRangeFill(r));
});
}
/* ———- Scoring ———- */
function computeScores(){
const s = State.symptoms;
let brandBias=0, ideaBias=0, perfBias=0, aiBias=0;
if(s.has(‘leads’)) perfBias+=10;
if(s.has(‘brand-tired’)) brandBias+=10;
if(s.has(‘no-standout’)) ideaBias+=12;
if(s.has(‘busy’)) perfBias+=6;
if(s.has(‘unclear’)) brandBias+=10;
if(s.has(‘wasted’)) perfBias+=10;
if(s.has(‘no-big-idea’)) ideaBias+=18;
if(s.has(‘no-ai’)) aiBias+=12;
const branding = Math.min(100, Math.round((avg(State.brand)*20) + brandBias));
const funnel = Math.min(100, Math.round((avg(State.perf)*20) + perfBias));
const ai = Math.min(100, Math.round((avg(State.ai)*20) + aiBias));
const bigidea = Math.min(100, Math.round(((State.brand.q3||3)*20) + ideaBias));
State.scores = { bigidea, branding, funnel, aienable: ai };
}
function primarySecondary(){
const e = Object.entries(State.scores).sort((a,b)=>a[1]-b[1]);
return {primary:e[0], secondary:e[1]};
}
/* ———- AI (client-side, on-site) ———- */
function extractReadableText(html){
const doc = new DOMParser().parseFromString(html, ‘text/html’);
[‘header’,’nav’,’footer’,’aside’,’form’,’noscript’,’iframe’,’script’,’style’,’menu’,’button’]
.forEach(sel => doc.querySelectorAll(sel).forEach(n=>n.remove()));
const text = (doc.body && doc.body.textContent ? doc.body.textContent : ”)
.replace(/\s+/g,’ ‘)
.trim();
return text;
}
async function buildSiteIndex(){
if(State.siteIndex) return State.siteIndex;
const out = [];
for(const path of (CONFIG.AI.SOURCES||[‘/’])){
try{
const url = new URL(path, window.location.origin).toString();
const res = await fetch(url, {credentials:’omit’});
if(!res.ok) continue;
const html = await res.text();
const text = extractReadableText(html);
if(text && text.length > 150) out.push({url, text});
}catch(e){ /* ignore */ }
}
State.siteIndex = out;
return out;
}
function isMenuLikeSentence(s){
const trimmed = s.trim();
if(trimmed.length 6) return true;
const words = trimmed.split(/\s+/);
if (words.length && words.filter(w=>w.length 0.6) return true;
return false;
}
function conversationalAnswer(question, pageText){
const BLOCK = /(skip to content|privacy|cookies?|subscribe|sign[-\s]?up|menu|search|contact|©|terms|policy)/i;
const CTA = /(book a\s+\d+\s*(?:min|minute)s?\s*call|book a call)/i;
const qTokens = question.toLowerCase().split(/\W+/).filter(Boolean);
const sentences = pageText
.replace(/[:;]\s*—/g,’—’)
.split(/(?s.trim())
.filter(Boolean)
.filter(s => !isMenuLikeSentence(s) && !BLOCK.test(s) && !CTA.test(s))
.slice(0, 800);
function score(sent){
let sc=0;
const t = sent.toLowerCase();
qTokens.forEach(tok => { if (t.includes(tok)) sc += Math.max(1, tok.length/4); });
if (/\b(brand|big idea|positioning|creative|marketing|roi|funnel|customer|ai|automation|content|strategy)\b/i.test(sent)) sc += 1.2;
const len = sent.length;
if(len>=60 && len({s,score:score(s)}))
.filter(x=>x.score>0.6)
.sort((a,b)=>b.score-a.score)
.slice(0,3)
.map(x=>x.s);
if(ranked.length===0) return null;
const ordered = sentences.filter(s=>ranked.includes(s)).slice(0,3);
const body = ordered.join(‘ ‘);
return `Here’s what I found based on your question:\n${body}\n\nFor a tailored plan, BOOK A CALL and we’ll map it to your brand.`;
}
function answerFromIndex(question, index){
if(!index || !index.length) return null;
const qTokens = question.toLowerCase().split(/\W+/).filter(Boolean);
let best = {score:0, page:null};
for(const page of index){
const t = page.text.toLowerCase();
let s=0; qTokens.forEach(tok=>{ if(t.includes(tok)) s += Math.max(1, tok.length/4); });
if(s>best.score){ best={score:s, page}; }
}
if(!best.page) return null;
const conv = conversationalAnswer(question, best.page.text);
return conv || null;
}
function pushLog(text, me){
const log = q(‘#mipf-aiLog’);
const d = document.createElement(‘div’);
d.className = ‘mipf-ai-msg’ + (me ? ‘ mipf-me’ : ”);
d.textContent = text;
log.appendChild(d);
log.scrollTo({top:log.scrollHeight, behavior:’smooth’});
}
async function handleAsk(){
const input = q(‘#mipf-aiText’);
const qtxt = input.value.trim(); if(!qtxt) return;
input.value=”; pushLog(qtxt,true);
const log = q(‘#mipf-aiLog’);
const thinking = document.createElement(‘div’);
thinking.className=’mipf-thinking mipf-anim’;
thinking.textContent=’Thinking…’;
log.appendChild(thinking);
log.scrollTo({top:log.scrollHeight, behavior:’smooth’});
await new Promise(r=>setTimeout(r,1000)); // human feel
let answer=”;
try{
if(CONFIG.AI.ENABLED){
const idx = await buildSiteIndex();
answer = answerFromIndex(qtxt, idx) ||
‘I couldn’t find that clearly on the site. Try a different phrasing, or BOOK A CALL and I’ll walk you through it.’;
}else{
const {primary}=primarySecondary(); const map={bigidea:’BIG IDEA’,branding:’Branding’,aienable:’AI’,funnel:’Funnel’};
answer = `Here’s the play: prioritise ${map[primary[0]]}. Start with one quick win above. BOOK A CALL and I’ll show you how to apply this to your brand.`;
}
}catch(e){
answer = ‘The on-site AI helper is offline right now. Use the Quick Wins above. BOOK A CALL for a tailored plan.’;
}
try{ thinking.remove(); }catch(e){}
pushLog(answer,false);
}
/* ———- Views ———- */
function renderStepper(){
const w = q(‘.mipf-stepper’); if(!w) return; w.innerHTML=”;
State.steps.forEach((name,i)=>{
const d = document.createElement(‘div’);
d.className = ‘mipf-step’ + (i===State.step ? ‘ mipf-active’:”);
d.innerHTML = ‘‘+name+’‘;
w.appendChild(d);
});
}
function rangeRow(g,k,label){
return `
`;
}
function viewSymptoms(){
const opts = [
{id:’leads’,label:”We’re not attracting the right kind of leads.”},
{id:’brand-tired’,label:’Our brand looks tired or inconsistent.’},
{id:’no-standout’,label:’We don’t stand out from competitors.’},
{id:’busy’,label:’Our marketing feels busy but ineffective.’},
{id:’unclear’,label:’People don’t understand what we do or why we’re different.’},
{id:’wasted’,label:’We’re wasting money on ads that don’t convert.’},
{id:’no-big-idea’,label:’We don’t have one clear BIG IDEA guiding our campaigns.’},
{id:’no-ai’,label:’We’re not sure how to use AI properly in our marketing.’}
];
const checks = opts.map(o=>`
`).join(”);
return `
`;
}
function viewBrand(){
return `
`;
}
function viewPerf(){
return `
`;
}
function viewAI(){
return `
`;
}
function viewDetails(){
return `
`;
}
function viewResults(){
computeScores();
const {primary, secondary} = primarySecondary();
const map = {
bigidea:{title:’No BIG IDEA’}, branding:{title:’Unclear Positioning’},
aienable:{title:’AI Without Outcomes’}, funnel:{title:’Leaky Funnel’}
};
const p = map[primary[0]]; const s = map[secondary[0]];
return `
`;
}
function fillQuickWins(){
const {primary} = primarySecondary();
const ul = q(‘#mipf-quickWins’); if(!ul) return;
const items = {
bigidea:[
‘Define one unifying idea that threads through all channels.’,
‘Logo-off test: is it still recognisably you?’,
‘Ship one campaign across three formats this week.’
],
branding:[
‘Rewrite your positioning in one sentence.’,
‘Create a one-page brand do/don’t for the team.’,
‘Audit five touchpoints and fix inconsistencies.’
],
aienable:[
‘Pick one process and reduce time by 50% with AI.’,
‘Create a shared prompt library in your voice.’,
‘Measure time saved and reinvest into testing.’
],
funnel:[
‘Map your buyer journey and mark three friction points.’,
‘Add a clearer CTA to your top page.’,
‘Set one re-engagement step for dropped leads.’
]
}[primary[0]];
ul.innerHTML = items.map(i=>`${i} `).join(”);
}
/* ———- Mailchimp ———- */
function showMcStatus(msg, ok=false){
const el = q(‘#mipf-mcStatus’); if(!el) return;
el.style.display=’block’;
el.style.color = ok ? ‘#b7f7b7’ : ‘#ffb4b4’;
el.textContent = msg;
}
function subscribeMailchimp(data, cb){
const action = CONFIG.MAILCHIMP.ACTION;
if(!action){ showMcStatus(‘Mailchimp form action is not set.’, false); cb && cb({ok:false,reason:’no-action’}); return; }
const base = action.replace(‘/post?’, ‘/post-json?’);
const params = new URLSearchParams();
params.append(‘FNAME’, data.fname||”);
params.append(‘LNAME’, data.lname||”);
params.append(‘EMAIL’, data.email||”);
if(data.company) params.append(‘COMPANY’, data.company);
(CONFIG.MAILCHIMP.COMPLETED_TAGS||[]).forEach(t=> params.append(‘tags[]’, t));
const cbName = ‘mipf_cb_’+Math.random().toString(36).slice(2);
params.append(‘c’, cbName);
const url = base + ‘&’ + params.toString();
const s = document.createElement(‘script’); s.src = url; s.async = true;
window[cbName] = function(resp){
try{ document.head.removeChild(s);}catch(e){}
try{ delete window[cbName]; }catch(e){}
cb && cb({ok: resp && resp.result===’success’, resp});
};
s.onerror = function(){
try{ document.head.removeChild(s);}catch(e){}
try{ delete window[cbName]; }catch(e){}
cb && cb({ok:false, reason:’network’});
};
document.head.appendChild(s);
}
/* ———- Render + handlers ———- */
function renderShell(){
if(!q(‘.mipf-container’)){
root.innerHTML = `
`;
q(‘#mipf-bookCallFooter’).addEventListener(‘click’, ()=> window.open(CONFIG.LINKS.BOOK_A_CALL,’_blank’));
}
}
function render(){
renderShell();
renderStepper();
const views = [ ()=>viewSymptoms(), ()=>viewBrand(), ()=>viewPerf(), ()=>viewAI(), ()=>viewDetails(), ()=>viewResults() ];
q(‘#mipf-view’).innerHTML = views[State.step]();
mipfInitRangeFills(q(‘#mipf-view’)); // ensure the green fill appears
if(State.step===5) fillQuickWins();
const view = q(‘#mipf-view’);
// Navigation
view.querySelectorAll(‘[data-next]’).forEach(b=> b.addEventListener(‘click’, ()=>{ State.step=Math.min(State.step+1,5); render(); }));
view.querySelectorAll(‘[data-back]’).forEach(b=> b.addEventListener(‘click’, ()=>{ State.step=Math.max(State.step-1,0); render(); }));
// Symptoms
view.querySelectorAll(‘input[type=checkbox][data-sym]’).forEach(ch=>{
ch.addEventListener(‘change’, ()=>{
const id=ch.getAttribute(‘data-sym’);
if(ch.checked) State.symptoms.add(id); else State.symptoms.delete(id);
});
});
// Ranges
view.querySelectorAll(‘input[type=range][data-range]’).forEach(r=>{
r.addEventListener(‘input’, ()=>{
const [g,k]=r.getAttribute(‘data-range’).split(‘:’);
State[g][k]=r.value;
r.parentElement.querySelector(‘div:last-child’).textContent=r.value;
});
});
// Finish -> subscribe + results
const see = q(‘#mipf-seeResults’);
if(see){
see.addEventListener(‘click’, ()=>{
State.user.fname = (q(‘#mipf-fname’) || {}).value?.trim() || ”;
State.user.lname = (q(‘#mipf-lname’) || {}).value?.trim() || ”;
State.user.email = (q(‘#mipf-email’) || {}).value?.trim() || ”;
State.user.company = (q(‘#mipf-company’) || {}).value?.trim() || ”;
State.user.wantsEmail = !!(q(‘#mipf-wantsemail’) && q(‘#mipf-wantsemail’).checked);
const emailOk = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(State.user.email||”);
if(!State.user.fname || !State.user.lname || !emailOk){
showMcStatus(‘Please enter a valid first name, last name and email address.’, false);
return;
}
computeScores();
if(State.user.wantsEmail){
showMcStatus(‘Subscribing…’);
subscribeMailchimp({
fname:State.user.fname, lname:State.user.lname, email:State.user.email, company:State.user.company
}, ({ok,resp,reason})=>{
if(ok){
const m = (resp && resp.msg) ? String(resp.msg) : ”;
showMcStatus(/confirm|opt-?in/i.test(m) ? ‘Subscribed. Please confirm your email.’ : ‘Subscribed. Check your inbox for your results.’, true);
}else{
let msg=’Could not subscribe right now.’;
if(reason===’no-action’) msg=’Mailchimp not configured.’;
else if(reason===’network’) msg=’Network error while contacting Mailchimp.’;
else if(resp && resp.msg) msg=String(resp.msg).replace(/&/g,’&’);
showMcStatus(msg,false);
}
State.step=5; render();
});
} else {
State.step=5; render();
}
});
}
// AI ask
const askBtn = q(‘#mipf-askBtn’);
if(askBtn){ askBtn.addEventListener(‘click’, handleAsk); }
// Print
const printBtn = q(‘#mipf-printBtn’);
if(printBtn){ printBtn.addEventListener(‘click’, ()=>window.print()); }
}
if(document.readyState === ‘loading’){
document.addEventListener(‘DOMContentLoaded’, render);
} else {
render();
}
})();
${label}
1 = strongly disagree · 5 = strongly agree
${State[g][k]}
Step 1 · Symptoms
Select all that apply.
${checks}
Step 2 · Brand & Message
${rangeRow(‘brand’,’q1′,’People instantly understand what our brand stands for.’)} ${rangeRow(‘brand’,’q2′,’Our visual identity and tone are consistent everywhere.’)} ${rangeRow(‘brand’,’q3′,’We have a clear positioning statement everyone knows.’)} ${rangeRow(‘brand’,’q4′,’Prospects remember us unprompted after they’ve seen our marketing.’)} ${rangeRow(‘brand’,’q5′,’We regularly review whether our brand still feels relevant.’)}Step 3 · Performance & Funnel
${rangeRow(‘perf’,’q1′,’Our marketing attracts the right type of customers.’)} ${rangeRow(‘perf’,’q2′,’We convert interest into measurable action.’)} ${rangeRow(‘perf’,’q3′,’We know where prospects drop off in the buyer journey.’)} ${rangeRow(‘perf’,’q4′,’We have strategies to re-engage lost leads.’)} ${rangeRow(‘perf’,’q5′,’Our campaigns deliver a clear ROI.’)}Step 4 · AI Enablement
${rangeRow(‘ai’,’q1′,’We use AI to speed up content creation or idea generation.’)} ${rangeRow(‘ai’,’q2′,’We know which AI tools best support our goals.’)} ${rangeRow(‘ai’,’q3′,’We have clear rules and prompts for AI use in marketing.’)} ${rangeRow(‘ai’,’q4′,’AI has reduced time or cost in measurable ways.’)} ${rangeRow(‘ai’,’q5′,’AI helps us generate creative ideas that feel on-brand.’)}Step 5 · Your Details
By submitting, you agree to receive occasional marketing emails from Mip Phillips Creative Marketing. You can unsubscribe at any time. See our Privacy Policy.
Your Diagnosis
Primary: ${p.title}
Secondary: ${s.title}
${pill(‘BIG IDEA’, `${State.scores.bigidea}/100 — ${scoreLabel(State.scores.bigidea)}`)}
${pill(‘Branding’, `${State.scores.branding}/100 — ${scoreLabel(State.scores.branding)}`)}
${pill(‘AI’, `${State.scores.aienable}/100 — ${scoreLabel(State.scores.aienable)}`)}
${pill(‘Funnel’, `${State.scores.funnel}/100 — ${scoreLabel(State.scores.funnel)}`)}
Three Quick Wins
If you have more questions ask them here.
Got questions about BIG IDEA Marketing, Branding or AI? Ask them here.
The AI will not link off-site. It answers from your website content.
Find What’s Blocking Your Marketing Results
Five quick steps. Get a crisp diagnosis and fixes to act on today.
