Travel Enquiry Form Page
Preview
Edit
Download
Run
Download Options
HTML File
Download as .html file
CSS File
Download as .css file
JavaScript File
Download as .js file
Combined HTML
All code in one HTML file
Project ZIP
All files in a ZIP archive
Cancel
HTML
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Travel Enquiry</title> <link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,400;0,600;1,300;1,400&family=Outfit:wght@300;400;500;600&display=swap" rel="stylesheet"> </head> <body> <!-- Background --> <div class="hero-bg"> <div class="sky-layer"></div> <div class="cloud cl1"></div> <div class="cloud cl2"></div> <div class="cloud cl3"></div> <div class="cloud cl4"></div> <div class="horizon"></div> <div id="particles"></div> </div> <!-- Success Overlay --> <div class="success-overlay" id="successOverlay"> <div class="success-plane">βοΈ</div> <div class="success-check"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"> <polyline points="20 6 9 17 4 12"/> </svg> </div> <div class="success-title">Enquiry Submitted!</div> <div class="success-sub">Thank you! Our travel specialists will review your request and reach out within 24 hours to craft your perfect itinerary.</div> <div class="success-ref">Ref: TRV-<span id="refNum"></span></div> <button class="btn-new" onclick="resetForm()">Submit Another Enquiry</button> </div> <div class="page"> <!-- Header --> <div class="site-header"> <div class="header-logo"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/> </svg> </div> <div class="header-brand">Wander<span>Lux</span></div> </div> <!-- Hero Text --> <div class="hero-text"> <div class="hero-eyebrow"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/> </svg> Bespoke Travel Experiences </div> <h1 class="hero-title">Plan your <em>dream</em><br>journey today</h1> <p class="hero-sub">Tell us where you want to go and we'll design a personalised travel experience crafted just for you.</p> </div> <!-- Progress Steps --> <div class="steps-bar" id="stepsBar"> <div class="step-item active" data-step="1"> <div class="step-num">1</div> <span class="step-label">Your Details</span> </div> <div class="step-connector"></div> <div class="step-item" data-step="2"> <div class="step-num">2</div> <span class="step-label">Destination</span> </div> <div class="step-connector"></div> <div class="step-item" data-step="3"> <div class="step-num">3</div> <span class="step-label">Travel Plans</span> </div> <div class="step-connector"></div> <div class="step-item" data-step="4"> <div class="step-num">4</div> <span class="step-label">Preferences</span> </div> </div> <!-- Main Form Card --> <div class="form-card"> <div class="card-accent"></div> <div class="card-body"> <!-- Β§ 1 Personal Details --> <div class="form-section" data-section="1"> <div class="section-title"> <div class="section-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/> </svg> </div> Personal Details </div> <div class="row-2"> <div class="field"> <label class="field-label" for="fname"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg> First Name <span class="required-star">*</span> </label> <div class="field-wrap" id="fnameWrap"> <input class="field-input" type="text" id="fname" placeholder="e.g. Sarah"/> <span class="field-bar"></span> <span class="field-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg></span> <span class="field-tick"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></span> </div> <span class="err" id="fnameErr">Please enter your first name</span> </div> <div class="field"> <label class="field-label" for="lname"> Last Name <span class="required-star">*</span> </label> <div class="field-wrap" id="lnameWrap"> <input class="field-input" type="text" id="lname" placeholder="e.g. Mitchell"/> <span class="field-bar"></span> <span class="field-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg></span> <span class="field-tick"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></span> </div> <span class="err" id="lnameErr">Please enter your last name</span> </div> <div class="field"> <label class="field-label" for="email"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg> Email Address <span class="required-star">*</span> </label> <div class="field-wrap" id="emailWrap"> <input class="field-input" type="email" id="email" placeholder="you@example.com"/> <span class="field-bar"></span> <span class="field-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg></span> <span class="field-tick"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></span> </div> <span class="err" id="emailErr">Enter a valid email address</span> </div> <div class="field"> <label class="field-label" for="phone"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12 19.79 19.79 0 0 1 1.61 3.4 2 2 0 0 1 3.6 1.22h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 8.96a16 16 0 0 0 6 6l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 21.73 16.92z"/></svg> Phone Number </label> <div class="field-wrap"> <input class="field-input" type="tel" id="phone" placeholder="+1 (555) 000-0000"/> <span class="field-bar"></span> <span class="field-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12 19.79 19.79 0 0 1 1.61 3.4 2 2 0 0 1 3.6 1.22h3a2 2 0 0 1 2 1.72c.127.96.361 1.903.7 2.81a2 2 0 0 1-.45 2.11L7.91 8.96a16 16 0 0 0 6 6l.95-.95a2 2 0 0 1 2.11-.45c.907.339 1.85.573 2.81.7A2 2 0 0 1 21.73 16.92z"/></svg></span> </div> </div> </div> </div> <!-- Β§ 2 Destination --> <div class="form-section" data-section="2"> <div class="section-title"> <div class="section-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"/><line x1="2" y1="12" x2="22" y2="12"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/> </svg> </div> Where do you want to go? </div> <div class="field" style="margin-bottom:20px"> <label class="field-label">Popular Destinations</label> <div class="dest-group" id="destGroup"> <label class="dest-card" data-val="europe"><input type="radio" name="dest" value="europe"/><span class="dest-name">Europe</span></label> <label class="dest-card" data-val="asia"><input type="radio" name="dest" value="asia"/><span class="dest-name">Asia</span></label> <label class="dest-card" data-val="maldives"><input type="radio" name="dest" value="maldives"/><span class="dest-name">Maldives</span></label> <label class="dest-card" data-val="americas"><input type="radio" name="dest" value="americas"/><span class="dest-name">Americas</span></label> <label class="dest-card" data-val="africa"><input type="radio" name="dest" value="africa"/><span class="dest-name">Africa</span></label> <label class="dest-card" data-val="other"><input type="radio" name="dest" value="other"/><span class="dest-name">Other</span></label> </div> </div> <div class="row-2"> <div class="field"> <label class="field-label" for="from"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 8 12 12 14 14"/></svg> Departing From <span class="required-star">*</span> </label> <div class="field-wrap" id="fromWrap"> <input class="field-input" type="text" id="from" placeholder="City or Airport"/> <span class="field-bar"></span> <span class="field-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg></span> <span class="field-tick"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></span> </div> <span class="err" id="fromErr">Please enter your departure city</span> </div> <div class="field"> <label class="field-label" for="specific">Specific Destination</label> <div class="field-wrap"> <input class="field-input" type="text" id="specific" placeholder="City, region or country"/> <span class="field-bar"></span> <span class="field-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/></svg></span> </div> </div> </div> </div> <!-- Β§ 3 Travel Dates & Travellers --> <div class="form-section" data-section="3"> <div class="section-title"> <div class="section-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/> </svg> </div> Travel Dates & Travellers </div> <div class="date-grid" style="margin-bottom:24px"> <div class="field"> <label class="field-label" for="depart"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg> Departure Date <span class="required-star">*</span> </label> <div class="field-wrap" id="departWrap"> <input class="field-input" type="date" id="depart"/> <span class="field-bar"></span> <span class="field-tick"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg></span> </div> <span class="err" id="departErr">Please select a departure date</span> </div> <div class="field"> <label class="field-label" for="return">Return Date</label> <div class="field-wrap"> <input class="field-input" type="date" id="return"/> <span class="field-bar"></span> </div> </div> </div> <div class="field" style="margin-bottom:8px"> <label class="field-label">Number of Travellers</label> <div class="traveller-grid"> <div class="traveller-box"> <div><div class="traveller-label">Adults</div><div class="traveller-sub">Age 18+</div></div> <div class="counter"> <button class="count-btn" onclick="adjustCount('adults',-1)">β</button> <span class="count-val" id="adults-val">2</span> <button class="count-btn" onclick="adjustCount('adults',1)">+</button> </div> </div> <div class="traveller-box"> <div><div class="traveller-label">Children</div><div class="traveller-sub">Age 2β17</div></div> <div class="counter"> <button class="count-btn" onclick="adjustCount('children',-1)">β</button> <span class="count-val" id="children-val">0</span> <button class="count-btn" onclick="adjustCount('children',1)">+</button> </div> </div> <div class="traveller-box"> <div><div class="traveller-label">Infants</div><div class="traveller-sub">Under 2</div></div> <div class="counter"> <button class="count-btn" onclick="adjustCount('infants',-1)">β</button> <span class="count-val" id="infants-val">0</span> <button class="count-btn" onclick="adjustCount('infants',1)">+</button> </div> </div> </div> </div> </div> <!-- Β§ 4 Preferences --> <div class="form-section" data-section="4"> <div class="section-title"> <div class="section-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/> </svg> </div> Travel Preferences </div> <div class="field" style="margin-bottom:22px"> <label class="field-label">Trip Type</label> <div class="type-group" id="typeGroup"> <label class="type-pill"> <input type="checkbox" value="beach"/> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg> Beach & Relaxation </label> <label class="type-pill"> <input type="checkbox" value="adventure"/> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="3 11 22 2 13 21 11 13 3 11"/></svg> Adventure </label> <label class="type-pill"> <input type="checkbox" value="culture"/> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg> Culture & History </label> <label class="type-pill"> <input type="checkbox" value="food"/> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8h1a4 4 0 0 1 0 8h-1"/><path d="M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z"/><line x1="6" y1="1" x2="6" y2="4"/><line x1="10" y1="1" x2="10" y2="4"/><line x1="14" y1="1" x2="14" y2="4"/></svg> Food & Cuisine </label> <label class="type-pill"> <input type="checkbox" value="luxury"/> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg> Luxury </label> <label class="type-pill"> <input type="checkbox" value="wildlife"/> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M8.56 2.75c4.37 6.03 6.02 9.42 8.03 17.72m2.54-15.38c-3.72 4.35-8.94 5.66-16.88 5.85m19.5 1.9c-3.5-.93-6.63-.82-8.94 0-2.58.92-5.01 2.86-7.44 6.32"/></svg> Wildlife & Nature </label> </div> </div> <div class="row-2" style="margin-bottom:24px"> <div class="field"> <label class="field-label" for="accommodation"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><polyline points="9 22 9 12 15 12 15 22"/></svg> Accommodation </label> <div class="field-wrap"> <select class="field-select" id="accommodation"> <option value="">Select preferenceβ¦</option> <option>5-Star Luxury Resort</option> <option>Boutique Hotel</option> <option>All-Inclusive</option> <option>Self-Catering Villa</option> <option>Eco Lodge / Glamping</option> <option>No preference</option> </select> <span class="field-bar"></span> <span class="field-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span> </div> </div> <div class="field"> <label class="field-label" for="flight"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 16v-2l-8-5V3.5a1.5 1.5 0 0 0-3 0V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5z"/></svg> Flight Class </label> <div class="field-wrap"> <select class="field-select" id="flight"> <option value="">Select classβ¦</option> <option>Economy</option> <option>Premium Economy</option> <option>Business Class</option> <option>First Class</option> <option>No preference</option> </select> <span class="field-bar"></span> <span class="field-icon"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg></span> </div> </div> </div> <!-- Budget Slider --> <div class="field" style="margin-bottom:24px"> <label class="field-label"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg> Approximate Budget (per person) </label> <div class="budget-wrap"> <div class="budget-display"> <div> <div class="budget-value" id="budgetVal">$3,000</div> </div> <div class="budget-label">per person</div> </div> <div class="range-track"> <div class="range-fill" id="rangeFill"></div> <input class="budget-slider" type="range" id="budgetSlider" min="500" max="20000" step="250" value="3000"/> </div> <div class="budget-markers"> <span>$500</span><span>$5k</span><span>$10k</span><span>$15k</span><span>$20k+</span> </div> </div> </div> <!-- Special Requests --> <div class="field"> <label class="field-label" for="notes"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg> Special Requests or Notes </label> <div class="field-wrap"> <textarea class="field-textarea" id="notes" placeholder="Dietary requirements, accessibility needs, special occasions, dream experiencesβ¦"></textarea> <span class="field-bar"></span> </div> </div> </div> <!-- Submit Area --> <div class="submit-area"> <div class="submit-note"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg> Your data is protected. We never share your details with third parties. </div> <button class="btn-submit" id="submitBtn"> <span class="bt"> Send My Enquiry <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg> </span> </button> </div> </div> </div> <!-- Trust Bar --> <div class="trust-bar"> <div class="trust-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg> No booking fee </div> <div class="trust-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg> ATOL protected </div> <div class="trust-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg> Reply within 24 hours </div> <div class="trust-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07A19.5 19.5 0 0 1 4.69 12"/><path d="M1.61 3.4 A2 2 0 0 1 3.6 1.22h3a2 2 0 0 1 2 1.72"/></svg> Expert consultants </div> </div> </div> </body> </html>
CSS
*,*::before,*::after{margin:0;padding:0;box-sizing:border-box} :root{ --sky: #e8f4fd; --sky-mid: #c3dff7; --ocean: #0369a1; --ocean-d: #075985; --ocean-dd: #0c4a6e; --teal: #0891b2; --sand: #fef3c7; --sand-d: #fde68a; --sunset: #f59e0b; --coral: #f97316; --white: #ffffff; --text: #0c2942; --text-2: #3d6180; --text-3: #7ba3c0; --border: rgba(3,105,161,.15); --border-f: rgba(3,105,161,.5); --card-bg: rgba(255,255,255,.92); --input-bg: rgba(240,249,255,.7); --radius: 14px; --radius-sm:9px; } html{scroll-behavior:smooth} body{ min-height:100vh; font-family:'Outfit',sans-serif; background:var(--sky); color:var(--text); overflow-x:hidden; position:relative; } /* ββ HERO BG ββ */ .hero-bg{ position:fixed;inset:0;z-index:0; background:linear-gradient(160deg,#e0f2fe 0%,#bae6fd 30%,#e0f7fa 60%,#fef9ee 100%); overflow:hidden; } /* Animated sky layers */ .sky-layer{ position:absolute;inset:0; background: radial-gradient(ellipse 80% 40% at 50% -5%, rgba(186,230,253,.8) 0%, transparent 60%), radial-gradient(ellipse 60% 60% at 90% 20%, rgba(224,242,254,.6) 0%, transparent 50%), radial-gradient(ellipse 50% 70% at 0% 80%, rgba(254,249,238,.7) 0%, transparent 55%); } /* Floating clouds */ .cloud{ position:absolute; border-radius:50px; background:rgba(255,255,255,.65); filter:blur(2px); animation:cloudDrift linear infinite; } .cloud::before,.cloud::after{ content:'';position:absolute; background:inherit;border-radius:50%; } .cl1{width:180px;height:50px;top:8%;left:-200px;animation-duration:55s;animation-delay:0s} .cl1::before{width:80px;height:70px;top:-35px;left:20px} .cl1::after{width:60px;height:55px;top:-25px;left:80px} .cl2{width:130px;height:38px;top:20%;left:-160px;animation-duration:75s;animation-delay:20s;opacity:.7} .cl2::before{width:60px;height:52px;top:-26px;left:15px} .cl2::after{width:50px;height:44px;top:-20px;left:60px} .cl3{width:220px;height:55px;top:6%;left:-250px;animation-duration:90s;animation-delay:35s;opacity:.5} .cl3::before{width:90px;height:75px;top:-38px;left:30px} .cl3::after{width:70px;height:60px;top:-28px;left:110px} .cl4{width:100px;height:30px;top:30%;left:-130px;animation-duration:60s;animation-delay:10s;opacity:.6} .cl4::before{width:45px;height:40px;top:-20px;left:10px} .cl4::after{width:38px;height:32px;top:-15px;left:45px} @keyframes cloudDrift{to{transform:translateX(110vw)}} /* Horizon gradient at bottom */ .horizon{ position:absolute;bottom:0;left:0;right:0;height:35%; background:linear-gradient(to top,rgba(254,243,199,.5),transparent); } /* Floating particles */ .particle{ position:absolute;border-radius:50%; background:rgba(3,105,161,.12); animation:particleFloat ease-in-out infinite; } @keyframes particleFloat{ 0%,100%{transform:translateY(0) rotate(0deg);opacity:.4} 50%{transform:translateY(-30px) rotate(180deg);opacity:.9} } /* ββ LAYOUT ββ */ .page{ position:relative;z-index:10; min-height:100vh; display:flex;flex-direction:column; align-items:center; padding:60px 20px 80px; } /* ββ TOP HEADER ββ */ .site-header{ display:flex;align-items:center;justify-content:center; gap:12px; margin-bottom:48px; animation:fadeDown .8s .1s both; } .header-logo{ width:44px;height:44px; border-radius:12px; background:linear-gradient(135deg,var(--ocean),var(--teal)); display:flex;align-items:center;justify-content:center; box-shadow:0 4px 16px rgba(3,105,161,.3); animation:logoPulse 4s ease-in-out infinite; } .header-logo svg{width:22px;height:22px;color:white} @keyframes logoPulse{ 0%,100%{box-shadow:0 4px 16px rgba(3,105,161,.3)} 50%{box-shadow:0 6px 24px rgba(3,105,161,.55)} } .header-brand{ font-family:'Cormorant Garamond',serif; font-size:26px;font-weight:600; color:var(--ocean-dd);letter-spacing:1px; } .header-brand span{color:var(--sunset)} /* ββ HERO TEXT ββ */ .hero-text{ text-align:center; margin-bottom:52px; max-width:600px; } .hero-eyebrow{ display:inline-flex;align-items:center;gap:8px; background:rgba(3,105,161,.08); border:1px solid rgba(3,105,161,.2); border-radius:100px; padding:6px 18px; font-size:12px;letter-spacing:2.5px; text-transform:uppercase; color:var(--ocean);font-weight:500; margin-bottom:20px; animation:fadeDown .7s .2s both; } .hero-eyebrow svg{width:12px;height:12px} .hero-title{ font-family:'Cormorant Garamond',serif; font-size:clamp(38px,6vw,68px); font-weight:300; line-height:1.1; color:var(--ocean-dd); margin-bottom:16px; animation:fadeDown .8s .3s both; } .hero-title em{ font-style:italic;font-weight:400; color:var(--sunset); } .hero-sub{ font-size:16px;color:var(--text-2); line-height:1.7;font-weight:300; animation:fadeDown .8s .4s both; } /* ββ PROGRESS STEPS ββ */ .steps-bar{ display:flex;align-items:center; gap:0; margin-bottom:44px; animation:fadeDown .7s .45s both; background:rgba(255,255,255,.7); border:1px solid rgba(3,105,161,.12); border-radius:100px; padding:6px 8px; backdrop-filter:blur(12px); } .step-item{ display:flex;align-items:center;gap:8px; padding:8px 16px; border-radius:100px; transition:all .4s cubic-bezier(.23,1,.32,1); cursor:default; } .step-item.active{ background:linear-gradient(135deg,var(--ocean),var(--teal)); box-shadow:0 4px 14px rgba(3,105,161,.3); } .step-item.done{background:rgba(3,105,161,.1)} .step-num{ width:22px;height:22px;border-radius:50%; display:flex;align-items:center;justify-content:center; font-size:11px;font-weight:600; background:rgba(3,105,161,.15); color:var(--ocean); flex-shrink:0;transition:all .3s; } .step-item.active .step-num{background:rgba(255,255,255,.25);color:white} .step-item.done .step-num{background:var(--sunset);color:white} .step-label{font-size:12px;font-weight:500;color:var(--text-2);letter-spacing:.5px;white-space:nowrap} .step-item.active .step-label{color:white} .step-connector{width:24px;height:1px;background:rgba(3,105,161,.15);flex-shrink:0} /* ββ MAIN CARD ββ */ .form-card{ width:100%;max-width:820px; background:var(--card-bg); border-radius:28px; border:1px solid rgba(255,255,255,.8); box-shadow: 0 2px 0 rgba(255,255,255,.9) inset, 0 32px 80px rgba(3,105,161,.12), 0 8px 32px rgba(0,0,0,.06); backdrop-filter:blur(24px); overflow:hidden; animation:cardRise .9s .5s cubic-bezier(.23,1,.32,1) both; position:relative; } @keyframes cardRise{ from{opacity:0;transform:translateY(40px) scale(.98)} to{opacity:1;transform:translateY(0) scale(1)} } /* Card top accent bar */ .card-accent{ height:4px; background:linear-gradient(90deg,var(--ocean) 0%,var(--teal) 40%,var(--sunset) 70%,var(--coral) 100%); background-size:200% 100%; animation:accentSlide 4s ease-in-out infinite alternate; } @keyframes accentSlide{ from{background-position:0% 50%} to{background-position:100% 50%} } .card-body{padding:44px 48px 48px} /* Section headers inside card */ .section-title{ font-family:'Cormorant Garamond',serif; font-size:22px;font-weight:600; color:var(--ocean-dd); display:flex;align-items:center;gap:10px; margin-bottom:24px; padding-bottom:14px; border-bottom:1px solid rgba(3,105,161,.1); } .section-icon{ width:34px;height:34px;border-radius:9px; background:linear-gradient(135deg,rgba(3,105,161,.1),rgba(8,145,178,.15)); border:1px solid rgba(3,105,161,.15); display:flex;align-items:center;justify-content:center; flex-shrink:0; } .section-icon svg{width:16px;height:16px;color:var(--ocean)} /* ββ GRID LAYOUTS ββ */ .row-2{display:grid;grid-template-columns:1fr 1fr;gap:20px} .row-3{display:grid;grid-template-columns:1fr 1fr 1fr;gap:20px} .row-auto{display:grid;grid-template-columns:2fr 1fr;gap:20px} .full{grid-column:1/-1} /* ββ FORM SECTION GROUPS ββ */ .form-section{ margin-bottom:36px; animation:sectionReveal .6s both; } .form-section:nth-child(1){animation-delay:.6s} .form-section:nth-child(2){animation-delay:.72s} .form-section:nth-child(3){animation-delay:.84s} .form-section:nth-child(4){animation-delay:.96s} @keyframes sectionReveal{ from{opacity:0;transform:translateY(16px)} to{opacity:1;transform:translateY(0)} } /* ββ FIELD ββ */ .field{display:flex;flex-direction:column;gap:7px} .field-label{ font-size:12px;letter-spacing:1.5px; text-transform:uppercase;font-weight:600; color:var(--text-2); display:flex;align-items:center;gap:6px; } .field-label svg{width:11px;height:11px;color:var(--ocean);opacity:.7} .required-star{color:var(--coral);margin-left:1px} .field-wrap{position:relative} .field-input, .field-select, .field-textarea{ width:100%; padding:14px 42px 14px 18px; background:var(--input-bg); border:1.5px solid var(--border); border-radius:var(--radius-sm); font-family:'Outfit',sans-serif; font-size:15px;color:var(--text); outline:none; transition:border-color .3s,background .3s,box-shadow .3s,transform .2s; caret-color:var(--ocean); -webkit-appearance:none; } .field-input::placeholder, .field-textarea::placeholder{color:var(--text-3);font-size:14px;font-weight:300} .field-input:hover,.field-select:hover,.field-textarea:hover{border-color:rgba(3,105,161,.3)} .field-input:focus,.field-select:focus,.field-textarea:focus{ border-color:var(--ocean); background:rgba(240,249,255,.95); box-shadow:0 0 0 4px rgba(3,105,161,.1); transform:translateY(-1px); } .field-select{cursor:pointer} .field-select option{background:white;color:var(--text)} .field-textarea{ padding-right:18px;resize:vertical; min-height:110px;line-height:1.6; } .field-icon{ position:absolute;right:13px;top:50%; transform:translateY(-50%); color:var(--text-3);pointer-events:none; transition:color .3s; } .field-icon svg{width:16px;height:16px} .field-input:focus~.field-icon, .field-select:focus~.field-icon{color:var(--ocean)} /* Animated underline */ .field-bar{ position:absolute;bottom:0;left:6px; height:2px;width:0; background:linear-gradient(90deg,var(--ocean),var(--teal)); border-radius:1px; transition:width .4s cubic-bezier(.23,1,.32,1); } .field-input:focus~.field-bar, .field-select:focus~.field-bar, .field-textarea:focus~.field-bar{width:calc(100% - 12px)} .err{ font-size:12px;color:#ef4444; opacity:0;transform:translateY(-3px); transition:all .25s;padding-left:2px; } .err.show{opacity:1;transform:translateY(0)} /* Success tick on filled fields */ .field-tick{ position:absolute;right:13px;top:50%; transform:translateY(-50%) scale(0); color:#22c55e; transition:transform .3s cubic-bezier(.34,1.56,.64,1); } .field-tick svg{width:15px;height:15px} .field-wrap.valid .field-tick{transform:translateY(-50%) scale(1)} .field-wrap.valid .field-icon{opacity:0} .field-wrap.valid .field-input,.field-wrap.valid .field-select{border-color:rgba(34,197,94,.4)} /* ββ DESTINATION CARDS ββ */ .dest-group{ display:grid; grid-template-columns:repeat(auto-fit,minmax(130px,1fr)); gap:10px; margin-top:4px; } .dest-card{ position:relative; border:1.5px solid var(--border); border-radius:var(--radius-sm); padding:14px 12px; cursor:pointer; transition:all .3s cubic-bezier(.23,1,.32,1); background:var(--input-bg); text-align:center; user-select:none; } .dest-card:hover{ border-color:rgba(3,105,161,.35); transform:translateY(-2px); box-shadow:0 6px 20px rgba(3,105,161,.1); } .dest-card.selected{ border-color:var(--ocean); background:rgba(3,105,161,.06); box-shadow:0 0 0 3px rgba(3,105,161,.12); } .dest-card input{position:absolute;opacity:0;pointer-events:none} .dest-emoji{font-size:22px;margin-bottom:5px;display:block} .dest-name{font-size:13px;font-weight:500;color:var(--text-2)} .dest-card.selected .dest-name{color:var(--ocean);font-weight:600} /* ββ TRIP TYPE PILLS ββ */ .type-group{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px} .type-pill{ display:flex;align-items:center;gap:7px; padding:9px 18px; border:1.5px solid var(--border); border-radius:100px; cursor:pointer; transition:all .3s cubic-bezier(.23,1,.32,1); background:var(--input-bg); user-select:none; font-size:13px;font-weight:500;color:var(--text-2); } .type-pill:hover{border-color:rgba(3,105,161,.35);transform:translateY(-1px)} .type-pill.selected{ background:linear-gradient(135deg,var(--ocean),var(--teal)); border-color:transparent;color:white; box-shadow:0 4px 14px rgba(3,105,161,.3); } .type-pill input{display:none} .type-pill svg{width:14px;height:14px} /* ββ BUDGET SLIDER ββ */ .budget-wrap{margin-top:4px} .budget-display{ display:flex;align-items:center;justify-content:space-between; margin-bottom:10px; } .budget-value{ font-family:'Cormorant Garamond',serif; font-size:26px;font-weight:600;color:var(--ocean-dd); transition:all .2s; } .budget-label{font-size:12px;color:var(--text-3);letter-spacing:1px;text-transform:uppercase} .range-track{position:relative;height:6px;border-radius:3px;background:rgba(3,105,161,.12);margin:8px 0} .range-fill{ position:absolute;left:0;top:0;height:100%; background:linear-gradient(90deg,var(--ocean),var(--teal)); border-radius:3px; transition:width .1s; } .budget-slider{ position:absolute;left:0;top:50%; transform:translateY(-50%); width:100%;height:6px; -webkit-appearance:none;appearance:none; background:transparent;cursor:pointer;outline:none; } .budget-slider::-webkit-slider-thumb{ -webkit-appearance:none; width:22px;height:22px; border-radius:50%; background:white; border:3px solid var(--ocean); box-shadow:0 2px 8px rgba(3,105,161,.3); transition:transform .2s,box-shadow .2s; cursor:grab; } .budget-slider::-webkit-slider-thumb:active{ cursor:grabbing;transform:scale(1.2); box-shadow:0 4px 14px rgba(3,105,161,.45); } .budget-markers{ display:flex;justify-content:space-between; margin-top:8px; font-size:11px;color:var(--text-3); } /* ββ DATE ROW ββ */ .date-grid{display:grid;grid-template-columns:1fr 1fr;gap:20px} /* ββ TRAVELLERS ββ */ .traveller-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:12px} .traveller-box{ background:var(--input-bg); border:1.5px solid var(--border); border-radius:var(--radius-sm); padding:14px 16px; display:flex;align-items:center;justify-content:space-between; gap:10px; } .traveller-label{ font-size:13px;font-weight:500;color:var(--text-2); } .traveller-sub{font-size:11px;color:var(--text-3);margin-top:1px} .counter{display:flex;align-items:center;gap:10px} .count-btn{ width:28px;height:28px;border-radius:50%; border:1.5px solid var(--border); background:white; color:var(--ocean); display:flex;align-items:center;justify-content:center; cursor:pointer;font-size:16px; transition:all .25s cubic-bezier(.34,1.56,.64,1); line-height:1; } .count-btn:hover{ background:var(--ocean);color:white; border-color:var(--ocean); transform:scale(1.1); box-shadow:0 3px 10px rgba(3,105,161,.3); } .count-val{ font-size:16px;font-weight:600;color:var(--ocean-dd); min-width:16px;text-align:center; transition:transform .2s cubic-bezier(.34,1.56,.64,1); } .count-val.pop{animation:numPop .25s cubic-bezier(.34,1.56,.64,1)} @keyframes numPop{50%{transform:scale(1.4) translateY(-3px)}} /* ββ SUBMIT ββ */ .submit-area{ margin-top:36px; display:flex; align-items:center; justify-content:space-between; gap:20px; flex-wrap:wrap; animation:sectionReveal .6s 1.1s both; } .submit-note{ display:flex;align-items:center;gap:8px; font-size:13px;color:var(--text-3);flex:1; } .submit-note svg{width:14px;height:14px;color:var(--ocean);flex-shrink:0} .btn-submit{ padding:16px 42px; background:linear-gradient(135deg,var(--ocean-dd) 0%,var(--ocean) 50%,var(--teal) 100%); background-size:200% 200%; border:none;border-radius:100px; color:white; font-family:'Outfit',sans-serif; font-size:15px;font-weight:600; letter-spacing:.5px; cursor:pointer; position:relative;overflow:hidden; transition:transform .3s,box-shadow .3s,background-position .5s; box-shadow:0 6px 24px rgba(3,105,161,.35); white-space:nowrap; flex-shrink:0; } .btn-submit::before{ content:'';position:absolute;inset:0; background:linear-gradient(135deg,rgba(255,255,255,.15),transparent); opacity:0;transition:opacity .3s; } .btn-submit:hover{ transform:translateY(-3px); box-shadow:0 12px 36px rgba(3,105,161,.45); background-position:right center; } .btn-submit:hover::before{opacity:1} .btn-submit:active{transform:translateY(-1px)} /* Shimmer */ .btn-submit::after{ content:'';position:absolute; top:0;left:-100%;width:60%;height:100%; background:linear-gradient(90deg,transparent,rgba(255,255,255,.2),transparent); transform:skewX(-20deg); animation:shimmer 3s ease-in-out infinite 2.5s; } @keyframes shimmer{0%{left:-100%}100%{left:200%}} .btn-submit .bt{position:relative;z-index:2;display:flex;align-items:center;gap:8px} .btn-submit .bt svg{width:16px;height:16px;transition:transform .3s} .btn-submit:hover .bt svg{transform:translateX(4px)} /* Loading */ .btn-submit.loading .bt{opacity:0} .btn-submit.loading::before{ content:'';opacity:1; position:absolute;top:50%;left:50%; width:20px;height:20px; transform:translate(-50%,-50%); border:2px solid rgba(255,255,255,.3); border-top-color:white; border-radius:50%; background:transparent; animation:spin .7s linear infinite;z-index:3; } @keyframes spin{to{transform:translate(-50%,-50%) rotate(360deg)}} /* Ripple */ .rip{ position:absolute;border-radius:50%; background:rgba(255,255,255,.25); transform:scale(0); animation:ripOut .7s linear; pointer-events:none; } @keyframes ripOut{to{transform:scale(8);opacity:0}} /* ββ SUCCESS STATE ββ */ .success-overlay{ position:fixed;inset:0;z-index:100; background:rgba(224,242,254,.97); backdrop-filter:blur(12px); display:flex;flex-direction:column; align-items:center;justify-content:center; gap:20px; opacity:0;pointer-events:none; transition:opacity .5s; } .success-overlay.show{opacity:1;pointer-events:all} .success-plane{ font-size:72px; animation:planeFly 1s cubic-bezier(.23,1,.32,1) both; filter:drop-shadow(0 8px 20px rgba(3,105,161,.2)); } @keyframes planeFly{ from{transform:translateX(-80px) translateY(30px) rotate(-15deg);opacity:0} to{transform:translateX(0) translateY(0) rotate(0deg);opacity:1} } .success-check{ width:76px;height:76px;border-radius:50%; border:2px solid var(--ocean); background:rgba(3,105,161,.08); display:flex;align-items:center;justify-content:center; animation:checkPop .5s .4s cubic-bezier(.34,1.56,.64,1) both; box-shadow:0 6px 24px rgba(3,105,161,.2); } .success-check svg{width:32px;height:32px;color:var(--ocean)} @keyframes checkPop{from{transform:scale(0);opacity:0}} .success-title{ font-family:'Cormorant Garamond',serif; font-size:36px;font-weight:600; color:var(--ocean-dd); animation:fadeDown .6s .6s both; text-align:center; } .success-sub{ font-size:16px;color:var(--text-2); animation:fadeDown .6s .75s both; text-align:center;max-width:380px;line-height:1.6; } .success-ref{ background:rgba(3,105,161,.08); border:1px solid rgba(3,105,161,.2); border-radius:100px; padding:8px 24px; font-size:13px;color:var(--ocean); letter-spacing:2px;text-transform:uppercase;font-weight:600; animation:fadeDown .6s .9s both; } .btn-new{ padding:14px 34px; background:linear-gradient(135deg,var(--ocean),var(--teal)); border:none;border-radius:100px; color:white;font-family:'Outfit',sans-serif; font-size:14px;font-weight:600;cursor:pointer; box-shadow:0 6px 20px rgba(3,105,161,.3); transition:transform .2s,box-shadow .2s; animation:fadeDown .6s 1.05s both; } .btn-new:hover{transform:translateY(-2px);box-shadow:0 10px 28px rgba(3,105,161,.4)} /* ββ SHAKE ββ */ @keyframes shake{ 0%,100%{transform:translateX(0)} 20%{transform:translateX(-6px)} 40%{transform:translateX(6px)} 60%{transform:translateX(-4px)} 80%{transform:translateX(4px)} } .shake{animation:shake .4s ease !important} /* ββ TRUST BAR ββ */ .trust-bar{ display:flex;align-items:center;justify-content:center; gap:28px;flex-wrap:wrap; margin-top:36px; animation:fadeDown .7s 1.2s both; } .trust-item{ display:flex;align-items:center;gap:7px; font-size:12px;color:var(--text-3);letter-spacing:.5px; } .trust-item svg{width:13px;height:13px;color:var(--ocean);opacity:.7} /* ββ SHARED ANIMS ββ */ @keyframes fadeDown{from{opacity:0;transform:translateY(-14px)}to{opacity:1;transform:translateY(0)}} @keyframes fadeUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:translateY(0)}} /* ββ RESPONSIVE ββ */ @media(max-width:720px){ .page{padding:40px 16px 60px} .card-body{padding:28px 22px 32px} .row-2,.row-3,.row-auto,.date-grid{grid-template-columns:1fr} .traveller-grid{grid-template-columns:1fr 1fr} .hero-title{font-size:36px} .steps-bar{gap:0;padding:4px 6px} .step-label{display:none} .step-connector{width:14px} .submit-area{flex-direction:column;align-items:stretch} .btn-submit{width:100%;justify-content:center} } @media(max-width:480px){ .page{padding:28px 12px 50px} .card-body{padding:22px 18px 26px} .hero-title{font-size:30px} .hero-sub{font-size:14px} .traveller-grid{grid-template-columns:1fr} .dest-group{grid-template-columns:repeat(3,1fr)} .section-title{font-size:18px} } @media(max-width:360px){ .dest-group{grid-template-columns:repeat(2,1fr)} .type-group{gap:6px} .type-pill{padding:7px 13px;font-size:12px} }
JavaScript
// ββ PARTICLES ββ const pc = document.getElementById('particles'); for (let i = 0; i < 18; i++) { const p = document.createElement('div'); p.className = 'particle'; const sz = Math.random() * 6 + 3; p.style.cssText = ` width:${sz}px;height:${sz}px; left:${Math.random()*100}%; top:${Math.random()*100}%; animation-duration:${Math.random()*6+5}s; animation-delay:${Math.random()*5}s; opacity:${Math.random()*.5+.1}; `; pc.appendChild(p); } // ββ DESTINATION CARDS ββ document.querySelectorAll('.dest-card').forEach(card => { card.addEventListener('click', () => { document.querySelectorAll('.dest-card').forEach(c => c.classList.remove('selected')); card.classList.add('selected'); }); }); // ββ TRIP TYPE PILLS ββ document.querySelectorAll('.type-pill').forEach(pill => { pill.addEventListener('click', () => pill.classList.toggle('selected')); }); // ββ COUNTER ββ const counts = { adults: 2, children: 0, infants: 0 }; function adjustCount(type, delta) { const min = type === 'adults' ? 1 : 0; counts[type] = Math.max(min, Math.min(10, counts[type] + delta)); const el = document.getElementById(`${type}-val`); el.textContent = counts[type]; el.classList.remove('pop'); void el.offsetWidth; el.classList.add('pop'); } // ββ BUDGET SLIDER ββ const slider = document.getElementById('budgetSlider'); const fill = document.getElementById('rangeFill'); const budVal = document.getElementById('budgetVal'); function updateSlider() { const pct = (slider.value - slider.min) / (slider.max - slider.min) * 100; fill.style.width = pct + '%'; const v = parseInt(slider.value); budVal.textContent = v >= 20000 ? '$20,000+' : '$' + v.toLocaleString(); } slider.addEventListener('input', updateSlider); updateSlider(); // ββ LIVE VALIDATION / TICK ββ function validateField(input, wrap, errEl, validator) { input.addEventListener('blur', () => { if (validator(input.value.trim())) { wrap.classList.add('valid'); errEl && errEl.classList.remove('show'); } else if (input.value.trim()) { wrap.classList.remove('valid'); errEl && errEl.classList.add('show'); } }); input.addEventListener('input', () => { if (validator(input.value.trim())) { wrap.classList.add('valid'); errEl && errEl.classList.remove('show'); } else { wrap.classList.remove('valid'); } }); } validateField( document.getElementById('fname'), document.getElementById('fnameWrap'), document.getElementById('fnameErr'), v => v.length >= 2 ); validateField( document.getElementById('lname'), document.getElementById('lnameWrap'), document.getElementById('lnameErr'), v => v.length >= 2 ); validateField( document.getElementById('email'), document.getElementById('emailWrap'), document.getElementById('emailErr'), v => /\S+@\S+\.\S+/.test(v) ); validateField( document.getElementById('from'), document.getElementById('fromWrap'), document.getElementById('fromErr'), v => v.length >= 2 ); // ββ PROGRESS BAR UPDATE ββ function updateProgress() { const filled = [ document.getElementById('fname').value.trim().length >= 2, document.getElementById('lname').value.trim().length >= 2, document.getElementById('email').value.trim().length >= 5, document.getElementById('from').value.trim().length >= 2, document.getElementById('depart').value !== '', ]; const total = filled.filter(Boolean).length; const steps = document.querySelectorAll('.step-item'); steps.forEach((s, i) => { s.classList.remove('active', 'done'); if (i < Math.floor(total / 1.3)) s.classList.add('done'); }); const active = Math.min(3, Math.floor(total / 1.3)); if (steps[active]) steps[active].classList.add('active'); else steps[steps.length - 1].classList.add('active'); } document.querySelectorAll('.field-input, .field-select').forEach(el => { el.addEventListener('input', updateProgress); el.addEventListener('change', updateProgress); }); // ββ RIPPLE ββ document.getElementById('submitBtn').addEventListener('click', function(e) { const r = this.getBoundingClientRect(); const d = document.createElement('div'); d.className = 'rip'; d.style.cssText = `left:${e.clientX-r.left}px;top:${e.clientY-r.top}px;width:24px;height:24px;margin:-12px`; this.appendChild(d); setTimeout(() => d.remove(), 700); }); // ββ SUBMIT ββ document.getElementById('submitBtn').addEventListener('click', function() { const fname = document.getElementById('fname').value.trim(); const lname = document.getElementById('lname').value.trim(); const email = document.getElementById('email').value.trim(); const from = document.getElementById('from').value.trim(); const dep = document.getElementById('depart').value; let ok = true; const checks = [ [fname.length < 2, 'fnameErr', 'fnameWrap'], [lname.length < 2, 'lnameErr', 'lnameWrap'], [!/\S+@\S+\.\S+/.test(email), 'emailErr', 'emailWrap'], [from.length < 2, 'fromErr', 'fromWrap'], [!dep, 'departErr', 'departWrap'], ]; checks.forEach(([bad, errId, wrapId]) => { const errEl = document.getElementById(errId); const wrapEl = document.getElementById(wrapId); if (bad) { errEl && errEl.classList.add('show'); if (wrapEl) { wrapEl.classList.remove('shake'); void wrapEl.offsetWidth; wrapEl.classList.add('shake'); } ok = false; } }); if (!ok) return; this.classList.add('loading'); setTimeout(() => { this.classList.remove('loading'); document.getElementById('refNum').textContent = Math.floor(100000 + Math.random() * 900000); document.getElementById('successOverlay').classList.add('show'); }, 2000); }); function resetForm() { document.getElementById('successOverlay').classList.remove('show'); document.querySelectorAll('.field-input, .field-textarea').forEach(el => el.value = ''); document.querySelectorAll('.field-select').forEach(el => el.selectedIndex = 0); document.querySelectorAll('.dest-card, .type-pill').forEach(el => el.classList.remove('selected')); document.querySelectorAll('.field-wrap').forEach(el => el.classList.remove('valid', 'shake')); document.querySelectorAll('.err').forEach(el => el.classList.remove('show')); counts.adults = 2; counts.children = 0; counts.infants = 0; ['adults','children','infants'].forEach(t => document.getElementById(`${t}-val`).textContent = counts[t]); slider.value = 3000; updateSlider(); }
Output Preview
Desktop
Mobile
Fullscreen