Skip to content

Commit 2999286

Browse files
committed
Soft-gate wallpaper download with drop-list nudge; set STOCK KV id
- scripts/subscribe.js: reusable email-to-Kit submitter (shared hidden iframe) for one-off signup spots outside the homepage form. - Product page shows a gentle "first dibs on the next drop?" nudge after a wallpaper download. Download stays free and ungated; the nudge only appears if a provider is configured and at most once per session. - wrangler.toml: fill in the STOCK KV namespace id. https://claude.ai/code/session_01VhWRYXbuqapZ9YkvksroaS
1 parent 91f4afc commit 2999286

5 files changed

Lines changed: 100 additions & 1 deletion

File tree

product.html

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@
5757
</div>
5858
<div class="pd-stage-meta tiny"><span id="pdInk">マシンドロー</span><span id="pdSize"></span></div>
5959
<button class="pd-wallpaper tiny" id="pdWallpaper">↓ Download phone wallpaper</button>
60+
<div class="pd-nudge" id="pdNudge" hidden>
61+
<p class="pd-nudge-copy tiny">Saved to your phone. Want first dibs when the next edition drops?</p>
62+
<form class="pd-nudge-form" id="pdNudgeForm" novalidate>
63+
<input type="email" id="pdNudgeEmail" placeholder="you@example.com" aria-label="Email address" autocomplete="email" />
64+
<button type="submit">Notify me</button>
65+
</form>
66+
<p class="pd-nudge-msg tiny" id="pdNudgeMsg" hidden></p>
67+
</div>
6068
</div>
6169

6270
<!-- RIGHT: details + acquire -->
@@ -122,6 +130,7 @@ <h3>Shipping &amp; returns</h3>
122130
<script src="data/editions.js"></script>
123131
<script src="scripts/config.js"></script>
124132
<script src="scripts/stock.js"></script>
133+
<script src="scripts/subscribe.js"></script>
125134
<script src="scripts/product.js"></script>
126135
<script src="scripts/cart.js"></script>
127136
</body>

scripts/product.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,38 @@
248248
a.download = key + "-" + color + "-wallpaper.png";
249249
a.click();
250250
dlBtn.textContent = "↓ Download phone wallpaper";
251+
revealNudge();
251252
}, 50);
252253
});
253254
}
255+
256+
// ---- soft gate: gentle drop-list nudge after a download ----
257+
// The wallpaper is always free; this just invites a signup once per visit,
258+
// and only if an email provider is wired up.
259+
function revealNudge() {
260+
var nudge = $("pdNudge");
261+
if (!nudge || nudge.dataset.done) return;
262+
if (!(window.PlotflowSubscribe && window.PlotflowSubscribe.configured())) return;
263+
try { if (sessionStorage.getItem("pf_nudge")) return; } catch (e) {}
264+
nudge.hidden = false;
265+
}
266+
267+
(function wireNudge() {
268+
var form = $("pdNudgeForm"); if (!form) return;
269+
var inp = $("pdNudgeEmail"), msg = $("pdNudgeMsg"), nudge = $("pdNudge");
270+
form.addEventListener("submit", function (e) {
271+
e.preventDefault();
272+
var sub = window.PlotflowSubscribe;
273+
if (!sub || !sub.valid(inp.value)) {
274+
msg.textContent = "Please enter a valid email."; msg.hidden = false;
275+
return;
276+
}
277+
sub.submit(inp.value);
278+
form.hidden = true;
279+
msg.textContent = "You're on the list. Watch for the next drop.";
280+
msg.hidden = false;
281+
nudge.dataset.done = "1";
282+
try { sessionStorage.setItem("pf_nudge", "1"); } catch (e) {}
283+
});
284+
})();
254285
})();

