/* ATX Decon — shared shell + components.
Exports to window at end. Loaded before pages. */
const PHONE_DISPLAY = "(512) 729-4800";
const PHONE_TEL = "+15127294800";
const EMAIL = "help@atxdecon.com";
const NAV = [
{ id: "home", label: "Home" },
{ id: "biohazard", label: "Biohazard" },
{ id: "infestation", label: "Room Infestation Cleanup" },
{ id: "hoarding", label: "Hoarding" },
{ id: "about", label: "About Us" },
{ id: "contact", label: "Contact Us" },
];
const SERVICES = [
{
id: "biohazard",
icon: "fa-shield-virus",
name: "Biohazard & Trauma",
short: "Biohazard Cleanup",
blurb: "Discreet, IICRC-standard cleanup and decontamination of blood, trauma, and unattended-death scenes.",
},
{
id: "infestation",
icon: "fa-house-medical",
name: "Room Infestation Cleanup",
short: "Room Infestation Cleanup",
blurb: "Full sanitation of rooms affected by rodents, pests, droppings, and the contamination they leave behind.",
},
{
id: "hoarding",
icon: "fa-boxes-stacked",
name: "Hoarding Cleanup",
short: "Hoarding Cleanup",
blurb: "Patient, judgment-free clearing and restoration of hoarding environments, paced around the people involved.",
},
];
/* ---------- Small bits ---------- */
function Eyebrow({ children }) {
return {children} ;
}
function CallBtn({ size, className = "", label }) {
return (
{label || PHONE_DISPLAY}
);
}
/* ---------- Image placeholder via user-fillable slot ---------- */
function Img({ id, ratio = "4 / 3", label = "Drop a photo", icon = "fa-image", style = {}, radius }) {
return (
);
}
/* ---------- Logo ---------- */
function Logo({ go, dark }) {
return (
go && go("home")}
aria-label="ATX Decon home"
style={{ background: "none", border: 0, padding: 0, display: "flex", alignItems: "center", gap: 13 }}
>
ATX Decon
Restoration & Remediation
);
}
/* ---------- Emergency utility bar ---------- */
function EmergencyBar() {
return (
STATUS · ON CALL 24 / 7 · AUSTIN, TX
);
}
/* ---------- Header / nav ---------- */
function Header({ current, go }) {
const [open, setOpen] = React.useState(false);
const [scrolled, setScrolled] = React.useState(false);
React.useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 8);
window.addEventListener("scroll", onScroll);
return () => window.removeEventListener("scroll", onScroll);
}, []);
const nav = (id) => { setOpen(false); go(id); };
return (
{NAV.map((n) => (
nav(n.id)}
>
{n.label}
))}
setOpen((v) => !v)} aria-label="Menu">
{open && (
)}
);
}
/* ---------- Trust strip ---------- */
function TrustStrip() {
const items = [
{ icon: "fa-certificate", text: "IICRC Certified" },
{ icon: "fa-file-shield", text: "Licensed · Bonded · Insured" },
{ icon: "fa-handshake-angle", text: "We bill insurance directly" },
{ icon: "fa-user-secret", text: "Discreet · Unmarked vehicles" },
{ icon: "fa-clock", text: "45-min metro response" },
];
return (
{items.map((it, i) => (
{it.text}
))}
);
}
/* ---------- Service card ---------- */
function ServiceCard({ svc, go, featured }) {
return (
go(svc.id)}>
{svc.name}
{svc.blurb}
Learn more
);
}
/* ---------- Process steps ---------- */
function ProcessSteps({ steps }) {
return (
{steps.map((s, i) => (
{String(i + 1).padStart(2, "0")}
{s.t}
{s.d}
))}
);
}
/* ---------- Stat ---------- */
function StatGrid({ stats }) {
return (
{stats.map((s, i) => (
))}
);
}
/* ---------- FAQ accordion ---------- */
function FAQ({ items }) {
const [open, setOpen] = React.useState(0);
return (
{items.map((it, i) => (
setOpen(open === i ? -1 : i)}>
{it.q}
))}
);
}
/* ---------- Result / reassurance band ---------- */
function ReassureBand() {
return (
ONE CALL. HANDLED.
Cleaned, decontaminated, and restored — fast.
Most jobs are fully cleaned, decontaminated, and back to normal in a single
discreet visit. You make one call — our certified team handles everything else,
quietly and completely — so you're not left waiting or dealing with it yourself.
);
}
/* ---------- Big CTA band ---------- */
function CTABand({ go }) {
return (
HERE WHEN YOU NEED US
Call now, or request a free estimate.
Emergencies don't keep business hours. A trained ATX Decon specialist answers
every call, day or night — no answering service, no runaround.
go("contact")}>
Request free estimate
SERVICE AREA
Austin & Central Texas
);
}
/* ---------- Footer ---------- */
function Footer({ go }) {
return (
);
}
Object.assign(window, {
PHONE_DISPLAY, PHONE_TEL, EMAIL, NAV, SERVICES,
Eyebrow, CallBtn, Img, Logo, EmergencyBar, Header, TrustStrip,
ServiceCard, ProcessSteps, StatGrid, FAQ, ReassureBand, CTABand, Footer,
});