nuxt-x-cards
nuxt-x-cards
Premium card component library for Nuxt 4. Used with nuxt-x-marketing under the Marketing page standard (prefer vertical cards for thumbs/grids; 0.3.x unlocked). Ships 12 auto-imported components covering heroes, features, media, product showcases, team members, reviews, testimonials, pricing, and comparison tables — all sharing a unified Oura/Rivian-inspired design language: warm neutral surfaces, cinematic image filters, 4px-grid spacing, and WCAG AA contrast.
0.2.5. Published. Same 0.2.4 product (CSS registration, no default webfonts, overlay).
Installation
npm install @xenterprises/nuxt-x-cards
Peer dependencies (install if your app doesn't already have them): nuxt ^4, vue ^3, @nuxt/ui ^4.6.1, @iconify-json/lucide, and @iconify-json/simple-icons.
What the consumer writes
The minimal consumer setup is an extends entry plus an optional app/app.config.ts with your brand overrides. No components, pages, or server code to write. All 12 XCard* components and the useXCards() composable are auto-imported. The layer registers xCards.css from nuxt.config.ts so overlays (including .overlay-cinematic), filters, and .serif-accent load from the package. It registers no pages, middleware, or server routes. Brands bring their own fonts. x.cards.fonts.googleFontsUrl defaults to an empty string, so the layer does not inject a Google Fonts stylesheet (no Inter + Playfair). Set a URL only if you want the optional plugin to load one.
// nuxt.config.ts
export default defineNuxtConfig({
extends: ["@xenterprises/nuxt-x-cards"],
});
// app/app.config.ts — must live in app/, not the project root
export default defineAppConfig({
x: {
cards: {
defaults: {
filter: "moody", // global image filter fallback for hero/media cards
},
brand: {
appName: "My Brand",
},
},
},
});
Then drop any XCard* component into a page:
<XCardHeroFullscreen
title="Built for speed"
image-url="/hero.jpg"
:primary-cta="{ label: 'Order Now', to: '/order' }"
/>
Every key under x.cards is optional — omit the whole app.config.ts and the layer falls back to its Oura/Rivian-inspired defaults (cream/olive palettes, cinematic filter, bottom-blur overlay). No environment variables are required — all configuration is via app.config.ts.
What the layer provides
12 components in five families, all auto-imported under the XCard prefix. Components fall back to useXCards() global defaults for filter, overlay, and aspect ratio unless overridden per instance.
HeroCards — above-the-fold hero sections
<XCardHeroFullscreen />— Full-viewport hero with gradient overlay, cinematic filter, and one or two CTAs<XCardHeroSplit />— Split two-column hero: image one side, editorial text the other, with hover zoom-in
FeatureCards — feature / benefit grids
<XCardFeature />— Multi-mode card supporting icon, full-bleed image, or large stat figure with four surface variants (default, elevated, bordered, glass)<XCardGrid />— Responsive 1/2/3/4-column CSS grid wrapper with 4px-grid gap tokens; slot-based, works with any XCard
MediaCards — full-bleed imagery
<XCardMedia />— Immersive full-bleed image card with gradient overlay, reveal animations, and configurable aspect ratio<XCardImageFilter />— Before/after filter showcase card with hover-to-reveal original; click/Enter/Space toggle for keyboard and touch users
ContentCards — social proof and people
<XCardProduct />— Product showcase card with color swatch switcher, image swap, andcolor-changeemit<XCardTeam />— Team member portrait card with role, bio, and ghost social-icon buttons<XCardReview />— Multi-source review card (Google, Yelp, Trustpilot, App Store, generic) with 5-star rating and avatar/initial fallback<XCardTestimonial />— Editorial testimonial card with split portrait + serif italic blockquote
PricingComparison — conversion blocks
<XCardPricing />— Pricing tier card with feature checklist, badge, and dark-inverted highlighted state<XCardComparison />— "Us vs Them" comparison table with boolean check/x or string values per row, dark-inverted "ours" column
Composables
useXCards()
Returns the merged layer configuration (consumer overrides deep-merged over defaults via defu). Use it to read design tokens in your own components.
const config = useXCards();
// config.colors.primary → "cream"
// config.defaults.filter → "cinematic"
// config.fonts.serif → "'Playfair Display', ..."
Returns XCardsConfig:
| Property | Type | Description |
|---|---|---|
colors.primary | string | Primary color name ("cream" default). |
colors.neutral | string | Neutral color name ("olive" default). |
colors.accents | object | { gold, goldHover, blue, green } hex values. |
fonts.sans | string | Sans-serif font stack. |
fonts.serif | string | Serif font stack (Playfair Display). |
fonts.display | string | Display font stack. |
fonts.googleFontsUrl | string | Optional stylesheet URL. Empty by default (no font injection). |
radius.card | string | Card border radius ('0.75rem'). |
radius.panel | string | Panel border radius ('1.5rem'). |
radius.pill | string | Pill/button border radius ('9999px'). |
spacing.baseUnit | number | Grid base unit in px (default 4). |
defaults.filter | string | Default image filter: "cinematic", "moody", "golden", "cool", "dramatic", "warm", "clean", "product", or "none". |
defaults.overlay | string | Default overlay style ('bottom-blur'). |
defaults.mediaAspectRatio | string | Default media aspect ratio ('landscape'). |
defaults.productAspectRatio | string | Default product aspect ratio ('product'). |
brand.appName | string | App name used in component titles ('nuxt-x-cards'). |
brand.logoIcon | string | Iconify icon class for the logo ('i-lucide-square-x'). |
Configuration
Override any token by adding an x.cards key to the consumer's app/app.config.ts:
// app/app.config.ts
export default defineAppConfig({
x: {
cards: {
colors: {
primary: "stone",
accents: {
gold: "#F5C518",
},
},
defaults: {
filter: "moody",
},
brand: {
appName: "My Brand",
logoIcon: "i-lucide-star",
},
},
},
});
Environment Variables
None required.
Minimal Usage Example
<template>
<!-- Hero section -->
<XCardHeroFullscreen
title="Built for speed"
subtitle="The fastest car we've ever made"
image-url="/hero.jpg"
filter="cinematic"
:primary-cta="{ label: 'Order Now', to: '/order' }"
:secondary-cta="{ label: 'Learn More', to: '/specs' }"
/>
<!-- Feature grid -->
<XCardGrid>
<XCardFeature
v-for="f in features"
:key="f.title"
:title="f.title"
:description="f.description"
:icon="f.icon"
/>
</XCardGrid>
<!-- Pricing -->
<XCardPricing
title="Pro"
price="$49"
period="/ month"
:features="['Unlimited projects', 'Priority support', 'API access']"
:highlighted="true"
:cta="{ label: 'Get started', to: '/signup' }"
/>
</template>
How It Works
Each component imports useXCards() to read the merged config for its design tokens. useXCards() calls useAppConfig() and reads appConfig.x.cards, then deep-merges it over the built-in defaults using defu — so consumers only need to override the keys they want to change. XCardImageFilter provides keyboard and touch accessibility: hover reveals the original, and click, Enter, and Space toggle the state for keyboard and touch users. All components use CSS custom properties driven by the design tokens so color swaps require no component changes. The layer registers no pages, middleware, or server routes. nuxt.config.ts registers xCards.css so overlays, filters, and .serif-accent load from the package. The optional fonts plugin injects x.cards.fonts.googleFontsUrl only when a consumer sets one. The default is empty. Brands bring their own fonts.
AI Context
package: "@xenterprises/nuxt-x-cards"
type: nuxt-layer
prefix: XCard
use-when: >
Adding premium card components to a Nuxt 4 project. Provides 12 auto-imported
XCard-prefixed components (heroes, feature grids, media, product showcases, team
members, reviews, testimonials, pricing, comparison) sharing a warm neutral /
cinematic design language. Configure design tokens via app.config.ts under x.cards.
No pages, middleware, or server routes are registered.
