11import * as React from 'react'
22import { LinkProps } from '@tanstack/react-router'
33import type { Library } from '~/libraries'
4- import { useIsDark } from '~/hooks/useIsDark'
54import { ChatPanel } from './ChatPanel'
65import { AnimationPhase } from '~/stores/aiLibraryHeroAnimation'
76import { useAILibraryHeroAnimation } from '~/hooks/useAILibraryHeroAnimation'
@@ -51,11 +50,13 @@ type AILibraryHeroProps = {
5150 actions ?: React . ReactNode
5251}
5352
54- export function AILibraryHero ( { } : AILibraryHeroProps ) {
55- const isDark = useIsDark ( )
56- const strokeColor = isDark ? 'rgba(255, 255, 255, 0.8)' : 'rgba(0, 0, 0, 0.6)'
57- const textColor = isDark ? '#ffffff' : '#000000'
53+ const HIGHLIGHT_COLOR = 'rgba(255, 255, 240, 0.95)'
5854
55+ export function AILibraryHero ( { } : AILibraryHeroProps ) {
56+ const strokeColor = 'var(--hero-stroke)'
57+ const textColor = 'var(--hero-text)'
58+ const glassGradientStart = 'var(--hero-glass-start)'
59+ const glassGradientEnd = 'var(--hero-glass-end)'
5960 // Use the animation hook - handles all animation state and orchestration
6061 const { store } = useAILibraryHeroAnimation ( )
6162
@@ -145,8 +146,7 @@ export function AILibraryHero({}: AILibraryHeroProps) {
145146 // Active path: selected framework -> client -> ai -> selected server
146147 // Only return off-white if we're in a highlighting phase AND this is the active path
147148 if ( isFrameworkSelected && isServerSelected ) {
148- // Off-white color when active
149- return isDark ? 'rgba(255, 255, 240, 0.95)' : 'rgba(255, 255, 240, 0.95)'
149+ return HIGHLIGHT_COLOR
150150 }
151151
152152 // Not the active path, return original color
@@ -180,6 +180,18 @@ export function AILibraryHero({}: AILibraryHeroProps) {
180180 < style
181181 dangerouslySetInnerHTML = { {
182182 __html : `
183+ :root {
184+ --hero-stroke: rgba(0, 0, 0, 0.6);
185+ --hero-text: #000000;
186+ --hero-glass-start: rgba(255, 255, 255, 0.8);
187+ --hero-glass-end: rgba(255, 255, 255, 0.6);
188+ }
189+ :root.dark {
190+ --hero-stroke: rgba(255, 255, 255, 0.8);
191+ --hero-text: #ffffff;
192+ --hero-glass-start: rgba(255, 255, 255, 0.55);
193+ --hero-glass-end: rgba(255, 255, 255, 0.55);
194+ }
183195 @keyframes pulse-down {
184196 0% {
185197 opacity: 0.6;
@@ -221,12 +233,12 @@ export function AILibraryHero({}: AILibraryHeroProps) {
221233 />
222234 < div className = "relative flex flex-col items-center gap-8 text-center px-4 overflow-visible" >
223235 { /* Diagram and Chat Panel Container */ }
224- < div
225- className = "relative z-10 w-full max-w-7xl mx-auto flex flex-row flex-wrap gap-8 lg:gap-12"
226- style = { { height : SVG_HEIGHT } }
227- >
236+ < div className = "relative z-10 w-full max-w-7xl mx-auto flex flex-col lg:flex-row items-center lg:items-stretch gap-8 lg:gap-12" >
228237 { /* SVG Diagram */ }
229- < div className = "relative w-full lg:flex-1 overflow-visible h-full" >
238+ < div
239+ className = "relative w-full lg:flex-1 overflow-visible"
240+ style = { { height : SVG_HEIGHT } }
241+ >
230242 < svg
231243 key = { `${ phase } -${ selectedFramework } -${ selectedServer } ` }
232244 xmlns = "http://www.w3.org/2000/svg"
@@ -285,20 +297,12 @@ export function AILibraryHero({}: AILibraryHeroProps) {
285297 >
286298 < stop
287299 offset = "0%"
288- stopColor = {
289- isDark
290- ? 'rgba(255, 255, 255, 0.55)'
291- : 'rgba(255, 255, 255, 0.8)'
292- }
300+ stopColor = { glassGradientStart }
293301 stopOpacity = "1"
294302 />
295303 < stop
296304 offset = "100%"
297- stopColor = {
298- isDark
299- ? 'rgba(255, 255, 255, 0.55)'
300- : 'rgba(255, 255, 255, 0.6)'
301- }
305+ stopColor = { glassGradientEnd }
302306 stopOpacity = "1"
303307 />
304308 </ linearGradient >
@@ -313,20 +317,12 @@ export function AILibraryHero({}: AILibraryHeroProps) {
313317 >
314318 < stop
315319 offset = "0%"
316- stopColor = {
317- isDark
318- ? 'rgba(255, 255, 255, 0.55)'
319- : 'rgba(255, 255, 255, 0.75)'
320- }
320+ stopColor = { glassGradientStart }
321321 stopOpacity = "1"
322322 />
323323 < stop
324324 offset = "100%"
325- stopColor = {
326- isDark
327- ? 'rgba(255, 255, 255, 0.55)'
328- : 'rgba(255, 255, 255, 0.55)'
329- }
325+ stopColor = { glassGradientEnd }
330326 stopOpacity = "1"
331327 />
332328 </ linearGradient >
@@ -613,9 +609,7 @@ export function AILibraryHero({}: AILibraryHeroProps) {
613609 phase === AnimationPhase . SHOWING_CHAT ||
614610 phase === AnimationPhase . PULSING_CONNECTIONS ||
615611 phase === AnimationPhase . STREAMING_RESPONSE
616- ? isDark
617- ? 'rgba(255, 255, 240, 0.95)'
618- : 'rgba(255, 255, 240, 0.95)'
612+ ? HIGHLIGHT_COLOR
619613 : strokeColor
620614 }
621615 strokeWidth = {
@@ -826,7 +820,10 @@ export function AILibraryHero({}: AILibraryHeroProps) {
826820 </ div >
827821
828822 { /* Chat Panel */ }
829- < div className = "w-full md:w-[400px] flex-shrink-0 h-full" >
823+ < div
824+ className = "w-full max-w-[400px] lg:w-[400px] flex-shrink-0"
825+ style = { { height : SVG_HEIGHT } }
826+ >
830827 < ChatPanel
831828 messages = { messages }
832829 typingUserMessage = { typingUserMessage }
0 commit comments