Hi Sam, thank you for the lovely brief. I have added 15 minutes of freestyle so Poppy gets her own dance moment. I bring my own speaker, just need a socket.
Expiry banner. Offers expire 48 hours after sending (configurable by teacher, max 7 days). Countdown updates live; under 6 hours it turns amber. Email and in-app reminders at 24h and 6h before expiry. Analytics: offer_viewed with time to expiry.
Offer header and teacher trust. Teacher name, photo, rating, review count, verification badges with the "checked on" date as tooltip. Links to 06-teacher-profile.html. Status badge values: Awaiting your reply, Expired, Declined, Accepted, Withdrawn.
Line items. Built from the teacher's offer (WF-49): package, add-ons, custom lines, travel. A diff banner highlights differences from the original request (price, date, place, group size). Prices are examples in GBP; VAT line appears only if the teacher is VAT registered.
Event details. Read-only copy of the request. "Edit details" sends a change request back to the teacher; the current offer is paused until she re-confirms. Date is re-checked against availability on page load; if now taken, show error "This date is no longer available" and disable Accept.
Teacher message and quick question. Latest teacher message in the offer, with a field to ask a question. Sending posts into the booking thread (shown in 25-booking-detail-messages.html) and keeps the offer open. Same contact-detail warning as WF-20.
Cancellation policy and terms. Policy is the teacher's chosen preset (Flexible, Moderate, Strict) displayed in plain English with refund dates calculated for this event. Tick box is required before Accept is enabled; unchecked click shows "Please confirm you have read the cancellation policy".
Decline. Optional reason select plus free text. Confirm modal: "Decline this offer? Amelia will be told. You can still message her." Moves booking to Cancelled tab. Analytics: offer_declined with reason.
Sticky summary and actions. Primary: "Accept offer and continue" goes to 22-checkout.html. Secondary: ask a question. Tertiary: decline. Buttons disabled when offer expired, with replacement CTA "Request a new offer".
Mobile
Single column. Summary becomes a fixed bottom bar with total and the Accept button; question and decline move into an overflow menu. Line items table switches to stacked rows.
States
Awaiting teacher (no offer yet): page shows "Amelia has not replied yet", response timer, and a "Nudge" action after 24 hours. Expired: grey banner, buttons replaced by request-again. Withdrawn by teacher: reason shown. Loading: skeleton table. Error: "We could not load this offer" with retry. Not owner: 403 page. Logged-out: redirect to 29-login.html with return URL.