npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xenterprises/nuxt-x-cards

v0.1.2

Published

A premium card component library for Nuxt 4 with cinematic image filters, warm surfaces, and accessible design.

Readme

nuxt-x-cards

A premium card component library for Nuxt 4 with cinematic image filters, warm surfaces, and accessible design.

Built on Nuxt UI v4 and Tailwind CSS v4. Inspired by Oura Ring and Rivian visual identities.


Quick Start

Install the layer in your Nuxt 4 project:

# From git (recommended during development)
pnpm add nuxt-x-cards@github:your-org/nuxt-x-cards

Add to your nuxt.config.ts:

export default defineNuxtConfig({
  extends: ['nuxt-x-cards']
})

All components, CSS utilities, and fonts are now available in your app.


Configuration

Customize the design system via app.config.ts under the x.cards namespace. Every key has a sensible default — override only what you need.

// app.config.ts
export default defineAppConfig({
  x: {
    cards: {
      colors: {
        primary: 'blue',             // your Tailwind palette name
        accents: { gold: '#FF6B00' } // override just the gold accent
      },
      fonts: {
        sans: "'Geist', system-ui, sans-serif",
        googleFontsUrl: 'https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700&display=swap'
      },
      brand: {
        appName: 'My App',
        logoIcon: 'i-lucide-zap'
      }
    }
  }
})

Full Config Reference

| Key | Type | Default | Description | |---|---|---|---| | colors.primary | string | 'cream' | Tailwind palette name for primary surfaces | | colors.neutral | string | 'olive' | Tailwind palette name for text and borders | | colors.accents.gold | string | '#FFAC00' | Primary accent (ratings, CTAs, highlights) | | colors.accents.goldHover | string | '#E69B00' | Gold hover state | | colors.accents.blue | string | '#8BA8BD' | Secondary cool accent | | colors.accents.green | string | '#1BC651' | Success/positive accent | | fonts.sans | string | 'Inter', ... | Sans-serif font stack | | fonts.serif | string | 'Playfair Display', ... | Serif font stack (italic accents) | | fonts.display | string | 'Inter', ... | Display font stack (large headings) | | fonts.googleFontsUrl | string | Google Fonts URL | Stylesheet URL for web fonts | | radius.card | string | '0.75rem' | Card corner radius (12px) | | radius.panel | string | '1.5rem' | Panel corner radius (24px) | | radius.pill | string | '9999px' | Pill/button radius | | spacing.baseUnit | number | 4 | Base grid unit in px | | defaults.filter | string | 'cinematic' | Default image filter for cards | | defaults.overlay | string | 'bottom-blur' | Default gradient overlay | | defaults.mediaAspectRatio | string | 'landscape' | Default XCardMedia aspect ratio | | defaults.productAspectRatio | string | 'product' | Default XCardProduct aspect ratio | | brand.appName | string | 'nuxt-x-cards' | App name in footer/SEO | | brand.logoIcon | string | 'i-lucide-square-x' | Iconify icon for logo |

Accessing Config in Components

Use the auto-imported useXCards() composable:

<script setup>
const xCards = useXCards()
// xCards.colors.primary → 'cream'
// xCards.defaults.filter → 'cinematic'
</script>

Color Customization

The layer ships with two custom palettes defined in CSS (@theme static):

  • Cream (primary) — warm Oura-inspired surfaces
  • Olive (neutral) — warm Rivian charcoal tones

Using Built-in Palettes

Set colors.primary and colors.neutral in your config. These must match palette names defined in your CSS @theme static block.

Creating Custom Palettes

To use your own colors, create a CSS file with your palette and import it:

/* assets/css/my-theme.css */
@theme static {
  --color-ocean-50: #F0F9FF;
  --color-ocean-100: #E0F2FE;
  /* ... shades 200-950 ... */
  --color-ocean-950: #0C1D29;
}

Then set:

// app.config.ts
x: {
  cards: {
    colors: { primary: 'ocean' }
  }
}

Note: The @theme static block is resolved at build time. The config values tell components which palette name to reference in utility classes (e.g., text-primary-200), but the actual hex values come from CSS.

Accent Colors

Accent colors (gold, blue, green) are defined as standalone CSS custom properties (--color-accent-gold, etc.) in the layer's CSS. Override them in your own CSS:

@theme static {
  --color-accent-gold: #FF6B00;
  --color-accent-gold-hover: #E05A00;
}

Font Customization

Fonts are configured in three parts that must stay in sync:

  1. fonts.sans / fonts.serif — CSS font-family stacks
  2. fonts.googleFontsUrl — URL that loads the web fonts
  3. CSS @theme static--font-sans, --font-serif, --font-display

