Embed snippet (paste on any page)
This loads the same widget, but posts to /tools/feedback/feedback.php.
<script>
(function(){
var ENDPOINT = "/tools/feedback/feedback.php"; // your endpoint
// inject widget
function mount(){
if (window.__tinyFeedbackMounted) return;
window.__tinyFeedbackMounted = true;
var btn = document.createElement("button");
btn.textContent = "Feedback";
btn.type = "button";
btn.style.position="fixed";
btn.style.right="14px";
btn.style.bottom="14px";
btn.style.zIndex="9999";
btn.style.border="0";
btn.style.borderRadius="999px";
btn.style.padding="10px 14px";
btn.style.fontWeight="900";
btn.style.cursor="pointer";
btn.style.background="#2a8cff";
btn.style.color="#06101a";
btn.style.boxShadow="0 18px 50px rgba(0,0,0,.35)";
var modal = document.createElement("div");
modal.style.position="fixed";
modal.style.inset="0";
modal.style.background="rgba(0,0,0,.55)";
modal.style.zIndex="10000";
modal.style.display="none";
modal.style.alignItems="center";
modal.style.justifyContent="center";
modal.innerHTML = ''
+ '<div style="width:min(520px,92vw);background:#111a26;border:1px solid rgba(255,255,255,.10);border-radius:16px;padding:14px;color:#e8eef8;font-family:system-ui,-apple-system,Segoe UI,Roboto,Arial,sans-serif;">'
+ ' <div style="display:flex;justify-content:space-between;align-items:center;gap:10px;">'
+ ' <div style="font-weight:900;font-size:16px;">Send feedback</div>'
+ ' <button type="button" data-x style="background:transparent;border:0;color:#e8eef8;font-size:20px;cursor:pointer;">×</button>'
+ ' </div>'
+ ' <div style="color:rgba(232,238,248,.75);font-size:13px;margin-top:6px;">Includes this page URL automatically.</div>'
+ ' <form data-f style="margin-top:12px;display:grid;gap:10px;">'
+ ' <input name="email" placeholder="Email (optional)" style="width:100%;padding:10px;border-radius:12px;border:1px solid rgba(255,255,255,.12);background:#0c1420;color:#e8eef8;">'
+ ' <textarea name="message" required placeholder="What’s wrong or what could be better?" style="width:100%;min-height:110px;padding:10px;border-radius:12px;border:1px solid rgba(255,255,255,.12);background:#0c1420;color:#e8eef8;resize:vertical;"></textarea>'
+ ' <input type="file" name="screenshot" accept="image/*" style="color:rgba(232,238,248,.75);font-size:13px;">'
+ ' <input name="companyfax" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;">'
+ ' <button type="submit" style="border:0;border-radius:12px;padding:10px 12px;font-weight:900;background:#2a8cff;color:#06101a;cursor:pointer;">Send</button>'
+ ' <div data-msg style="font-size:13px;color:rgba(232,238,248,.75)"></div>'
+ ' </form>'
+ '</div>';
function open(){ modal.style.display="flex"; }
function close(){ modal.style.display="none"; }
btn.addEventListener("click", open);
modal.addEventListener("click", function(e){ if (e.target===modal) close(); });
modal.querySelector("[data-x]").addEventListener("click", close);
modal.querySelector("[data-f]").addEventListener("submit", function(e){
e.preventDefault();
var msg = modal.querySelector("[data-msg]");
msg.textContent = "Sending...";
var fd = new FormData(e.target);
fd.append("page_url", location.href);
fetch(ENDPOINT, { method:"POST", body: fd, credentials:"omit" })
.then(function(r){ return r.json().catch(function(){ return {ok:false,error:"Bad response"}; }); })
.then(function(j){
if (j.ok){
msg.textContent = "Sent. Thank you!";
e.target.reset();
setTimeout(close, 650);
} else {
msg.textContent = j.error || "Failed to send.";
}
})
.catch(function(){ msg.textContent = "Network error."; });
});
document.body.appendChild(btn);
document.body.appendChild(modal);
}
if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", mount);
else mount();
})();
</script>