@@ -43,29 +43,31 @@ function CardContentPreview({ card, iconColor, onImageClick }: Readonly<CardCont
4343 // Image card preview
4444 if ( cardType === 'image' && card . imageData ) {
4545 return (
46- < button
47- type = "button"
48- className = "relative mb-3 rounded-xl overflow-hidden group-hover:ring-2 ring-(--accent-primary) transition-all cursor-zoom-in w-full"
49- onClick = { onImageClick }
50- title = "Click to view full-screen"
51- aria-label = "View image full-screen"
52- >
53- < img
54- src = { card . imageData . trim ( ) }
55- alt = { card . title }
56- className = "w-full h-auto max-h-64 object-cover"
57- onError = { ( e ) => {
58- // Hide broken data URIs to avoid noisy console errors
59- e . currentTarget . style . display = 'none' ;
60- } }
61- />
62- < div className = "absolute inset-0 bg-linear-to-t from-black/40 to-transparent opacity-0 group-hover:opacity-100 transition-opacity" />
63- < div className = "absolute bottom-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity" >
46+ < div className = "relative mb-3 rounded-xl overflow-hidden group-hover:ring-2 ring-(--accent-primary) transition-all w-full" >
47+ < button
48+ type = "button"
49+ className = "w-full cursor-zoom-in bg-transparent border-0 p-0 relative z-10"
50+ onClick = { onImageClick }
51+ title = "Click to view full-screen"
52+ aria-label = "View image full-screen"
53+ >
54+ < img
55+ src = { card . imageData . trim ( ) }
56+ alt = { card . title }
57+ className = "w-full h-auto max-h-64 object-cover"
58+ onError = { ( e ) => {
59+ // Hide broken data URIs to avoid noisy console errors
60+ e . currentTarget . style . display = 'none' ;
61+ } }
62+ />
63+ </ button >
64+ < div className = "absolute inset-0 bg-linear-to-t from-black/40 to-transparent opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" />
65+ < div className = "absolute bottom-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" >
6466 < span className = "text-xs px-2 py-1 rounded-full glass glass--dense text-white" >
6567 Click to zoom
6668 </ span >
6769 </ div >
68- </ button >
70+ </ div >
6971 ) ;
7072 }
7173
@@ -89,8 +91,9 @@ function CardContentPreview({ card, iconColor, onImageClick }: Readonly<CardCont
8991 downloadFile ( card . fileData , card . fileName ) ;
9092 }
9193 } }
92- className = "p-2 rounded-lg hover:bg-hover transition-colors shrink-0"
94+ className = "p-2 rounded-lg hover:bg-hover transition-colors shrink-0 z-10 relative "
9395 title = "Download file"
96+ aria-label = "Download file"
9497 >
9598 < ArrowDownTrayIcon className = "w-4 h-4" style = { { color : iconColor } } />
9699 </ button >
@@ -157,28 +160,35 @@ export function Card({ card, onClick, onStarToggle, className }: Readonly<CardPr
157160
158161 return (
159162 < >
160- < button
161- type = "button"
162- onClick = { handleCardClick }
163+ < div
163164 className = { cn (
164- 'group relative glass glass--dense rounded-2xl p-4 transition-all duration-200 w-full text-left ' ,
165+ 'group relative glass glass--dense rounded-2xl p-4 transition-all duration-200 w-full' ,
165166 'hover:-translate-y-1 hover:shadow-[0_28px_70px_color-mix(in_srgb,var(--accent-primary)_18%,transparent)]' ,
166- 'cursor-pointer border border-transparent' ,
167+ 'border border-transparent' ,
167168 className
168169 ) }
169170 >
171+ { /* Clickable backdrop button - covers the card for click handling */ }
172+ < button
173+ type = "button"
174+ onClick = { handleCardClick }
175+ className = "absolute inset-0 w-full h-full rounded-2xl cursor-pointer bg-transparent border-0 z-0 focus:outline-none focus:ring-2 focus:ring-(--accent-primary) focus:ring-offset-2 focus:ring-offset-(--glass-bg)"
176+ aria-label = { `Open ${ card . title } ` }
177+ />
178+
170179 { /* Card Header */ }
171- < div className = "flex items-start justify-between gap-3 mb-2" >
180+ < div className = "flex items-start justify-between gap-3 mb-2 relative z-10 pointer-events-none " >
172181 < div className = "flex items-center gap-2 flex-1 min-w-0" >
173182 < Icon className = "w-5 h-5 shrink-0" style = { { color : iconColor } } />
174183 < h3 className = "font-semibold text-(--text-strong) truncate group-hover:text-accent transition-colors" >
175184 { card . title }
176185 </ h3 >
177186 </ div >
178187
179- < div className = "flex items-center gap-1.5 shrink-0" >
188+ < div className = "flex items-center gap-1.5 shrink-0 pointer-events-auto " >
180189 { /* Star Button */ }
181190 < button
191+ type = "button"
182192 onClick = { handleStarClick }
183193 disabled = { isStarring }
184194 className = { cn (
@@ -198,7 +208,7 @@ export function Card({ card, onClick, onStarToggle, className }: Readonly<CardPr
198208 </ button >
199209
200210 { /* Card Type Badge */ }
201- < span className = "text-xs px-2 py-1 rounded-full border capitalize"
211+ < span className = "text-xs px-2 py-1 rounded-full border capitalize pointer-events-none "
202212 style = { {
203213 borderColor : 'color-mix(in srgb, var(--accent-border) 60%, transparent)' ,
204214 background : 'color-mix(in srgb, var(--accent-primary) 10%, transparent)' ,
@@ -212,21 +222,23 @@ export function Card({ card, onClick, onStarToggle, className }: Readonly<CardPr
212222
213223 { /* Card Description */ }
214224 { card . description && (
215- < p className = "text-sm text-(--text-soft) mb-3 line-clamp-2" >
225+ < p className = "text-sm text-(--text-soft) mb-3 line-clamp-2 relative z-10 pointer-events-none " >
216226 { card . description }
217227 </ p >
218228 ) }
219229
220230 { /* Card Content Preview */ }
221- < CardContentPreview
222- card = { card }
223- iconColor = { iconColor }
224- onImageClick = { handleImageClick }
225- />
231+ < div className = "relative z-10" >
232+ < CardContentPreview
233+ card = { card }
234+ iconColor = { iconColor }
235+ onImageClick = { handleImageClick }
236+ />
237+ </ div >
226238
227239 { /* Tags */ }
228240 { card . tags && card . tags . length > 0 && (
229- < div className = "flex flex-wrap gap-1.5" >
241+ < div className = "flex flex-wrap gap-1.5 relative z-10 pointer-events-none " >
230242 { card . tags . map ( ( tag ) => (
231243 < span
232244 key = { tag . id }
@@ -247,7 +259,7 @@ export function Card({ card, onClick, onStarToggle, className }: Readonly<CardPr
247259 < div className = "absolute inset-0 rounded-2xl opacity-0 group-hover:opacity-100 transition-opacity pointer-events-none" >
248260 < div className = "absolute inset-0 rounded-2xl bg-[radial-gradient(circle_at_top,var(--accent-soft),transparent_65%)]" />
249261 </ div >
250- </ button >
262+ </ div >
251263
252264 { /* Lightbox for image cards */ }
253265 { card . cardType [ 0 ] === 'image' && card . imageData && (
0 commit comments