popup modal event booking tickets calendar overlay popup modal event booking tickets quantity calendar overlay event booking modal ticket purchase popup event registration dialog
Popup Event Booking
Fetch pattern JSON:
curl https://webspire.de/patterns/popup/event-booking.json event-booking.html
<!-- Modal overlay -->
<div class="fixed inset-0 z-50 flex items-center justify-center p-4" style="background-color: rgba(0,0,0,0.6); backdrop-filter: blur(4px);"> <!-- ws-ok -->
<!-- Modal card -->
<div class="ws-popup relative w-full max-w-lg overflow-hidden rounded-3xl shadow-2xl bg-[var(--ws-popup-bg)]" role="dialog" aria-modal="true" aria-labelledby="event-booking-title">
<!-- Close button -->
<button
class="absolute right-4 top-4 z-10 flex h-9 w-9 items-center justify-center rounded-full transition hover:opacity-70"
style="background-color: rgba(0,0,0,0.3); color: var(--ws-color-text-inverse);" <!-- ws-ok -->
aria-label="Close"
>
<svg class="h-4 w-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12"/></svg>
</button>
<!-- Event image / banner -->
<div class="aspect-video w-full" style="background: linear-gradient(135deg, var(--ws-color-accent), var(--ws-color-warning));">
<div class="flex h-full items-center justify-center">
<span class="text-sm font-medium text-white/60">Event banner image</span>
</div>
</div>
<!-- Content -->
<div class="p-6">
<!-- Event title -->
<h2 id="event-booking-title" class="text-xl font-bold tracking-tight text-[var(--ws-popup-text)]">
Webspire Design Sprint — Live Workshop
</h2>
<!-- Event detail chips -->
<div class="mt-4 flex flex-wrap gap-3">
<!-- Date -->
<span class="inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium bg-[var(--ws-color-surface-alt)] text-[var(--ws-popup-text-soft)]">
<svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/></svg>
April 15, 2026
</span>
<!-- Time -->
<span class="inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium bg-[var(--ws-color-surface-alt)] text-[var(--ws-popup-text-soft)]">
<svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
2:00 PM – 5:00 PM CET
</span>
<!-- Location -->
<span class="inline-flex items-center gap-1.5 rounded-full px-3 py-1 text-xs font-medium bg-[var(--ws-color-surface-alt)] text-[var(--ws-popup-text-soft)]">
<svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/><path stroke-linecap="round" stroke-linejoin="round" d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/></svg>
Online — Zoom
</span>
</div>
<!-- Description -->
<p class="mt-4 text-sm leading-relaxed text-[var(--ws-popup-text-soft)]">
A hands-on workshop covering the Webspire token system, MCP composition tools, and live pattern customisation. Bring your own project.
</p>
<!-- Divider -->
<div class="my-5 h-px bg-[var(--ws-popup-border)]"></div>
<!-- Ticket section -->
<div class="flex items-center justify-between gap-4">
<!-- Ticket type -->
<div class="flex-1">
<label class="mb-1.5 block text-xs font-semibold text-[var(--ws-popup-text)]" for="ticket-type">Ticket type</label>
<select
id="ticket-type"
class="w-full rounded-xl border px-3 py-2 text-sm border-[var(--ws-popup-border)] bg-[var(--ws-popup-bg)] text-[var(--ws-popup-text)]"
>
<option>Standard — €29</option>
<option>VIP with recording — €49</option>
<option>Team (3 seats) — €79</option>
</select>
</div>
<!-- Quantity selector -->
<div>
<label class="mb-1.5 block text-xs font-semibold text-[var(--ws-popup-text)]">Quantity</label>
<div class="flex items-center gap-2">
<button class="flex h-9 w-9 items-center justify-center rounded-xl border text-sm font-bold transition hover:opacity-70 border-[var(--ws-popup-border)] text-[var(--ws-popup-text)]" aria-label="Decrease quantity">−</button>
<span class="w-6 text-center text-sm font-semibold text-[var(--ws-popup-text)]">1</span>
<button class="flex h-9 w-9 items-center justify-center rounded-xl border text-sm font-bold transition hover:opacity-70 border-[var(--ws-popup-border)] text-[var(--ws-popup-text)]" aria-label="Increase quantity">+</button>
</div>
</div>
</div>
<!-- Total price -->
<div class="mt-4 flex items-center justify-between rounded-xl p-3 bg-[var(--ws-color-surface-alt)]">
<span class="text-sm font-medium text-[var(--ws-popup-text-soft)]">Total</span>
<span class="text-lg font-bold text-[var(--ws-popup-text)]">€29.00</span>
</div>
<!-- Action buttons -->
<div class="mt-5 flex flex-col gap-3 sm:flex-row">
<a href="#" class="flex flex-1 items-center justify-center rounded-xl px-5 py-3 text-sm font-semibold transition hover:opacity-90 bg-[var(--ws-color-accent)] text-white">
Book tickets
</a>
<a href="#" class="flex flex-1 items-center justify-center rounded-xl border px-5 py-3 text-sm font-semibold transition hover:opacity-80 border-[var(--ws-popup-border)] text-[var(--ws-popup-text)]">
Add to calendar
</a>
</div>
</div>
</div>
</div>
Details
Responsive Dark Mode Tailwind Only SSR Safe Copy & Paste
Stable Published
popupmodaleventbookingticketscalendaroverlay
Slots
| Name | Required | Description |
|---|---|---|
| image | No | Event banner image at top of card. |
| title | Yes | Event name heading. |
| details | Yes | Date, time, and location chips. |
| description | No | Short event description paragraph. |
| ticket-type | Yes | Ticket type dropdown selector. |
| quantity | Yes | Quantity increment/decrement control. |
| total | Yes | Total price display. |
| actions | Yes | Book tickets and Add to calendar buttons. |
Props
| Name | Type | Default | Description |
|---|---|---|---|
| price | number | 29 | Base ticket price for total calculation. |
| currency | string | € | Currency symbol. |
Static modal layout for event booking. The quantity selector and total price update require a small JavaScript handler — connect the +/- buttons to a counter and multiply by the selected ticket price. The role="dialog" and aria-modal="true" attributes are already in place for accessibility compliance.