From a243dd8fc6bf077720b3fb5003f64db29e6d4212 Mon Sep 17 00:00:00 2001 From: jwinterm Date: Fri, 10 Jul 2026 09:11:07 -0400 Subject: [PATCH] fix(ui): real right gutter so play-area focus outline shows on the right; Smirk flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Play area: add a 6px right gutter on .container (border-box) so the outward yellow focus outline isn't clipped by overflow:hidden at the viewport edge — the inset-outline attempt got clipped in Chromium. Revert to an outward outline (ui.js). Smirk: on the NIP-98 path, only fall back to the legacy connect() when the wallet genuinely lacks signNostrEvent — a LOCKED or user-cancelled signNostrEvent now surfaces instead of triggering a second unlock prompt. (The unlock-popup-on-locked behavior itself is a wallet-build capability, added to smirk-monorepo 2026-07-09; builds before that throw LOCKED and get the friendly retry hint.) --- html/js/network/smirkAuth.js | 14 ++++++++++---- html/js/ui/ui.js | 7 +++---- html/styles/stylesheet.css | 4 ++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/html/js/network/smirkAuth.js b/html/js/network/smirkAuth.js index d9dbde6..35073e1 100644 --- a/html/js/network/smirkAuth.js +++ b/html/js/network/smirkAuth.js @@ -77,10 +77,16 @@ const SmirkAuth = { verifyData = result.verifyData; provenPublicKey = result.pubkey; } catch (nip98Err) { - // Graceful fallback: if NIP-98 signing/verification fails - // (wallet threw, lacks the method mid-flow, etc.) fall back to - // the legacy path so login still works. - console.warn('Smirk NIP-98 auth failed, falling back to legacy:', nip98Err && nip98Err.message); + // Only fall back to the legacy path when the wallet genuinely can't do NIP-98 + // (method missing / unsupported). For LOCKED (unlock the extension), USER_REJECTED + // (user closed the popup), or a real signing failure, SURFACE it — re-invoking + // connect() would just pop a second prompt. On a current Smirk build a locked + // signNostrEvent auto-opens the unlock popup and never reaches here. + const code = nip98Err && nip98Err.code; + const methodMissing = code === 'UNSUPPORTED' || code === 'METHOD_NOT_FOUND' + || /not a function|is not supported|no such method|unsupported/i.test((nip98Err && nip98Err.message) || ''); + if (!methodMissing) throw nip98Err; + console.warn('Smirk NIP-98 unsupported, falling back to legacy:', nip98Err && nip98Err.message); const result = await this._verifyLegacy(socketId, challenge); verifyData = result.verifyData; provenPublicKey = result.pubkey; diff --git a/html/js/ui/ui.js b/html/js/ui/ui.js index 53b9af3..d40c9dc 100644 --- a/html/js/ui/ui.js +++ b/html/js/ui/ui.js @@ -19,10 +19,9 @@ const UI = { var chatInput = $('#chatInput'); if (document.activeElement === gameDisplay[0]) { - // Inset the outline (offset -2px) so it is drawn INSIDE the box — the play area is - // flush to the viewport's right edge and the container clips an outward outline there, - // which hid the border on the right side. - gameDisplay.css({ 'outline': '2px solid yellow', 'outline-offset': '-2px' }); + // Outward outline; the .container now has a right gutter (padding-right) so the right + // segment isn't clipped by overflow:hidden. (Inset offset gets clipped in Chromium.) + gameDisplay.css({ 'outline': '2px solid yellow', 'outline-offset': '0' }); chatInput.css('outline', 'none'); } else if (document.activeElement === chatInput[0]) { chatInput.css('outline', '2px solid cyan'); diff --git a/html/styles/stylesheet.css b/html/styles/stylesheet.css index 807e0f8..bc33238 100644 --- a/html/styles/stylesheet.css +++ b/html/styles/stylesheet.css @@ -73,6 +73,10 @@ body { height: 100vh; width: 100%; max-width: 100vw; + box-sizing: border-box; + /* A few px of right gutter so the play area isn't flush to the viewport edge — otherwise + overflow:hidden clips the yellow focus outline on the right side. */ + padding-right: 6px; overflow: hidden; gap: 1px; background-color: var(--bg-panel);