| | <!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> |