To change fonts:

// app.config.ts
x: {
  cards: {
    fonts: {
      sans: "'Geist', system-ui, sans-serif",
      serif: "'Lora', 'Georgia', serif",
      googleFontsUrl: 'https://fonts.googleapis.com/css2?family=Geist:wght@300;400;500;600;700&family=Lora:ital,wght@0,400;0,700;1,400&display=swap'
    }
  }
}

And override the CSS custom properties:

@theme static {
  --font-sans: 'Geist', system-ui, sans-serif;
  --font-serif: 'Lora', 'Georgia', serif;
}

Set googleFontsUrl to an empty string to disable Google Fonts loading (for self-hosted fonts).


Components

XCardHeroFullscreen

Full-viewport hero with cinematic overlay and optional CTAs.

| Prop | Type | Default | Description | |---|---|---|---| | title | string | required | Main heading | | titleAccent | string | — | Italic serif phrase within heading | | subtitle | string | — | Subheading text | | pretitle | string | — | Section label above heading | | imageUrl | string | required | Background image URL | | imageAlt | string | — | Alt text | | theme | 'dark' \| 'light' | 'dark' | Text color scheme | | filter | string | config default | CSS image filter | | overlay | string | config default | Gradient overlay | | primaryCta | { label, to } | — | Primary button | | secondaryCta | { label, to } | — | Secondary button | | height | 'full' \| 'tall' \| 'medium' | 'full' | Viewport height |

XCardHeroSplit

Split-layout hero with image on one side, text on the other.

| Prop | Type | Default | Description | |---|---|---|---| | title | string | required | Main heading | | titleAccent | string | — | Italic serif phrase | | description | string | — | Body text | | pretitle | string | — | Section label | | imageUrl | string | required | Image URL | | imageAlt | string | — | Alt text | | variant | 'left-image' \| 'right-image' | 'left-image' | Image position | | filter | string | config default | CSS image filter | | cta | { label, to } | — | CTA button | | theme | 'dark' \| 'light' | 'light' | Color scheme |

XCardMedia

Immersive media card with full-bleed image and text overlay.

| Prop | Type | Default | Description | |---|---|---|---| | title | string | required | Heading | | description | string | — | Body text | | imageUrl | string | required | Image URL | | imageAlt | string | — | Alt text | | filter | string | config default | CSS image filter | | overlay | string | config default | Gradient overlay | | cta | { label, to } | — | CTA button | | aspectRatio | 'cinematic' \| 'landscape' \| 'square' \| 'portrait' | config default | Aspect ratio | | size | 'sm' \| 'md' \| 'lg' | 'md' | Padding scale |

XCardProduct

Product showcase with color swatches and image switching.

| Prop | Type | Default | Description | |---|---|---|---| | title | string | required | Product name | | description | string | — | Product description | | price | string | — | Price display | | imageUrl | string | required | Default image | | imageAlt | string | — | Alt text | | badge | string | — | Badge text (e.g., "New") | | colors | Array<{ name, hex, imageUrl? }> | — | Color swatches | | cta | { label, to } | — | CTA button | | aspectRatio | 'square' \| 'product' \| 'portrait' \| 'landscape' | config default | Aspect ratio |

XCardFeature

Versatile feature card with icon, stat, or image variants.

| Prop | Type | Default | Description | |---|---|---|---| | title | string | required | Feature name | | description | string | — | Feature description | | icon | string | — | Iconify icon name | | imageUrl | string | — | Feature image | | stat | { value, label } | — | Stat display | | variant | 'default' \| 'elevated' \| 'bordered' \| 'glass' | 'default' | Card style |

XCardTestimonial

Story-driven testimonial with lifestyle imagery and serif quotes.

| Prop | Type | Default | Description | |---|---|---|---| | quote | string | required | Testimonial text | | author | string | required | Author name | | role | string | — | Author role/title | | imageUrl | string | — | Lifestyle image | | imageAlt | string | — | Alt text |

XCardTeam

Team member card with portrait and social links.

| Prop | Type | Default | Description | |---|---|---|---| | name | string | required | Person's name | | role | string | required | Job title | | bio | string | — | Short bio | | imageUrl | string | required | Portrait photo | | imageAlt | string | — | Alt text | | socials | Array<{ icon, to, label }> | — | Social links |

XCardPricing

Pricing tier card with feature list and optional highlighting.

