From 96107cd9516f38d13e20ab11bfb5ac34837814da Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Sat, 24 Jan 2026 10:20:37 -0500 Subject: [PATCH 01/16] init --- .../devPrompts/KeylessPrompt/index.tsx | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx index 9844b8ef814..df81c4c7b85 100644 --- a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx +++ b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx @@ -76,14 +76,6 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { }); }, [_props.copyKeysUrl]); - const getKeysUrlFromLastActive = useMemo(() => { - return withLastActiveFallback(() => { - const redirectUrlParts = handleDashboardUrlParsing(_props.copyKeysUrl); - const url = new URL(`${redirectUrlParts.baseDomain}/last-active?path=api-keys`); - return url.href; - }); - }, [_props.copyKeysUrl]); - const mainCTAStyles = css` ${basePromptElementStyles}; display: flex; @@ -131,10 +123,11 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { '&[data-expanded="true"]': { flexDirection: 'column', - alignItems: 'flex-center', - justifyContent: 'flex-center', - height: claimed || success ? 'fit-content' : isSignedIn ? '8.5rem' : '12rem', - overflow: 'hidden', + alignItems: 'flex-start', + justifyContent: 'flex-start', + // Use fit-content for height - this will be animated with interpolate-size in modern browsers + height: 'fit-content', + overflow: 'clip', width: 'fit-content', minWidth: '16.125rem', gap: `${t.space.$1x5}`, @@ -142,6 +135,11 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { borderRadius: `${t.radii.$xl}`, transition: 'all 230ms cubic-bezier(0.28, 1, 0.32, 1)', }, + + // Progressive enhancement for height: auto/fit-content transitions + '@supports (interpolate-size: allow-keywords)': { + interpolateSize: 'allow-keywords', + }, })} > + ) : ( + ({ + flexDirection: 'column', + alignItems: 'center', + gap: t.space.$2x5, + })} + > + - Dismiss - - ) : ( - ({ - flexDirection: 'column', - alignItems: 'center', - gap: t.space.$2x5, - })} - > - - {claimed ? 'Get API keys' : 'Claim application'} - - - ))} + } + `} + > + {claimed ? 'Get API keys' : 'Claim application'} + + + )} From 0a730a5a5ab76835abe552195ac84af291c83730 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Sat, 24 Jan 2026 10:59:07 -0500 Subject: [PATCH 05/16] wip --- packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx index 1b9e6b1b022..d63524ffa3a 100644 --- a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx +++ b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx @@ -315,7 +315,8 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { flexDirection: 'column', gap: t.space.$3, opacity: isForcedExpanded ? 1 : 0, - transition: 'opacity 150ms ease-out', + // Fade in during expansion, finishing slightly after container completes + transition: 'opacity 250ms ease-out', transitionDelay: isForcedExpanded ? '50ms' : '0ms', })} > From 7f1a2f1b5f2986353ecbaa5864124a54289876ac Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Sat, 24 Jan 2026 11:00:25 -0500 Subject: [PATCH 06/16] wip --- .../ui/src/components/devPrompts/KeylessPrompt/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx index d63524ffa3a..d9f32520419 100644 --- a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx +++ b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx @@ -127,9 +127,9 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { padding: `${t.space.$2} ${t.space.$3}`, borderRadius: '1.25rem', - // Transition all morphing properties at same rate + // Transition all morphing properties at same rate - snappier timing transition: - 'width 200ms ease-out, height 200ms ease-out, padding 200ms ease-out, border-radius 200ms ease-out, gap 200ms ease-out, background 200ms ease-out', + 'width 150ms ease-out, height 150ms ease-out, padding 150ms ease-out, border-radius 150ms ease-out, gap 150ms ease-out, background 150ms ease-out', '&[data-expanded="false"]:hover': { background: 'linear-gradient(180deg, rgba(255, 255, 255, 0.20) 0%, rgba(255, 255, 255, 0) 100%), #1f1f1f', @@ -316,8 +316,8 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { gap: t.space.$3, opacity: isForcedExpanded ? 1 : 0, // Fade in during expansion, finishing slightly after container completes - transition: 'opacity 250ms ease-out', - transitionDelay: isForcedExpanded ? '50ms' : '0ms', + transition: 'opacity 180ms ease-out', + transitionDelay: isForcedExpanded ? '30ms' : '0ms', })} >
Date: Sat, 24 Jan 2026 11:25:16 -0500 Subject: [PATCH 07/16] wip --- .../devPrompts/KeylessPrompt/index.tsx | 332 +++++++++--------- 1 file changed, 175 insertions(+), 157 deletions(-) diff --git a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx index d9f32520419..3347ff39ed0 100644 --- a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx +++ b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx @@ -28,6 +28,11 @@ const buttonIdentifierPrefix = `--clerk-keyless-prompt`; const buttonIdentifier = `${buttonIdentifierPrefix}-button`; const contentIdentifier = `${buttonIdentifierPrefix}-content`; +// Animation timing constants +const ANIMATION_DURATION = '150ms'; +const CONTENT_FADE_DURATION = '180ms'; +const CONTENT_FADE_DELAY = '30ms'; + /** * If we cannot reconstruct the url properly, then simply fallback to Clerk Dashboard */ @@ -55,6 +60,7 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { const appName = environment.displayConfig.applicationName; const isForcedExpanded = claimed || success || isExpanded; + const claimUrlToDashboard = useMemo(() => { if (claimed) { return _props.copyKeysUrl; @@ -76,6 +82,9 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { }); }, [_props.copyKeysUrl]); + // Determine CTA button color based on state + const ctaButtonColor = claimed || success ? 'white' : '#fde047'; + const mainCTAStyles = css` ${basePromptElementStyles}; display: flex; @@ -89,7 +98,7 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { font-size: 0.75rem; font-weight: 500; letter-spacing: 0.12px; - color: ${claimed ? 'white' : success ? 'white' : '#fde047'}; + color: ${ctaButtonColor}; text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.32); white-space: nowrap; user-select: none; @@ -103,6 +112,144 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { 0px 0px 4px 0px rgba(243, 107, 22, 0) inset; `; + // Determine CTA button hover styles + const ctaButtonHoverStyles = claimed + ? 'background: #4B4B4B; transition: all 120ms ease-in-out;' + : `box-shadow: + 0px 0px 6px 0px rgba(253, 224, 71, 0.24) inset, + 0px 0px 0px 1px rgba(255, 255, 255, 0.04) inset, + 0px 1px 0px 0px rgba(255, 255, 255, 0.04) inset, + 0px 0px 0px 1px rgba(0, 0, 0, 0.12), + 0px 1.5px 2px 0px rgba(0, 0, 0, 0.48);`; + + // Render the appropriate icon based on state + function renderStatusIcon() { + if (success) { + return ( + + ); + } + + if (claimed) { + return ( + + + + ); + } + + return ( +
+ + + + + + + +
+ ); + } + + // Get the status text based on state + function getStatusText() { + if (success) { + return 'Claim completed'; + } + if (claimed) { + return 'Missing environment keys'; + } + return 'Clerk is in keyless mode'; + } + + // Common paragraph styles for content text + const contentParagraphStyles = css` + ${basePromptElementStyles}; + color: #b4b4b4; + font-size: 0.8125rem; + font-weight: 400; + line-height: 1rem; + `; + + // Title text styles + const titleTextStyles = css` + ${basePromptElementStyles}; + color: #d9d9d9; + font-size: 0.875rem; + font-weight: 500; + white-space: nowrap; + cursor: pointer; + `; + return ( { padding: `${t.space.$2} ${t.space.$3}`, borderRadius: '1.25rem', - // Transition all morphing properties at same rate - snappier timing - transition: - 'width 150ms ease-out, height 150ms ease-out, padding 150ms ease-out, border-radius 150ms ease-out, gap 150ms ease-out, background 150ms ease-out', + // AIM transition - interpolate-size handles fit-content smoothly + transition: `width ${ANIMATION_DURATION} cubic-bezier(0.4, 0, 0.2, 1), + height ${ANIMATION_DURATION} cubic-bezier(0.4, 0, 0.2, 1), + padding ${ANIMATION_DURATION} cubic-bezier(0.4, 0, 0.2, 1), + border-radius ${ANIMATION_DURATION} cubic-bezier(0.4, 0, 0.2, 1), + gap ${ANIMATION_DURATION} cubic-bezier(0.4, 0, 0.2, 1), + background ${ANIMATION_DURATION} cubic-bezier(0.4, 0, 0.2, 1)`, '&[data-expanded="false"]:hover': { background: 'linear-gradient(180deg, rgba(255, 255, 255, 0.20) 0%, rgba(255, 255, 255, 0) 100%), #1f1f1f', }, '&[data-expanded="true"]': { - // Expanded: static width, dynamic height via fit-content + // Expanded: static width, dynamic height via fit-content (AIM technique) + // interpolate-size: allow-keywords enables smooth transition to fit-content width: '16.125rem', height: 'fit-content', gap: `${t.space.$1x5}`, @@ -165,108 +317,14 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { gap: t.space.$2, })} > - {success ? ( - - ) : claimed ? ( - - - - ) : ( -
- - - - - - - -
- )} + {renderStatusIcon()}

