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.
- package/README.md +133 -36
- package/package.json +17 -4
- package/src/components/index.ts +18 -202
- package/src/components/lib/Galaxy3D.astro +249 -137
- package/src/components/lib/app/AppSidebar.astro +249 -0
- package/src/components/lib/app/AppTopbar.astro +284 -0
- package/src/components/lib/app/ArrivalsBoard.astro +176 -0
- package/src/components/lib/app/AuthCard.astro +213 -0
- package/src/components/lib/app/DataTable.astro +346 -0
- package/src/components/lib/app/GuestProfileCard.astro +133 -0
- package/src/components/lib/app/HousekeepingBoard.astro +189 -0
- package/src/components/lib/app/PageHeader.astro +157 -0
- package/src/components/lib/app/PlanUsageCard.astro +112 -0
- package/src/components/lib/app/RoomRack.astro +207 -0
- package/src/components/lib/app/SettingsSection.astro +96 -0
- package/src/components/lib/app/SwitchRow.astro +71 -0
- package/src/components/lib/app/TeamMembers.astro +190 -0
- package/src/components/lib/app/app-icons.ts +52 -0
- package/src/components/lib/app/index.ts +19 -0
- package/src/components/lib/buttons/NeonBorderButton.astro +162 -0
- package/src/components/lib/buttons/RippleButton.astro +199 -0
- package/src/components/lib/buttons/SlideRevealButton.astro +159 -0
- package/src/components/lib/buttons/index.ts +4 -0
- package/src/components/lib/cards/GithubRepoCard.astro +176 -0
- package/src/components/lib/cards/PricingCompareMiniCard.astro +196 -0
- package/src/components/lib/cards/StatsTrendCard.astro +149 -0
- package/src/components/lib/cards/index.ts +3 -0
- package/src/components/lib/charts/ActivityRings.astro +105 -0
- package/src/components/lib/charts/AreaChart.astro +4 -4
- package/src/components/lib/charts/BarChart.astro +3 -3
- package/src/components/lib/charts/BoxPlotChart.astro +109 -0
- package/src/components/lib/charts/BubbleChart.astro +101 -0
- package/src/components/lib/charts/BulletChart.astro +160 -0
- package/src/components/lib/charts/BumpChart.astro +92 -0
- package/src/components/lib/charts/CandlestickChart.astro +105 -0
- package/src/components/lib/charts/ChartFrame.astro +373 -0
- package/src/components/lib/charts/DivergingBarChart.astro +98 -0
- package/src/components/lib/charts/DonutChart.astro +2 -2
- package/src/components/lib/charts/DumbbellChart.astro +92 -0
- package/src/components/lib/charts/ForecastLineChart.astro +125 -0
- package/src/components/lib/charts/FunnelChart.astro +122 -0
- package/src/components/lib/charts/GaugeChart.astro +111 -0
- package/src/components/lib/charts/GoalProgressChart.astro +97 -0
- package/src/components/lib/charts/GroupedBarChart.astro +125 -0
- package/src/components/lib/charts/HeatmapChart.astro +131 -0
- package/src/components/lib/charts/HistogramChart.astro +111 -0
- package/src/components/lib/charts/HorizontalBarChart.astro +155 -0
- package/src/components/lib/charts/KpiStatTile.astro +116 -0
- package/src/components/lib/charts/KpiTrendGrid.astro +60 -0
- package/src/components/lib/charts/LineChart.astro +160 -0
- package/src/components/lib/charts/LinearProgressGauge.astro +136 -0
- package/src/components/lib/charts/LollipopChart.astro +100 -0
- package/src/components/lib/charts/MeterGauge.astro +122 -0
- package/src/components/lib/charts/MetricDeltaTable.astro +125 -0
- package/src/components/lib/charts/PieChart.astro +135 -0
- package/src/components/lib/charts/PolarAreaChart.astro +85 -0
- package/src/components/lib/charts/PopulationPyramid.astro +122 -0
- package/src/components/lib/charts/PunchCardChart.astro +89 -0
- package/src/components/lib/charts/RadarChart.astro +94 -0
- package/src/components/lib/charts/RadarMetricChart.astro +168 -0
- package/src/components/lib/charts/RadialBarChart.astro +124 -0
- package/src/components/lib/charts/RangeAreaChart.astro +113 -0
- package/src/components/lib/charts/RetentionCohortTable.astro +126 -0
- package/src/components/lib/charts/SankeyChart.astro +128 -0
- package/src/components/lib/charts/ScatterPlot.astro +139 -0
- package/src/components/lib/charts/SegmentedBarChart.astro +119 -0
- package/src/components/lib/charts/SlopeChart.astro +105 -0
- package/src/components/lib/charts/SparklineChart.astro +87 -0
- package/src/components/lib/charts/StackedAreaChart.astro +130 -0
- package/src/components/lib/charts/StackedBarChart.astro +136 -0
- package/src/components/lib/charts/SunburstChart.astro +103 -0
- package/src/components/lib/charts/TreemapChart.astro +94 -0
- package/src/components/lib/charts/WaffleChart.astro +121 -0
- package/src/components/lib/charts/WaterfallChart.astro +118 -0
- package/src/components/lib/charts/chart-tooltip.ts +75 -0
- package/src/components/lib/charts/chart-utils.ts +271 -0
- package/src/components/lib/charts/index.ts +46 -0
- package/src/components/lib/data/ActivityHeatmapGrid.astro +157 -0
- package/src/components/lib/data/MetricComparisonRow.astro +109 -0
- package/src/components/lib/data/StatusTimelineFeed.astro +168 -0
- package/src/components/lib/data/index.ts +3 -0
- package/src/components/lib/ecommerce/CartDrawer.astro +483 -0
- package/src/components/lib/ecommerce/CartPageList.astro +290 -0
- package/src/components/lib/ecommerce/CartToast.astro +276 -0
- package/src/components/lib/ecommerce/CategoryTiles.astro +143 -0
- package/src/components/lib/ecommerce/CheckoutForm.astro +423 -0
- package/src/components/lib/ecommerce/CountdownBanner.astro +230 -0
- package/src/components/lib/ecommerce/FilterBar.astro +278 -0
- package/src/components/lib/ecommerce/FilterSidebar.astro +405 -0
- package/src/components/lib/ecommerce/LiveActivityToast.astro +213 -0
- package/src/components/lib/ecommerce/OrderSummary.astro +295 -0
- package/src/components/lib/ecommerce/ProductBuyBox.astro +247 -0
- package/src/components/lib/ecommerce/ProductCardMinimal.astro +229 -0
- package/src/components/lib/ecommerce/ProductGallery.astro +145 -0
- package/src/components/lib/ecommerce/ProductGrid.astro +118 -0
- package/src/components/lib/ecommerce/ProductMedia.astro +113 -0
- package/src/components/lib/ecommerce/ProductRating.astro +78 -0
- package/src/components/lib/ecommerce/ProductToolbar.astro +93 -0
- package/src/components/lib/ecommerce/PromoBar.astro +145 -0
- package/src/components/lib/ecommerce/StockIndicator.astro +127 -0
- package/src/components/lib/ecommerce/StoreHeader.astro +446 -0
- package/src/components/lib/ecommerce/StoreHero.astro +260 -0
- package/src/components/lib/ecommerce/StoreProductCard.astro +307 -0
- package/src/components/lib/ecommerce/TrustBadges.astro +101 -0
- package/src/components/lib/ecommerce/VariantPicker.astro +145 -0
- package/src/components/lib/ecommerce/cart-store.ts +151 -0
- package/src/components/lib/ecommerce/catalog-filter.ts +62 -0
- package/src/components/lib/ecommerce/index.ts +34 -0
- package/src/components/lib/ecommerce/product-icons.ts +28 -0
- package/src/components/lib/ecommerce/types.ts +70 -0
- package/src/components/lib/feedback/ProgressRingCounter.astro +118 -0
- package/src/components/lib/feedback/ToastNotificationGroup.astro +173 -0
- package/src/components/lib/feedback/index.ts +2 -0
- package/src/components/lib/forms/AnimatedInput.astro +4 -2
- package/src/components/lib/forms/CustomRadioGroup.astro +3 -1
- package/src/components/lib/forms/GlassInlineToggleGroup.astro +161 -0
- package/src/components/lib/forms/PasswordStrengthInput.astro +242 -0
- package/src/components/lib/forms/PhoneCountryInput.astro +145 -0
- package/src/components/lib/forms/TagsAutocompleteInput.astro +249 -0
- package/src/components/lib/forms/index.ts +5 -0
- package/src/components/lib/index.ts +2 -0
- package/src/components/lib/layout/BentoGrid3.astro +6 -4
- package/src/components/lib/layout/CenterFixedBox.astro +2 -2
- package/src/components/lib/layout/CenteredContainer.astro +4 -2
- package/src/components/lib/layout/ClusterHorizontal.astro +2 -2
- package/src/components/lib/layout/DiagonalSectionDivider.astro +69 -0
- package/src/components/lib/layout/FeatureHero.astro +4 -2
- package/src/components/lib/layout/FooterCenteredMinimal.astro +4 -2
- package/src/components/lib/layout/FullBleedSection.astro +2 -2
- package/src/components/lib/layout/GalleryGrid4.astro +2 -2
- package/src/components/lib/layout/HolyGrailGrid.astro +127 -0
- package/src/components/lib/layout/LandingSectionSplit.astro +5 -3
- package/src/components/lib/layout/MasonryGrid.astro +2 -2
- package/src/components/lib/layout/MinimalFooterGrid.astro +1 -1
- package/src/components/lib/layout/ScrollSnapSection.astro +1 -1
- package/src/components/lib/layout/SidebarLayoutWrapper.astro +4 -2
- package/src/components/lib/layout/SplitScreenLayout.astro +3 -3
- package/src/components/lib/layout/StepLayoutVertical.astro +1 -1
- package/src/components/lib/layout/StickySidebarWrapper.astro +4 -2
- package/src/components/lib/layout/index.ts +3 -1
- package/src/components/lib/navigation/QuickJumpDock.astro +125 -0
- package/src/components/lib/navigation/StepBreadcrumbBar.astro +151 -0
- package/src/components/lib/navigation/SubNavbarPills.astro +102 -0
- package/src/components/lib/navigation/index.ts +3 -0
- package/src/components/lib/overlays/CookiePreferencesDrawer.astro +226 -0
- package/src/components/lib/overlays/FloatingFeedbackWidget.astro +203 -0
- package/src/components/lib/overlays/ImageCompareSlider.astro +172 -0
- package/src/components/lib/overlays/index.ts +3 -0
- package/src/components/lib/sections/AgencyContactBrief.astro +194 -0
- package/src/components/lib/sections/AgencyFooterCta.astro +94 -0
- package/src/components/lib/sections/AgencyHeader.astro +161 -0
- package/src/components/lib/sections/AgencyHeroKinetic.astro +172 -0
- package/src/components/lib/sections/AgencyServicesList.astro +113 -0
- package/src/components/lib/sections/AgencyTeamGrid.astro +111 -0
- package/src/components/lib/sections/AgencyWorkGrid.astro +147 -0
- package/src/components/lib/sections/BlogGridSection.astro +133 -0
- package/src/components/lib/sections/ButtonsShowcase.astro +20 -18
- package/src/components/lib/sections/CardsShowcase.astro +28 -26
- package/src/components/lib/sections/CareersOpenings.astro +141 -0
- package/src/components/lib/sections/ChangelogSection.astro +151 -0
- package/src/components/lib/sections/ContactGlassForm.astro +10 -8
- package/src/components/lib/sections/ContactSplitMap.astro +141 -0
- package/src/components/lib/sections/CtaAppDownload.astro +13 -11
- package/src/components/lib/sections/CtaGlowBanner.astro +12 -10
- package/src/components/lib/sections/CtaNewsletterSection.astro +165 -0
- package/src/components/lib/sections/CtaSplitImage.astro +149 -0
- package/src/components/lib/sections/DataShowcase.astro +23 -21
- package/src/components/lib/sections/FaqAccordionSection.astro +8 -8
- package/src/components/lib/sections/FaqTwoColumn.astro +121 -0
- package/src/components/lib/sections/FeatureAlternatingRows.astro +192 -0
- package/src/components/lib/sections/FeatureBentoGrid.astro +13 -11
- package/src/components/lib/sections/FeatureIconGrid.astro +155 -0
- package/src/components/lib/sections/FeatureTabsShowcase.astro +182 -0
- package/src/components/lib/sections/FeatureTimelineFlow.astro +8 -6
- package/src/components/lib/sections/FeedbackShowcase.astro +15 -13
- package/src/components/lib/sections/FooterMegaSection.astro +157 -0
- package/src/components/lib/sections/FormsShowcase.astro +22 -20
- package/src/components/lib/sections/HeroDashboardPreview.astro +182 -0
- package/src/components/lib/sections/HeroGlass.astro +22 -20
- package/src/components/lib/sections/HeroGradient.astro +15 -13
- package/src/components/lib/sections/HeroMinimalCentered.astro +175 -0
- package/src/components/lib/sections/HeroShowcaseSplit.astro +306 -0
- package/src/components/lib/sections/HeroSplit.astro +13 -11
- package/src/components/lib/sections/HeroTerminal.astro +253 -0
- package/src/components/lib/sections/HeroWaitlist.astro +231 -0
- package/src/components/lib/sections/HowItWorksSteps.astro +180 -0
- package/src/components/lib/sections/IntegrationsGrid.astro +167 -0
- package/src/components/lib/sections/LayoutShowcase.astro +21 -19
- package/src/components/lib/sections/LogoCloudSection.astro +96 -0
- package/src/components/lib/sections/LogoWallGrid.astro +93 -0
- package/src/components/lib/sections/NavigationShowcase.astro +15 -13
- package/src/components/lib/sections/OverlaysShowcase.astro +21 -19
- package/src/components/lib/sections/PricingComparisonMatrix.astro +15 -13
- package/src/components/lib/sections/PricingSinglePlan.astro +159 -0
- package/src/components/lib/sections/PricingTierCards.astro +11 -9
- package/src/components/lib/sections/PricingToggleCards.astro +171 -0
- package/src/components/lib/sections/ShopCategoryHero.astro +103 -0
- package/src/components/lib/sections/ShopCollectionMosaic.astro +131 -0
- package/src/components/lib/sections/ShopFooterWordmark.astro +100 -0
- package/src/components/lib/sections/ShopHeaderEditorial.astro +396 -0
- package/src/components/lib/sections/ShopHeroEditorial.astro +151 -0
- package/src/components/lib/sections/ShopLookbook.astro +250 -0
- package/src/components/lib/sections/ShopNewsletterEditorial.astro +128 -0
- package/src/components/lib/sections/ShopProductRail.astro +150 -0
- package/src/components/lib/sections/ShopReviewsEditorial.astro +133 -0
- package/src/components/lib/sections/ShopValuesMarquee.astro +91 -0
- package/src/components/lib/sections/StatsCounterBand.astro +124 -0
- package/src/components/lib/sections/StatsDashboardSection.astro +85 -0
- package/src/components/lib/sections/StatsMetricShowcase.astro +9 -7
- package/src/components/lib/sections/TeamGridSection.astro +12 -10
- package/src/components/lib/sections/TestimonialCarousel.astro +167 -0
- package/src/components/lib/sections/TestimonialFeatured.astro +122 -0
- package/src/components/lib/sections/TestimonialGridSection.astro +188 -0
- package/src/components/lib/sections/TestimonialWallGlass.astro +11 -9
- package/src/components/lib/sections/TypographyShowcase.astro +10 -8
- package/src/components/lib/sections/index.ts +39 -0
- package/src/components/lib/templates/ecommerce/StoreCategoryPage.astro +160 -0
- package/src/components/lib/templates/ecommerce/StoreCheckoutPage.astro +98 -0
- package/src/components/lib/templates/ecommerce/StoreHomePage.astro +191 -0
- package/src/components/lib/templates/ecommerce/StoreLayout.astro +169 -0
- package/src/components/lib/templates/ecommerce/StoreProductPage.astro +165 -0
- package/src/components/lib/templates/ecommerce/data.ts +187 -0
- package/src/components/lib/templates/ecommerce/index.ts +14 -0
- package/src/components/lib/templates/ecommerce-editorial/EditorialBagPage.astro +52 -0
- package/src/components/lib/templates/ecommerce-editorial/EditorialCheckoutPage.astro +123 -0
- package/src/components/lib/templates/ecommerce-editorial/EditorialHomePage.astro +102 -0
- package/src/components/lib/templates/ecommerce-editorial/EditorialLayout.astro +216 -0
- package/src/components/lib/templates/ecommerce-editorial/EditorialProductPage.astro +205 -0
- package/src/components/lib/templates/ecommerce-editorial/EditorialShopPage.astro +112 -0
- package/src/components/lib/templates/ecommerce-editorial/data.ts +125 -0
- package/src/components/lib/templates/ecommerce-editorial/index.ts +16 -0
- package/src/components/lib/templates/saas-hotel/AppLayout.astro +83 -0
- package/src/components/lib/templates/saas-hotel/DashboardPage.astro +66 -0
- package/src/components/lib/templates/saas-hotel/GuestsPage.astro +65 -0
- package/src/components/lib/templates/saas-hotel/LandingPage.astro +213 -0
- package/src/components/lib/templates/saas-hotel/ReportsPage.astro +63 -0
- package/src/components/lib/templates/saas-hotel/ReservationsPage.astro +49 -0
- package/src/components/lib/templates/saas-hotel/RoomsPage.astro +48 -0
- package/src/components/lib/templates/saas-hotel/SettingsPage.astro +115 -0
- package/src/components/lib/templates/saas-hotel/SignInPage.astro +50 -0
- package/src/components/lib/templates/saas-hotel/data.ts +229 -0
- package/src/components/lib/templates/saas-hotel/index.ts +19 -0
- package/src/components/lib/templates/saas-hotel/lobby-theme.css +90 -0
- package/src/components/lib/typography/AnimatedCounterText.astro +102 -0
- package/src/components/lib/typography/CurvedPathHeading.astro +86 -0
- package/src/components/lib/typography/GradientTextMarquee.astro +105 -0
- package/src/components/lib/typography/HackerDecodeText.astro +85 -0
- package/src/components/lib/typography/index.ts +4 -0
- package/src/styles/global.css +113 -1
|
@@ -8,6 +8,7 @@ interface Props {
|
|
|
8
8
|
const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astro.props;
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
<div class="cq-overlays-showcase-cq">
|
|
11
12
|
<section class="overlays-showcase">
|
|
12
13
|
<div class="container">
|
|
13
14
|
<div class="showcase-header">
|
|
@@ -77,8 +78,9 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
77
78
|
</div>
|
|
78
79
|
</div>
|
|
79
80
|
</section>
|
|
80
|
-
|
|
81
|
+
</div>
|
|
81
82
|
<style>
|
|
83
|
+
.cq-overlays-showcase-cq { container-type: inline-size; }
|
|
82
84
|
.overlays-showcase {
|
|
83
85
|
padding: var(--sp-16) 0;
|
|
84
86
|
position: relative;
|
|
@@ -95,8 +97,8 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
95
97
|
text-transform: uppercase;
|
|
96
98
|
letter-spacing: 0.1em;
|
|
97
99
|
color: var(--c-primary-light);
|
|
98
|
-
background:
|
|
99
|
-
border: 1px solid
|
|
100
|
+
background: color-mix(in srgb, var(--c-primary, #b8860b) 10%, transparent);
|
|
101
|
+
border: 1px solid color-mix(in srgb, var(--c-primary, #b8860b) 25%, transparent);
|
|
100
102
|
border-radius: var(--r-full);
|
|
101
103
|
margin-bottom: var(--sp-4);
|
|
102
104
|
}
|
|
@@ -118,7 +120,7 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
118
120
|
padding: var(--sp-12);
|
|
119
121
|
background: rgba(10, 10, 10, 0.6);
|
|
120
122
|
backdrop-filter: blur(20px);
|
|
121
|
-
border: 1px solid
|
|
123
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
|
|
122
124
|
border-radius: var(--r-xl);
|
|
123
125
|
margin-bottom: var(--sp-6);
|
|
124
126
|
box-shadow: 0 20px 60px rgba(0,0,0,0.4);
|
|
@@ -160,9 +162,9 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
160
162
|
padding: var(--sp-6);
|
|
161
163
|
background: rgba(30, 30, 30, 0.9);
|
|
162
164
|
backdrop-filter: blur(16px);
|
|
163
|
-
border: 1px solid
|
|
165
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
|
|
164
166
|
border-radius: var(--r-lg);
|
|
165
|
-
box-shadow: 0 24px 80px rgba(0,0,0,0.5), 0 0 0 1px
|
|
167
|
+
box-shadow: 0 24px 80px rgba(0,0,0,0.5), 0 0 0 1px rgb(var(--ink-rgb, 255 255 255) / 0.05);
|
|
166
168
|
transform: scale(1) translateY(0);
|
|
167
169
|
}
|
|
168
170
|
.overlay-card__header {
|
|
@@ -191,7 +193,7 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
191
193
|
transition: all 0.2s ease;
|
|
192
194
|
}
|
|
193
195
|
.overlay-close:hover {
|
|
194
|
-
background:
|
|
196
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.1);
|
|
195
197
|
color: var(--c-text-1);
|
|
196
198
|
}
|
|
197
199
|
.overlay-card__body {
|
|
@@ -226,7 +228,7 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
226
228
|
width: 200px;
|
|
227
229
|
background: rgba(25, 25, 25, 0.95);
|
|
228
230
|
backdrop-filter: blur(18px);
|
|
229
|
-
border: 1px solid
|
|
231
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
|
|
230
232
|
border-radius: var(--r-lg);
|
|
231
233
|
box-shadow: -12px 0 40px rgba(0,0,0,0.4);
|
|
232
234
|
transform: translateX(0);
|
|
@@ -278,15 +280,15 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
278
280
|
font-size: 0.8rem;
|
|
279
281
|
font-weight: 600;
|
|
280
282
|
color: var(--c-text-2);
|
|
281
|
-
background:
|
|
282
|
-
border: 1px solid
|
|
283
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.04);
|
|
284
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
|
|
283
285
|
border-radius: var(--r-md);
|
|
284
286
|
cursor: pointer;
|
|
285
287
|
transition: all 0.2s ease;
|
|
286
288
|
}
|
|
287
289
|
.popover-target:hover {
|
|
288
290
|
color: var(--c-text-1);
|
|
289
|
-
border-color:
|
|
291
|
+
border-color: color-mix(in srgb, var(--c-primary, #b8860b) 30%, transparent);
|
|
290
292
|
}
|
|
291
293
|
.popover-content {
|
|
292
294
|
position: absolute;
|
|
@@ -297,7 +299,7 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
297
299
|
padding: var(--sp-3) var(--sp-4);
|
|
298
300
|
background: rgba(40, 40, 40, 0.95);
|
|
299
301
|
backdrop-filter: blur(14px);
|
|
300
|
-
border: 1px solid
|
|
302
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
|
|
301
303
|
border-radius: var(--r-md);
|
|
302
304
|
box-shadow: 0 12px 32px rgba(0,0,0,0.4);
|
|
303
305
|
}
|
|
@@ -309,8 +311,8 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
309
311
|
width: 10px;
|
|
310
312
|
height: 10px;
|
|
311
313
|
background: rgba(40, 40, 40, 0.95);
|
|
312
|
-
border-right: 1px solid
|
|
313
|
-
border-bottom: 1px solid
|
|
314
|
+
border-right: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
|
|
315
|
+
border-bottom: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
|
|
314
316
|
transform: translateX(-50%) rotate(45deg);
|
|
315
317
|
}
|
|
316
318
|
.popover-text {
|
|
@@ -334,12 +336,12 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
334
336
|
}
|
|
335
337
|
.btn--primary {
|
|
336
338
|
background: linear-gradient(135deg, var(--c-primary-light), var(--c-primary));
|
|
337
|
-
color: #0a0a0a;
|
|
338
|
-
box-shadow: 0 4px 20px
|
|
339
|
+
color: var(--c-on-primary, #0a0a0a);
|
|
340
|
+
box-shadow: 0 4px 20px color-mix(in srgb, var(--c-primary, #b8860b) 30%, transparent);
|
|
339
341
|
}
|
|
340
342
|
.btn--primary:hover {
|
|
341
343
|
transform: translateY(-2px);
|
|
342
|
-
box-shadow: 0 8px 30px
|
|
344
|
+
box-shadow: 0 8px 30px color-mix(in srgb, var(--c-primary, #b8860b) 40%, transparent);
|
|
343
345
|
}
|
|
344
346
|
.btn--ghost {
|
|
345
347
|
background: transparent;
|
|
@@ -354,7 +356,7 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
354
356
|
.usage-code {
|
|
355
357
|
text-align: center;
|
|
356
358
|
padding: var(--sp-4);
|
|
357
|
-
background:
|
|
359
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.02);
|
|
358
360
|
border-radius: var(--r-md);
|
|
359
361
|
}
|
|
360
362
|
.usage-code code {
|
|
@@ -363,7 +365,7 @@ const { title = "Overlays", subtitle = "Modals, drawers, and popovers." } = Astr
|
|
|
363
365
|
color: var(--c-primary-light);
|
|
364
366
|
}
|
|
365
367
|
|
|
366
|
-
@
|
|
368
|
+
@container (max-width: 640px) {
|
|
367
369
|
.preview-stage { padding: var(--sp-8) var(--sp-4); }
|
|
368
370
|
.overlay-card { width: 240px; padding: var(--sp-4); }
|
|
369
371
|
.drawer-panel { width: 160px; right: var(--sp-2); }
|
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
} = Astro.props;
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
+
<div class="cq-pricing-comparison-matrix-cq">
|
|
24
25
|
<section class={`pricing-section ${className}`} aria-labelledby="pricing-title">
|
|
25
26
|
<div class="pricing-bg" aria-hidden="true">
|
|
26
27
|
<div class="pricing-glow"></div>
|
|
@@ -129,7 +130,7 @@ const {
|
|
|
129
130
|
</div>
|
|
130
131
|
</div>
|
|
131
132
|
</section>
|
|
132
|
-
|
|
133
|
+
</div>
|
|
133
134
|
<script>
|
|
134
135
|
const toggleBtn = document.getElementById('billingToggleBtn');
|
|
135
136
|
const priceVals = document.querySelectorAll('.price-val');
|
|
@@ -149,6 +150,7 @@ const {
|
|
|
149
150
|
</script>
|
|
150
151
|
|
|
151
152
|
<style>
|
|
153
|
+
.cq-pricing-comparison-matrix-cq { container-type: inline-size; }
|
|
152
154
|
.pricing-section {
|
|
153
155
|
position: relative;
|
|
154
156
|
padding: var(--sp-20, 5rem) var(--sp-6, 1.5rem);
|
|
@@ -170,7 +172,7 @@ const {
|
|
|
170
172
|
transform: translateX(-50%);
|
|
171
173
|
width: 600px;
|
|
172
174
|
height: 500px;
|
|
173
|
-
background: radial-gradient(circle,
|
|
175
|
+
background: radial-gradient(circle, color-mix(in srgb, var(--c-primary, #b8860b) 12%, transparent), transparent 70%);
|
|
174
176
|
filter: blur(100px);
|
|
175
177
|
}
|
|
176
178
|
|
|
@@ -195,7 +197,7 @@ const {
|
|
|
195
197
|
font-weight: 700;
|
|
196
198
|
letter-spacing: 0.06em;
|
|
197
199
|
text-transform: uppercase;
|
|
198
|
-
background:
|
|
200
|
+
background: color-mix(in srgb, var(--c-primary, #b8860b) 12%, transparent);
|
|
199
201
|
color: #eab308;
|
|
200
202
|
border: 1px solid rgba(234, 179, 8, 0.25);
|
|
201
203
|
margin-bottom: var(--sp-4, 1rem);
|
|
@@ -224,7 +226,7 @@ const {
|
|
|
224
226
|
gap: 0.75rem;
|
|
225
227
|
padding: 0.4rem 0.8rem;
|
|
226
228
|
background: rgba(15, 23, 42, 0.8);
|
|
227
|
-
border: 1px solid
|
|
229
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.1);
|
|
228
230
|
border-radius: 9999px;
|
|
229
231
|
}
|
|
230
232
|
|
|
@@ -248,7 +250,7 @@ const {
|
|
|
248
250
|
width: 44px;
|
|
249
251
|
height: 24px;
|
|
250
252
|
border-radius: 9999px;
|
|
251
|
-
background:
|
|
253
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.15);
|
|
252
254
|
border: none;
|
|
253
255
|
position: relative;
|
|
254
256
|
cursor: pointer;
|
|
@@ -286,7 +288,7 @@ const {
|
|
|
286
288
|
background: rgba(15, 23, 42, 0.6);
|
|
287
289
|
backdrop-filter: blur(20px);
|
|
288
290
|
-webkit-backdrop-filter: blur(20px);
|
|
289
|
-
border: 1px solid
|
|
291
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
|
|
290
292
|
border-radius: var(--r-xl, 20px);
|
|
291
293
|
padding: 2.25rem 2rem;
|
|
292
294
|
display: flex;
|
|
@@ -297,7 +299,7 @@ const {
|
|
|
297
299
|
|
|
298
300
|
.plan-card:hover {
|
|
299
301
|
transform: translateY(-4px);
|
|
300
|
-
border-color:
|
|
302
|
+
border-color: rgb(var(--ink-rgb, 255 255 255) / 0.18);
|
|
301
303
|
}
|
|
302
304
|
|
|
303
305
|
.plan-card--popular {
|
|
@@ -393,19 +395,19 @@ const {
|
|
|
393
395
|
}
|
|
394
396
|
|
|
395
397
|
.plan-btn--ghost {
|
|
396
|
-
background:
|
|
398
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.05);
|
|
397
399
|
color: #fff;
|
|
398
|
-
border: 1px solid
|
|
400
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.12);
|
|
399
401
|
}
|
|
400
402
|
|
|
401
403
|
.plan-btn--ghost:hover {
|
|
402
|
-
background:
|
|
403
|
-
border-color:
|
|
404
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.1);
|
|
405
|
+
border-color: rgb(var(--ink-rgb, 255 255 255) / 0.25);
|
|
404
406
|
}
|
|
405
407
|
|
|
406
408
|
.plan-divider {
|
|
407
409
|
height: 1px;
|
|
408
|
-
background:
|
|
410
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.08);
|
|
409
411
|
margin: 1.5rem 0;
|
|
410
412
|
}
|
|
411
413
|
|
|
@@ -454,7 +456,7 @@ const {
|
|
|
454
456
|
color: #10b981;
|
|
455
457
|
}
|
|
456
458
|
|
|
457
|
-
@
|
|
459
|
+
@container (max-width: 960px) {
|
|
458
460
|
.pricing-cards {
|
|
459
461
|
grid-template-columns: 1fr;
|
|
460
462
|
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* PricingSinglePlan — One-plan pricing section: price card on one side,
|
|
4
|
+
* full feature checklist on the other, with a money-back guarantee note.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} title - Section heading.
|
|
7
|
+
* @param {string} subtitle - Section description.
|
|
8
|
+
* @param {string} planName - Plan name.
|
|
9
|
+
* @param {string} price - Formatted price.
|
|
10
|
+
* @param {string} period - Billing period label.
|
|
11
|
+
* @param {string} originalPrice - Optional struck-through price.
|
|
12
|
+
* @param {string[]} features - Included features.
|
|
13
|
+
* @param {{label: string, href: string}} cta - CTA button.
|
|
14
|
+
* @param {string} guarantee - Reassurance note under the CTA.
|
|
15
|
+
* @param {string} variant - Card style (glow|glass|minimal).
|
|
16
|
+
* @param {string} size - Vertical rhythm (sm|md|lg).
|
|
17
|
+
* @param {string} className - Extra CSS class.
|
|
18
|
+
*/
|
|
19
|
+
interface Props {
|
|
20
|
+
title?: string;
|
|
21
|
+
subtitle?: string;
|
|
22
|
+
planName?: string;
|
|
23
|
+
price?: string;
|
|
24
|
+
period?: string;
|
|
25
|
+
originalPrice?: string;
|
|
26
|
+
features?: string[];
|
|
27
|
+
cta?: { label: string; href: string };
|
|
28
|
+
guarantee?: string;
|
|
29
|
+
variant?: 'glow' | 'glass' | 'minimal';
|
|
30
|
+
size?: 'sm' | 'md' | 'lg';
|
|
31
|
+
className?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const {
|
|
35
|
+
title = 'One price. Everything included.',
|
|
36
|
+
subtitle = 'Lifetime access to every component, section and future update.',
|
|
37
|
+
planName = 'Lifetime license',
|
|
38
|
+
price = '$149',
|
|
39
|
+
period = 'one-time payment',
|
|
40
|
+
originalPrice = '$249',
|
|
41
|
+
features = [
|
|
42
|
+
'250+ components & sections',
|
|
43
|
+
'45 dependency-free SVG charts',
|
|
44
|
+
'Lifetime updates',
|
|
45
|
+
'Unlimited projects',
|
|
46
|
+
'Commercial license',
|
|
47
|
+
'Figma design kit',
|
|
48
|
+
'Private community',
|
|
49
|
+
'Priority email support',
|
|
50
|
+
],
|
|
51
|
+
cta = { label: 'Get lifetime access', href: '#' },
|
|
52
|
+
guarantee = '30-day money-back guarantee. No questions asked.',
|
|
53
|
+
variant = 'glow',
|
|
54
|
+
size = 'md',
|
|
55
|
+
className = '',
|
|
56
|
+
} = Astro.props;
|
|
57
|
+
|
|
58
|
+
const id = `psp-${Math.random().toString(36).slice(2, 8)}`;
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
<div class="cq-pricing-single-plan-cq">
|
|
62
|
+
<section class={`psp psp--${variant} psp--${size} ${className}`} aria-labelledby={id}>
|
|
63
|
+
<div class="psp__inner">
|
|
64
|
+
<header class="psp__head">
|
|
65
|
+
<h2 id={id} class="psp__title">{title}</h2>
|
|
66
|
+
<p class="psp__subtitle">{subtitle}</p>
|
|
67
|
+
</header>
|
|
68
|
+
<div class="psp__card">
|
|
69
|
+
<div class="psp__price-col">
|
|
70
|
+
<p class="psp__plan">{planName}</p>
|
|
71
|
+
<p class="psp__price">
|
|
72
|
+
{originalPrice && <s class="psp__orig"><span class="psp__sr">Was </span>{originalPrice}</s>}
|
|
73
|
+
<span class="psp__amount"><span class="psp__sr">Now </span>{price}</span>
|
|
74
|
+
</p>
|
|
75
|
+
<p class="psp__period">{period}</p>
|
|
76
|
+
<a class="psp__cta" href={cta.href}>{cta.label}</a>
|
|
77
|
+
<p class="psp__guarantee">
|
|
78
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" /><path d="m9 12 2 2 4-4" /></svg>
|
|
79
|
+
{guarantee}
|
|
80
|
+
</p>
|
|
81
|
+
</div>
|
|
82
|
+
<div class="psp__features-col">
|
|
83
|
+
<h3 class="psp__features-title">What’s included</h3>
|
|
84
|
+
<ul class="psp__features">
|
|
85
|
+
{features.map((f) => (
|
|
86
|
+
<li><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5" /></svg>{f}</li>
|
|
87
|
+
))}
|
|
88
|
+
</ul>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</section>
|
|
93
|
+
</div>
|
|
94
|
+
<style>
|
|
95
|
+
.cq-pricing-single-plan-cq { container-type: inline-size; }
|
|
96
|
+
.psp {
|
|
97
|
+
--psp-py: 5.5rem;
|
|
98
|
+
padding: var(--psp-py) var(--sp-6, 1.5rem);
|
|
99
|
+
background: var(--c-bg, #050505);
|
|
100
|
+
}
|
|
101
|
+
.psp--sm { --psp-py: 3.5rem; }
|
|
102
|
+
.psp--lg { --psp-py: 7.5rem; }
|
|
103
|
+
.psp__inner { max-width: 960px; margin: 0 auto; }
|
|
104
|
+
.psp__head { text-align: center; margin-bottom: 3rem; }
|
|
105
|
+
.psp__title { margin: 0 0 0.75rem; font-size: clamp(1.9rem, 4vw, 2.75rem); font-weight: 800; letter-spacing: -0.03em; color: var(--c-text-1, #fff); }
|
|
106
|
+
.psp__subtitle { margin: 0; font-size: 1.0625rem; color: var(--c-text-2, #a3a3a3); }
|
|
107
|
+
.psp__card {
|
|
108
|
+
position: relative;
|
|
109
|
+
display: grid;
|
|
110
|
+
grid-template-columns: 1fr 1.3fr;
|
|
111
|
+
border-radius: var(--r-xl, 28px);
|
|
112
|
+
overflow: hidden;
|
|
113
|
+
border: 1px solid var(--c-border, rgb(var(--ink-rgb, 255 255 255) / 0.08));
|
|
114
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.02);
|
|
115
|
+
}
|
|
116
|
+
.psp--glow .psp__card { border-color: color-mix(in srgb, var(--c-primary-light, #d4a017) 35%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--c-primary-light, #d4a017) 8%, transparent), 0 40px 100px -40px color-mix(in srgb, var(--c-primary-light, #d4a017) 40%, transparent); }
|
|
117
|
+
.psp--glass .psp__card { backdrop-filter: blur(16px); background: linear-gradient(160deg, rgb(var(--ink-rgb, 255 255 255) / 0.06), rgb(var(--ink-rgb, 255 255 255) / 0.015)); }
|
|
118
|
+
.psp--minimal .psp__card { background: transparent; }
|
|
119
|
+
.psp__price-col {
|
|
120
|
+
display: flex;
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
justify-content: center;
|
|
123
|
+
padding: clamp(2rem, 5vw, 3rem);
|
|
124
|
+
background: radial-gradient(circle at 30% 0%, var(--c-primary-glow, color-mix(in srgb, var(--c-primary, #b8860b) 18%, transparent)), transparent 70%), rgb(var(--ink-rgb, 255 255 255) / 0.02);
|
|
125
|
+
border-right: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.06);
|
|
126
|
+
}
|
|
127
|
+
.psp__plan { margin: 0 0 1rem; font-size: 0.875rem; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--c-primary-light, #d4a017); }
|
|
128
|
+
.psp__price { display: flex; align-items: baseline; gap: 0.75rem; margin: 0; }
|
|
129
|
+
.psp__orig { font-size: 1.25rem; color: var(--c-text-3, #8a8a8a); }
|
|
130
|
+
.psp__amount { font-size: clamp(3rem, 7vw, 4rem); font-weight: 800; letter-spacing: -0.04em; color: var(--c-text-1, #fff); line-height: 1; }
|
|
131
|
+
.psp__period { margin: 0.5rem 0 2rem; font-size: 0.9rem; color: var(--c-text-2, #a3a3a3); }
|
|
132
|
+
.psp__cta {
|
|
133
|
+
display: inline-flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
justify-content: center;
|
|
136
|
+
min-height: 52px;
|
|
137
|
+
border-radius: var(--r-md, 12px);
|
|
138
|
+
background: var(--c-primary-light, #d4a017);
|
|
139
|
+
color: var(--c-on-primary, #0a0a0a);
|
|
140
|
+
font-weight: 700;
|
|
141
|
+
text-decoration: none;
|
|
142
|
+
transition: background 0.2s ease, transform 0.2s ease;
|
|
143
|
+
}
|
|
144
|
+
.psp__cta:hover { background: var(--c-accent, #fef3c7); color: var(--c-on-primary, #0a0a0a); transform: translateY(-1px); }
|
|
145
|
+
.psp__cta:focus-visible { outline: 2px solid var(--c-primary-light, #d4a017); outline-offset: 3px; }
|
|
146
|
+
.psp__guarantee { display: flex; align-items: flex-start; gap: 0.5rem; margin: 1.25rem 0 0; font-size: 0.8125rem; line-height: 1.5; color: var(--c-text-2, #a3a3a3); }
|
|
147
|
+
.psp__guarantee svg { color: var(--chart-pos, #34c38f); flex-shrink: 0; margin-top: 1px; }
|
|
148
|
+
.psp__features-col { padding: clamp(2rem, 5vw, 3rem); }
|
|
149
|
+
.psp__features-title { margin: 0 0 1.5rem; font-size: 1rem; font-weight: 650; color: var(--c-text-1, #fff); }
|
|
150
|
+
.psp__features { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; gap: 1rem 1.5rem; }
|
|
151
|
+
.psp__features li { display: flex; align-items: flex-start; gap: 0.6rem; font-size: 0.9375rem; line-height: 1.4; color: var(--c-text-1, #fff); }
|
|
152
|
+
.psp__features svg { color: var(--c-primary-light, #d4a017); flex-shrink: 0; }
|
|
153
|
+
.psp__sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
|
154
|
+
@container (max-width: 760px) {
|
|
155
|
+
.psp__card { grid-template-columns: 1fr; }
|
|
156
|
+
.psp__price-col { border-right: 0; border-bottom: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.06); }
|
|
157
|
+
.psp__features { grid-template-columns: 1fr; }
|
|
158
|
+
}
|
|
159
|
+
</style>
|
|
@@ -21,6 +21,7 @@ const {
|
|
|
21
21
|
} = Astro.props;
|
|
22
22
|
---
|
|
23
23
|
|
|
24
|
+
<div class="cq-pricing-tier-cards-cq">
|
|
24
25
|
<section class={`tier-pricing-section ${className}`} aria-labelledby="tier-pricing-title">
|
|
25
26
|
<div class="container">
|
|
26
27
|
<div class="section-header">
|
|
@@ -79,8 +80,9 @@ const {
|
|
|
79
80
|
</div>
|
|
80
81
|
</div>
|
|
81
82
|
</section>
|
|
82
|
-
|
|
83
|
+
</div>
|
|
83
84
|
<style>
|
|
85
|
+
.cq-pricing-tier-cards-cq { container-type: inline-size; }
|
|
84
86
|
.tier-pricing-section {
|
|
85
87
|
padding: var(--sp-20, 5rem) var(--sp-6, 1.5rem);
|
|
86
88
|
background: var(--c-bg-primary, #030712);
|
|
@@ -105,7 +107,7 @@ const {
|
|
|
105
107
|
font-weight: 700;
|
|
106
108
|
letter-spacing: 0.06em;
|
|
107
109
|
text-transform: uppercase;
|
|
108
|
-
background:
|
|
110
|
+
background: color-mix(in srgb, var(--c-primary, #b8860b) 12%, transparent);
|
|
109
111
|
color: #eab308;
|
|
110
112
|
border: 1px solid rgba(234, 179, 8, 0.25);
|
|
111
113
|
margin-bottom: var(--sp-4, 1rem);
|
|
@@ -136,7 +138,7 @@ const {
|
|
|
136
138
|
|
|
137
139
|
.tier-card {
|
|
138
140
|
background: rgba(15, 23, 42, 0.55);
|
|
139
|
-
border: 1px solid
|
|
141
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.08);
|
|
140
142
|
border-radius: 20px;
|
|
141
143
|
padding: 2.5rem 2rem;
|
|
142
144
|
display: flex;
|
|
@@ -146,7 +148,7 @@ const {
|
|
|
146
148
|
|
|
147
149
|
.tier-card:hover {
|
|
148
150
|
transform: translateY(-4px);
|
|
149
|
-
border-color:
|
|
151
|
+
border-color: rgb(var(--ink-rgb, 255 255 255) / 0.2);
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
.tier-card--highlight {
|
|
@@ -163,7 +165,7 @@ const {
|
|
|
163
165
|
font-size: 0.72rem;
|
|
164
166
|
font-weight: 700;
|
|
165
167
|
text-transform: uppercase;
|
|
166
|
-
background:
|
|
168
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.08);
|
|
167
169
|
color: #cbd5e1;
|
|
168
170
|
margin-bottom: 1rem;
|
|
169
171
|
}
|
|
@@ -225,13 +227,13 @@ const {
|
|
|
225
227
|
}
|
|
226
228
|
|
|
227
229
|
.tier-btn--ghost {
|
|
228
|
-
background:
|
|
229
|
-
border: 1px solid
|
|
230
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.05);
|
|
231
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.12);
|
|
230
232
|
color: #fff;
|
|
231
233
|
}
|
|
232
234
|
|
|
233
235
|
.tier-btn--ghost:hover {
|
|
234
|
-
background:
|
|
236
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.12);
|
|
235
237
|
}
|
|
236
238
|
|
|
237
239
|
.tier-list {
|
|
@@ -248,7 +250,7 @@ const {
|
|
|
248
250
|
color: #cbd5e1;
|
|
249
251
|
}
|
|
250
252
|
|
|
251
|
-
@
|
|
253
|
+
@container (max-width: 960px) {
|
|
252
254
|
.tier-grid {
|
|
253
255
|
grid-template-columns: 1fr;
|
|
254
256
|
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
---
|
|
2
|
+
/**
|
|
3
|
+
* PricingToggleCards — Three pricing tiers with an accessible monthly/yearly
|
|
4
|
+
* switch (role="switch"), savings badge and a highlighted recommended plan.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} title - Section heading.
|
|
7
|
+
* @param {string} subtitle - Section description.
|
|
8
|
+
* @param {Array<{name: string, monthly: number, yearly: number, description: string, features: string[], cta: string, href: string, featured?: boolean}>} plans - Tiers.
|
|
9
|
+
* @param {string} currency - Currency symbol.
|
|
10
|
+
* @param {string} savingsLabel - Badge next to the yearly option.
|
|
11
|
+
* @param {string} variant - Card style (glass|solid|outline).
|
|
12
|
+
* @param {string} size - Vertical rhythm (sm|md|lg).
|
|
13
|
+
* @param {string} className - Extra CSS class.
|
|
14
|
+
*/
|
|
15
|
+
interface Plan { name: string; monthly: number; yearly: number; description: string; features: string[]; cta: string; href: string; featured?: boolean }
|
|
16
|
+
interface Props {
|
|
17
|
+
title?: string;
|
|
18
|
+
subtitle?: string;
|
|
19
|
+
plans?: Plan[];
|
|
20
|
+
currency?: string;
|
|
21
|
+
savingsLabel?: string;
|
|
22
|
+
variant?: 'glass' | 'solid' | 'outline';
|
|
23
|
+
size?: 'sm' | 'md' | 'lg';
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const {
|
|
28
|
+
title = 'Simple pricing that scales with you',
|
|
29
|
+
subtitle = 'Start free. Upgrade when your team grows. Cancel anytime.',
|
|
30
|
+
plans = [
|
|
31
|
+
{ name: 'Starter', monthly: 0, yearly: 0, description: 'For side projects and prototypes.', features: ['All components', 'Community support', '1 project'], cta: 'Get started', href: '#' },
|
|
32
|
+
{ name: 'Pro', monthly: 24, yearly: 19, description: 'For professionals shipping client work.', features: ['Everything in Starter', 'Premium sections', 'Unlimited projects', 'Priority support'], cta: 'Start 14-day trial', href: '#', featured: true },
|
|
33
|
+
{ name: 'Team', monthly: 79, yearly: 63, description: 'For agencies and product teams.', features: ['Everything in Pro', '10 seats included', 'Figma kit', 'Private Discord'], cta: 'Contact sales', href: '#' },
|
|
34
|
+
],
|
|
35
|
+
currency = '$',
|
|
36
|
+
savingsLabel = 'Save 20%',
|
|
37
|
+
variant = 'glass',
|
|
38
|
+
size = 'md',
|
|
39
|
+
className = '',
|
|
40
|
+
} = Astro.props;
|
|
41
|
+
|
|
42
|
+
const id = `ptc-${Math.random().toString(36).slice(2, 8)}`;
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
<section class={`ptc ptc--${variant} ptc--${size} ${className}`} aria-labelledby={id} data-ptc data-period="monthly">
|
|
46
|
+
<div class="ptc__inner">
|
|
47
|
+
<header class="ptc__head">
|
|
48
|
+
<h2 id={id} class="ptc__title">{title}</h2>
|
|
49
|
+
<p class="ptc__subtitle">{subtitle}</p>
|
|
50
|
+
<div class="ptc__toggle">
|
|
51
|
+
<span class="ptc__period" id={`${id}-m`}>Monthly</span>
|
|
52
|
+
<button type="button" class="ptc__switch" role="switch" aria-checked="false" aria-labelledby={`${id}-y`}>
|
|
53
|
+
<span class="ptc__knob" aria-hidden="true"></span>
|
|
54
|
+
</button>
|
|
55
|
+
<span class="ptc__period" id={`${id}-y`}>Yearly <span class="ptc__save">{savingsLabel}</span></span>
|
|
56
|
+
</div>
|
|
57
|
+
</header>
|
|
58
|
+
|
|
59
|
+
<ul class="ptc__grid">
|
|
60
|
+
{plans.map((p) => (
|
|
61
|
+
<li class={`ptc__card ${p.featured ? 'ptc__card--featured' : ''}`}>
|
|
62
|
+
{p.featured && <span class="ptc__ribbon">Most popular</span>}
|
|
63
|
+
<h3 class="ptc__name">{p.name}</h3>
|
|
64
|
+
<p class="ptc__desc">{p.description}</p>
|
|
65
|
+
<p class="ptc__price">
|
|
66
|
+
<span class="ptc__amount" data-monthly={`${currency}${p.monthly}`} data-yearly={`${currency}${p.yearly}`}>{currency}{p.monthly}</span>
|
|
67
|
+
<span class="ptc__per">/ month<span class="ptc__billed" data-yearly-only>, billed yearly</span></span>
|
|
68
|
+
</p>
|
|
69
|
+
<a class="ptc__cta" href={p.href}>{p.cta}</a>
|
|
70
|
+
<ul class="ptc__features">
|
|
71
|
+
{p.features.map((f) => (
|
|
72
|
+
<li><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 6 9 17l-5-5" /></svg>{f}</li>
|
|
73
|
+
))}
|
|
74
|
+
</ul>
|
|
75
|
+
</li>
|
|
76
|
+
))}
|
|
77
|
+
</ul>
|
|
78
|
+
<p class="ptc__live" role="status" aria-live="polite"></p>
|
|
79
|
+
</div>
|
|
80
|
+
</section>
|
|
81
|
+
|
|
82
|
+
<script>
|
|
83
|
+
document.querySelectorAll<HTMLElement>('[data-ptc]').forEach((root) => {
|
|
84
|
+
const sw = root.querySelector<HTMLButtonElement>('.ptc__switch');
|
|
85
|
+
const live = root.querySelector('.ptc__live');
|
|
86
|
+
sw?.addEventListener('click', () => {
|
|
87
|
+
const yearly = sw.getAttribute('aria-checked') !== 'true';
|
|
88
|
+
sw.setAttribute('aria-checked', String(yearly));
|
|
89
|
+
root.dataset.period = yearly ? 'yearly' : 'monthly';
|
|
90
|
+
root.querySelectorAll<HTMLElement>('.ptc__amount').forEach((el) => {
|
|
91
|
+
el.textContent = (yearly ? el.dataset.yearly : el.dataset.monthly) || '';
|
|
92
|
+
});
|
|
93
|
+
if (live) live.textContent = yearly ? 'Showing yearly prices' : 'Showing monthly prices';
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
</script>
|
|
97
|
+
|
|
98
|
+
<style>
|
|
99
|
+
.ptc {
|
|
100
|
+
--ptc-py: 5.5rem;
|
|
101
|
+
padding: var(--ptc-py) var(--sp-6, 1.5rem);
|
|
102
|
+
background: radial-gradient(ellipse 60% 40% at 50% 0%, var(--c-primary-glow, color-mix(in srgb, var(--c-primary, #b8860b) 10%, transparent)), transparent 70%), var(--c-bg, #050505);
|
|
103
|
+
}
|
|
104
|
+
.ptc--sm { --ptc-py: 3.5rem; }
|
|
105
|
+
.ptc--lg { --ptc-py: 7.5rem; }
|
|
106
|
+
.ptc__inner { max-width: 1120px; margin: 0 auto; }
|
|
107
|
+
.ptc__head { text-align: center; margin-bottom: 3rem; }
|
|
108
|
+
.ptc__title { margin: 0 0 0.75rem; font-size: clamp(1.9rem, 4vw, 2.75rem); font-weight: 800; letter-spacing: -0.03em; color: var(--c-text-1, #fff); }
|
|
109
|
+
.ptc__subtitle { margin: 0 0 2rem; font-size: 1.0625rem; color: var(--c-text-2, #a3a3a3); }
|
|
110
|
+
.ptc__toggle { display: inline-flex; align-items: center; gap: 0.85rem; font-size: 0.9375rem; color: var(--c-text-2, #a3a3a3); }
|
|
111
|
+
.ptc__switch {
|
|
112
|
+
position: relative;
|
|
113
|
+
width: 52px;
|
|
114
|
+
height: 30px;
|
|
115
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.15);
|
|
116
|
+
border-radius: 999px;
|
|
117
|
+
background: rgb(var(--ink-rgb, 255 255 255) / 0.08);
|
|
118
|
+
cursor: pointer;
|
|
119
|
+
transition: background 0.25s ease;
|
|
120
|
+
}
|
|
121
|
+
.ptc__switch::after { content: ''; position: absolute; inset: -8px; }
|
|
122
|
+
.ptc__switch[aria-checked='true'] { background: var(--c-primary, #b8860b); border-color: transparent; }
|
|
123
|
+
.ptc__switch:focus-visible { outline: 2px solid var(--c-primary-light, #d4a017); outline-offset: 3px; }
|
|
124
|
+
.ptc__knob { position: absolute; top: 3px; left: 3px; width: 22px; height: 22px; border-radius: 50%; background: #fff; transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1); }
|
|
125
|
+
.ptc__switch[aria-checked='true'] .ptc__knob { transform: translateX(22px); }
|
|
126
|
+
[data-period='monthly'] .ptc__period:first-child,
|
|
127
|
+
[data-period='yearly'] .ptc__period:last-child { color: var(--c-text-1, #fff); }
|
|
128
|
+
.ptc__save { margin-left: 0.35rem; padding: 0.15rem 0.5rem; border-radius: 999px; background: rgba(52, 195, 143, 0.15); color: #7ee2b8; font-size: 0.75rem; font-weight: 650; }
|
|
129
|
+
|
|
130
|
+
.ptc__grid { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.25rem; align-items: stretch; }
|
|
131
|
+
.ptc__card {
|
|
132
|
+
position: relative;
|
|
133
|
+
display: flex;
|
|
134
|
+
flex-direction: column;
|
|
135
|
+
padding: 2rem;
|
|
136
|
+
border-radius: var(--r-xl, 24px);
|
|
137
|
+
}
|
|
138
|
+
.ptc--glass .ptc__card { background: linear-gradient(160deg, rgb(var(--ink-rgb, 255 255 255) / 0.05), rgb(var(--ink-rgb, 255 255 255) / 0.015)); border: 1px solid var(--c-border, rgb(var(--ink-rgb, 255 255 255) / 0.07)); backdrop-filter: blur(12px); }
|
|
139
|
+
.ptc--solid .ptc__card { background: var(--c-bg-2, #111); border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.06); }
|
|
140
|
+
.ptc--outline .ptc__card { border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.12); }
|
|
141
|
+
.ptc__card--featured { border-color: color-mix(in srgb, var(--c-primary-light, #d4a017) 55%, transparent) !important; box-shadow: 0 30px 80px -30px color-mix(in srgb, var(--c-primary-light, #d4a017) 35%, transparent); }
|
|
142
|
+
.ptc__ribbon { position: absolute; top: -12px; left: 2rem; padding: 0.25rem 0.75rem; border-radius: 999px; background: var(--c-primary-light, #d4a017); color: var(--c-on-primary, #0a0a0a); font-size: 0.75rem; font-weight: 700; }
|
|
143
|
+
.ptc__name { margin: 0 0 0.35rem; font-size: 1.125rem; font-weight: 650; color: var(--c-text-1, #fff); }
|
|
144
|
+
.ptc__desc { margin: 0 0 1.5rem; font-size: 0.9rem; color: var(--c-text-2, #a3a3a3); }
|
|
145
|
+
.ptc__price { display: flex; align-items: baseline; gap: 0.4rem; margin: 0 0 1.5rem; }
|
|
146
|
+
.ptc__amount { font-size: 3rem; font-weight: 800; letter-spacing: -0.04em; color: var(--c-text-1, #fff); font-variant-numeric: tabular-nums; line-height: 1; }
|
|
147
|
+
.ptc__per { font-size: 0.875rem; color: var(--c-text-3, #8a8a8a); }
|
|
148
|
+
.ptc__billed { display: none; }
|
|
149
|
+
[data-period='yearly'] .ptc__billed { display: inline; }
|
|
150
|
+
.ptc__cta {
|
|
151
|
+
display: inline-flex;
|
|
152
|
+
align-items: center;
|
|
153
|
+
justify-content: center;
|
|
154
|
+
min-height: 48px;
|
|
155
|
+
border-radius: var(--r-md, 12px);
|
|
156
|
+
border: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.14);
|
|
157
|
+
color: var(--c-text-1, #fff);
|
|
158
|
+
font-weight: 650;
|
|
159
|
+
text-decoration: none;
|
|
160
|
+
transition: background 0.2s ease, border-color 0.2s ease;
|
|
161
|
+
}
|
|
162
|
+
.ptc__cta:hover { border-color: rgb(var(--ink-rgb, 255 255 255) / 0.3); color: var(--c-text-1, #fff); }
|
|
163
|
+
.ptc__card--featured .ptc__cta { background: var(--c-primary-light, #d4a017); color: var(--c-on-primary, #0a0a0a); border-color: transparent; }
|
|
164
|
+
.ptc__card--featured .ptc__cta:hover { background: var(--c-accent, #fef3c7); color: var(--c-on-primary, #0a0a0a); }
|
|
165
|
+
.ptc__cta:focus-visible { outline: 2px solid var(--c-primary-light, #d4a017); outline-offset: 3px; }
|
|
166
|
+
.ptc__features { list-style: none; margin: 1.75rem 0 0; padding: 1.5rem 0 0; border-top: 1px solid rgb(var(--ink-rgb, 255 255 255) / 0.07); display: grid; gap: 0.7rem; }
|
|
167
|
+
.ptc__features li { display: flex; align-items: center; gap: 0.6rem; font-size: 0.9rem; color: var(--c-text-1, #fff); }
|
|
168
|
+
.ptc__features svg { color: var(--c-primary-light, #d4a017); flex-shrink: 0; }
|
|
169
|
+
.ptc__live { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
|
|
170
|
+
@media (prefers-reduced-motion: reduce) { .ptc__knob, .ptc__switch { transition: none; } }
|
|
171
|
+
</style>
|