@@ -59,95 +59,118 @@ useSeoMeta({
5959 </script >
6060
6161<template >
62- <main class =" container py-8 xl:py-12" >
63- <header class =" mb-8" >
64- <h1 class =" font-mono text-2xl sm:text-3xl font-medium mb-2" >
65- {{ $t('compare.packages.title') }}
66- </h1 >
67- <p class =" text-fg-muted" >
68- {{ $t('compare.packages.tagline') }}
69- </p >
70- </header >
71-
72- <!-- Package selector -->
73- <section class =" mb-8" aria-labelledby =" packages-heading" >
74- <h2 id =" packages-heading" class =" text-xs text-fg-subtle uppercase tracking-wider mb-3" >
75- {{ $t('compare.packages.section_packages') }}
76- </h2 >
77- <ComparePackageSelector v-model =" packages" :max =" 4" />
78- </section >
79-
80- <!-- Facet selector -->
81- <section class =" mb-8" aria-labelledby =" facets-heading" >
82- <div class =" flex items-center gap-2 mb-3" >
83- <h2 id =" facets-heading" class =" text-xs text-fg-subtle uppercase tracking-wider" >
84- {{ $t('compare.packages.section_facets') }}
62+ <main class =" container flex-1 py-12 sm:py-16 w-full" >
63+ <div class =" max-w-2xl mx-auto" >
64+ <header class =" mb-12" >
65+ <h1 class =" font-mono text-3xl sm:text-4xl font-medium mb-4" >
66+ {{ $t('compare.packages.title') }}
67+ </h1 >
68+ <p class =" text-fg-muted text-lg" >
69+ {{ $t('compare.packages.tagline') }}
70+ </p >
71+ </header >
72+
73+ <!-- Package selector -->
74+ <section class =" mb-8" aria-labelledby =" packages-heading" >
75+ <h2 id =" packages-heading" class =" text-xs text-fg-subtle uppercase tracking-wider mb-3" >
76+ {{ $t('compare.packages.section_packages') }}
8577 </h2 >
86- <button
87- type =" button"
88- class =" text-[10px] transition-colors focus-visible:outline-none focus-visible:underline"
89- :class =" isAllSelected ? 'text-fg-muted' : 'text-fg-muted/60 hover:text-fg-muted'"
90- :disabled =" isAllSelected"
91- :aria-label =" $t('compare.facets.select_all')"
92- @click =" selectAll"
93- >
94- {{ $t('compare.facets.all') }}
95- </button >
96- <span class =" text-[10px] text-fg-muted/40" aria-hidden =" true" >/</span >
97- <button
98- type =" button"
99- class =" text-[10px] transition-colors focus-visible:outline-none focus-visible:underline"
100- :class =" isNoneSelected ? 'text-fg-muted' : 'text-fg-muted/60 hover:text-fg-muted'"
101- :disabled =" isNoneSelected"
102- :aria-label =" $t('compare.facets.deselect_all')"
103- @click =" deselectAll"
78+ <ComparePackageSelector v-model =" packages" :max =" 4" />
79+ </section >
80+
81+ <!-- Facet selector -->
82+ <section class =" mb-8" aria-labelledby =" facets-heading" >
83+ <div class =" flex items-center gap-2 mb-3" >
84+ <h2 id =" facets-heading" class =" text-xs text-fg-subtle uppercase tracking-wider" >
85+ {{ $t('compare.packages.section_facets') }}
86+ </h2 >
87+ <button
88+ type =" button"
89+ class =" text-[10px] transition-colors focus-visible:outline-none focus-visible:underline"
90+ :class =" isAllSelected ? 'text-fg-muted' : 'text-fg-muted/60 hover:text-fg-muted'"
91+ :disabled =" isAllSelected"
92+ :aria-label =" $t('compare.facets.select_all')"
93+ @click =" selectAll"
94+ >
95+ {{ $t('compare.facets.all') }}
96+ </button >
97+ <span class =" text-[10px] text-fg-muted/40" aria-hidden =" true" >/</span >
98+ <button
99+ type =" button"
100+ class =" text-[10px] transition-colors focus-visible:outline-none focus-visible:underline"
101+ :class =" isNoneSelected ? 'text-fg-muted' : 'text-fg-muted/60 hover:text-fg-muted'"
102+ :disabled =" isNoneSelected"
103+ :aria-label =" $t('compare.facets.deselect_all')"
104+ @click =" deselectAll"
105+ >
106+ {{ $t('compare.facets.none') }}
107+ </button >
108+ </div >
109+ <CompareFacetSelector />
110+ </section >
111+
112+ <!-- Comparison grid -->
113+ <section v-if =" canCompare" class =" mt-10" aria-labelledby =" comparison-heading" >
114+ <h2 id =" comparison-heading" class =" text-xs text-fg-subtle uppercase tracking-wider mb-4" >
115+ {{ $t('compare.packages.section_comparison') }}
116+ </h2 >
117+
118+ <div
119+ v-if =" status === 'pending' && (!packagesData || packagesData.every(p => p === null))"
120+ class =" flex items-center justify-center py-12"
104121 >
105- {{ $t('compare.facets.none') }}
106- </button >
107- </div >
108- <CompareFacetSelector />
109- </section >
110-
111- <!-- Comparison grid -->
112- <section v-if =" canCompare" class =" mt-10" aria-labelledby =" comparison-heading" >
113- <h2 id =" comparison-heading" class =" text-xs text-fg-subtle uppercase tracking-wider mb-4" >
114- {{ $t('compare.packages.section_comparison') }}
115- </h2 >
116-
117- <div
118- v-if =" status === 'pending' && (!packagesData || packagesData.every(p => p === null))"
119- class =" flex items-center justify-center py-12"
120- >
121- <LoadingSpinner :text =" $t('compare.packages.loading')" />
122- </div >
123-
124- <div v-else-if =" packagesData && packagesData.some(p => p !== null)" >
125- <CompareComparisonGrid :columns =" packages.length" :headers =" gridHeaders" >
126- <CompareFacetRow
127- v-for =" facet in selectedFacets"
128- :key =" facet"
129- :label =" FACET_INFO[facet].label"
130- :description =" FACET_INFO[facet].description"
131- :values =" getFacetValues(facet)"
132- :facet-loading =" isFacetLoading(facet)"
133- :column-loading =" columnLoading"
134- :bar =" facet !== 'lastUpdated'"
135- />
136- </CompareComparisonGrid >
137- </div >
138-
139- <div v-else class =" text-center py-12" role =" alert" >
140- <p class =" text-fg-muted" >{{ $t('compare.packages.error') }}</p >
141- </div >
142- </section >
143-
144- <!-- Empty state -->
145- <section v-else class =" text-center py-16 border border-dashed border-border rounded-lg" >
146- <div class =" i-carbon:compare w-12 h-12 text-fg-subtle mx-auto mb-4" aria-hidden =" true" />
147- <h2 class =" font-mono text-lg text-fg-muted mb-2" >{{ $t('compare.packages.empty_title') }}</h2 >
148- <p class =" text-sm text-fg-subtle max-w-md mx-auto" >
149- {{ $t('compare.packages.empty_description') }}
150- </p >
151- </section >
122+ <LoadingSpinner :text =" $t('compare.packages.loading')" />
123+ </div >
124+
125+ <div v-else-if =" packagesData && packagesData.some(p => p !== null)" >
126+ <!-- Desktop: Grid layout -->
127+ <div class =" hidden md:block overflow-x-auto" >
128+ <CompareComparisonGrid :columns =" packages.length" :headers =" gridHeaders" >
129+ <CompareFacetRow
130+ v-for =" facet in selectedFacets"
131+ :key =" facet"
132+ :label =" FACET_INFO[facet].label"
133+ :description =" FACET_INFO[facet].description"
134+ :values =" getFacetValues(facet)"
135+ :facet-loading =" isFacetLoading(facet)"
136+ :column-loading =" columnLoading"
137+ :bar =" facet !== 'lastUpdated'"
138+ :headers =" gridHeaders"
139+ />
140+ </CompareComparisonGrid >
141+ </div >
142+
143+ <!-- Mobile: Card-based layout -->
144+ <div class =" md:hidden space-y-3" >
145+ <CompareFacetCard
146+ v-for =" facet in selectedFacets"
147+ :key =" facet"
148+ :label =" FACET_INFO[facet].label"
149+ :description =" FACET_INFO[facet].description"
150+ :values =" getFacetValues(facet)"
151+ :facet-loading =" isFacetLoading(facet)"
152+ :column-loading =" columnLoading"
153+ :bar =" facet !== 'lastUpdated'"
154+ :headers =" gridHeaders"
155+ />
156+ </div >
157+ </div >
158+
159+ <div v-else class =" text-center py-12" role =" alert" >
160+ <p class =" text-fg-muted" >{{ $t('compare.packages.error') }}</p >
161+ </div >
162+ </section >
163+
164+ <!-- Empty state -->
165+ <section v-else class =" text-center py-16 border border-dashed border-border rounded-lg" >
166+ <div class =" i-carbon:compare w-12 h-12 text-fg-subtle mx-auto mb-4" aria-hidden =" true" />
167+ <h2 class =" font-mono text-lg text-fg-muted mb-2" >
168+ {{ $t('compare.packages.empty_title') }}
169+ </h2 >
170+ <p class =" text-sm text-fg-subtle max-w-md mx-auto" >
171+ {{ $t('compare.packages.empty_description') }}
172+ </p >
173+ </section >
174+ </div >
152175 </main >
153176</template >
0 commit comments