- {success ? 'Claim completed' : claimed ? 'Missing environment keys' : 'Clerk is in keyless mode'} + {getStatusText()}

@@ -315,9 +373,9 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { flexDirection: 'column', gap: t.space.$3, opacity: isForcedExpanded ? 1 : 0, - // Fade in during expansion, finishing slightly after container completes - transition: 'opacity 180ms ease-out', - transitionDelay: isForcedExpanded ? '30ms' : '0ms', + transition: `opacity ${CONTENT_FADE_DURATION} cubic-bezier(0.4, 0, 0.2, 1)`, + transitionDelay: isForcedExpanded ? CONTENT_FADE_DELAY : '0ms', + pointerEvents: isForcedExpanded ? 'auto' : 'none', })} >
{ `} > {success ? ( -

+

Your application{' '} {

) : claimed ? ( -

+

You claimed this application but haven't set keys in your environment. Get them from the Clerk Dashboard.

) : isSignedIn ? ( -

+

You've created your first user! Link this application to your Clerk account to explore the Dashboard. @@ -411,11 +445,7 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { <>

@@ -423,11 +453,7 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => {

@@ -442,9 +468,11 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { {success ? ( + `} + > + + + - ({ - flexDirection: 'column', - gap: t.space.$3, - opacity: isForcedExpanded ? 1 : 0, - transition: `opacity ${CONTENT_FADE_DURATION} ${EASING_CURVE}`, - transitionDelay: isForcedExpanded ? CONTENT_FADE_DELAY : '0ms', - pointerEvents: isForcedExpanded ? 'auto' : 'none', - })} - > -