scripts/subscribe.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* ============================================================
2+
PLOTFLOW · Subscribe helper
3+
A tiny, reusable email-to-Kit submitter for one-off signup spots
4+
(e.g. the post-wallpaper-download nudge) that aren't the main
5+
homepage form. Posts to PLOTFLOW_CONFIG.newsletterEndpoint via a
6+
shared hidden iframe so it works cross-origin without CORS and
7+
never navigates the page.
8+
Depends on: scripts/config.js
9+
============================================================ */
10+
(function () {
11+
var CFG = window.PLOTFLOW_CONFIG || {};
12+
var sink, form, input;
13+
14+
function ensure() {
15+
if (form) return;
16+
sink = document.createElement("iframe");
17+
sink.name = "plotflow-sub-sink";
18+
sink.setAttribute("aria-hidden", "true");
19+
sink.style.display = "none";
20+
document.body.appendChild(sink);
21+
22+
form = document.createElement("form");
23+
form.method = "post";
24+
form.target = "plotflow-sub-sink";
25+
form.style.display = "none";
26+
input = document.createElement("input");
27+
input.type = "hidden";
28+
input.name = CFG.newsletterField || "email_address";
29+
form.appendChild(input);
30+
document.body.appendChild(form);
31+
}
32+
33+
function valid(v) { return /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(String(v || "")); }
34+
35+
window.PlotflowSubscribe = {
36+
valid: valid,
37+
configured: function () { return !!CFG.newsletterEndpoint; },
38+
// Fire-and-forget POST. Returns true if it was sent, false if invalid
39+
// email or no provider configured.
40+
submit: function (emailVal) {
41+
if (!CFG.newsletterEndpoint || !valid(emailVal)) return false;
42+
ensure();
43+
form.action = CFG.newsletterEndpoint;
44+
input.value = emailVal;
45+
form.submit();
46+
return true;
47+
}
48+
};
49+
})();

styles/styles.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,16 @@ footer .grain{opacity:.3}
240240
.pd-wallpaper{display:block;width:100%;margin-top:8px;padding:10px;color:var(--dim);border:1px solid var(--line);
241241
background:transparent;font-weight:700;font-size:8.5px;letter-spacing:.14em;text-transform:uppercase;text-align:center;transition:border-color .2s,color .2s}
242242
.pd-wallpaper:hover{border-color:var(--mute);color:var(--white)}
243+
.pd-nudge{margin-top:10px;padding:14px;border:1px solid var(--line);background:rgba(245,244,239,.04)}
244+
.pd-nudge-copy{color:var(--mute);letter-spacing:.06em;line-height:1.5;margin-bottom:10px;text-transform:none;font-size:11px;font-weight:600}
245+
.pd-nudge-form{display:flex;gap:8px}
246+
.pd-nudge-form input{flex:1;min-width:0;background:var(--con2);border:1px solid var(--line);color:var(--white);
247+
font-family:var(--sans);font-size:13px;padding:9px 11px}
248+
.pd-nudge-form input:focus{outline:none;border-color:var(--mute)}
249+
.pd-nudge-form button{background:var(--white);color:var(--ink);font-weight:800;font-size:9px;letter-spacing:.12em;
250+
text-transform:uppercase;padding:9px 14px;white-space:nowrap}
251+
.pd-nudge-form button:hover{background:var(--red);color:var(--white)}
252+
.pd-nudge-msg{margin-top:8px;color:var(--dim);letter-spacing:.06em;text-transform:none;font-size:11px;font-weight:600}
243253

244254
.pd-head{border-bottom:1px solid var(--line);padding-bottom:18px;margin-bottom:18px}
245255
.pd-code{color:var(--red);letter-spacing:.18em;margin-bottom:8px}

worker/wrangler.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ compatibility_date = "2024-11-01"
1010
# (older wrangler: `wrangler kv:namespace create STOCK`)
1111
[[kv_namespaces]]
1212
binding = "STOCK"
13-
id = "REPLACE_WITH_KV_NAMESPACE_ID"
13+
id = "2b13bb3aa5f04e6eae5d65c80844f865"

0 commit comments

Comments
 (0)