<!-- O-Shot® Self-Test with Name/Email/Phone + mailto email (front-end only) -->
<div id="oshot-selftest" class="oshot-wrap" data-version="1.2" aria-live="polite"></div>
<style>
#oshot-selftest {
--bg:#ffffff;
--text:#111827;
--muted:#6b7280;
--border:#e5e7eb;
--brand:#4f46e5;
--brand-2:#4338ca;
--card:#ffffff;
--soft:#f9fafb;
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, "Apple Color Emoji","Segoe UI Emoji";
color: var(--text);
}
#oshot-selftest * { box-sizing: border-box; }
#oshot-selftest .container { max-width: 720px; margin: 24px auto; padding: 0 16px; }
#oshot-selftest h1 { font-size: 1.5rem; margin: 0 0 6px; font-weight: 800; }
#oshot-selftest p.sub { margin: 0 0 12px; color: var(--muted); font-size: .95rem; }
#oshot-selftest .card {
background: var(--card);
border: 1px solid var(--border);
border-radius: 16px;
padding: 20px;
box-shadow: 0 1px 2px rgba(0,0,0,.04);
}
#oshot-selftest .progress { margin-bottom: 14px; }
#oshot-selftest .progress .row {
display:flex;
justify-content:space-between;
font-size:.75rem;
color: var(--muted);
margin-bottom:6px;
}
#oshot-selftest .bar { height:8px; background: var(--border); border-radius:999px; overflow:hidden; }
#oshot-selftest .bar > span {
display:block;
height:8px;
width:0%;
background: var(--brand);
border-radius:999px;
transition: width .25s ease;
}
#oshot-selftest .q-label { font-weight: 700; margin-bottom: 10px; }
#oshot-selftest .options { display:grid; gap:8px; }
#oshot-selftest .opt {
border:1px solid var(--border);
border-radius: 12px;
padding:12px 14px;
cursor:pointer;
transition: box-shadow .15s, border-color .15s;
}
#oshot-selftest .opt:hover { box-shadow: 0 2px 10px rgba(0,0,0,.06); }
#oshot-selftest .opt.selected {
#oshot-selftest .opt.selected {
background: var(--brand); /* same color as Next button */
color: #ffffff; /* readable text */
border-color: var(--brand); /* unify border with theme */
box-shadow: 0 0 0 2px rgba(79,70,229,.25);
}
#oshot-selftest .opt input { display:none; }
#oshot-selftest .actions {
display:flex;
gap:10px;
margin-top:16px;
flex-wrap:wrap;
}
#oshot-selftest .btn {
border-radius:12px;
padding:10px 14px;
font-size:.9rem;
border:1px solid var(--border);
background:#fff;
cursor:pointer;
}
#oshot-selftest .btn.primary {
background: #4f46e5;
color:#ffffff;
border-color: #4f46e5;
}
#oshot-selftest .btn.primary:hover {
background: var(--brand-2);
border-color: var(--brand-2);
}
#oshot-selftest .btn:disabled { opacity:.6; cursor:not-allowed; }
#oshot-selftest .muted { color: var(--muted); font-size:.85rem; }
#oshot-selftest .grid { display:grid; gap:14px; }
#oshot-selftest .scoreline {
display:flex;
align-items:baseline;
gap:10px;
}
#oshot-selftest .scoreline .raw {
font-size: 2rem;
font-weight: 900;
}
#oshot-selftest .callout {
background: var(--soft);
border:1px solid var(--border);
border-radius:14px;
padding:14px;
}
#oshot-selftest .cta { margin-top:16px; }
#oshot-selftest .cta h3 { margin:0 0 8px; font-size:1.05rem; font-weight:800; }
#oshot-selftest .cta .cta-row {
display:flex;
gap:10px;
flex-wrap:wrap;
margin-top:12px;
}
#oshot-selftest .cta a,
#oshot-selftest .cta button { text-decoration:none; }
#oshot-selftest .sms { background:#111827; color:#fff; }
/* Lead form */
#oshot-selftest .lead {
margin-top:14px;
border:1px dashed var(--border);
border-radius:12px;
padding:12px;
}
#oshot-selftest .lead h4 {
margin:0 0 8px;
font-size:1rem;
font-weight:800;
}
#oshot-selftest .fld {
display:flex;
flex-direction:column;
gap:6px;
margin-bottom:10px;
}
#oshot-selftest .fld input[type="text"],
#oshot-selftest .fld input[type="email"],
#oshot-selftest .fld input[type="tel"] {
padding:10px 12px;
border:1px solid var(--border);
border-radius:10px;
}
#oshot-selftest .agree {
display:flex;
align-items:flex-start;
gap:8px;
font-size:.9rem;
margin-bottom:8px;
}
#oshot-selftest .ok { color:#065f46; font-weight:700; }
#oshot-selftest footer {
margin-top:14px;
color: var(--muted);
font-size:.8rem;
}
@media (prefers-color-scheme: dark) {
#oshot-selftest {
--bg:#0b0d12;
--text:#e5e7eb;
--muted:#9ca3af;
--border:#1f2937;
--card:#0f1320;
--soft:#111827;
--brand:#6366f1;
--brand-2:#4f46e5;
}
#oshot-selftest .btn {
background:#0f1320;
color:#e5e7eb;
border-color:var(--border);
}
#oshot-selftest .fld input {
background:#0f1320;
color:#e5e7eb;
border-color:var(--border);
}
}
</style>
<script>
(() => {
const el = document.getElementById('oshot-selftest');
if (!el) return;
// 🔴 CHANGE THIS to your clinic email:
const clinicEmail = "YOUR_CLINIC_EMAIL_HERE"; // e.g. "info@cwaesthetics.com"
const QUIZ = {
title: "O-Shot® Self-Test",
subtitle: "Answer these quick questions to see if the O-Shot® may be right for you. This is not medical advice.",
disclaimer: "Results are educational only. Please schedule a consultation to confirm candidacy.",
// Doubled weights → max score = 32
questions: [
{ id:"q1", label:"Do you have vaginal dryness?", required:true, options:[
{value:"yes", label:"Yes", weight:4},
{value:"no", label:"No", weight:0}
]},
{ id:"q2", label:"Do you notice less sensation?", required:true, options:[
{value:"yes", label:"Yes", weight:4},
{value:"no", label:"No", weight:0}
]},
{ id:"q3", label:"Has your libido changed?", required:true, options:[
{value:"decreased", label:"Yes – decreased", weight:2},
{value:"same", label:"No change", weight:0}
]},
{ id:"q4", label:"Any pain with sex?", required:true, options:[
{value:"yes", label:"Yes", weight:4},
{value:"sometimes", label:"Sometimes", weight:2},
{value:"no", label:"No", weight:0}
]},
{ id:"q5", label:"Do you have bladder leaking or need to rush to the bathroom?", required:true, options:[
{value:"often", label:"Often", weight:4},
{value:"sometimes", label:"Sometimes", weight:2},
{value:"rarely", label:"Rarely/No", weight:0}
]},
{ id:"q6", label:"If you have had any pregnancies, were any with large babies?", required:false, options:[
{value:"yes", label:"Yes", weight:2},
{value:"no", label:"No", weight:0},
{value:"na", label:"Not applicable", weight:0}
]},
{ id:"q7", label:"If you had a vaginal delivery, did you have bad vaginal tears?", required:false, options:[
{value:"yes", label:"Yes", weight:4},
{value:"no", label:"No", weight:0},
{value:"na", label:"Not applicable", weight:0}
]},
{ id:"q8", label:"Have you had less self-confidence with your sexual wellness?", required:true, options:[
{value:"yes", label:"Yes", weight:2},
{value:"no", label:"No", weight:0}
]},
{ id:"q9", label:"Have symptoms affected your relationship with a partner?", required:true, options:[
{value:"yes", label:"Yes", weight:2},
{value:"no", label:"No", weight:0}
]},
{ id:"q10", label:"Do you want to improve your intimate wellness?", required:true, options:[
{value:"yes", label:"Yes", weight:2},
{value:"no", label:"No", weight:0}
]},
{ id:"q11", label:"Are you premenopausal, perimenopausal, or postmenopausal?", required:true, options:[
{value:"premeno", label:"Premenopausal", weight:0},
{value:"perimeno", label:"Perimenopausal", weight:2},
{value:"postmeno", label:"Postmenopausal", weight:2}
]}
],
result: {
title: "Your O-Shot® Readiness Snapshot",
body: "Based on your answers, your raw score reflects how closely your concerns align with common O-Shot® goals. Use the guide below, then schedule a private consult to confirm candidacy.",
guide: [
{range:"0–12", label:"The O-Shot® may be helpful. You may also benefit from hormone and wellness therapies."},
{range:"13–24", label:"You are showing moderate signs that the O-Shot® could help improve your intimate wellness."},
{range:"≥25", label:"You may be an excellent candidate for the O-Shot® and could experience significant improvement in sensitivity, dryness, and overall function."}
],
ctaHeadline: "Ready to set up your consultation?",
ctaSmsText: "Text OSHOT to 770-649-0094",
ctaSmsHref: "sms:+17706490094?body=OSHOT",
ctaBookText: "Book a Virtual Consult",
ctaBookHref: "https://oshotatlanta.com"
}
};
const answers = {};
let step = 0;
let lastScore = 0;
let lastMax = 0;
const $ = (s, r = el) => r.querySelector(s);
const $$ = (s, r = el) => Array.from(r.querySelectorAll(s));
function maxPossiblePoints(questions) {
return questions.reduce((sum, q) => {
const maxW = Math.max(...q.options.map(o => o.weight || 0));
return sum + (isFinite(maxW) ? maxW : 0);
}, 0);
}
function totalScore(questions, answersObj) {
return questions.reduce((sum, q) => {
const v = answersObj[q.id];
const opt = (q.options || []).find(o => o.value === v);
return sum + (opt ? (opt.weight || 0) : 0);
}, 0);
}
function render() {
const qs = QUIZ.questions;
const isDone = step >= qs.length;
el.innerHTML = `
<div class="container">
<header>
<h1>${QUIZ.title}</h1>
<p class="sub">${QUIZ.subtitle}</p>
</header>
<div class="card">
${!isDone ? renderQuestion(qs) : renderResults(qs)}
</div>
<footer>
Educational tool only. © ${new Date().getFullYear()} Cobb Wellness & Aesthetics — All rights reserved.
</footer>
</div>
`;
if (!isDone) bindQuestionHandlers(qs);
else bindResultHandlers();
}
function renderProgress(idx, total) {
const safeTotal = Math.max(1, total);
const pct = Math.round((idx / safeTotal) * 100); // starts at 0%
return `
<div class="progress">
<div class="row"><span>Progress</span><span>${pct}%</span></div>
<div class="bar"><span style="width:${pct}%"></span></div>
</div>
`;
}
function renderOptions(q) {
const sel = answers[q.id] ?? "";
return `
<div class="options" role="radiogroup" aria-label="${q.label}">
${q.options.map(o => `
<label class="opt ${sel === o.value ? "selected" : ""}">
<input type="radio" name="${q.id}" value="${o.value}" ${sel === o.value ? "checked" : ""} />
<span>${o.label}</span>
</label>
`).join("")}
</div>
`;
}
function renderQuestion(qs) {
const q = qs[step];
return `
${renderProgress(step, qs.length)}
<div class="q">
<div class="q-label">${q.label}${q.required ? " *" : ""}</div>
${renderOptions(q)}
<div class="actions">
<button class="btn" data-act="prev" ${step === 0 ? "disabled" : ""}>Back</button>
<button class="btn primary" data-act="next">${step === qs.length - 1 ? "See Results" : "Next"}</button>
</div>
<div class="muted" style="margin-top:8px;">${QUIZ.disclaimer}</div>
</div>
`;
}
function bindQuestionHandlers(qs) {
$$(".opt").forEach(label => {
label.addEventListener("click", () => {
const input = label.querySelector("input");
if (!input) return;
answers[input.name] = input.value;
$$(".opt").forEach(l => l.classList.remove("selected"));
label.classList.add("selected");
});
});
$("[data-act='prev']")?.addEventListener("click", () => {
step = Math.max(0, step - 1);
render();
});
$("[data-act='next']").addEventListener("click", () => {
const q = qs[step];
if (q.required && !answers[q.id]) {
alert("Please choose an option to continue.");
return;
}
step = step + 1;
render();
});
}
function renderResults(qs) {
lastScore = totalScore(qs, answers);
lastMax = maxPossiblePoints(qs);
const r = QUIZ.result;
let interp = r.guide[0].label;
if (lastScore >= 25) interp = r.guide[2].label;
else if (lastScore >= 13) interp = r.guide[1].label;
return `
<div class="grid">
<div class="scoreline">
<div class="raw" aria-label="O-Shot Readiness Raw Score">${lastScore} / ${lastMax}</div>
<div><strong>${r.title}</strong></div>
</div>
<div class="callout">
<p style="margin:0 0 8px;">${r.body}</p>
<ul style="margin:0 0 10px 18px;">
${r.guide.map(g => `<li><strong>${g.range}:</strong> ${g.label}</li>`).join("")}
</ul>
<p style="margin:6px 0 0;"><em>Based on your score: ${interp}</em></p>
</div>
<div class="cta">
<h3>${r.ctaHeadline}</h3>
<div class="cta-row">
<a class="btn sms" href="${r.ctaSmsHref}">${r.ctaSmsText}</a>
<a class="btn primary" href="${r.ctaBookHref}" target="_blank" rel="noopener">${r.ctaBookText}</a>
<button class="btn" data-act="restart">Restart</button>
<button class="btn" data-act="print">Print</button>
</div>
<p class="muted" style="margin-top:8px;">This self-test is educational. A provider consultation will confirm candidacy and personalize your plan.</p>
</div>
<form class="lead" id="oshot-lead-form" novalidate>
<h4>Want personalized guidance? Share your info and we’ll reach out.</h4>
<div class="fld">
<label for="oshot-name">Name</label>
<input type="text" id="oshot-name" name="name" required>
</div>
<div class="fld">
<label for="oshot-email">Email</label>
<input type="email" id="oshot-email" name="email" required>
</div>
<div class="fld">
<label for="oshot-phone">Phone</label>
<input type="tel" id="oshot-phone" name="phone" placeholder="(###) ###-####" required>
</div>
<div class="agree">
<input type="checkbox" id="oshot-agree" required>
<label for="oshot-agree">I agree to be contacted about scheduling and understand this is not medical advice.</label>
</div>
<div class="actions">
<button type="submit" class="btn primary">Send Email Request</button>
<span class="muted" id="oshot-lead-msg"></span>
</div>
</form>
</div>
`;
}
function bindResultHandlers() {
$("[data-act='restart']")?.addEventListener("click", () => {
for (const k in answers) delete answers[k];
step = 0;
render();
});
$("[data-act='print']")?.addEventListener("click", () => window.print());
const form = document.getElementById("oshot-lead-form");
const msg = document.getElementById("oshot-lead-msg");
if (!form || !msg) return;
form.addEventListener("submit", (e) => {
e.preventDefault();
msg.textContent = "";
const name = form.querySelector("#oshot-name").value.trim();
const email = form.querySelector("#oshot-email").value.trim();
const phone = form.querySelector("#oshot-phone").value.trim();
const agree = form.querySelector("#oshot-agree").checked;
if (!name || !email || !phone) {
msg.textContent = "Please complete all fields.";
return;
}
if (!/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(email)) {
msg.textContent = "Please enter a valid email address.";
return;
}
if (!agree) {
msg.textContent = "Please confirm consent to be contacted.";
return;
}
if (!clinicEmail || clinicEmail === "YOUR_CLINIC_EMAIL_HERE") {
msg.textContent = "Email is not configured. Please contact the office directly.";
return;
}
const subject = encodeURIComponent("O-Shot® Self-Test Consultation Request");
const bodyLines = [
"O-Shot® Self-Test Consultation Request",
"",
"Name: " + name,
"Email: " + email,
"Phone: " + phone,
"",
"Self-Test Score: " + lastScore + " / " + lastMax,
"Page: " + window.location.href,
"",
"Note: This message was generated from the O-Shot® self-test on your website."
];
const body = encodeURIComponent(bodyLines.join("\n"));
const mailtoLink = `mailto:${encodeURIComponent(clinicEmail)}?subject=${subject}&body=${body}`;
window.location.href = mailtoLink;
msg.innerHTML = '<span class="ok">Thank you! Your email app should open so you can send the request.</span>';
});
}
render();
})();
</script>
<!-- /O-Shot® Self-Test -->
