Appointment confirmed
Your consultation is booked
Reference #APT-2048
We saved your appointment
Appointment details
- Date
- Time
- Format
- Video consultation
Practitioner
Taylor Smith
Design system consultant
€95 paid
Booking and appointment flow composed from date and time inputs, radio choices, summary cards, validation and confirmation feedback.
Group the date and time controls before the appointment format so the booking follows a predictable order. Keep the selected service, practitioner, duration and price visible in adjacent summary cards.
<form class="card shadow-sm" action="/appointments" method="post" aria-labelledby="appointment-booking-title">
<header class="card-header">
<h3 class="card-title" id="appointment-booking-title">Book a consultation</h3>
<p class="card-subtitle">Choose when and how you would like to meet.</p>
</header>
<div class="card-body grid gap-4">
<div class="col-12 col-lg-7 d-flex flex-column gap-3">
<div class="grid gap-3">
<div class="col-12 col-sm-6">
<label class="form-label is-required" for="booking-date">Date</label>
<input class="form-control" id="booking-date" name="date" type="date" min="2026-09-12" value="2026-09-18" required />
</div>
<div class="col-12 col-sm-6">
<label class="form-label is-required" for="booking-time">Time</label>
<input class="form-control" id="booking-time" name="time" type="time" min="09:00" max="16:30" step="1800" value="10:30" required />
</div>
</div>
<fieldset class="border border-0 p-0 m-0">
<legend class="form-label is-required">Appointment format</legend>
<div class="d-flex flex-column gap-2">
<div class="form-check border border-primary bg-primary bg-opacity-10 rounded p-3">
<input class="form-check-input" id="format-video" name="format" type="radio" value="video" checked required />
<label class="form-label" for="format-video"><strong>Video consultation</strong></label>
</div>
<div class="form-check border rounded p-3">
<input class="form-check-input" id="format-office" name="format" type="radio" value="office" required />
<label class="form-label" for="format-office"><strong>In person</strong></label>
</div>
</div>
</fieldset>
<div>
<label class="form-label is-required" for="booking-email">Confirmation email</label>
<input class="form-control" id="booking-email" name="email" type="email" autocomplete="email" required />
</div>
</div>
<aside class="col-12 col-lg-5 d-flex flex-column gap-3" aria-label="Appointment summary">
<section class="border rounded p-3" aria-labelledby="service-title">
<h4 id="service-title">Design system consultation</h4>
<p>With Taylor Smith · 45 minutes</p>
</section>
<section class="border rounded p-3" aria-labelledby="summary-title">
<h4 id="summary-title">Your appointment</h4>
<dl>
<div class="d-flex justify-content-between gap-3"><dt>Date</dt><dd><time datetime="2026-09-18">Sep 18, 2026</time></dd></div>
<div class="d-flex justify-content-between gap-3"><dt>Time</dt><dd><time datetime="10:30">10:30</time></dd></div>
<div class="d-flex justify-content-between gap-3"><dt>Total</dt><dd>€95</dd></div>
</dl>
</section>
</aside>
</div>
<footer class="card-footer d-flex gap-2">
<button class="btn btn-text btn-secondary" type="reset">Reset appointment</button>
<button class="btn btn-solid btn-primary" type="submit">Request appointment</button>
</footer>
</form>On an unsuccessful response, place a linked error summary before the controls and preserve valid choices. Mark each affected control with aria-invalid and connect it to specific feedback using aria-describedby.
<form class="card shadow-sm border-error" action="/appointments" method="post" aria-labelledby="validation-title">
<header class="card-header">
<h3 id="validation-title">Choose another appointment</h3>
<p>The requested slot is no longer available.</p>
</header>
<div class="card-body d-flex flex-column gap-3">
<div class="alert bg-error" role="alert" aria-labelledby="error-title">
<div class="alert-content">
<p class="alert-title" id="error-title">There are 3 problems</p>
<ul class="alert-message">
<li><a class="text-inherit" href="#invalid-date">Choose an available date.</a></li>
<li><a class="text-inherit" href="#invalid-time">Choose a time between 09:00 and 16:30.</a></li>
<li><a class="text-inherit" href="#invalid-video">Choose an appointment format.</a></li>
</ul>
</div>
</div>
<div>
<label class="form-label is-required" for="invalid-date">Date</label>
<input class="form-control is-invalid" id="invalid-date" name="date" type="date" required aria-invalid="true" aria-describedby="invalid-date-feedback" />
<div class="invalid-feedback" id="invalid-date-feedback">Choose an available date.</div>
</div>
<div>
<label class="form-label is-required" for="invalid-time">Time</label>
<input class="form-control is-invalid" id="invalid-time" name="time" type="time" required aria-invalid="true" aria-describedby="invalid-time-feedback" />
<div class="invalid-feedback" id="invalid-time-feedback">Choose a time between 09:00 and 16:30.</div>
</div>
<fieldset class="border border-0 p-0 m-0">
<legend class="form-label is-required">Appointment format</legend>
<div class="form-check">
<input class="form-check-input is-invalid" id="invalid-video" name="format" type="radio" value="video" required aria-invalid="true" aria-describedby="invalid-format-feedback" />
<label class="form-label" for="invalid-video">Video consultation</label>
</div>
<div class="form-check">
<input class="form-check-input is-invalid" id="invalid-office" name="format" type="radio" value="office" required aria-invalid="true" aria-describedby="invalid-format-feedback" />
<label class="form-label" for="invalid-office">In person</label>
</div>
<div class="invalid-feedback" id="invalid-format-feedback">Choose an appointment format.</div>
</fieldset>
<button class="btn btn-solid btn-primary" type="submit">Check availability</button>
</div>
</form>After the booking succeeds, present an explicit status and repeat the date, time, format, practitioner, reference and contact destination. Keep rescheduling and cancellation actions available without competing with the confirmation message.
Appointment confirmed
Reference #APT-2048
We saved your appointment
Practitioner
Design system consultant
€95 paid
<article class="card shadow-sm border-success" aria-labelledby="confirmation-title">
<header class="card-header">
<p class="text-success"><strong>Appointment confirmed</strong></p>
<h3 class="card-title" id="confirmation-title">Your consultation is booked</h3>
<span class="badge bg-success">Confirmed</span>
<p class="card-subtitle">Reference #APT-2048</p>
</header>
<div class="card-body d-flex flex-column gap-4">
<div class="alert bg-success" role="status">
<div class="alert-content">
<p class="alert-title">We saved your appointment</p>
<p class="alert-message">A calendar invitation and private video link were sent to john.doe@example.com.</p>
</div>
</div>
<div class="grid gap-3">
<section class="col-12 col-md-7 border rounded p-3" aria-labelledby="details-title">
<h4 id="details-title">Appointment details</h4>
<dl>
<div class="d-flex justify-content-between gap-3"><dt>Date</dt><dd><time datetime="2026-09-18">Friday, September 18, 2026</time></dd></div>
<div class="d-flex justify-content-between gap-3"><dt>Time</dt><dd><time datetime="10:30">10:30–11:15 CEST</time></dd></div>
<div class="d-flex justify-content-between gap-3"><dt>Format</dt><dd>Video consultation</dd></div>
</dl>
</section>
<section class="col-12 col-md-5 border rounded p-3" aria-labelledby="practitioner-title">
<h4 id="practitioner-title">Taylor Smith</h4>
<p>Design system consultant</p>
<p><strong>€95 paid</strong></p>
</section>
</div>
<footer class="d-flex flex-column flex-sm-row justify-content-end gap-2">
<button class="btn btn-text btn-secondary" type="button">Cancel appointment</button>
<button class="btn btn-outline btn-primary" type="button">Reschedule</button>
</footer>
</div>
</article>