File: /home/primrwxj/theproviders.info/index-b.php
<?php
// ============================================
// Version B (Test): Conversion-Optimized
// - Stronger trust + social proof
// - Sticky call CTA (mobile)
// - Exit intent modal to reduce bounce
// - Same lead handling as Version A
// ============================================
$site_name = "TheProviders.info";
$city_label = "Murfreesboro, TN";
$service_label = "Roof Repair";
$to_email = "offers@theproviders.info";
$from_email = "no-reply@theproviders.info";
// Twilio
$twilio_sid = getenv("TWILIO_ACCOUNT_SID") ?: "MGb6cb5c7195345e7c33030c185e64083e";
$twilio_token = getenv("TWILIO_AUTH_TOKEN") ?: "AC3261bd028f2272ff2b5ccdd5b8f9875b:8f86a579fa80da2d18a7bbfd0ac842a6";
$twilio_from = getenv("TWILIO_FROM_NUMBER") ?: "+18443147041";
$twilio_to = getenv("TWILIO_TO_NUMBER") ?: "+12704844592";
$enable_sms = true;
// Optional: display phone CTA (can be Google Voice or real number)
$display_phone = "(615) 624-4157"; // <-- replace or keep placeholder
$tel_phone = "+16156244157"; // <-- digits only for tel:
$lead_csv_dir = __DIR__ . "/leads";
$lead_csv_file = $lead_csv_dir . "/leads.csv";
if (!is_dir($lead_csv_dir)) { @mkdir($lead_csv_dir, 0755, true); }
function clean($v){ $v=trim((string)$v); return str_replace(["\r","\n"]," ",$v); }
function is_valid_email($email){ return (bool)filter_var($email, FILTER_VALIDATE_EMAIL); }
function twilio_send_sms($sid, $token, $from, $to, $message){
if (!$sid || !$token || !$from || !$to) return ["ok"=>false, "error"=>"Missing Twilio config."];
$url = "https://api.twilio.com/2010-04-01/Accounts/{$sid}/Messages.json";
$post = http_build_query(["From"=>$from,"To"=>$to,"Body"=>$message]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, $sid . ":" . $token);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$resp = curl_exec($ch);
$err = curl_error($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($resp === false) return ["ok"=>false, "error"=>$err ?: "Unknown cURL error"];
if ($code < 200 || $code >= 300) return ["ok"=>false, "error"=>"Twilio HTTP $code: $resp"];
return ["ok"=>true];
}
$error_msg = "";
if ($_SERVER["REQUEST_METHOD"] === "POST") {
$hp = clean($_POST["company"] ?? "");
$ts = (int)($_POST["form_ts"] ?? 0);
$now = time();
if ($hp !== "") {
$error_msg = "Submission blocked.";
} elseif ($ts === 0 || ($now - $ts) < 3) {
$error_msg = "Please try again.";
} else {
$full_name = clean($_POST["full_name"] ?? "");
$phone = clean($_POST["phone"] ?? "");
$email = clean($_POST["email"] ?? "");
$zip = clean($_POST["zip"] ?? "");
$issue = clean($_POST["issue"] ?? "");
$urgency = clean($_POST["urgency"] ?? "");
$allowed_issues = [
"Roof leak",
"Storm / wind damage",
"Missing or damaged shingles",
"Sagging roof",
"Emergency repair",
"Inspection only"
];
$allowed_urgency = ["ASAP","This week","Flexible"];
$errors = [];
if ($full_name === "" || strlen($full_name) < 2) $errors[] = "Enter your full name.";
if ($phone === "" || strlen($phone) < 7) $errors[] = "Enter a valid phone number.";
if ($email === "" || !is_valid_email($email)) $errors[] = "Enter a valid email.";
if ($zip === "" || !preg_match("/^\d{5}(-\d{4})?$/", $zip)) $errors[] = "Enter a valid ZIP code.";
if (!in_array($issue, $allowed_issues, true)) $errors[] = "Choose an issue.";
if (!in_array($urgency, $allowed_urgency, true)) $errors[] = "Choose a timeframe.";
if ($errors) {
$error_msg = implode(" ", $errors);
} else {
$subject = "[Lead] Roof Repair - Murfreesboro ($issue, $urgency)";
$body =
"New Lead from $site_name (Variant B)\n"
. "---------------------------------\n"
. "Name: $full_name\n"
. "Phone: $phone\n"
. "Email: $email\n"
. "ZIP: $zip\n"
. "Issue: $issue\n"
. "Urgency: $urgency\n"
. "IP: " . ($_SERVER["REMOTE_ADDR"] ?? "unknown") . "\n"
. "Submitted: " . date("Y-m-d H:i:s") . "\n";
$headers = [
"From: $site_name <$from_email>",
"Reply-To: $full_name <$email>",
"Content-Type: text/plain; charset=UTF-8"
];
$mail_ok = @mail($to_email, $subject, $body, implode("\r\n", $headers));
$csv_ok = false;
$is_new = !file_exists($lead_csv_file);
if ($fp = @fopen($lead_csv_file, "a")) {
if ($is_new) fputcsv($fp, ["timestamp","service","city","full_name","phone","email","zip","issue","urgency","ip","variant"]);
fputcsv($fp, [date("c"), $service_label, $city_label, $full_name, $phone, $email, $zip, $issue, $urgency, ($_SERVER["REMOTE_ADDR"] ?? ""), "B"]);
fclose($fp);
$csv_ok = true;
}
$sms_ok = false;
if ($enable_sms) {
$msg = "NEW LEAD (B) Roof Repair Murfreesboro\n$full_name | $phone | $zip\n$issue | $urgency";
$res = twilio_send_sms($twilio_sid, $twilio_token, $twilio_from, $twilio_to, $msg);
$sms_ok = $res["ok"];
}
if ($mail_ok || $csv_ok || $sms_ok) {
header("Location: /thank-you.php?v=B");
exit;
} else {
$error_msg = "We couldn’t send your request right now. Please try again in a few minutes.";
}
}
}
}
?>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Murfreesboro Roof Repair Quote | TheProviders.info</title>
<meta name="description" content="Fast roof repair quotes in Murfreesboro, TN. Leaks, storm damage, missing shingles, emergency repairs.">
<style>
:root{
--bg:#ffffff;
--ink:#0f172a;
--muted:#475569;
--line:#e2e8f0;
--card:#ffffff;
--accent:#0f766e; /* green */
--accent2:#1d4ed8; /* blue */
--radius:16px;
--shadow: 0 12px 28px rgba(15, 23, 42, .10);
--max: 1040px;
}
*{box-sizing:border-box}
body{
margin:0; font-family: system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;
background: linear-gradient(180deg, #ffffff, #f8fafc);
color:var(--ink);
}
.wrap{max-width:var(--max); margin:0 auto; padding:22px 16px 90px}
.top{display:flex; justify-content:space-between; align-items:center; gap:12px; padding:8px 0 18px}
.brand{font-weight:900; letter-spacing:.2px}
.cta-top{display:flex; gap:10px; align-items:center; flex-wrap:wrap}
.btn-mini{
display:inline-flex; align-items:center; gap:8px;
padding:10px 12px; border-radius:999px;
border:1px solid var(--line);
background:#ffffff;
color:var(--ink);
text-decoration:none; font-weight:800; font-size:14px;
box-shadow: 0 6px 14px rgba(15,23,42,.06);
}
.btn-mini:hover{filter:brightness(1.02)}
.grid{display:grid; grid-template-columns: 1fr 420px; gap:16px}
@media (max-width: 980px){ .grid{grid-template-columns:1fr} }
.card{
background:var(--card);
border:1px solid var(--line);
border-radius:var(--radius);
box-shadow:var(--shadow);
overflow:hidden;
}
.hero{padding:22px}
h1{margin:0 0 10px; font-size:clamp(28px,4vw,42px); line-height:1.1}
.sub{margin:0 0 14px; color:var(--muted); line-height:1.65}
.trustbar{display:flex; flex-wrap:wrap; gap:10px; margin-top:10px}
.chip{
border:1px solid #c7f9e9;
background:#ecfdf5;
color:#065f46;
padding:8px 10px;
border-radius:999px;
font-size:13px;
font-weight:700;
}
.highlights{display:grid; gap:10px; margin-top:14px}
.hl{
padding:12px;
border:1px solid var(--line);
border-radius:14px;
background:#f8fafc;
}
.hl strong{display:block; margin-bottom:4px}
.form{padding:18px}
.form h2{margin:0 0 6px; font-size:20px}
.form p{margin:0 0 12px; color:var(--muted); line-height:1.65}
label{display:block; font-size:13px; color:var(--muted); margin:10px 0 6px}
input,select{
width:100%;
padding:12px;
border-radius:12px;
border:1px solid var(--line);
background:#fff;
color:var(--ink);
outline:none;
}
input:focus, select:focus{
border-color: rgba(15,118,110,.35);
box-shadow: 0 0 0 4px rgba(15,118,110,.10);
}
.row{display:grid; grid-template-columns:1fr 1fr; gap:12px}
@media (max-width:520px){ .row{grid-template-columns:1fr} }
.btn{
width:100%;
padding:13px 14px;
border-radius:14px;
border:1px solid rgba(15,118,110,.35);
background: linear-gradient(180deg, rgba(15,118,110,1), rgba(15,118,110,.90));
color:#fff;
font-weight:900;
cursor:pointer;
margin-top:12px;
}
.btn:hover{filter:brightness(1.02)}
.note{font-size:12px; color:var(--muted); margin-top:10px; line-height:1.55}
.alert{margin:0 0 12px; padding:12px; border-radius:12px; border:1px solid var(--line); background:#f8fafc; line-height:1.55}
.alert.err{border-color: rgba(185,28,28,.25); background: rgba(185,28,28,.05); color:#7f1d1d}
.hp{position:absolute; left:-9999px; top:-9999px; height:0; width:0; overflow:hidden}
.social{padding:16px 22px; border-top:1px solid var(--line)}
.social h3{margin:0 0 10px; font-size:18px}
.quotes{display:grid; gap:10px}
.q{
padding:12px;
border-radius:14px;
border:1px solid var(--line);
background:#f8fafc;
color:var(--muted);
line-height:1.55;
}
.q b{color:var(--ink)}
/* Sticky call button (mobile) */
.sticky{position:fixed; left:16px; right:16px; bottom:14px; display:none; gap:10px}
.sticky a{
flex:1; text-align:center; text-decoration:none;
padding:14px 14px; border-radius:14px;
border:1px solid rgba(29,78,216,.25);
background: linear-gradient(180deg, rgba(29,78,216,1), rgba(29,78,216,.90));
color:#fff; font-weight:900;
box-shadow: 0 12px 26px rgba(15,23,42,.12);
}
@media (max-width: 980px){ .sticky{display:flex;} }
/* Exit intent modal */
.modal-backdrop{position:fixed; inset:0; background:rgba(15,23,42,.35); display:none; align-items:center; justify-content:center; padding:16px;}
.modal{max-width:520px; width:100%; background:#fff; border:1px solid var(--line); border-radius:16px; box-shadow:var(--shadow); padding:16px;}
.modal h4{margin:0 0 6px; font-size:18px}
.modal p{margin:0 0 12px; color:var(--muted); line-height:1.6}
.modal .actions{display:flex; gap:10px; flex-wrap:wrap}
.modal .actions button, .modal .actions a{
flex:1; min-width:180px; padding:12px; border-radius:12px;
border:1px solid var(--line); background:#f8fafc; color:var(--ink);
font-weight:900; cursor:pointer; text-decoration:none; text-align:center;
}
.modal .actions a.primary{
border-color: rgba(15,118,110,.25);
background:#ecfdf5;
color:#065f46;
}
</style>
</head>
<body>
<div class="wrap">
<div class="top">
<div class="brand">TheProviders.info</div>
<div class="cta-top">
<a class="btn-mini" href="tel:<?php echo htmlspecialchars($tel_phone); ?>">Call Now: <?php echo htmlspecialchars($display_phone); ?></a>
<a class="btn-mini" href="https://theproviders.info/privacy-policy.html">Privacy</a>
</div>
<div style="margin-top:8px; color:#475569; font-size:13px;">
<strong>Call hours:</strong> 8:00am–7:00pm Central. After hours, leave a voicemail — we’ll return calls the next business day.
</div>
</div>
<div class="grid">
<div class="card">
<div class="hero">
<h1>Need roof repair in Murfreesboro?</h1>
<p class="sub">Submit a 60-second request. We route it to roofers who serve your ZIP code. Fast response for leaks and storm damage.</p>
<div class="trustbar">
<span class="chip">ZIP-based routing</span>
<span class="chip">Same-day callbacks (often)</span>
<span class="chip">No obligation</span>
</div>
<div class="highlights">
<div class="hl"><strong>Leak or storm damage?</strong> Get a fast inspection/repair callback from a local roofer.</div>
<div class="hl"><strong>Clear next step:</strong> You choose who to hire after you compare options.</div>
</div>
</div>
<div class="social">
<h3>Recent homeowner feedback</h3>
<div class="quotes">
<div class="q"><b>“Quick response.”</b> I got a call back the same day about my leak.</div>
<div class="q"><b>“Simple.”</b> The form took a minute and I didn’t have to chase anyone.</div>
<div class="q"><b>“Helpful routing.”</b> I only heard from roofers who actually serve my area.</div>
</div>
<p class="note" style="margin-top:10px;">Note: Feedback reflects individual experiences and may vary.</p>
</div>
</div>
<div class="card">
<div class="form">
<h2>Get My Quote</h2>
<p>Tell us what’s happening and when you need help. We’ll route your request to Murfreesboro-area roofers.</p>
<?php if ($error_msg): ?>
<div class="alert err"><?php echo htmlspecialchars($error_msg); ?></div>
<?php endif; ?>
<form method="post" action="" id="leadForm">
<div class="hp">
<label>Company</label>
<input type="text" name="company" tabindex="-1" autocomplete="off" />
</div>
<input type="hidden" name="form_ts" value="<?php echo time(); ?>">
<label for="full_name">Full Name</label>
<input id="full_name" name="full_name" type="text" placeholder="John Smith" required>
<div class="row">
<div>
<label for="phone">Phone Number</label>
<input id="phone" name="phone" type="tel" placeholder="(615) 555-1234" required>
</div>
<div>
<label for="zip">ZIP Code</label>
<input id="zip" name="zip" type="text" placeholder="37129" required>
</div>
</div>
<label for="email">Email</label>
<input id="email" name="email" type="email" placeholder="you@email.com" required>
<div class="row">
<div>
<label for="issue">What’s the issue?</label>
<select id="issue" name="issue" required>
<option value="" selected disabled>Select one</option>
<option>Roof leak</option>
<option>Storm / wind damage</option>
<option>Missing or damaged shingles</option>
<option>Sagging roof</option>
<option>Emergency repair</option>
<option>Inspection only</option>
</select>
</div>
<div>
<label for="urgency">When do you need service?</label>
<select id="urgency" name="urgency" required>
<option value="" selected disabled>Select one</option>
<option>ASAP</option>
<option>This week</option>
<option>Flexible</option>
</select>
</div>
</div>
<button class="btn" type="submit">Get My Quote</button>
<div class="note">We route your request to independent local roofers. You choose who to hire. <a href="https://theproviders.info/privacy-policy.html">Privacy note</a>.
<p></p>
<center><strong>Disclaimer:</strong> TheProviders.info connects homeowners with independent contractors. Pricing, warranties, and availability are determined by the contractor.
</center>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="sticky">
<a href="tel:<?php echo htmlspecialchars($tel_phone); ?>">Call Now</a>
<a href="#leadForm" onclick="document.getElementById('full_name').focus(); return false;">Get Quote</a>
</div>
<div class="modal-backdrop" id="exitModal">
<div class="modal">
<h4>Before you go…</h4>
<p>If you’re dealing with a leak or storm damage, a quick request can save you hours of calls. Want a local roofer to contact you?</p>
<div class="actions">
<a class="primary" href="#leadForm" onclick="closeExit(); document.getElementById('full_name').focus(); return false;">Yes — Get My Quote</a>
<a href="tel:<?php echo htmlspecialchars($tel_phone); ?>">Call Now</a>
<button type="button" onclick="closeExit()">Not now</button>
</div>
<p class="note" style="margin-top:10px;">No spam. Only routed to local providers for your request.</p>
</div>
</div>
<script>
// Exit intent (desktop): show modal once
let exitShown = false;
function closeExit(){ document.getElementById('exitModal').style.display = 'none'; }
document.addEventListener('mouseout', function(e){
if (exitShown) return;
if (e.clientY <= 0) {
exitShown = true;
document.getElementById('exitModal').style.display = 'flex';
}
});
</script>
</body>
</html>