astro-component-kit 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/README.md +133 -36
  2. package/package.json +17 -4
  3. package/src/components/index.ts +18 -202
  4. package/src/components/lib/Galaxy3D.astro +249 -137
  5. package/src/components/lib/app/AppSidebar.astro +249 -0
  6. package/src/components/lib/app/AppTopbar.astro +284 -0
  7. package/src/components/lib/app/ArrivalsBoard.astro +176 -0
  8. package/src/components/lib/app/AuthCard.astro +213 -0
  9. package/src/components/lib/app/DataTable.astro +346 -0
  10. package/src/components/lib/app/GuestProfileCard.astro +133 -0
  11. package/src/components/lib/app/HousekeepingBoard.astro +189 -0
  12. package/src/components/lib/app/PageHeader.astro +157 -0
  13. package/src/components/lib/app/PlanUsageCard.astro +112 -0
  14. package/src/components/lib/app/RoomRack.astro +207 -0
  15. package/src/components/lib/app/SettingsSection.astro +96 -0
  16. package/src/components/lib/app/SwitchRow.astro +71 -0
  17. package/src/components/lib/app/TeamMembers.astro +190 -0
  18. package/src/components/lib/app/app-icons.ts +52 -0
  19. package/src/components/lib/app/index.ts +19 -0
  20. package/src/components/lib/buttons/NeonBorderButton.astro +162 -0
  21. package/src/components/lib/buttons/RippleButton.astro +199 -0
  22. package/src/components/lib/buttons/SlideRevealButton.astro +159 -0
  23. package/src/components/lib/buttons/index.ts +4 -0
  24. package/src/components/lib/cards/GithubRepoCard.astro +176 -0
  25. package/src/components/lib/cards/PricingCompareMiniCard.astro +196 -0
  26. package/src/components/lib/cards/StatsTrendCard.astro +149 -0
  27. package/src/components/lib/cards/index.ts +3 -0
  28. package/src/components/lib/charts/ActivityRings.astro +105 -0
  29. package/src/components/lib/charts/AreaChart.astro +4 -4
  30. package/src/components/lib/charts/BarChart.astro +3 -3
  31. package/src/components/lib/charts/BoxPlotChart.astro +109 -0
  32. package/src/components/lib/charts/BubbleChart.astro +101 -0
  33. package/src/components/lib/charts/BulletChart.astro +160 -0
  34. package/src/components/lib/charts/BumpChart.astro +92 -0
  35. package/src/components/lib/charts/CandlestickChart.astro +105 -0
  36. package/src/components/lib/charts/ChartFrame.astro +373 -0
  37. package/src/components/lib/charts/DivergingBarChart.astro +98 -0
  38. package/src/components/lib/charts/DonutChart.astro +2 -2
  39. package/src/components/lib/charts/DumbbellChart.astro +92 -0
  40. package/src/components/lib/charts/ForecastLineChart.astro +125 -0
  41. package/src/components/lib/charts/FunnelChart.astro +122 -0
  42. package/src/components/lib/charts/GaugeChart.astro +111 -0
  43. package/src/components/lib/charts/GoalProgressChart.astro +97 -0
  44. package/src/components/lib/charts/GroupedBarChart.astro +125 -0
  45. package/src/components/lib/charts/HeatmapChart.astro +131 -0
  46. package/src/components/lib/charts/HistogramChart.astro +111 -0
  47. package/src/components/lib/charts/HorizontalBarChart.astro +155 -0
  48. package/src/components/lib/charts/KpiStatTile.astro +116 -0
  49. package/src/components/lib/charts/KpiTrendGrid.astro +60 -0
  50. package/src/components/lib/charts/LineChart.astro +160 -0
  51. package/src/components/lib/charts/LinearProgressGauge.astro +136 -0
  52. package/src/components/lib/charts/LollipopChart.astro +100 -0
  53. package/src/components/lib/charts/MeterGauge.astro +122 -0
  54. package/src/components/lib/charts/MetricDeltaTable.astro +125 -0
  55. package/src/components/lib/charts/PieChart.astro +135 -0
  56. package/src/components/lib/charts/PolarAreaChart.astro +85 -0
  57. package/src/components/lib/charts/PopulationPyramid.astro +122 -0
  58. package/src/components/lib/charts/PunchCardChart.astro +89 -0
  59. package/src/components/lib/charts/RadarChart.astro +94 -0
  60. package/src/components/lib/charts/RadarMetricChart.astro +168 -0
  61. package/src/components/lib/charts/RadialBarChart.astro +124 -0
  62. package/src/components/lib/charts/RangeAreaChart.astro +113 -0
  63. package/src/components/lib/charts/RetentionCohortTable.astro +126 -0
  64. package/src/components/lib/charts/SankeyChart.astro +128 -0
  65. package/src/components/lib/charts/ScatterPlot.astro +139 -0
  66. package/src/components/lib/charts/SegmentedBarChart.astro +119 -0
  67. package/src/components/lib/charts/SlopeChart.astro +105 -0
  68. package/src/components/lib/charts/SparklineChart.astro +87 -0
  69. package/src/components/lib/charts/StackedAreaChart.astro +130 -0
  70. package/src/components/lib/charts/StackedBarChart.astro +136 -0
  71. package/src/components/lib/charts/SunburstChart.astro +103 -0
  72. package/src/components/lib/charts/TreemapChart.astro +94 -0
  73. package/src/components/lib/charts/WaffleChart.astro +121 -0
  74. package/src/components/lib/charts/WaterfallChart.astro +118 -0
  75. package/src/components/lib/charts/chart-tooltip.ts +75 -0
  76. package/src/components/lib/charts/chart-utils.ts +271 -0
  77. package/src/components/lib/charts/index.ts +46 -0
  78. package/src/components/lib/data/ActivityHeatmapGrid.astro +157 -0
  79. package/src/components/lib/data/MetricComparisonRow.astro +109 -0
  80. package/src/components/lib/data/StatusTimelineFeed.astro +168 -0
  81. package/src/components/lib/data/index.ts +3 -0
  82. package/src/components/lib/ecommerce/CartDrawer.astro +483 -0
  83. package/src/components/lib/ecommerce/CartPageList.astro +290 -0
  84. package/src/components/lib/ecommerce/CartToast.astro +276 -0
  85. package/src/components/lib/ecommerce/CategoryTiles.astro +143 -0
  86. package/src/components/lib/ecommerce/CheckoutForm.astro +423 -0
  87. package/src/components/lib/ecommerce/CountdownBanner.astro +230 -0
  88. package/src/components/lib/ecommerce/FilterBar.astro +278 -0
  89. package/src/components/lib/ecommerce/FilterSidebar.astro +405 -0
  90. package/src/components/lib/ecommerce/LiveActivityToast.astro +213 -0
  91. package/src/components/lib/ecommerce/OrderSummary.astro +295 -0
  92. package/src/components/lib/ecommerce/ProductBuyBox.astro +247 -0
  93. package/src/components/lib/ecommerce/ProductCardMinimal.astro +229 -0
  94. package/src/components/lib/ecommerce/ProductGallery.astro +145 -0
  95. package/src/components/lib/ecommerce/ProductGrid.astro +118 -0
  96. package/src/components/lib/ecommerce/ProductMedia.astro +113 -0
  97. package/src/components/lib/ecommerce/ProductRating.astro +78 -0
  98. package/src/components/lib/ecommerce/ProductToolbar.astro +93 -0
  99. package/src/components/lib/ecommerce/PromoBar.astro +145 -0
  100. package/src/components/lib/ecommerce/StockIndicator.astro +127 -0
  101. package/src/components/lib/ecommerce/StoreHeader.astro +446 -0
  102. package/src/components/lib/ecommerce/StoreHero.astro +260 -0
  103. package/src/components/lib/ecommerce/StoreProductCard.astro +307 -0
  104. package/src/components/lib/ecommerce/TrustBadges.astro +101 -0
  105. package/src/components/lib/ecommerce/VariantPicker.astro +145 -0
  106. package/src/components/lib/ecommerce/cart-store.ts +151 -0
  107. package/src/components/lib/ecommerce/catalog-filter.ts +62 -0
  108. package/src/components/lib/ecommerce/index.ts +34 -0
  109. package/src/components/lib/ecommerce/product-icons.ts +28 -0
  110. package/src/components/lib/ecommerce/types.ts +70 -0
  111. package/src/components/lib/feedback/ProgressRingCounter.astro +118 -0
  112. package/src/components/lib/feedback/ToastNotificationGroup.astro +173 -0
  113. package/src/components/lib/feedback/index.ts +2 -0
  114. package/src/components/lib/forms/AnimatedInput.astro +4 -2
  115. package/src/components/lib/forms/CustomRadioGroup.astro +3 -1
  116. package/src/components/lib/forms/GlassInlineToggleGroup.astro +161 -0
  117. package/src/components/lib/forms/PasswordStrengthInput.astro +242 -0
  118. package/src/components/lib/forms/PhoneCountryInput.astro +145 -0
  119. package/src/components/lib/forms/TagsAutocompleteInput.astro +249 -0
  120. package/src/components/lib/forms/index.ts +5 -0
  121. package/src/components/lib/index.ts +2 -0
  122. package/src/components/lib/layout/BentoGrid3.astro +6 -4
  123. package/src/components/lib/layout/CenterFixedBox.astro +2 -2
  124. package/src/components/lib/layout/CenteredContainer.astro +4 -2
  125. package/src/components/lib/layout/ClusterHorizontal.astro +2 -2
  126. package/src/components/lib/layout/DiagonalSectionDivider.astro +69 -0
  127. package/src/components/lib/layout/FeatureHero.astro +4 -2
  128. package/src/components/lib/layout/FooterCenteredMinimal.astro +4 -2
  129. package/src/components/lib/layout/FullBleedSection.astro +2 -2
  130. package/src/components/lib/layout/GalleryGrid4.astro +2 -2
  131. package/src/components/lib/layout/HolyGrailGrid.astro +127 -0
  132. package/src/components/lib/layout/LandingSectionSplit.astro +5 -3
  133. package/src/components/lib/layout/MasonryGrid.astro +2 -2
  134. package/src/components/lib/layout/MinimalFooterGrid.astro +1 -1
  135. package/src/components/lib/layout/ScrollSnapSection.astro +1 -1
  136. package/src/components/lib/layout/SidebarLayoutWrapper.astro +4 -2
  137. package/src/components/lib/layout/SplitScreenLayout.astro +3 -3
  138. package/src/components/lib/layout/StepLayoutVertical.astro +1 -1
  139. package/src/components/lib/layout/StickySidebarWrapper.astro +4 -2
  140. package/src/components/lib/layout/index.ts +3 -1
  141. package/src/components/lib/navigation/QuickJumpDock.astro +125 -0
  142. package/src/components/lib/navigation/StepBreadcrumbBar.astro +151 -0
  143. package/src/components/lib/navigation/SubNavbarPills.astro +102 -0
  144. package/src/components/lib/navigation/index.ts +3 -0
  145. package/src/components/lib/overlays/CookiePreferencesDrawer.astro +226 -0
  146. package/src/components/lib/overlays/FloatingFeedbackWidget.astro +203 -0
  147. package/src/components/lib/overlays/ImageCompareSlider.astro +172 -0
  148. package/src/components/lib/overlays/index.ts +3 -0
  149. package/src/components/lib/sections/AgencyContactBrief.astro +194 -0
  150. package/src/components/lib/sections/AgencyFooterCta.astro +94 -0
  151. package/src/components/lib/sections/AgencyHeader.astro +161 -0
  152. package/src/components/lib/sections/AgencyHeroKinetic.astro +172 -0
  153. package/src/components/lib/sections/AgencyServicesList.astro +113 -0
  154. package/src/components/lib/sections/AgencyTeamGrid.astro +111 -0
  155. package/src/components/lib/sections/AgencyWorkGrid.astro +147 -0
  156. package/src/components/lib/sections/BlogGridSection.astro +133 -0
  157. package/src/components/lib/sections/ButtonsShowcase.astro +20 -18
  158. package/src/components/lib/sections/CardsShowcase.astro +28 -26
  159. package/src/components/lib/sections/CareersOpenings.astro +141 -0
  160. package/src/components/lib/sections/ChangelogSection.astro +151 -0
  161. package/src/components/lib/sections/ContactGlassForm.astro +10 -8
  162. package/src/components/lib/sections/ContactSplitMap.astro +141 -0
  163. package/src/components/lib/sections/CtaAppDownload.astro +13 -11
  164. package/src/components/lib/sections/CtaGlowBanner.astro +12 -10
  165. package/src/components/lib/sections/CtaNewsletterSection.astro +165 -0
  166. package/src/components/lib/sections/CtaSplitImage.astro +149 -0
  167. package/src/components/lib/sections/DataShowcase.astro +23 -21
  168. package/src/components/lib/sections/FaqAccordionSection.astro +8 -8
  169. package/src/components/lib/sections/FaqTwoColumn.astro +121 -0
  170. package/src/components/lib/sections/FeatureAlternatingRows.astro +192 -0
  171. package/src/components/lib/sections/FeatureBentoGrid.astro +13 -11
  172. package/src/components/lib/sections/FeatureIconGrid.astro +155 -0
  173. package/src/components/lib/sections/FeatureTabsShowcase.astro +182 -0
  174. package/src/components/lib/sections/FeatureTimelineFlow.astro +8 -6
  175. package/src/components/lib/sections/FeedbackShowcase.astro +15 -13
  176. package/src/components/lib/sections/FooterMegaSection.astro +157 -0
  177. package/src/components/lib/sections/FormsShowcase.astro +22 -20
  178. package/src/components/lib/sections/HeroDashboardPreview.astro +182 -0
  179. package/src/components/lib/sections/HeroGlass.astro +22 -20
  180. package/src/components/lib/sections/HeroGradient.astro +15 -13
  181. package/src/components/lib/sections/HeroMinimalCentered.astro +175 -0
  182. package/src/components/lib/sections/HeroShowcaseSplit.astro +306 -0
  183. package/src/components/lib/sections/HeroSplit.astro +13 -11
  184. package/src/components/lib/sections/HeroTerminal.astro +253 -0
  185. package/src/components/lib/sections/HeroWaitlist.astro +231 -0
  186. package/src/components/lib/sections/HowItWorksSteps.astro +180 -0
  187. package/src/components/lib/sections/IntegrationsGrid.astro +167 -0
  188. package/src/components/lib/sections/LayoutShowcase.astro +21 -19
  189. package/src/components/lib/sections/LogoCloudSection.astro +96 -0
  190. package/src/components/lib/sections/LogoWallGrid.astro +93 -0
  191. package/src/components/lib/sections/NavigationShowcase.astro +15 -13
  192. package/src/components/lib/sections/OverlaysShowcase.astro +21 -19
  193. package/src/components/lib/sections/PricingComparisonMatrix.astro +15 -13
  194. package/src/components/lib/sections/PricingSinglePlan.astro +159 -0
  195. package/src/components/lib/sections/PricingTierCards.astro +11 -9
  196. package/src/components/lib/sections/PricingToggleCards.astro +171 -0
  197. package/src/components/lib/sections/ShopCategoryHero.astro +103 -0
  198. package/src/components/lib/sections/ShopCollectionMosaic.astro +131 -0
  199. package/src/components/lib/sections/ShopFooterWordmark.astro +100 -0
  200. package/src/components/lib/sections/ShopHeaderEditorial.astro +396 -0
  201. package/src/components/lib/sections/ShopHeroEditorial.astro +151 -0
  202. package/src/components/lib/sections/ShopLookbook.astro +250 -0
  203. package/src/components/lib/sections/ShopNewsletterEditorial.astro +128 -0
  204. package/src/components/lib/sections/ShopProductRail.astro +150 -0
  205. package/src/components/lib/sections/ShopReviewsEditorial.astro +133 -0
  206. package/src/components/lib/sections/ShopValuesMarquee.astro +91 -0
  207. package/src/components/lib/sections/StatsCounterBand.astro +124 -0
  208. package/src/components/lib/sections/StatsDashboardSection.astro +85 -0
  209. package/src/components/lib/sections/StatsMetricShowcase.astro +9 -7
  210. package/src/components/lib/sections/TeamGridSection.astro +12 -10
  211. package/src/components/lib/sections/TestimonialCarousel.astro +167 -0
  212. package/src/components/lib/sections/TestimonialFeatured.astro +122 -0
  213. package/src/components/lib/sections/TestimonialGridSection.astro +188 -0
  214. package/src/components/lib/sections/TestimonialWallGlass.astro +11 -9
  215. package/src/components/lib/sections/TypographyShowcase.astro +10 -8
  216. package/src/components/lib/sections/index.ts +39 -0
  217. package/src/components/lib/templates/ecommerce/StoreCategoryPage.astro +160 -0
  218. package/src/components/lib/templates/ecommerce/StoreCheckoutPage.astro +98 -0
  219. package/src/components/lib/templates/ecommerce/StoreHomePage.astro +191 -0
  220. package/src/components/lib/templates/ecommerce/StoreLayout.astro +169 -0
  221. package/src/components/lib/templates/ecommerce/StoreProductPage.astro +165 -0
  222. package/src/components/lib/templates/ecommerce/data.ts +187 -0
  223. package/src/components/lib/templates/ecommerce/index.ts +14 -0
  224. package/src/components/lib/templates/ecommerce-editorial/EditorialBagPage.astro +52 -0
  225. package/src/components/lib/templates/ecommerce-editorial/EditorialCheckoutPage.astro +123 -0
  226. package/src/components/lib/templates/ecommerce-editorial/EditorialHomePage.astro +102 -0
  227. package/src/components/lib/templates/ecommerce-editorial/EditorialLayout.astro +216 -0
  228. package/src/components/lib/templates/ecommerce-editorial/EditorialProductPage.astro +205 -0
  229. package/src/components/lib/templates/ecommerce-editorial/EditorialShopPage.astro +112 -0
  230. package/src/components/lib/templates/ecommerce-editorial/data.ts +125 -0
  231. package/src/components/lib/templates/ecommerce-editorial/index.ts +16 -0
  232. package/src/components/lib/templates/saas-hotel/AppLayout.astro +83 -0
  233. package/src/components/lib/templates/saas-hotel/DashboardPage.astro +66 -0
  234. package/src/components/lib/templates/saas-hotel/GuestsPage.astro +65 -0
  235. package/src/components/lib/templates/saas-hotel/LandingPage.astro +213 -0
  236. package/src/components/lib/templates/saas-hotel/ReportsPage.astro +63 -0
  237. package/src/components/lib/templates/saas-hotel/ReservationsPage.astro +49 -0
  238. package/src/components/lib/templates/saas-hotel/RoomsPage.astro +48 -0
  239. package/src/components/lib/templates/saas-hotel/SettingsPage.astro +115 -0
  240. package/src/components/lib/templates/saas-hotel/SignInPage.astro +50 -0
  241. package/src/components/lib/templates/saas-hotel/data.ts +229 -0
  242. package/src/components/lib/templates/saas-hotel/index.ts +19 -0
  243. package/src/components/lib/templates/saas-hotel/lobby-theme.css +90 -0
  244. package/src/components/lib/typography/AnimatedCounterText.astro +102 -0
  245. package/src/components/lib/typography/CurvedPathHeading.astro +86 -0
  246. package/src/components/lib/typography/GradientTextMarquee.astro +105 -0
  247. package/src/components/lib/typography/HackerDecodeText.astro +85 -0
  248. package/src/components/lib/typography/index.ts +4 -0
  249. package/src/styles/global.css +113 -1
