Code pill: six fixed cells on their own row, tap to copy, wrapping header; claim error names the length when it is not 6; board hint

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-20 07:59:52 -05:00
parent f1e1886f48
commit 5db6cdff52
4 changed files with 10 additions and 4 deletions
+1
View File
@@ -73,6 +73,7 @@ function check(t, memberId, typed) {
if (rec.memberId !== Number(memberId)) return { error: 'That mission belongs to a different account.' }; if (rec.memberId !== Number(memberId)) return { error: 'That mission belongs to a different account.' };
const want = codeFor(rec); const want = codeFor(rec);
const got = String(typed || '').trim().toUpperCase(); const got = String(typed || '').trim().toUpperCase();
if (got.length !== 6) return { error: 'Codes are 6 characters and you typed ' + got.length + '. Look at the site again: the code sits in six boxes, and a tap on it copies all six.' };
if (got !== want) return { error: 'That is not the code. It is on the site, and it is yours alone.' }; if (got !== want) return { error: 'That is not the code. It is on the site, and it is yours alone.' };
return { ok: true, rec }; return { ok: true, rec };
} }
+1 -1
View File
@@ -46,6 +46,6 @@
<footer class="foot">Rewards are for completed missions, not income. The daily pool is limited; when it is spent, claims close until midnight Central. Cryptocurrency involves risk of loss.</footer> <footer class="foot">Rewards are for completed missions, not income. The daily pool is limited; when it is spent, claims close until midnight Central. Cryptocurrency involves risk of loss.</footer>
</div> </div>
<div class="modal" id="shareModal" hidden><div class="modal-card"><button class="modal-x" id="shareClose" type="button" aria-label="Close">×</button><div id="shareBody"></div></div></div> <div class="modal" id="shareModal" hidden><div class="modal-card"><button class="modal-x" id="shareClose" type="button" aria-label="Close">×</button><div id="shareBody"></div></div></div>
<script src="/app.js?v=9"></script> <script src="/app.js?v=10"></script>
</body> </body>
</html> </html>
+1 -1
View File
@@ -36,7 +36,7 @@
+ '<p style="margin-top:10px"><span class="range">' + r.minPol + ' to ' + r.maxPol + ' POL</span> <span style="color:var(--dim);font-size:12px">· ' + m.dwell + 's on the site</span></p>' + '<p style="margin-top:10px"><span class="range">' + r.minPol + ' to ' + r.maxPol + ' POL</span> <span style="color:var(--dim);font-size:12px">· ' + m.dwell + 's on the site</span></p>'
+ (m.done ? '' : (board.pool && board.pool.spent && !isOpen) ? '<div style="margin-top:14px"><span class="tag gold">Closed until midnight Central</span></div>' : (board.daily && !board.daily.left && !isOpen) ? '<div style="margin-top:14px"><span class="tag">Back tomorrow</span></div>' : isOpen + (m.done ? '' : (board.pool && board.pool.spent && !isOpen) ? '<div style="margin-top:14px"><span class="tag gold">Closed until midnight Central</span></div>' : (board.daily && !board.daily.left && !isOpen) ? '<div style="margin-top:14px"><span class="tag">Back tomorrow</span></div>' : isOpen
? '<div class="timer" id="timer">Your code appears on the site after <b>' + m.dwell + 's</b>. Keep that tab open.</div>' ? '<div class="timer" id="timer">Your code appears on the site after <b>' + m.dwell + 's</b>. Keep that tab open.</div>'
+ '<div class="codebox"><input id="code" maxlength="6" placeholder="CODE" autocomplete="off" spellcheck="false"><button class="btn pol" id="submit">Claim</button></div>' + '<div class="codebox"><input id="code" maxlength="6" placeholder="6 CHARACTERS" autocomplete="off" spellcheck="false" inputmode="text" autocapitalize="characters"><button class="btn pol" id="submit">Claim</button></div><div class="site" style="font-size:12px;margin-top:6px">Six characters. On the site, tap the code to copy it, then paste it here.</div>'
+ '<div class="msg" id="msg"></div>' + '<div class="msg" id="msg"></div>'
+ '<p style="margin-top:8px"><a href="' + esc(open.url) + '" target="_blank" rel="noopener">Open the site again ↗</a></p>' + '<p style="margin-top:8px"><a href="' + esc(open.url) + '" target="_blank" rel="noopener">Open the site again ↗</a></p>'
: '<div style="margin-top:14px"><button class="btn" data-start="' + esc(m.id) + '">Start mission</button></div>') : '<div style="margin-top:14px"><button class="btn" data-start="' + esc(m.id) + '">Start mission</button></div>')
+7 -2
View File
@@ -27,8 +27,13 @@
var el = slotEl(slot); el.innerHTML = ''; var el = slotEl(slot); el.innerHTML = '';
var box = document.createElement('div'); var box = document.createElement('div');
box.setAttribute('role', 'note'); box.setAttribute('role', 'note');
box.style.cssText = 'display:inline-flex;align-items:center;gap:10px;padding:10px 14px;border-radius:14px;background:linear-gradient(135deg,#1a0f3d,#2b1a63);color:#f1eefb;font:600 14px/1.2 system-ui,-apple-system,"Segoe UI",sans-serif;box-shadow:0 8px 30px rgba(130,71,229,.45),0 0 0 1px rgba(255,255,255,.08);letter-spacing:.02em'; // the code as six fixed cells on its own row: a short read is visible at a glance, nothing can wrap or clip
box.innerHTML = '<img src="' + API + '/img/coin-sm.png" alt="" width="30" height="30" style="width:30px;height:30px;object-fit:contain;flex:none;filter:drop-shadow(0 0 8px rgba(130,71,229,.85))"><span>PolHunter code <b style="font-family:ui-monospace,Menlo,monospace;font-size:16px;letter-spacing:.14em;color:#f3be43">' + code + '</b></span>'; // a single glyph away, and a tap copies it for the board (OPG saw 5 of 6 characters twice, 2026-09-20)
box.style.cssText = 'display:inline-flex;flex-direction:column;align-items:flex-start;gap:8px;padding:12px 14px;border-radius:14px;background:linear-gradient(135deg,#1a0f3d,#2b1a63);color:#f1eefb;font:600 13px/1.2 system-ui,-apple-system,"Segoe UI",sans-serif;box-shadow:0 8px 30px rgba(130,71,229,.45),0 0 0 1px rgba(255,255,255,.08);letter-spacing:.02em;max-width:100%;cursor:pointer;-webkit-user-select:none;user-select:none';
var cells = code.split('').map(function (ch) { return '<span style="display:inline-block;min-width:26px;padding:5px 0;text-align:center;border-radius:7px;background:rgba(0,0,0,.35);border:1px solid rgba(243,190,67,.45);font:700 18px/1 ui-monospace,Menlo,monospace;color:#f3be43">' + ch + '</span>'; }).join('');
box.innerHTML = '<span style="display:flex;align-items:center;gap:8px;flex-wrap:wrap;max-width:100%"><img src="' + API + '/img/coin-sm.png" alt="" width="26" height="26" style="width:26px;height:26px;object-fit:contain;flex:none;filter:drop-shadow(0 0 8px rgba(130,71,229,.85))"><span style="white-space:nowrap">PolHunter code</span> <span style="opacity:.7;font-weight:500;font-size:12px">6 characters, tap to copy</span></span><span style="display:inline-flex;gap:4px;white-space:nowrap">' + cells + '</span>';
box.setAttribute('title', 'Tap to copy ' + code);
box.addEventListener('click', function () { var done = function () { var s = box.querySelector('span span'); if (s) s.textContent = 'copied, paste it on your board'; }; try { navigator.clipboard.writeText(code).then(done, done); } catch (e) { done(); } });
el.appendChild(box); el.appendChild(box);
} }
var tries = 0, pending = null, done = false; var tries = 0, pending = null, done = false;