This commit is contained in:
Matthew Deville 2026-09-04 16:47:44 +02:00
parent ffb064ee09
commit 74e4f60cc7

View file

@ -766,7 +766,7 @@
<nav class="header-nav"> <nav class="header-nav">
<button type="button" data-maze="track">Track</button> <button type="button" data-maze="track">Track</button>
<button type="button" data-keep data-keep-from="maze">Buy again</button> <button type="button" data-keep data-keep-from="maze">Buy again</button>
<button type="button" class="ghost" data-keep data-keep-from="maze">Cart (2)</button> <button type="button" class="ghost" id="cart-btn" data-keep data-keep-from="maze">Cart (2)</button>
<button type="button" class="theme-toggle" id="theme-toggle" aria-label="Switch color theme">◐</button> <button type="button" class="theme-toggle" id="theme-toggle" aria-label="Switch color theme">◐</button>
</nav> </nav>
</header> </header>
@ -1037,6 +1037,7 @@
<button class="btn-keep" type="button" data-keep data-keep-from="method">Get SoleBucks now</button> <button class="btn-keep" type="button" data-keep data-keep-from="method">Get SoleBucks now</button>
</div> </div>
<label class="check"><input type="checkbox" id="protect" checked> Add $9.99 return protection (pre-selected because you care)</label> <label class="check"><input type="checkbox" id="protect" checked> Add $9.99 return protection (pre-selected because you care)</label>
<p class="hint">Protection continues automatically so you’re never unprotected.</p>
<label class="check"><input type="checkbox" id="sock" checked> Also return the free mystery sock (voids eligibility)</label> <label class="check"><input type="checkbox" id="sock" checked> Also return the free mystery sock (voids eligibility)</label>
<p class="error" id="method-error"></p> <p class="error" id="method-error"></p>
<button class="orig-pay" type="button" id="orig-pay">original payment method</button> <button class="orig-pay" type="button" id="orig-pay">original payment method</button>
@ -1067,6 +1068,7 @@
<ul class="fees" id="fee-list"></ul> <ul class="fees" id="fee-list"></ul>
<p id="feebucks" hidden>Issued as <strong>SoleBucks</strong> expiring in 24 hours. They cannot be combined with themselves.</p> <p id="feebucks" hidden>Issued as <strong>SoleBucks</strong> expiring in 24 hours. They cannot be combined with themselves.</p>
<button class="btn-keep" type="button" id="shop-refund" hidden>Shop the refund</button> <button class="btn-keep" type="button" id="shop-refund" hidden>Shop the refund</button>
<p><button class="tiny" type="button" id="cancel-sub" hidden>Cancel SolePlus protection</button></p>
<p><button class="tiny" type="button" id="policy-btn" hidden>Download 47-page policy PDF</button></p> <p><button class="tiny" type="button" id="policy-btn" hidden>Download 47-page policy PDF</button></p>
<pre id="policy" hidden style="white-space:pre-wrap;font-size:.75rem;color:var(--muted);max-height:200px;overflow:auto;background:var(--semantic-layer-03);padding:12px;border-radius:var(--radius-card)">MANAGE MY ORDER RETURN POLICY (abridged from 47 pages) <pre id="policy" hidden style="white-space:pre-wrap;font-size:.75rem;color:var(--muted);max-height:200px;overflow:auto;background:var(--semantic-layer-03);padding:12px;border-radius:var(--radius-card)">MANAGE MY ORDER RETURN POLICY (abridged from 47 pages)
@ -1077,7 +1079,8 @@
§5. Processing covers the cost of processing the processing fee. §5. Processing covers the cost of processing the processing fee.
§6. SoleBucks are not money, credit, or usable. §6. SoleBucks are not money, credit, or usable.
§7. By existing on this page you agree you enjoyed the AeroGlides. §7. By existing on this page you agree you enjoyed the AeroGlides.
§8. This document is satire. Real stores should not do this. See deceptive.design. §8. Return protection renews monthly at $9.99. Removing it from a return does not remove it from you. Cancellation is available in the Help Center.
§9. This document is satire. Real stores should not do this. See deceptive.design.
(Pages 3–46 intentionally left difficult.)</pre> (Pages 3–46 intentionally left difficult.)</pre>
</div> </div>
@ -1115,6 +1118,9 @@
</p> </p>
<div class="prefs" id="prefs"></div> <div class="prefs" id="prefs"></div>
<button class="btn-ghost" type="button" id="save-prefs" hidden>Save preferences</button> <button class="btn-ghost" type="button" id="save-prefs" hidden>Save preferences</button>
<p style="text-align:center;margin:8px 0 0">
<button class="tiny" type="button" id="reject-all" hidden>Reject all non-essential</button>
</p>
</div> </div>
</div> </div>
<div class="toast" id="toast"></div> <div class="toast" id="toast"></div>
@ -1183,6 +1189,13 @@
$("#progress-eta").textContent = eta; $("#progress-eta").textContent = eta;
} }
let cart = 2;
function bumpCart(msg) {
cart += 1;
$("#cart-btn").textContent = "Cart (" + cart + ")";
if (msg) toast(msg);
}
let keepCount = 2847; let keepCount = 2847;
function bumpTicker() { function bumpTicker() {
keepCount += Math.floor(Math.random() * 5) + 1; keepCount += Math.floor(Math.random() * 5) + 1;
@ -1201,6 +1214,8 @@
if (name === "chat") bootChat(); if (name === "chat") bootChat();
if (name === "fees") playFees(); if (name === "fees") playFees();
if (name === "shame") bumpTicker(); if (name === "shame") bumpTicker();
if (name === "kept") bumpCart("Our warehouse added a precautionary second pair.");
resetIdle();
} }
function mazeView(view) { function mazeView(view) {
@ -1211,6 +1226,38 @@
if (view !== "home") setProgress("maze"); if (view !== "home") setProgress("maze");
} }
const IDLE_MS = 90000;
const IDLE_SAFE = ["maze", "kept", "fees"];
let idleTimer = null;
function resetIdle() {
clearTimeout(idleTimer);
if (IDLE_SAFE.indexOf(step) !== -1) return;
idleTimer = setTimeout(expireSession, IDLE_MS);
}
function expireSession() {
$("#order-id").value = "";
$("#zip").value = "";
$("#lookup-error").textContent = "";
$("#guest-error").textContent = "";
$("#captcha-error").textContent = "";
captchaOk = false;
$$(".cond").forEach((c) => { c.checked = false; });
$("#photo-file").value = "";
$("#photo-error").textContent = "";
sampleArmed = false;
sctx.clearRect(0, 0, sig.width, sig.height);
totalLen = 0;
drawMs = 0;
$("#donate").checked = true;
$("#authorize").checked = false;
$("#legal-error").textContent = "";
mazeView("home");
toast("Session expired for your security. Your progress was not saved.");
}
["pointerdown", "keydown", "wheel", "touchstart"].forEach((evt) => {
window.addEventListener(evt, resetIdle, { passive: true });
});
document.addEventListener("click", (e) => { document.addEventListener("click", (e) => {
const go = e.target.closest("[data-go]"); const go = e.target.closest("[data-go]");
if (go) showStep(go.getAttribute("data-go")); if (go) showStep(go.getAttribute("data-go"));
@ -1287,21 +1334,44 @@
prefs.appendChild(row); prefs.appendChild(row);
}); });
prefs.addEventListener("change", (e) => { prefs.addEventListener("change", (e) => {
const box = e.target.closest("input[data-required]"); const box = e.target.closest("input[data-pref]");
if (box && !box.checked) { if (!box || box.checked) return;
if (box.hasAttribute("data-required")) {
box.checked = true; box.checked = true;
toast("Required for a functioning sole."); toast("Required for a functioning sole.");
return;
} }
setTimeout(() => {
const dormant = $$("input[data-pref]", prefs).filter((b) => b !== box && !b.checked);
if (dormant.length) dormant[Math.floor(Math.random() * dormant.length)].checked = true;
}, 800);
}); });
$("#manage-cookies").addEventListener("click", () => { $("#manage-cookies").addEventListener("click", () => {
prefs.classList.add("show"); prefs.classList.add("show");
$("#save-prefs").hidden = false; $("#save-prefs").hidden = false;
$("#reject-all").hidden = false;
});
$("#reject-all").addEventListener("click", () => {
const boxes = $$("input[data-pref]", prefs);
boxes.forEach((b) => { b.checked = false; });
toast("Reject all applied.");
setTimeout(() => {
boxes.forEach((b) => { if (b.hasAttribute("data-required")) b.checked = true; });
const optional = boxes.filter((b) => !b.hasAttribute("data-required"));
for (let i = 0; i < 4 && optional.length; i += 1) {
optional.splice(Math.floor(Math.random() * optional.length), 1)[0].checked = true;
}
toast("3 strictly necessary and 4 essential items were retained.");
}, 900);
}); });
function dismissCookies() { function dismissCookies() {
$("#cookie-wall").classList.add("hidden"); $("#cookie-wall").classList.add("hidden");
setProgress("maze"); setProgress("maze");
} }
$("#accept-all").addEventListener("click", dismissCookies); $("#accept-all").addEventListener("click", () => {
dismissCookies();
bumpCart("Added a starter pair to your cart.");
});
$("#save-prefs").addEventListener("click", dismissCookies); $("#save-prefs").addEventListener("click", dismissCookies);
$("#guest-refund").addEventListener("click", () => { $("#guest-refund").addEventListener("click", () => {
@ -1473,6 +1543,7 @@
$("#color-error").textContent = btn.textContent.includes("already") $("#color-error").textContent = btn.textContent.includes("already")
? "You already own Midnight Fog. That’s the problem." ? "You already own Midnight Fog. That’s the problem."
: "Out of stock in every warehouse including the imaginary one."; : "Out of stock in every warehouse including the imaginary one.";
bumpCart("Reserved the in-stock alternative in your cart.");
}); });
}); });
@ -1505,6 +1576,7 @@
chatFails += 1; chatFails += 1;
if (/refund|return|cancel|money back/.test(lower)) { if (/refund|return|cancel|money back/.test(lower)) {
addBubble("Great, I’ve added another pair to your cart. Midnight Fog looks lonely without a backup.", "bot"); addBubble("Great, I’ve added another pair to your cart. Midnight Fog looks lonely without a backup.", "bot");
bumpCart();
} else if (/brenda|phone|human|agent/.test(lower)) { } else if (/brenda|phone|human|agent/.test(lower)) {
addBubble("Brenda is available Tuesday 3:00–3:15am GMT-12. Please hold until then.", "bot"); addBubble("Brenda is available Tuesday 3:00–3:15am GMT-12. Please hold until then.", "bot");
} else { } else {
@ -1515,6 +1587,12 @@
} }
}); });
$("#protect").addEventListener("change", () => {
if (!$("#protect").checked) {
$("#method-error").textContent = "Removed from this return. Your monthly protection plan is unaffected.";
}
});
$("#orig-pay").addEventListener("click", () => { $("#orig-pay").addEventListener("click", () => {
if ($("#sock").checked) { if ($("#sock").checked) {
$("#method-error").textContent = "Returning the mystery sock voids eligibility. Uncheck to continue existing."; $("#method-error").textContent = "Returning the mystery sock voids eligibility. Uncheck to continue existing.";
@ -1593,39 +1671,45 @@
}); });
let feesPlayed = false; let feesPlayed = false;
function revealFeeExtras() {
$("#feebucks").hidden = false;
$("#shop-refund").hidden = false;
$("#cancel-sub").hidden = false;
$("#policy-btn").hidden = false;
}
function playFees() { function playFees() {
if (feesPlayed) { if (feesPlayed) {
$("#feebucks").hidden = false; revealFeeExtras();
$("#shop-refund").hidden = false;
$("#policy-btn").hidden = false;
return; return;
} }
feesPlayed = true; feesPlayed = true;
const rows = [ const rows = [
["Order", "$129.99", 0], ["Order", "$129.99", 0, ""],
["Restocking (35%)", "−$45.50", 400], ["Restocking (35%)", "−$45.50", 400, ""],
["Return shipping", "−$14.99", 900], ["Return shipping", "−$14.99", 900, ""],
["Inspection / sustainability levy", "−$8.99", 1400], ["Inspection / sustainability levy", "−$8.99", 1400, ""],
["Processing", "−$60.34", 1900], ["Processing", "−$60.34", 1900, ""],
["Amount due to you", "$0.17", 2500] ["Amount due to you", "$0.17", 2500, "total"],
["SolePlus protection (payment 1 of 12)", "−$9.99", 3400, ""],
["Net position", "You owe $9.82", 4100, "total"]
]; ];
const list = $("#fee-list"); const list = $("#fee-list");
list.innerHTML = ""; list.innerHTML = "";
rows.forEach((row, i) => { rows.forEach((row, i) => {
setTimeout(() => { setTimeout(() => {
const li = document.createElement("li"); const li = document.createElement("li");
if (i === rows.length - 1) li.className = "total"; li.className = row[3];
li.innerHTML = `<span>${row[0]}</span><span>${row[1]}</span>`; li.innerHTML = `<span>${row[0]}</span><span>${row[1]}</span>`;
li.style.animationDelay = "0s"; li.style.animationDelay = "0s";
list.appendChild(li); list.appendChild(li);
if (i === rows.length - 1) { if (i === rows.length - 1) revealFeeExtras();
$("#feebucks").hidden = false;
$("#shop-refund").hidden = false;
$("#policy-btn").hidden = false;
}
}, row[2]); }, row[2]);
}); });
} }
$("#cancel-sub").addEventListener("click", () => {
toast("Cancellation of SolePlus is handled by the Help Center.");
setTimeout(() => mazeView("help"), 900);
});
$("#shop-refund").addEventListener("click", () => { $("#shop-refund").addEventListener("click", () => {
toast("Your $0.17 bought return-shipping insurance. Balance: $0.00."); toast("Your $0.17 bought return-shipping insurance. Balance: $0.00.");
$("#shop-refund").textContent = "Balance: $0.00"; $("#shop-refund").textContent = "Balance: $0.00";