Newsletter Signup

Email capture form for a mailing list.

Get the digest

One email a week, unsubscribe any time.

html

<form class="news news--inline">
  <div class="news__copy">
    <p class="news__heading">Get the digest</p>
    <p class="news__micro">One email a week, unsubscribe any time.</p>
  </div>
  <div class="news__field">
    <label for="news-email" class="news__label">Email address</label>
    <input id="news-email" type="email" name="email" placeholder="you@example.com" required />
    <button type="submit" style="background:#A8E6C1;">Subscribe</button>
  </div>
</form>
<style>
.news { font: 15px system-ui, sans-serif; color: #241430; display: flex; gap: 16px; padding: 20px; background: #FAF7F2; border: 1px solid #24143022; border-radius: 14px; max-width: 460px; }
.news--inline { flex-direction: row; align-items: center; }
.news--stacked { flex-direction: column; align-items: stretch; }
.news__heading { margin: 0 0 4px; font-weight: 700; font-size: 16px; }
.news__micro { margin: 0; font-size: 13px; color: #241430aa; }
.news__label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.news__field { display: flex; gap: 8px; }
.news--stacked .news__field { flex-direction: column; }
.news__field input { flex: 1; font: inherit; padding: 9px 12px; border: 1px solid #24143033; border-radius: 8px; min-width: 0; }
.news__field button { border: none; color: #241430; padding: 9px 18px; border-radius: 8px; font-weight: 700; cursor: pointer; white-space: nowrap; }
.news__field button:hover, .news__field button:focus-visible { opacity: .85; }
</style>

tailwind

<form class="news-tw news-tw--inline font-sans text-[15px] text-[#241430] flex gap-4 p-5 bg-[#FAF7F2] border border-[#24143022] rounded-2xl max-w-[460px]">
  <div>
    <p class="m-0 mb-1 font-bold text-base">Get the digest</p>
    <p class="m-0 text-[13px] text-[#241430]/65">One email a week, unsubscribe any time.</p>
  </div>
  <div class="news-tw__field flex gap-2">
    <label for="news-tw-email" class="sr-only">Email address</label>
    <input id="news-tw-email" type="email" name="email" placeholder="you@example.com" required class="flex-1 min-w-0 font-sans px-3 py-2 border border-[#24143033] rounded-lg" />
    <button type="submit" class="border-0 text-[#241430] px-4.5 py-2 rounded-lg font-bold cursor-pointer whitespace-nowrap hover:opacity-85" style="background:#A8E6C1;">Subscribe</button>
  </div>
</form>
<style>
.news-tw--inline { flex-direction: row; align-items: center; }
.news-tw--stacked { flex-direction: column; align-items: stretch; }
.news-tw--stacked .news-tw__field { flex-direction: column; }
</style>

react

export function NewsletterSignup({
  heading = "Get the digest",
  microcopy = "One email a week, unsubscribe any time.",
  layout = "inline",
  accent = "#A8E6C1",
}) {
  const stacked = layout === "stacked";
  return (
    <form style={{ font: "15px system-ui, sans-serif", color: "#241430", display: "flex", gap: 16, padding: 20,
      background: "#FAF7F2", border: "1px solid #24143022", borderRadius: 14, maxWidth: 460,
      flexDirection: stacked ? "column" : "row", alignItems: stacked ? "stretch" : "center" }}>
      <div>
        <p style={{ margin: "0 0 4px", fontWeight: 700, fontSize: 16 }}>{heading}</p>
        <p style={{ margin: 0, fontSize: 13, color: "#241430aa" }}>{microcopy}</p>
      </div>
      <div style={{ display: "flex", gap: 8, flexDirection: stacked ? "column" : "row" }}>
        <label htmlFor="news-email" style={{ position: "absolute", width: 1, height: 1, overflow: "hidden" }}>Email address</label>
        <input id="news-email" type="email" name="email" placeholder="you@example.com" required
          style={{ flex: 1, font: "inherit", padding: "9px 12px", border: "1px solid #24143033", borderRadius: 8, minWidth: 0 }} />
        <button type="submit" style={{ border: "none", color: "#241430", padding: "9px 18px", borderRadius: 8,
          fontWeight: 700, cursor: "pointer", whiteSpace: "nowrap", background: accent }}>Subscribe</button>
      </div>
    </form>
  );
}