@@ -34,7 +34,7 @@ function FacetSection({
3434 if ( values . length === 0 ) return null ;
3535
3636 return (
37- < section className = "rounded-2xl border border-slate-200 bg-slate-50/85 p-4 shadow-sm " >
37+ < section className = "rounded-[24px] border border-white/80 bg-white/88 p-4 shadow-[0_16px_40px_rgba(14,165,233,0.08)] " >
3838 < button
3939 type = "button"
4040 className = "tb-focus-ring flex w-full items-center justify-between gap-3 rounded-lg text-left"
@@ -74,22 +74,22 @@ export function GalleryClient({
7474 const [ query , setQuery ] = useState < string > ( "" ) ;
7575 const [ selected , setSelected ] = useState < SelectedFacets > ( ( ) => emptySelectedFacets ( ) ) ;
7676 const [ activeRepo , setActiveRepo ] = useState < string | null > ( null ) ;
77- const [ openFacets , setOpenFacets ] = useState < { maturity : boolean ; paradigm : boolean } > ( {
77+ const [ openFacets , setOpenFacets ] = useState < {
78+ maturity : boolean ;
79+ preview : boolean ;
80+ paradigm : boolean ;
81+ } > ( {
7882 maturity : true ,
83+ preview : true ,
7984 paradigm : true
8085 } ) ;
8186
8287 const deferredQuery = useDeferredValue ( query ) ;
8388 const allMaturities = useMemo ( ( ) => facetValues ( tasks , "maturity" ) , [ tasks ] ) ;
89+ const allPreviewValues = useMemo ( ( ) => facetValues ( tasks , "preview" ) , [ tasks ] ) ;
8490 const allParadigms = useMemo ( ( ) => facetValues ( tasks , "paradigm" ) , [ tasks ] ) ;
8591 const previewCount = useMemo ( ( ) => tasks . filter ( ( task ) => task . web_variant ) . length , [ tasks ] ) ;
86- const paradigmCount = useMemo (
87- ( ) =>
88- new Set (
89- tasks . flatMap ( ( task ) => task . tags ?. paradigm ?? [ ] ) . map ( ( value ) => value . toLowerCase ( ) )
90- ) . size ,
91- [ tasks ]
92- ) ;
92+ const voiceCount = useMemo ( ( ) => tasks . filter ( ( task ) => task . has_voiceover ) . length , [ tasks ] ) ;
9393 const filtered = useMemo (
9494 ( ) => filterTasks ( tasks , deferredQuery , selected ) ,
9595 [ deferredQuery , selected , tasks ]
@@ -102,6 +102,7 @@ export function GalleryClient({
102102 const anyFilters =
103103 query . trim ( ) . length > 0 ||
104104 selected . maturity . size > 0 ||
105+ selected . preview . size > 0 ||
105106 selected . paradigm . size > 0 ||
106107 selected . response . size > 0 ||
107108 selected . modality . size > 0 ||
@@ -111,6 +112,7 @@ export function GalleryClient({
111112 setSelected ( ( current ) => {
112113 const next : SelectedFacets = {
113114 maturity : new Set ( current . maturity ) ,
115+ preview : new Set ( current . preview ) ,
114116 paradigm : new Set ( current . paradigm ) ,
115117 response : new Set ( current . response ) ,
116118 modality : new Set ( current . modality ) ,
@@ -129,23 +131,23 @@ export function GalleryClient({
129131
130132 return (
131133 < section className = "space-y-6" >
132- < div className = "rounded-[32px ] border border-slate-200 bg-white/90 p-5 shadow-sm " >
134+ < div className = "rounded-[36px ] border border-white/80 bg-white/84 p-5 shadow-[0_20px_60px_rgba(14,165,233,0.12)] " >
133135 < div className = "flex flex-col gap-6" >
134136 < div className = "flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between" >
135137 < div >
136- < div className = "text-[11px] font-semibold uppercase tracking-[0.18em] text-slate-500 " >
138+ < div className = "text-[11px] font-semibold uppercase tracking-[0.18em] text-brand-800 " >
137139 Tasks
138140 </ div >
139141 < div className = "mt-2 font-heading text-3xl font-semibold tracking-tight text-slate-900" >
140142 Browse canonical local tasks and aligned previews.
141143 </ div >
142144 < div className = "mt-2 max-w-3xl text-sm leading-6 text-slate-700" >
143- This page keeps the denser explorer layout: filter from the left, scan the list on
144- the right, and open README-backed details only when needed .
145+ Filter from the left, scan a cleaner alphabetical list on the right, and expand
146+ README-backed details only when you need deeper context .
145147 </ div >
146148 </ div >
147149
148- < div className = "rounded-2xl border border-slate-200 bg-slate-50/85 px-4 py-3 text-sm text-slate-700 shadow-sm" >
150+ < div className = "rounded-[24px] border border-white/80 bg-[linear-gradient(135deg,rgba(255,255,255,0.94),rgba(236,254,255,0.88),rgba(255,247,237,0.86))] px-4 py-3 text-sm text-slate-700 shadow-sm" >
149151 Index updated{ " " }
150152 < span className = "font-semibold text-slate-900" >
151153 { formatIsoDateTime ( generatedAt ) }
@@ -154,36 +156,36 @@ export function GalleryClient({
154156 </ div >
155157
156158 < div className = "grid gap-3 md:grid-cols-2 xl:grid-cols-4" >
157- < div className = "rounded-2xl border border-slate-200 bg-slate-50/85 p-4 shadow-sm" >
159+ < div className = "rounded-[24px] border border-brand-100 bg-white/90 p-4 shadow-sm" >
158160 < div className = "text-[11px] font-semibold uppercase tracking-wide text-slate-500" >
159161 Total tasks
160162 </ div >
161163 < div className = "mt-2 font-heading text-2xl font-semibold text-slate-900" >
162164 { tasks . length }
163165 </ div >
164166 </ div >
165- < div className = "rounded-2xl border border-slate-200 bg-slate-50/85 p-4 shadow-sm" >
167+ < div className = "rounded-[24px] border border-brand-100 bg-white/90 p-4 shadow-sm" >
166168 < div className = "text-[11px] font-semibold uppercase tracking-wide text-slate-500" >
167169 Matching now
168170 </ div >
169171 < div className = "mt-2 font-heading text-2xl font-semibold text-slate-900" >
170172 { filtered . length }
171173 </ div >
172174 </ div >
173- < div className = "rounded-2xl border border-slate-200 bg-slate-50/85 p-4 shadow-sm" >
175+ < div className = "rounded-[24px] border border-brand-100 bg-white/90 p-4 shadow-sm" >
174176 < div className = "text-[11px] font-semibold uppercase tracking-wide text-slate-500" >
175177 Previews
176178 </ div >
177179 < div className = "mt-2 font-heading text-2xl font-semibold text-slate-900" >
178180 { previewCount }
179181 </ div >
180182 </ div >
181- < div className = "rounded-2xl border border-slate-200 bg-slate-50/85 p-4 shadow-sm" >
183+ < div className = "rounded-[24px] border border-brand-100 bg-white/90 p-4 shadow-sm" >
182184 < div className = "text-[11px] font-semibold uppercase tracking-wide text-slate-500" >
183- Paradigms
185+ Voice-ready
184186 </ div >
185187 < div className = "mt-2 font-heading text-2xl font-semibold text-slate-900" >
186- { paradigmCount }
188+ { voiceCount }
187189 </ div >
188190 </ div >
189191 </ div >
@@ -193,7 +195,7 @@ export function GalleryClient({
193195 < div className = "grid grid-cols-1 gap-6 lg:grid-cols-12" >
194196 < aside className = "lg:col-span-4 xl:col-span-3" >
195197 < div className = "sticky top-24 space-y-4" >
196- < section className = "rounded-2xl border border-slate-200 bg-white/90 p-4 shadow-sm " >
198+ < section className = "rounded-[24px] border border-white/80 bg-white/90 p-4 shadow-[0_16px_40px_rgba(14,165,233,0.08)] " >
197199 < label className = "block" htmlFor = "task-explorer-search" >
198200 < span className = "text-xs font-semibold uppercase tracking-wide text-slate-600" >
199201 Search
@@ -203,7 +205,7 @@ export function GalleryClient({
203205 value = { query }
204206 onChange = { ( event ) => setQuery ( event . target . value ) }
205207 placeholder = "e.g. stroop, T000012, H000006, EEG"
206- className = "tb-focus-ring mt-2 w-full rounded-2xl border border-slate-200 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-400"
208+ className = "tb-focus-ring mt-2 w-full rounded-2xl border border-brand-100 bg-white px-4 py-3 text-sm text-slate-900 placeholder:text-slate-400"
207209 />
208210 </ label >
209211
@@ -215,7 +217,7 @@ export function GalleryClient({
215217 { anyFilters ? (
216218 < button
217219 type = "button"
218- className = "tb-focus-ring rounded-lg border border-slate-200 bg-white px-3 py-2 text-sm font-semibold text-slate-800 shadow-sm hover:border-brand-200 hover:bg-brand-50"
220+ className = "tb-focus-ring rounded-2xl border border-brand-100 bg-white px-3 py-2 text-sm font-semibold text-slate-800 shadow-sm hover:border-brand-200 hover:bg-brand-50"
219221 onClick = { clearAll }
220222 >
221223 Clear
@@ -236,7 +238,18 @@ export function GalleryClient({
236238 }
237239 />
238240 < FacetSection
239- title = "Paradigm"
241+ title = "Preview"
242+ facet = "preview"
243+ values = { allPreviewValues }
244+ selected = { selected }
245+ onToggle = { toggleFacet }
246+ isOpen = { openFacets . preview }
247+ onToggleOpen = { ( ) =>
248+ setOpenFacets ( ( current ) => ( { ...current , preview : ! current . preview } ) )
249+ }
250+ />
251+ < FacetSection
252+ title = "Paradigm / Task Type"
240253 facet = "paradigm"
241254 values = { allParadigms }
242255 selected = { selected }
@@ -251,17 +264,17 @@ export function GalleryClient({
251264
252265 < section className = "space-y-3 lg:col-span-8 xl:col-span-9" >
253266 { filtered . length === 0 ? (
254- < div className = "rounded-[32px] border border-slate-200 bg-white/90 p-10 text-center shadow-sm " >
267+ < div className = "rounded-[32px] border border-white/80 bg-white/90 p-10 text-center shadow-[0_18px_44px_rgba(14,165,233,0.08)] " >
255268 < div className = "font-heading text-lg font-semibold tracking-tight text-slate-900" >
256269 No matches
257270 </ div >
258271 < div className = "mt-2 text-sm text-slate-700" >
259- Try clearing filters or searching by paradigm name, repo handle, or task ID.
272+ Try clearing filters or searching by task name, repo handle, or task ID.
260273 </ div >
261274 < div className = "mt-5" >
262275 < button
263276 type = "button"
264- className = "tb-focus-ring rounded-lg bg-cta-500 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-cta-600 "
277+ className = "tb-focus-ring rounded-2xl bg-gradient-to-r from- cta-500 to-cta-600 px-4 py-2 text-sm font-semibold text-white shadow-[0_12px_24px_rgba(245,158,11,0.24)] hover:-translate-y-0.5 "
265278 onClick = { clearAll }
266279 >
267280 Reset explorer
0 commit comments