From 104198b99212eb69af33c172b49be223b23f64e2 Mon Sep 17 00:00:00 2001 From: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> Date: Sun, 19 Jul 2026 13:06:05 -0700 Subject: [PATCH 1/2] feat(desktop): add fuzzy onboarding cards Co-authored-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub19x6jnl6rhepymwyl2xlltz3ce7rfg2ktllle3g2vu59n3s490k8s9n40l3 <29b529ff43be424db89f51bff58a38cf86942acbffff98a14ce50b38c2a57d8f@sprout-oss.stage.blox.sqprod.co> --- .../features/communities/ui/WelcomeSetup.tsx | 199 ++++++++++-------- .../src/features/onboarding/ui/BackupStep.tsx | 21 +- .../onboarding/ui/InviteRedeemForm.tsx | 68 +++--- .../onboarding/ui/MachineOnboardingFlow.tsx | 2 +- .../onboarding/ui/NostrKeyImportForm.tsx | 8 +- .../onboarding/ui/OnboardingChrome.tsx | 2 +- .../src/features/onboarding/ui/SetupStep.tsx | 13 +- desktop/src/shared/ui/card-texture.css | 6 +- desktop/src/shared/ui/card.tsx | 22 +- 9 files changed, 194 insertions(+), 147 deletions(-) diff --git a/desktop/src/features/communities/ui/WelcomeSetup.tsx b/desktop/src/features/communities/ui/WelcomeSetup.tsx index a4e7354ac31..bc29f38fd62 100644 --- a/desktop/src/features/communities/ui/WelcomeSetup.tsx +++ b/desktop/src/features/communities/ui/WelcomeSetup.tsx @@ -5,7 +5,6 @@ import { useCommunityOnboarding } from "@/features/onboarding/communityOnboardin import { normalizeRelayUrl } from "@/features/communities/relayProbe"; import { InviteRedeemForm } from "@/features/onboarding/ui/InviteRedeemForm"; import { - ONBOARDING_KEY_FRAME_CLASS, ONBOARDING_KEY_ROW_CLASS, ONBOARDING_KEY_TEXT_CLASS, } from "@/features/onboarding/ui/NsecMaskedDisplay"; @@ -20,10 +19,14 @@ import { import { getIdentity } from "@/shared/api/tauriIdentity"; import { pubkeyToNpub } from "@/shared/lib/nostrUtils"; import { Button } from "@/shared/ui/button"; +import { Card } from "@/shared/ui/card"; import { Input } from "@/shared/ui/input"; import { StartupWindowDragRegion } from "@/shared/ui/StartupWindowDragRegion"; import { useSystemColorScheme } from "@/shared/theme/useSystemColorScheme"; -import { OnboardingChrome } from "@/features/onboarding/ui/OnboardingChrome"; +import { + ONBOARDING_PRIMARY_CTA_CLASS, + OnboardingChrome, +} from "@/features/onboarding/ui/OnboardingChrome"; import { HostedCommunityOnboarding } from "@/features/communities/ui/HostedCommunityOnboarding"; import { writeTextToClipboard } from "@/shared/lib/clipboard"; @@ -37,7 +40,16 @@ type WelcomeSetupProps = { }; const COMMUNITY_OPTION_CARD_CLASS = - "flex min-h-24 w-full max-w-[352px] items-center justify-center rounded-xl bg-white/75 px-6 py-4 text-center text-sm font-normal leading-6 text-foreground transition-colors duration-150 ease-out hover:bg-white/85 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/35"; + "w-full max-w-[320px] items-center px-6 py-4 text-center text-sm font-normal leading-6 text-foreground [--buzz-card-textured-min-height:88px] transition-[filter] duration-150 ease-out hover:brightness-[0.98] focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-foreground/35"; +const WIDE_TEXTURE_CARD_CLASS = + "relative left-1/2 w-[min(calc(100%+10rem),calc(100vw-2rem))] max-w-[1040px] -translate-x-1/2 px-8 py-6 [--buzz-card-textured-min-height:192px]"; +const WIDE_TEXTURE_CONTENT_CLASS = "mx-auto w-full max-w-[840px]"; +const HORIZONTAL_INPUT_OVERFLOW_FADE = { + WebkitMaskImage: + "linear-gradient(to right, transparent, black 2rem, black calc(100% - 2rem), transparent)", + maskImage: + "linear-gradient(to right, transparent, black 2rem, black calc(100% - 2rem), transparent)", +}; export function WelcomeSetup({ initialPage = "welcome", @@ -111,16 +123,17 @@ export function WelcomeSetup({ return (
-
+
{page === "welcome" ? (
-
- - + + showPage("invite")} - type="button" + variant="textured" > - I have an invite link - - + + showPage("owned")} - type="button" + variant="textured" > - - Create or connect to my own community - - + +
-
-
+
+

