@@ -50,6 +50,11 @@ const FAQs: React.FC = () => {
50
50
setActiveIndex ( activeIndex === index ? null : index ) ;
51
51
} ;
52
52
53
+ // Split FAQs into two columns manually to prevent shifting
54
+ const midPoint = Math . ceil ( faqData . length / 2 ) ;
55
+ const leftColumnFAQs = faqData . slice ( 0 , midPoint ) ;
56
+ const rightColumnFAQs = faqData . slice ( midPoint ) ;
57
+
53
58
return (
54
59
< section
55
60
className = { `py-8 transition-colors duration-300 ${
@@ -79,67 +84,136 @@ const FAQs: React.FC = () => {
79
84
</ p >
80
85
</ div >
81
86
82
- { /* Accordion Masonry Columns to prevent sibling expansion */ }
83
- < div className = "columns-1 md:columns-2 md:gap-x-6" >
84
- { faqData . map ( ( faq , index ) => (
85
- < motion . div
86
- key = { index }
87
- className = "accordion h-fit border-gray-200 dark:border-gray-700 pb-4 mb-4 break-inside-avoid"
88
- initial = { { opacity : 0 , y : 10 } }
89
- animate = { { opacity : 1 , y : 0 } }
90
- transition = { { duration : 0.3 } }
91
- >
92
- < button
93
- className = { `accordion-toggle group flex justify-between items-center text-lg font-semibold w-full transition-all duration-300
94
- ${
95
- isDark
96
- ? "text-gray-100 bg-gray-800 hover:bg-gray-700 hover:text-white border border-gray-700 hover:border-gray-600"
97
- : "text-gray-900 bg-white hover:bg-gray-50 hover:text-gray-900 border border-gray-200 hover:border-gray-300 shadow-sm"
98
- }
99
- p-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2` }
100
- onClick = { ( ) => toggleAccordion ( index ) }
101
- >
102
- < span className = "text-left pr-4" > { faq . question } </ span >
103
- < motion . span
104
- className = { `transform transition-transform duration-300 flex-shrink-0 ${
105
- isDark ? "text-gray-300" : "text-gray-600"
106
- } `}
107
- animate = { { rotate : activeIndex === index ? 180 : 0 } }
108
- >
109
- < FiChevronDown size = { 22 } />
110
- </ motion . span >
111
- </ button >
87
+ { /* FAQ Manual Column Layout - Prevents vertical shifting */ }
88
+ < div className = "grid grid-cols-1 md:grid-cols-2 gap-6" >
89
+ { /* Left Column */ }
90
+ < div className = "space-y-4" >
91
+ { leftColumnFAQs . map ( ( faq , index ) => (
112
92
< motion . div
113
- className = "accordion-content overflow-hidden"
114
- initial = { { height : 0 , opacity : 0 } }
115
- animate = { {
116
- height : activeIndex === index ? "auto" : 0 ,
117
- opacity : activeIndex === index ? 1 : 0 ,
118
- } }
119
- transition = { { duration : 0.3 , ease : "easeInOut" } }
93
+ key = { index }
94
+ className = "accordion border-gray-200 dark:border-gray-700"
95
+ initial = { { opacity : 0 , y : 10 } }
96
+ animate = { { opacity : 1 , y : 0 } }
97
+ transition = { { duration : 0.3 } }
120
98
>
121
- < div
122
- className = { `mt-3 p-5 text-base leading-relaxed transition-colors duration-200 rounded-lg border-l-4 ${
123
- isDark
124
- ? "text-gray-100 bg-gradient-to-r from-gray-800/80 to-gray-900/60 border-l-indigo-400 shadow-lg"
125
- : "text-gray-900 bg-gradient-to-r from-white to-gray-50 border-l-indigo-500 shadow-md"
126
- } `}
127
- dangerouslySetInnerHTML = { {
128
- __html : faq . answer . replace (
129
- / < s t r o n g > / g,
130
- `<strong style="color: ${ isDark ? '#ffffff' : '#000000' } ; font-weight: 700; background: ${ isDark ? 'rgba(99, 102, 241, 0.2)' : 'rgba(199, 210, 254, 0.4)' } ; padding: 2px 6px; border-radius: 4px;">`
131
- ) . replace (
132
- / < a / g,
133
- `<a style="color: ${ isDark ? '#c4b5fd' : '#3730a3' } ; text-decoration: underline; font-weight: 600; transition: all 0.2s ease;" `
134
- ) . replace (
135
- / • / g,
136
- `<span style="color: ${ isDark ? '#818cf8' : '#4f46e5' } ; font-weight: bold;">•</span> `
137
- )
99
+ < button
100
+ className = { `accordion-toggle group flex justify-between items-center text-lg font-semibold w-full transition-all duration-300
101
+ ${
102
+ isDark
103
+ ? "text-gray-100 bg-gray-800 hover:bg-gray-700 hover:text-white border border-gray-700 hover:border-gray-600"
104
+ : "text-gray-900 bg-white hover:bg-gray-50 hover:text-gray-900 border border-gray-200 hover:border-gray-300 shadow-sm"
105
+ }
106
+ p-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2` }
107
+ onClick = { ( ) => toggleAccordion ( index ) }
108
+ >
109
+ < span className = "text-left pr-4" > { faq . question } </ span >
110
+ < motion . span
111
+ className = { `transform transition-transform duration-300 flex-shrink-0 ${
112
+ isDark ? "text-gray-300" : "text-gray-600"
113
+ } `}
114
+ animate = { { rotate : activeIndex === index ? 180 : 0 } }
115
+ >
116
+ < FiChevronDown size = { 22 } />
117
+ </ motion . span >
118
+ </ button >
119
+ < motion . div
120
+ className = "accordion-content overflow-hidden"
121
+ initial = { { height : 0 , opacity : 0 } }
122
+ animate = { {
123
+ height : activeIndex === index ? "auto" : 0 ,
124
+ opacity : activeIndex === index ? 1 : 0 ,
138
125
} }
139
- />
126
+ transition = { { duration : 0.3 , ease : "easeInOut" } }
127
+ >
128
+ < div
129
+ className = { `mt-3 p-5 text-base leading-relaxed transition-colors duration-200 rounded-lg border-l-4 ${
130
+ isDark
131
+ ? "text-gray-100 bg-gradient-to-r from-gray-800/80 to-gray-900/60 border-l-indigo-400 shadow-lg"
132
+ : "text-gray-900 bg-gradient-to-r from-white to-gray-50 border-l-indigo-500 shadow-md"
133
+ } `}
134
+ dangerouslySetInnerHTML = { {
135
+ __html : faq . answer . replace (
136
+ / < s t r o n g > / g,
137
+ `<strong style="color: ${ isDark ? '#ffffff' : '#000000' } ; font-weight: 700; background: ${ isDark ? 'rgba(99, 102, 241, 0.2)' : 'rgba(199, 210, 254, 0.4)' } ; padding: 2px 6px; border-radius: 4px;">`
138
+ ) . replace (
139
+ / < a / g,
140
+ `<a style="color: ${ isDark ? '#c4b5fd' : '#3730a3' } ; text-decoration: underline; font-weight: 600; transition: all 0.2s ease;" `
141
+ ) . replace (
142
+ / • / g,
143
+ `<span style="color: ${ isDark ? '#818cf8' : '#4f46e5' } ; font-weight: bold;">•</span> `
144
+ )
145
+ } }
146
+ />
147
+ </ motion . div >
140
148
</ motion . div >
141
- </ motion . div >
142
- ) ) }
149
+ ) ) }
150
+ </ div >
151
+
152
+ { /* Right Column */ }
153
+ < div className = "space-y-4" >
154
+ { rightColumnFAQs . map ( ( faq , index ) => {
155
+ const actualIndex = index + leftColumnFAQs . length ;
156
+ return (
157
+ < motion . div
158
+ key = { actualIndex }
159
+ className = "accordion border-gray-200 dark:border-gray-700"
160
+ initial = { { opacity : 0 , y : 10 } }
161
+ animate = { { opacity : 1 , y : 0 } }
162
+ transition = { { duration : 0.3 } }
163
+ >
164
+ < button
165
+ className = { `accordion-toggle group flex justify-between items-center text-lg font-semibold w-full transition-all duration-300
166
+ ${
167
+ isDark
168
+ ? "text-gray-100 bg-gray-800 hover:bg-gray-700 hover:text-white border border-gray-700 hover:border-gray-600"
169
+ : "text-gray-900 bg-white hover:bg-gray-50 hover:text-gray-900 border border-gray-200 hover:border-gray-300 shadow-sm"
170
+ }
171
+ p-4 rounded-lg focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2` }
172
+ onClick = { ( ) => toggleAccordion ( actualIndex ) }
173
+ >
174
+ < span className = "text-left pr-4" > { faq . question } </ span >
175
+ < motion . span
176
+ className = { `transform transition-transform duration-300 flex-shrink-0 ${
177
+ isDark ? "text-gray-300" : "text-gray-600"
178
+ } `}
179
+ animate = { { rotate : activeIndex === actualIndex ? 180 : 0 } }
180
+ >
181
+ < FiChevronDown size = { 22 } />
182
+ </ motion . span >
183
+ </ button >
184
+ < motion . div
185
+ className = "accordion-content overflow-hidden"
186
+ initial = { { height : 0 , opacity : 0 } }
187
+ animate = { {
188
+ height : activeIndex === actualIndex ? "auto" : 0 ,
189
+ opacity : activeIndex === actualIndex ? 1 : 0 ,
190
+ } }
191
+ transition = { { duration : 0.3 , ease : "easeInOut" } }
192
+ >
193
+ < div
194
+ className = { `mt-3 p-5 text-base leading-relaxed transition-colors duration-200 rounded-lg border-l-4 ${
195
+ isDark
196
+ ? "text-gray-100 bg-gradient-to-r from-gray-800/80 to-gray-900/60 border-l-indigo-400 shadow-lg"
197
+ : "text-gray-900 bg-gradient-to-r from-white to-gray-50 border-l-indigo-500 shadow-md"
198
+ } `}
199
+ dangerouslySetInnerHTML = { {
200
+ __html : faq . answer . replace (
201
+ / < s t r o n g > / g,
202
+ `<strong style="color: ${ isDark ? '#ffffff' : '#000000' } ; font-weight: 700; background: ${ isDark ? 'rgba(99, 102, 241, 0.2)' : 'rgba(199, 210, 254, 0.4)' } ; padding: 2px 6px; border-radius: 4px;">`
203
+ ) . replace (
204
+ / < a / g,
205
+ `<a style="color: ${ isDark ? '#c4b5fd' : '#3730a3' } ; text-decoration: underline; font-weight: 600; transition: all 0.2s ease;" `
206
+ ) . replace (
207
+ / • / g,
208
+ `<span style="color: ${ isDark ? '#818cf8' : '#4f46e5' } ; font-weight: bold;">•</span> `
209
+ )
210
+ } }
211
+ />
212
+ </ motion . div >
213
+ </ motion . div >
214
+ ) ;
215
+ } ) }
216
+ </ div >
143
217
</ div >
144
218
</ div >
145
219
</ div >
0 commit comments