Modal windows are a powerful tool in web design, offering a way to display important information without navigating away from the current page. They can enhance user experience by providing context-sensitive content in a focused manner.
In this article, we will explore 10 exemplary modal window designs that showcase various use cases and creative implementations. These examples will inspire you to create engaging and functional modal windows for your own projects.
CODE1
Here's the code:
CODETEXT1
CODE2
Here's the code:
CODETEXT2
CODE3
Here's the code:
CODETEXT3
CODE4
Here's the code:
CODETEXT4
CODE5
Here's the code:
CODETEXT5
Subframe's drag-and-drop interface and intuitive, responsive canvas make designing pixel-perfect modal windows a breeze. Loved by designers and developers alike, it ensures your UI is both stunning and functional.
Start for free and experience the ease of creating beautiful, production-ready code with Subframe.
CODE6
Here's the code:
CODETEXT6
CODE7
Here's the code:
CODETEXT7
CODE8
Here's the code:
CODETEXT8
CODE9
Here's the code:
CODETEXT9
CODE10
Here's the code:
CODETEXT10
Ready to elevate your UI design game? With Subframe, you can create pixel-perfect modal windows and other UI elements in minutes. Our drag-and-drop editor ensures efficiency and precision.
Don't wait—start for free and begin designing stunning, production-ready interfaces right away.
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Pastel Flow Checkout</title> <style> @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600&display=swap'); :root { --primary: #a6c1ee; --primary-light: #c4dbfd; --secondary: #fbc2eb; --secondary-light: #fcd7f1; --text: #5a5a7a; --text-light: #8a8aa0; --white: #ffffff; --shadow: rgba(166, 193, 238, 0.15); --error: #ff8a8a; --success: #a0d9a0; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background: linear-gradient(135deg, var(--primary-light) 0%, var(--secondary-light) 100%); padding: 20px; } .backdrop { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.4); backdrop-filter: blur(4px); z-index: 10; opacity: 0; transition: opacity 0.3s ease; } .checkout-modal { position: relative; width: 100%; max-width: 600px; background: var(--white); border-radius: 16px; box-shadow: 0 10px 30px var(--shadow); overflow: hidden; z-index: 20; opacity: 0; transform: translateY(30px); transition: opacity 0.4s ease, transform 0.4s ease; } .show { opacity: 1; transform: translateY(0); } .checkout-header { padding: 24px; background: linear-gradient(to right, var(--primary), var(--secondary)); color: var(--white); position: relative; overflow: hidden; } .checkout-header::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: rgba(255, 255, 255, 0.1); transform: rotate(45deg); z-index: 1; } .checkout-header h2 { font-weight: 500; position: relative; z-index: 2; } .checkout-header .close-btn { position: absolute; top: 24px; right: 24px; background: rgba(255, 255, 255, 0.2); border: none; width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; color: var(--white); font-size: 16px; transition: all 0.3s ease; z-index: 2; } .checkout-header .close-btn:hover { background: rgba(255, 255, 255, 0.4); transform: rotate(90deg); } .progress-container { display: flex; justify-content: space-between; padding: 0 40px; margin-top: -15px; position: relative; z-index: 3; } .progress-step { display: flex; flex-direction: column; align-items: center; } .step-circle { width: 30px; height: 30px; border-radius: 50%; background: var(--white); display: flex; align-items: center; justify-content: center; font-size: 14px; color: var(--text-light); font-weight: 500; position: relative; border: 2px solid var(--primary-light); transition: all 0.3s ease; } .step-circle.active { background: var(--primary); color: var(--white); border-color: var(--primary); box-shadow: 0 3px 10px rgba(166, 193, 238, 0.4); } .step-circle.completed { background: var(--primary); color: var(--white); border-color: var(--primary); } .step-circle.completed::after { content: '✓'; position: absolute; } .step-label { margin-top: 8px; font-size: 12px; color: var(--text-light); font-weight: 500; transition: all 0.3s ease; } .step-label.active { color: var(--primary); font-weight: 600; } .progress-line { position: absolute; top: 15px; left: 60px; right: 60px; height: 2px; background: var(--primary-light); z-index: -1; } .progress-line::before { content: ''; position: absolute; top: 0; left: 0; height: 100%; background: var(--primary); width: 0%; transition: width 0.5s ease; } .checkout-content { padding: 30px 24px; max-height: 400px; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--primary-light) transparent; } .checkout-content::-webkit-scrollbar { width: 5px; } .checkout-content::-webkit-scrollbar-track { background: transparent; } .checkout-content::-webkit-scrollbar-thumb { background-color: var(--primary-light); border-radius: 10px; } .step-content { display: none; animation: fadeIn 0.5s forwards; } .step-content.active { display: block; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .form-group { margin-bottom: 20px; } .form-group label { display: block; margin-bottom: 8px; font-size: 14px; color: var(--text); font-weight: 500; } .form-control { width: 100%; padding: 12px 16px; border: 1px solid #e2e8f0; border-radius: 8px; font-size: 14px; color: var(--text); transition: all 0.3s ease; background: #f8fafc; } .form-control:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(166, 193, 238, 0.15); background: var(--white); } .form-row { display: flex; gap: 15px; } .form-col { flex: 1; } .checkout-footer { padding: 20px 24px; display: flex; justify-content: space-between; border-top: 1px solid #f1f5f9; background: #fcfcff; } .btn { padding: 10px 20px; border-radius: 8px; font-size: 14px; font-weight: 500; cursor: pointer; transition: all 0.3s ease; border: none; } .btn-back { background: transparent; color: var(--text-light); border: 1px solid #e2e8f0; } .btn-back:hover { background: #f8fafc; color: var(--text); } .btn-next { background: linear-gradient(to right, var(--primary), var(--secondary)); color: var(--white); padding: 10px 24px; position: relative; overflow: hidden; } .btn-next::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: rgba(255, 255, 255, 0.1); transform: rotate(45deg) translateY(100%); transition: transform 0.6s ease; } .btn-next:hover::before { transform: rotate(45deg) translateY(-100%); } .btn-next:focus { box-shadow: 0 0 0 3px rgba(166, 193, 238, 0.3); } .cart-item { display: flex; align-items: center; margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid #f1f5f9; } .cart-item:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; } .cart-item-img { width: 70px; height: 70px; border-radius: 8px; background: #f8fafc; overflow: hidden; margin-right: 15px; position: relative; } .cart-item-img img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.3s ease; } .cart-item:hover .cart-item-img img { transform: scale(1.05); } .cart-item-details { flex: 1; } .cart-item-title { font-size: 14px; font-weight: 500; color: var(--text); margin-bottom: 5px; } .cart-item-variant { font-size: 12px; color: var(--text-light); margin-bottom: 5px; } .cart-item-price { font-size: 14px; font-weight: 600; color: var(--primary); } .cart-summary { margin-top: 30px; background: #f8fafc; border-radius: 8px; padding: 15px; } .summary-row { display: flex; justify-content: space-between; margin-bottom: 10px; } .summary-row:last-child { margin-bottom: 0; padding-top: 10px; border-top: 1px dashed #e2e8f0; font-weight: 600; color: var(--text); } .summary-label { font-size: 13px; color: var(--text-light); } .summary-value { font-size: 13px; color: var(--text); } .payment-methods { display: flex; gap: 10px; margin-bottom: 25px; } .payment-method { flex: 1; border: 1px solid #e2e8f0; border-radius: 8px; padding: 15px; cursor: pointer; transition: all 0.3s ease; text-align: center; position: relative; overflow: hidden; } .payment-method input { position: absolute; opacity: 0; } .payment-method-icon { display: flex; align-items: center; justify-content: center; margin-bottom: 8px; font-size: 24px; color: var(--text-light); transition: all 0.3s ease; } .payment-method-label { font-size: 13px; color: var(--text-light); transition: all 0.3s ease; } .payment-method:hover { border-color: var(--primary-light); } .payment-method.selected { border-color: var(--primary); background: rgba(166, 193, 238, 0.05); } .payment-method.selected .payment-method-icon, .payment-method.selected .payment-method-label { color: var(--primary); } .payment-method::before { content: ''; position: absolute; width: 20px; height: 20px; background: var(--primary); top: -10px; right: -10px; border-radius: 50%; transform: scale(0); transition: transform 0.3s ease; } .payment-method.selected::before { transform: scale(1); } .payment-method.selected::after { content: '✓'; position: absolute; top: 0px; right: 3px; color: white; font-size: 10px; } .card-icon { display: flex; gap: 5px; margin-top: 15px; } .card-icon span { width: 40px; height: 25px; border-radius: 4px; background: #f1f5f9; display: flex; align-items: center; justify-content: center; font-size: 16px; color: var(--text-light); } .success-animation { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 30px 0; } .checkmark-circle { width: 80px; height: 80px; position: relative; display: flex; align-items: center; justify-content: center; background: linear-gradient(to right, var(--primary-light), var(--secondary-light)); border-radius: 50%; margin-bottom: 20px; animation: scaleIn 0.5s ease forwards; } .checkmark { transform-origin: 50% 50%; stroke-dasharray: 48; stroke-dashoffset: 48; animation: stroke 0.5s cubic-bezier(0.65, 0, 0.45, 1) 0.5s forwards; } @keyframes stroke { 100% { stroke-dashoffset: 0; } } @keyframes scaleIn { 0% { transform: scale(0); } 100% { transform: scale(1); } } .success-message { text-align: center; } .success-message h3 { color: var(--primary); margin-bottom: 10px; font-weight: 500; } .success-message p { color: var(--text-light); font-size: 14px; margin-bottom: 5px; max-width: 300px; } .order-info { margin-top: 20px; background: #f8fafc; border-radius: 8px; padding: 15px; width: 100%; text-align: left; } .order-row { display: flex; justify-content: space-between; margin-bottom: 8px; } .order-label { font-size: 13px; color: var(--text-light); } .order-value { font-size: 13px; color: var(--text); font-weight: 500; } .floating-bubble { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.2); z-index: 1; animation: float 8s infinite ease-in-out; } .bubble-1 { width: 50px; height: 50px; top: 20%; left: 10%; animation-delay: 0s; } .bubble-2 { width: 30px; height: 30px; top: 60%; left: 80%; animation-delay: 1s; } .bubble-3 { width: 40px; height: 40px; top: 30%; left: 60%; animation-delay: 2s; } @keyframes float { 0%, 100% { transform: translateY(0) rotate(0deg); } 50% { transform: translateY(-20px) rotate(10deg); } } .input-icon { position: relative; } .input-icon .form-control { padding-left: 40px; } .input-icon .icon { position: absolute; left: 16px; top: 50%; transform: translateY(-50%); color: var(--text-light); } .badge { display: inline-block; padding: 4px 8px; background: var(--primary-light); color: var(--primary); border-radius: 12px; font-size: 11px; font-weight: 500; margin-left: 8px; } .checkbox-container { display: flex; align-items: center; margin-top: 20px; } .checkbox-input { position: absolute; opacity: 0; } .checkbox-custom { width: 18px; height: 18px; border: 2px solid #e2e8f0; border-radius: 4px; margin-right: 10px; position: relative; transition: all 0.3s ease; cursor: pointer; } .checkbox-input:checked + .checkbox-custom { background: var(--primary); border-color: var(--primary); } .checkbox-input:checked + .checkbox-custom::after { content: ''; position: absolute; top: 3px; left: 6px; width: 4px; height: 8px; border: solid white; border-width: 0 2px 2px 0; transform: rotate(45deg); } .checkbox-label { font-size: 13px; color: var(--text-light); cursor: pointer; } .checkbox-label a { color: var(--primary); text-decoration: none; } .checkbox-label a:hover { text-decoration: underline; } .error-message { color: var(--error); font-size: 12px; margin-top: 5px; display: none; } .form-control.error { border-color: var(--error); } .form-control.error + .error-message { display: block; } .cart-quantity { display: flex; align-items: center; margin-top: 5px; } .quantity-btn { width: 20px; height: 20px; background: #f1f5f9; border: none; border-radius: 4px; cursor: pointer; display: flex; align-items: center; justify-content: center; color: var(--text-light); transition: all 0.2s ease; } .quantity-btn:hover { background: var(--primary-light); color: var(--primary); } .quantity-input { width: 30px; text-align: center; border: none; background: transparent; font-size: 13px; color: var(--text); margin: 0 5px; } .progress-dot { position: absolute; width: 6px; height: 6px; border-radius: 50%; background: var(--secondary); opacity: 0; z-index: 3; } /* Media Queries */ @media (max-width: 600px) { .checkout-modal { width: 95%; } .progress-container { padding: 0 20px; } .progress-line { left: 40px; right: 40px; } .form-row { flex-direction: column; gap: 20px; } .payment-methods { flex-direction: column; } } /* For the demo button */ .demo-btn { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: var(--primary); color: white; border: none; padding: 12px 24px; border-radius: 8px; font-weight: 500; cursor: pointer; box-shadow: 0 4px 10px rgba(166, 193, 238, 0.3); transition: all 0.3s ease; z-index: 5; } .demo-btn:hover { background: #95b0dd; transform: translateX(-50%) translateY(-2px); box-shadow: 0 6px 15px rgba(166, 193, 238, 0.4); } </style> </head> <body> <button class="demo-btn" id="open-checkout">Start Checkout</button> <div class="backdrop" id="backdrop"></div> <div class="checkout-modal" id="checkout-modal"> <div class="checkout-header"> <div class="floating-bubble bubble-1"></div> <div class="floating-bubble bubble-2"></div> <div class="floating-bubble bubble-3"></div> <h2>Complete Your Purchase</h2> <button class="close-btn" id="close-btn">×</button> </div> <div class="progress-container"> <div class="progress-line"> <div class="progress-dot" id="progress-dot"></div> </div> <div class="progress-step" data-step="1"> <div class="step-circle active">1</div> <div class="step-label active">Cart</div> </div> <div class="progress-step" data-step="2"> <div class="step-circle">2</div> <div class="step-label">Details</div> </div> <div class="progress-step" data-step="3"> <div class="step-circle">3</div> <div class="step-label">Payment</div> </div> <div class="progress-step" data-step="4"> <div class="step-circle">4</div> <div class="step-label">Confirm</div> </div> </div> <div class="checkout-content"> <!-- Step 1: Cart --> <div class="step-content active" id="step-1"> <div class="cart-item"> <div class="cart-item-img"> <img src="https://images.unsplash.com/photo-1542291026-7eec264c27ff" alt="Product"> </div> <div class="cart-item-details"> <div class="cart-item-title">Nimbus Running Shoes</div> <div class="cart-item-variant">Size: 42 | Color: Cloud Blue</div> <div class="cart-item-price">$129.99</div> <div class="cart-quantity"> <button class="quantity-btn minus">-</button> <input type="text" class="quantity-input" value="1" readonly> <button class="quantity-btn plus">+</button> </div> </div> </div> <div class="cart-item"> <div class="cart-item-img"> <img src="https://images.unsplash.com/photo-1523275335684-37898b6baf30" alt="Product"> </div> <div class="cart-item-details"> <div class="cart-item-title">SmartFit Fitness Tracker</div> <div class="cart-item-variant">Color: Mist Gray</div> <div class="cart-item-price">$89.99</div> <div class="cart-quantity"> <button class="quantity-btn minus">-</button> <input type="text" class="quantity-input" value="1" readonly> <button class="quantity-btn plus">+</button> </div> </div> </div> <div class="cart-summary"> <div class="summary-row"> <div class="summary-label">Subtotal</div> <div class="summary-value">$219.98</div> </div> <div class="summary-row"> <div class="summary-label">Shipping</div> <div class="summary-value">$4.99</div> </div> <div class="summary-row"> <div class="summary-label">Tax</div> <div class="summary-value">$13.20</div> </div> <div class="summary-row"> <div class="summary-label">Total</div> <div class="summary-value">$238.17</div> </div> </div> </div> <!-- Step 2: Customer Details --> <div class="step-content" id="step-2"> <div class="form-group"> <label for="name">Full Name</label> <div class="input-icon"> <i class="icon">👤</i> <input type="text" class="form-control" id="name" placeholder="Your full name"> <div class="error-message">Please enter your full name</div> </div> </div> <div class="form-group"> <label for="email">Email Address <span class="badge">Receipt</span></label> <div class="input-icon"> <i class="icon">✉️</i> <input type="email" class="form-control" id="email" placeholder="[email protected]"> <div class="error-message">Please enter a valid email address</div> </div> </div> <div class="form-group"> <label for="phone">Phone Number</label> <div class="input-icon"> <i class="icon">📱</i> <input type="tel" class="form-control" id="phone" placeholder="(123) 456-7890"> <div class="error-message">Please enter a valid phone number</div> </div> </div> <div class="form-group"> <label for="address">Shipping Address</label> <input type="text" class="form-control" id="address" placeholder="Street address"> <div class="error-message">Please enter your address</div> </div> <div class="form-row"> <div class="form-col"> <div class="form-group"> <label for="city">City</label> <input type="text" class="form-control" id="city" placeholder="City"> <div class="error-message">Please enter your city</div> </div> </div> <div class="form-col"> <div class="form-group"> <label for="zipcode">Zip Code</label> <input type="text" class="form-control" id="zipcode" placeholder="Zip code"> <div class="error-message">Please enter a valid zip code</div> </div> </div> </div> <div class="checkbox-container"> <input type="checkbox" id="save-info" class="checkbox-input"> <div class="checkbox-custom"></div> <label for="save-info" class="checkbox-label">Save my information for faster checkout next time</label> </div> </div> <!-- Step 3: Payment Information --> <div class="step-content" id="step-3"> <div class="payment-methods"> <div class="payment-method selected"> <input type="radio" name="payment" id="credit-card" checked> <div class="payment-method-icon">💳</div> <div class="payment-method-label">Credit Card</div> </div> <div class="payment-method"> <input type="radio" name="payment" id="paypal"> <div class="payment-method-icon">🅿️</div> <div class="payment-method-label">PayPal</div> </div> <div class="payment-method"> <input type="radio" name="payment" id="apple-pay"> <div class="payment-method-icon">🍎</div> <div class="payment-method-label">Apple Pay</div> </div> </div> <div class="form-group"> <label for="card-number">Card Number</label> <div class="input-icon"> <i class="icon">💳</i> <input type="text" class="form-control" id="card-number" placeholder="1234 5678 9012 3456"> <div class="error-message">Please enter a valid card number</div> </div> <div class="card-icon"> <span>visa</span> <span>mc</span> <span>amex</span> </div> </div> <div class="form-row"> <div class="form-col"> <div class="form-group"> <label for="expiry">Expiry Date</label> <input type="text" class="form-control" id="expiry" placeholder="MM/YY"> <div class="error-message">Please enter a valid expiry date</div> </div> </div> <div class="form-col"> <div class="form-group"> <label for="cvv">Security Code</label> <input type="text" class="form-control" id="cvv" placeholder="CVV"> <div class="error-message">Please enter a valid security code</div> </div> </div> </div> <div class="form-group"> <label for="name-on-card">Name on Card</label> <input type="text" class="form-control" id="name-on-card" placeholder="Name as it appears on your card"> <div class="error-message">Please enter the name on your card</div> </div> <div class="checkbox-container"> <input type="checkbox" id="save-card" class="checkbox-input"> <div class="checkbox-custom"></div> <label for="save-card" class="checkbox-label">Save card for future purchases</label> </div> </div> <!-- Step 4: Order Confirmation --> <div class="step-content" id="step-4"> <div class="cart-summary"> <div class="summary-row"> <div class="summary-label">Products (2)</div> <div class="summary-value">$219.98</div> </div> <div class="summary-row"> <div class="summary-label">Shipping</div> <div class="summary-value">$4.99</div> </div> <div class="summary-row"> <div class="summary-label">Tax</div> <div class="summary-value">$13.20</div> </div> <div class="summary-row"> <div class="summary-label">Total</div> <div class="summary-value">$238.17</div> </div> </div> <div class="form-group" style="margin-top: 20px;"> <label for="promo">Promo Code</label> <div class="input-icon"> <i class="icon">🏷️</i> <input type="text" class="form-control" id="promo" placeholder="Enter promo code"> </div> </div> <div class="checkbox-container"> <input type="checkbox" id="terms" class="checkbox-input"> <div class="checkbox-custom"></div> <label for="terms" class="checkbox-label">I agree to the <a href="#">Terms & Conditions</a> and <a href="#">Privacy Policy</a></label> </div> <div style="margin-top: 20px; font-size: 13px; color: var(--text-light);"> <p>By completing this purchase, you'll earn <strong style="color: var(--primary);">238</strong> loyalty points!</p> </div> </div> <!-- Step 5: Success --> <div class="step-content" id="step-5"> <div class="success-animation"> <div class="checkmark-circle"> <svg class="checkmark" xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 52 52"> <circle class="checkmark-circle" cx="26" cy="26" r="25" fill="none" stroke="white" stroke-width="2"/> <path class="checkmark-check" fill="none" stroke="white" stroke-width="3" d="M14.1 27.2l7.1 7.2 16.7-16.8"/> </svg> </div> <div class="success-message"> <h3>Payment Successful!</h3> <p>Your order has been placed and will be shipped soon.</p> <p>A confirmation email has been sent to your inbox.</p> <div class="order-info"> <div class="order-row"> <div class="order-label">Order ID</div> <div class="order-value">#AF80392</div> </div> <div class="order-row"> <div class="order-label">Amount Paid</div> <div class="order-value">$238.17</div> </div> <div class="order-row"> <div class="order-label">Estimated Delivery</div> <div class="order-value">Sep 18 - Sep 24</div> </div> </div> </div> </div> </div> </div> <div class="checkout-footer"> <button class="btn btn-back" id="btn-back" style="visibility: hidden;">Back</button> <button class="btn btn-next" id="btn-next">Next Step</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Elements const modal = document.getElementById('checkout-modal'); const backdrop = document.getElementById('backdrop'); const openBtn = document.getElementById('open-checkout'); const closeBtn = document.getElementById('close-btn'); const nextBtn = document.getElementById('btn-next'); const backBtn = document.getElementById('btn-back'); const progressSteps = document.querySelectorAll('.progress-step'); const stepContents = document.querySelectorAll('.step-content'); const progressLine = document.querySelector('.progress-line'); const progressDot = document.getElementById('progress-dot'); // Payment method selection const paymentMethods = document.querySelectorAll('.payment-method'); // Quantity controls const minusBtns = document.querySelectorAll('.quantity-btn.minus'); const plusBtns = document.querySelectorAll('.quantity-btn.plus'); let
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Healthcare Appointment Booking</title> <style> @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=Source+Serif+Pro:wght@300;400;600&display=swap'); :root { --primary: #3a74cf; --primary-light: #edf2fa; --primary-dark: #2a5ba8; --secondary: #e3f0ff; --accent: #64a2ff; --gray-100: #f8f9fa; --gray-200: #e9ecef; --gray-300: #dee2e6; --gray-400: #ced4da; --gray-500: #adb5bd; --gray-600: #6c757d; --gray-700: #495057; --gray-800: #343a40; --success: #4CAF50; --error: #f44336; --border-radius: 8px; --shadow: 0 4px 12px rgba(0, 0, 0, 0.08); --transition: all 0.3s ease; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Source Serif Pro', serif; color: var(--gray-800); background-color: var(--gray-100); display: flex; justify-content: center; align-items: center; min-height: 100vh; line-height: 1.6; padding: 20px; } .container { max-width: 680px; width: 100%; position: relative; } .btn { padding: 12px 24px; border: none; background-color: var(--primary); color: white; border-radius: var(--border-radius); font-family: 'Playfair Display', serif; font-weight: 600; cursor: pointer; font-size: 16px; transition: var(--transition); display: inline-block; } .btn:hover { background-color: var(--primary-dark); transform: translateY(-2px); box-shadow: 0 6px 15px rgba(58, 116, 207, 0.25); } .btn:active { transform: translateY(0); } .btn-secondary { background-color: white; color: var(--primary); border: 1px solid var(--primary); } .btn-secondary:hover { background-color: var(--primary-light); } .modal-overlay { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(0, 0, 0, 0.5); backdrop-filter: blur(3px); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; visibility: hidden; transition: var(--transition); } .modal-overlay.active { opacity: 1; visibility: visible; } .modal { background-color: white; border-radius: var(--border-radius); box-shadow: var(--shadow); width: 100%; max-width: 560px; position: relative; transform: translateY(20px); transition: var(--transition); overflow: hidden; } .modal-overlay.active .modal { transform: translateY(0); } .modal-header { padding: 24px; background-color: var(--primary); color: white; position: relative; overflow: hidden; } .modal-header::before { content: ''; position: absolute; width: 200px; height: 200px; background-color: rgba(255, 255, 255, 0.1); border-radius: 50%; top: -100px; right: -100px; } .modal-header::after { content: ''; position: absolute; width: 150px; height: 150px; background-color: rgba(255, 255, 255, 0.1); border-radius: 50%; bottom: -75px; left: -75px; } .modal-title { font-family: 'Playfair Display', serif; font-size: 24px; font-weight: 700; margin-bottom: 8px; position: relative; z-index: 1; } .modal-subtitle { font-weight: 300; opacity: 0.9; margin-bottom: 0; position: relative; z-index: 1; } .modal-body { padding: 24px; max-height: 400px; overflow-y: auto; } .progress-bar { height: 4px; background-color: var(--gray-300); margin-bottom: 16px; border-radius: 4px; overflow: hidden; } .progress-fill { height: 100%; background-color: var(--primary); transition: width 0.5s ease; width: 0%; } .step { display: none; } .step.active { display: block; animation: fadeIn 0.4s ease; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .form-group { margin-bottom: 20px; } .form-label { display: block; margin-bottom: 8px; font-weight: 500; color: var(--gray-700); } .form-input { width: 100%; padding: 12px 16px; border: 1px solid var(--gray-300); border-radius: var(--border-radius); font-family: 'Source Serif Pro', serif; font-size: 16px; transition: var(--transition); } .form-input:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 3px rgba(58, 116, 207, 0.2); } .form-input.error { border-color: var(--error); } .form-error { font-size: 14px; color: var(--error); margin-top: 4px; display: none; } .form-error.visible { display: block; animation: shake 0.4s ease; } @keyframes shake { 0%, 100% { transform: translateX(0); } 20%, 60% { transform: translateX(-5px); } 40%, 80% { transform: translateX(5px); } } .calendar { display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px; margin-bottom: 20px; } .calendar-header { grid-column: 1 / span 7; display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .calendar-title { font-family: 'Playfair Display', serif; font-size: 18px; font-weight: 600; } .calendar-nav { display: flex; gap: 8px; } .calendar-nav-btn { background-color: var(--gray-100); border: none; width: 32px; height: 32px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: var(--transition); } .calendar-nav-btn:hover { background-color: var(--gray-200); } .weekday { text-align: center; font-weight: 600; font-size: 14px; color: var(--gray-600); padding: 8px 0; } .day { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; border-radius: var(--border-radius); cursor: pointer; font-size: 15px; font-weight: 500; transition: var(--transition); user-select: none; position: relative; } .day.inactive { color: var(--gray-400); cursor: default; } .day.today { border: 1px dashed var(--primary); } .day.available:not(.inactive):hover { background-color: var(--primary-light); } .day.available:not(.inactive):active { background-color: var(--secondary); } .day.selected { background-color: var(--primary); color: white; } .day.has-slots::after { content: ''; position: absolute; width: 4px; height: 4px; background-color: var(--accent); border-radius: 50%; bottom: 4px; } .time-slots { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 16px; } .time-slot { padding: 10px; border: 1px solid var(--gray-300); border-radius: var(--border-radius); text-align: center; cursor: pointer; transition: var(--transition); } .time-slot:hover { border-color: var(--primary); background-color: var(--primary-light); } .time-slot.selected { background-color: var(--primary); color: white; border-color: var(--primary); } .modal-footer { padding: 16px 24px; display: flex; justify-content: space-between; border-top: 1px solid var(--gray-200); } .specialty-select { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-top: 16px; } .specialty-option { border: 1px solid var(--gray-300); border-radius: var(--border-radius); padding: 16px; cursor: pointer; transition: var(--transition); } .specialty-option:hover { border-color: var(--primary); background-color: var(--primary-light); } .specialty-option.selected { border-color: var(--primary); background-color: var(--primary-light); } .specialty-icon { display: flex; justify-content: center; margin-bottom: 12px; font-size: 24px; color: var(--primary); } .specialty-title { font-weight: 600; text-align: center; margin-bottom: 4px; } .specialty-desc { font-size: 14px; color: var(--gray-600); text-align: center; } .doctor-list { display: grid; grid-template-columns: 1fr; gap: 16px; margin-top: 16px; } .doctor-card { display: flex; gap: 16px; padding: 16px; border: 1px solid var(--gray-300); border-radius: var(--border-radius); cursor: pointer; transition: var(--transition); } .doctor-card:hover { border-color: var(--primary); background-color: var(--primary-light); transform: translateY(-2px); box-shadow: var(--shadow); } .doctor-card.selected { border-color: var(--primary); background-color: var(--primary-light); } .doctor-avatar { width: 64px; height: 64px; border-radius: 50%; background-color: var(--gray-200); overflow: hidden; position: relative; } .doctor-avatar img { width: 100%; height: 100%; object-fit: cover; } .doctor-info { flex: 1; } .doctor-name { font-family: 'Playfair Display', serif; font-weight: 600; margin-bottom: 4px; } .doctor-specialty { font-size: 14px; color: var(--primary); margin-bottom: 4px; } .doctor-details { font-size: 14px; color: var(--gray-600); display: flex; gap: 8px; } .summary-section { margin-bottom: 20px; padding-bottom: 20px; border-bottom: 1px solid var(--gray-200); } .summary-section:last-child { border-bottom: none; margin-bottom: 0; padding-bottom: 0; } .summary-title { font-weight: 600; margin-bottom: 8px; font-family: 'Playfair Display', serif; color: var(--primary); } .summary-detail { display: flex; gap: 8px; margin-bottom: 4px; } .summary-label { width: 120px; color: var(--gray-600); } .summary-value { font-weight: 500; flex: 1; } .success-animation { text-align: center; margin: 32px 0; } .checkmark { width: 80px; height: 80px; border-radius: 50%; display: block; stroke-width: 2; stroke: #fff; stroke-miterlimit: 10; margin: 0 auto 20px; box-shadow: inset 0px 0px 0px var(--success); animation: fill .4s ease-in-out .4s forwards, scale .3s ease-in-out .9s both; } .checkmark__circle { stroke-dasharray: 166; stroke-dashoffset: 166; stroke-width: 2; stroke-miterlimit: 10; stroke: var(--success); fill: none; animation: stroke .6s cubic-bezier(0.65, 0, 0.45, 1) forwards; } .checkmark__check { transform-origin: 50% 50%; stroke-dasharray: 48; stroke-dashoffset: 48; animation: stroke .3s cubic-bezier(0.65, 0, 0.45, 1) .8s forwards; } @keyframes stroke { 100% { stroke-dashoffset: 0; } } @keyframes scale { 0%, 100% { transform: none; } 50% { transform: scale3d(1.1, 1.1, 1); } } @keyframes fill { 100% { box-shadow: inset 0px 0px 0px 30px var(--success); } } .success-title { font-family: 'Playfair Display', serif; font-size: 24px; font-weight: 700; margin-bottom: 8px; color: var(--success); } .success-message { margin-bottom: 24px; color: var(--gray-700); } /* Trust markers */ .trust-markers { display: flex; justify-content: center; gap: 16px; margin-top: 24px; color: var(--gray-600); font-size: 14px; } .trust-marker { display: flex; align-items: center; gap: 6px; } .trust-marker i { color: var(--primary); } /* Animations and effects */ .pulse { animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.05); } 100% { transform: scale(1); } } /* Responsive styles */ @media (max-width: 600px) { .time-slots { grid-template-columns: repeat(2, 1fr); } .specialty-select { grid-template-columns: 1fr; } .doctor-card { flex-direction: column; align-items: center; text-align: center; } .doctor-details { justify-content: center; } .summary-detail { flex-direction: column; gap: 2px; } .summary-label { width: auto; } .modal-footer { flex-direction: column; gap: 10px; } .modal-footer .btn { width: 100%; text-align: center; } } </style> </head> <body> <div class="container"> <button id="open-modal" class="btn pulse">Schedule Your Appointment</button> <div id="modal-overlay" class="modal-overlay"> <div class="modal"> <div class="modal-header"> <h2 class="modal-title">Schedule Your Appointment</h2> <p class="modal-subtitle">We're here to help you get the care you need</p> </div> <div class="progress-bar"> <div class="progress-fill" id="progress"></div> </div> <div class="modal-body"> <!-- Step 1: Select Specialty --> <div class="step active" id="step-1"> <h3>What type of care do you need?</h3> <p>Select a specialty to find the right doctor for your needs.</p> <div class="specialty-select"> <div class="specialty-option" data-specialty="primary-care"> <div class="specialty-icon"> <i>👨⚕️</i> </div> <div class="specialty-title">Primary Care</div> <div class="specialty-desc">Annual checkups, minor illnesses, preventive care</div> </div> <div class="specialty-option" data-specialty="cardiology"> <div class="specialty-icon"> <i>❤️</i> </div> <div class="specialty-title">Cardiology</div> <div class="specialty-desc">Heart conditions, chest pain, palpitations</div> </div> <div class="specialty-option" data-specialty="dermatology"> <div class="specialty-icon"> <i>🧴</i> </div> <div class="specialty-title">Dermatology</div> <div class="specialty-desc">Skin conditions, rashes, acne, mole checks</div> </div> <div class="specialty-option" data-specialty="orthopedics"> <div class="specialty-icon"> <i>🦴</i> </div> <div class="specialty-title">Orthopedics</div> <div class="specialty-desc">Joint pain, injuries, bone health</div> </div> </div> </div> <!-- Step 2: Select Doctor --> <div class="step" id="step-2"> <h3>Choose your healthcare provider</h3> <p>Select a doctor from our team of specialists.</p> <div class="doctor-list"> <div class="doctor-card" data-doctor="dr-thompson"> <div class="doctor-avatar"> <img src="data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3e%3ccircle fill='%233a74cf' cx='32' cy='32' r='32'/%3e%3ccircle fill='%23ffffff' cx='32' cy='26' r='10'/%3e%3cpath fill='%23ffffff' d='M32,40 C22,40 18,46 18,52 L46,52 C46,46 42,40 32,40 Z'/%3e%3c/svg%3e" alt="Dr. Thompson"> </div> <div class="doctor-info"> <div class="doctor-name">Dr. Sarah Thompson</div> <div class="doctor-specialty">Primary Care Physician</div> <div class="doctor-details"> <span>⭐ 4.9 (243 reviews)</span> <span>• 12 years exp.</span> </div> </div> </div> <div class="doctor-card" data-doctor="dr-patel"> <div class="doctor-avatar"> <img src="data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3e%3ccircle fill='%233a74cf' cx='32' cy='32' r='32'/%3e%3ccircle fill='%23ffffff' cx='32' cy='26' r='10'/%3e%3cpath fill='%23ffffff' d='M32,40 C22,40 18,46 18,52 L46,52 C46,46 42,40 32,40 Z'/%3e%3c/svg%3e" alt="Dr. Patel"> </div> <div class="doctor-info"> <div class="doctor-name">Dr. Raj Patel</div> <div class="doctor-specialty">Cardiologist</div> <div class="doctor-details"> <span>⭐ 4.8 (196 reviews)</span> <span>• 15 years exp.</span> </div> </div> </div> <div class="doctor-card" data-doctor="dr-miller"> <div class="doctor-avatar"> <img src="data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='64' height='64' viewBox='0 0 64 64'%3e%3ccircle fill='%233a74cf' cx='32' cy='32' r='32'/%3e%3ccircle fill='%23ffffff' cx='32' cy='26' r='10'/%3e%3cpath fill='%23ffffff' d='M32,40 C22,40 18,46 18,52 L46,52 C46,46 42,40 32,40 Z'/%3e%3c/svg%3e" alt="Dr. Miller"> </div> <div class="doctor-info"> <div class="doctor-name">Dr. Emma Miller</div> <div class="doctor-specialty">Dermatologist</div> <div class="doctor-details"> <span>⭐ 4.7 (187 reviews)</span> <span>• 8 years exp.</span> </div> </div> </div> </div> </div> <!-- Step 3: Select Date --> <div class="step" id="step-3"> <h3>Select an appointment date</h3> <p>Choose a day that works for your schedule.</p> <div class="calendar-header"> <div class="calendar-title">May 2023</div> <div class="calendar-nav"> <button class="calendar-nav-btn" id="prev-month"> ← </button> <button class="calendar-nav-btn" id="next-month"> → </button> </div> </div> <div class="calendar" id="calendar"> <div class="weekday">Sun</div> <div class="weekday">Mon</div> <div class="weekday">Tue</div> <div class="weekday">Wed</div> <div class="weekday">Thu</div> <div class="weekday">Fri</div> <div class="weekday">Sat</div> <!-- Calendar days will be populated by JavaScript --> </div> <div class="time-slots" id="time-slots"> <div class="time-slot" data-time="09:00">9:00 AM</div> <div class="time-slot" data-time="09:30">9:30 AM</div> <div class="time-slot" data-time="10:00">10:00 AM</div> <div class="time-slot" data-time="10:30">10:30 AM</div> <div class="time-slot" data-time="11:00">11:00 AM</div> <div class="time-slot" data-time="11:30">11:30 AM</div> <div class="time-slot" data-time="13:00">1:00 PM</div> <div class="time-slot" data-time="13:30">1:30 PM</div> <div class="time-slot" data-time="14:00">2:00 PM</div> </div> </div> <!-- Step 4: Patient Information --> <div class="step" id="step-4"> <h3>Your Information</h3> <p>Please provide your details to confirm your appointment.</p> <div class="form-group"> <label class="form-label" for="name">Full Name</label> <input type="text" id="name" class="form-input" placeholder="Enter your full name"> <div class="form-error" id="name-error">Please enter your full name</div> </div> <div class="form-group"> <label class="form-label" for="email">Email Address</label> <input type="email" id="email" class="form-input" placeholder="Enter your email address"> <div class="form-error" id="email-error">Please enter a valid email address</div> </div> <div class="form-group"> <label class="form-label" for="phone">Phone Number</label> <input type="tel" id="phone" class="form-input" placeholder="Enter your phone number"> <div class="form-error" id="phone-error">Please enter a valid phone number</div> </div> <div class="form-group"> <label class="form-label" for="reason">Reason for Visit</label> <input type="text" id="reason" class="form-input" placeholder="Briefly describe your symptoms or reason"> <div class="form-error" id="reason-error">Please enter a reason for your visit</div> </div> </div> <!-- Step 5: Confirm Appointment --> <div class="step" id="step-5"> <h3>Review and Confirm</h3> <p>Please review your appointment details before confirming.</p> <div class="summary-section"> <div class="summary-title">Provider</div> <div class="summary-detail"> <div class="summary-label">Doctor:</div> <div class="summary-value" id="summary-doctor">Dr. Sarah Thompson</div> </div> <div class="summary-detail"> <div class="summary-label">Specialty:</div> <div class="summary-value" id="summary-specialty">Primary Care</div> </div> </div> <div class="summary-section"> <div class="summary-title">Appointment</div> <div class="summary-detail"> <div class="summary-label">Date:</div> <div class="summary-value" id="summary-date">May 15, 2023</div> </div> <div class="summary-detail"> <div class="summary-label">Time:</div> <div class="summary-value" id="summary-time">10:00 AM</div> </div> <div class="summary-detail"> <div class="summary-label">Reason:</div> <div class="summary-value" id="summary-reason">Annual physical examination</div> </div> </div> <div class="summary-section"> <div class="summary-title">Your Information</div> <div class="summary-detail"> <div class="summary-label">Name:</div> <div class="summary-value" id="summary-name">John Doe</div> </div> <div class="summary-detail"> <div class="summary-label">Email:</div> <div class="summary-value" id="summary-email">[email protected]</div> </div> <div class="summary-detail"> <div class="summary-label">Phone:</div> <div class="summary-value" id="summary-phone">(123) 456-7890</div> </div> </div> <div class="trust-markers"> <div class="trust-marker"> <i>🔒</i> Secure booking </div> <div class="trust-marker"> <i>⏱️</i> Instant confirmation </div> <div class="trust-marker"> <i>📱</i> Email reminder </div> </div> </div> <!-- Step 6: Success --> <div class="step" id="step-6"> <div class="success-animation"> <svg class="checkmark" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 52 52"> <circle class="checkmark__circle" cx="26" cy="26" r="25" fill="none"/> <path class="checkmark__check" fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/> </svg> <h3 class="success-title">Appointment Confirmed!</h3> <p class="success-message">Your appointment has been successfully scheduled. A confirmation has been sent to your email.</p> </div> <div class="summary-section"> <div class="summary-title">Appointment Details</div> <div class="summary-detail"> <div class="summary-label">Provider:</div> <div class="summary-value" id="final-doctor">Dr. Sarah Thompson</div> </div> <div class="summary-detail"> <div class="summary-label">Date & Time:</div> <div class="summary-value" id="final-datetime">May 15, 2023 at 10:00 AM</div> </div> <div class="summary-detail"> <div class="summary-label">Location:</div> <div class="summary-value">Northside Medical Center<br>123 Health Avenue, Suite 200</div> </div> </div> <div class="trust-markers"> <div class="trust-marker"> <i>📅</i> Added to your calendar </div> <div class="trust-marker"> <i>📩</i> Email sent </div> </div> </div> </div> <div class="modal-footer"> <button class="btn btn-secondary" id="btn-back" style="display: none;">Back</button> <button class="btn" id="btn-next">Next</button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Elements const openModalBtn = document.getElementById('open-modal'); const modalOverlay = document.getElementById('modal-overlay'); const backBtn = document.getElementById('btn-back'); const nextBtn = document.getElementById('btn-next'); const progressBar = document.getElementById('progress'); const steps = document.querySelectorAll('.step'); const calendar = document.getElementById('calendar'); const timeSlots = document.getElementById('time-slots'); const prevMonthBtn = document.getElementById('prev-month'); const nextMonthBtn = document.getElementById('next-month'); // Variables let currentStep = 1; const totalSteps = steps.length; let selectedSpecialty = null; let selectedDoctor = null; let selectedDate = null; let selectedTime = null; let currentMonth = new Date().getMonth(); let currentYear = new Date().getFullYear(); // Open modal openModalBtn.addEventListener('click', function() { modalOverlay.classList.add('active'); updateCalendar(); }); // Close modal when clicking outside modalOverlay.addEventListener('click', function(e) { if (e.target === modalOverlay) { modalOverlay.classList.remove('active'); } }); // Update progress bar function updateProgress() { const progress = ((currentStep - 1) / (totalSteps - 1)) * 100; progressBar.style.width = `${progress}%`; } // Show current step function showStep(stepNumber) { steps.forEach((step, index) => { if (index + 1 === stepNumber) { step.classList.add('active'); } else { step.classList.remove('active'); } }); // Update buttons if (stepNumber === 1) { backBtn.style.display = 'none'; } else { backBtn.style.display = 'block'; } if (stepNumber === totalSteps) { nextBtn.style.display = 'none'; } else if (stepNumber === totalSteps - 1) { nextBtn.textContent = 'Confirm Appointment'; } else { nextBtn.style.display = 'block'; nextBtn.textContent = 'Next'; } updateProgress(); } // Navigate to next step nextBtn.addEventListener('click', function() { if (validateCurrentStep()) { if (currentStep === totalSteps - 1) { // Submit appointment submitAppointment(); } else { currentStep++; showStep(currentStep); } } }); // Navigate to previous step backBtn.addEventListener('click', function() { if (currentStep > 1) { currentStep--; showStep(currentStep); } }); // Validate current step function validateCurrentStep() { switch (currentStep) { case 1: return validateSpecialty(); case 2: return validateDoctor(); case 3: return validateDateTime(); case 4: return validatePatientInfo(); default: return true; } } // Specialty selection const specialtyOptions = document.querySelectorAll('.specialty-option'); specialtyOptions.forEach(option => { option.addEventListener('click', function() {
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary: #1E3A8A; --danger: #DC2626; --warning: #F59E0B; --success: #10B981; --text: #F3F4F6; --text-secondary: #9CA3AF; --background: #111827; --background-secondary: #1F2937; --accent: #6366F1; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } body { background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; height: 100vh; color: var(--text); font-size: 16px; line-height: 1.5; overflow: hidden; } .dashboard-container { width: 100%; max-width: 700px; height: 700px; background-color: var(--background); border-radius: 12px; overflow: hidden; position: relative; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5); } .dashboard-header { background-color: var(--background-secondary); padding: 16px 24px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .dashboard-logo { display: flex; align-items: center; } .dashboard-logo h1 { font-size: 18px; font-weight: 600; margin-left: 10px; } .dashboard-logo svg { width: 24px; height: 24px; fill: var(--accent); } .user-profile { display: flex; align-items: center; } .user-avatar { width: 32px; height: 32px; border-radius: 50%; background-color: var(--primary); display: flex; align-items: center; justify-content: center; font-weight: 600; margin-left: 10px; } .dashboard-content { padding: 20px; height: calc(100% - 65px); overflow-y: auto; background: linear-gradient(to bottom, var(--background) 0%, rgba(31, 41, 55, 0.8) 100%); position: relative; } .stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; margin-bottom: 20px; } .stat-card { background-color: var(--background-secondary); border-radius: 8px; padding: 16px; transition: transform 0.3s ease; } .stat-card:hover { transform: translateY(-5px); } .stat-title { color: var(--text-secondary); font-size: 14px; margin-bottom: 8px; } .stat-value { font-size: 24px; font-weight: 700; } .stat-trend { display: flex; align-items: center; margin-top: 8px; font-size: 14px; } .up-trend { color: var(--success); } .down-trend { color: var(--danger); } .trend-icon { margin-right: 4px; } .chart-container { background-color: var(--background-secondary); border-radius: 8px; padding: 16px; height: 220px; margin-bottom: 20px; position: relative; } .chart-title { display: flex; justify-content: space-between; margin-bottom: 16px; } .chart-title h3 { font-size: 16px; font-weight: 600; } .chart-period { display: flex; gap: 10px; } .period-btn { background: transparent; border: 1px solid rgba(255, 255, 255, 0.1); color: var(--text-secondary); padding: 4px 10px; border-radius: 4px; cursor: pointer; font-size: 12px; transition: all 0.2s ease; } .period-btn.active { background-color: var(--primary); color: white; border-color: var(--primary); } .period-btn:hover:not(.active) { background-color: rgba(255, 255, 255, 0.05); } /* Alert Modal */ .alert-modal-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.85); display: flex; justify-content: center; align-items: center; z-index: 100; backdrop-filter: blur(5px); opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .alert-modal-overlay.active { opacity: 1; pointer-events: all; } .alert-modal { background-color: var(--background-secondary); width: 90%; max-width: 500px; border-radius: 12px; overflow: hidden; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.7); transform: translateY(20px); opacity: 0; transition: all 0.4s cubic-bezier(0.19, 1, 0.22, 1); } .alert-modal.active { transform: translateY(0); opacity: 1; } .alert-header { padding: 20px; background-color: var(--danger); display: flex; align-items: center; justify-content: space-between; position: relative; overflow: hidden; } .alert-header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); transform: translateX(-100%); animation: shine 3s infinite; } @keyframes shine { 100% { transform: translateX(100%); } } .alert-title { display: flex; align-items: center; } .alert-title svg { width: 24px; height: 24px; margin-right: 12px; } .alert-title h2 { font-size: 20px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; } .alert-close { background: transparent; border: none; color: white; cursor: pointer; width: 32px; height: 32px; border-radius: 50%; display: flex; align-items: center; justify-content: center; transition: background-color 0.2s; } .alert-close:hover { background-color: rgba(255, 255, 255, 0.1); } .alert-body { padding: 24px; } .alert-message { margin-bottom: 24px; } .alert-message p { margin-bottom: 16px; font-size: 15px; } .alert-message strong { color: var(--danger); } .alert-visualization { background-color: rgba(0, 0, 0, 0.2); border-radius: 8px; padding: 20px; margin-bottom: 24px; height: 180px; position: relative; overflow: hidden; } .visualization-title { font-size: 14px; color: var(--text-secondary); margin-bottom: 12px; display: flex; justify-content: space-between; } .alert-metrics { display: flex; gap: 16px; margin-bottom: 24px; } .metric { flex: 1; background-color: rgba(0, 0, 0, 0.2); border-radius: 8px; padding: 16px; } .metric-title { font-size: 13px; color: var(--text-secondary); margin-bottom: 8px; } .metric-value { font-size: 20px; font-weight: 700; } .metric.negative .metric-value { color: var(--danger); } .alert-actions { display: flex; gap: 12px; } .btn { flex: 1; padding: 12px; border-radius: 6px; border: none; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.2s; display: flex; justify-content: center; align-items: center; } .btn svg { margin-right: 8px; width: 18px; height: 18px; } .btn-primary { background-color: var(--primary); color: white; } .btn-primary:hover { background-color: #2540a0; } .btn-secondary { background-color: transparent; border: 1px solid rgba(255, 255, 255, 0.1); color: var(--text); } .btn-secondary:hover { background-color: rgba(255, 255, 255, 0.05); } .countdown { text-align: center; margin-top: 16px; font-size: 13px; color: var(--text-secondary); } .alert-indicator { position: absolute; top: 20px; right: 20px; width: 10px; height: 10px; border-radius: 50%; background-color: var(--danger); box-shadow: 0 0 10px var(--danger); animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.5); opacity: 0.5; } 100% { transform: scale(1); opacity: 1; } } /* Chart Styles */ .chart-line { position: absolute; bottom: 40px; left: 40px; width: calc(100% - 80px); height: 60%; overflow: hidden; } .chart-path { stroke-dasharray: 1000; stroke-dashoffset: 1000; animation: dash 2s ease-in-out forwards; } @keyframes dash { to { stroke-dashoffset: 0; } } .threshold-line { stroke: var(--danger); stroke-dasharray: 5; stroke-width: 1; } .threshold-label { position: absolute; right: 20px; color: var(--danger); font-size: 12px; padding: 2px 6px; border-radius: 4px; background-color: rgba(220, 38, 38, 0.1); } .chart-dot { position: absolute; width: 10px; height: 10px; border-radius: 50%; background-color: var(--danger); box-shadow: 0 0 10px var(--danger); transform: translate(-50%, -50%); z-index: 2; } .alert-point { animation: alertPulse 2s infinite; } @keyframes alertPulse { 0% { transform: translate(-50%, -50%) scale(1); box-shadow: 0 0 10px var(--danger); } 50% { transform: translate(-50%, -50%) scale(1.5); box-shadow: 0 0 20px var(--danger); } 100% { transform: translate(-50%, -50%) scale(1); box-shadow: 0 0 10px var(--danger); } } .time-labels { position: absolute; bottom: 10px; left: 40px; width: calc(100% - 80px); display: flex; justify-content: space-between; } .time-label { font-size: 11px; color: var(--text-secondary); } /* Responsive adjustments */ @media (max-width: 600px) { .stats-grid { grid-template-columns: repeat(2, 1fr); } .alert-metrics { flex-direction: column; gap: 8px; } .alert-title h2 { font-size: 18px; } .alert-actions { flex-direction: column; } } @media (max-width: 400px) { .stats-grid { grid-template-columns: 1fr; } .dashboard-header { padding: 12px; } .dashboard-logo h1 { font-size: 16px; } } /* Notification badge animation */ .notification-badge { position: absolute; top: -5px; right: -5px; width: 16px; height: 16px; border-radius: 50%; background-color: var(--danger); display: flex; align-items: center; justify-content: center; font-size: 10px; font-weight: bold; animation: badgePulse 2s infinite; } @keyframes badgePulse { 0% { transform: scale(1); } 50% { transform: scale(1.2); } 100% { transform: scale(1); } } /* Button hover effects */ .notification-btn { position: relative; background: transparent; border: none; color: var(--text); cursor: pointer; width: 32px; height: 32px; border-radius: 4px; display: flex; align-items: center; justify-content: center; transition: background-color 0.2s; } .notification-btn:hover { background-color: rgba(255, 255, 255, 0.1); } </style> </head> <body> <div class="dashboard-container"> <div class="dashboard-header"> <div class="dashboard-logo"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <path d="M12 2L2 7L12 12L22 7L12 2Z" /> <path d="M2 17L12 22L22 17" /> <path d="M2 12L12 17L22 12" /> </svg> <h1>FinPulse Analytics</h1> </div> <div class="user-profile"> <button class="notification-btn" id="alertTrigger"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path> <path d="M13.73 21a2 2 0 0 1-3.46 0"></path> </svg> <div class="notification-badge">1</div> </button> <div class="user-avatar">TS</div> </div> </div> <div class="dashboard-content"> <div class="stats-grid"> <div class="stat-card"> <div class="stat-title">Cash Position</div> <div class="stat-value">$1.42M</div> <div class="stat-trend up-trend"> <span class="trend-icon">↑</span> 3.2% </div> </div> <div class="stat-card"> <div class="stat-title">Burn Rate</div> <div class="stat-value">$247K</div> <div class="stat-trend down-trend"> <span class="trend-icon">↓</span> 5.8% </div> </div> <div class="stat-card"> <div class="stat-title">Runway</div> <div class="stat-value">5.7 mo</div> <div class="stat-trend down-trend"> <span class="trend-icon">↓</span> 1.2 mo </div> </div> </div> <div class="chart-container"> <div class="chart-title"> <h3>Cash Flow Projection</h3> <div class="chart-period"> <button class="period-btn">1M</button> <button class="period-btn active">3M</button> <button class="period-btn">6M</button> <button class="period-btn">1Y</button> </div> </div> <svg width="100%" height="150" viewBox="0 0 500 150" preserveAspectRatio="none"> <path d="M0,75 C50,65 100,45 150,55 C200,65 250,85 300,80 C350,75 400,25 450,15 L450,150 L0,150 Z" fill="rgba(99, 102, 241, 0.1)" stroke="var(--accent)" stroke-width="2"></path> </svg> </div> <!-- Alert indicator in corner --> <div class="alert-indicator"></div> </div> <!-- Alert Modal --> <div class="alert-modal-overlay" id="alertModal"> <div class="alert-modal"> <div class="alert-header"> <div class="alert-title"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path> <line x1="12" y1="9" x2="12" y2="13"></line> <line x1="12" y1="17" x2="12.01" y2="17"></line> </svg> <h2>Critical Cashflow Alert</h2> </div> <button class="alert-close" id="closeAlert"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <line x1="18" y1="6" x2="6" y2="18"></line> <line x1="6" y1="6" x2="18" y2="18"></line> </svg> </button> </div> <div class="alert-body"> <div class="alert-message"> <p>Your projected runway has fallen below <strong>6 months</strong> due to unexpected Q3 expense increases, primarily in cloud infrastructure costs (+42%) and marketing spend overages (+28%).</p> <p>Immediate attention is required to prevent potential liquidity issues by Q1 2024.</p> </div> <div class="alert-visualization"> <div class="visualization-title"> <span>Runway Projection Trend</span> <span>Updated: Today, 9:34 AM</span> </div> <div class="chart-line"> <svg width="100%" height="100%" viewBox="0 0 400 100" preserveAspectRatio="none"> <!-- Threshold line --> <line x1="0" y1="40" x2="400" y2="40" class="threshold-line" /> <!-- Actual line chart --> <path d="M0,20 C40,15 80,25 120,30 C160,35 200,20 240,50 C280,80 320,85 360,90" fill="none" stroke="var(--danger)" stroke-width="2" class="chart-path" /> </svg> <!-- The critical alert point --> <div class="chart-dot alert-point" style="top: 50%; left: 60%;"></div> <!-- Threshold label --> <div class="threshold-label" style="top: 35%;">6 Month Threshold</div> <!-- Time labels --> <div class="time-labels"> <div class="time-label">Aug</div> <div class="time-label">Sep</div> <div class="time-label">Oct</div> <div class="time-label">Nov</div> <div class="time-label">Dec</div> </div> </div> </div> <div class="alert-metrics"> <div class="metric negative"> <div class="metric-title">Current Runway</div> <div class="metric-value">5.7 months</div> </div> <div class="metric"> <div class="metric-title">Monthly Burn</div> <div class="metric-value">$247,500</div> </div> <div class="metric negative"> <div class="metric-title">Cash Depletion Date</div> <div class="metric-value">May 2024</div> </div> </div> <div class="alert-actions"> <button class="btn btn-primary"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon> </svg> View Action Plan </button> <button class="btn btn-secondary" id="dismissBtn"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <circle cx="12" cy="12" r="10"></circle> <line x1="15" y1="9" x2="9" y2="15"></line> <line x1="9" y1="9" x2="15" y2="15"></line> </svg> Dismiss for 24h </button> </div> <div class="countdown"> This alert will auto-escalate to leadership in <strong>23:14:52</strong> </div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const alertTrigger = document.getElementById('alertTrigger'); const alertModal = document.getElementById('alertModal'); const closeAlert = document.getElementById('closeAlert'); const dismissBtn = document.getElementById('dismissBtn'); const alertModalContent = document.querySelector('.alert-modal'); // Show alert modal with animation function showAlertModal() { alertModal.classList.add('active'); setTimeout(() => { alertModalContent.classList.add('active'); }, 100); } // Hide alert modal with animation function hideAlertModal() { alertModalContent.classList.remove('active'); setTimeout(() => { alertModal.classList.remove('active'); }, 300); } // Listen for clicks on the notification icon alertTrigger.addEventListener('click', showAlertModal); // Listen for clicks on the close button closeAlert.addEventListener('click', hideAlertModal); // Listen for clicks on the dismiss button dismissBtn.addEventListener('click', function() { // Show a brief confirmation animation this.innerHTML = ` <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <path d="M20 6L9 17l-5-5"></path> </svg> Alert Snoozed `; // After a delay, close the modal setTimeout(() => { hideAlertModal(); // Remove the notification badge document.querySelector('.notification-badge').style.display = 'none'; // Reset button text after modal is closed setTimeout(() => { this.innerHTML = ` <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <circle cx="12" cy="12" r="10"></circle> <line x1="15" y1="9" x2="9" y2="15"></line> <line x1="9" y1="9" x2="15" y2="15"></line> </svg> Dismiss for 24h `; }, 500); }, 1000); }); // Close the modal if user clicks outside of it alertModal.addEventListener('click', function(e) { if (e.target === alertModal) { hideAlertModal(); } }); // Add interactive elements to the dashboard const periodBtns = document.querySelectorAll('.period-btn'); periodBtns.forEach(btn => { btn.addEventListener('click', function() { // Remove active class from all buttons periodBtns.forEach(b => b.classList.remove('active')); // Add active class to clicked button this.classList.add('active'); }); }); // Automatically show the alert modal after a delay setTimeout(showAlertModal, 1500); // Countdown timer let countdownEl = document.querySelector('.countdown strong'); let hours = 23; let minutes = 14; let seconds = 52; const countdownInterval = setInterval(() => { seconds--; if (seconds < 0) { seconds = 59; minutes--; } if (minutes < 0) { minutes = 59; hours--; } if (hours < 0) { clearInterval(countdownInterval); return; } const formattedHours = hours.toString().padStart(2, '0'); const formattedMinutes = minutes.toString().padStart(2, '0'); const formattedSeconds = seconds.toString().padStart(2, '0'); countdownEl.textContent = `${formattedHours}:${formattedMinutes}:${formattedSeconds}`; }, 1000); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: #f6f9fc; overflow: hidden; } .backdrop { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); backdrop-filter: blur(5px); z-index: 10; display: flex; justify-content: center; align-items: center; } .modal { background: #fff; width: 90%; max-width: 600px; border-radius: 24px; overflow: hidden; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.15); transform: translateY(0); opacity: 1; animation: modalAppear 0.4s cubic-bezier(0.16, 1, 0.3, 1); position: relative; } @keyframes modalAppear { 0% { opacity: 0; transform: translateY(40px); } 100% { opacity: 1; transform: translateY(0); } } .modal-header { background: linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%); padding: 40px 30px 70px; color: white; position: relative; overflow: hidden; } .modal-header h2 { font-size: 28px; margin-bottom: 10px; font-weight: 700; position: relative; z-index: 2; } .modal-header p { font-size: 16px; opacity: 0.9; max-width: 80%; position: relative; z-index: 2; } .pattern { position: absolute; top: 0; right: 0; height: 100%; width: 40%; opacity: 0.2; background-image: radial-gradient(circle at 20% 40%, rgba(255, 255, 255, 0.3) 15px, transparent 16px), radial-gradient(circle at 60% 80%, rgba(255, 255, 255, 0.3) 10px, transparent 11px), radial-gradient(circle at 90% 10%, rgba(255, 255, 255, 0.3) 20px, transparent 21px), radial-gradient(circle at 40% 60%, rgba(255, 255, 255, 0.3) 8px, transparent 9px), radial-gradient(circle at 70% 30%, rgba(255, 255, 255, 0.3) 12px, transparent 13px); background-size: 180px 180px; animation: floatPattern 20s linear infinite; } @keyframes floatPattern { 0% { background-position: 0 0; } 100% { background-position: 180px 180px; } } .course-card { background: white; border-radius: 18px; padding: 20px; margin: -50px 20px 20px; box-shadow: 0 15px 30px rgba(0, 0, 0, 0.08); position: relative; z-index: 3; transition: transform 0.3s ease; } .course-card:hover { transform: translateY(-5px); } .course-meta { display: flex; align-items: center; margin-bottom: 15px; } .course-level { background: #EEF2FF; color: #4F46E5; font-size: 12px; padding: 4px 10px; border-radius: 20px; font-weight: 500; margin-right: 12px; } .course-time { display: flex; align-items: center; font-size: 14px; color: #6B7280; } .course-time svg { margin-right: 5px; } .course-title { font-size: 20px; font-weight: 600; color: #1F2937; margin-bottom: 10px; } .course-instructor { display: flex; align-items: center; margin-bottom: 20px; } .instructor-avatar { width: 36px; height: 36px; border-radius: 50%; background: #F3F4F6; overflow: hidden; margin-right: 10px; } .instructor-avatar img { width: 100%; height: 100%; object-fit: cover; } .instructor-name { font-size: 14px; color: #4B5563; } .instructor-name span { display: block; font-size: 12px; color: #9CA3AF; } .course-progress { margin-bottom: 20px; } .progress-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .progress-label { font-size: 14px; color: #374151; font-weight: 500; } .progress-percent { font-size: 14px; color: #6366F1; font-weight: 600; } .progress-bar { height: 6px; background: #E5E7EB; border-radius: 3px; overflow: hidden; } .progress-fill { height: 100%; background: linear-gradient(90deg, #6366F1 0%, #8B5CF6 100%); border-radius: 3px; width: 0; transition: width 1.5s cubic-bezier(0.16, 1, 0.3, 1); } .course-details { margin-top: 20px; } .highlights { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-bottom: 16px; } .highlight-item { display: flex; align-items: center; font-size: 13px; color: #4B5563; } .highlight-item svg { margin-right: 6px; color: #6366F1; flex-shrink: 0; } .modal-actions { padding: 0 20px 20px; } .enroll-btn { background: linear-gradient(135deg, #6366F1 0%, #8B5CF6 100%); color: white; border: none; border-radius: 12px; padding: 14px; width: 100%; font-weight: 600; font-size: 16px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 5px 15px rgba(99, 102, 241, 0.3); position: relative; overflow: hidden; } .enroll-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(99, 102, 241, 0.4); } .enroll-btn:active { transform: translateY(0); } .ripple { position: absolute; border-radius: 50%; background-color: rgba(255, 255, 255, 0.6); transform: scale(0); animation: ripple 0.6s linear; } @keyframes ripple { to { transform: scale(2.5); opacity: 0; } } .tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 15px; } .tag { background: #F3F4F6; color: #4B5563; font-size: 12px; padding: 4px 10px; border-radius: 20px; transition: all 0.2s ease; } .tag:hover { background: #E5E7EB; transform: translateY(-2px); } .close-btn { position: absolute; top: 20px; right: 20px; width: 32px; height: 32px; border-radius: 50%; background: rgba(255, 255, 255, 0.2); border: none; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.2s ease; z-index: 5; } .close-btn:hover { background: rgba(255, 255, 255, 0.3); transform: rotate(90deg); } .close-btn svg { width: 16px; height: 16px; color: white; } .enrollment-success { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: white; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 10; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; padding: 30px; text-align: center; } .enrollment-success.active { opacity: 1; pointer-events: all; } .success-icon { width: 100px; height: 100px; background: #F0FDF4; border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 20px; position: relative; } .success-icon svg { color: #10B981; width: 50px; height: 50px; opacity: 0; transform: scale(0.5); transition: all 0.3s ease; } .enrollment-success.active .success-icon svg { opacity: 1; transform: scale(1); } .success-icon::before { content: ''; position: absolute; width: 100%; height: 100%; border-radius: 50%; background: rgba(16, 185, 129, 0.1); animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(0.95); opacity: 0.7; } 50% { transform: scale(1.05); opacity: 0.3; } 100% { transform: scale(0.95); opacity: 0.7; } } .enrollment-success h3 { font-size: 24px; color: #111827; margin-bottom: 10px; } .enrollment-success p { color: #6B7280; margin-bottom: 30px; font-size: 16px; } .success-btn { background: #10B981; color: white; border: none; border-radius: 12px; padding: 14px 30px; font-weight: 600; font-size: 16px; cursor: pointer; transition: all 0.2s ease; box-shadow: 0 5px 15px rgba(16, 185, 129, 0.3); } .success-btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(16, 185, 129, 0.4); } /* For tablets and smaller screens */ @media (max-width: 640px) { .modal { width: 95%; } .modal-header { padding: 30px 20px 60px; } .modal-header h2 { font-size: 24px; } .modal-header p { max-width: 100%; font-size: 14px; } .course-title { font-size: 18px; } .highlights { grid-template-columns: 1fr; } } /* For very small screens */ @media (max-width: 380px) { .modal-header h2 { font-size: 20px; } .course-meta { flex-direction: column; align-items: flex-start; } .course-level { margin-bottom: 8px; } } </style> </head> <body> <div class="backdrop"> <div class="modal"> <div class="modal-header"> <button class="close-btn"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" /> </svg> </button> <h2>Find your path to design mastery</h2> <p>Join over 12,000 students already enrolled and start your learning journey today</p> <div class="pattern"></div> </div> <div class="course-card"> <div class="course-meta"> <div class="course-level">Intermediate</div> <div class="course-time"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 24 24" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /> </svg> 8 weeks • 24 lessons </div> </div> <h3 class="course-title">UX/UI Design Masterclass: From Wireframes to High-Fidelity Prototypes</h3> <div class="course-instructor"> <div class="instructor-avatar"> <img src="https://images.unsplash.com/photo-1580489944761-15a19d654956?ixlib=rb-1.2.1&auto=format&fit=crop&w=100&q=80" alt="Instructor"> </div> <div class="instructor-name"> Maya Rodriguez <span>Senior UX Designer at Figma</span> </div> </div> <div class="course-progress"> <div class="progress-header"> <div class="progress-label">Course completion</div> <div class="progress-percent">0%</div> </div> <div class="progress-bar"> <div class="progress-fill"></div> </div> </div> <div class="course-details"> <div class="highlights"> <div class="highlight-item"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" 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"></polyline> </svg> Lifetime access </div> <div class="highlight-item"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" 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"></polyline> </svg> Real-world projects </div> <div class="highlight-item"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" 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"></polyline> </svg> 1-on-1 mentorship </div> <div class="highlight-item"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" 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"></polyline> </svg> Course certificate </div> </div> <div class="tags"> <div class="tag">Design Systems</div> <div class="tag">User Testing</div> <div class="tag">Figma</div> <div class="tag">Prototyping</div> </div> </div> </div> <div class="modal-actions"> <button class="enroll-btn">Enroll Now — Start Learning Today</button> </div> <div class="enrollment-success"> <div class="success-icon"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"> <path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" /> </svg> </div> <h3>You're all set!</h3> <p>You've successfully enrolled in the UX/UI Design Masterclass. Your first lesson is ready for you to begin.</p> <button class="success-btn">Start First Lesson</button> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Animate progress bar on load setTimeout(() => { document.querySelector('.progress-fill').style.width = '0%'; }, 300); // Close button functionality document.querySelector('.close-btn').addEventListener('click', function() { document.querySelector('.modal').style.animation = 'modalAppear 0.4s cubic-bezier(0.16, 1, 0.3, 1) reverse forwards'; setTimeout(() => { document.querySelector('.backdrop').style.opacity = '0'; setTimeout(() => { document.querySelector('.backdrop').style.display = 'none'; }, 300); }, 200); }); // Enroll button with ripple effect document.querySelector('.enroll-btn').addEventListener('click', function(e) { // Create ripple effect const button = this; const ripple = document.createElement('span'); ripple.classList.add('ripple'); const rect = button.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; ripple.style.left = `${x}px`; ripple.style.top = `${y}px`; button.appendChild(ripple); // Remove ripple after animation completes setTimeout(() => { ripple.remove(); }, 600); // Simulate progress for visual feedback const progressFill = document.querySelector('.progress-fill'); const progressPercent = document.querySelector('.progress-percent'); let progress = 0; const interval = setInterval(() => { progress += 1; progressFill.style.width = `${progress}%`; progressPercent.textContent = `${progress}%`; if (progress >= 100) { clearInterval(interval); // Show success message setTimeout(() => { document.querySelector('.enrollment-success').classList.add('active'); }, 500); } }, 15); }); // Success button click document.querySelector('.success-btn').addEventListener('click', function() { document.querySelector('.enrollment-success').classList.remove('active'); // Reset progress setTimeout(() => { document.querySelector('.progress-fill').style.width = '0%'; document.querySelector('.progress-percent').textContent = '0%'; }, 300); }); // Add hover effect to course card const courseCard = document.querySelector('.course-card'); courseCard.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-5px)'; }); courseCard.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; }); // Animate tags on hover const tags = document.querySelectorAll('.tag'); tags.forEach(tag => { tag.addEventListener('mouseenter', function() { this.style.transform = 'translateY(-2px)'; this.style.background = '#E5E7EB'; }); tag.addEventListener('mouseleave', function() { this.style.transform = 'translateY(0)'; this.style.background = '#F3F4F6'; }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Social Media Post Creator</title> <style> :root { --primary: #6C5CE7; --secondary: #FD79A8; --accent: #00CEC9; --dark: #2D3436; --light: #FFFFFF; --gray: #DFE6E9; --success: #55efc4; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: rgba(0, 0, 0, 0.4); height: 700px; width: 700px; display: flex; justify-content: center; align-items: center; overflow: hidden; } .modal { background: var(--light); width: 90%; max-width: 600px; border-radius: 16px; overflow: hidden; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); position: relative; transition: transform 0.3s ease, box-shadow 0.3s ease; transform: translateY(0); } .modal:hover { transform: translateY(-5px); box-shadow: 0 30px 60px -12px rgba(0, 0, 0, 0.3); } .modal-header { background: linear-gradient(135deg, var(--primary), var(--secondary)); color: var(--light); padding: 20px; display: flex; justify-content: space-between; align-items: center; position: relative; overflow: hidden; } .modal-header::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: linear-gradient(45deg, rgba(255, 255, 255, 0) 30%, rgba(255, 255, 255, 0.15) 40%, rgba(255, 255, 255, 0) 50%); transform: rotate(45deg); animation: shimmer 3s infinite; } @keyframes shimmer { 0% { transform: translateX(-100%) rotate(45deg); } 100% { transform: translateX(100%) rotate(45deg); } } .modal-title { font-size: 24px; font-weight: 700; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); display: flex; align-items: center; gap: 10px; } .modal-title i { font-size: 28px; } .close-btn { background: none; border: none; color: var(--light); font-size: 24px; cursor: pointer; transition: transform 0.3s ease; z-index: 1; } .close-btn:hover { transform: rotate(90deg); } .modal-body { padding: 20px; } .tabs { display: flex; margin-bottom: 20px; border-bottom: 2px solid var(--gray); } .tab { padding: 10px 20px; font-weight: 600; color: var(--dark); cursor: pointer; position: relative; transition: all 0.3s ease; } .tab.active { color: var(--primary); } .tab.active::after { content: ''; position: absolute; bottom: -2px; left: 0; width: 100%; height: 2px; background-color: var(--primary); animation: slideIn 0.3s ease forwards; } @keyframes slideIn { from { transform: scaleX(0); } to { transform: scaleX(1); } } .tab:not(.active):hover { color: var(--secondary); } .content-area { display: flex; flex-direction: column; gap: 20px; } .text-input { position: relative; margin-bottom: 10px; } .text-input textarea { width: 100%; min-height: 120px; padding: 15px; border: 2px solid var(--gray); border-radius: 12px; resize: none; font-size: 16px; transition: border 0.3s ease, box-shadow 0.3s ease; } .text-input textarea:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 4px rgba(108, 92, 231, 0.15); } .character-count { position: absolute; bottom: 10px; right: 10px; color: var(--dark); font-size: 12px; background: rgba(255, 255, 255, 0.8); padding: 2px 6px; border-radius: 10px; transition: color 0.3s ease; } .character-count.warning { color: orange; } .character-count.danger { color: red; } .media-dropzone { border: 2px dashed var(--gray); border-radius: 12px; padding: 30px; text-align: center; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; } .media-dropzone:hover { border-color: var(--primary); background-color: rgba(108, 92, 231, 0.05); } .media-dropzone.dragging { border-color: var(--accent); background-color: rgba(0, 206, 201, 0.1); transform: scale(1.02); } .media-dropzone i { font-size: 36px; color: var(--primary); margin-bottom: 10px; display: block; } .media-dropzone p { color: var(--dark); margin-bottom: 10px; } .media-dropzone span { color: var(--primary); font-weight: 600; } .media-preview { display: grid; grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); gap: 10px; margin-top: 20px; max-height: 110px; overflow-y: auto; padding: 5px; } .media-item { position: relative; height: 80px; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); transition: transform 0.3s ease; } .media-item:hover { transform: scale(1.05); } .media-item img { width: 100%; height: 100%; object-fit: cover; } .media-item .remove-btn { position: absolute; top: 5px; right: 5px; background: rgba(0, 0, 0, 0.6); color: white; border: none; border-radius: 50%; width: 20px; height: 20px; font-size: 10px; cursor: pointer; display: flex; justify-content: center; align-items: center; transition: background 0.3s ease; } .media-item .remove-btn:hover { background: rgba(255, 0, 0, 0.8); } .options { display: flex; flex-wrap: wrap; gap: 10px; } .option-btn { display: flex; align-items: center; gap: 5px; padding: 8px 12px; background-color: var(--gray); border: none; border-radius: 8px; color: var(--dark); font-weight: 600; cursor: pointer; transition: all 0.3s ease; font-size: 14px; } .option-btn:hover { background-color: var(--primary); color: var(--light); } .option-btn i { font-size: 16px; } .post-preview { margin-top: 20px; padding: 15px; background-color: var(--light); border: 1px solid var(--gray); border-radius: 12px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); transition: all 0.3s ease; } .preview-header { display: flex; justify-content: space-between; margin-bottom: 10px; } .preview-title { font-weight: 700; color: var(--primary); font-size: 16px; } .platform-selector { position: relative; display: inline-block; } .platform-selector select { appearance: none; padding: 5px 25px 5px 10px; border: 1px solid var(--gray); border-radius: 6px; background-color: var(--light); font-size: 14px; cursor: pointer; } .platform-selector::after { content: '▼'; font-size: 10px; color: var(--dark); position: absolute; right: 10px; top: 50%; transform: translateY(-50%); pointer-events: none; } .preview-content { position: relative; padding: 10px; border-radius: 8px; background-color: #f9f9f9; font-size: 14px; overflow: hidden; transition: all 0.3s ease; } .instagram .preview-content { max-height: 105px; overflow-y: auto; font-family: 'Montserrat', sans-serif; } .twitter .preview-content { font-family: 'Roboto', sans-serif; max-height: 105px; overflow-y: auto; } .linkedin .preview-content { font-family: 'Arial', sans-serif; max-height: 105px; overflow-y: auto; } .preview-text { margin-bottom: 10px; word-wrap: break-word; line-height: 1.4; } .preview-media { display: flex; gap: 5px; overflow-x: auto; padding-bottom: 5px; max-height: 50px; } .preview-media img { height: 40px; border-radius: 4px; object-fit: cover; } .modal-footer { display: flex; justify-content: space-between; align-items: center; padding: 15px 20px; background-color: var(--gray); } .schedule-options { display: flex; align-items: center; gap: 10px; } .schedule-btn { background: none; border: none; color: var(--dark); font-weight: 600; cursor: pointer; display: flex; align-items: center; gap: 5px; padding: 5px 10px; border-radius: 6px; transition: background 0.3s ease; } .schedule-btn:hover { background-color: rgba(0, 0, 0, 0.1); } .post-btn { background: linear-gradient(to right, var(--primary), var(--secondary)); color: var(--light); border: none; padding: 10px 24px; border-radius: 30px; font-weight: 700; cursor: pointer; transition: all 0.3s ease; position: relative; overflow: hidden; box-shadow: 0 4px 15px rgba(108, 92, 231, 0.3); } .post-btn::before { content: ''; position: absolute; top: 0; left: -100%; width: 100%; height: 100%; background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.3), transparent); transition: left 0.5s; } .post-btn:hover { transform: translateY(-3px); box-shadow: 0 6px 20px rgba(108, 92, 231, 0.4); } .post-btn:hover::before { left: 100%; } .post-btn:active { transform: translateY(0); } .emoji-picker { position: absolute; bottom: 40px; right: 10px; background: var(--light); border-radius: 8px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); width: 200px; max-height: 150px; overflow-y: auto; padding: 10px; display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; z-index: 10; visibility: hidden; opacity: 0; transform: translateY(10px); transition: all 0.3s ease; } .emoji-picker.visible { visibility: visible; opacity: 1; transform: translateY(0); } .emoji-btn { background: none; border: none; font-size: 18px; cursor: pointer; padding: 5px; border-radius: 4px; transition: all 0.2s ease; } .emoji-btn:hover { background-color: var(--gray); transform: scale(1.1); } .file-input { display: none; } .schedule-panel { position: absolute; bottom: 65px; left: 20px; background: var(--light); border-radius: 8px; padding: 15px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); width: 250px; z-index: 10; visibility: hidden; opacity: 0; transform: translateY(10px); transition: all 0.3s ease; } .schedule-panel.visible { visibility: visible; opacity: 1; transform: translateY(0); } .schedule-panel h4 { margin-bottom: 10px; color: var(--dark); font-size: 16px; } .schedule-input { margin-bottom: 10px; } .schedule-input input { width: 100%; padding: 8px; border: 1px solid var(--gray); border-radius: 6px; } .schedule-actions { display: flex; justify-content: space-between; } .schedule-actions button { padding: 8px 12px; border: none; border-radius: 6px; cursor: pointer; font-weight: 600; transition: all 0.3s ease; } .cancel-schedule { background-color: var(--gray); color: var(--dark); } .confirm-schedule { background-color: var(--primary); color: var(--light); } .schedule-badge { display: inline-flex; align-items: center; gap: 5px; padding: 5px 10px; background-color: rgba(108, 92, 231, 0.1); color: var(--primary); border-radius: 15px; font-size: 12px; font-weight: 600; margin-left: 10px; visibility: hidden; opacity: 0; transition: all 0.3s ease; } .schedule-badge.visible { visibility: visible; opacity: 1; } /* Toast Notification */ .toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%) translateY(100px); background-color: var(--success); color: white; padding: 12px 20px; border-radius: 8px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); display: flex; align-items: center; gap: 10px; z-index: 1000; opacity: 0; transition: all 0.5s ease; } .toast.visible { transform: translateX(-50%) translateY(0); opacity: 1; } .toast i { font-size: 20px; } /* Responsive adjustments */ @media (max-width: 600px) { .modal { width: 95%; } .options { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 10px; } .option-btn { white-space: nowrap; } .modal-footer { flex-direction: column; gap: 15px; } .post-btn { width: 100%; } } /* Loading animation */ .loading-dots { display: inline-flex; align-items: center; margin-left: 5px; } .loading-dots span { width: 5px; height: 5px; background-color: white; border-radius: 50%; margin: 0 2px; animation: loadingDots 1.5s infinite ease-in-out; } .loading-dots span:nth-child(2) { animation-delay: 0.3s; } .loading-dots span:nth-child(3) { animation-delay: 0.6s; } @keyframes loadingDots { 0%, 100% { transform: scale(0); } 50% { transform: scale(1); } } /* Platform specific styles */ .platform-indicator { position: absolute; top: 10px; right: 10px; font-size: 20px; opacity: 0.3; } .instagram .platform-indicator { color: #E1306C; } .twitter .platform-indicator { color: #1DA1F2; } .linkedin .platform-indicator { color: #0077B5; } </style> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css"> </head> <body> <div class="modal"> <div class="modal-header"> <h2 class="modal-title"><i class="fas fa-bullhorn"></i> Create a Post</h2> <button class="close-btn" id="closeBtn"><i class="fas fa-times"></i></button> </div> <div class="modal-body"> <div class="tabs"> <div class="tab active" data-tab="compose">Compose</div> <div class="tab" data-tab="preview">Preview</div> </div> <div class="content-area" id="composeTab"> <div class="text-input"> <textarea id="postText" placeholder="What's on your mind? Share your updates, news, or thoughts..."></textarea> <div class="character-count" id="charCount">0/280</div> <div class="emoji-picker" id="emojiPicker"> <!-- Emojis will be added via JS --> </div> </div> <div class="media-dropzone" id="dropzone"> <i class="fas fa-cloud-upload-alt"></i> <p>Drag and drop media files here</p> <p>or <span>browse</span> to upload</p> <input type="file" id="fileInput" class="file-input" multiple accept="image/*,video/*"> <div class="media-preview" id="mediaPreview"></div> </div> <div class="options"> <button class="option-btn" id="emojiBtn"><i class="far fa-smile"></i> Emoji</button> <button class="option-btn"><i class="fas fa-hashtag"></i> Hashtags</button> <button class="option-btn"><i class="fas fa-poll"></i> Poll</button> <button class="option-btn"><i class="fas fa-map-marker-alt"></i> Location</button> <button class="option-btn"><i class="fas fa-user-tag"></i> Tag</button> </div> </div> <div class="content-area" id="previewTab" style="display: none;"> <div class="post-preview instagram" id="postPreview"> <div class="preview-header"> <div class="preview-title">Post Preview</div> <div class="platform-selector"> <select id="platformSelect"> <option value="instagram">Instagram</option> <option value="twitter">Twitter</option> <option value="linkedin">LinkedIn</option> </select> </div> </div> <div class="preview-content"> <i class="platform-indicator fab fa-instagram"></i> <div class="preview-text" id="previewText">Your post will appear here...</div> <div class="preview-media" id="previewMedia"></div> </div> </div> </div> </div> <div class="modal-footer"> <div class="schedule-options"> <button class="schedule-btn" id="scheduleBtn"> <i class="far fa-clock"></i> Schedule </button> <div class="schedule-badge" id="scheduleBadge"> <i class="fas fa-clock"></i> <span id="scheduleTime"></span> </div> <div class="schedule-panel" id="schedulePanel"> <h4>Schedule Your Post</h4> <div class="schedule-input"> <input type="datetime-local" id="scheduleDateTime"> </div> <div class="schedule-actions"> <button class="cancel-schedule" id="cancelSchedule">Cancel</button> <button class="confirm-schedule" id="confirmSchedule">Schedule</button> </div> </div> </div> <button class="post-btn" id="postBtn"> Post Now <div class="loading-dots" style="display: none;" id="loadingDots"> <span></span> <span></span> <span></span> </div> </button> </div> </div> <div class="toast" id="toast"> <i class="fas fa-check-circle"></i> <span id="toastMessage">Post published successfully!</span> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Elements const closeBtn = document.getElementById('closeBtn'); const postText = document.getElementById('postText'); const charCount = document.getElementById('charCount'); const dropzone = document.getElementById('dropzone'); const fileInput = document.getElementById('fileInput'); const mediaPreview = document.getElementById('mediaPreview'); const emojiBtn = document.getElementById('emojiBtn'); const emojiPicker = document.getElementById('emojiPicker'); const tabs = document.querySelectorAll('.tab'); const composeTab = document.getElementById('composeTab'); const previewTab = document.getElementById('previewTab'); const previewText = document.getElementById('previewText'); const previewMedia = document.getElementById('previewMedia'); const platformSelect = document.getElementById('platformSelect'); const postPreview = document.getElementById('postPreview'); const postBtn = document.getElementById('postBtn'); const loadingDots = document.getElementById('loadingDots'); const toast = document.getElementById('toast'); const scheduleBtn = document.getElementById('scheduleBtn'); const schedulePanel = document.getElementById('schedulePanel'); const scheduleDateTime = document.getElementById('scheduleDateTime'); const cancelSchedule = document.getElementById('cancelSchedule'); const confirmSchedule = document.getElementById('confirmSchedule'); const scheduleBadge = document.getElementById('scheduleBadge'); const scheduleTime = document.getElementById('scheduleTime'); // Set default schedule time to tomorrow at 9am const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); tomorrow.setHours(9, 0, 0, 0); scheduleDateTime.value = tomorrow.toISOString().slice(0, 16); // Initialize text character counter postText.addEventListener('input', function() { const length = this.value.length; let maxLength = 280; // Adjust max length based on platform if (platformSelect.value === 'instagram') { maxLength = 2200; } else if (platformSelect.value === 'twitter') { maxLength = 280; } else if (platformSelect.value === 'linkedin') { maxLength = 3000; } charCount.textContent = `${length}/${maxLength}`; // Update preview text previewText.textContent = this.value || 'Your post will appear here...'; // Warning colors if (length > maxLength * 0.8 && length <= maxLength) { charCount.className = 'character-count warning'; } else if (length > maxLength) { charCount.className = 'character-count danger'; } else { charCount.className = 'character-count'; } }); // Close button effect closeBtn.addEventListener('click', function() { document.querySelector('.modal').style.transform = 'translateY(20px)'; document.querySelector('.modal').style.opacity = '0'; setTimeout(() => { document.querySelector('.modal').style.transform = 'translateY(0)'; document.querySelector('.modal').style.opacity = '1'; }, 300); }); // Tab switching tabs.forEach(tab => { tab.addEventListener('click', function() { const tabName = this.getAttribute('data-tab'); // Remove active class from all tabs tabs.forEach(t => t.classList.remove('active')); // Add active class to clicked tab this.classList.add('active'); // Show appropriate content if (tabName === 'compose') { composeTab.style.display = 'flex'; previewTab.style.display = 'none'; } else { composeTab.style.display = 'none'; previewTab.style.display = 'flex'; } }); }); // Platform selector platformSelect.addEventListener('change', function() { const platform = this.value; // Update preview style postPreview.className = 'post-preview ' + platform; // Update platform icon const indicator = document.querySelector('.platform-indicator'); if (platform === 'instagram') { indicator.className = 'platform-indicator fab fa-instagram'; } else if (platform === 'twitter') { indicator.className = 'platform-indicator fab fa-twitter'; } else if (platform === 'linkedin') { indicator.className = 'platform-indicator fab fa-linkedin'; } // Update character count limit const currentLength = postText.value.length; let maxLength = 280; if (platform === 'instagram') { maxLength = 2200; } else if (platform === 'twitter') { maxLength = 280; } else if (platform === 'linkedin') { maxLength = 3000; } charCount.textContent = `${currentLength}/${maxLength}`; // Warning colors if (currentLength > maxLength * 0.8 && currentLength <= maxLength) { charCount.className = 'character-count warning'; } else if (currentLength > maxLength) { charCount.className = 'character-count danger'; } else { charCount.className = 'character-count'; } }); // File drag and drop ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { dropzone.addEventListener(eventName, preventDefaults, false); }); function preventDefaults(e) { e.preventDefault(); e.stopPropagation(); } ['dragenter', 'dragover'].forEach(eventName => { dropzone.addEventListener(eventName, function() { dropzone.classList.add('dragging'); }, false); }); ['dragleave', 'drop'].forEach(eventName => { dropzone.addEventListener(eventName, function() { dropzone.classList.remove('dragging'); }, false); }); dropzone.addEventListener('drop', handleDrop, false); function handleDrop(e) { const dt = e.dataTransfer; const files = dt.files; handleFiles(files); } dropzone.addEventListener('click', function() { fileInput.click(); }); fileInput.addEventListener('change', function() { handleFiles(this.files); }); function handleFiles(files) { [...files].forEach(file => { if (file.type.startsWith('image/')) { const reader = new FileReader(); reader.onload = function(e) { addMediaItem(e.target.result); }; reader.readAsDataURL(file); } }); } function addMediaItem(src) { const mediaItem = document.createElement('div'); mediaItem.className = 'media-item'; const img = document.createElement('img'); img.src = src; const removeBtn = document.createElement('button'); removeBtn.className = 'remove-btn'; removeBtn.innerHTML = '<i class="fas fa-times"></i>'; removeBtn.addEventListener('click', function(e) { e.stopPropagation(); mediaItem.remove(); updatePreviewMedia(); }); mediaItem.appendChild(img); mediaItem.appendChild(removeBtn); mediaPreview.appendChild(mediaItem); // Also add to preview updatePreviewMedia(); } function updatePreviewMedia() { // Clear current preview previewMedia.innerHTML = ''; // Add all media items const mediaItems = document.querySelectorAll('.media-item img'); mediaItems.forEach(item => { const previewImg = document.createElement('img'); previewImg.src = item.src; previewMedia.appendChild(previewImg); }); } // Emoji picker emojiBtn.addEventListener('click', function() { emojiPicker.classList.toggle('visible'); }); // Close emoji picker when clicking outside document.addEventListener('click', function(e) { if (!emojiBtn.contains(e.target) && !emojiPicker.contains(e.target)) { emojiPicker.classList.remove('visible'); } }); // Add emojis to picker const emojis = ['😀', '😂', '😍', '🥰', '😎', '🙌', '👍', '🎉', '🔥', '❤️', '💯', '🤔', '😊', '🙏', '👏', '✨', '🌟', '💪', '🚀', '🌈']; emojis.forEach(emoji => { const emojiBtn = document.createElement('button'); emojiBtn.className = 'emoji-btn'; emojiBtn.textContent = emoji; emojiBtn.addEventListener('click', function() { // Add emoji to text at cursor position const startPos = postText.selectionStart; const endPos = postText.selectionEnd; const textBefore = postText.value.substring(0, startPos); const textAfter = postText.value.substring(endPos, postText.value.length); postText.value = textBefore + emoji + textAfter; // Trigger input event to update character count const event = new Event('input', { bubbles: true }); postText.dispatchEvent(event); // Set cursor position after emoji postText.selectionStart = startPos + emoji.length; postText.selectionEnd = startPos + emoji.length; postText.focus(); }); emojiPicker.appendChild(emojiBtn); }); // Schedule functionality scheduleBtn.addEventListener('click', function() { schedulePanel.classList.toggle('visible'); }); cancelSchedule.addEventListener('click', function() { schedulePanel.classList.remove('visible'); }); confirmSchedule.addEventListener('click', function() { const scheduledDate = new Date(scheduleDateTime.value); if (scheduledDate > new Date()) { scheduleTime.textContent = scheduledDate.toLocaleString('en-US', { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' }); scheduleBadge.classList.add('visible'); schedulePanel.classList.remove('visible'); // Update post button text postBtn.textContent = 'Schedule Post'; } else { alert('Please select a future date and time.'); } }); // Post button postBtn.addEventListener('click', function() { // Show loading animation this.textContent = 'Posting'; loadingDots.style.display = 'inline-flex'; // Simulate posting setTimeout(() => { // Hide loading animation loadingDots.style.display = 'none'; // Show success message if (scheduleBadge.classList.contains('visible')) { toast.querySelector('#toastMessage').textContent = 'Post scheduled successfully!'; } else { toast.querySelector('#toastMessage').textContent = 'Post published successfully!'; } toast.classList.add('visible'); // Reset button text postBtn.textContent = scheduleBadge.classList.contains('visible') ? 'Schedule Post' : 'Post Now'; // Hide toast after 3 seconds setTimeout(() => { toast.classList.remove('visible'); }, 3000); }, 1500); }); // Initialize with some example content postText.value = "Just launched our new summer collection! 🌞 Vibrant colors, sustainable materials, and designs inspired by coastal adventures. Limited edition items available now! #SummerVibes #NewCollection #ShopNow"; // Trigger input event to update character count and preview const event = new Event('input', { bubbles: true }); postText.dispatchEvent(event); // Add sample media addMediaItem('https://images.unsplash.com/photo-1560243563-062bfc001d68?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'); addMediaItem('https://images.unsplash.com/photo-1617137984095-74e4e5e3613f?ixlib=rb-1.2.1&auto=format&fit=crop&w=800&q=60'); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Travel Booking Confirmation</title> <style> @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&family=Lora:wght@400;500&display=swap'); * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Lora', serif; background-color: #f8f5f2; color: #3a3a3a; height: 100vh; display: flex; align-items: center; justify-content: center; overflow: hidden; position: relative; } .modal-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); backdrop-filter: blur(5px); display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity 0.5s ease; } .modal-overlay.active { opacity: 1; } .modal { width: 650px; max-width: 95%; max-height: 90vh; background-color: #fff; border-radius: 12px; overflow: hidden; box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); transform: translateY(50px); opacity: 0; transition: all 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275); position: relative; } .modal.active { transform: translateY(0); opacity: 1; } .modal-header { position: relative; height: 200px; overflow: hidden; background: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.4)), url('https://images.unsplash.com/photo-1503220317375-aaad61436b1b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80'); background-size: cover; background-position: center; padding: 2rem; display: flex; flex-direction: column; justify-content: flex-end; color: white; } .modal-header h1 { font-family: 'Playfair Display', serif; font-weight: 700; font-size: 2.2rem; margin-bottom: 0.5rem; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); position: relative; } .modal-header p { font-size: 1rem; width: 80%; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); } .modal-body { padding: 1.5rem; height: 380px; overflow-y: auto; scrollbar-width: thin; } .modal-body::-webkit-scrollbar { width: 6px; } .modal-body::-webkit-scrollbar-thumb { background-color: #d8ae76; border-radius: 6px; } .section-title { font-family: 'Playfair Display', serif; font-weight: 600; font-size: 1.3rem; margin-bottom: 1rem; color: #9c6644; border-bottom: 1px solid #f0e6d9; padding-bottom: 0.5rem; } .itinerary-section { margin-bottom: 2rem; } .itinerary-item { display: flex; margin-bottom: 1rem; padding-bottom: 1rem; border-bottom: 1px dashed #f0e6d9; } .itinerary-item:last-child { border-bottom: none; } .itinerary-day { flex: 0 0 100px; font-weight: 500; color: #9c6644; } .itinerary-details { flex: 1; } .itinerary-details h4 { font-family: 'Playfair Display', serif; margin-bottom: 0.3rem; } .itinerary-details p { font-size: 0.9rem; color: #666; } .map-section { margin-bottom: 2rem; position: relative; border-radius: 8px; overflow: hidden; height: 200px; } .map-interact { position: absolute; right: 10px; bottom: 10px; background-color: rgba(255, 255, 255, 0.9); padding: 0.4rem 0.8rem; border-radius: 4px; font-size: 0.8rem; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); transition: all 0.3s ease; z-index: 2; } .map-interact:hover { background-color: #9c6644; color: white; } .map-container { width: 100%; height: 100%; background-color: #f0e6d9; position: relative; overflow: hidden; } .map-container img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.5s ease; } .map-container:hover img { transform: scale(1.05); } .map-marker { position: absolute; width: 16px; height: 16px; background-color: #d8ae76; border-radius: 50%; transform: translate(-50%, -50%); box-shadow: 0 0 0 4px rgba(216, 174, 118, 0.3); z-index: 1; cursor: pointer; } .map-marker::after { content: ''; position: absolute; top: 50%; left: 50%; width: 8px; height: 8px; background-color: white; border-radius: 50%; transform: translate(-50%, -50%); opacity: 0.8; } .map-marker:hover { background-color: #9c6644; box-shadow: 0 0 0 6px rgba(156, 102, 68, 0.4); } .marker-tooltip { position: absolute; bottom: calc(100% + 10px); left: 50%; transform: translateX(-50%); white-space: nowrap; background-color: white; padding: 0.3rem 0.6rem; border-radius: 4px; font-size: 0.8rem; box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1); opacity: 0; visibility: hidden; transition: all 0.3s ease; z-index: 3; } .marker-tooltip::after { content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%); border-width: 6px; border-style: solid; border-color: white transparent transparent transparent; } .map-marker:hover .marker-tooltip { opacity: 1; visibility: visible; } .price-section { background-color: #f9f6f1; padding: 1.5rem; border-radius: 8px; margin-bottom: 2rem; } .price-item { display: flex; justify-content: space-between; margin-bottom: 0.8rem; } .price-total { font-weight: 700; font-size: 1.1rem; margin-top: 1rem; padding-top: 1rem; border-top: 1px solid #e6ddd0; display: flex; justify-content: space-between; } .modal-footer { display: flex; padding: 1.5rem; background-color: #f9f6f1; border-top: 1px solid #f0e6d9; } .btn { font-family: 'Lora', serif; font-size: 1rem; padding: 0.8rem 1.5rem; border-radius: 6px; border: none; cursor: pointer; transition: all 0.3s ease; font-weight: 500; } .btn-secondary { background-color: transparent; border: 1px solid #d8ae76; color: #9c6644; margin-right: 1rem; flex: 1; } .btn-secondary:hover { background-color: rgba(216, 174, 118, 0.1); } .btn-primary { background-color: #d8ae76; color: white; flex: 2; position: relative; overflow: hidden; } .btn-primary::after { content: ''; position: absolute; top: 50%; left: 50%; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.2); border-radius: 50%; transform: translate(-50%, -50%) scale(0); transition: transform 0.5s ease-out; } .btn-primary:hover { background-color: #9c6644; } .btn-primary:active::after { transform: translate(-50%, -50%) scale(3); opacity: 0; } .circle-decoration { position: absolute; width: 140px; height: 140px; border-radius: 50%; background-color: rgba(216, 174, 118, 0.1); z-index: -1; } .circle-1 { top: -50px; right: -50px; } .circle-2 { bottom: -70px; left: -70px; width: 200px; height: 200px; background-color: rgba(156, 102, 68, 0.05); } .confirmation-tag { position: absolute; top: 2rem; right: 2rem; background-color: rgba(255, 255, 255, 0.9); padding: 0.4rem 0.8rem; border-radius: 4px; font-size: 0.8rem; color: #9c6644; font-weight: 500; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); transform: rotate(3deg); } /* Animation for the confirm button success */ @keyframes confirm-success { 0% { width: 0; opacity: 0; } 50% { opacity: 1; } 100% { width: 100%; opacity: 1; } } .btn-success { position: relative; background-color: #4caf50; color: white; } .btn-success::before { content: "✓ "; margin-right: 5px; } .confirmation-animation { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.9); display: flex; align-items: center; justify-content: center; z-index: 100; opacity: 0; visibility: hidden; transition: all 0.5s ease; } .confirmation-animation.active { opacity: 1; visibility: visible; } .confirmation-content { text-align: center; transform: translateY(30px); opacity: 0; transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); transition-delay: 0.3s; } .confirmation-animation.active .confirmation-content { transform: translateY(0); opacity: 1; } .checkmark-circle { width: 80px; height: 80px; margin: 0 auto 20px; border-radius: 50%; background-color: #4caf50; display: flex; align-items: center; justify-content: center; box-shadow: 0 6px 16px rgba(76, 175, 80, 0.3); } .checkmark { color: white; font-size: 40px; transform: scale(0); opacity: 0; transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1); transition-delay: 0.8s; } .confirmation-animation.active .checkmark { transform: scale(1); opacity: 1; } .confirmation-title { font-family: 'Playfair Display', serif; font-size: 2rem; margin-bottom: 0.5rem; color: #3a3a3a; } /* Responsiveness */ @media (max-width: 600px) { .modal-header { height: 150px; padding: 1.5rem; } .modal-header h1 { font-size: 1.8rem; } .modal-body { padding: 1rem; height: 430px; } .modal-footer { padding: 1rem; flex-direction: column; } .btn-secondary { margin-right: 0; margin-bottom: 1rem; } .itinerary-item { flex-direction: column; } .itinerary-day { margin-bottom: 0.5rem; } .confirmation-tag { top: 1rem; right: 1rem; } } /* Opening animation */ @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } .open-animation { animation: fadeIn 1s ease forwards; } </style> </head> <body> <div class="modal-overlay active"> <div class="modal active"> <div class="circle-decoration circle-1"></div> <div class="circle-decoration circle-2"></div> <div class="modal-header"> <div class="confirmation-tag">Ready to confirm</div> <h1>Amalfi Coast Getaway</h1> <p>8-day journey through Italy's stunning coastline</p> </div> <div class="modal-body"> <div class="itinerary-section"> <h3 class="section-title">Your Itinerary</h3> <div class="itinerary-item"> <div class="itinerary-day">Day 1-2</div> <div class="itinerary-details"> <h4>Sorrento</h4> <p>Begin your journey in the clifftop town of Sorrento. Stay at the elegant Hotel Bellevue Syrene with panoramic views of the Bay of Naples.</p> </div> </div> <div class="itinerary-item"> <div class="itinerary-day">Day 3-4</div> <div class="itinerary-details"> <h4>Positano</h4> <p>Continue to the vertical town of Positano. Enjoy beachfront dining and boutique shopping while staying at Le Sirenuse.</p> </div> </div> <div class="itinerary-item"> <div class="itinerary-day">Day 5-6</div> <div class="itinerary-details"> <h4>Amalfi</h4> <p>Explore the historic maritime republic of Amalfi. Visit the cathedral and paper museums while staying at Hotel Santa Caterina.</p> </div> </div> <div class="itinerary-item"> <div class="itinerary-day">Day 7-8</div> <div class="itinerary-details"> <h4>Ravello</h4> <p>Conclude in the hilltop town of Ravello. Attend a concert at Villa Rufolo and enjoy your final stay at Palazzo Avino.</p> </div> </div> </div> <div class="map-section"> <div class="map-container"> <img src="https://images.unsplash.com/photo-1562095241-8c6714fd4178?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=800&q=80" alt="Amalfi Coast Map"> <div class="map-marker" style="top: 30%; left: 20%;"> <div class="marker-tooltip">Sorrento</div> </div> <div class="map-marker" style="top: 45%; left: 35%;"> <div class="marker-tooltip">Positano</div> </div> <div class="map-marker" style="top: 60%; left: 55%;"> <div class="marker-tooltip">Amalfi</div> </div> <div class="map-marker" style="top: 50%; left: 75%;"> <div class="marker-tooltip">Ravello</div> </div> </div> <div class="map-interact">Interactive Map</div> </div> <div class="price-section"> <h3 class="section-title">Price Breakdown</h3> <div class="price-item"> <span>Accommodation (7 nights)</span> <span>€3,240</span> </div> <div class="price-item"> <span>Private transfers</span> <span>€680</span> </div> <div class="price-item"> <span>Guided experiences</span> <span>€950</span> </div> <div class="price-item"> <span>Dining reservations</span> <span>€430</span> </div> <div class="price-total"> <span>Total</span> <span>€5,300</span> </div> </div> </div> <div class="modal-footer"> <button class="btn btn-secondary" id="modify-btn">Modify Itinerary</button> <button class="btn btn-primary" id="confirm-btn">Confirm Booking</button> </div> </div> </div> <div class="confirmation-animation" id="confirmation-animation"> <div class="confirmation-content"> <div class="checkmark-circle"> <span class="checkmark">✓</span> </div> <h2 class="confirmation-title">Booking Confirmed!</h2> <p>Your Amalfi Coast adventure is set.<br>Check your email for detailed itinerary.</p> </div> </div> <script> document.addEventListener("DOMContentLoaded", function() { const modalOverlay = document.querySelector('.modal-overlay'); const modal = document.querySelector('.modal'); const confirmBtn = document.getElementById('confirm-btn'); const modifyBtn = document.getElementById('modify-btn'); const confirmationAnimation = document.getElementById('confirmation-animation'); const mapInteract = document.querySelector('.map-interact'); const mapContainer = document.querySelector('.map-container'); // Simulate opening modal with animation setTimeout(() => { modalOverlay.classList.add('active'); modal.classList.add('active'); }, 300); // Handle confirmation button click confirmBtn.addEventListener('click', function() { // Change button state confirmBtn.classList.add('btn-success'); confirmBtn.textContent = 'Booking Confirmed'; confirmBtn.disabled = true; // Show confirmation animation after a delay setTimeout(() => { confirmationAnimation.classList.add('active'); }, 1000); // Hide confirmation after some time setTimeout(() => { confirmationAnimation.classList.remove('active'); // Reset the modal state setTimeout(() => { confirmBtn.classList.remove('btn-success'); confirmBtn.textContent = 'Confirm Booking'; confirmBtn.disabled = false; }, 1000); }, 4000); }); // Handle modify button click modifyBtn.addEventListener('click', function() { // Add a subtle shake animation to indicate modification option modal.style.animation = 'shake 0.5s cubic-bezier(.36,.07,.19,.97) both'; setTimeout(() => { modal.style.animation = ''; }, 500); }); // Map interaction mapInteract.addEventListener('click', function() { mapContainer.classList.toggle('expanded'); if (mapContainer.classList.contains('expanded')) { mapInteract.textContent = 'Close Map'; } else { mapInteract.textContent = 'Interactive Map'; } }); // Add hover effects for map markers const mapMarkers = document.querySelectorAll('.map-marker'); mapMarkers.forEach(marker => { marker.addEventListener('mouseenter', function() { this.style.transform = 'translate(-50%, -50%) scale(1.3)'; this.style.transition = 'transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275)'; }); marker.addEventListener('mouseleave', function() { this.style.transform = 'translate(-50%, -50%) scale(1)'; }); marker.addEventListener('click', function() { const tooltip = this.querySelector('.marker-tooltip'); const text = tooltip.textContent; // Create a temporary highlight effect const highlight = document.createElement('div'); highlight.style.position = 'absolute'; highlight.style.top = '0'; highlight.style.left = '0'; highlight.style.width = '100%'; highlight.style.height = '100%'; highlight.style.backgroundColor = 'rgba(216, 174, 118, 0.2)'; highlight.style.zIndex = '0'; highlight.style.opacity = '0'; highlight.style.transition = 'opacity 0.5s ease'; mapContainer.appendChild(highlight); setTimeout(() => { highlight.style.opacity = '1'; }, 10); setTimeout(() => { highlight.style.opacity = '0'; }, 700); setTimeout(() => { mapContainer.removeChild(highlight); }, 1200); // Scroll to the corresponding itinerary item const itineraryItems = document.querySelectorAll('.itinerary-item'); itineraryItems.forEach(item => { if (item.querySelector('h4').textContent.includes(text)) { item.scrollIntoView({ behavior: 'smooth', block: 'center' }); // Highlight the itinerary item item.style.backgroundColor = 'rgba(216, 174, 118, 0.1)'; item.style.transition = 'background-color 0.3s ease'; setTimeout(() => { item.style.backgroundColor = 'transparent'; }, 2000); } }); }); }); // Add CSS animation for the shake effect const style = document.createElement('style'); style.textContent = ` @keyframes shake { 0%, 100% { transform: translateX(0); } 10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); } 20%, 40%, 60%, 80% { transform: translateX(5px); } } `; document.head.appendChild(style); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Chakra+Petch:wght@300;500;700&display=swap'); :root { --primary-neon: #00ffff; --secondary-neon: #ff00ff; --tertiary-neon: #ffff00; --bg-dark: #0a0a20; --bg-darker: #050510; --text-light: #ffffff; --glow-intensity: 10px; } * { margin: 0; padding: 0; box-sizing: border-box; } body { width: 100%; height: 100vh; font-family: 'Chakra Petch', sans-serif; background: var(--bg-darker); display: flex; align-items: center; justify-content: center; color: var(--text-light); overflow: hidden; position: relative; } .achievement-modal { width: 90%; max-width: 500px; background: linear-gradient(135deg, rgba(10, 10, 32, 0.9), rgba(5, 5, 16, 0.95)); border: 2px solid var(--primary-neon); border-radius: 15px; box-shadow: 0 0 var(--glow-intensity) var(--primary-neon), inset 0 0 15px rgba(0, 255, 255, 0.3); position: relative; overflow: hidden; opacity: 0; transform: scale(0.8); animation: modalAppear 0.6s cubic-bezier(0.17, 0.67, 0.12, 1.35) forwards; z-index: 100; } .achievement-header { padding: 20px; text-align: center; position: relative; } .achievement-title { font-family: 'Orbitron', sans-serif; font-size: 2.2rem; font-weight: 900; color: var(--text-light); text-transform: uppercase; margin-bottom: 5px; letter-spacing: 1px; text-shadow: 0 0 10px var(--primary-neon), 0 0 20px var(--primary-neon); animation: titleGlow 2s infinite alternate; } .achievement-subtitle { font-size: 1rem; font-weight: 300; color: rgba(255, 255, 255, 0.7); margin-bottom: 15px; } .achievement-content { padding: 0 25px 25px; display: flex; flex-direction: column; align-items: center; } .achievement-badge { width: 130px; height: 130px; background: linear-gradient(135deg, var(--primary-neon), var(--secondary-neon)); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin-bottom: 20px; box-shadow: 0 0 25px rgba(0, 255, 255, 0.5); position: relative; animation: pulseGlow 2s infinite; } .achievement-badge::before { content: ""; position: absolute; width: 120px; height: 120px; background: var(--bg-dark); border-radius: 50%; } .achievement-badge-inner { width: 110px; height: 110px; background: linear-gradient(135deg, var(--bg-dark), var(--bg-darker)); border-radius: 50%; display: flex; align-items: center; justify-content: center; position: relative; border: 2px solid rgba(255, 255, 255, 0.1); z-index: 2; } .achievement-badge-icon { font-size: 48px; color: var(--primary-neon); text-shadow: 0 0 10px var(--primary-neon); } .achievement-description { text-align: center; margin-bottom: 25px; font-size: 1.1rem; line-height: 1.4; font-weight: 300; } .achievement-highlight { font-weight: 700; color: var(--tertiary-neon); text-shadow: 0 0 5px var(--tertiary-neon); } .achievement-xp { background: rgba(0, 255, 255, 0.1); border: 1px solid var(--primary-neon); border-radius: 8px; padding: 10px 20px; font-family: 'Orbitron', sans-serif; font-size: 1.3rem; margin-bottom: 25px; position: relative; box-shadow: 0 0 10px rgba(0, 255, 255, 0.2); } .achievement-xp::before { content: ""; position: absolute; width: 100%; height: 100%; top: 0; left: 0; background: linear-gradient(90deg, transparent, rgba(0, 255, 255, 0.3), transparent); animation: xpScan 2s infinite; } .achievement-actions { display: flex; justify-content: center; gap: 15px; width: 100%; } .action-btn { background: linear-gradient(135deg, rgba(0, 255, 255, 0.1), rgba(255, 0, 255, 0.1)); border: 1px solid; border-color: var(--primary-neon); padding: 10px 20px; border-radius: 30px; font-family: 'Chakra Petch', sans-serif; color: var(--text-light); font-size: 0.9rem; font-weight: 500; cursor: pointer; transition: all 0.2s ease; position: relative; overflow: hidden; flex: 1; max-width: 140px; text-align: center; box-shadow: 0 0 5px rgba(0, 255, 255, 0.2); } .action-btn:hover { background: linear-gradient(135deg, rgba(0, 255, 255, 0.3), rgba(255, 0, 255, 0.3)); transform: translateY(-2px); box-shadow: 0 5px 15px rgba(0, 255, 255, 0.3); } .action-btn:active { transform: translateY(1px); } .action-btn i { margin-right: 5px; } .action-btn.share-btn { border-color: var(--secondary-neon); } .action-btn.share-btn:hover { background: linear-gradient(135deg, rgba(255, 0, 255, 0.3), rgba(0, 255, 255, 0.3)); box-shadow: 0 5px 15px rgba(255, 0, 255, 0.3); } .action-btn.continue-btn { border-color: var(--tertiary-neon); } .action-btn.continue-btn:hover { background: linear-gradient(135deg, rgba(255, 255, 0, 0.3), rgba(0, 255, 255, 0.3)); box-shadow: 0 5px 15px rgba(255, 255, 0, 0.3); } .close-btn { position: absolute; top: 15px; right: 15px; background: none; border: none; color: rgba(255, 255, 255, 0.7); font-size: 20px; cursor: pointer; transition: all 0.2s; z-index: 5; } .close-btn:hover { color: var(--text-light); transform: rotate(90deg); } .particles-container { position: absolute; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; pointer-events: none; } .particle { position: absolute; width: 8px; height: 8px; background-color: var(--primary-neon); border-radius: 50%; animation: particleAnimation 2s linear forwards; opacity: 0; } .bg-grid { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: linear-gradient(to right, rgba(0, 255, 255, 0.1) 1px, transparent 1px), linear-gradient(to bottom, rgba(0, 255, 255, 0.1) 1px, transparent 1px); background-size: 25px 25px; z-index: -1; opacity: 0.3; } .highlight-scan { position: absolute; width: 100%; height: 5px; background: linear-gradient(90deg, transparent, var(--primary-neon), transparent); top: 0; left: 0; filter: blur(5px); animation: scanEffect 2s ease-in-out infinite; } @keyframes modalAppear { 0% { opacity: 0; transform: scale(0.8) translateY(20px); } 100% { opacity: 1; transform: scale(1) translateY(0); } } @keyframes titleGlow { 0% { text-shadow: 0 0 10px var(--primary-neon), 0 0 20px var(--primary-neon); } 100% { text-shadow: 0 0 15px var(--primary-neon), 0 0 30px var(--primary-neon), 0 0 45px var(--primary-neon); } } @keyframes pulseGlow { 0% { box-shadow: 0 0 15px rgba(0, 255, 255, 0.5); } 50% { box-shadow: 0 0 30px rgba(0, 255, 255, 0.8); } 100% { box-shadow: 0 0 15px rgba(0, 255, 255, 0.5); } } @keyframes xpScan { 0% { left: -100%; } 100% { left: 100%; } } @keyframes particleAnimation { 0% { transform: translate(0, 0) scale(1); opacity: 1; } 100% { transform: translate(var(--endX), var(--endY)) scale(0); opacity: 0; } } @keyframes scanEffect { 0% { top: -5px; } 100% { top: 100%; } } @media (max-width: 500px) { .achievement-title { font-size: 1.8rem; } .achievement-badge { width: 100px; height: 100px; } .achievement-badge::before { width: 90px; height: 90px; } .achievement-badge-inner { width: 80px; height: 80px; } .achievement-badge-icon { font-size: 36px; } .action-btn { padding: 8px 15px; font-size: 0.8rem; } } .ripple { position: absolute; border-radius: 50%; background-color: rgba(0, 255, 255, 0.4); transform: scale(0); animation: rippleEffect 0.6s linear; } @keyframes rippleEffect { to { transform: scale(4); opacity: 0; } } .progress-ring { transform: rotate(-90deg); transition: all 0.3s ease; } .circle-bg { fill: none; stroke: rgba(255, 255, 255, 0.1); stroke-width: 3; } .circle { fill: none; stroke: var(--tertiary-neon); stroke-width: 3; stroke-linecap: round; stroke-dasharray: 283; stroke-dashoffset: 283; transition: stroke-dashoffset 1s ease; filter: drop-shadow(0 0 5px var(--tertiary-neon)); } .level-indicator { position: absolute; font-family: 'Orbitron', sans-serif; font-size: 1.2rem; font-weight: 700; color: var(--tertiary-neon); text-shadow: 0 0 5px var(--tertiary-neon); } /* Add a glitch effect to the achievement title */ .glitch-effect { position: relative; } .glitch-effect::before, .glitch-effect::after { content: "ACHIEVEMENT UNLOCKED"; position: absolute; width: 100%; height: 100%; left: 0; top: 0; } .glitch-effect::before { color: var(--secondary-neon); z-index: -1; animation: glitch-effect 3s infinite linear alternate-reverse; } .glitch-effect::after { color: var(--tertiary-neon); z-index: -2; animation: glitch-effect 2s infinite linear alternate-reverse; } @keyframes glitch-effect { 0% { left: -3px; top: -3px; } 25% { left: 1px; top: 0px; } 50% { left: -1px; top: 2px; } 75% { left: 3px; top: -1px; } 100% { left: -1px; top: -1px; } } </style> </head> <body> <div class="bg-grid"></div> <div class="achievement-modal"> <div class="highlight-scan"></div> <button class="close-btn">×</button> <div class="achievement-header"> <h1 class="achievement-title glitch-effect">ACHIEVEMENT UNLOCKED</h1> <p class="achievement-subtitle">Your gaming skills have evolved!</p> </div> <div class="achievement-content"> <div class="achievement-badge"> <div class="achievement-badge-inner"> <svg class="progress-ring" width="110" height="110"> <circle class="circle-bg" cx="55" cy="55" r="45"></circle> <circle class="circle" cx="55" cy="55" r="45"></circle> </svg> <div class="level-indicator"> LVL 5 </div> </div> </div> <p class="achievement-description"> You've mastered the art of <span class="achievement-highlight">Speed Runner</span> by completing "The Neon Labyrinth" in under 2 minutes, faster than 98% of all players! </p> <div class="achievement-xp"> +2,500 XP </div> <div class="achievement-actions"> <div class="action-btn share-btn"> <i>📱</i> Share </div> <div class="action-btn claim-btn"> <i>🏆</i> Claim </div> <div class="action-btn continue-btn"> <i>▶️</i> Continue </div> </div> </div> </div> <div class="particles-container"></div> <script> document.addEventListener('DOMContentLoaded', function() { // Animation for progress ring setTimeout(() => { const circle = document.querySelector('.circle'); const dashoffset = 283 - (283 * 0.85); // 85% completion circle.style.strokeDashoffset = dashoffset; }, 500); // Create particle effects function createParticles() { const colors = ['#00ffff', '#ff00ff', '#ffff00', '#ffffff']; const container = document.querySelector('.particles-container'); for (let i = 0; i < 40; i++) { setTimeout(() => { const particle = document.createElement('div'); particle.classList.add('particle'); // Random starting position centered around badge const modalRect = document.querySelector('.achievement-modal').getBoundingClientRect(); const badgeRect = document.querySelector('.achievement-badge').getBoundingClientRect(); const startX = badgeRect.left + badgeRect.width / 2 - modalRect.left; const startY = badgeRect.top + badgeRect.height / 2 - modalRect.top; particle.style.left = `${startX}px`; particle.style.top = `${startY}px`; // Random color const randomColor = colors[Math.floor(Math.random() * colors.length)]; particle.style.backgroundColor = randomColor; particle.style.boxShadow = `0 0 10px ${randomColor}`; // Random size const size = Math.random() * 10 + 5; particle.style.width = `${size}px`; particle.style.height = `${size}px`; // Random end position const angle = Math.random() * Math.PI * 2; const distance = 100 + Math.random() * 150; const endX = Math.cos(angle) * distance; const endY = Math.sin(angle) * distance; particle.style.setProperty('--endX', `${endX}px`); particle.style.setProperty('--endY', `${endY}px`); // Random animation duration const duration = 1 + Math.random() * 2; particle.style.animationDuration = `${duration}s`; container.appendChild(particle); // Remove particle after animation ends setTimeout(() => { particle.remove(); }, duration * 1000); }, i * 50); } } // Create ripple effect function function createRipple(event) { const button = event.currentTarget; const rect = button.getBoundingClientRect(); const circle = document.createElement('span'); circle.classList.add('ripple'); const diameter = Math.max(rect.width, rect.height); circle.style.width = circle.style.height = `${diameter}px`; const x = event.clientX - rect.left - diameter / 2; const y = event.clientY - rect.top - diameter / 2; circle.style.left = `${x}px`; circle.style.top = `${y}px`; button.appendChild(circle); setTimeout(() => { circle.remove(); }, 600); } // Apply ripple effect to all buttons const buttons = document.querySelectorAll('.action-btn'); buttons.forEach(button => { button.addEventListener('click', createRipple); }); // Handle button clicks document.querySelector('.share-btn').addEventListener('click', function() { // The create particles animation on share button click createParticles(); }); document.querySelector('.claim-btn').addEventListener('click', function() { const xpElement = document.querySelector('.achievement-xp'); xpElement.style.background = 'rgba(255, 255, 0, 0.2)'; xpElement.style.borderColor = 'var(--tertiary-neon)'; xpElement.style.boxShadow = '0 0 15px rgba(255, 255, 0, 0.3)'; xpElement.textContent = "Claimed: +2,500 XP"; // Disable the claim button this.style.opacity = '0.5'; this.style.cursor = 'default'; this.textContent = "Claimed"; this.removeEventListener('click', createRipple); createParticles(); }); document.querySelector('.continue-btn').addEventListener('click', function() { document.querySelector('.achievement-modal').style.animation = 'modalAppear 0.6s cubic-bezier(0.17, 0.67, 0.12, 1.35) reverse forwards'; setTimeout(() => { // For demonstration purposes, we'll just reset the modal setTimeout(() => { document.querySelector('.achievement-modal').style.animation = 'modalAppear 0.6s cubic-bezier(0.17, 0.67, 0.12, 1.35) forwards'; }, 600); }, 600); }); // Close button functionality document.querySelector('.close-btn').addEventListener('click', function() { document.querySelector('.achievement-modal').style.animation = 'modalAppear 0.6s cubic-bezier(0.17, 0.67, 0.12, 1.35) reverse forwards'; setTimeout(() => { // For demonstration purposes, we'll just reset the modal setTimeout(() => { document.querySelector('.achievement-modal').style.animation = 'modalAppear 0.6s cubic-bezier(0.17, 0.67, 0.12, 1.35) forwards'; }, 600); }, 600); }); // Initial particles show setTimeout(createParticles, 800); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Terroir Restaurant Reservations</title> <style> :root { --primary: #8B4513; --secondary: #D2B48C; --accent: #A0522D; --background: #FFF8E7; --text: #3A2618; --white: #FFFFFF; --green: #538d4e; --red: #9e2b25; --yellow: #d4a72c; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Garamond', serif; } body { background-color: #f5f5f5; display: flex; justify-content: center; align-items: center; min-height: 700px; color: var(--text); } .container { width: 700px; height: 700px; overflow: hidden; position: relative; } .reservation-modal { background-color: var(--background); border-radius: 10px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); width: 100%; height: 100%; position: relative; overflow: hidden; display: flex; flex-direction: column; } .modal-header { padding: 25px; background-color: var(--primary); color: var(--white); position: relative; overflow: hidden; z-index: 1; } .modal-header::before { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: url('data:image/svg+xml;utf8,<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg"><path d="M0 50 Q 25 0, 50 50 T 100 50" stroke="rgba(255,255,255,0.05)" fill="none" stroke-width="20" /></svg>'); opacity: 0.1; z-index: -1; } .modal-title { font-size: 32px; margin-bottom: 8px; letter-spacing: 1px; font-weight: 400; } .modal-subtitle { font-size: 16px; opacity: 0.9; font-weight: 300; letter-spacing: 0.5px; } .modal-content { padding: 25px; overflow-y: auto; flex-grow: 1; display: flex; flex-direction: column; gap: 20px; } .form-section { margin-bottom: 10px; } .form-section-title { font-size: 18px; margin-bottom: 12px; color: var(--primary); font-weight: 600; display: flex; align-items: center; gap: 10px; } .form-section-title::after { content: ""; height: 1px; background-color: var(--secondary); flex-grow: 1; } .form-row { display: flex; gap: 15px; margin-bottom: 15px; } .form-group { flex: 1; position: relative; } .form-group label { display: block; margin-bottom: 8px; font-size: 14px; color: var(--text); } .form-group input, .form-group select { width: 100%; padding: 12px; border: 1px solid var(--secondary); border-radius: 5px; background-color: var(--white); font-size: 16px; color: var(--text); transition: all 0.3s ease; } .form-group input:focus, .form-group select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px rgba(160, 82, 45, 0.1); } .table-map { position: relative; background-color: var(--white); border-radius: 8px; padding: 20px; margin-top: 10px; border: 1px solid var(--secondary); height: 200px; overflow: hidden; transition: all 0.3s ease; } .table-grid { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(2, 1fr); gap: 15px; height: 100%; } .table { background-color: var(--secondary); border-radius: 5px; display: flex; align-items: center; justify-content: center; cursor: pointer; position: relative; transition: all 0.3s ease; overflow: hidden; } .table.available { border: 2px solid var(--green); } .table.selected { transform: scale(0.95); background-color: var(--accent); color: var(--white); box-shadow: 0 5px 15px rgba(160, 82, 45, 0.3); } .table.unavailable { opacity: 0.6; background-color: #d9d9d9; border: 2px solid var(--red); cursor: not-allowed; } .table::before { content: ""; position: absolute; width: 100%; height: 100%; background: radial-gradient(circle, rgba(255,255,255,0.2) 0%, rgba(255,255,255,0) 70%); opacity: 0; transition: opacity 0.3s; } .table:hover::before { opacity: 1; } .table-number { font-size: 18px; font-weight: bold; } .table-status { position: absolute; bottom: 5px; font-size: 12px; width: 100%; text-align: center; } .time-slots { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 5px; } .time-slot { padding: 8px 15px; background-color: var(--white); border: 1px solid var(--secondary); border-radius: 20px; cursor: pointer; transition: all 0.3s ease; font-size: 14px; } .time-slot:hover { background-color: var(--secondary); color: var(--text); } .time-slot.selected { background-color: var(--accent); color: var(--white); border-color: var(--accent); transform: scale(0.95); } .time-slot.unavailable { opacity: 0.5; cursor: not-allowed; text-decoration: line-through; } .legend { display: flex; gap: 15px; margin-top: 10px; font-size: 12px; } .legend-item { display: flex; align-items: center; gap: 5px; } .legend-color { width: 12px; height: 12px; border-radius: 50%; } .legend-color.available { background-color: var(--green); } .legend-color.selected { background-color: var(--accent); } .legend-color.unavailable { background-color: var(--red); } .special-request { margin-top: 15px; } .special-request textarea { width: 100%; padding: 12px; border: 1px solid var(--secondary); border-radius: 5px; background-color: var(--white); font-size: 16px; resize: none; height: 80px; font-family: 'Garamond', serif; } .special-request textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 2px rgba(160, 82, 45, 0.1); } .modal-footer { padding: 20px 25px; background-color: rgba(139, 69, 19, 0.05); border-top: 1px solid rgba(139, 69, 19, 0.1); text-align: right; } .btn { padding: 12px 25px; border: none; border-radius: 5px; font-size: 16px; cursor: pointer; transition: all 0.3s ease; font-weight: 600; letter-spacing: 0.5px; } .btn-primary { background-color: var(--primary); color: var(--white); box-shadow: 0 4px 6px rgba(139, 69, 19, 0.1); } .btn-primary:hover { background-color: var(--accent); transform: translateY(-2px); box-shadow: 0 6px 12px rgba(139, 69, 19, 0.2); } .btn-secondary { background-color: transparent; color: var(--primary); margin-right: 10px; } .btn-secondary:hover { background-color: rgba(139, 69, 19, 0.05); } .toast { position: absolute; bottom: -60px; left: 50%; transform: translateX(-50%); background-color: var(--primary); color: var(--white); padding: 15px 25px; border-radius: 30px; font-size: 16px; box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); opacity: 0; transition: all 0.5s ease; z-index: 100; } .toast.show { bottom: 20px; opacity: 1; } .recommendation { background-color: rgba(212, 167, 44, 0.1); border-left: 4px solid var(--yellow); padding: 15px; border-radius: 5px; margin-top: 10px; font-style: italic; } .recommendation-title { font-weight: bold; margin-bottom: 5px; color: var(--accent); font-size: 14px; } .recommendation-text { font-size: 14px; } .availability-indicator { display: flex; align-items: center; gap: 5px; font-size: 14px; margin-top: 5px; } .indicator-dot { width: 8px; height: 8px; border-radius: 50%; } .indicator-dot.high { background-color: var(--green); } .indicator-dot.medium { background-color: var(--yellow); } .indicator-dot.low { background-color: var(--red); } @media (max-width: 600px) { .modal-title { font-size: 24px; } .form-row { flex-direction: column; gap: 10px; } .table-grid { grid-template-columns: repeat(2, 1fr); grid-template-rows: repeat(3, 1fr); } .time-slots { gap: 5px; } .time-slot { padding: 6px 10px; font-size: 12px; } } .loading { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 248, 231, 0.8); display: flex; justify-content: center; align-items: center; z-index: 1000; opacity: 0; visibility: hidden; transition: all 0.3s ease; } .loading.show { opacity: 1; visibility: visible; } .spinner { width: 50px; height: 50px; border: 5px solid rgba(139, 69, 19, 0.1); border-radius: 50%; border-top-color: var(--primary); animation: spin 1s ease-in-out infinite; } @keyframes spin { to { transform: rotate(360deg); } } .icon { display: inline-block; width: 20px; height: 20px; stroke-width: 0; stroke: currentColor; fill: currentColor; vertical-align: middle; } .animate-in { animation: fadeIn 0.5s ease forwards; } @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .pulse-animation { animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(139, 69, 19, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(139, 69, 19, 0); } 100% { box-shadow: 0 0 0 0 rgba(139, 69, 19, 0); } } </style> </head> <body> <div class="container"> <div class="reservation-modal"> <div class="modal-header"> <h1 class="modal-title">Terroir Dining Reservations</h1> <p class="modal-subtitle">Select your perfect table for an unforgettable culinary journey</p> </div> <div class="modal-content"> <div class="form-section animate-in" style="animation-delay: 0.1s"> <h2 class="form-section-title">Guest Details</h2> <div class="form-row"> <div class="form-group"> <label for="name">Full Name</label> <input type="text" id="name" placeholder="John Doe"> </div> <div class="form-group"> <label for="email">Email Address</label> <input type="email" id="email" placeholder="[email protected]"> </div> </div> <div class="form-row"> <div class="form-group"> <label for="phone">Phone Number</label> <input type="tel" id="phone" placeholder="(555) 123-4567"> </div> <div class="form-group"> <label for="guests">Number of Guests</label> <select id="guests"> <option value="1">1 Guest</option> <option value="2" selected>2 Guests</option> <option value="3">3 Guests</option> <option value="4">4 Guests</option> <option value="5">5 Guests</option> <option value="6">6 Guests</option> <option value="more">7+ Guests (call us)</option> </select> </div> </div> </div> <div class="form-section animate-in" style="animation-delay: 0.2s"> <h2 class="form-section-title">Reservation Details</h2> <div class="form-row"> <div class="form-group"> <label for="date">Select Date</label> <input type="date" id="date" min="" value=""> <div class="availability-indicator"> <span class="indicator-dot high"></span> <span>High availability on this date</span> </div> </div> <div class="form-group"> <label for="time">Select Time</label> <div class="time-slots"> <div class="time-slot" data-time="17:30">5:30 PM</div> <div class="time-slot" data-time="18:00">6:00 PM</div> <div class="time-slot" data-time="18:30">6:30 PM</div> <div class="time-slot unavailable" data-time="19:00">7:00 PM</div> <div class="time-slot" data-time="19:30">7:30 PM</div> <div class="time-slot" data-time="20:00">8:00 PM</div> <div class="time-slot" data-time="20:30">8:30 PM</div> <div class="time-slot unavailable" data-time="21:00">9:00 PM</div> </div> </div> </div> </div> <div class="form-section animate-in" style="animation-delay: 0.3s"> <h2 class="form-section-title">Select Your Table</h2> <div class="table-map"> <div class="table-grid"> <div class="table available" data-table="1"> <span class="table-number">1</span> <div class="table-status">Window</div> </div> <div class="table available" data-table="2"> <span class="table-number">2</span> <div class="table-status">Window</div> </div> <div class="table unavailable" data-table="3"> <span class="table-number">3</span> <div class="table-status">Fireplace</div> </div> <div class="table available" data-table="4"> <span class="table-number">4</span> <div class="table-status">Corner</div> </div> <div class="table available" data-table="5"> <span class="table-number">5</span> <div class="table-status">Private</div> </div> <div class="table available" data-table="6"> <span class="table-number">6</span> <div class="table-status">Central</div> </div> </div> </div> <div class="legend"> <div class="legend-item"> <div class="legend-color available"></div> <span>Available</span> </div> <div class="legend-item"> <div class="legend-color selected"></div> <span>Selected</span> </div> <div class="legend-item"> <div class="legend-color unavailable"></div> <span>Unavailable</span> </div> </div> <div class="recommendation"> <div class="recommendation-title">Chef's Recommendation</div> <div class="recommendation-text">Table 5 offers a private alcove setting perfect for intimate dinners, with a view of our herb garden and direct service from our sommelier.</div> </div> </div> <div class="form-section animate-in" style="animation-delay: 0.4s"> <h2 class="form-section-title">Special Requests</h2> <div class="special-request"> <textarea id="requests" placeholder="Let us know of any dietary requirements, special occasions, or seating preferences."></textarea> </div> </div> </div> <div class="modal-footer"> <button class="btn btn-secondary" id="cancel-btn">Cancel</button> <button class="btn btn-primary pulse-animation" id="reserve-btn">Confirm Reservation</button> </div> <div class="toast" id="toast">Your reservation details have been saved</div> <div class="loading" id="loading"> <div class="spinner"></div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Set default date to tomorrow const tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); const dateInput = document.getElementById('date'); dateInput.min = tomorrow.toISOString().split('T')[0]; dateInput.value = tomorrow.toISOString().split('T')[0]; // Handle time slot selection const timeSlots = document.querySelectorAll('.time-slot:not(.unavailable)'); timeSlots.forEach(slot => { slot.addEventListener('click', function() { timeSlots.forEach(s => s.classList.remove('selected')); this.classList.add('selected'); }); }); // Handle table selection const tables = document.querySelectorAll('.table:not(.unavailable)'); tables.forEach(table => { table.addEventListener('click', function() { if (this.classList.contains('selected')) { this.classList.remove('selected'); } else { tables.forEach(t => t.classList.remove('selected')); this.classList.add('selected'); } }); // Add hover animation table.addEventListener('mouseenter', function() { if (!this.classList.contains('unavailable')) { this.style.transform = 'scale(0.98)'; } }); table.addEventListener('mouseleave', function() { if (!this.classList.contains('selected')) { this.style.transform = 'scale(1)'; } }); }); // Handle date change dateInput.addEventListener('change', function() { const selectedDate = new Date(this.value); const dayOfWeek = selectedDate.getDay(); // Simulate different availability based on day of week const availabilityIndicator = document.querySelector('.availability-indicator'); const indicatorDot = document.querySelector('.indicator-dot'); let availabilityText = ""; // Weekend has low availability if (dayOfWeek === 5 || dayOfWeek === 6) { // Friday or Saturday indicatorDot.className = 'indicator-dot low'; availabilityText = "Limited availability on this date"; // Make some time slots unavailable document.querySelectorAll('.time-slot').forEach(slot => { if (['19:00', '19:30', '20:00'].includes(slot.dataset.time)) { slot.classList.add('unavailable'); } }); } // Tuesday and Wednesday have medium availability else if (dayOfWeek === 2 || dayOfWeek === 3) { indicatorDot.className = 'indicator-dot medium'; availabilityText = "Moderate availability on this date"; // Reset time slots document.querySelectorAll('.time-slot').forEach(slot => { if (slot.dataset.time !== '19:00' && slot.dataset.time !== '21:00') { slot.classList.remove('unavailable'); } }); } // Other days have high availability else { indicatorDot.className = 'indicator-dot high'; availabilityText = "High availability on this date"; // Reset time slots document.querySelectorAll('.time-slot').forEach(slot => { if (slot.dataset.time !== '19:00' && slot.dataset.time !== '21:00') { slot.classList.remove('unavailable'); } }); } availabilityIndicator.innerHTML = ` <span class="${indicatorDot.className}"></span> <span>${availabilityText}</span> `; }); // Handle number of guests change const guestsSelect = document.getElementById('guests'); guestsSelect.addEventListener('change', function() { const numGuests = parseInt(this.value); // Disable small tables for larger parties tables.forEach(table => { const tableNum = parseInt(table.dataset.table); if (numGuests > 4 && tableNum < 5) { table.classList.add('unavailable'); table.classList.remove('selected'); } else if (numGuests > 2 && tableNum < 3) { table.classList.add('unavailable'); table.classList.remove('selected'); } else if (!table.dataset.originallyUnavailable) { table.classList.remove('unavailable'); } }); // Update recommendation based on party size const recommendationText = document.querySelector('.recommendation-text'); if (numGuests >= 5) { recommendationText.textContent = "Table 6 in our central dining area can comfortably accommodate your party with extra space for a celebratory experience."; } else if (numGuests >= 3) { recommendationText.textContent = "Tables 4 and 5 are ideal for your group size, offering spacious seating and excellent views of our open kitchen."; } else { recommendationText.textContent = "Table 5 offers a private alcove setting perfect for intimate dinners, with a view of our herb garden and direct service from our sommelier."; } }); // Store original unavailable tables document.querySelectorAll('.table.unavailable').forEach(table => { table.dataset.originallyUnavailable = true; }); // Handle reservation button const reserveBtn = document.getElementById('reserve-btn'); reserveBtn.addEventListener('click', function() { const name = document.getElementById('name').value; const email = document.getElementById('email').value; const date = document.getElementById('date').value; const selectedTimeSlot = document.querySelector('.time-slot.selected'); const selectedTable = document.querySelector('.table.selected'); // Basic validation if (!name || !email || !date || !selectedTimeSlot || !selectedTable) { showToast('Please complete all required reservation details'); return; } // Show loading spinner const loading = document.getElementById('loading'); loading.classList.add('show'); // Simulate API call setTimeout(() => { loading.classList.remove('show'); // Success message showToast(`Reservation confirmed for ${selectedTimeSlot.textContent} at Table ${selectedTable.dataset.table}`); // Reset form partially (in a real app, we might redirect) document.querySelectorAll('.time-slot').forEach(s => s.classList.remove('selected')); document.querySelectorAll('.table').forEach(t => t.classList.remove('selected')); document.getElementById('requests').value = ''; }, 1500); }); // Handle cancel button const cancelBtn = document.getElementById('cancel-btn'); cancelBtn.addEventListener('click', function() { // In a real app this might close the modal // For demo purposes, just reset the form document.getElementById('name').value = ''; document.getElementById('email').value = ''; document.getElementById('phone').value = ''; document.getElementById('guests').value = '2'; document.getElementById('requests').value = ''; document.querySelectorAll('.time-slot').forEach(s => s.classList.remove('selected')); document.querySelectorAll('.table').forEach(t => t.classList.remove('selected')); showToast('Reservation canceled'); }); // Toast message function function showToast(message) { const toast = document.getElementById('toast'); toast.textContent = message; toast.classList.add('show'); setTimeout(() => { toast.classList.remove('show'); }, 3000); } }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Corporate Onboarding Modal</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } :root { --primary: #1a73e8; --primary-dark: #1557b6; --secondary: #34a853; --accent: #7536de; --text: #333; --text-light: #777; --border: #e6e6e6; --background: #f9f9f9; --white: #fff; --shadow: 0 8px 30px rgba(0, 0, 0, 0.12); --step-incomplete: #d0d0d0; } body { display: flex; justify-content: center; align-items: center; min-height: 100vh; background-color: var(--background); } .modal-container { position: relative; width: 100%; max-width: 650px; height: 650px; background-color: var(--white); border-radius: 12px; box-shadow: var(--shadow); overflow: hidden; transition: transform 0.3s, box-shadow 0.3s; } .modal-container:hover { transform: translateY(-5px); box-shadow: 0 12px 40px rgba(0, 0, 0, 0.18); } .modal-header { position: relative; padding: 30px 35px; background: linear-gradient(135deg, var(--primary), var(--accent)); color: var(--white); overflow: hidden; } .modal-header::before { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: repeating-linear-gradient( 45deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05) 10px, transparent 10px, transparent 20px ); animation: patternMove 30s linear infinite; } @keyframes patternMove { 0% { transform: translateX(0) translateY(0); } 100% { transform: translateX(100px) translateY(100px); } } .company-logo { display: flex; align-items: center; position: relative; z-index: 1; } .logo-mark { background-color: var(--white); width: 40px; height: 40px; border-radius: 8px; position: relative; display: flex; justify-content: center; align-items: center; font-weight: bold; font-size: 20px; color: var(--primary); margin-right: 12px; } .company-name { font-size: 22px; font-weight: 600; } .modal-header h1 { margin-top: 20px; font-size: 28px; font-weight: 700; position: relative; z-index: 1; } .modal-header p { margin-top: 8px; font-size: 16px; opacity: 0.9; position: relative; z-index: 1; } .progress-steps { display: flex; justify-content: space-between; margin: 35px 0 0; position: relative; z-index: 1; } .progress-line { position: absolute; top: 12px; left: 20px; right: 20px; height: 3px; background-color: rgba(255, 255, 255, 0.3); z-index: -1; } .progress-line-fill { height: 100%; width: 0%; background-color: var(--white); transition: width 0.5s ease-in-out; } .step { display: flex; flex-direction: column; align-items: center; position: relative; z-index: 2; } .step-number { width: 26px; height: 26px; border-radius: 50%; background-color: rgba(255, 255, 255, 0.3); display: flex; justify-content: center; align-items: center; font-size: 14px; font-weight: 600; color: var(--white); margin-bottom: 8px; transition: all 0.3s ease; } .step.active .step-number { background-color: var(--white); color: var(--primary); transform: scale(1.2); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2); } .step.completed .step-number { background-color: var(--white); color: var(--primary); } .step-label { font-size: 12px; color: var(--white); opacity: 0.7; transition: opacity 0.3s ease; } .step.active .step-label { opacity: 1; font-weight: 500; } .modal-body { padding: 0; height: calc(100% - 230px); overflow: hidden; } .slide-container { display: flex; height: 100%; transition: transform 0.5s cubic-bezier(0.65, 0, 0.35, 1); } .slide { flex: 0 0 100%; padding: 35px; height: 100%; overflow-y: auto; } .slide::-webkit-scrollbar { width: 6px; } .slide::-webkit-scrollbar-thumb { background-color: var(--border); border-radius: 6px; } .slide h2 { margin-bottom: 18px; color: var(--text); font-size: 20px; font-weight: 600; } .form-group { margin-bottom: 22px; } .form-group label { display: block; margin-bottom: 8px; font-size: 14px; font-weight: 500; color: var(--text); } .form-group input[type="text"], .form-group input[type="email"], .form-group input[type="password"], .form-group select { width: 100%; padding: 12px 16px; border: 1px solid var(--border); border-radius: 8px; font-size: 15px; color: var(--text); transition: all 0.3s; } .form-group input:focus, .form-group select:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px rgba(26, 115, 232, 0.15); } .password-field { position: relative; } .password-toggle { position: absolute; right: 12px; top: 12px; cursor: pointer; color: var(--text-light); background: none; border: none; font-size: 14px; } .checkbox-group { display: flex; align-items: center; margin-top: 5px; } .checkbox-group input[type="checkbox"] { width: 18px; height: 18px; margin-right: 10px; accent-color: var(--primary); cursor: pointer; } .checkbox-group label { cursor: pointer; margin-bottom: 0; } .team-avatars { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 5px; margin-bottom: 20px; } .avatar-container { position: relative; width: 80px; text-align: center; } .avatar { width: 60px; height: 60px; border-radius: 50%; object-fit: cover; margin-bottom: 8px; border: 2px solid transparent; transition: all 0.2s; cursor: pointer; } .avatar-container p { font-size: 12px; line-height: 1.2; color: var(--text); margin: 0; } .avatar-container p.role { font-size: 11px; color: var(--text-light); } .avatar:hover { transform: scale(1.05); border-color: var(--primary); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1); } .tool-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; margin-bottom: 15px; } .tool-item { display: flex; align-items: center; padding: 12px; border: 1px solid var(--border); border-radius: 8px; cursor: pointer; transition: all 0.2s; } .tool-item:hover { border-color: var(--primary); background-color: rgba(26, 115, 232, 0.05); } .tool-icon { flex-shrink: 0; width: 40px; height: 40px; border-radius: 8px; margin-right: 12px; display: flex; align-items: center; justify-content: center; font-size: 20px; color: var(--white); } .tool-info { flex-grow: 1; } .tool-name { font-weight: 500; font-size: 14px; margin-bottom: 2px; } .tool-desc { font-size: 12px; color: var(--text-light); line-height: 1.3; } .success-container { text-align: center; padding: 20px 0; } .success-icon { width: 80px; height: 80px; background-color: var(--secondary); color: white; border-radius: 50%; margin: 10px auto 20px; display: flex; align-items: center; justify-content: center; font-size: 40px; } .success-title { font-size: 24px; font-weight: 600; color: var(--text); margin-bottom: 15px; } .success-desc { font-size: 16px; color: var(--text-light); margin: 0 auto 25px; max-width: 350px; line-height: 1.5; } .success-desc strong { color: var(--text); } .next-steps { background-color: var(--background); border-radius: 8px; padding: 20px; text-align: left; margin-top: 20px; } .next-steps h3 { font-size: 16px; margin-bottom: 12px; color: var(--text); } .next-steps ul { list-style: none; } .next-steps li { margin-bottom: 10px; padding-left: 26px; position: relative; font-size: 14px; color: var(--text-light); } .next-steps li::before { content: "✓"; position: absolute; left: 0; color: var(--secondary); font-weight: bold; } .modal-footer { display: flex; justify-content: space-between; padding: 20px 35px; border-top: 1px solid var(--border); background-color: var(--white); } .btn { padding: 12px 24px; border-radius: 8px; font-size: 15px; font-weight: 500; cursor: pointer; transition: all 0.2s; outline: none; border: none; } .btn-back { background-color: var(--white); color: var(--text); border: 1px solid var(--border); } .btn-back:hover { background-color: var(--background); } .btn-next { background-color: var(--primary); color: var(--white); } .btn-next:hover { background-color: var(--primary-dark); } .btn-finish { background-color: var(--secondary); color: var(--white); } .btn-finish:hover { background-color: #2d9349; } .btn:disabled { opacity: 0.6; cursor: not-allowed; } /* Animation classes */ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } .fade-in { animation: fadeIn 0.5s ease forwards; } @keyframes checkmarkDraw { 0% { stroke-dashoffset: 100; } 100% { stroke-dashoffset: 0; } } .draw-checkmark { stroke-dasharray: 100; stroke-dashoffset: 100; animation: checkmarkDraw 1s ease-out forwards; } @media (max-width: 600px) { .modal-container { height: 600px; max-width: 100%; border-radius: 0; } .modal-header { padding: 25px; } .modal-header h1 { font-size: 24px; } .modal-body { height: calc(100% - 210px); } .slide { padding: 25px; } .tool-list { grid-template-columns: 1fr; } .modal-footer { padding: 15px 25px; } .step-label { display: none; } .progress-line { top: 12px; } } </style> </head> <body> <div class="modal-container"> <div class="modal-header"> <div class="company-logo"> <div class="logo-mark">N</div> <div class="company-name">NovaTech</div> </div> <h1>Welcome to NovaTech</h1> <p>Let's set up your company profile in just a few steps</p> <div class="progress-steps"> <div class="progress-line"> <div class="progress-line-fill" id="progress-fill"></div> </div> <div class="step active" data-step="1"> <div class="step-number">1</div> <div class="step-label">Your Details</div> </div> <div class="step" data-step="2"> <div class="step-number">2</div> <div class="step-label">Team Connect</div> </div> <div class="step" data-step="3"> <div class="step-number">3</div> <div class="step-label">Workspace</div> </div> <div class="step" data-step="4"> <div class="step-number">4</div> <div class="step-label">Confirmation</div> </div> </div> </div> <div class="modal-body"> <div class="slide-container"> <!-- Step 1: Account Information --> <div class="slide" id="slide-1"> <h2>Complete Your Profile</h2> <div class="form-group"> <label for="fullname">Full Name</label> <input type="text" id="fullname" placeholder="John Smith" required> </div> <div class="form-group"> <label for="jobtitle">Job Title</label> <input type="text" id="jobtitle" placeholder="Senior Developer" required> </div> <div class="form-group"> <label for="email">Work Email</label> <input type="email" id="email" placeholder="[email protected]" required> </div> <div class="form-group"> <label for="department">Department</label> <select id="department" required> <option value="" disabled selected>Select your department</option> <option value="engineering">Engineering</option> <option value="product">Product</option> <option value="design">Design</option> <option value="marketing">Marketing</option> <option value="sales">Sales</option> <option value="hr">Human Resources</option> <option value="finance">Finance</option> </select> </div> <div class="form-group"> <label for="password">Create Password</label> <div class="password-field"> <input type="password" id="password" placeholder="Choose a secure password" required> <button type="button" class="password-toggle" id="password-toggle">Show</button> </div> </div> <div class="form-group"> <div class="checkbox-group"> <input type="checkbox" id="terms"> <label for="terms">I agree to the NovaTech <a href="#" style="color: var(--primary);">Terms of Service</a> and <a href="#" style="color: var(--primary);">Privacy Policy</a></label> </div> </div> </div> <!-- Step 2: Team Connect --> <div class="slide" id="slide-2"> <h2>Connect with Your Team</h2> <p style="margin-bottom: 20px; color: var(--text-light);">We've found team members who you might work with frequently based on your department.</p> <h3 style="font-size: 16px; margin-bottom: 10px; color: var(--text);">Development Team</h3> <div class="team-avatars"> <div class="avatar-container"> <img src="https://randomuser.me/api/portraits/women/44.jpg" class="avatar"> <p>Sarah Chen</p> <p class="role">Lead Developer</p> </div> <div class="avatar-container"> <img src="https://randomuser.me/api/portraits/men/32.jpg" class="avatar"> <p>Michael Torres</p> <p class="role">Frontend Dev</p> </div> <div class="avatar-container"> <img src="https://randomuser.me/api/portraits/women/68.jpg" class="avatar"> <p>Jessica Kim</p> <p class="role">Backend Dev</p> </div> <div class="avatar-container"> <img src="https://randomuser.me/api/portraits/men/75.jpg" class="avatar"> <p>David Wilson</p> <p class="role">DevOps</p> </div> </div> <h3 style="font-size: 16px; margin-bottom: 10px; color: var(--text);">Product Team</h3> <div class="team-avatars"> <div class="avatar-container"> <img src="https://randomuser.me/api/portraits/women/25.jpg" class="avatar"> <p>Anika Patel</p> <p class="role">Product Manager</p> </div> <div class="avatar-container"> <img src="https://randomuser.me/api/portraits/men/55.jpg" class="avatar"> <p>Robert Garcia</p> <p class="role">UX Designer</p> </div> </div> <div class="form-group"> <div class="checkbox-group"> <input type="checkbox" id="add-team"> <label for="add-team">Connect with these team members</label> </div> </div> <div class="form-group"> <label for="manager">Your Direct Manager</label> <select id="manager" required> <option value="" disabled selected>Select your manager</option> <option value="sarah-chen">Sarah Chen (Lead Developer)</option> <option value="anika-patel">Anika Patel (Product Manager)</option> <option value="james-rodriguez">James Rodriguez (CTO)</option> </select> </div> </div> <!-- Step 3: Tools & Resources --> <div class="slide" id="slide-3"> <h2>Essential Tools & Resources</h2> <p style="margin-bottom: 20px; color: var(--text-light);">Select the tools you'll need access to for your role at NovaTech.</p> <div class="tool-list"> <div class="tool-item"> <div class="tool-icon" style="background-color: #2684FF;"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none"> <path d="M11.53 2.3L2 12.5l4.4 4.8L20 2.3h-8.47z" fill="currentColor"/> <path d="M14.67 12.1L6.4 21l8.33-3.07 5.93-2.2-6-3.63z" fill="currentColor"/> </svg> </div> <div class="tool-info"> <div class="tool-name">Jira</div> <div class="tool-desc">Project tracking & agile management</div> </div> </div> <div class="tool-item"> <div class="tool-icon" style="background-color: #1A73E8;"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none"> <path d="M12 4L2 9.6l10 5.6 8.5-4.76v6.56H22v-7L12 4zm8.5 9.52L12 18.2 3.5 13v-2.8L12 15.8l8.5-4.76v2.48z" fill="currentColor"/> </svg> </div> <div class="tool-info"> <div class="tool-name">Google Workspace</div> <div class="tool-desc">Email, docs, and collaboration</div> </div> </div> <div class="tool-item"> <div class="tool-icon" style="background-color: #6264A7;"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none"> <path d="M12 3L2 7l10 4 10-4-10-4zm0 10L2 9v8l10 4 10-4V9l-10 4z" fill="currentColor"/> </svg> </div> <div class="tool-info"> <div class="tool-name">Microsoft Teams</div> <div class="tool-desc">Chat and video conferencing</div> </div> </div> <div class="tool-item"> <div class="tool-icon" style="background-color: #FF5722;"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none"> <path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 14H4V6h16v12zM6 10h2v2H6v-2zm0 4h8v2H6v-2zm10 0h2v2h-2v-2zm-10-8h12v2H6V6z" fill="currentColor"/> </svg> </div> <div class="tool-info"> <div class="tool-name">Confluence</div> <div class="tool-desc">Team documentation & knowledge base</div> </div> </div> <div class="tool-item"> <div class="tool-icon" style="background-color: #7C3AED;"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none"> <path d="M17 3H7c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H7V5h10v14zm-4.5-7c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5.67-1.5 1.5-1.5 1.5.67 1.5 1.5z" fill="currentColor"/> </svg> </div> <div class="tool-info"> <div class="tool-name">Figma</div> <div class="tool-desc">Design collaboration</div> </div> </div> <div class="tool-item"> <div class="tool-icon" style="background-color: #24292E;"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none"> <path d="M12 2C6.48 2 2 6.48 2 12c0 4.42 2.87 8.17 6.84 9.5.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34-.46-1.16-1.11-1.47-1.11-1.47-.91-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.87 1.52 2.34 1.07 2.91.83.09-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.92 0-1.11.38-2 1.03-2.71-.1-.25-.45-1.29.1-2.64 0 0 .84-.27 2.75 1.02.79-.22 1.65-.33 2.5-.33.85 0 1.71.11 2.5.33 1.91-1.29 2.75-1.02 2.75-1.02.55 1.35.2 2.39.1 2.64.65.71 1.03 1.6 1.03 2.71 0 3.82-2.34 4.66-4.57 4.91.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0012 2z" fill="currentColor"/> </svg> </div> <div class="tool-info"> <div class="tool-name">GitHub</div> <div class="tool-desc">Code repository & version control</div> </div> </div> </div> <div class="form-group"> <label for="additional">Additional Tools Required</label> <input type="text" id="additional" placeholder="If you need other tools, please specify"> </div> </div> <!-- Step 4: Completion --> <div class="slide" id="slide-4"> <div class="success-container"> <div class="success-icon"> <svg width="40" height="40" 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" class="draw-checkmark"></polyline> </svg> </div> <h2 class="success-title">Setup Complete!</h2> <p class="success-desc"> Welcome aboard, <strong id="welcome-name">John</strong>! Your NovaTech account is now ready for you to start collaborating with your team. </p> <div class="next-steps"> <h3>What's Next?</h3> <ul> <li>Check your email for login credentials to the tools you selected</li> <li>Schedule a 15-minute orientation call with your manager</li> <li>Complete your compliance training by Friday</li> <li>Join the company all-hands meeting next Monday at 10 AM</li> </ul> </div> </div> </div> </div> </div> <div class="modal-footer"> <button class="btn btn-back" id="btn-back" disabled>Back</button> <button class="btn btn-next" id="btn-next">Continue</button> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { const slides = document.querySelectorAll('.slide'); const slideContainer = document.querySelector('.slide-container'); const steps = document.querySelectorAll('.step'); const progressFill = document.getElementById('progress-fill'); const btnBack = document.getElementById('btn-back'); const btnNext = document.getElementById('btn-next'); const passwordField = document.getElementById('password'); const passwordToggle = document.getElementById('password-toggle'); const fullnameInput = document.getElementById('fullname'); const welcomeName = document.getElementById('welcome-name'); let currentSlide = 0; const totalSlides = slides.length; // Initialize the form updateUI(); // Add event listeners btnNext.addEventListener('click', nextSlide); btnBack.addEventListener('click', prevSlide); // Password visibility toggle passwordToggle.addEventListener('click', function() { const type = passwordField.getAttribute('type') === 'password' ? 'text' : 'password'; passwordField.setAttribute('type', type); passwordToggle.textContent = type === 'password' ? 'Show' : 'Hide'; }); // Tool items click handler const toolItems = document.querySelectorAll('.tool-item'); toolItems.forEach(item => { item.addEventListener('click', function() { this.classList.toggle('selected'); if (this.classList.contains('selected')) { this.style.borderColor = 'var(--primary)'; this.style.backgroundColor = 'rgba(26, 115, 232, 0.05)'; } else { this.style.borderColor = 'var(--border)'; this.style.backgroundColor = ''; } }); }); // Avatar click handler const avatars = document.querySelectorAll('.avatar'); avatars.forEach(avatar => { avatar.addEventListener('click', function() { this.classList.toggle('selected'); if (this.classList.contains('selected')) { this.style.borderColor = 'var(--primary)'; this.style.boxShadow = '0 3px 10px rgba(0, 0, 0, 0.2)'; } else { this.style.borderColor = 'transparent'; this.style.boxShadow = ''; } }); }); function nextSlide() { if (currentSlide < totalSlides - 1) { currentSlide++; updateUI(); // If this is the last slide, update the welcome name if (currentSlide === totalSlides - 1) { const name = fullnameInput.value.split(' ')[0] || 'John'; welcomeName.textContent = name; } } } function prevSlide() { if (currentSlide > 0) { currentSlide--; updateUI(); } } function updateUI() { // Update slides slideContainer.style.transform = `translateX(-${currentSlide * 100}%)`; // Update steps steps.forEach((step, index) => { if (index < currentSlide) { step.classList.remove('active'); step.classList.add('completed'); } else if (index === currentSlide) { step.classList.add('active'); step.classList.remove('completed'); } else { step.classList.remove('active', 'completed'); } }); // Update progress bar const progressPercentage = (currentSlide / (totalSlides - 1)) * 100; progressFill.style.width = `${progressPercentage}%`; // Update buttons btnBack.disabled = currentSlide === 0; if (currentSlide === totalSlides - 1) { btnNext.textContent = 'Get Started'; btnNext.classList.remove('btn-next'); btnNext.classList.add('btn-finish'); // Add a fun animation when reaching the complete step const successContainer = document.querySelector('.success-container'); successContainer.classList.add('fade-in'); } else { btnNext.textContent = 'Continue'; btnNext.classList.add('btn-next'); btnNext.classList.remove('btn-finish'); } // Add subtle animation to the current slide slides.forEach((slide, index) => { if (index === currentSlide) { slide.classList.add('fade-in'); } else { slide.classList.remove('fade-in'); } }); } // Form validation for the first slide const requiredFields = document.querySelectorAll('#slide-1 input[required], #slide-1 select[required]'); const termsCheckbox = document.getElementById('terms'); requiredFields.forEach(field => { field.addEventListener('input', validateForm); }); termsCheckbox.addEventListener('change', validateForm); function validateForm() { let isValid = true; requiredFields.forEach(field => { if (!field.value.trim()) { isValid = false; } }); if (!termsCheckbox.checked) { isValid = false; } btnNext.disabled = !isValid && currentSlide === 0; } // Initialize validation validateForm(); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>E-learning Quiz Feedback</title> <style> :root { --primary: #FF5757; --secondary: #3A86FF; --success: #4CAF50; --warning: #FFBE0B; --dark: #2D3142; --light: #F8F9FA; --correct: #02C39A; --incorrect: #FF595E; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', sans-serif; } @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap'); body { background-color: #f5f5f5; height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; color: var(--dark); } .container { position: relative; width: 100%; max-width: 700px; height: 700px; padding: 20px; overflow: hidden; background-color: var(--light); } .quiz-intro { position: absolute; width: 100%; height: 100%; left: 0; top: 0; padding: 40px; display: flex; flex-direction: column; justify-content: center; align-items: center; background-color: var(--light); z-index: 10; transition: transform 0.6s ease-in-out; } .quiz-intro.slide-up { transform: translateY(-100%); } .intro-title { font-size: 2.5rem; font-weight: 700; margin-bottom: 20px; color: var(--primary); text-align: center; } .intro-subtitle { font-size: 1.2rem; margin-bottom: 40px; text-align: center; color: var(--dark); } .start-btn { padding: 12px 32px; background-color: var(--secondary); color: white; border: none; border-radius: 30px; font-size: 1.1rem; font-weight: 600; cursor: pointer; transition: transform 0.3s, background-color 0.3s; box-shadow: 0 4px 10px rgba(58, 134, 255, 0.3); } .start-btn:hover { background-color: #2a75ff; transform: translateY(-3px); } .quiz-container { height: 100%; display: flex; flex-direction: column; opacity: 0; transition: opacity 0.5s ease; } .quiz-container.active { opacity: 1; } .question-count { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .count-text { font-size: 1.1rem; font-weight: 600; color: var(--secondary); } .timer { background-color: var(--warning); color: white; padding: 8px 16px; border-radius: 20px; font-weight: 600; } .question { font-size: 1.4rem; font-weight: 600; margin-bottom: 25px; color: var(--dark); } .options { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 30px; } .option { background-color: white; padding: 20px; border-radius: 10px; cursor: pointer; transition: all 0.3s; border: 2px solid #e0e0e0; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05); display: flex; align-items: center; } .option:hover { transform: translateY(-3px); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); border-color: var(--secondary); } .option.selected { border-color: var(--secondary); background-color: rgba(58, 134, 255, 0.1); } .option-letter { width: 35px; height: 35px; border-radius: 50%; background-color: #f0f0f0; display: flex; justify-content: center; align-items: center; font-weight: 600; margin-right: 15px; color: var(--dark); } .option.selected .option-letter { background-color: var(--secondary); color: white; } .next-btn { align-self: flex-end; padding: 12px 25px; background-color: var(--secondary); color: white; border: none; border-radius: 30px; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.3s; box-shadow: 0 4px 10px rgba(58, 134, 255, 0.3); margin-top: auto; } .next-btn:hover { background-color: #2a75ff; transform: translateY(-3px); } .next-btn:disabled { background-color: #b0b0b0; cursor: not-allowed; transform: none; box-shadow: none; } .result-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: center; z-index: 100; opacity: 0; visibility: hidden; transition: all 0.5s; } .result-modal.show { opacity: 1; visibility: visible; } .result-content { width: 90%; max-width: 600px; background-color: white; border-radius: 15px; padding: 40px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); position: relative; transform: scale(0.8); transition: transform 0.5s; overflow: hidden; } .result-modal.show .result-content { transform: scale(1); } .confetti { position: absolute; width: 100%; height: 100%; top: 0; left: 0; pointer-events: none; z-index: -1; } .result-header { text-align: center; margin-bottom: 30px; } .result-title { font-size: 2.2rem; font-weight: 700; margin-bottom: 15px; background: linear-gradient(to right, var(--primary), var(--secondary)); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; } .score-display { display: flex; justify-content: center; align-items: center; margin-bottom: 30px; } .score-circle { width: 150px; height: 150px; position: relative; display: flex; justify-content: center; align-items: center; } .score-text { font-size: 2.5rem; font-weight: 700; color: var(--secondary); } .performance-graph { margin-bottom: 30px; } .graph-title { font-size: 1.2rem; font-weight: 600; margin-bottom: 15px; text-align: center; } .bar-container { display: flex; align-items: flex-end; justify-content: space-between; height: 150px; } .graph-bar { flex: 1; margin: 0 5px; background-color: #e0e0e0; border-radius: 5px 5px 0 0; height: 20%; position: relative; transition: height 1s cubic-bezier(0.68, -0.55, 0.27, 1.55); } .bar-label { position: absolute; bottom: -25px; left: 0; width: 100%; text-align: center; font-size: 0.8rem; font-weight: 500; } .feedback-section { margin-bottom: 30px; } .feedback-title { font-size: 1.2rem; font-weight: 600; margin-bottom: 15px; } .feedback-text { line-height: 1.6; } .finish-btn { display: block; width: 100%; padding: 12px; background-color: var(--primary); color: white; border: none; border-radius: 30px; font-size: 1rem; font-weight: 600; cursor: pointer; transition: all 0.3s; box-shadow: 0 4px 10px rgba(255, 87, 87, 0.3); } .finish-btn:hover { background-color: #ff3c3c; transform: translateY(-3px); } @media (max-width: 600px) { .options { grid-template-columns: 1fr; } .intro-title { font-size: 2rem; } .result-title { font-size: 1.8rem; } .result-content { padding: 25px; } .score-circle { width: 120px; height: 120px; } .score-text { font-size: 2rem; } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes confettiRain { 0% { transform: translateY(-100vh) rotate(0deg); } 100% { transform: translateY(100vh) rotate(360deg); } } .confetti-piece { position: absolute; width: 10px; height: 30px; background: #ffd700; top: -10%; opacity: 0; } .progress-ring { position: absolute; top: 0; left: 0; } .question-progress { width: 100%; height: 8px; background-color: #e0e0e0; border-radius: 10px; margin-bottom: 30px; overflow: hidden; } .progress-bar { height: 100%; background-color: var(--secondary); border-radius: 10px; width: 0; transition: width 0.4s ease; } .badge { display: inline-block; padding: 8px 16px; border-radius: 20px; font-weight: 600; margin-top: 15px; animation: fadeIn 0.8s forwards; box-shadow: 0 3px 6px rgba(0, 0, 0, 0.1); } .badge.excellent { background-color: var(--success); color: white; } .badge.good { background-color: var(--warning); color: var(--dark); } .badge.needs-improvement { background-color: var(--incorrect); color: white; } .detailed-feedback { margin-top: 20px; padding: 15px; border-radius: 10px; background-color: #f5f5f5; transition: all 0.3s; } .detailed-feedback ul { margin-top: 10px; padding-left: 20px; } .detailed-feedback li { margin-bottom: 8px; } .restart-quiz { margin-top: 15px; background-color: transparent; border: 2px solid var(--secondary); color: var(--secondary); padding: 10px 20px; border-radius: 30px; font-weight: 600; cursor: pointer; transition: all 0.3s; } .restart-quiz:hover { background-color: var(--secondary); color: white; } </style> </head> <body> <div class="container"> <div class="quiz-intro" id="quizIntro"> <h1 class="intro-title">Digital Marketing Fundamentals</h1> <p class="intro-subtitle">Test your knowledge of key digital marketing concepts with this quick 5-question assessment. Ready to showcase your expertise?</p> <button class="start-btn" id="startQuiz">Start Quiz</button> </div> <div class="quiz-container" id="quizContainer"> <div class="question-count"> <span class="count-text" id="questionCount">Question 1 of 5</span> <span class="timer" id="timer">00:30</span> </div> <div class="question-progress"> <div class="progress-bar" id="progressBar"></div> </div> <h2 class="question" id="question">What is the primary purpose of search engine optimization (SEO)?</h2> <div class="options" id="options"> <div class="option" data-index="0"> <div class="option-letter">A</div> <span>To increase ad visibility</span> </div> <div class="option" data-index="1"> <div class="option-letter">B</div> <span>To improve website ranking in search results</span> </div> <div class="option" data-index="2"> <div class="option-letter">C</div> <span>To increase social media followers</span> </div> <div class="option" data-index="3"> <div class="option-letter">D</div> <span>To reduce website loading time</span> </div> </div> <button class="next-btn" id="nextButton" disabled>Next Question</button> </div> </div> <div class="result-modal" id="resultModal"> <div class="confetti" id="confetti"></div> <div class="result-content"> <div class="result-header"> <h2 class="result-title">Your Quiz Results</h2> <div id="performanceBadge"></div> </div> <div class="score-display"> <div class="score-circle"> <svg class="progress-ring" width="150" height="150"> <circle id="progressCircle" stroke="#3A86FF" stroke-width="10" fill="transparent" r="65" cx="75" cy="75" stroke-dasharray="408" stroke-dashoffset="408" /> </svg> <span class="score-text" id="scoreText">0%</span> </div> </div> <div class="performance-graph"> <h3 class="graph-title">Question Performance</h3> <div class="bar-container" id="barContainer"> <div class="graph-bar" style="height: 0%;"> <span class="bar-label">Q1</span> </div> <div class="graph-bar" style="height: 0%;"> <span class="bar-label">Q2</span> </div> <div class="graph-bar" style="height: 0%;"> <span class="bar-label">Q3</span> </div> <div class="graph-bar" style="height: 0%;"> <span class="bar-label">Q4</span> </div> <div class="graph-bar" style="height: 0%;"> <span class="bar-label">Q5</span> </div> </div> </div> <div class="feedback-section"> <h3 class="feedback-title">Feedback Summary</h3> <p class="feedback-text" id="feedbackText"></p> <div class="detailed-feedback" id="detailedFeedback"></div> </div> <div class="actions"> <button class="finish-btn" id="finishBtn">Finish Quiz</button> <button class="restart-quiz" id="restartQuiz">Try Again</button> </div> </div> </div> <script> // Quiz data with questions, options and answers const quizData = [ { question: "What is the primary purpose of search engine optimization (SEO)?", options: [ "To increase ad visibility", "To improve website ranking in search results", "To increase social media followers", "To reduce website loading time" ], answer: 1 }, { question: "Which metric measures the percentage of website visitors who leave after viewing only one page?", options: [ "Conversion rate", "Click-through rate", "Bounce rate", "Engagement rate" ], answer: 2 }, { question: "What does CTA stand for in digital marketing?", options: [ "Click To Advance", "Call To Action", "Content Target Analysis", "Customer Traffic Acquisition" ], answer: 1 }, { question: "Which social media platform is known for its professional networking focus?", options: [ "Instagram", "Twitter", "LinkedIn", "TikTok" ], answer: 2 }, { question: "What is remarketing in digital advertising?", options: [ "Rebranding a product for a new market", "Targeting ads to users who previously visited your site", "Refreshing old content for new campaigns", "Reusing the same ad across multiple platforms" ], answer: 1 } ]; // DOM elements const quizIntro = document.getElementById('quizIntro'); const startQuizBtn = document.getElementById('startQuiz'); const quizContainer = document.getElementById('quizContainer'); const questionCount = document.getElementById('questionCount'); const timerElement = document.getElementById('timer'); const questionElement = document.getElementById('question'); const optionsContainer = document.getElementById('options'); const nextButton = document.getElementById('nextButton'); const resultModal = document.getElementById('resultModal'); const scoreText = document.getElementById('scoreText'); const feedbackText = document.getElementById('feedbackText'); const detailedFeedback = document.getElementById('detailedFeedback'); const performanceBadge = document.getElementById('performanceBadge'); const finishBtn = document.getElementById('finishBtn'); const restartQuiz = document.getElementById('restartQuiz'); const progressBar = document.getElementById('progressBar'); const barContainer = document.getElementById('barContainer'); const progressCircle = document.getElementById('progressCircle'); const confettiContainer = document.getElementById('confetti'); // Quiz state variables let currentQuestion = 0; let score = 0; let timer; let timeLeft = 30; let selectedOption = null; let userAnswers = []; let quizStarted = false; // Initialize the quiz function initQuiz() { currentQuestion = 0; score = 0; userAnswers = []; loadQuestion(); startTimer(); quizStarted = true; updateProgressBar(); } // Load current question and options function loadQuestion() { if (currentQuestion < quizData.length) { selectedOption = null; nextButton.disabled = true; questionCount.textContent = `Question ${currentQuestion + 1} of ${quizData.length}`; questionElement.textContent = quizData[currentQuestion].question; // Clear previous options optionsContainer.innerHTML = ''; // Add options for current question quizData[currentQuestion].options.forEach((option, index) => { const optionDiv = document.createElement('div'); optionDiv.classList.add('option'); optionDiv.setAttribute('data-index', index); optionDiv.innerHTML = ` <div class="option-letter">${String.fromCharCode(65 + index)}</div> <span>${option}</span> `; optionDiv.addEventListener('click', () => selectOption(optionDiv, index)); optionsContainer.appendChild(optionDiv); }); resetTimer(); } else { showResults(); } } // Handle option selection function selectOption(element, index) { // Remove selected class from all options const options = document.querySelectorAll('.option'); options.forEach(option => option.classList.remove('selected')); // Add selected class to clicked option element.classList.add('selected'); selectedOption = index; nextButton.disabled = false; // Store user's answer userAnswers[currentQuestion] = { selected: index, correct: index === quizData[currentQuestion].answer }; } // Timer functions function startTimer() { clearInterval(timer); timeLeft = 30; timerElement.textContent = formatTime(timeLeft); timer = setInterval(() => { timeLeft--; timerElement.textContent = formatTime(timeLeft); if (timeLeft <= 0) { clearInterval(timer); if (selectedOption === null) { // If no option was selected, record it as incorrect userAnswers[currentQuestion] = { selected: null, correct: false }; } nextQuestion(); } }, 1000); } function resetTimer() { clearInterval(timer); startTimer(); } function formatTime(seconds) { return `00:${seconds < 10 ? '0' : ''}${seconds}`; } // Progress to next question function nextQuestion() { if (currentQuestion < quizData.length - 1) { currentQuestion++; loadQuestion(); updateProgressBar(); } else { showResults(); } } // Update progress bar function updateProgressBar() { const progress = ((currentQuestion) / quizData.length) * 100; progressBar.style.width = `${progress}%`; } // Show quiz results function showResults() { clearInterval(timer); // Calculate score score = userAnswers.filter(answer => answer && answer.correct).length; const percentage = Math.round((score / quizData.length) * 100); // Update score text scoreText.textContent = `${percentage}%`; // Animate progress circle const circle = progressCircle; const radius = circle.r.baseVal.value; const circumference = 2 * Math.PI * radius; circle.style.strokeDasharray = `${circumference} ${circumference}`; const offset = circumference - (percentage / 100) * circumference; circle.style.strokeDashoffset = offset; // Set circle color based on score if (percentage >= 80) { circle.setAttribute('stroke', '#4CAF50'); } else if (percentage >= 60) { circle.setAttribute('stroke', '#FFBE0B'); } else { circle.setAttribute('stroke', '#FF595E'); } // Generate performance badge if (percentage >= 80) { performanceBadge.innerHTML = '<div class="badge excellent">Excellent!</div>'; } else if (percentage >= 60) { performanceBadge.innerHTML = '<div class="badge good">Good Effort!</div>'; } else { performanceBadge.innerHTML = '<div class="badge needs-improvement">Needs Improvement</div>'; } // Generate feedback text let feedback = ''; if (percentage >= 80) { feedback = "Outstanding! You've demonstrated excellent knowledge of digital marketing fundamentals. Your understanding of key concepts will serve you well in any marketing role."; } else if (percentage >= 60) { feedback = "Good job! You have a solid grasp of digital marketing basics. With a bit more study in a few areas, you'll be an expert in no time."; } else { feedback = "You've taken the first step in learning digital marketing. Focus on the areas highlighted below to strengthen your knowledge."; } feedbackText.textContent = feedback; // Generate detailed feedback let detailedHTML = '<ul>'; let strengths = []; let weaknesses = []; userAnswers.forEach((answer, index) => { if (answer && answer.correct) { strengths.push(quizData[index].question); } else { const correctAnswerIndex = quizData[index].answer; const correctAnswer = quizData[index].options[correctAnswerIndex]; weaknesses.push({ question: quizData[index].question, correctAnswer }); } }); if (strengths.length > 0) { detailedHTML += '<li><strong>Strengths:</strong> You demonstrated good understanding of ' + (strengths.length === 1 ? 'this concept' : 'these concepts') + '.</li>'; } if (weaknesses.length > 0) { detailedHTML += '<li><strong>Areas to improve:</strong></li>'; weaknesses.forEach(item => { detailedHTML += `<li>${item.question} (Correct answer: ${item.correctAnswer})</li>`; }); } detailedHTML += '</ul>'; detailedFeedback.innerHTML = detailedHTML; // Animate bars in the performance graph setTimeout(() => { const bars = barContainer.querySelectorAll('.graph-bar'); userAnswers.forEach((answer, index) => { setTimeout(() => { if (answer && answer.correct) { bars[index].style.height = '100%'; bars[index].style.backgroundColor = '#4CAF50'; } else { bars[index].style.height = '40%'; bars[index].style.backgroundColor = '#FF595E'; } }, index * 200); }); }, 500); // Create confetti for high scores if (percentage >= 70) { createConfetti(); } // Show the modal resultModal.classList.add('show'); } // Create confetti animation function createConfetti() { const colors = ['#FF5757', '#3A86FF', '#4CAF50', '#FFBE0B', '#FF5757', '#02C39A']; for (let i = 0; i < 100; i++) { const confetti = document.createElement('div'); confetti.classList.add('confetti-piece'); confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; confetti.style.left = Math.random() * 100 + '%'; confetti.style.width = Math.random() * 10 + 5 + 'px'; confetti.style.height = Math.random() * 20 + 10 + 'px'; confetti.style.opacity = Math.random() + 0.5; confetti.style.transform = `rotate(${Math.random() * 360}deg)`; confetti.style.animation = `confettiRain ${Math.random() * 3 + 2}s linear infinite`; confetti.style.animationDelay = Math.random() * 5 + 's'; confettiContainer.appendChild(confetti); } } // Event listeners startQuizBtn.addEventListener('click', () => { quizIntro.classList.add('slide-up'); quizContainer.classList.add('active'); setTimeout(initQuiz, 400); }); nextButton.addEventListener('click', nextQuestion); finishBtn.addEventListener('click', () => { resultModal.classList.remove('show'); quizIntro.classList.remove('slide-up'); quizContainer.classList.remove('active'); }); restartQuiz.addEventListener('click', () => { resultModal.classList.remove('show'); setTimeout(() => { initQuiz(); }, 300); }); </script> </body> </html>