- Step 1: Share your public key + Step 1: Ask your community host to send you an invite link + or add you using your public key

-
-
-
- +
+
+ + {npub || "Loading…"} + +
+
-
-
+ {identityError ? (

{identityError} @@ -257,27 +276,37 @@ export function WelcomeSetup({ onSubmit={handleJoin} >

Step 2: Paste in your community URL

- { - setRelayUrl(event.target.value); - setRelayUrlError(null); - }} - placeholder="Enter community URL" - spellCheck={false} - type="url" - value={relayUrl} - /> + +
+ { + setRelayUrl(event.target.value); + setRelayUrlError(null); + }} + placeholder="Enter community URL" + spellCheck={false} + type="url" + value={relayUrl} + /> +
+
{relayUrlError ? (

{relayUrlError} @@ -288,7 +317,7 @@ export function WelcomeSetup({

-
+
-
+

Your unique identity key has been created

@@ -93,7 +91,7 @@ export function BackupStep({ direction, onBack, onNext }: BackupStepProps) {

-
+
{isLoading ? (
@@ -125,10 +123,11 @@ export function BackupStep({ direction, onBack, onNext }: BackupStepProps) {
) : nsec ? ( - // Translucent white card frames the key with equal padding. -
- -
+ +
+ +
+
) : (

No key available to back up. diff --git a/desktop/src/features/onboarding/ui/InviteRedeemForm.tsx b/desktop/src/features/onboarding/ui/InviteRedeemForm.tsx index 8a3c961975a..55026d2b57c 100644 --- a/desktop/src/features/onboarding/ui/InviteRedeemForm.tsx +++ b/desktop/src/features/onboarding/ui/InviteRedeemForm.tsx @@ -13,11 +13,11 @@ import { } from "@/shared/api/invites"; import { cn } from "@/shared/lib/cn"; import { Button } from "@/shared/ui/button"; +import { Card } from "@/shared/ui/card"; import { Input } from "@/shared/ui/input"; import { Spinner } from "@/shared/ui/spinner"; import { JoinPolicyNotice } from "./JoinPolicyNotice"; import { - ONBOARDING_KEY_FRAME_CLASS, ONBOARDING_KEY_ROW_CLASS, ONBOARDING_KEY_TEXT_CLASS, } from "./NsecMaskedDisplay"; @@ -26,6 +26,13 @@ import { OnboardingFooter } from "./OnboardingFooter"; const POLICY_DISCOVERY_DELAY_MS = 250; const POLICY_REVEAL_EASE = [0.23, 1, 0.32, 1] as const; +const SPOTLIGHT_TEXTURE_CONTENT_CLASS = "mx-auto w-full max-w-[920px]"; +const SPOTLIGHT_OVERFLOW_FADE = { + WebkitMaskImage: + "linear-gradient(to right, transparent, black 2rem, black calc(100% - 2rem), transparent)", + maskImage: + "linear-gradient(to right, transparent, black 2rem, black calc(100% - 2rem), transparent)", +}; type InviteRedeemFormProps = { /** @@ -255,38 +262,45 @@ export function InviteRedeemForm({

{isOnboardingSpotlight ? ( - +
+ +
+ ) : (