diff --git a/.changeset/auth-success-page-command-cards.md b/.changeset/auth-success-page-command-cards.md new file mode 100644 index 000000000..65d8a49ac --- /dev/null +++ b/.changeset/auth-success-page-command-cards.md @@ -0,0 +1,5 @@ +--- +"clerk": patch +--- + +Replace the Clerk Skills install box on the sign-in success page with three command cards — install, customize, and deploy — showing what the CLI can do right after authentication. diff --git a/packages/cli-core/src/lib/auth-server.ts b/packages/cli-core/src/lib/auth-server.ts index cfde3424a..692a1bc60 100644 --- a/packages/cli-core/src/lib/auth-server.ts +++ b/packages/cli-core/src/lib/auth-server.ts @@ -65,30 +65,25 @@ const PAGE_STYLE = ` .auth-page > p { margin-top: 0.75rem; } @keyframes roll-in { from { transform: rotateX(90deg); opacity: 0; } to { transform: rotateX(0deg); opacity: 1; } } @keyframes fade-in { from { opacity: 0; filter: blur(2px); } to { opacity: 1; filter: blur(0px); } } - @keyframes sparkle-pulse { 0%, 100% { opacity: 0.7; transform: scale(1); } 50% { opacity: 1; transform: scale(1.12); } } - .ai-section { margin-top: 2rem; display: flex; justify-content: center; opacity: 0; animation: fade-in 0.4s ease-out 0.85s forwards; } - .ai-installer-wrap { display: flex; flex-direction: column; align-items: center; width: 24rem; max-width: 100%; } - .ai-installer { display: flex; flex-direction: column; width: 100%; border: 1px solid var(--cli-border); border-radius: 12px; overflow: hidden; text-align: left; } - .ai-header { display: flex; align-items: center; gap: 0.5rem; padding: 0.6rem 1rem; border-bottom: 1px solid var(--cli-border); background: var(--cli-tab-bg); font-size: 12.5px; color: var(--cli-fg-muted); } - .ai-header span { color: var(--cli-fg-muted); } - .ai-learn { display: inline-flex; align-items: center; gap: 0.3rem; margin-top: 0.75rem; font-size: 12px; color: var(--cli-fg-faint); text-decoration: none; transition: color 0.15s; } - .ai-learn:hover { color: var(--cli-accent); } - .ai-learn:hover .ai-external { transform: translate(1px, -1px); } - .ai-external { width: 11px; height: 11px; flex: none; color: currentColor; transition: transform 0.2s; } - .ai-sparkle { width: 14px; height: 14px; display: inline-block; flex: none; color: var(--cli-accent); animation: sparkle-pulse 2s ease-in-out infinite; transform-origin: 50% 50%; } - .ai-code-row { display: flex; align-items: center; gap: 0.5rem; padding: 0.7rem 0.5rem 0.7rem 1rem; background: var(--cli-code-bg); } - .ai-cmd-wrap { flex: 1; min-width: 0; overflow: hidden; -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 1.875rem), transparent 100%); mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 1.875rem), transparent 100%); } - .ai-cmd { display: block; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; line-height: 1.1; letter-spacing: -0.02em; color: var(--cli-fg-muted); user-select: text; } - .ai-bin { color: var(--cli-fg-muted); } - .ai-mid { color: var(--cli-syntax-mid); } - .ai-target { color: var(--cli-syntax-target); font-weight: 500; } - .ai-copy { background: transparent; border: 0; width: 1.75rem; height: 1.75rem; cursor: pointer; color: var(--cli-fg-dim); border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; flex: none; transition: color 0.3s cubic-bezier(0.4,0.36,0,1), background 0.15s, transform 0.15s; } - .ai-copy:hover { color: var(--cli-fg); background: var(--cli-hover-bg); } - .ai-copy:active { transform: scale(0.92); } - .ai-copy .icon-check { display: none; color: #16a34a; } - .ai-copy.copied .icon-copy { display: none; } - .ai-copy.copied .icon-check { display: inline; } - .ai-copy.copied, .ai-copy.copied:hover { color: #16a34a; } + .cli-cards { margin-top: 2.5rem; opacity: 0; animation: fade-in 0.4s ease-out 0.85s forwards; } + .cli-cards-intro { color: var(--cli-fg-muted); } + .cli-cards-grid { margin-top: 1rem; margin-inline: auto; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0.75rem; width: 52rem; max-width: 100%; } + @media (max-width: 860px) { .cli-cards-grid { grid-template-columns: 1fr; width: 24rem; } } + .cli-card { display: flex; flex-direction: column; gap: 0.5rem; border: 1px solid var(--cli-border); border-radius: 12px; padding: 1rem; text-align: left; } + .cli-card-title { display: flex; align-items: center; gap: 0.45rem; font-size: 13.5px; font-weight: 600; } + .cli-card-icon { width: 14px; height: 14px; flex: none; color: var(--cli-fg-dim); } + .cli-card-desc { flex: 1; font-size: 12.5px; line-height: 1.45; color: var(--cli-fg-muted); } + .cli-card-code { display: flex; align-items: center; gap: 0.5rem; margin-top: 0.25rem; padding: 0.45rem 0.35rem 0.45rem 0.75rem; border: 1px solid var(--cli-border); border-radius: 8px; background: var(--cli-code-bg); } + .cli-card-code code { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; letter-spacing: -0.02em; color: var(--cli-fg); user-select: text; } + .cli-prompt { color: var(--cli-fg-faint); user-select: none; } + .cli-bin { color: var(--cli-syntax-mid); } + .copy-btn { background: transparent; border: 0; width: 1.75rem; height: 1.75rem; cursor: pointer; color: var(--cli-fg-dim); border-radius: 6px; display: inline-flex; align-items: center; justify-content: center; flex: none; transition: color 0.3s cubic-bezier(0.4,0.36,0,1), background 0.15s, transform 0.15s; } + .copy-btn:hover { color: var(--cli-fg); background: var(--cli-hover-bg); } + .copy-btn:active { transform: scale(0.92); } + .copy-btn .icon-check { display: none; color: #16a34a; } + .copy-btn.copied .icon-copy { display: none; } + .copy-btn.copied .icon-check { display: inline; } + .copy-btn.copied, .copy-btn.copied:hover { color: #16a34a; } `; function animatedText(text: string): string { @@ -107,30 +102,45 @@ animation:roll-in 0.15s ease-out ${delay}s both;">${char}`; ); } -const SPARKLE_ICON_SVG = ``; - -const EXTERNAL_ICON_SVG = ``; +const TERMINAL_ICON_SVG = ``; const COPY_ICON_SVG = ``; const CHECK_ICON_SVG = ``; const COPY_SCRIPT = ` - function copyClerkSkill(btn) { - const cmd = document.querySelector('.ai-cmd').textContent.replace(/\\s+/g, ' ').trim(); - const reset = function () { setTimeout(function () { btn.classList.remove('copied'); }, 1500); }; - if (navigator.clipboard && window.isSecureContext) { - navigator.clipboard.writeText(cmd).then(function () { btn.classList.add('copied'); reset(); }); - } else { + function copyCmd(btn) { + const cmd = btn.parentElement.querySelector('.cli-cmd-text').textContent.replace(/\\s+/g, ' ').trim(); + const done = function () { + btn.classList.add('copied'); + setTimeout(function () { btn.classList.remove('copied'); }, 1500); + }; + const fallback = function () { const ta = document.createElement('textarea'); ta.value = cmd; ta.style.position = 'fixed'; ta.style.opacity = '0'; document.body.appendChild(ta); ta.select(); - try { document.execCommand('copy'); btn.classList.add('copied'); reset(); } catch (e) {} + try { document.execCommand('copy'); done(); } catch (e) {} document.body.removeChild(ta); + }; + if (navigator.clipboard && window.isSecureContext) { + navigator.clipboard.writeText(cmd).then(done).catch(fallback); + } else { + fallback(); } } `; +function commandCard(title: string, description: string, commandHtml: string): string { + return `
${escapeHtml(description)}
+$ ${commandHtml}
+
+ You can close this window and return to your terminal.
-npx skills add clerk/skills
- You may close this window.
+Set up, configure, and ship Clerk from your agent or terminal.
+