| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> |
| <meta name="theme-color" content="#121212"> |
| <title>Subscription Portal UI - Liquid Glass</title> |
| <style> |
| |
| body { |
| margin: 0; |
| padding: 0; |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; |
| background-color: #0a0a0a; |
| color: white; |
| display: flex; |
| justify-content: center; |
| height: 100vh; |
| overflow: hidden; |
| } |
| |
| |
| .app-container { |
| width: 100%; |
| max-width: 400px; |
| height: 100%; |
| position: relative; |
| display: flex; |
| flex-direction: column; |
| overflow: hidden; |
| background: #121212; |
| } |
| |
| |
| .app-container::before { |
| content: ''; |
| position: absolute; |
| top: 20%; |
| left: -100px; |
| width: 300px; |
| height: 300px; |
| background: #1DB954; |
| filter: blur(90px); |
| opacity: 0.4; |
| z-index: 0; |
| } |
| .app-container::after { |
| content: ''; |
| position: absolute; |
| bottom: 10%; |
| right: -100px; |
| width: 300px; |
| height: 300px; |
| background: #E50914; |
| filter: blur(90px); |
| opacity: 0.3; |
| z-index: 0; |
| } |
| |
| |
| .glass { |
| background: rgba(40, 40, 40, 0.4); |
| box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.5); |
| backdrop-filter: blur( 15px ); |
| -webkit-backdrop-filter: blur( 15px ); |
| border: 1px solid rgba( 255, 255, 255, 0.1 ); |
| } |
| |
| |
| .header { |
| padding: 30px 25px; |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| z-index: 10; |
| } |
| .header h1 { margin: 0; font-size: 26px; font-weight: 800; letter-spacing: 0.5px;} |
| .header .revenue { color: #1DB954; font-weight: 700; font-size: 16px; text-shadow: 0 0 10px rgba(29, 185, 84, 0.3);} |
| |
| |
| .card-stack { |
| flex: 1; |
| position: relative; |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| z-index: 10; |
| } |
| |
| .card { |
| width: 85%; |
| height: 58%; |
| border-radius: 24px; |
| position: absolute; |
| display: flex; |
| flex-direction: column; |
| justify-content: space-between; |
| padding: 25px; |
| box-sizing: border-box; |
| transition:All 0.4s cubic-bezier(0.25, 0.8, 0.25, 1); |
| |
| |
| background: rgba(50, 50, 50, 0.3); |
| box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3); |
| backdrop-filter: blur( 20px ); |
| -webkit-backdrop-filter: blur( 20px ); |
| border-top: 1px solid rgba( 255, 255, 255, 0.2 ); |
| border-left: 1px solid rgba( 255, 255, 255, 0.2 ); |
| } |
| |
| |
| .service-badge { |
| align-self: flex-start; |
| padding: 6px 14px; |
| border-radius: 50px; |
| font-size: 12px; |
| font-weight: 700; |
| text-transform: uppercase; |
| letter-spacing: 1px; |
| |
| background: rgba(255, 255, 255, 0.05); |
| backdrop-filter: blur(5px); |
| border: 1px solid rgba(255,255,255,0.1); |
| } |
| |
| |
| .dot { |
| height: 8px; |
| width: 8px; |
| border-radius: 50%; |
| display: inline-block; |
| margin-right: 8px; |
| } |
| |
| |
| .client-info h2 { font-size: 30px; margin: 0 0 10px 0; font-weight: 800; } |
| .client-info p { color: rgba(255,255,255,0.7); margin: 0; font-size: 15px; font-weight: 500;} |
| .expiry-warning { color: #ff5555; font-size: 14px; margin-top: 15px; display: block; font-weight: 600; letter-spacing: 0.5px;} |
| |
| |
| .actions { |
| padding: 0 30px 110px 30px; |
| display: flex; |
| justify-content: space-between; |
| gap: 15px; |
| z-index: 10; |
| } |
| |
| .btn-action { |
| flex: 1; |
| height: 55px; |
| border-radius: 20px; |
| border: none; |
| font-size: 15px; |
| font-weight: 700; |
| cursor: pointer; |
| transition: transform 0.1s; |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| text-transform: uppercase; |
| letter-spacing: 1px; |
| } |
| .btn-action:active { transform: scale(0.97); } |
| |
| .btn-message { |
| background-color: transparent; |
| color: white; |
| border: 2px solid rgba(255,255,255,0.3); |
| } |
| .btn-renew { |
| background-color: #1DB954; |
| color: #0a0a0a; |
| box-shadow: 0 5px 15px rgba(29, 185, 84, 0.3); |
| } |
| |
| |
| .bottom-nav { |
| position: absolute; |
| bottom: 0; |
| width: 100%; |
| height: 85px; |
| display: flex; |
| justify-content: space-around; |
| align-items: center; |
| z-index: 20; |
| padding-bottom: 10px; |
| |
| |
| background: rgba(30, 30, 30, 0.6); |
| backdrop-filter: blur( 20px ); |
| -webkit-backdrop-filter: blur( 20px ); |
| border-top: 1px solid rgba( 255, 255, 255, 0.1 ); |
| } |
| .nav-item { |
| display: flex; |
| flex-direction: column; |
| align-items: center; |
| color: rgba(255,255,255,0.5); |
| font-size: 11px; |
| font-weight: 600; |
| gap: 6px; |
| cursor: pointer; |
| width: 60px; |
| } |
| .nav-item.active { color: #1DB954; } |
| .nav-item.active .nav-box { background: #1DB954; border:none;} |
| |
| |
| .nav-box { |
| width: 24px; |
| height: 24px; |
| border-radius: 8px; |
| border: 2px solid rgba(255,255,255,0.3); |
| transition: 0.2s; |
| } |
| .nav-add-btn { |
| width: 45px; |
| height: 45px; |
| background: linear-gradient(135deg, #1DB954, #1ed760); |
| border-radius: 15px; |
| display: flex; |
| justify-content: center; |
| align-items: center; |
| font-size: 24px; |
| color: #0a0a0a; |
| box-shadow: 0 5px 15px rgba(29, 185, 84, 0.4); |
| } |
| |
| |
| .swipe-right { |
| transform: translateX(130%) rotate(15deg) scale(0.8) !important; |
| opacity: 0 !important; |
| } |
| .swipe-left { |
| transform: translateX(-130%) rotate(-15deg) scale(0.8) !important; |
| opacity: 0 !important; |
| } |
| </style> |
| </head> |
| <body> |
|
|
| <div class="app-container"> |
| <div class="header"> |
| <div> |
| <div style="font-size:13px; color:rgba(255,255,255,0.6); margin-bottom:4px;">Hello Admin,</div> |
| <h1>Overview</h1> |
| </div> |
| <div class="revenue">ZMW 4,500</div> |
| </div> |
|
|
| <div class="card-stack" id="cardStack"> |
| </div> |
|
|
| <div class="actions"> |
| <button class="btn-action btn-message" onclick="swipeLeft()"> |
| Message |
| </button> |
| <button class="btn-action btn-renew" onclick="swipeRight()"> |
| Renew Client |
| </button> |
| </div> |
|
|
| <div class="bottom-nav"> |
| <div class="nav-item active"> |
| <div class="nav-box"></div> |
| <span>Home</span> |
| </div> |
| <div class="nav-item"> |
| <div class="nav-box"></div> |
| <span>List</span> |
| </div> |
| <div class="nav-item"> |
| <div class="nav-add-btn">+</div> |
| </div> |
| <div class="nav-item"> |
| <div class="nav-box"></div> |
| <span>Stats</span> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| |
| const clients = [ |
| { name: "Chanda Mumba", service: "Netflix Premium", expiry: "EXPIRES IN 2 DAYS", color: "#E50914" }, |
| { name: "John Banda", service: "Spotify Duo", expiry: "EXPIRES TOMORROW", color: "#1DB954" }, |
| { name: "Sarah Lungu", service: "Apple Music", expiry: "EXPIRES TODAY", color: "#FC3C44" }, |
| ]; |
| |
| const stack = document.getElementById('cardStack'); |
| let activeIndex = clients.length - 1; |
| |
| function renderCards() { |
| stack.innerHTML = ''; |
| clients.forEach((client, index) => { |
| const card = document.createElement('div'); |
| card.className = `card`; |
| |
| |
| let scale = 1 - (clients.length - 1 - index) * 0.06; |
| let translateY = (clients.length - 1 - index) * 15; |
| let zIndex = index; |
| let opacity = 1 - (clients.length - 1 - index) * 0.3; |
| |
| card.style.zIndex = zIndex; |
| card.style.transform = `scale(${scale}) translateY(-${translateY}px)`; |
| card.style.opacity = opacity; |
| |
| card.innerHTML = ` |
| <div class="service-badge" style="color:${client.color};"> |
| <span class="dot" style="background-color:${client.color}"></span>${client.service} |
| </div> |
| <div class="client-info"> |
| <h2>${client.name}</h2> |
| <p>${client.service} Plan</p> |
| <span class="expiry-warning" style="color:${client.color}">${client.expiry}</span> |
| </div> |
| `; |
| stack.appendChild(card); |
| }); |
| } |
| |
| renderCards(); |
| |
| function swipeRight() { |
| if(activeIndex < 0) return; |
| const cards = document.querySelectorAll('.card'); |
| cards[activeIndex].classList.add('swipe-right'); |
| setTimeout(() => { activeIndex--; }, 200); |
| } |
| |
| function swipeLeft() { |
| if(activeIndex < 0) return; |
| const cards = document.querySelectorAll('.card'); |
| cards[activeIndex].classList.add('swipe-left'); |
| setTimeout(() => { |
| alert(`Opening WhatsApp for ${clients[activeIndex].name}...`); |
| activeIndex--; |
| }, 300); |
| } |
| </script> |
|
|
| </body> |
| </html> |