@@ -96,131 +96,100 @@ export function Hero() {
9696 Jump in with a ready-made stack template, explore the full wizard, or drop a GitHub repo for an automatic scan.
9797 </ motion . p >
9898
99- < motion . ul
100- className = "mx-auto flex max-w-3xl flex-col items-start gap-2 text-left text-sm text-muted-foreground md:flex-row md:flex-wrap md:justify-center"
101- variants = { itemVariants }
102- >
103- { featureHighlights . map ( ( feature ) => (
104- < motion . li
105- key = { feature }
106- className = "inline-flex items-center gap-2 rounded-full border border-border/60 bg-background/70 px-4 py-2 text-sm text-foreground shadow-sm backdrop-blur md:text-base"
107- variants = { itemVariants }
108- >
109- < CheckCircle2 className = "size-4 text-primary" />
110- { feature }
111- </ motion . li >
112- ) ) }
113- </ motion . ul >
99+
114100
115101 < motion . div
116- className = "mx-auto w-full max-w-4xl space-y-8 text-left"
102+ className = "mx-auto w-full max-w-4xl text-left"
117103 variants = { itemVariants }
118104 >
119- < div className = "flex flex-col gap-4 " >
120- < div className = "flex flex-wrap items-center justify-between gap-3 " >
105+ < div className = "flex flex-col gap-6 lg:flex-row lg:items-start " >
106+ < div className = "flex-1 space-y-4 " >
121107 < h2 className = "text-lg font-semibold uppercase tracking-wide text-muted-foreground" >
122108 Start fast with popular stacks
123109 </ h2 >
124- < Button variant = "outline" size = "sm" onClick = { handleMoreStacks } >
125- More stacks
126- < ArrowRight className = "ml-2 h-4 w-4" />
127- </ Button >
128- </ div >
129- < div className = "grid gap-3 md:grid-cols-3" >
130- { popularStacks . map ( ( stack ) => {
131- const descriptor = getIconDescriptor ( stack . icon ?? stack . value )
132- const iconHex = descriptor ? iconColorOverrides [ descriptor . slug ] ?? descriptor . hex : undefined
133- const iconColor = iconHex ? getAccessibleIconColor ( iconHex ) : undefined
134- const iconBackground = iconColor ? hexToRgba ( iconColor , 0.18 ) ?? undefined : undefined
135- const iconRing = iconColor ? hexToRgba ( iconColor , 0.32 ) ?? undefined : undefined
136- const initials = getFallbackInitials ( stack . label )
137-
138- return (
139- < button
140- key = { stack . value }
141- type = "button"
142- onClick = { ( ) => handleStackClick ( stack . value ) }
143- className = "group flex h-full flex-col gap-4 rounded-3xl border border-border/70 bg-background/90 px-5 py-6 text-left shadow-sm transition-all hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60"
144- >
145- < span
146- className = "flex h-10 w-10 items-center justify-center rounded-xl ring-1 ring-border/40"
147- style = { {
148- color : iconColor ,
149- backgroundColor : iconBackground ,
150- boxShadow : iconRing ? `inset 0 0 0 1px ${ iconRing } ` : undefined ,
151- } }
152- aria-hidden
110+ < div className = "flex flex-wrap gap-3" >
111+ { popularStacks . map ( ( stack ) => {
112+ const descriptor = getIconDescriptor ( stack . icon ?? stack . value )
113+ const iconHex = descriptor ? iconColorOverrides [ descriptor . slug ] ?? descriptor . hex : undefined
114+ const iconColor = iconHex ? getAccessibleIconColor ( iconHex ) : undefined
115+ const iconBackground = iconColor ? hexToRgba ( iconColor , 0.18 ) ?? undefined : undefined
116+ const iconRing = iconColor ? hexToRgba ( iconColor , 0.32 ) ?? undefined : undefined
117+ const initials = getFallbackInitials ( stack . label )
118+
119+ return (
120+ < button
121+ key = { stack . value }
122+ type = "button"
123+ onClick = { ( ) => handleStackClick ( stack . value ) }
124+ className = "group inline-flex items-center gap-3 rounded-full border border-border/70 bg-background/90 px-4 py-2 text-sm font-medium text-foreground shadow-sm transition hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60"
153125 >
154- { descriptor ? (
155- < span
156- className = "inline-flex h-6 w-6 items-center justify-center [&>svg]:h-full [&>svg]:w-full"
157- style = { { color : iconColor ?? "inherit" } }
158- dangerouslySetInnerHTML = { { __html : descriptor . markup } }
159- />
160- ) : (
161- < span className = "text-sm font-semibold uppercase tracking-wide text-muted-foreground" >
162- { initials }
163- </ span >
164- ) }
165- </ span >
166- < div className = "space-y-2" >
167- < div className = "flex items-center justify-between gap-3" >
168- < p className = "text-base font-semibold text-foreground" > { stack . label } </ p >
169- < ArrowRight className = "h-4 w-4 text-muted-foreground transition group-hover:text-primary" />
170- </ div >
171- { stack . tags && stack . tags . length > 0 ? (
172- < div className = "flex flex-wrap gap-1 text-[10px] uppercase tracking-wide text-muted-foreground/70" >
173- { stack . tags . slice ( 0 , 3 ) . map ( ( tag ) => (
174- < span key = { tag } className = "rounded-full bg-muted/70 px-2 py-0.5" >
175- { tag }
176- </ span >
177- ) ) }
178- </ div >
179- ) : null }
180- < p className = "text-sm text-muted-foreground" >
181- Auto-fill recommended defaults and jump straight to the summary.
182- </ p >
183- </ div >
184- </ button >
185- )
186- } ) }
126+ < span
127+ className = "flex h-8 w-8 items-center justify-center rounded-full ring-1 ring-border/40"
128+ style = { {
129+ color : iconColor ,
130+ backgroundColor : iconBackground ,
131+ boxShadow : iconRing ? `inset 0 0 0 1px ${ iconRing } ` : undefined ,
132+ } }
133+ aria-hidden
134+ >
135+ { descriptor ? (
136+ < span
137+ className = "inline-flex h-5 w-5 items-center justify-center [&>svg]:h-full [&>svg]:w-full"
138+ style = { { color : iconColor ?? "inherit" } }
139+ dangerouslySetInnerHTML = { { __html : descriptor . markup } }
140+ />
141+ ) : (
142+ < span className = "text-xs font-semibold uppercase tracking-wide text-muted-foreground" >
143+ { initials }
144+ </ span >
145+ ) }
146+ </ span >
147+ < span className = "flex items-center gap-2" >
148+ { stack . label }
149+ < ArrowRight className = "h-3.5 w-3.5 text-muted-foreground transition group-hover:text-primary" />
150+ </ span >
151+ </ button >
152+ )
153+ } ) }
154+
155+ < button
156+ type = "button"
157+ onClick = { handleMoreStacks }
158+ className = "inline-flex items-center gap-2 rounded-full border border-border/70 bg-background/80 px-4 py-2 text-sm font-semibold text-foreground shadow-sm transition hover:-translate-y-0.5 hover:border-primary/40 hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60"
159+ >
160+ More stacks
161+ < ArrowRight className = "h-3.5 w-3.5" />
162+ </ button >
163+ </ div >
187164 </ div >
188- </ div >
189165
190- < div className = "flex items-center gap-4" >
191- < div className = "h-px flex-1 bg-border/60" />
192- < span className = "text-xs font-semibold uppercase tracking-[0.3em] text-muted-foreground" >
193- or
194- </ span >
195- < div className = "h-px flex-1 bg-border/60" />
166+ < form
167+ onSubmit = { handleGithubSubmit }
168+ className = "flex flex-1 flex-col gap-3 rounded-3xl border border-border/70 bg-background/95 p-6 shadow-sm"
169+ >
170+ < div className = "space-y-2 text-left" >
171+ < p className = "text-sm font-semibold uppercase tracking-wide text-muted-foreground" >
172+ Scan a GitHub repository
173+ </ p >
174+ < p className = "text-sm text-muted-foreground" >
175+ Paste an owner/repo or URL and we'll prefill the wizard with detected tech and tooling.
176+ </ p >
177+ </ div >
178+ < div className = "flex w-full flex-col gap-2 sm:flex-row" >
179+ < input
180+ type = "text"
181+ value = { githubRepo }
182+ onChange = { ( event ) => setGithubRepo ( event . target . value ) }
183+ placeholder = "github.com/owner/repo"
184+ className = "w-full rounded-xl border border-border/70 bg-background px-4 py-2 text-sm text-foreground shadow-sm transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60 sm:min-w-[260px]"
185+ />
186+ < Button type = "submit" size = "sm" className = "gap-2" >
187+ Scan repo
188+ < Github className = "h-4 w-4" />
189+ </ Button >
190+ </ div >
191+ </ form >
196192 </ div >
197-
198- < form
199- onSubmit = { handleGithubSubmit }
200- className = "flex flex-col gap-3 rounded-3xl border border-border/70 bg-background/95 p-6 shadow-sm sm:flex-row sm:items-center"
201- >
202- < div className = "flex-1 space-y-2 text-left" >
203- < p className = "text-sm font-semibold uppercase tracking-wide text-muted-foreground" >
204- Scan a GitHub repository
205- </ p >
206- < p className = "text-sm text-muted-foreground" >
207- Paste an owner/repo or URL and we'll prefill the wizard with detected tech and tooling.
208- </ p >
209- </ div >
210- < div className = "flex w-full flex-col gap-2 sm:w-auto sm:flex-row" >
211- < input
212- type = "text"
213- value = { githubRepo }
214- onChange = { ( event ) => setGithubRepo ( event . target . value ) }
215- placeholder = "github.com/owner/repo"
216- className = "w-full rounded-xl border border-border/70 bg-background px-4 py-2 text-sm text-foreground shadow-sm transition focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/60 sm:min-w-[260px]"
217- />
218- < Button type = "submit" size = "sm" className = "gap-2" >
219- Scan repo
220- < Github className = "h-4 w-4" />
221- </ Button >
222- </ div >
223- </ form >
224193 </ motion . div >
225194 </ motion . div >
226195 </ motion . section >
0 commit comments