mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-09-05 08:06:19 +00:00
design review improvements
This commit is contained in:
parent
89d65816f1
commit
05e8bd1161
12 changed files with 139 additions and 70 deletions
|
|
@ -169,7 +169,7 @@ export default function OnboardingPage() {
|
|||
<div className="min-h-screen bg-black">
|
||||
{isWelcomeFlow && (
|
||||
<InitialHeader
|
||||
showUserSupermemory={currentStep === "features"}
|
||||
showUserSupermemory={currentStep === "features" || currentStep === "memories"}
|
||||
name={name}
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { PanelRightCloseIcon, SendIcon } from "lucide-react"
|
|||
import { collectValidUrls } from "@/utils/url-helpers"
|
||||
import { $fetch } from "@lib/api"
|
||||
import { cn } from "@lib/utils"
|
||||
import { dmSansFont } from "@/utils/fonts"
|
||||
import { dmSansClassName } from "@/utils/fonts"
|
||||
|
||||
interface ChatSidebarProps {
|
||||
formData: {
|
||||
|
|
@ -268,13 +268,13 @@ export function ChatSidebar({ formData }: ChatSidebarProps) {
|
|||
key="closed"
|
||||
className={cn(
|
||||
"absolute top-0 right-0 flex items-start justify-start m-4",
|
||||
dmSansFont.className,
|
||||
dmSansClassName(),
|
||||
)}
|
||||
layoutId="chat-toggle-button"
|
||||
>
|
||||
<motion.button
|
||||
onClick={toggleChat}
|
||||
className="flex items-center gap-2 rounded-full px-3 py-1.5 text-xs font-medium border-[1px] border-[#17181A]"
|
||||
className="flex items-center gap-2 rounded-full px-3 py-1.5 text-xs font-medium border-[1px] border-[#17181A] text-white cursor-pointer"
|
||||
style={{
|
||||
background: "linear-gradient(180deg, #0A0E14 0%, #05070A 100%)",
|
||||
}}
|
||||
|
|
@ -288,7 +288,7 @@ export function ChatSidebar({ formData }: ChatSidebarProps) {
|
|||
key="open"
|
||||
className={cn(
|
||||
"w-[450px] h-[calc(100vh-110px)] bg-[#0A0E14] backdrop-blur-md flex flex-col rounded-2xl m-4",
|
||||
dmSansFont.className,
|
||||
dmSansClassName(),
|
||||
)}
|
||||
initial={{ x: "100px", opacity: 0 }}
|
||||
animate={{ x: 0, opacity: 1 }}
|
||||
|
|
@ -297,7 +297,7 @@ export function ChatSidebar({ formData }: ChatSidebarProps) {
|
|||
>
|
||||
<motion.button
|
||||
onClick={toggleChat}
|
||||
className="absolute top-4 right-4 flex items-center gap-2 rounded-full p-2 text-xs"
|
||||
className="absolute top-4 right-4 flex items-center gap-2 rounded-full p-2 text-xs text-white cursor-pointer"
|
||||
style={{
|
||||
background: "linear-gradient(180deg, #0A0E14 0%, #05070A 100%)",
|
||||
}}
|
||||
|
|
@ -308,7 +308,7 @@ export function ChatSidebar({ formData }: ChatSidebarProps) {
|
|||
</motion.button>
|
||||
<div className="flex-1 flex flex-col px-4 space-y-3 pb-4 justify-end">
|
||||
{messages.length === 0 && !isLoading && !formData && (
|
||||
<div className="flex items-center gap-2 text-foreground/50">
|
||||
<div className="flex items-center gap-2 text-white/50">
|
||||
<NovaOrb size={28} className="!blur-none" />
|
||||
<span className="text-sm">Waiting for your input</span>
|
||||
</div>
|
||||
|
|
@ -325,7 +325,7 @@ export function ChatSidebar({ formData }: ChatSidebarProps) {
|
|||
className="flex items-start gap-2"
|
||||
>
|
||||
{msg.type === "waiting" ? (
|
||||
<div className="flex items-center gap-2 text-foreground/70">
|
||||
<div className="flex items-center gap-2 text-white/50">
|
||||
<NovaOrb size={30} className="!blur-none" />
|
||||
<span className="text-sm">{msg.message}</span>
|
||||
</div>
|
||||
|
|
@ -374,7 +374,7 @@ export function ChatSidebar({ formData }: ChatSidebarProps) {
|
|||
</a>
|
||||
)}
|
||||
{memory.description && (
|
||||
<p className="text-xs text-foreground/70 mt-1">
|
||||
<p className="text-xs text-white/50 mt-1">
|
||||
{memory.description}
|
||||
</p>
|
||||
)}
|
||||
|
|
@ -403,13 +403,13 @@ export function ChatSidebar({ formData }: ChatSidebarProps) {
|
|||
onChange={(e) => setMessage(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
placeholder="Chat with your Supermemory"
|
||||
className="w-full text-foreground placeholder:text-foreground/20 rounded-sm outline-none resize-none text-base leading-relaxed bg-transparent px-2 h-10"
|
||||
className="w-full text-white placeholder:text-white/20 rounded-sm outline-none resize-none text-base leading-relaxed bg-transparent px-2 h-10"
|
||||
/>
|
||||
<div className="flex justify-end absolute bottom-3 right-2">
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={!message.trim()}
|
||||
className="text-foreground/20 hover:text-foreground disabled:opacity-50 disabled:cursor-not-allowed rounded-xl transition-all"
|
||||
className="text-white/20 hover:text-white disabled:opacity-50 disabled:cursor-not-allowed rounded-xl transition-all"
|
||||
size="icon"
|
||||
>
|
||||
<SendIcon className="size-4" />
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { useState } from "react"
|
|||
import { Button } from "@ui/components/button"
|
||||
import { MCPDetailView } from "@/components/mcp-detail-view"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { cn } from "@lib/utils"
|
||||
import { dmSansClassName } from "@/utils/fonts"
|
||||
|
||||
const integrationCards = [
|
||||
{
|
||||
|
|
@ -24,7 +26,7 @@ const integrationCards = [
|
|||
description: "Set up once and use your memory in Cursor, Claude, etc",
|
||||
icon: (
|
||||
<div className="rounded flex items-center justify-center">
|
||||
<img src="/mcp-icon.svg" alt="MCP" className="size-14" />
|
||||
<img src="/onboarding/mcp.png" alt="MCP" className="size-28 h-auto" />
|
||||
</div>
|
||||
),
|
||||
},
|
||||
|
|
@ -66,13 +68,13 @@ export function IntegrationsStep() {
|
|||
<h1 className="text-white text-3xl font-medium">
|
||||
Build your personal memory
|
||||
</h1>
|
||||
<p className="text-white text-sm opacity-60 max-w-xs">
|
||||
<p className={cn("text-white text-sm opacity-60 max-w-xs", dmSansClassName())}>
|
||||
Your supermemory comes alive when you capture and connect what's
|
||||
important
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-2 max-w-lg w-full mb-12">
|
||||
<div className="grid grid-cols-2 gap-3 max-w-lg w-full mb-12">
|
||||
{integrationCards.map((card) => {
|
||||
const isClickable = card.title === "Connect to AI"
|
||||
|
||||
|
|
@ -81,7 +83,9 @@ export function IntegrationsStep() {
|
|||
<button
|
||||
key={card.title}
|
||||
type="button"
|
||||
className="bg-[#080B0F] relative rounded-lg p-4 hover:border-gray-600 transition-colors duration-300 border-2 border-[#0D121A] cursor-pointer text-left w-full hover:bg-[url('/onboarding/bg-gradient-1.png')] hover:bg-[length:250%_auto] hover:bg-[center_top_3rem] hover:bg-no-repeat"
|
||||
className={cn("bg-[#080B0F] relative rounded-lg p-4 hover:border-[#3374FF] hover:border-[0.1px] transition-colors duration-300 border-[0.1px] border-[#0D121A] cursor-pointer text-left w-full hover:bg-[url('/onboarding/bg-gradient-1.png')] hover:bg-[length:175%_auto] hover:bg-[center_top_2rem] hover:bg-no-repeat",
|
||||
"hover:border-b-0 border-b-0"
|
||||
)}
|
||||
onClick={() => setSelectedCard("Connect to AI")}
|
||||
>
|
||||
<div className="flex-1 mt-10">
|
||||
|
|
@ -100,7 +104,7 @@ export function IntegrationsStep() {
|
|||
return (
|
||||
<div
|
||||
key={card.title}
|
||||
className="bg-[#080B0F] relative rounded-lg p-4 hover:border-gray-600 transition-colors duration-300 border-2 border-[#0D121A] hover:bg-[url('/onboarding/bg-gradient-1.png')] hover:bg-[length:150%_auto] hover:bg-[center_top_2rem] hover:bg-no-repeat"
|
||||
className="bg-[#080B0F] relative rounded-lg p-4 hover:border-[#3374FF] hover:border-[0.1px] transition-colors duration-300 border-[0.1px] border-[#0D121A] hover:bg-[url('/onboarding/bg-gradient-1.png')] hover:bg-[length:175%_auto] hover:bg-[center_top_2rem] hover:bg-no-repeat"
|
||||
>
|
||||
<div className="flex-1 mt-10">
|
||||
<h3 className="text-white text-sm font-medium">{card.title}</h3>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { motion } from "motion/react"
|
|||
import { Button } from "@ui/components/button"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { cn } from "@lib/utils"
|
||||
import { dmSansFont } from "@/utils/fonts"
|
||||
import { dmSansClassName } from "@/utils/fonts"
|
||||
|
||||
const relatableOptions = [
|
||||
{
|
||||
|
|
@ -58,18 +58,18 @@ export function RelatableQuestion() {
|
|||
<div
|
||||
className={cn(
|
||||
"flex flex-wrap justify-center gap-4 max-w-3xl",
|
||||
dmSansFont.className,
|
||||
dmSansClassName(),
|
||||
)}
|
||||
>
|
||||
{relatableOptions.map((option, index) => (
|
||||
<button
|
||||
key={option.text}
|
||||
className={`
|
||||
relative rounded-lg p-2 cursor-pointer transition-all duration-300 opacity-50 hover:opacity-100 border-[#0D121A] max-w-[140px] min-h-[159px]
|
||||
relative rounded-lg p-2 cursor-pointer transition-all duration-300 opacity-50 hover:opacity-100 hover:border-[#4C608B] hover:border-[1px] border-[#0D121A] max-w-[140px] min-h-[159px]
|
||||
${
|
||||
selectedOptions.includes(index)
|
||||
? "border-[#3374FF] border-[0.1px] opacity-100 bg-[url('/onboarding/bg-gradient-1.png')] bg-[length:250%_auto] bg-[center_top_3rem] bg-no-repeat"
|
||||
: "border-2 bg-[#080B0F] hover:bg-[url('/onboarding/bg-gradient-1.png')] hover:bg-[length:250%_auto] hover:bg-[center_top_3rem] hover:bg-no-repeat"
|
||||
: "border-2 bg-[#080B0F] hover:bg-[url('/onboarding/bg-gradient-1.png')] hover:bg-[length:450%_auto] hover:bg-[center_top_3rem] hover:bg-no-repeat"
|
||||
}
|
||||
`}
|
||||
onClick={() => {
|
||||
|
|
@ -103,8 +103,11 @@ export function RelatableQuestion() {
|
|||
<div className="flex gap-4 my-8">
|
||||
<div key={selectedOptions.length === 0 ? "skip" : "continue"}>
|
||||
<Button
|
||||
className="text-foreground font-medium"
|
||||
variant="link"
|
||||
className={cn(
|
||||
"font-medium text-white",
|
||||
selectedOptions.length !== 0 ? "rounded-xl" : "",
|
||||
)}
|
||||
variant={selectedOptions.length !== 0 ? "onboarding" : "link"}
|
||||
size="lg"
|
||||
onClick={handleContinueOrSkip}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { dmSansFont } from "@/utils/fonts"
|
||||
import { dmSansClassName } from "@/utils/fonts"
|
||||
import { cn } from "@lib/utils"
|
||||
import { Button } from "@ui/components/button"
|
||||
import { motion } from "motion/react"
|
||||
|
|
@ -22,8 +22,8 @@ export function ContinueStep() {
|
|||
>
|
||||
<p
|
||||
className={cn(
|
||||
"text-[#8A8A8A] text-sm opacity-80 mb-6 max-w-sm",
|
||||
dmSansFont.className,
|
||||
"text-[#8A8A8A] text-sm mb-6 max-w-sm",
|
||||
dmSansClassName(),
|
||||
)}
|
||||
>
|
||||
I'm built with Supermemory's super fast memory API,
|
||||
|
|
@ -31,7 +31,7 @@ export function ContinueStep() {
|
|||
across your AI apps.
|
||||
</p>
|
||||
<Button
|
||||
className="rounded-xl px-6 py-3 bg-black border border-gray-800 hover:bg-gray-900 h-[40px] cursor-pointer"
|
||||
variant="onboarding"
|
||||
onClick={handleContinue}
|
||||
>
|
||||
Continue →
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { motion } from "motion/react"
|
|||
import { Button } from "@ui/components/button"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { cn } from "@lib/utils"
|
||||
import { dmSansFont } from "@/utils/fonts"
|
||||
import { dmSansClassName } from "@/utils/fonts"
|
||||
|
||||
export function FeaturesStep() {
|
||||
const router = useRouter()
|
||||
|
|
@ -15,14 +15,14 @@ export function FeaturesStep() {
|
|||
initial={{ opacity: 0, y: 40 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, ease: "easeOut", delay: 0.3 }}
|
||||
className="text-center max-w-[22rem]"
|
||||
className="text-center max-w-[22rem] space-y-6"
|
||||
layout
|
||||
>
|
||||
<h2 className="text-white text-3xl font-medium mb-2">
|
||||
<h2 className="text-white text-3xl font-medium">
|
||||
What I can do for you
|
||||
</h2>
|
||||
|
||||
<div className={cn("space-y-4 mb-8 letter-spacing-[-0.01em] ", dmSansFont.className)}>
|
||||
<div className={cn("space-y-4 mb-8 mx-4", dmSansClassName())}>
|
||||
<div className="flex items-start space-x-2">
|
||||
<div className="w-14 h-14 rounded-lg flex items-center justify-center flex-shrink-0">
|
||||
<img
|
||||
|
|
@ -32,12 +32,11 @@ export function FeaturesStep() {
|
|||
/>
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<p className="text-white font-light text-[14px]">
|
||||
<p className="text-white font-light">
|
||||
Remember every context
|
||||
</p>
|
||||
<p className="text-[#8A8A8A] text-[14px]">
|
||||
I keep track of what you've saved and shared with your
|
||||
supermemory.
|
||||
<p className="text-[#8A8A8A]">
|
||||
I keep track of what you've saved and shared with your supermemory.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -51,11 +50,11 @@ export function FeaturesStep() {
|
|||
/>
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<p className="text-white font-light text-lg">
|
||||
<p className="text-white font-light">
|
||||
Find when you need it
|
||||
</p>
|
||||
<p className="text-[#8A8A8A] text-xs">
|
||||
I surface the right memories inside your supermemory, superfast.
|
||||
<p className="text-[#8A8A8A]">
|
||||
I surface the right memories inside <br /> your supermemory, superfast.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -69,10 +68,10 @@ export function FeaturesStep() {
|
|||
/>
|
||||
</div>
|
||||
<div className="text-left">
|
||||
<p className="text-white font-light text-lg">
|
||||
<p className="text-white font-light">
|
||||
Grow with your supermemory
|
||||
</p>
|
||||
<p className="text-[#8A8A8A] text-xs">
|
||||
<p className="text-[#8A8A8A]">
|
||||
I learn and personalize over time, so every interaction feels
|
||||
natural.
|
||||
</p>
|
||||
|
|
@ -89,12 +88,10 @@ export function FeaturesStep() {
|
|||
initial={{ opacity: 0, y: 10 }}
|
||||
>
|
||||
<Button
|
||||
className="rounded-xl px-6 py-3 bg-black border border-gray-800 hover:bg-gray-900 max-w-[10rem] h-[40px] cursor-pointer"
|
||||
variant="onboarding"
|
||||
onClick={handleContinue}
|
||||
>
|
||||
<motion.button whileTap={{ scale: 0.95 }} className="w-full">
|
||||
Add memories →
|
||||
</motion.button>
|
||||
Add memories →
|
||||
</Button>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ export function MemoriesStep({ onSubmit }: MemoriesStepProps) {
|
|||
placeholder="x.com/yourhandle"
|
||||
value={twitterHandle}
|
||||
onChange={(e) => setTwitterHandle(e.target.value)}
|
||||
className="w-full px-4 py-2 bg-[#070E1B] border border-[#525966]/20 rounded-xl text-white placeholder-[#8A8A8A] focus:outline-none focus:border-[#4A4A4A] transition-colors"
|
||||
className="w-full px-4 py-2 bg-[#070E1B] border border-[#525966]/20 rounded-xl text-white placeholder-onboarding focus:outline-none focus:border-[#4A4A4A] transition-colors"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ export function MemoriesStep({ onSubmit }: MemoriesStepProps) {
|
|||
placeholder="linkedin.com/in/yourname"
|
||||
value={linkedinProfile}
|
||||
onChange={(e) => setLinkedinProfile(e.target.value)}
|
||||
className="w-full px-4 py-2 bg-[#070E1B] border border-[#525966]/20 rounded-xl text-white placeholder-[#8A8A8A] focus:outline-none focus:border-[#4A4A4A] transition-colors"
|
||||
className="w-full px-4 py-2 bg-[#070E1B] border border-[#525966]/20 rounded-xl text-white placeholder-onboarding focus:outline-none focus:border-[#4A4A4A] transition-colors"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
@ -99,7 +99,7 @@ export function MemoriesStep({ onSubmit }: MemoriesStepProps) {
|
|||
{otherLinks.map((link, index) => (
|
||||
<div
|
||||
key={`other-link-${index}-${link.length}`}
|
||||
className="flex items-center space-x-2 mb-2"
|
||||
className="flex items-center mb-2 relative"
|
||||
>
|
||||
<input
|
||||
id={`other-links-${index}`}
|
||||
|
|
@ -107,13 +107,13 @@ export function MemoriesStep({ onSubmit }: MemoriesStepProps) {
|
|||
placeholder="Add your website, GitHub, Notion..."
|
||||
value={link}
|
||||
onChange={(e) => updateOtherLink(index, e.target.value)}
|
||||
className="flex-1 px-4 py-2 bg-[#070E1B] border border-[#525966]/20 rounded-xl text-white placeholder-[#8A8A8A] focus:outline-none focus:border-[#4A4A4A] transition-colors"
|
||||
className="flex-1 px-4 py-2 bg-[#070E1B] border border-[#525966]/20 rounded-xl text-white placeholder-onboarding focus:outline-none focus:border-[#4A4A4A] transition-colors"
|
||||
/>
|
||||
{index === otherLinks.length - 1 && otherLinks.length < 3 && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={addOtherLink}
|
||||
className="w-10 h-10 bg-[#070E1B] border border-[#525966]/20 rounded-xl flex items-center justify-center text-white hover:bg-[#2A2A2A] transition-colors"
|
||||
className="size-8 m-1 absolute right-0 top-0 bg-black border border-[#161F2C] rounded-lg flex items-center justify-center text-white hover:bg-[#161F2C] transition-colors text-xl"
|
||||
>
|
||||
+
|
||||
</button>
|
||||
|
|
@ -135,7 +135,7 @@ export function MemoriesStep({ onSubmit }: MemoriesStepProps) {
|
|||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
rows={4}
|
||||
className="w-full px-4 py-2 bg-[#070E1B] border border-[#525966]/20 rounded-xl text-white placeholder-[#8A8A8A] focus:outline-none focus:border-[#4A4A4A] transition-colors"
|
||||
className="w-full px-4 py-2 bg-[#070E1B] border border-[#525966]/20 rounded-xl text-white placeholder-onboarding focus:outline-none focus:border-[#4A4A4A] transition-colors min-h-[4rem]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,18 @@
|
|||
|
||||
import { useState, useEffect } from "react"
|
||||
import { Button } from "@ui/components/button"
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@ui/components/select"
|
||||
import { CircleCheckIcon, CopyIcon } from "lucide-react"
|
||||
import { toast } from "sonner"
|
||||
import { analytics } from "@/lib/analytics"
|
||||
import { cn } from "@lib/utils"
|
||||
import { dmSansClassName } from "@/utils/fonts"
|
||||
|
||||
const clients = {
|
||||
cursor: "Cursor",
|
||||
|
|
@ -65,42 +74,67 @@ export function MCPDetailView({ onBack }: MCPDetailViewProps) {
|
|||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="flex-1 flex flex-col items-center justify-start">
|
||||
<h1 className="text-white text-3xl font-medium mb-6 text-center">
|
||||
<div className="flex-1 flex flex-col items-start justify-start">
|
||||
<h1 className="text-white text-3xl font-medium mb-6 text-start">
|
||||
Connect your AI to supermemory MCP
|
||||
</h1>
|
||||
|
||||
<div className="mb-8 space-x-4 flex max-w-2xl">
|
||||
<div className="flex items-start space-x-3">
|
||||
<div className={cn("flex items-start space-x-3", dmSansClassName())}>
|
||||
<CircleCheckIcon className="size-10 text-green-500" />
|
||||
<p className="text-foreground/40 text-sm">
|
||||
<p className="text-white/40 text-sm">
|
||||
MCP connects your AI apps to create and use memories directly
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-start space-x-3">
|
||||
<div className={cn("flex items-start space-x-3", dmSansClassName())}>
|
||||
<CircleCheckIcon className="size-10 text-green-500" />
|
||||
<p className="text-foreground/40 text-sm">
|
||||
<p className="text-white/40 text-sm">
|
||||
Auto-fetch the right context from anything you've saved
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-start space-x-3">
|
||||
<div className={cn("flex items-start space-x-3", dmSansClassName())}>
|
||||
<CircleCheckIcon className="size-10 text-green-500" />
|
||||
<p className="text-foreground/40 text-sm">
|
||||
<p className="text-white/40 text-sm">
|
||||
One-time setup, seamless integration across your workflow
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="w-full max-w-2xl space-y-6">
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="bg-[#29395266] text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-medium flex-shrink-0">
|
||||
<div className="w-full max-w-2xl relative">
|
||||
<div className="absolute left-4 top-0 w-[1px] h-full bg-[#1E293B] z-10" />
|
||||
<div className="flex items-start space-x-4 z-20">
|
||||
<div className="bg-[#161F2B] text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-medium flex-shrink-0 z-20">
|
||||
1
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="text-white text-lg font-medium mb-4">
|
||||
Select your AI client
|
||||
</h3>
|
||||
<div className="flex flex-wrap gap-2 mb-4">
|
||||
<div className="flex-1 mb-4">
|
||||
<div className="flex gap-4 mb-4">
|
||||
<h3 className="text-white text-lg font-medium">
|
||||
Select your AI client
|
||||
</h3>
|
||||
{selectedClient && <Select
|
||||
onValueChange={(value) =>
|
||||
setSelectedClient(value as keyof typeof clients)
|
||||
}
|
||||
value={selectedClient || undefined}
|
||||
>
|
||||
<SelectTrigger className="max-w-md rounded-full border-[#242A33] text-white hover:border-gray-600 !bg-transparent">
|
||||
<SelectValue placeholder="Select a client" />
|
||||
</SelectTrigger>
|
||||
<SelectContent className="bg-black border-none">
|
||||
{Object.entries(clients).slice(0, 7).map(([key, clientName]) => (
|
||||
<SelectItem
|
||||
key={key}
|
||||
value={key}
|
||||
className="text-white hover:bg-[#080B0F]"
|
||||
>
|
||||
{clientName}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
}
|
||||
</div>
|
||||
<div className={cn("flex flex-wrap gap-2 mb-4", selectedClient ? "hidden" : "")}>
|
||||
{Object.entries(clients)
|
||||
.slice(0, 7)
|
||||
.map(([key, clientName]) => (
|
||||
|
|
@ -132,11 +166,11 @@ export function MCPDetailView({ onBack }: MCPDetailViewProps) {
|
|||
</div>
|
||||
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="bg-[#29395266] text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-medium flex-shrink-0">
|
||||
<div className="bg-[#161F2B] text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-medium flex-shrink-0 z-20">
|
||||
2
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<h3 className="text-white text-lg font-medium">
|
||||
<div className="flex-1 mb-4">
|
||||
<h3 className="text-white text-lg font-medium mb-4">
|
||||
Copy the installation command
|
||||
</h3>
|
||||
{selectedClient && (
|
||||
|
|
@ -257,7 +291,7 @@ export function MCPDetailView({ onBack }: MCPDetailViewProps) {
|
|||
<div className="space-y-3">
|
||||
<div className="relative">
|
||||
<input
|
||||
className="font-mono text-xs w-full pr-10 p-2 bg-black border border-gray-600 rounded text-green-400"
|
||||
className="font-mono text-xs w-full pr-10 p-2 bg-black border border-gray-600 rounded-lg text-green-400"
|
||||
readOnly
|
||||
value={generateInstallCommand()}
|
||||
/>
|
||||
|
|
@ -281,7 +315,7 @@ export function MCPDetailView({ onBack }: MCPDetailViewProps) {
|
|||
</div>
|
||||
|
||||
<div className="flex items-start space-x-4">
|
||||
<div className="bg-[#29395266] text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-medium flex-shrink-0">
|
||||
<div className="bg-[#161F2B] text-white rounded-full w-8 h-8 flex items-center justify-center text-sm font-medium flex-shrink-0 z-20">
|
||||
3
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
|
|
|
|||
|
|
@ -1,6 +1,14 @@
|
|||
@import "tailwindcss";
|
||||
@plugin "@tailwindcss/typography";
|
||||
|
||||
@theme {
|
||||
--color-onboarding: #525966;
|
||||
}
|
||||
|
||||
:root {
|
||||
--color-placeholder-onboarding: #525966;
|
||||
}
|
||||
|
||||
.sm-tweet-theme .react-tweet-theme {
|
||||
--tweet-container-margin: 0px;
|
||||
}
|
||||
|
|
@ -20,4 +28,10 @@
|
|||
|
||||
.scrollbar-thin::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
[class*="dmSans"],
|
||||
.font-dm-sans {
|
||||
letter-spacing: -0.01em;
|
||||
line-height: 135%;
|
||||
}
|
||||
BIN
apps/web/public/onboarding/mcp.png
Normal file
BIN
apps/web/public/onboarding/mcp.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
|
|
@ -1,13 +1,29 @@
|
|||
import { DM_Mono, DM_Sans } from "next/font/google"
|
||||
import { cn } from "@lib/utils"
|
||||
|
||||
// DM Sans font
|
||||
export const dmSansFont = DM_Sans({
|
||||
subsets: ["latin"],
|
||||
weight: ["400", "500", "700"],
|
||||
variable: "--font-dm-sans",
|
||||
})
|
||||
|
||||
// DM Mono font
|
||||
export const dmMonoFont = DM_Mono({
|
||||
subsets: ["latin"],
|
||||
weight: ["400"],
|
||||
variable: "--font-dm-mono",
|
||||
})
|
||||
|
||||
/**
|
||||
* Utility function that combines dmSansFont.className with required typography styles
|
||||
* (letter-spacing: -0.01em and line-height: 135%)
|
||||
*/
|
||||
export function dmSansClassName(additionalClasses?: string) {
|
||||
return cn(
|
||||
dmSansFont.className,
|
||||
"tracking-[-0.01em]",
|
||||
"leading-[135%]",
|
||||
additionalClasses,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ const buttonVariants = cva(
|
|||
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
settingsNav: "cursor-pointer rounded-sm bg-transparent",
|
||||
onboarding: "rounded-xl !px-6 !py-3 bg-black border border-[#161F2C] hover:bg-[#161F2C] !h-[40px] cursor-pointer text-white",
|
||||
},
|
||||
size: {
|
||||
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue