fix(federation): presence-sign modal scales and scrolls on small phones
Some checks failed
Demo images / Build & push demo images (push) Failing after 1m37s

The info card above the action buttons now shrinks with the viewport and
scrolls internally (min-h-0 + overflow-y-auto in a max-h-full flex column),
keeping Cancel / Sign & Publish always visible. The hero disc and viz ring
scale down on narrow or short screens via a --seg-radius CSS variable so
the animation honors the smaller ring.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
archipelago 2026-07-22 03:12:15 -04:00
parent 184257390d
commit 317a72aafe

View File

@ -15,10 +15,10 @@
role="dialog"
aria-modal="true"
aria-label="Sign and publish node presence"
class="relative z-10 w-full max-w-lg"
class="relative z-10 w-full max-w-lg flex flex-col min-h-0 max-h-full"
>
<!-- Header: glass disc + radial viz ring, mirroring NostrIdentityPicker -->
<div class="relative mb-6 flex flex-col items-center">
<div class="relative mb-4 sm:mb-6 flex flex-col items-center shrink-0">
<div class="presence-hero">
<div class="presence-viz-ring">
<div
@ -41,7 +41,9 @@
<p class="mt-1 text-white/25 tracking-widest uppercase" style="font-size: 10px;">Nostr node discovery</p>
</div>
<div class="glass-card p-4 space-y-4">
<!-- Scrollable content: on short viewports (small phones) this card
shrinks and scrolls internally so the action buttons stay in view -->
<div class="glass-card p-4 space-y-4 overflow-y-auto min-h-0 overscroll-contain">
<!-- Signer: single locked row, same look as the identity picker rows.
Node discovery always signs with the node's own key never a
personal identity so there is deliberately nothing to pick. -->
@ -103,7 +105,7 @@
</div>
<!-- Actions -->
<div class="flex gap-3 mt-4">
<div class="flex gap-3 mt-4 shrink-0">
<button @click="$emit('cancel')" class="glass-button flex-1 py-3 rounded-lg text-sm font-medium text-white/70">
Cancel
</button>
@ -116,7 +118,7 @@
</button>
</div>
<p class="mt-3 text-center text-[10px] text-white/20 tracking-widest">
<p class="mt-3 text-center text-[10px] text-white/20 tracking-widest shrink-0">
NIP-01 &middot; SECP256K1 &middot; SCHNORR &middot; Signed locally
</p>
</div>
@ -160,6 +162,24 @@ function truncateNpub(npub: string): string {
height: 148px;
}
/* Small phones: shrink the hero so the signed-info card keeps most of the
viewport; the card itself scrolls internally when it still doesn't fit. */
@media (max-width: 480px), (max-height: 740px) {
.presence-hero {
width: 96px;
height: 96px;
transform: scale(0.9);
}
.presence-viz-segment {
--seg-radius: -40px;
height: 10px;
}
.presence-glass-border {
width: 72px;
height: 72px;
}
}
.presence-viz-ring {
position: absolute;
inset: 0;
@ -179,27 +199,27 @@ function truncateNpub(npub: string): string {
background: linear-gradient(to bottom, rgba(250, 250, 250, 0.4), rgba(250, 250, 250, 0.06));
border-radius: 1.5px;
transform-origin: center center;
transform: rotate(var(--seg-deg)) translateY(-60px);
transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px));
animation: presence-seg-pulse 14s ease-in-out infinite;
animation-delay: calc(var(--seg-i) * 0.02s);
}
@keyframes presence-seg-pulse {
0% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(0.4); }
7.1% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(1); }
14.3% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(0.4); }
21.4% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(1); }
28.6% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(0.4); }
35.7% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(1); }
42.9% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(0.4); }
50% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(1); }
57.1% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(0.4); }
64.3% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(1); }
71.4% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(0.4); }
78.6% { opacity: 1; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(1.5); }
85.7% { opacity: 1; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(1.5); }
92.9% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(0.4); }
100% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(-60px) scaleY(0.4); }
0% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(0.4); }
7.1% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(1); }
14.3% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(0.4); }
21.4% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(1); }
28.6% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(0.4); }
35.7% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(1); }
42.9% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(0.4); }
50% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(1); }
57.1% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(0.4); }
64.3% { opacity: 0.7; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(1); }
71.4% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(0.4); }
78.6% { opacity: 1; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(1.5); }
85.7% { opacity: 1; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(1.5); }
92.9% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(0.4); }
100% { opacity: 0.15; transform: rotate(var(--seg-deg)) translateY(var(--seg-radius, -60px)) scaleY(0.4); }
}
.presence-glass-border {