Skip to content
Velocity X Docs
← All components

Newsletter — Card

Free · MIT

Standalone card-format newsletter opt-in with an icon badge and privacy microcopy.

Category
Forms
Framework
astro
Version
1.0.0
Peer deps
none

Install

bash
velocityx add newsletter-card

Free and MIT licensed — no account needed. The file lands under src/components/velocity/newsletter-card/ by default (override with --dest), and it's yours to edit from the moment it's written.

Demo

View the live demo on the showcase site ↗

Source

Pulled live from the registry — this is the exact file velocityx add newsletter-card writes into your project right now.

components/velocity/newsletter-card/NewsletterCard.astro

astro
---
//    VELOCITY COMPONENT · theming
// 
//    Colours here are Tailwind `primary-*` / `accent-*`, which resolve through
//    the Velocity preset. Out of the box they are a neutral indigo — NOT the
//    Aidxn brand — so this drops into your project without dragging our look in.
// 
//    ⚡ NOT USING VELOCITY? Run this once, in your project root:
// 
//          velocityx theme
// 
//    It writes velocity-preset.cjs + velocity-theme.css. Add the preset to your
//    tailwind.config, import the css, then set your whole brand in ONE place:
// 
//          :root {
//            --vx-brand: custom;
//            --vx-primary-600: 220 38 38;   <- your action colour
//            --vx-primary-700: 185 28 28;
//          }
// 
//    ⚠️  Raw RGB channels, space separated — NOT hex. `#DC2626` here silently
//        breaks every /opacity variant in the library (bg-primary-600/20 etc).
// 
//    Prefer not to install anything? Find-and-replace `primary-` with your own
//    scale name. Nothing else in this file depends on Velocity.
/**
 * NewsletterCard — a standalone card-format newsletter opt-in, for sidebars,
 * blog footers, or a dedicated section. Includes an icon badge, heading,
 * email field and a privacy microcopy line. Presentational only.
 */
export interface Props {
  action?: string;
  method?: string;
  eyebrow?: string;
  heading?: string;
  subheading?: string;
  submitLabel?: string;
  privacyNote?: string;
  className?: string;
}

const {
  action = '#',
  method = 'POST',
  eyebrow = 'Newsletter',
  heading = 'One email, every other Friday.',
  subheading = "The build notes, design decisions, and what's shipping next — no fluff.",
  submitLabel = 'Join the list',
  privacyNote = 'Unsubscribe any time. We never share your email.',
  className = '',
} = Astro.props;

const inputClass =
  'w-full rounded-xl border-2 border-primary-200 dark:border-primary-800 bg-white dark:bg-primary-950/60 px-4 py-3 text-sm font-medium text-primary-950 dark:text-white placeholder:text-primary-950/40 dark:placeholder:text-primary-300/40 outline-none transition focus:border-primary-500 focus:ring-4 focus:ring-primary-500/15';
---

<div class:list={['rounded-3xl border border-primary-500/15 bg-white/95 dark:bg-primary-950/60 backdrop-blur-sm p-6 sm:p-8 shadow-[0_8px_50px_rgba(0,0,0,0.08)] max-w-md', className]}>
  <span class="inline-flex h-11 w-11 items-center justify-center rounded-2xl bg-primary-500/10 dark:bg-primary-400/15 text-primary-600 dark:text-primary-300 mb-4">
    <svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.8">
      <path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0v.243a2.25 2.25 0 01-1.07 1.916l-7.5 4.615a2.25 2.25 0 01-2.36 0L3.32 8.91a2.25 2.25 0 01-1.07-1.916V6.75" />
    </svg>
  </span>

  <p class="h-eyebrow text-primary-600 dark:text-primary-400 mb-1.5">{eyebrow}</p>
  <h3 class="h-sub font-bold text-primary-950 dark:text-white">{heading}</h3>
  <p class="mt-2 body-md text-primary-950/60 dark:text-primary-200/60">{subheading}</p>

  <form action={action} method={method} class="mt-5 flex flex-col gap-3">
    <label for="nlc-email" class="sr-only">Email address</label>
    <input id="nlc-email" name="email" type="email" required autocomplete="email" placeholder="you@company.com" class={inputClass} />
    <button type="submit" class="btn btn-primary btn-block">{submitLabel}</button>
  </form>

  <p class="mt-3 body-sm text-primary-950/45 dark:text-primary-200/45">{privacyNote}</p>
</div>

Theming

Uses the shared primary-* / accent-* scale — see Theming if colours look unstyled after install.