CTA .mv-cta

Call to Action im Editorial-Stil: ein Band zwischen zwei Haarlinien mit der Überschrift links und Details rechts, eine stets dunkle Tintenfläche oder ein Newsletter-Panel mit Inline-Formular und Status-Feedback.

KategorieBlöcke
TypBlock (fertige Sektion) (.mv-cta)
Statusstabil
Installiert auchbutton, dot-pattern, input
Keywordscta, call to action, banner, newsletter, waitlist, signup, landing, editorial

When to use

  • A landing page needs a restrained closing call to action with headline and details side by side
  • A dark ink slab should break the page rhythm before the footer without animated effects
  • A newsletter or waitlist signup needs an inline form with success or error status

Avoid when

  • The call to action is the first thing visitors see at the top of the page → use Hero instead

Installation

node scripts/add.mjs cta --out ./src/marvelous

KI-Agent mit dem MCP-Server von Marvelous UI: install_components({ slugs: ["cta"], target_dir: "<absolute path>/src/marvelous", framework: "react" }).

Kopierte Dateien (inklusive Abhängigkeiten): tokens/tokens.css, core/base.css, components/cta/cta.css, components/button/button.css, core/canvas.js, core/element.js, core/motion.js, core/pointer.js, components/dot-pattern/dot-pattern.css, components/dot-pattern/dot-pattern.js, components/input/input.css.

Verwendung

Referenz-Markup zum Starten und Anpassen mit Attributen, data-* und CSS-Variablen:

<div id="cta-demo" style="background:var(--mv-bg)">
  <!-- Band (default) -->
  <section class="mv-cta" aria-labelledby="cta-b-title">
    <div class="mv-cta-inner">
      <div class="mv-cta-panel">
        <p class="mv-cta-eyebrow">Ready when you are</p>
        <h2 class="mv-cta-title" id="cta-b-title">Close September <span class="mv-cta-muted">in Ledgerline.</span></h2>
        <p class="mv-cta-text">Connect your bank feeds this afternoon and run your next month-end on a single screen. Our team migrates your checklist for you.</p>
        <div class="mv-cta-actions">
          <a class="mv-button" data-size="lg" href="#cta-demo">Start a free trial</a>
          <a class="mv-button" data-size="lg" data-variant="outline" href="#cta-demo">Book a demo</a>
        </div>
        <p class="mv-cta-note">
          <span><svg 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>30 days free</span>
          <span><svg 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>No card required</span>
          <span><svg 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>Free migration</span>
        </p>
      </div>
    </div>
  </section>

  <!-- Ink -->
  <section class="mv-cta" data-variant="ink" aria-labelledby="cta-i-title">
    <div class="mv-cta-inner" style="padding-top:0">
      <div class="mv-cta-panel">
        <div class="mv-cta-bg" aria-hidden="true">
          <div class="mv-dot-pattern" data-fill style="--mv-dot-pattern-mask: radial-gradient(ellipse 55% 90% at 100% 100%, #000 10%, transparent 70%)"></div>
        </div>
        <p class="mv-cta-eyebrow">For controllers &amp; CFOs</p>
        <h2 class="mv-cta-title" id="cta-i-title">Your auditor will <span class="mv-cta-muted">thank you.</span></h2>
        <p class="mv-cta-text">Give them a read-only link to every match, approval and journal of the year: signed, timestamped and exportable in one click.</p>
        <div class="mv-cta-actions">
          <a class="mv-button" data-size="lg" href="#cta-demo">Talk to a specialist</a>
          <a class="mv-button" data-size="lg" data-variant="ghost" href="#cta-demo">Security →</a>
        </div>
        <p class="mv-cta-note">SOC 2 Type II · ISO 27001 · GDPR, hosted in the EU</p>
      </div>
    </div>
  </section>

  <!-- Newsletter -->
  <section class="mv-cta" data-variant="newsletter" aria-labelledby="cta-n-title">
    <div class="mv-cta-inner" style="padding-top:0">
      <div class="mv-cta-panel">
        <p class="mv-cta-eyebrow">The Close Notes</p>
        <h2 class="mv-cta-title" id="cta-n-title">One month-end playbook, <span class="mv-cta-muted">every other Tuesday.</span></h2>
        <p class="mv-cta-text">Checklists, accrual templates and war stories from 21,000 finance leads. A four-minute read, never a sales pitch.</p>
        <form class="mv-cta-form" id="cta-news" novalidate>
          <label class="mv-sr-only" for="cta-email">Work email</label>
          <input class="mv-input" data-size="lg" id="cta-email" type="email" placeholder="[email protected]" autocomplete="email" aria-describedby="cta-news-status">
          <button class="mv-button" data-size="lg" type="submit">Subscribe</button>
        </form>
        <p class="mv-cta-note">Unsubscribe in one click. We never share your address.</p>
        <p class="mv-cta-status" id="cta-news-status" role="status" aria-live="polite"></p>
      </div>
    </div>
  </section>

  <script type="module">
    const form = document.querySelector("#cta-news");
    const status = document.querySelector("#cta-news-status");
    const input = form?.querySelector("input");
    const seen = new Set();
    let timer;
    const say = (state, text) => {
      clearTimeout(timer);
      status.dataset.state = state;
      status.textContent = text;
      timer = setTimeout(() => { status.textContent = ""; delete status.dataset.state; }, 5000);
    };
    form?.addEventListener("submit", (e) => {
      e.preventDefault();
      const email = input.value.trim().toLowerCase();
      if (!email) return;
      if (!input.checkValidity()) return say("error", "That address doesn’t look right. Check for a typo.");
      if (seen.has(email)) return say("error", "You’re already subscribed with this address.");
      seen.add(email);
      input.value = "";
      say("success", "Subscribed. The next issue lands on Tuesday.");
    });
  </script>
</div>

API

Attributes

NameTypDefaultDescription
data-variantband | ink | newsletterbandband (default, or no attribute): open layout between two hairlines; ink: dark slab (color-scheme: dark) in both themes, the eyebrow sits on its own rule; newsletter: quiet bordered panel, form on the right. All switch to title | details columns from 52rem.

Content structure

NameDescription
.mv-cta-panelPanel: optional -bg (decorative layer), -eyebrow, -title (with -muted), -text, -actions or -form, -note, -status.
.mv-cta-formInline field + button; the button goes full width in containers under 26rem.
.mv-cta-statusForm feedback (role="status"), hidden when empty; data-state="success | error" colors it.
.mv-cta-noteReassurance line; use <span> elements with an icon for a list.

CSS classes

NameDescription
mv-ctaRoot section, mv-cta query container.

CSS variables

NameDefaultDescription
--mv-cta-panel-bgtransparent (ink: near-black, newsletter: var(--mv-bg-subtle))Panel background.
--mv-cta-rulevar(--mv-border-strong)Band hairlines.
--mv-cta-max72remMax width.
--mv-cta-bgtransparentSection background.

Accessibility

Section labeled by its title. The decorative layer is aria-hidden. The form has a visually hidden label, a native email field and a polite live status region linked with aria-describedby; errors are spelled out in text. The ink panel keeps its contrast in both themes.

Diese Seite wurde mit KI übersetzt. Übersetzungsfehler melden