({ + flexDirection: 'column', + gap: t.space.$3, + opacity: isForcedExpanded ? 1 : 0, + transition: `opacity ${CONTENT_FADE_DURATION} ${EASING_CURVE}`, + transitionDelay: isForcedExpanded ? CONTENT_FADE_DELAY : '0ms', + pointerEvents: isForcedExpanded ? 'auto' : 'none', + // marginBlockEnd: `calc(-1 * ${t.space.$3})`, + // paddingBlockEnd: t.space.$3, + // maskImage: `linear-gradient(to bottom, black calc(100% - ${t.space.$3}), transparent)`, + })} >
- {success ? ( -

- Your application{' '} - - {appName} - {' '} - has been claimed. Configure settings from the{' '} - ({ - color: t.colors.$whiteAlpha600, - textDecoration: 'underline solid', - transition: `${t.transitionTiming.$common} ${t.transitionDuration.$fast}`, - ':hover': { - color: t.colors.$whiteAlpha800, - }, - })} - > - Clerk Dashboard - -

- ) : claimed ? ( -

- You claimed this application but haven't set keys in your environment. Get them from the Clerk - Dashboard. -

- ) : isSignedIn ? ( -

- - You've created your first user! Link this application to your Clerk account to explore the +

+ {success ? ( +

+ Your application{' '} + + {appName} + {' '} + has been claimed. Configure settings from the{' '} + ({ + color: t.colors.$whiteAlpha600, + textDecoration: 'underline solid', + transition: `${t.transitionTiming.$common} ${t.transitionDuration.$fast}`, + ':hover': { + color: t.colors.$whiteAlpha800, + }, + })} + > + Clerk Dashboard + +

+ ) : claimed ? ( +

+ You claimed this application but haven't set keys in your environment. Get them from the Clerk Dashboard. - -

- ) : ( - <> -

- Temporary API keys are enabled so you can get started immediately.

-

- Claim this application to access the Clerk Dashboard where you can manage auth settings and explore - more Clerk features. + ) : isSignedIn ? ( +

+ + You've created your first user! Link this application to your Clerk account to explore the + Dashboard. +

- - )} + ) : ( + <> +

+ Temporary API keys are enabled so you can get started immediately. +

+

+ Claim this application to access the Clerk Dashboard where you can manage auth settings and + explore more Clerk features. +

+ + )} +
-
- {success ? ( - - ) : ( - ({ - flexDirection: 'column', - alignItems: 'center', - gap: t.space.$2x5, - })} - > - { + void (async () => { + await _props.onDismiss?.(); + window.location.reload(); + })(); + }} css={css` ${mainCTAStyles}; - opacity: ${isForcedExpanded ? 1 : 0}; - ${isAnimating ? 'pointer-events: none; opacity: 0.6;' : ''} - transition: opacity ${isForcedExpanded ? CONTENT_FADE_DURATION : '80ms'} ${EASING_CURVE}; - transitiondelay: ${isForcedExpanded ? CONTENT_FADE_DELAY : '0ms'}; &:hover { - ${isAnimating ? '' : ctaButtonHoverStyles} + background: #4b4b4b; + transition: all 120ms ease-in-out; } `} > - {claimed ? 'Get API keys' : 'Claim application'} - - - )} + Dismiss + + ) : ( + ({ + flexDirection: 'column', + alignItems: 'center', + gap: t.space.$2x5, + })} + > + + {claimed ? 'Get API keys' : 'Claim application'} + + + )} + @@ -546,6 +553,315 @@ const KeylessPromptInternal = (_props: KeylessPromptProps) => { ); }; +function KeylessPromptInternal(_props: KeylessPromptProps) { + const [isOpen, setIsOpen] = useState(false); + const id = React.useId(); + return ( + + + {/* @property enables animating custom properties in gradients */} + +
+ + +
+
+
+
+
+

Temporary API keys are enabled so you can get started immediately.

+

+ Claim this application to access the Clerk Dashboard where you can manage auth settings and + explore more Clerk features. +

+
+ + + Claim application + + + +
+
+
+
+
+
+
+ ); +} + export const KeylessPrompt = (props: KeylessPromptProps) => ( From 7f368e1520ccdb39125fa28b3e3aada5c6ff45b5 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Sat, 24 Jan 2026 17:56:08 -0500 Subject: [PATCH 12/16] wip --- .../devPrompts/KeylessPrompt/index.tsx | 82 +++++++++++++------ 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx index 18bdf227d43..fa683c94790 100644 --- a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx +++ b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx @@ -556,18 +556,35 @@ const _KeylessPromptInternal = (_props: KeylessPromptProps) => { function KeylessPromptInternal(_props: KeylessPromptProps) { const [isOpen, setIsOpen] = useState(false); const id = React.useId(); + const containerRef = React.useRef(null); + + React.useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Escape' && isOpen) { + setIsOpen(false); + } + }; + + const handleClickOutside = (e: MouseEvent) => { + if (isOpen && containerRef.current && !containerRef.current.contains(e.target as Node)) { + setIsOpen(false); + } + }; + + window.addEventListener('keydown', handleKeyDown); + document.addEventListener('mousedown', handleClickOutside); + + return () => { + window.removeEventListener('keydown', handleKeyDown); + document.removeEventListener('mousedown', handleClickOutside); + }; + }, [isOpen]); + return ( - {/* @property enables animating custom properties in gradients */} -
@@ -814,6 +843,7 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { rgb(108, 71, 255) 0px 0px 0px 1px, rgba(255, 255, 255, 0.07) 0px 1px 0px 0px inset, rgba(33, 33, 38, 0.2) 0px 1px 3px 0px; + outline: none; &::before { content: ''; position: absolute; @@ -822,6 +852,10 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { mix-blend-mode: overlay; border-radius: inherit; } + &:focus-visible { + outline: 2px solid #6c47ff; + outline-offset: 2px; + } `} > Date: Sat, 24 Jan 2026 18:03:09 -0500 Subject: [PATCH 13/16] wip --- .../components/devPrompts/KeylessPrompt/index.tsx | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx index fa683c94790..93b43b2a334 100644 --- a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx +++ b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx @@ -381,7 +381,6 @@ const _KeylessPromptInternal = (_props: KeylessPromptProps) => { transition: `opacity ${CONTENT_FADE_DURATION} ${EASING_CURVE}`, transitionDelay: isForcedExpanded ? CONTENT_FADE_DELAY : '0ms', pointerEvents: isForcedExpanded ? 'auto' : 'none', - // marginBlockEnd: `calc(-1 * ${t.space.$3})`, // paddingBlockEnd: t.space.$3, // maskImage: `linear-gradient(to bottom, black calc(100% - ${t.space.$3}), transparent)`, })} @@ -736,6 +735,19 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { > Clerk is in keyless mode + + {isOpen ? 'Collapse' : 'Expand'} prompt content + Date: Sat, 24 Jan 2026 19:41:39 -0500 Subject: [PATCH 14/16] wip --- .../devPrompts/KeylessPrompt/index.tsx | 223 +++++++++--------- 1 file changed, 112 insertions(+), 111 deletions(-) diff --git a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx index 93b43b2a334..aca833b071e 100644 --- a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx +++ b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx @@ -585,17 +585,28 @@ function KeylessPromptInternal(_props: KeylessPromptProps) {
@@ -670,6 +680,7 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { --size: 1rem; width: var(--size); height: var(--size); + color: var(--foreground); `} viewBox='0 0 128 128' fill='none' @@ -679,36 +690,34 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { cx='64' cy='64' r='20' - fill='#fafafa' + fill='currentColor' /> @@ -756,7 +765,7 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { --size: 1rem; width: var(--size); height: var(--size); - color: white; + color: var(--foreground); margin-inline-start: auto; margin-inline-end: 0.75rem; opacity: ${isOpen ? 0.6 : 0}; @@ -783,7 +792,8 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { grid-template-rows: ${isOpen ? '1fr' : '0fr'}; contain: layout style; will-change: grid-template-rows; - transition: grid-template-rows ${isOpen ? '220ms' : '180ms'} var(--ease-bezier); + transition: grid-template-rows ${isOpen ? 'var(--duration-open)' : 'var(--duration-close)'} + var(--ease-bezier); @media (prefers-reduced-motion: reduce) { transition: none; } @@ -795,110 +805,101 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { css={css` overflow: hidden; min-height: 0; - mask-image: linear-gradient(to bottom, black calc(100% - 0.75rem), transparent); `} >
-
Temporary API keys are enabled so you can get started immediately.

+

+ Claim this application to access the Clerk Dashboard where you can manage auth settings and explore + more Clerk features. +

+
+ + -

Temporary API keys are enabled so you can get started immediately.

-

- Claim this application to access the Clerk Dashboard where you can manage auth settings and - explore more Clerk features. -

-
- + - Claim application - - - -
+ + +
From 435a1ca0136371fbacd9fc90998a80dae604de19 Mon Sep 17 00:00:00 2001 From: Alex Carpenter Date: Sat, 24 Jan 2026 19:58:42 -0500 Subject: [PATCH 15/16] wip --- .../devPrompts/KeylessPrompt/index.tsx | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx index aca833b071e..d9c26028e6f 100644 --- a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx +++ b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx @@ -596,14 +596,14 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { --foreground-secondary: #b4b4b4; --accent: #6c47ff; --offset: 1.25rem; - --width-expanded: 18rem; - --width-collapsed: 13rem; + --width-opened: 18rem; + --width-closed: 13rem; position: fixed; bottom: var(--offset); right: var(--offset); z-index: 999999; height: auto; - width: ${isOpen ? 'var(--width-expanded)' : 'var(--width-collapsed)'}; + width: ${isOpen ? 'var(--width-opened)' : 'var(--width-closed)'}; interpolate-size: allow-keywords; background: linear-gradient(180deg, rgba(255, 255, 255, 0.01) 0%, rgba(255, 255, 255, 0) 100%), var(--background); @@ -615,16 +615,13 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { 0px 16px 36px -6px rgba(0, 0, 0, 0.36), 0px 6px 16px -2px rgba(0, 0, 0, 0.2); border-radius: ${isOpen ? '0.75rem' : '2.5rem'}; - contain: layout style paint; isolation: isolate; - will-change: width, height, border-radius; + will-change: width, border-radius; transform: translateZ(0); backface-visibility: hidden; transition: - height ${isOpen ? 'var(--duration-open)' : 'var(--duration-close)'} var(--ease-bezier), width ${isOpen ? 'var(--duration-open)' : 'var(--duration-close)'} var(--ease-bezier), - border-radius var(--duration-open) var(--ease-bezier), - background ${isOpen ? 'var(--duration-open)' : 'var(--duration-close)'} var(--ease-bezier); + border-radius var(--duration-open) var(--ease-bezier); @media (prefers-reduced-motion: reduce) { transition: none; } @@ -790,8 +787,6 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { css={css` display: grid; grid-template-rows: ${isOpen ? '1fr' : '0fr'}; - contain: layout style; - will-change: grid-template-rows; transition: grid-template-rows ${isOpen ? 'var(--duration-open)' : 'var(--duration-close)'} var(--ease-bezier); @media (prefers-reduced-motion: reduce) { @@ -805,11 +800,12 @@ function KeylessPromptInternal(_props: KeylessPromptProps) { css={css` overflow: hidden; min-height: 0; + mask-image: linear-gradient(to bottom, black calc(100% - 0.75rem), transparent); `} >
Date: Sat, 24 Jan 2026 20:16:40 -0500 Subject: [PATCH 16/16] slide in the line --- .../devPrompts/KeylessPrompt/index.tsx | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx index d9c26028e6f..c13ffd7b427 100644 --- a/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx +++ b/packages/ui/src/components/devPrompts/KeylessPrompt/index.tsx @@ -675,6 +675,7 @@ function KeylessPromptInternal(_props: KeylessPromptProps) {