| Prop | Type | Default | Description | |---|---|---|---| | title | string | required | Plan name | | description | string | — | Plan description | | price | string | required | Price display | | period | string | — | Billing period | | features | string[] | [] | Feature list | | cta | { label, to } | — | CTA button | | highlighted | boolean | false | Dark inverted styling | | badge | string | — | Badge text |

XCardComparison

Feature comparison table with highlighted "ours" column.

| Prop | Type | Default | Description | |---|---|---|---| | title | string | — | Section heading | | description | string | — | Section description | | features | Array<{ name, ours, theirs }> | required | Feature rows (boolean or string) | | ourLabel | string | 'Us' | Our column header | | theirLabel | string | 'Them' | Their column header | | ourLogo | string | — | Iconify icon for our brand | | theirLogo | string | — | Iconify icon for competitor |

XCardReview

Multi-source review card with star ratings.

| Prop | Type | Default | Description | |---|---|---|---| | reviewText | string | required | Review body | | reviewerName | string | required | Reviewer name | | reviewerAvatar | string | — | Avatar image URL | | rating | 1-5 | required | Star rating | | source | 'google' \| 'yelp' \| 'trustpilot' \| 'appstore' \| 'generic' | 'generic' | Review source | | date | string | — | Review date | | aspectRatio | 'auto' \| 'square' \| '4:3' \| '3:4' \| '16:9' \| '9:16' | 'auto' | Card aspect ratio |

XCardImageFilter

Filter showcase card with before/after hover effect.

| Prop | Type | Default | Description | |---|---|---|---| | imageUrl | string | required | Image URL | | imageAlt | string | — | Alt text | | filter | string | required | Filter name | | title | string | — | Filter display name | | description | string | — | Filter description | | cssValues | string | — | CSS filter values display |

XCardGrid

Responsive grid layout wrapper.

| Prop | Type | Default | Description | |---|---|---|---| | columns | 1 \| 2 \| 3 \| 4 | 3 | Column count | | gap | 'sm' \| 'md' \| 'lg' | 'md' | Gap size |

SectionHeading

Section intro with optional label and serif accent.

| Prop | Type | Default | Description | |---|---|---|---| | title | string | required | Section heading | | titleAccent | string | — | Italic serif phrase | | description | string | — | Section description | | label | string | — | Uppercase label above heading | | align | 'left' \| 'center' | 'left' | Text alignment |


CSS Utilities

Image Filters

| Class | Effect | |---|---| | .filter-x-cinematic | saturate(0.7) contrast(1.15) brightness(0.95) | | .filter-x-moody | saturate(0.5) contrast(1.25) brightness(0.85) sepia(0.1) | | .filter-x-golden | saturate(0.65) contrast(1.1) brightness(1.05) sepia(0.15) | | .filter-x-cool | saturate(0.6) contrast(1.2) brightness(0.9) hue-rotate(10deg) | | .filter-x-dramatic | saturate(0.4) contrast(1.35) brightness(0.8) | | .filter-x-clean | saturate(1.05) contrast(1.05) brightness(1.02) | | .filter-x-product | saturate(0.95) contrast(1.1) brightness(1.08) | | .filter-x-warm | saturate(0.9) contrast(1.05) brightness(1.05) sepia(0.08) |

Gradient Overlays

| Class | Use | |---|---| | .overlay-bottom | Strong bottom gradient for text | | .overlay-bottom-fade | Smooth 5-stop bottom fade | | .overlay-bottom-blur | Gradient + backdrop blur with mask | | .overlay-top | Top gradient for header text | | .overlay-full | Solid semi-transparent overlay | | .overlay-cinematic | Rivian-style bottom-heavy gradient | | .overlay-oura | Oura-style gradient |

Blur Panels

| Class | Use | |---|---| | .text-blur-panel | Dark frosted glass for white text | | .text-blur-panel-heavy | Maximum readability on busy images | | .text-blur-panel-light | Light frosted glass for dark text | | .blur-badge | Inline pill-shaped blur badge |

Typography

| Class | Description | |---|---| | .heading-tight | Tight letter-spacing (-0.03em), condensed line-height | | .body-tight | Slight letter-spacing tightening (-0.01em) | | .serif-accent | Italic Playfair Display for emotional phrases | | .section-label | Uppercase bold 12px label | | .text-heading | Contrast-safe heading color (13.6:1) | | .text-body | Contrast-safe body color (6.6:1) | | .text-secondary | Contrast-safe secondary color (4.8:1) | | .text-caption | Caption color (3.5:1, bold/large only) |

Button Variants