@@ -0,0 +1,226 @@
1
+ ---
2
+ /**
3
+ * CookiePreferencesDrawer — GDPR/CCPA consent drawer with frosted glass styling and category toggles.
4
+ *
5
+ * @param {string} title - Header text. Default is 'Privacy Preferences'.
6
+ * @param {string} description - Explanation text for user privacy consent.
7
+ */
8
+ interface Props {
9
+ title?: string;
10
+ description?: string;
11
+ }
12
+
13
+ const {
14
+ title = 'Privacy & Cookie Settings',
15
+ description = 'We use cookies and telemetry to improve performance, analyze usage, and customize your experience.',
16
+ } = Astro.props;
17
+
18
+ const categories = [
19
+ { id: 'necessary', name: 'Strictly Necessary', desc: 'Required for core authentication and security.', locked: true },
20
+ { id: 'analytics', name: 'Performance & Analytics', desc: 'Anonymous traffic data to improve component reliability.', locked: false },
21
+ { id: 'marketing', name: 'Targeted Experience', desc: 'Personalized recommendations based on library interactions.', locked: false },
22
+ ];
23
+ ---
24
+
25
+ <aside class="cookie-drawer" role="dialog" aria-modal="true" aria-label={title} data-cookie-drawer>
26
+ <div class="cookie-drawer__header">
27
+ <div class="cookie-drawer__icon">🍪</div>
28
+ <div class="cookie-drawer__titles">
29
+ <h4 class="cookie-drawer__title">{title}</h4>
30
+ <p class="cookie-drawer__desc">{description}</p>
31
+ </div>
32
+ </div>
33
+
34
+ <div class="cookie-drawer__categories">
35
+ {categories.map((cat) => (
36
+ <div class="cookie-cat">
37
+ <div class="cookie-cat__info">
38
+ <span class="cookie-cat__name">{cat.name}</span>
39
+ <span class="cookie-cat__desc">{cat.desc}</span>
40
+ </div>
41
+ <label class="switch">
42
+ <input
43
+ type="checkbox"
44
+ checked={cat.locked}
45
+ disabled={cat.locked}
46
+ name={cat.id}
47
+ />
48
+ <span class="slider"></span>
49
+ </label>
50
+ </div>
51
+ ))}
52
+ </div>
53
+
54
+ <div class="cookie-drawer__actions">
55
+ <button type="button" class="btn btn--secondary" data-cookie-reject>Reject All</button>
56
+ <button type="button" class="btn btn--primary" data-cookie-accept>Accept Selected</button>
57
+ </div>
58
+ </aside>
59
+
60
+ <style>
61
+ .cookie-drawer {
62
+ position: fixed;
63
+ bottom: 1.5rem;
64
+ left: 1.5rem;
65
+ right: 1.5rem;
66
+ max-width: 520px;
67
+ z-index: 100;
68
+ margin: 0 auto;
69
+ padding: 1.4rem;
70
+ background: rgba(12, 12, 16, 0.94);
71
+ backdrop-filter: blur(24px);
72
+ border: 1px solid rgba(255, 255, 255, 0.12);
73
+ border-radius: var(--r-xl, 24px);
74
+ box-shadow: 0 24px 64px rgba(0, 0, 0, 0.7);
75
+ font-family: var(--font-sans, system-ui, sans-serif);
76
+ transition: transform 0.3s ease, opacity 0.3s ease;
77
+ }
78
+
79
+ .cookie-drawer__header {
80
+ display: flex;
81
+ gap: 12px;
82
+ margin-bottom: 16px;
83
+ }
84
+
85
+ .cookie-drawer__icon {
86
+ font-size: 1.8rem;
87
+ line-height: 1;
88
+ }
89
+
90
+ .cookie-drawer__title {
91
+ font-size: 1rem;
92
+ font-weight: 800;
93
+ color: var(--c-text-1, #ffffff);
94
+ margin: 0 0 4px 0;
95
+ }
96
+
97
+ .cookie-drawer__desc {
98
+ font-size: 0.8rem;
99
+ color: var(--c-text-2, #a3a3a3);
100
+ margin: 0;
101
+ line-height: 1.45;
102
+ }
103
+
104
+ .cookie-drawer__categories {
105
+ display: flex;
106
+ flex-direction: column;
107
+ gap: 10px;
108
+ margin-bottom: 18px;
109
+ padding: 10px 0;
110
+ border-top: 1px solid rgba(255, 255, 255, 0.06);
111
+ border-bottom: 1px solid rgba(255, 255, 255, 0.06);
112
+ }
113
+
114
+ .cookie-cat {
115
+ display: flex;
116
+ justify-content: space-between;
117
+ align-items: center;
118
+ gap: 12px;
119
+ }
120
+
121
+ .cookie-cat__name {
122
+ display: block;
123
+ font-size: 0.82rem;
124
+ font-weight: 700;
125
+ color: var(--c-text-1, #ffffff);
126
+ }
127
+
128
+ .cookie-cat__desc {
129
+ display: block;
130
+ font-size: 0.72rem;
131
+ color: var(--c-text-3, #737373);
132
+ }
133
+
134
+ /* Switch toggle */
135
+ .switch {
136
+ position: relative;
137
+ display: inline-block;
138
+ width: 38px;
139
+ height: 22px;
140
+ flex-shrink: 0;
141
+ }
142
+ .switch input { opacity: 0; width: 0; height: 0; }
143
+ .slider {
144
+ position: absolute;
145
+ cursor: pointer;
146
+ inset: 0;
147
+ background-color: rgba(255, 255, 255, 0.15);
148
+ border-radius: 34px;
149
+ transition: 0.25s;
150
+ }
151
+ .slider:before {
152
+ position: absolute;
153
+ content: "";
154
+ height: 16px;
155
+ width: 16px;
156
+ left: 3px;
157
+ bottom: 3px;
158
+ background-color: white;
159
+ border-radius: 50%;
160
+ transition: 0.25s;
161
+ }
162
+ input:checked + .slider {
163
+ background-color: var(--c-primary-light, #d4a017);
164
+ }
165
+ input:checked + .slider:before {
166
+ transform: translateX(16px);
167
+ }
168
+ input:disabled + .slider {
169
+ opacity: 0.6;
170
+ cursor: not-allowed;
171
+ }
172
+
173
+ .cookie-drawer__actions {
174
+ display: flex;
175
+ justify-content: flex-end;
176
+ gap: 10px;
177
+ }
178
+
179
+ .btn {
180
+ padding: 0.55rem 1.2rem;
181
+ font-size: 0.82rem;
182
+ font-weight: 700;
183
+ border-radius: var(--r-md, 10px);
184
+ cursor: pointer;
185
+ transition: all 0.2s ease;
186
+ }
187
+
188
+ .btn--secondary {
189
+ background: rgba(255, 255, 255, 0.05);
190
+ border: 1px solid rgba(255, 255, 255, 0.1);
191
+ color: var(--c-text-2, #a3a3a3);
192
+ }
193
+ .btn--secondary:hover {
194
+ color: var(--c-text-1, #ffffff);
195
+ background: rgba(255, 255, 255, 0.1);
196
+ }
197
+
198
+ .btn--primary {
199
+ background: linear-gradient(135deg, #d4a017, #b8860b);
200
+ border: none;
201
+ color: #050505;
202
+ box-shadow: 0 4px 14px rgba(184, 134, 11, 0.35);
203
+ }
204
+ .btn--primary:hover {
205
+ transform: translateY(-1px);
206
+ box-shadow: 0 6px 20px rgba(184, 134, 11, 0.45);
207
+ }
208
+ </style>
209
+
210
+ <script>
211
+ function setupCookieDrawers() {
212
+ document.querySelectorAll('[data-cookie-drawer]').forEach((drawer) => {
213
+ const dismiss = () => {
214
+ (drawer as HTMLElement).style.transform = 'translateY(120%)';
215
+ (drawer as HTMLElement).style.opacity = '0';
216
+ setTimeout(() => drawer.remove(), 350);
217
+ };
218
+
219
+ drawer.querySelector('[data-cookie-reject]')?.addEventListener('click', dismiss);
220
+ drawer.querySelector('[data-cookie-accept]')?.addEventListener('click', dismiss);
221
+ });
222
+ }
223
+
224
+ setupCookieDrawers();
225
+ document.addEventListener('astro:page-load', setupCookieDrawers);
226
+ </script>
@@ -0,0 +1,203 @@
1
+ ---
2
+ /**
3
+ * FloatingFeedbackWidget — Fixed corner floating pill that expands into an interactive feedback survey card.
4
+ *
5
+ * @param {string} title - Widget title. Default is 'Was this helpful?'.
6
+ * @param {string} position - Screen anchor ('bottom-right' | 'bottom-left'). Default is 'bottom-right'.
7
+ */
8
+ interface Props {
9
+ title?: string;
10
+ position?: 'bottom-right' | 'bottom-left';
11
+ }
12
+
13
+ const {
14
+ title = 'Send Feedback',
15
+ position = 'bottom-right',
16
+ } = Astro.props;
17
+ ---
18
+
19
+ <div class:list={['fb-widget', `fb-widget--${position}`]} data-feedback-widget>
20
+ <button type="button" class="fb-widget__trigger" aria-label="Open feedback modal" data-fb-trigger>
21
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
22
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
23
+ </svg>
24
+ <span>Feedback</span>
25
+ </button>
26
+
27
+ <div class="fb-widget__card" data-fb-card hidden>
28
+ <div class="fb-widget__head">
29
+ <h5 class="fb-widget__title">{title}</h5>
30
+ <button type="button" class="fb-widget__close" aria-label="Close" data-fb-close>×</button>
31
+ </div>
32
+
33
+ <div class="fb-widget__emojis">
34
+ <button type="button" class="emoji-btn" aria-label="Sad">🙁</button>
35
+ <button type="button" class="emoji-btn" aria-label="Neutral">😐</button>
36
+ <button type="button" class="emoji-btn emoji-btn--selected" aria-label="Happy">😊</button>
37
+ <button type="button" class="emoji-btn" aria-label="Love it">🤩</button>
38
+ </div>
39
+
40
+ <textarea
41
+ placeholder="Any details to share? (optional)"
42
+ class="fb-widget__textarea"
43
+ rows="2"
44
+ ></textarea>
45
+
46
+ <button type="button" class="fb-widget__send" data-fb-send>
47
+ Send Feedback
48
+ </button>
49
+ </div>
50
+ </div>
51
+
52
+ <style>
53
+ .fb-widget {
54
+ position: fixed;
55
+ z-index: 90;
56
+ font-family: var(--font-sans, system-ui, sans-serif);
57
+ }
58
+
59
+ .fb-widget--bottom-right { bottom: 1.5rem; right: 1.5rem; }
60
+ .fb-widget--bottom-left { bottom: 1.5rem; left: 1.5rem; }
61
+
62
+ .fb-widget__trigger {
63
+ display: inline-flex;
64
+ align-items: center;
65
+ gap: 8px;
66
+ padding: 0.6rem 1.1rem;
67
+ background: rgba(14, 14, 18, 0.9);
68
+ backdrop-filter: blur(16px);
69
+ border: 1px solid rgba(255, 255, 255, 0.12);
70
+ border-radius: var(--r-full, 9999px);
71
+ color: var(--c-text-1, #ffffff);
72
+ font-size: 0.82rem;
73
+ font-weight: 700;
74
+ cursor: pointer;
75
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
76
+ transition: transform 0.2s ease, border-color 0.2s ease;
77
+ }
78
+
79
+ .fb-widget__trigger:hover {
80
+ transform: translateY(-2px);
81
+ border-color: rgba(184, 134, 11, 0.4);
82
+ color: var(--c-primary-light, #d4a017);
83
+ }
84
+
85
+ .fb-widget__card {
86
+ position: absolute;
87
+ bottom: calc(100% + 12px);
88
+ right: 0;
89
+ width: 280px;
90
+ padding: 1.2rem;
91
+ background: rgba(12, 12, 16, 0.95);
92
+ backdrop-filter: blur(24px);
93
+ border: 1px solid rgba(255, 255, 255, 0.12);
94
+ border-radius: var(--r-xl, 20px);
95
+ box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6);
96
+ display: flex;
97
+ flex-direction: column;
98
+ gap: 12px;
99
+ }
100
+
101
+ .fb-widget__head {
102
+ display: flex;
103
+ justify-content: space-between;
104
+ align-items: center;
105
+ }
106
+
107
+ .fb-widget__title {
108
+ font-size: 0.88rem;
109
+ font-weight: 800;
110
+ color: var(--c-text-1, #ffffff);
111
+ margin: 0;
112
+ }
113
+
114
+ .fb-widget__close {
115
+ background: transparent;
116
+ border: none;
117
+ color: var(--c-text-3, #737373);
118
+ font-size: 1.2rem;
119
+ line-height: 1;
120
+ cursor: pointer;
121
+ }
122
+
123
+ .fb-widget__emojis {
124
+ display: flex;
125
+ justify-content: space-between;
126
+ gap: 6px;
127
+ }
128
+
129
+ .emoji-btn {
130
+ flex: 1;
131
+ font-size: 1.4rem;
132
+ background: rgba(255, 255, 255, 0.03);
133
+ border: 1px solid rgba(255, 255, 255, 0.08);
134
+ border-radius: var(--r-md, 10px);
135
+ padding: 6px 0;
136
+ cursor: pointer;
137
+ transition: transform 0.2s ease, background 0.2s ease;
138
+ }
139
+
140
+ .emoji-btn:hover,
141
+ .emoji-btn--selected {
142
+ transform: scale(1.15);
143
+ background: rgba(184, 134, 11, 0.2);
144
+ border-color: rgba(184, 134, 11, 0.4);
145
+ }
146
+
147
+ .fb-widget__textarea {
148
+ width: 100%;
149
+ background: rgba(255, 255, 255, 0.03);
150
+ border: 1px solid rgba(255, 255, 255, 0.08);
151
+ border-radius: var(--r-sm, 8px);
152
+ color: var(--c-text-1, #ffffff);
153
+ font-size: 0.8rem;
154
+ padding: 8px;
155
+ resize: none;
156
+ outline: none;
157
+ font-family: inherit;
158
+ }
159
+
160
+ .fb-widget__send {
161
+ padding: 0.6rem;
162
+ background: linear-gradient(135deg, #d4a017, #b8860b);
163
+ border: none;
164
+ border-radius: var(--r-sm, 8px);
165
+ color: #050505;
166
+ font-size: 0.8rem;
167
+ font-weight: 800;
168
+ cursor: pointer;
169
+ transition: opacity 0.2s;
170
+ }
171
+
172
+ .fb-widget__send:hover {
173
+ opacity: 0.9;
174
+ }
175
+ </style>
176
+
177
+ <script>
178
+ function setupFeedbackWidgets() {
179
+ document.querySelectorAll('[data-feedback-widget]').forEach((widget) => {
180
+ const trigger = widget.querySelector('[data-fb-trigger]');
181
+ const card = widget.querySelector('[data-fb-card]') as HTMLElement;
182
+ const close = widget.querySelector('[data-fb-close]');
183
+ const send = widget.querySelector('[data-fb-send]');
184
+ if (!trigger || !card) return;
185
+
186
+ trigger.addEventListener('click', () => {
187
+ card.hidden = !card.hidden;
188
+ });
189
+
190
+ close?.addEventListener('click', () => {
191
+ card.hidden = true;
192
+ });
193
+
194
+ send?.addEventListener('click', () => {
195
+ card.innerHTML = `<p style="text-align:center;font-size:0.85rem;color:#10b981;font-weight:700;margin:1rem 0;">✓ Thank you for your feedback!</p>`;
196
+ setTimeout(() => { card.hidden = true; }, 2000);
197
+ });
198
+ });
199
+ }
200
+
201
+ setupFeedbackWidgets();
202
+ document.addEventListener('astro:page-load', setupFeedbackWidgets);
203
+ </script>
@@ -0,0 +1,172 @@
1
+ ---
2
+ /**
3
+ * ImageCompareSlider — Interactive dual-image split compare slider with draggable separator bar.
4
+ *
5
+ * @param {string} beforeImage - URL of original / before image.
6
+ * @param {string} afterImage - URL of modified / after image.
7
+ * @param {string} beforeLabel - Label tag. Default is 'Before'.
8
+ * @param {string} afterLabel - Label tag. Default is 'After'.
9
+ * @param {number} initialPosition - Starting separator position (0 to 100). Default is 50.
10
+ */
11
+ interface Props {
12
+ beforeImage?: string;
13
+ afterImage?: string;
14
+ beforeLabel?: string;
15
+ afterLabel?: string;
16
+ initialPosition?: number;
17
+ }
18
+
19
+ const {
20
+ beforeImage = 'https://images.unsplash.com/photo-1518770660439-4636190af475?w=800&auto=format&fit=crop&q=80',
21
+ afterImage = 'https://images.unsplash.com/photo-1550751827-4bd374c3f58b?w=800&auto=format&fit=crop&q=80',
22
+ beforeLabel = 'Before (Wireframe)',
23
+ afterLabel = 'After (Production)',
24
+ initialPosition = 50,
25
+ } = Astro.props;
26
+ ---
27
+
28
+ <div class="img-compare" data-img-compare style={`--pos: ${initialPosition}%;`}>
29
+ <div class="img-compare__layer img-compare__layer--after">
30
+ <img src={afterImage} alt={afterLabel} loading="lazy" />
31
+ <span class="img-compare__tag img-compare__tag--after">{afterLabel}</span>
32
+ </div>
33
+
34
+ <div class="img-compare__layer img-compare__layer--before" data-compare-before>
35
+ <img src={beforeImage} alt={beforeLabel} loading="lazy" />
36
+ <span class="img-compare__tag img-compare__tag--before">{beforeLabel}</span>
37
+ </div>
38
+
39
+ <div class="img-compare__handle" data-compare-handle aria-hidden="true">
40
+ <div class="handle-line"></div>
41
+ <div class="handle-button">
42
+ <span>‹</span>
43
+ <span>›</span>
44
+ </div>
45
+ </div>
46
+
47
+ <input
48
+ type="range"
49
+ min="0"
50
+ max="100"
51
+ value={initialPosition}
52
+ class="img-compare__range"
53
+ aria-label="Drag to compare images"
54
+ data-compare-range
55
+ />
56
+ </div>
57
+
58
+ <style>
59
+ .img-compare {
60
+ position: relative;
61
+ width: 100%;
62
+ max-width: 600px;
63
+ aspect-ratio: 16 / 10;
64
+ overflow: hidden;
65
+ border-radius: var(--r-xl, 20px);
66
+ border: 1px solid rgba(255, 255, 255, 0.1);
67
+ box-shadow: 0 16px 40px rgba(0, 0, 0, 0.5);
68
+ user-select: none;
69
+ font-family: var(--font-sans, system-ui, sans-serif);
70
+ }
71
+
72
+ .img-compare__layer {
73
+ position: absolute;
74
+ inset: 0;
75
+ width: 100%;
76
+ height: 100%;
77
+ }
78
+
79
+ .img-compare__layer img {
80
+ width: 100%;
81
+ height: 100%;
82
+ object-fit: cover;
83
+ display: block;
84
+ pointer-events: none;
85
+ }
86
+
87
+ .img-compare__layer--before {
88
+ clip-path: polygon(0 0, var(--pos) 0, var(--pos) 100%, 0 100%);
89
+ }
90
+
91
+ .img-compare__tag {
92
+ position: absolute;
93
+ top: 14px;
94
+ padding: 4px 10px;
95
+ background: rgba(0, 0, 0, 0.65);
96
+ backdrop-filter: blur(8px);
97
+ color: #ffffff;
98
+ font-size: 0.72rem;
99
+ font-weight: 700;
100
+ border-radius: var(--r-full, 9999px);
101
+ border: 1px solid rgba(255, 255, 255, 0.15);
102
+ pointer-events: none;
103
+ }
104
+
105
+ .img-compare__tag--before { left: 14px; }
106
+ .img-compare__tag--after { right: 14px; }
107
+
108
+ .img-compare__handle {
109
+ position: absolute;
110
+ top: 0;
111
+ bottom: 0;
112
+ left: var(--pos);
113
+ transform: translateX(-50%);
114
+ pointer-events: none;
115
+ z-index: 5;
116
+ display: flex;
117
+ flex-direction: column;
118
+ align-items: center;
119
+ justify-content: center;
120
+ }
121
+
122
+ .handle-line {
123
+ width: 2px;
124
+ height: 100%;
125
+ background: #ffffff;
126
+ box-shadow: 0 0 8px rgba(0, 0, 0, 0.8);
127
+ }
128
+
129
+ .handle-button {
130
+ position: absolute;
131
+ top: 50%;
132
+ transform: translateY(-50%);
133
+ width: 36px;
134
+ height: 36px;
135
+ border-radius: 50%;
136
+ background: #ffffff;
137
+ color: #050505;
138
+ display: flex;
139
+ align-items: center;
140
+ justify-content: center;
141
+ gap: 4px;
142
+ font-size: 0.95rem;
143
+ font-weight: 900;
144
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
145
+ }
146
+
147
+ .img-compare__range {
148
+ position: absolute;
149
+ inset: 0;
150
+ width: 100%;
151
+ height: 100%;
152
+ opacity: 0;
153
+ cursor: ew-resize;
154
+ z-index: 10;
155
+ }
156
+ </style>
157
+
158
+ <script>
159
+ function setupImageCompare() {
160
+ document.querySelectorAll('[data-img-compare]').forEach((comp) => {
161
+ const range = comp.querySelector('[data-compare-range]') as HTMLInputElement;
162
+ if (!range) return;
163
+
164
+ range.addEventListener('input', () => {
165
+ (comp as HTMLElement).style.setProperty('--pos', `${range.value}%`);
166
+ });
167
+ });
168
+ }
169
+
170
+ setupImageCompare();
171
+ document.addEventListener('astro:page-load', setupImageCompare);
172
+ </script>
@@ -21,3 +21,6 @@ export { default as SplashIntroOverlay } from './SplashIntroOverlay.astro';
21
21
  export { default as SpotlightIndicator } from './SpotlightIndicator.astro';
22
22
  export { default as ToastStackOverlay } from './ToastStackOverlay.astro';
23
23
  export { default as TooltipActionTray } from './TooltipActionTray.astro';
24
+ export { default as CookiePreferencesDrawer } from './CookiePreferencesDrawer.astro';
25
+ export { default as ImageCompareSlider } from './ImageCompareSlider.astro';
26
+ export { default as FloatingFeedbackWidget } from './FloatingFeedbackWidget.astro';