| Class | Style | |---|---| | .btn-oura-dark | Dark pill button, cream text | | .btn-oura-olive | Olive pill button, cream text | | .btn-oura-light | Cream pill button, dark text | | .btn-oura-outline | Outline pill, inverts on hover | | .btn-rivian-primary | Gold rectangular CTA, uppercase | | .btn-rivian-text | Underlined text link |

Card Animations

| Class | Effect | |---|---| | .card-zoom-out | Image starts scaled 1.05, zooms to 1 on hover | | .card-zoom-in | Image starts at 1, zooms to 1.05 on hover | | .card-text-reveal | Text fades up from 85% opacity on hover | | .fade-in-up | Scroll reveal: fade in + slide up 24px |

Surfaces & Gradients

| Class | Description | |---|---| | .bg-surface | Primary-200 background | | .bg-surface-light | Primary-100 background | | .bg-surface-dark | Primary-300 background | | .bg-rivian-dark | #151515 dark background | | .bg-gradient-oura-warm | Radial warm gradient | | .bg-gradient-oura-cool | Radial cool gradient | | .bg-gradient-oura-hero | Combined warm+cool hero gradient |

Aspect Ratios

| Class | Ratio | |---|---| | .aspect-cinematic | 21:9 | | .aspect-landscape | 16:9 | | .aspect-portrait | 2:3 | | .aspect-product | 10:7 |


Image Prompt Templates

The prompts/ directory contains base photography descriptions for generating consistent imagery with AI image models (Nano Banana 2 or similar).

| Template | Style | Paired Filter | |---|---|---| | hero-lifestyle | Cinematic outdoor adventure | .filter-x-cinematic | | product-studio | Clean studio photography | .filter-x-product | | portrait-team | Natural light portraits | .filter-x-warm | | testimonial-lifestyle | Candid golden hour | .filter-x-golden | | media-editorial | Moody editorial | .filter-x-moody | | food-wellness | Bright wellness | .filter-x-clean |

Each file includes camera simulation, lighting setup, color grading notes, a copy-paste base prompt, and variation modifiers.


Design System

Color Palettes

Cream (Primary)

| Shade | Hex | Use | |---|---|---| | 50 | #FDFCFA | Lightest surface | | 100 | #FAF8F4 | Light surface | | 200 | #F7F1E8 | Default surface / body bg | | 300 | #EDE4D5 | Dark surface | | 400 | #DDD0BB | Muted accent | | 500 | #C9B896 | Disabled state | | 600 | #B5A07A | Secondary text | | 700 | #9A8362 | Body text | | 800 | #7D6A4F | Strong text | | 900 | #655543 | Heading text | | 950 | #2D261E | Darkest |

Olive (Neutral)

| Shade | Hex | Use | |---|---|---| | 50 | #F7F6F4 | Lightest | | 100 | #EDECEA | Light border | | 200 | #D3D1CE | Border | | 300 | #B5B2AD | Muted text | | 400 | #918D86 | Placeholder | | 500 | #74716A | Caption text | | 600 | #5C5952 | Secondary text | | 700 | #4A4741 | Body text | | 800 | #3A3834 | Strong text | | 900 | #1E2427 | Dark surface | | 950 | #1C1B1A | Darkest surface |

Typography Scale

All line-heights are multiples of the 4px base grid:

| Step | Size | Line-height | Grid | |---|---|---|---| | xs | 12px | 16px | 4 x 4 | | sm | 14px | 20px | 4 x 5 | | base | 16px | 24px | 4 x 6 | | lg | 20px | 28px | 4 x 7 | | xl | 24px | 32px | 4 x 8 | | 2xl | 32px | 40px | 4 x 10 | | 3xl | 40px | 48px | 4 x 12 | | 4xl | 48px | 52px | 4 x 13 | | 5xl | 64px | 68px | 4 x 17 |

WCAG Contrast Ratios

All text-on-surface combinations meet WCAG AA:

| Combination | Ratio | Standard | |---|---|---| | neutral-950 on primary-200 | 13.6:1 | AAA (headings) | | neutral-700 on primary-200 | 6.6:1 | AA (body) | | neutral-600 on primary-200 | 4.8:1 | AA (body) | | neutral-500 on primary-200 | 3.5:1 | AA (large/bold) | | primary-100 on neutral-900 | 14.5:1 | AAA (inverted) |


Demo Pages

Run the layer standalone to browse all demo pages:

pnpm dev

Routes: /, /hero-cards, /product-cards, /feature-cards, /media-cards, /testimonial-cards, /review-cards, /pricing-cards, /comparison-cards, /team-cards, /image-filters


Dependencies

License

MIT