Creating visually appealing borders can significantly enhance the user interface of any web application. In this article, we will explore ten diverse border examples that can elevate your design.
From simple solid lines to intricate patterns, these border styles will provide you with the inspiration and tools needed to make your UI stand out. Let's dive into these creative border examples.
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 it effortless to design pixel-perfect borders and UI elements. Loved by designers and developers alike, Subframe ensures your creations are both stunning and functional.
Start for free and experience the ease of designing with Subframe today!
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 borders and stunning UI elements in minutes. Our drag-and-drop editor ensures efficiency and precision.
Don't wait—start for free and begin designing immediately. Experience the ease and power of Subframe today!
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Financial Dashboard</title> <style> :root { --primary-color: #f8f9fa; --secondary-color: #e9ecef; --accent-color: #4361ee; --text-primary: #212529; --text-secondary: #6c757d; --border-color: #dee2e6; --success-color: #2ecc71; --danger-color: #e74c3c; --warning-color: #f39c12; --card-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); --hover-shadow: 0 6px 12px rgba(0, 0, 0, 0.08); --chart-color-1: #4361ee; --chart-color-2: #3a0ca3; --chart-color-3: #7209b7; --chart-color-4: #f72585; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--primary-color); color: var(--text-primary); height: 100vh; padding: 20px; overflow-x: hidden; } .dashboard-container { max-width: 700px; height: 660px; margin: 0 auto; display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: auto 1fr 1fr; gap: 20px; overflow-y: auto; padding-right: 10px; } .dashboard-container::-webkit-scrollbar { width: 6px; } .dashboard-container::-webkit-scrollbar-track { background: var(--primary-color); } .dashboard-container::-webkit-scrollbar-thumb { background-color: var(--border-color); border-radius: 20px; } header { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; margin-bottom: 5px; } .title h1 { font-size: 1.5rem; font-weight: 600; margin-bottom: 5px; } .date-selector { display: flex; align-items: center; background: var(--secondary-color); padding: 6px 12px; border-radius: 20px; font-size: 0.85rem; cursor: pointer; transition: all 0.2s ease; } .date-selector:hover { background: var(--border-color); } .date-selector i { margin-left: 8px; } .card { background: white; border-radius: 10px; padding: 20px; position: relative; border: 1px solid var(--border-color); box-shadow: var(--card-shadow); transition: all 0.3s ease; cursor: pointer; overflow: hidden; } .card:hover { box-shadow: var(--hover-shadow); border-width: 2px; border-color: var(--accent-color); transform: translateY(-2px); } .card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 15px; } .card-title { font-size: 0.9rem; color: var(--text-secondary); font-weight: 500; } .card-value { font-size: 1.5rem; font-weight: 600; margin: 5px 0; } .card-change { font-size: 0.8rem; display: flex; align-items: center; gap: 5px; } .positive { color: var(--success-color); } .negative { color: var(--danger-color); } .neutral { color: var(--warning-color); } .card-icon { width: 36px; height: 36px; display: flex; align-items: center; justify-content: center; border-radius: 8px; background: var(--secondary-color); } .stats-card { grid-column: span 1; } .charts-card { grid-column: span 2; } .expense-card { grid-column: span 3; } .chart-container { height: 170px; margin-top: 10px; } .chart-legend { display: flex; justify-content: center; gap: 15px; margin-top: 15px; font-size: 0.8rem; } .legend-item { display: flex; align-items: center; gap: 5px; } .legend-color { width: 12px; height: 12px; border-radius: 50%; } .transactions { margin-top: 15px; max-height: 220px; overflow-y: auto; } .transaction { display: flex; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid var(--secondary-color); } .transaction:last-child { border-bottom: none; } .transaction-left { display: flex; gap: 10px; align-items: center; } .transaction-icon { width: 32px; height: 32px; border-radius: 8px; background: var(--secondary-color); display: flex; align-items: center; justify-content: center; } .transaction-details h4 { font-size: 0.9rem; font-weight: 500; } .transaction-details p { font-size: 0.8rem; color: var(--text-secondary); } .transaction-amount { font-weight: 600; font-size: 0.9rem; } .expense { color: var(--danger-color); } .income { color: var(--success-color); } .portfolio-container { display: flex; justify-content: space-between; margin-top: 15px; flex-wrap: wrap; gap: 10px; } .stock-item { width: 48%; display: flex; justify-content: space-between; padding: 8px 10px; background: var(--secondary-color); border-radius: 8px; margin-bottom: 8px; transition: all 0.2s ease; } .stock-item:hover { background: #e2e6ea; transform: translateX(3px); } .stock-name { font-size: 0.85rem; font-weight: 500; } .stock-ticker { font-size: 0.75rem; color: var(--text-secondary); } .stock-price { font-size: 0.85rem; font-weight: 600; } .stock-change { font-size: 0.75rem; } canvas { margin-top: 10px; } @media (max-width: 700px) { .dashboard-container { grid-template-columns: 1fr; height: auto; } .stats-card, .charts-card, .expense-card { grid-column: 1; } header { flex-direction: column; align-items: flex-start; gap: 10px; } .date-selector { align-self: flex-start; } } .pulse-animation { position: absolute; top: 0; right: 0; width: 6px; height: 6px; border-radius: 50%; background-color: var(--success-color); box-shadow: 0 0 0 rgba(46, 204, 113, 0.4); animation: pulse 2s infinite; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0.4); } 70% { box-shadow: 0 0 0 10px rgba(46, 204, 113, 0); } 100% { box-shadow: 0 0 0 0 rgba(46, 204, 113, 0); } } .tooltip { position: absolute; background: rgba(0, 0, 0, 0.8); color: #fff; padding: 5px 10px; border-radius: 5px; font-size: 12px; pointer-events: none; opacity: 0; transition: opacity 0.3s; z-index: 100; } .stock-item:hover .tooltip { opacity: 1; } </style> </head> <body> <div class="dashboard-container"> <header> <div class="title"> <h1>Financial Overview</h1> <p>Welcome back, Jordan. Here's your financial snapshot.</p> </div> <div class="date-selector"> <span>October 2023</span> <i class="fas fa-chevron-down"></i> </div> </header> <div class="card stats-card"> <div class="card-header"> <div> <div class="card-title">Total Balance</div> <div class="card-value">$42,587.29</div> <div class="card-change positive"> <i class="fas fa-arrow-up"></i> <span>3.2% since last month</span> </div> </div> <div class="card-icon"> <i class="fas fa-wallet"></i> </div> </div> <div class="pulse-animation"></div> </div> <div class="card stats-card"> <div class="card-header"> <div> <div class="card-title">Monthly Income</div> <div class="card-value">$12,450.00</div> <div class="card-change positive"> <i class="fas fa-arrow-up"></i> <span>5.7% since last month</span> </div> </div> <div class="card-icon"> <i class="fas fa-chart-line"></i> </div> </div> </div> <div class="card stats-card"> <div class="card-header"> <div> <div class="card-title">Monthly Expenses</div> <div class="card-value">$8,342.65</div> <div class="card-change negative"> <i class="fas fa-arrow-up"></i> <span>2.3% since last month</span> </div> </div> <div class="card-icon"> <i class="fas fa-chart-pie"></i> </div> </div> </div> <div class="card charts-card"> <div class="card-header"> <div> <div class="card-title">Cash Flow Analysis</div> <div class="card-value">$4,107.35</div> <div class="card-change positive"> <i class="fas fa-arrow-up"></i> <span>12.8% growth this quarter</span> </div> </div> </div> <div class="chart-container"> <canvas id="cashFlowChart"></canvas> </div> <div class="chart-legend"> <div class="legend-item"> <div class="legend-color" style="background-color: var(--chart-color-1);"></div> <span>Income</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--chart-color-2);"></div> <span>Expenses</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: var(--chart-color-3);"></div> <span>Net</span> </div> </div> </div> <div class="card charts-card"> <div class="card-header"> <div> <div class="card-title">Investment Portfolio</div> <div class="card-value">$28,725.44</div> <div class="card-change positive"> <i class="fas fa-arrow-up"></i> <span>4.2% return YTD</span> </div> </div> </div> <div class="portfolio-container"> <div class="stock-item"> <div> <div class="stock-name">Apple</div> <div class="stock-ticker">AAPL</div> </div> <div> <div class="stock-price">$178.72</div> <div class="stock-change positive">+1.5%</div> </div> </div> <div class="stock-item"> <div> <div class="stock-name">Tesla</div> <div class="stock-ticker">TSLA</div> </div> <div> <div class="stock-price">$242.35</div> <div class="stock-change positive">+2.8%</div> </div> </div> <div class="stock-item"> <div> <div class="stock-name">Microsoft</div> <div class="stock-ticker">MSFT</div> </div> <div> <div class="stock-price">$329.81</div> <div class="stock-change positive">+0.7%</div> </div> </div> <div class="stock-item"> <div> <div class="stock-name">Amazon</div> <div class="stock-ticker">AMZN</div> </div> <div> <div class="stock-price">$131.69</div> <div class="stock-change negative">-0.3%</div> </div> </div> </div> </div> <div class="card expense-card"> <div class="card-header"> <div> <div class="card-title">Recent Transactions</div> </div> </div> <div class="transactions"> <div class="transaction"> <div class="transaction-left"> <div class="transaction-icon"> <i class="fas fa-shopping-bag"></i> </div> <div class="transaction-details"> <h4>Whole Foods Market</h4> <p>Oct 23, 2023 · Groceries</p> </div> </div> <div class="transaction-amount expense">-$86.42</div> </div> <div class="transaction"> <div class="transaction-left"> <div class="transaction-icon"> <i class="fas fa-home"></i> </div> <div class="transaction-details"> <h4>Mortgage Payment</h4> <p>Oct 20, 2023 · Housing</p> </div> </div> <div class="transaction-amount expense">-$1,450.00</div> </div> <div class="transaction"> <div class="transaction-left"> <div class="transaction-icon"> <i class="fas fa-building"></i> </div> <div class="transaction-details"> <h4>Acme Corp</h4> <p>Oct 15, 2023 · Salary</p> </div> </div> <div class="transaction-amount income">+$6,225.00</div> </div> <div class="transaction"> <div class="transaction-left"> <div class="transaction-icon"> <i class="fas fa-utensils"></i> </div> <div class="transaction-details"> <h4>Urban Plate</h4> <p>Oct 13, 2023 · Dining</p> </div> </div> <div class="transaction-amount expense">-$42.15</div> </div> <div class="transaction"> <div class="transaction-left"> <div class="transaction-icon"> <i class="fas fa-car"></i> </div> <div class="transaction-details"> <h4>City Parking</h4> <p>Oct 11, 2023 · Transportation</p> </div> </div> <div class="transaction-amount expense">-$15.50</div> </div> <div class="transaction"> <div class="transaction-left"> <div class="transaction-icon"> <i class="fas fa-hand-holding-usd"></i> </div> <div class="transaction-details"> <h4>Dividend Payment</h4> <p>Oct 10, 2023 · Investment</p> </div> </div> <div class="transaction-amount income">+$325.78</div> </div> </div> </div> </div> <div class="tooltip" id="tooltip"></div> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script> <script> document.addEventListener('DOMContentLoaded', function() { // Replace Font Awesome with SVG icons since the CDN might not load const iconReplacements = { 'fa-wallet': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16"><path fill="currentColor" d="M461.2 128H80c-8.84 0-16-7.16-16-16s7.16-16 16-16h384c8.84 0 16-7.16 16-16 0-26.51-21.49-48-48-48H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h397.2c28.02 0 50.8-21.53 50.8-48V176c0-26.47-22.78-48-50.8-48zM416 336c-17.67 0-32-14.33-32-32s14.33-32 32-32 32 14.33 32 32-14.33 32-32 32z"></path></svg>', 'fa-chart-line': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16"><path fill="currentColor" d="M496 384H64V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-32c0-8.84-7.16-16-16-16zM464 96H345.94c-21.38 0-32.09 25.85-16.97 40.97l32.4 32.4L288 242.75l-73.37-73.37c-12.5-12.5-32.76-12.5-45.25 0l-68.69 68.69c-6.25 6.25-6.25 16.38 0 22.63l22.62 22.62c6.25 6.25 16.38 6.25 22.63 0L192 237.25l73.37 73.37c12.5 12.5 32.76 12.5 45.25 0l96-96 32.4 32.4c15.12 15.12 40.97 4.41 40.97-16.97V112c.01-8.84-7.15-16-15.99-16z"></path></svg>', 'fa-chart-pie': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 544 512" width="16" height="16"><path fill="currentColor" d="M527.79 288H290.5l158.03 158.03c6.04 6.04 15.98 6.53 22.19.68 38.7-36.46 65.32-85.61 73.13-140.86 1.34-9.46-6.51-17.85-16.06-17.85zm-15.83-64.8C503.72 103.74 408.26 8.28 288.8.04 279.68-.59 272 7.1 272 16.24V240h223.77c9.14 0 16.82-7.68 16.19-16.8zM224 288V50.71c0-9.55-8.39-17.4-17.84-16.06C86.99 51.49-4.1 155.6.14 280.37 4.5 408.51 114.83 513.59 243.03 511.98c50.4-.63 96.97-16.87 135.26-44.03 7.9-5.6 8.42-17.23 1.57-24.08L224 288z"></path></svg>', 'fa-arrow-up': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="12" height="12"><path fill="currentColor" d="M34.9 289.5l-22.2-22.2c-9.4-9.4-9.4-24.6 0-33.9L207 39c9.4-9.4 24.6-9.4 33.9 0l194.3 194.3c9.4 9.4 9.4 24.6 0 33.9L413 289.4c-9.5 9.5-25 9.3-34.3-.4L264 168.6V456c0 13.3-10.7 24-24 24h-32c-13.3 0-24-10.7-24-24V168.6L69.2 289.1c-9.3 9.8-24.8 10-34.3.4z"></path></svg>', 'fa-shopping-bag': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16"><path fill="currentColor" d="M352 160v-32C352 57.42 294.579 0 224 0 153.42 0 96 57.42 96 128v32H0v272c0 44.183 35.817 80 80 80h288c44.183 0 80-35.817 80-80V160h-96zm-192-32c0-35.29 28.71-64 64-64s64 28.71 64 64v32H160v-32zm160 120c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24zm-192 0c-13.255 0-24-10.745-24-24s10.745-24 24-24 24 10.745 24 24-10.745 24-24 24z"></path></svg>', 'fa-home': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" width="16" height="16"><path fill="currentColor" d="M280.37 148.26L96 300.11V464a16 16 0 0 0 16 16l112.06-.29a16 16 0 0 0 15.92-16V368a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v95.64a16 16 0 0 0 16 16.05L464 480a16 16 0 0 0 16-16V300L295.67 148.26a12.19 12.19 0 0 0-15.3 0zM571.6 251.47L488 182.56V44.05a12 12 0 0 0-12-12h-56a12 12 0 0 0-12 12v72.61L318.47 43a48 48 0 0 0-61 0L4.34 251.47a12 12 0 0 0-1.6 16.9l25.5 31A12 12 0 0 0 45.15 301l235.22-193.74a12.19 12.19 0 0 1 15.3 0L530.9 301a12 12 0 0 0 16.9-1.6l25.5-31a12 12 0 0 0-1.7-16.93z"></path></svg>', 'fa-building': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="16" height="16"><path fill="currentColor" d="M436 480h-20V24c0-13.255-10.745-24-24-24H56C42.745 0 32 10.745 32 24v456H12c-6.627 0-12 5.373-12 12v20h448v-20c0-6.627-5.373-12-12-12zM128 76c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12V76zm0 96c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40zm52 148h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40c0 6.627-5.373 12-12 12zm76 160h-64v-84c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v84zm64-172c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40zm0-96c0 6.627-5.373 12-12 12h-40c-6.627 0-12-5.373-12-12v-40c0-6.627 5.373-12 12-12h40c6.627 0 12 5.373 12 12v40z"></path></svg>', 'fa-utensils': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 416 512" width="16" height="16"><path fill="currentColor" d="M207.9 15.2c.8 4.7 16.1 94.5 16.1 128.8 0 52.3-27.8 89.6-68.9 104.6L168 486.7c.7 13.7-10.2 25.3-24 25.3H80c-13.7 0-24.7-11.5-24-25.3l12.9-238.1C27.7 233.6 0 196.2 0 144 0 109.6 15.3 19.9 16.1 15.2 19.3-5.1 61.4-5.4 64 16.3v141.2c1.3 3.4 15.1 3.2 16 0 1.4-25.3 7.9-139.2 8-141.8 3.3-20.8 44.7-20.8 47.9 0 .2 2.7 6.6 116.5 8 141.8.9 3.2 14.8 3.4 16 0V16.3c2.6-21.6 44.8-21.4 48-1.1zm119.2 285.7l-15 185.1c-1.2 14 9.9 26 23.9 26h56c13.3 0 24-10.7 24-24V24c0-13.2-10.7-24-24-24-82.5 0-221.4 178.5-64.9 300.9z"></path></svg>', 'fa-car': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="16" height="16"><path fill="currentColor" d="M499.99 176h-59.87l-16.64-41.6C406.38 91.63 365.57 64 319.5 64h-127c-46.06 0-86.88 27.63-103.99 70.4L71.87 176H12.01C4.2 176-1.53 183.34.37 190.91l6 24C7.7 220.25 12.5 224 18.01 224h20.07C24.65 235.73 16 252.78 16 272v48c0 16.12 6.16 30.67 16 41.93V416c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-32h256v32c0 17.67 14.33 32 32 32h32c17.67 0 32-14.33 32-32v-54.07c9.84-11.25 16-25.8 16-41.93v-48c0-19.22-8.65-36.27-22.07-48H494c5.51 0 10.31-3.75 11.64-9.09l6-24c1.89-7.57-3.84-14.91-11.65-14.91zm-352.06-17.83c7.29-18.22 24.94-30.17 44.57-30.17h127c19.63 0 37.28 11.95 44.57 30.17L384 208H128l19.93-49.83zM96 319.8c-19.2 0-32-12.76-32-31.9S76.8 256 96 256s48 28.71 48 47.85-28.8 15.95-48 15.95zm320 0c-19.2 0-48 3.19-48-15.95S396.8 256 416 256s32 12.76 32 31.9-12.8 31.9-32 31.9z"></path></svg>', 'fa-hand-holding-usd': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512" width="16" height="16"><path fill="currentColor" d="M271.06,144.3l54.27,14.3a8.59,8.59,0,0,1,6.63,8.1c0,4.6-4.09,8.4-9.12,8.4h-35.6a30,30,0,0,1-11.19-2.2c-5.24-2.2-11.28-1.7-15.3,2l-19,17.5a11.68,11.68,0,0,0-2.25,2.66,11.42,11.42,0,0,0,3.88,15.74,83.77,83.77,0,0,0,34.51,11.5V240c0,8.8,7.83,16,17.37,16h17.37c9.55,0,17.38-7.2,17.38-16V222.4c32.93-3.6,57.84-31,53.5-63-3.15-23-22.46-41.3-46.56-47.7L282.68,97.4a8.59,8.59,0,0,1-6.63-8.1c0-4.6,4.09-8.4,9.12-8.4h35.6A30,30,0,0,1,332,83.1c5.23,2.2,11.28,1.7,15.3-2l19-17.5A11.31,11.31,0,0,0,368.47,61a11.43,11.43,0,0,0-3.84-15.78,83.82,83.82,0,0,0-34.52-11.5V16c0-8.8-7.82-16-17.37-16H295.37C285.82,0,278,7.2,278,16V33.6c-32.89,3.6-57.85,31-53.51,63C227.63,119.6,247,137.9,271.06,144.3ZM565.27,328.1c-11.8-10.7-30.2-10-42.6,0L430.27,402a63.64,63.64,0,0,1-40,14H272a16,16,0,0,1,0-32h78.29c15.9,0,30.71-10.9,33.25-26.6a31.2,31.2,0,0,0,.46-5.46A32,32,0,0,0,352,320H192a117.66,117.66,0,0,0-74.1,26.29L71.4,384H16A16,16,0,0,0,0,400v96a16,16,0,0,0,16,16H372.77a64,64,0,0,0,40-14L564,345a32,32,0,0,0,1.28-48.9Z"></path></svg>', 'fa-chevron-down': '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" width="12" height="12"><path fill="currentColor" d="M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z"></path></svg>', }; document.querySelectorAll('[class*="fas fa-"]').forEach(icon => { for(const [className, svg] of Object.entries(iconReplacements)) { if(icon.classList.contains(className)) { icon.innerHTML = svg; icon.classList.remove(`fas`, className); break; } } }); // Cash Flow Chart const cashFlowCtx = document.getElementById('cashFlowChart').getContext('2d'); const cashFlowChart = new Chart(cashFlowCtx, { type: 'line', data: { labels: ['May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct'], datasets: [ { label: 'Income', data: [10500, 11200, 11800, 12000, 11600, 12450], borderColor: getComputedStyle(document.documentElement).getPropertyValue('--chart-color-1'), backgroundColor: 'rgba(67, 97, 238, 0.1)',
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Nexus Mobile Banking</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } :root { --primary: #3e51b5; --primary-light: #6978c9; --secondary: #5ebacd; --dark: #1a2151; --text: #333333; --light-text: #777777; --bg: #f8f9fc; --white: #ffffff; --success: #4caf50; --warning: #ff9800; --box-shadow: 0 10px 20px rgba(62, 81, 181, 0.1); --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } body { background: var(--bg); color: var(--text); display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; padding: 1rem; } .container { max-width: 700px; width: 100%; height: 680px; background: var(--white); border-radius: 24px; box-shadow: var(--box-shadow); overflow: hidden; position: relative; } .header { background: linear-gradient(135deg, var(--primary), var(--dark)); color: var(--white); padding: 20px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid rgba(255, 255, 255, 0.1); } .logo { display: flex; align-items: center; } .logo-icon { width: 32px; height: 32px; background: var(--white); border-radius: 8px; display: flex; align-items: center; justify-content: center; margin-right: 10px; color: var(--primary); font-weight: bold; font-size: 18px; } .logo-text { font-size: 1.2rem; font-weight: 600; } .profile { width: 36px; height: 36px; background: rgba(255, 255, 255, 0.3); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: var(--transition); } .profile:hover { background: rgba(255, 255, 255, 0.5); } .main { padding: 20px; height: calc(100% - 76px); overflow-y: auto; } .welcome { margin-bottom: 20px; } .welcome h2 { font-size: 1.5rem; font-weight: 600; margin-bottom: 5px; } .welcome p { color: var(--light-text); font-size: 0.9rem; } .balance-panel { background: linear-gradient(120deg, var(--primary-light), var(--primary)); background-size: 200% 200%; border-radius: 16px; padding: 20px; color: var(--white); margin-bottom: 20px; position: relative; overflow: hidden; box-shadow: 0 8px 16px rgba(62, 81, 181, 0.2); transition: var(--transition); } .balance-panel::before { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(45deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0)); pointer-events: none; } .balance-panel:hover { transform: translateY(-3px); box-shadow: 0 15px 20px rgba(62, 81, 181, 0.25); background-position: right center; } .balance-label { font-size: 0.9rem; opacity: 0.9; margin-bottom: 5px; font-weight: 500; } .balance-amount { font-size: 2rem; font-weight: 700; margin-bottom: 15px; letter-spacing: 1px; } .balance-actions { display: flex; gap: 10px; margin-top: 10px; } .action-button { background: rgba(255, 255, 255, 0.2); border: none; color: white; padding: 8px 15px; border-radius: 20px; font-size: 0.85rem; cursor: pointer; transition: var(--transition); display: flex; align-items: center; gap: 5px; } .action-button:hover { background: rgba(255, 255, 255, 0.3); } .section-title { font-size: 1.1rem; font-weight: 600; margin: 20px 0 15px; display: flex; align-items: center; justify-content: space-between; } .section-title span { color: var(--primary); font-size: 0.85rem; cursor: pointer; } .section-title span:hover { text-decoration: underline; } .accounts-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; margin-bottom: 20px; } .account-card { background: var(--white); border-radius: 16px; padding: 15px; border: 1px solid rgba(0, 0, 0, 0.08); cursor: pointer; transition: var(--transition); position: relative; overflow: hidden; } .account-card::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(120deg, transparent, rgba(94, 186, 205, 0.05), transparent); transform: translateX(-100%); transition: transform 0.8s; } .account-card:hover::before { transform: translateX(100%); } .account-card.active { border-color: var(--primary); box-shadow: 0 0 0 1px var(--primary), 0 5px 15px rgba(62, 81, 181, 0.1); } .account-card.active::after { content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border-radius: 16px; box-shadow: 0 0 15px rgba(62, 81, 181, 0.3); opacity: 0; animation: pulse 1.5s infinite; } @keyframes pulse { 0% { opacity: 0.3; transform: scale(1); } 70% { opacity: 0; transform: scale(1.05); } 100% { opacity: 0; transform: scale(1.1); } } .account-name { font-size: 0.9rem; font-weight: 600; margin-bottom: 8px; color: var(--text); } .account-balance { font-size: 1.1rem; font-weight: 700; margin-bottom: 5px; } .account-number { font-size: 0.8rem; color: var(--light-text); } .transactions { margin-bottom: 20px; } .transaction-item { display: flex; align-items: center; padding: 12px 0; border-bottom: 1px solid rgba(0, 0, 0, 0.05); transition: var(--transition); } .transaction-item:hover { background-color: rgba(62, 81, 181, 0.03); } .transaction-icon { width: 36px; height: 36px; border-radius: 10px; background: rgba(62, 81, 181, 0.1); display: flex; align-items: center; justify-content: center; margin-right: 12px; color: var(--primary); font-size: 1rem; } .transaction-icon.payment { background: rgba(255, 152, 0, 0.1); color: var(--warning); } .transaction-icon.income { background: rgba(76, 175, 80, 0.1); color: var(--success); } .transaction-details { flex: 1; } .transaction-title { font-size: 0.9rem; font-weight: 600; margin-bottom: 3px; } .transaction-date { font-size: 0.8rem; color: var(--light-text); } .transaction-amount { font-weight: 600; font-size: 0.9rem; } .amount-negative { color: #f44336; } .amount-positive { color: var(--success); } .quick-actions { display: flex; gap: 12px; margin-top: 15px; overflow-x: auto; padding-bottom: 5px; } .quick-action-btn { display: flex; flex-direction: column; align-items: center; min-width: 70px; text-align: center; cursor: pointer; transition: var(--transition); } .quick-action-btn:hover .quick-action-icon { transform: translateY(-3px); background: var(--primary); color: white; } .quick-action-icon { width: 48px; height: 48px; border-radius: 14px; background: rgba(62, 81, 181, 0.1); display: flex; align-items: center; justify-content: center; margin-bottom: 8px; color: var(--primary); font-size: 1.2rem; transition: var(--transition); } .quick-action-label { font-size: 0.8rem; color: var(--text); font-weight: 500; } .bottom-nav { position: absolute; bottom: 0; left: 0; right: 0; background: var(--white); display: flex; justify-content: space-around; padding: 12px 20px; border-top: 1px solid rgba(0, 0, 0, 0.05); box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.03); } .nav-item { display: flex; flex-direction: column; align-items: center; cursor: pointer; transition: var(--transition); position: relative; } .nav-item.active { color: var(--primary); } .nav-item.active::after { content: ""; position: absolute; bottom: -12px; width: 5px; height: 5px; background: var(--primary); border-radius: 50%; } .nav-item:hover { color: var(--primary); } .nav-icon { font-size: 1.2rem; margin-bottom: 5px; } .nav-label { font-size: 0.8rem; font-weight: 500; } /* For floating action button */ .fab { position: absolute; bottom: 80px; right: 20px; width: 56px; height: 56px; border-radius: 28px; background: linear-gradient(135deg, var(--primary), var(--primary-light)); color: white; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; box-shadow: 0 4px 12px rgba(62, 81, 181, 0.3); cursor: pointer; transition: var(--transition); z-index: 10; } .fab:hover { transform: scale(1.05); box-shadow: 0 6px 16px rgba(62, 81, 181, 0.4); } .fab-menu { position: absolute; bottom: 150px; right: 30px; display: flex; flex-direction: column; align-items: flex-end; gap: 15px; opacity: 0; transform: translateY(20px); pointer-events: none; transition: all 0.3s ease; z-index: 9; } .fab-menu.open { opacity: 1; transform: translateY(0); pointer-events: all; } .fab-item { display: flex; align-items: center; gap: 10px; cursor: pointer; } .fab-label { background: var(--dark); color: white; padding: 6px 12px; border-radius: 4px; font-size: 0.8rem; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); } .fab-icon { width: 42px; height: 42px; border-radius: 21px; background: white; color: var(--primary); display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); transition: var(--transition); } .fab-item:hover .fab-icon { transform: scale(1.1); background: var(--primary); color: white; } /* Custom scrollbar */ .main::-webkit-scrollbar { width: 5px; } .main::-webkit-scrollbar-track { background: transparent; } .main::-webkit-scrollbar-thumb { background-color: rgba(0, 0, 0, 0.2); border-radius: 10px; } /* Responsive adjustments */ @media (max-width: 480px) { .accounts-grid { grid-template-columns: 1fr; } .balance-amount { font-size: 1.8rem; } .quick-actions { gap: 8px; } .quick-action-icon { width: 42px; height: 42px; } } /* Loading shimmer effect */ @keyframes shimmer { 0% { background-position: -468px 0; } 100% { background-position: 468px 0; } } .shimmer { background: linear-gradient(to right, #f6f7f8 8%, #edeef1 18%, #f6f7f8 33%); background-size: 800px 104px; animation: shimmer 1.5s infinite linear; } /* Notification indicator */ .notification-dot { position: absolute; top: -2px; right: -2px; width: 8px; height: 8px; background: #ff5252; border-radius: 50%; border: 2px solid var(--white); } /* Tooltip */ .tooltip { position: absolute; background: var(--dark); color: white; padding: 5px 10px; border-radius: 4px; font-size: 0.75rem; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; z-index: 100; } .tooltip::after { content: ""; position: absolute; bottom: -4px; left: 50%; transform: translateX(-50%); width: 0; height: 0; border-left: 5px solid transparent; border-right: 5px solid transparent; border-top: 5px solid var(--dark); } /* Modal styles */ .modal { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); display: flex; align-items: center; justify-content: center; z-index: 1000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .modal.active { opacity: 1; pointer-events: all; } .modal-content { background: white; border-radius: 16px; width: 90%; max-width: 360px; padding: 20px; box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); transform: translateY(20px); transition: transform 0.3s ease; overflow: hidden; } .modal.active .modal-content { transform: translateY(0); } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; } .modal-title { font-size: 1.2rem; font-weight: 600; } .modal-close { background: none; border: none; font-size: 1.5rem; cursor: pointer; color: var(--light-text); } .modal-body { margin-bottom: 20px; } .input-group { margin-bottom: 15px; } .input-label { display: block; margin-bottom: 5px; font-size: 0.85rem; font-weight: 500; color: var(--light-text); } .input-field { width: 100%; padding: 12px; border: 1px solid rgba(0, 0, 0, 0.1); border-radius: 8px; font-size: 0.9rem; transition: var(--transition); } .input-field:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 2px rgba(62, 81, 181, 0.1); } .btn { background: var(--primary); color: white; border: none; border-radius: 8px; padding: 12px; font-size: 0.9rem; font-weight: 500; cursor: pointer; width: 100%; transition: var(--transition); } .btn:hover { background: var(--primary-light); } .btn-secondary { background: transparent; color: var(--primary); border: 1px solid var(--primary); margin-top: 10px; } .btn-secondary:hover { background: rgba(62, 81, 181, 0.05); } .modal-footer { display: flex; gap: 10px; } .modal-footer .btn { flex: 1; } /* Security indicator in transfer modal */ .security-indicator { display: flex; align-items: center; margin-top: 10px; font-size: 0.8rem; color: var(--success); } .security-indicator svg { margin-right: 5px; } </style> </head> <body> <div class="container"> <div class="header"> <div class="logo"> <div class="logo-icon">N</div> <div class="logo-text">Nexus Banking</div> </div> <div class="profile"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path> <circle cx="12" cy="7" r="4"></circle> </svg> </div> </div> <div class="main"> <div class="welcome"> <h2>Good afternoon, Alex</h2> <p>Your financial summary for today, June 16</p> </div> <div class="balance-panel" id="main-balance"> <div class="balance-label">Total Balance</div> <div class="balance-amount">$14,582.63</div> <div class="balance-actions"> <button class="action-button" id="transfer-btn"> <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"> <path d="M17 1l4 4-4 4"></path> <path d="M21 5H9"></path> <path d="M7 23l-4-4 4-4"></path> <path d="M3 19h12"></path> </svg> Transfer </button> <button class="action-button"> <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"> <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect> <line x1="16" y1="2" x2="16" y2="6"></line> <line x1="8" y1="2" x2="8" y2="6"></line> <line x1="3" y1="10" x2="21" y2="10"></line> </svg> Schedule </button> </div> </div> <div class="section-title"> Your Accounts <span>See all</span> </div> <div class="accounts-grid"> <div class="account-card active" data-account="checking"> <div class="account-name">Primary Checking</div> <div class="account-balance">$8,432.21</div> <div class="account-number">•••• 4582</div> </div> <div class="account-card" data-account="savings"> <div class="account-name">High-Yield Savings</div> <div class="account-balance">$5,950.42</div> <div class="account-number">•••• 7731</div> </div> <div class="account-card" data-account="credit"> <div class="account-name">Platinum Credit Card</div> <div class="account-balance">$200.00</div> <div class="account-number">•••• 9218</div> </div> <div class="account-card" data-account="investment"> <div class="account-name">Investment Portfolio</div> <div class="account-balance">$12,385.77</div> <div class="account-number">•••• 3356</div> </div> </div> <div class="section-title"> Recent Transactions <span>View all</span> </div> <div class="transactions"> <div class="transaction-item"> <div class="transaction-icon"> <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="22 12 16 12 14 15 10 15 8 12 2 12"></polyline> <path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path> </svg> </div> <div class="transaction-details"> <div class="transaction-title">Urban Coffee Shop</div> <div class="transaction-date">Today • 10:23 AM</div> </div> <div class="transaction-amount amount-negative">-$4.75</div> </div> <div class="transaction-item"> <div class="transaction-icon payment"> <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"> <rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect> <line x1="1" y1="10" x2="23" y2="10"></line> </svg> </div> <div class="transaction-details"> <div class="transaction-title">Monthly Internet Bill</div> <div class="transaction-date">Yesterday • 6:15 PM</div> </div> <div class="transaction-amount amount-negative">-$69.99</div> </div> <div class="transaction-item"> <div class="transaction-icon income"> <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"> <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path> <polyline points="17 21 17 13 7 13 7 21"></polyline> <polyline points="7 3 7 8 15 8"></polyline> </svg> </div> <div class="transaction-details"> <div class="transaction-title">Salary Deposit</div> <div class="transaction-date">Jun 15 • 9:30 AM</div> </div> <div class="transaction-amount amount-positive">+$3,250.00</div> </div> <div class="transaction-item"> <div class="transaction-icon payment"> <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"> <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path> <circle cx="12" cy="10" r="3"></circle> </svg> </div> <div class="transaction-details"> <div class="transaction-title">Grocery Store</div> <div class="transaction-date">Jun 14 • 1:45 PM</div> </div> <div class="transaction-amount amount-negative">-$78.32</div> </div> </div> <div class="section-title">Quick Actions</div> <div class="quick-actions"> <div class="quick-action-btn" id="pay-bills"> <div class="quick-action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect> <line x1="1" y1="10" x2="23" y2="10"></line> </svg> </div> <div class="quick-action-label">Pay Bills</div> </div> <div class="quick-action-btn" id="mobile-deposit"> <div class="quick-action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect> <circle cx="8.5" cy="8.5" r="1.5"></circle> <polyline points="21 15 16 10 5 21"></polyline> </svg> </div> <div class="quick-action-label">Deposit</div> </div> <div class="quick-action-btn" id="goals"> <div class="quick-action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="10"></circle> <polyline points="12 6 12 12 16 14"></polyline> </svg> </div> <div class="quick-action-label">Goals</div> </div> <div class="quick-action-btn" id="insights"> <div class="quick-action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="18" y1="20" x2="18" y2="10"></line> <line x1="12" y1="20" x2="12" y2="4"></line> <line x1="6" y1="20" x2="6" y2="14"></line> </svg> </div> <div class="quick-action-label">Insights</div> </div> </div> </div> <div class="bottom-nav"> <div class="nav-item active"> <div class="nav-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path> <polyline points="9 22 9 12 15 12 15 22"></polyline> </svg> </div> <div class="nav-label">Home</div> </div> <div class="nav-item"> <div class="nav-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="22 12 16 12 14 15 10 15 8 12 2 12"></polyline> <path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path> </svg> </div> <div class="nav-label">Cards</div> </div> <div class="nav-item"> <div class="nav-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="23 6 13.5 15.5 8.5 10.5 1 18"></polyline> <polyline points="17 6 23 6 23 12"></polyline> </svg> </div> <div class="nav-label">Invest</div> </div> <div class="nav-item"> <div class="nav-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path> </svg> <div class="notification-dot"></div> </div> <div class="nav-label">Support</div> </div> </div> <div class="fab" id="fab-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="12" y1="5" x2="12" y2="19"></line> <line x1="5" y1="12" x2="19" y2="12"></line> </svg> </div> <div class="fab-menu"
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>EduPlayground - Interactive Learning Platform</title> <style> :root { --primary: #6563ff; --secondary: #ff6b6b; --accent1: #4ecdc4; --accent2: #ffbe0b; --light: #f7f7f7; --dark: #2c2c2c; --border-radius: 18px; --card-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); --transition: all 0.3s cubic-bezier(0.25, 0.8, 0.25, 1); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Poppins', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--light); color: var(--dark); display: flex; flex-direction: column; align-items: center; justify-content: flex-start; min-height: 100vh; padding: 20px; overflow-x: hidden; } .container { max-width: 700px; width: 100%; height: 700px; display: flex; flex-direction: column; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--primary) var(--light); } .container::-webkit-scrollbar { width: 8px; } .container::-webkit-scrollbar-thumb { background-color: var(--primary); border-radius: 10px; } .header { text-align: center; margin-bottom: 20px; position: relative; } .header h1 { font-size: 2.2rem; color: var(--dark); margin-bottom: 10px; background: linear-gradient(90deg, var(--primary), var(--secondary)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; position: relative; display: inline-block; } .header p { font-size: 1rem; color: var(--dark); opacity: 0.8; max-width: 500px; margin: 0 auto; } .module-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; margin-bottom: 30px; } .module { background: white; border-radius: var(--border-radius); overflow: hidden; position: relative; cursor: pointer; height: 160px; transition: var(--transition); box-shadow: var(--card-shadow); } .module::before { content: ""; position: absolute; inset: 0; border: 3px solid transparent; border-radius: var(--border-radius); background: linear-gradient(45deg, var(--accent2), var(--accent1)) border-box; -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: var(--transition); } .module:hover { transform: translateY(-5px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15); } .module:hover::before { opacity: 1; } .module .icon { position: absolute; top: 15px; right: 15px; background: var(--light); width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 20px; color: var(--primary); transition: var(--transition); } .module:hover .icon { background: var(--primary); color: white; transform: rotate(360deg); } .module .content { padding: 20px; position: relative; z-index: 1; height: 100%; display: flex; flex-direction: column; justify-content: space-between; } .module h3 { font-size: 1.2rem; margin-bottom: 8px; color: var(--dark); } .module p { font-size: 0.85rem; color: var(--dark); opacity: 0.8; } .module .progress { height: 6px; background: #e0e0e0; border-radius: 3px; margin-top: 10px; overflow: hidden; } .module .progress-bar { height: 100%; border-radius: 3px; transition: var(--transition); } .learning-cards { display: flex; flex-direction: column; gap: 15px; } .card { background: white; border-radius: var(--border-radius); overflow: hidden; position: relative; cursor: pointer; transition: var(--transition); box-shadow: var(--card-shadow); } .card::before { content: ""; position: absolute; inset: 0; border: 3px solid transparent; border-radius: var(--border-radius); background: linear-gradient(45deg, var(--primary), var(--secondary)) border-box; -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: var(--transition); z-index: 1; } .card:hover { transform: translateY(-3px) scale(1.01); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15); } .card:hover::before { opacity: 1; } .card .card-content { padding: 20px; display: flex; align-items: center; gap: 15px; position: relative; z-index: 0; } .card .card-icon { min-width: 50px; height: 50px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 22px; color: white; transition: var(--transition); } .card:hover .card-icon { transform: scale(1.1); } .card .card-text { flex: 1; } .card h3 { font-size: 1.1rem; margin-bottom: 5px; color: var(--dark); } .card p { font-size: 0.85rem; color: var(--dark); opacity: 0.8; } .card .card-action { background: var(--light); width: 36px; height: 36px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 16px; color: var(--primary); transition: var(--transition); } .card:hover .card-action { background: var(--primary); color: white; transform: rotate(90deg); } .section-title { font-size: 1.5rem; margin-bottom: 15px; color: var(--dark); position: relative; display: inline-block; } .section-title::after { content: ""; position: absolute; left: 0; bottom: -5px; width: 40px; height: 4px; background: var(--accent1); border-radius: 2px; } .featured-module { background: white; border-radius: var(--border-radius); overflow: hidden; position: relative; margin-bottom: 30px; box-shadow: var(--card-shadow); transition: var(--transition); } .featured-module::before { content: ""; position: absolute; inset: 0; border: 3px solid transparent; border-radius: var(--border-radius); background: linear-gradient(45deg, var(--primary), var(--secondary)) border-box; -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: var(--transition); z-index: 1; } .featured-module:hover::before { opacity: 1; } .featured-content { padding: 25px; position: relative; z-index: 0; } .featured-tag { display: inline-block; background: var(--accent2); color: var(--dark); padding: 5px 12px; border-radius: 20px; font-size: 0.75rem; font-weight: 600; margin-bottom: 15px; } .featured-module h2 { font-size: 1.4rem; margin-bottom: 12px; color: var(--dark); } .featured-module p { font-size: 0.9rem; color: var(--dark); opacity: 0.8; margin-bottom: 20px; } .btn { display: inline-flex; align-items: center; gap: 8px; background: var(--primary); color: white; padding: 10px 20px; border-radius: 30px; font-size: 0.9rem; font-weight: 500; text-decoration: none; transition: var(--transition); border: none; cursor: pointer; } .btn:hover { background: #5452e3; transform: translateY(-2px); box-shadow: 0 5px 15px rgba(101, 99, 255, 0.3); } .btn .icon { font-size: 18px; } .color-primary { background: var(--primary); } .color-secondary { background: var(--secondary); } .color-accent1 { background: var(--accent1); } .color-accent2 { background: var(--accent2); } .pulse { position: relative; } .pulse::after { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border-radius: inherit; animation: pulse 2s infinite; z-index: -1; } @keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(101, 99, 255, 0.5); } 70% { box-shadow: 0 0 0 10px rgba(101, 99, 255, 0); } 100% { box-shadow: 0 0 0 0 rgba(101, 99, 255, 0); } } @media (max-width: 600px) { .module-grid { grid-template-columns: 1fr 1fr; } .header h1 { font-size: 1.8rem; } .section-title { font-size: 1.3rem; } .featured-module h2 { font-size: 1.2rem; } } @media (max-width: 400px) { .module-grid { grid-template-columns: 1fr; } .card .card-content { flex-direction: column; text-align: center; } .card .card-action { position: absolute; top: 15px; right: 15px; } } @keyframes borderAnimation { 0% { background-position: 0% 50%; } 50% { background-position: 100% 50%; } 100% { background-position: 0% 50%; } } </style> </head> <body> <div class="container"> <div class="header"> <h1>EduPlayground</h1> <p>Discover playful learning experiences designed to engage and inspire curiosity</p> </div> <div class="featured-module"> <div class="featured-content"> <span class="featured-tag">New Course</span> <h2>Hands-on Data Visualization</h2> <p>Transform complex data into compelling visual stories. Learn techniques for creating clear, interactive, and impactful visualizations for diverse audiences.</p> <button class="btn pulse"> <span>Start Learning</span> <span class="icon">→</span> </button> </div> </div> <h2 class="section-title">Continue Learning</h2> <div class="module-grid"> <div class="module" data-progress="72"> <div class="content"> <div> <h3>Coding Fundamentals</h3> <p>Build your programming foundation</p> </div> <div class="progress"> <div class="progress-bar color-primary" style="width: 72%"></div> </div> </div> <div class="icon">★</div> </div> <div class="module" data-progress="45"> <div class="content"> <div> <h3>Design Thinking</h3> <p>Creative problem-solving methods</p> </div> <div class="progress"> <div class="progress-bar color-secondary" style="width: 45%"></div> </div> </div> <div class="icon">✦</div> </div> <div class="module" data-progress="18"> <div class="content"> <div> <h3>AI Essentials</h3> <p>Understanding machine learning</p> </div> <div class="progress"> <div class="progress-bar color-accent1" style="width: 18%"></div> </div> </div> <div class="icon">◆</div> </div> <div class="module" data-progress="90"> <div class="content"> <div> <h3>Digital Storytelling</h3> <p>Craft compelling narratives</p> </div> <div class="progress"> <div class="progress-bar color-accent2" style="width: 90%"></div> </div> </div> <div class="icon">♦</div> </div> </div> <h2 class="section-title">Recommended For You</h2> <div class="learning-cards"> <div class="card"> <div class="card-content"> <div class="card-icon color-primary">🔍</div> <div class="card-text"> <h3>Critical Thinking Workshop</h3> <p>Develop analytical skills to evaluate information with clarity and precision</p> </div> <div class="card-action">+</div> </div> </div> <div class="card"> <div class="card-content"> <div class="card-icon color-secondary">🧪</div> <div class="card-text"> <h3>Science of Learning</h3> <p>Discover research-backed techniques to improve retention and understanding</p> </div> <div class="card-action">+</div> </div> </div> <div class="card"> <div class="card-content"> <div class="card-icon color-accent1">🎨</div> <div class="card-text"> <h3>Visual Communication</h3> <p>Express complex ideas through effective visual elements and design principles</p> </div> <div class="card-action">+</div> </div> </div> <div class="card"> <div class="card-content"> <div class="card-icon color-accent2">🔗</div> <div class="card-text"> <h3>Systems Thinking</h3> <p>Identify connections and relationships between different elements in complex systems</p> </div> <div class="card-action">+</div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Initialize progress bars const modules = document.querySelectorAll('.module'); modules.forEach(module => { const progress = module.getAttribute('data-progress'); const progressBar = module.querySelector('.progress-bar'); // Start with 0 width and animate to actual progress progressBar.style.width = '0%'; setTimeout(() => { progressBar.style.width = `${progress}%`; }, 300); }); // Add click event listeners to all interactive elements const clickableItems = document.querySelectorAll('.module, .card, .btn'); clickableItems.forEach(item => { item.addEventListener('click', function(e) { e.preventDefault(); // Create ripple effect const ripple = document.createElement('div'); ripple.classList.add('ripple'); ripple.style.position = 'absolute'; ripple.style.borderRadius = '50%'; ripple.style.transform = 'scale(0)'; ripple.style.background = 'rgba(255, 255, 255, 0.3)'; ripple.style.pointerEvents = 'none'; ripple.style.width = '100px'; ripple.style.height = '100px'; ripple.style.transition = 'transform 0.6s, opacity 0.6s'; ripple.style.zIndex = '0'; const rect = item.getBoundingClientRect(); const x = e.clientX - rect.left - 50; const y = e.clientY - rect.top - 50; ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; item.appendChild(ripple); setTimeout(() => { ripple.style.transform = 'scale(4)'; ripple.style.opacity = '0'; setTimeout(() => { ripple.remove(); }, 600); }, 10); // Simulate module or card selection const wasSelected = item.classList.contains('selected'); // Toggle selection if clicking on a module or card (not the button) if (!item.classList.contains('btn')) { if (!wasSelected) { // Deselect all others document.querySelectorAll('.selected').forEach(el => { el.classList.remove('selected'); }); item.classList.add('selected'); // Additional feedback for selection const icon = item.querySelector('.icon, .card-icon'); if (icon) { const originalTransform = icon.style.transform; icon.style.transform = originalTransform + ' scale(1.2)'; setTimeout(() => { icon.style.transform = originalTransform; }, 300); } } } }); }); // Hover effects for cards and modules const hoverItems = document.querySelectorAll('.card, .module'); hoverItems.forEach(item => { item.addEventListener('mouseenter', function() { const before = window.getComputedStyle(item, '::before'); if (before) { item.style.setProperty('--hover-animation', 'borderAnimation 3s linear infinite'); } }); item.addEventListener('mouseleave', function() { item.style.setProperty('--hover-animation', 'none'); }); }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --bg-color: #f8f8f8; --text-color: #121212; --accent-1: #ff3e4d; --accent-2: #3e8aff; --accent-3: #ffce00; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--bg-color); color: var(--text-color); min-height: 700px; overflow-x: hidden; display: flex; flex-direction: column; position: relative; } .cursor { width: 20px; height: 20px; border-radius: 50%; background-color: var(--accent-1); position: fixed; pointer-events: none; mix-blend-mode: difference; z-index: 9999; transform: translate(-50%, -50%); transition: transform 0.1s ease-out, width 0.2s ease, height 0.2s ease; } header { padding: 1.5rem; display: flex; justify-content: space-between; align-items: center; position: relative; } .logo { font-weight: 800; font-size: 1.5rem; text-transform: uppercase; letter-spacing: -1px; position: relative; display: inline-block; } .logo::after { content: ''; position: absolute; bottom: -4px; left: 0; width: 100%; height: 3px; background: linear-gradient(90deg, var(--accent-1), var(--accent-2)); transform: scaleX(0); transform-origin: right; transition: transform 0.4s cubic-bezier(0.19, 1, 0.22, 1); } .logo:hover::after { transform: scaleX(1); transform-origin: left; } .nav-toggle { width: 40px; height: 40px; position: relative; cursor: pointer; z-index: 10; display: flex; justify-content: center; align-items: center; } .nav-toggle span { width: 25px; height: 2px; background-color: var(--text-color); position: absolute; transition: all 0.3s ease; } .nav-toggle span:nth-child(1) { transform: translateY(-6px); } .nav-toggle span:nth-child(3) { transform: translateY(6px); } .nav-toggle.active span:nth-child(1) { transform: rotate(45deg); } .nav-toggle.active span:nth-child(2) { opacity: 0; } .nav-toggle.active span:nth-child(3) { transform: rotate(-45deg); } .main-nav { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.95); display: flex; flex-direction: column; justify-content: center; align-items: center; z-index: 5; clip-path: circle(0% at calc(100% - 60px) 60px); transition: clip-path 0.7s cubic-bezier(0.19, 1, 0.22, 1); } .main-nav.active { clip-path: circle(150% at calc(100% - 60px) 60px); } .nav-links { list-style: none; text-align: center; padding: 0; } .nav-links li { margin: 1.5rem 0; position: relative; overflow: hidden; } .nav-item { display: inline-block; font-size: 2.5rem; font-weight: 700; text-decoration: none; color: var(--text-color); text-transform: uppercase; position: relative; padding: 0 1rem; overflow: hidden; transition: color 0.3s ease; } .nav-item::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: var(--text-color); transform: scaleX(0); transform-origin: right; z-index: -1; transition: transform 0.4s cubic-bezier(0.19, 1, 0.22, 1); } .nav-item:hover { color: var(--bg-color); } .nav-item:hover::before { transform: scaleX(1); transform-origin: left; } .border-container { position: relative; margin: 2rem auto; width: 90%; max-width: 650px; overflow: hidden; border-radius: 2px; } .asymmetric-border { position: absolute; pointer-events: none; } .border-top { top: 0; left: 0; width: 100%; height: 8px; background: var(--accent-1); clip-path: polygon(0 0, 80% 0, 70% 100%, 0% 100%); } .border-right { top: 0; right: 0; width: 5px; height: 100%; background: var(--accent-2); clip-path: polygon(0 20%, 100% 0, 100% 100%, 0 90%); } .border-bottom { bottom: 0; left: 20%; width: 80%; height: 3px; background: var(--accent-3); clip-path: polygon(0 0, 100% 0, 90% 100%, 10% 100%); } .border-left { top: 10%; left: 0; width: 10px; height: 80%; background: #000; clip-path: polygon(0 0, 100% 10%, 100% 90%, 0 100%); } .hero-section { position: relative; padding: 1rem; margin-top: 2rem; } .hero-title { font-size: 3.5rem; font-weight: 900; line-height: 1; margin-bottom: 1.5rem; letter-spacing: -2px; max-width: 650px; margin-left: auto; margin-right: auto; position: relative; } .hero-title .highlight { position: relative; display: inline-block; } .highlight.one { color: var(--accent-1); } .highlight.two { color: var(--accent-2); } .highlight.three { color: var(--accent-3); } .hero-description { font-size: 1.1rem; line-height: 1.6; margin-bottom: 2rem; max-width: 550px; margin-left: auto; margin-right: auto; } .services-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1.5rem; margin: 2rem auto; max-width: 650px; padding: 0 1rem; } .service-card { position: relative; padding: 1.5rem; background-color: white; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05); transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; overflow: hidden; } .service-card::before { content: ''; position: absolute; top: -5px; left: 0; width: 100%; height: 5px; background: linear-gradient(90deg, var(--accent-1), var(--accent-2), var(--accent-3)); transition: transform 0.3s ease; } .service-card:hover { transform: translateY(-5px); box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); } .service-card:hover::before { transform: translateY(5px); } .service-title { font-size: 1.3rem; font-weight: 700; margin-bottom: 0.5rem; position: relative; display: inline-block; } .service-description { font-size: 0.9rem; line-height: 1.5; color: #666; } .marquee-container { position: relative; width: 100%; overflow: hidden; margin: 3rem 0; background: #000; padding: 1.5rem 0; } .marquee { display: flex; white-space: nowrap; animation: marquee 30s linear infinite; } .marquee-item { color: white; font-size: 3rem; font-weight: 900; text-transform: uppercase; padding: 0 1rem; } @keyframes marquee { 0% { transform: translateX(0); } 100% { transform: translateX(-50%); } } .cta-section { max-width: 650px; margin: 0 auto 2rem; padding: 0 1rem; } .cta-title { font-size: 2rem; font-weight: 800; margin-bottom: 1rem; position: relative; display: inline-block; } .cta-description { margin-bottom: 1.5rem; line-height: 1.6; } .cta-button { display: inline-block; padding: 0.8rem 2rem; font-weight: 600; text-decoration: none; color: white; background-color: var(--text-color); border: none; position: relative; overflow: hidden; cursor: pointer; transition: color 0.3s ease; z-index: 1; } .cta-button::before { content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: linear-gradient(45deg, var(--accent-1), var(--accent-2)); z-index: -1; transform: scaleX(0); transform-origin: right; transition: transform 0.3s ease; } .cta-button:hover::before { transform: scaleX(1); transform-origin: left; } @media (max-width: 768px) { .hero-title { font-size: 2.5rem; } .services-grid { grid-template-columns: 1fr; } .nav-item { font-size: 2rem; } } @media (max-width: 480px) { .hero-title { font-size: 2rem; } .hero-description { font-size: 1rem; } .nav-item { font-size: 1.8rem; } } </style> </head> <body> <div class="cursor"></div> <header> <div class="logo">Flux</div> <div class="nav-toggle"> <span></span> <span></span> <span></span> </div> </header> <nav class="main-nav"> <ul class="nav-links"> <li><a href="#" class="nav-item">Work</a></li> <li><a href="#" class="nav-item">Services</a></li> <li><a href="#" class="nav-item">About</a></li> <li><a href="#" class="nav-item">Contact</a></li> </ul> </nav> <div class="border-container"> <div class="asymmetric-border border-top"></div> <div class="asymmetric-border border-right"></div> <div class="asymmetric-border border-bottom"></div> <div class="asymmetric-border border-left"></div> <section class="hero-section"> <h1 class="hero-title"> We craft <span class="highlight one">boundaries</span> that <span class="highlight two">break</span> the <span class="highlight three">rules</span> </h1> <p class="hero-description"> At Flux, we push the limits of conventional design. Our asymmetrical borders and dynamic line work create visual stories that captivate and inspire. Where others see edges, we see opportunities. </p> </section> </div> <div class="services-grid"> <div class="service-card"> <h3 class="service-title">Border Design</h3> <p class="service-description">We craft asymmetrical borders with varying thicknesses that make bold visual statements while enhancing your brand's presence.</p> </div> <div class="service-card"> <h3 class="service-title">Contrast Systems</h3> <p class="service-description">Our high-contrast palettes balance striking black and white elements with strategic bursts of vibrant color for maximum impact.</p> </div> <div class="service-card"> <h3 class="service-title">Depth Architecture</h3> <p class="service-description">We engineer layered border systems that create a sense of depth and dimension, bringing artistry to every interface.</p> </div> <div class="service-card"> <h3 class="service-title">Motion Design</h3> <p class="service-description">Our borders don't just exist—they move, breathe, and interact, creating memorable experiences that engage users.</p> </div> </div> <div class="marquee-container"> <div class="marquee"> <div class="marquee-item">Breaking Boundaries</div> <div class="marquee-item">Designing Edges</div> <div class="marquee-item">Crafting Contrast</div> <div class="marquee-item">Bold Statements</div> <div class="marquee-item">Breaking Boundaries</div> <div class="marquee-item">Designing Edges</div> </div> </div> <div class="cta-section"> <h2 class="cta-title">Ready to push boundaries?</h2> <p class="cta-description">Let's collaborate to create striking designs that stand out through innovative border work, layered depth, and dynamic contrast. Our approach transforms ordinary interfaces into extraordinary experiences.</p> <button class="cta-button">Start a Project</button> </div> <script> // Custom cursor const cursor = document.querySelector('.cursor'); document.addEventListener('mousemove', (e) => { cursor.style.left = e.clientX + 'px'; cursor.style.top = e.clientY + 'px'; }); document.addEventListener('mousedown', () => { cursor.style.transform = 'translate(-50%, -50%) scale(0.8)'; }); document.addEventListener('mouseup', () => { cursor.style.transform = 'translate(-50%, -50%) scale(1)'; }); // Elements that make the cursor grow on hover const hoverElements = document.querySelectorAll('.nav-item, .logo, .cta-button, .service-card'); hoverElements.forEach(element => { element.addEventListener('mouseenter', () => { cursor.style.width = '50px'; cursor.style.height = '50px'; cursor.style.mixBlendMode = 'difference'; }); element.addEventListener('mouseleave', () => { cursor.style.width = '20px'; cursor.style.height = '20px'; cursor.style.mixBlendMode = 'difference'; }); }); // Navigation toggle const navToggle = document.querySelector('.nav-toggle'); const mainNav = document.querySelector('.main-nav'); navToggle.addEventListener('click', () => { navToggle.classList.toggle('active'); mainNav.classList.toggle('active'); }); // Service card animation const serviceCards = document.querySelectorAll('.service-card'); serviceCards.forEach(card => { card.addEventListener('mouseenter', () => { const borderBefore = card.querySelector('::before'); if (borderBefore) { borderBefore.style.transform = 'translateY(5px)'; } }); card.addEventListener('mouseleave', () => { const borderBefore = card.querySelector('::before'); if (borderBefore) { borderBefore.style.transform = 'translateY(0)'; } }); }); // Prevent form submission const ctaButton = document.querySelector('.cta-button'); ctaButton.addEventListener('click', (e) => { e.preventDefault(); // Create ripple effect const ripple = document.createElement('span'); ripple.style.position = 'absolute'; ripple.style.borderRadius = '50%'; ripple.style.backgroundColor = 'rgba(255, 255, 255, 0.7)'; ripple.style.width = '10px'; ripple.style.height = '10px'; ripple.style.transform = 'scale(0)'; ripple.style.animation = 'ripple 0.6s linear'; ripple.style.pointerEvents = 'none'; const rect = ctaButton.getBoundingClientRect(); const x = e.clientX - rect.left; const y = e.clientY - rect.top; ripple.style.left = x + 'px'; ripple.style.top = y + 'px'; ctaButton.appendChild(ripple); setTimeout(() => { ripple.remove(); }, 600); }); // Add ripple animation const style = document.createElement('style'); style.textContent = ` @keyframes ripple { to { transform: scale(15); opacity: 0; } } `; document.head.appendChild(style); // Handle mobile cursor if ('ontouchstart' in window) { cursor.style.display = 'none'; } </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Financial Analytics Dashboard</title> <style> :root { --primary: #2a3f54; --secondary: #e74c3c; --accent: #3498db; --text: #2c3e50; --light-bg: #f8f9fa; --border-light: rgba(200, 200, 200, 0.2); --border-active: rgba(52, 152, 219, 0.7); --border-hover: rgba(52, 152, 219, 0.3); --shadow: 0 2px 15px rgba(0, 0, 0, 0.05); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; } body { background-color: var(--light-bg); color: var(--text); font-size: 14px; line-height: 1.5; overflow-x: hidden; max-width: 700px; height: 700px; margin: 0 auto; padding: 1rem; } .dashboard { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: auto auto 1fr; gap: 1rem; height: 100%; } .header { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; padding-bottom: 1rem; } .title h1 { font-size: 1.5rem; font-weight: 700; color: var(--primary); } .subtitle { font-size: 0.85rem; color: #6c757d; margin-top: 0.25rem; } .timeframe { display: flex; gap: 0.5rem; } .timeframe button { background: transparent; border: 1px solid var(--border-light); border-radius: 4px; padding: 0.3rem 0.7rem; font-size: 0.8rem; cursor: pointer; transition: all 0.2s ease; } .timeframe button:hover { border-color: var(--border-hover); } .timeframe button.active { background-color: var(--accent); color: white; border-color: var(--accent); } .card { background: white; border-radius: 8px; box-shadow: var(--shadow); padding: 1rem; border: 1px solid var(--border-light); transition: all 0.3s ease; position: relative; overflow: hidden; display: flex; flex-direction: column; } .card:hover { border-color: var(--border-hover); transform: translateY(-2px); } .card.active { border: 1px solid var(--border-active); } .card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem; } .card-title { font-weight: 600; color: var(--primary); font-size: 0.9rem; } .card-value { font-size: 1.5rem; font-weight: 700; margin: 0.75rem 0; } .trend { font-size: 0.8rem; display: flex; align-items: center; gap: 0.25rem; } .trend.positive { color: #27ae60; } .trend.negative { color: #e74c3c; } .small-card { grid-column: span 1; } .medium-card { grid-column: span 2; } .large-card { grid-column: span 4; } .chart-container { flex: 1; display: flex; align-items: center; justify-content: center; position: relative; min-height: 100px; } /* Specific card placements */ .revenue-card { grid-column: 1 / 2; grid-row: 2 / 3; } .users-card { grid-column: 2 / 3; grid-row: 2 / 3; } .conversion-card { grid-column: 3 / 4; grid-row: 2 / 3; } .growth-card { grid-column: 4 / 5; grid-row: 2 / 3; } .sales-trend-card { grid-column: 1 / 3; grid-row: 3 / 4; } .performance-card { grid-column: 3 / 5; grid-row: 3 / 4; } .tooltip { position: absolute; background: rgba(42, 63, 84, 0.9); color: white; padding: 0.5rem; border-radius: 4px; font-size: 0.8rem; opacity: 0; pointer-events: none; transition: opacity 0.2s ease; z-index: 10; } .legend { display: flex; gap: 1rem; font-size: 0.75rem; margin-top: 0.5rem; } .legend-item { display: flex; align-items: center; gap: 0.25rem; } .legend-color { width: 10px; height: 10px; border-radius: 50%; } @media (max-width: 600px) { .dashboard { grid-template-columns: 1fr 1fr; } .small-card { grid-column: span 1; } .medium-card { grid-column: span 2; } .large-card { grid-column: span 2; } .revenue-card, .users-card { grid-row: 2 / 3; } .conversion-card, .growth-card { grid-row: 3 / 4; } .sales-trend-card { grid-column: 1 / 3; grid-row: 4 / 5; } .performance-card { grid-column: 1 / 3; grid-row: 5 / 6; } } /* Graph animations */ @keyframes growLine { 0% { opacity: 0; transform: scaleX(0); transform-origin: left; } 100% { opacity: 1; transform: scaleX(1); transform-origin: left; } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } /* Toggle switch styles */ .toggle-container { display: flex; align-items: center; gap: 0.5rem; } .toggle { position: relative; display: inline-block; width: 32px; height: 16px; } .toggle input { opacity: 0; width: 0; height: 0; } .slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; transition: .3s; border-radius: 16px; } .slider:before { position: absolute; content: ""; height: 12px; width: 12px; left: 2px; bottom: 2px; background-color: white; transition: .3s; border-radius: 50%; } input:checked + .slider { background-color: var(--accent); } input:checked + .slider:before { transform: translateX(16px); } .toggle-label { font-size: 0.75rem; } /* Loader animation for when data is refreshing */ .loader { width: 100%; height: 3px; background: linear-gradient(90deg, var(--accent), transparent); position: absolute; top: 0; left: 0; animation: loaderAnim 1.5s infinite; opacity: 0; transition: opacity 0.3s ease; } .data-refreshing .loader { opacity: 1; } @keyframes loaderAnim { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } </style> </head> <body> <div class="dashboard"> <div class="header"> <div class="title"> <h1>Financial Performance</h1> <p class="subtitle">Interactive visualization with subtle borders</p> </div> <div class="timeframe"> <button class="time-btn" data-time="day">Day</button> <button class="time-btn" data-time="week">Week</button> <button class="time-btn active" data-time="month">Month</button> <button class="time-btn" data-time="year">Year</button> </div> </div> <div class="card small-card revenue-card" data-type="revenue"> <div class="loader"></div> <div class="card-header"> <span class="card-title">Revenue</span> <div class="toggle-container"> <span class="toggle-label">Auto</span> <label class="toggle"> <input type="checkbox" checked> <span class="slider"></span> </label> </div> </div> <div class="card-value">$24,580</div> <div class="trend positive"> <span>↑</span> 8.2% vs last period </div> <div class="chart-container revenue-chart"></div> </div> <div class="card small-card users-card" data-type="users"> <div class="loader"></div> <div class="card-header"> <span class="card-title">Active Users</span> </div> <div class="card-value">2,843</div> <div class="trend positive"> <span>↑</span> 4.6% vs last period </div> <div class="chart-container users-chart"></div> </div> <div class="card small-card conversion-card" data-type="conversion"> <div class="loader"></div> <div class="card-header"> <span class="card-title">Conversion</span> </div> <div class="card-value">3.2%</div> <div class="trend negative"> <span>↓</span> 1.1% vs last period </div> <div class="chart-container conversion-chart"></div> </div> <div class="card small-card growth-card" data-type="growth"> <div class="loader"></div> <div class="card-header"> <span class="card-title">Growth Rate</span> </div> <div class="card-value">12.5%</div> <div class="trend positive"> <span>↑</span> 2.3% vs last period </div> <div class="chart-container growth-chart"></div> </div> <div class="card medium-card sales-trend-card" data-type="sales-trend"> <div class="loader"></div> <div class="card-header"> <span class="card-title">Sales Trend</span> </div> <div class="chart-container sales-trend-chart"></div> <div class="legend"> <div class="legend-item"> <div class="legend-color" style="background-color: #3498db;"></div> <span>Current</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: rgba(52, 152, 219, 0.3);"></div> <span>Previous</span> </div> </div> </div> <div class="card medium-card performance-card" data-type="performance"> <div class="loader"></div> <div class="card-header"> <span class="card-title">Performance by Market</span> </div> <div class="chart-container performance-chart"></div> <div class="legend"> <div class="legend-item"> <div class="legend-color" style="background-color: #3498db;"></div> <span>North America</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: #e74c3c;"></div> <span>Europe</span> </div> <div class="legend-item"> <div class="legend-color" style="background-color: #2ecc71;"></div> <span>Asia</span> </div> </div> </div> </div> <div id="tooltip" class="tooltip"></div> <script> // Utility functions function generateRandomData(length, min, max, trend = 0) { const data = []; let value = Math.floor(Math.random() * (max - min)) + min; for (let i = 0; i < length; i++) { value = value + (Math.random() - 0.5 + trend) * 10; value = Math.max(min, Math.min(max, value)); data.push(Math.floor(value)); } return data; } function drawSparklinesChart(container, data, color) { const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("width", "100%"); svg.setAttribute("height", "40"); svg.setAttribute("viewBox", `0 0 ${data.length - 1} 100`); svg.style.overflow = "visible"; const line = document.createElementNS("http://www.w3.org/2000/svg", "path"); const max = Math.max(...data); const min = Math.min(...data); const range = max - min || 1; let path = `M 0 ${100 - ((data[0] - min) / range * 100)}`; for (let i = 1; i < data.length; i++) { const x = i; const y = 100 - ((data[i] - min) / range * 100); path += ` L ${x} ${y}`; } line.setAttribute("d", path); line.setAttribute("fill", "none"); line.setAttribute("stroke", color); line.setAttribute("stroke-width", "2"); line.style.animation = "growLine 1s ease-out forwards"; svg.appendChild(line); // Add dots for the last point const lastPoint = document.createElementNS("http://www.w3.org/2000/svg", "circle"); const lastX = data.length - 1; const lastY = 100 - ((data[data.length - 1] - min) / range * 100); lastPoint.setAttribute("cx", lastX); lastPoint.setAttribute("cy", lastY); lastPoint.setAttribute("r", "3"); lastPoint.setAttribute("fill", color); lastPoint.style.animation = "fadeIn 1s ease-out forwards"; svg.appendChild(lastPoint); container.innerHTML = ''; container.appendChild(svg); } function drawLineChart(container, datasets, labels) { const width = container.clientWidth; const height = container.clientHeight; // Create SVG const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("width", "100%"); svg.setAttribute("height", "100%"); svg.setAttribute("viewBox", `0 0 ${width} ${height}`); // Find min and max values across all datasets let allValues = []; datasets.forEach(dataset => { allValues = allValues.concat(dataset.data); }); const max = Math.max(...allValues); const min = Math.min(...allValues) > 0 ? 0 : Math.min(...allValues); const range = max - min || 1; // Padding const paddingLeft = 25; const paddingRight = 15; const paddingTop = 15; const paddingBottom = 25; const chartWidth = width - paddingLeft - paddingRight; const chartHeight = height - paddingTop - paddingBottom; // Draw axes const xAxis = document.createElementNS("http://www.w3.org/2000/svg", "line"); xAxis.setAttribute("x1", paddingLeft); xAxis.setAttribute("y1", height - paddingBottom); xAxis.setAttribute("x2", width - paddingRight); xAxis.setAttribute("y2", height - paddingBottom); xAxis.setAttribute("stroke", "#ccc"); xAxis.setAttribute("stroke-width", "1"); const yAxis = document.createElementNS("http://www.w3.org/2000/svg", "line"); yAxis.setAttribute("x1", paddingLeft); yAxis.setAttribute("y1", paddingTop); yAxis.setAttribute("x2", paddingLeft); yAxis.setAttribute("y2", height - paddingBottom); yAxis.setAttribute("stroke", "#ccc"); yAxis.setAttribute("stroke-width", "1"); svg.appendChild(xAxis); svg.appendChild(yAxis); // Draw grid lines const gridLinesCount = 5; for (let i = 0; i < gridLinesCount; i++) { const y = paddingTop + (chartHeight / gridLinesCount * i); const gridLine = document.createElementNS("http://www.w3.org/2000/svg", "line"); gridLine.setAttribute("x1", paddingLeft); gridLine.setAttribute("y1", y); gridLine.setAttribute("x2", width - paddingRight); gridLine.setAttribute("y2", y); gridLine.setAttribute("stroke", "#eee"); gridLine.setAttribute("stroke-width", "1"); svg.appendChild(gridLine); // Y-axis labels const label = document.createElementNS("http://www.w3.org/2000/svg", "text"); label.setAttribute("x", paddingLeft - 5); label.setAttribute("y", y + 4); label.setAttribute("text-anchor", "end"); label.setAttribute("font-size", "8"); label.setAttribute("fill", "#999"); const value = max - (max - min) / gridLinesCount * i; label.textContent = Math.round(value); svg.appendChild(label); } // X-axis labels const xLabelsCount = Math.min(labels.length, 7); // Limit number of labels to avoid crowding for (let i = 0; i < xLabelsCount; i++) { const index = Math.floor(i * (labels.length - 1) / (xLabelsCount - 1)); const x = paddingLeft + (chartWidth / (xLabelsCount - 1) * i); const label = document.createElementNS("http://www.w3.org/2000/svg", "text"); label.setAttribute("x", x); label.setAttribute("y", height - paddingBottom + 15); label.setAttribute("text-anchor", "middle"); label.setAttribute("font-size", "8"); label.setAttribute("fill", "#999"); label.textContent = labels[index]; svg.appendChild(label); } // Draw datasets datasets.forEach((dataset, datasetIndex) => { // Line const path = document.createElementNS("http://www.w3.org/2000/svg", "path"); let d = ''; dataset.data.forEach((value, index) => { const x = paddingLeft + (chartWidth / (dataset.data.length - 1)) * index; const y = paddingTop + chartHeight - ((value - min) / range * chartHeight); if (index === 0) { d += `M ${x} ${y}`; } else { d += ` L ${x} ${y}`; } }); path.setAttribute("d", d); path.setAttribute("fill", "none"); path.setAttribute("stroke", dataset.color); path.setAttribute("stroke-width", "2"); path.style.animation = "growLine 1.5s ease-out forwards"; // Area under the line for the first dataset if (datasetIndex === 0 && dataset.fill) { const area = document.createElementNS("http://www.w3.org/2000/svg", "path"); let areaD = d + ` L ${paddingLeft + chartWidth} ${height - paddingBottom}` + ` L ${paddingLeft} ${height - paddingBottom} Z`; area.setAttribute("d", areaD); area.setAttribute("fill", dataset.fillColor || `${dataset.color}33`); // Add transparency area.setAttribute("stroke", "none"); area.style.animation = "fadeIn 1.5s ease-out forwards"; svg.appendChild(area); } svg.appendChild(path); // Points dataset.data.forEach((value, index) => { const x = paddingLeft + (chartWidth / (dataset.data.length - 1)) * index; const y = paddingTop + chartHeight - ((value - min) / range * chartHeight); const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); circle.setAttribute("cx", x); circle.setAttribute("cy", y); circle.setAttribute("r", "3"); circle.setAttribute("fill", dataset.color); circle.style.animation = "fadeIn 2s ease-out forwards"; // Add an invisible larger circle for better hover detection const hoverCircle = document.createElementNS("http://www.w3.org/2000/svg", "circle"); hoverCircle.setAttribute("cx", x); hoverCircle.setAttribute("cy", y); hoverCircle.setAttribute("r", "8"); hoverCircle.setAttribute("fill", "transparent"); hoverCircle.setAttribute("data-value", value); hoverCircle.setAttribute("data-label", labels[index]); hoverCircle.setAttribute("data-set", dataset.label); // Add hover event for tooltip hoverCircle.addEventListener("mouseenter", function(e) { const tooltip = document.getElementById("tooltip"); const value = this.getAttribute("data-value"); const label = this.getAttribute("data-label"); const setName = this.getAttribute("data-set"); tooltip.innerHTML = `${setName}: ${value}<br>${label}`; tooltip.style.opacity = "1"; tooltip.style.left = `${x}px`; tooltip.style.top = `${y - 30}px`; }); hoverCircle.addEventListener("mouseleave", function() { document.getElementById("tooltip").style.opacity = "0"; }); svg.appendChild(circle); svg.appendChild(hoverCircle); }); }); container.innerHTML = ''; container.appendChild(svg); } function drawBarChart(container, datasets, labels) { const width = container.clientWidth; const height = container.clientHeight; // Create SVG const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); svg.setAttribute("width", "100%"); svg.setAttribute("height", "100%"); svg.setAttribute("viewBox", `0 0 ${width} ${height}`); // Find max value let max = 0; datasets.forEach(dataset => { max = Math.max(max, ...dataset.data); }); // Padding const paddingLeft = 25; const paddingRight = 10; const paddingTop = 15; const paddingBottom = 25; const chartWidth = width - paddingLeft - paddingRight; const chartHeight = height - paddingTop - paddingBottom; // Draw axes const xAxis = document.createElementNS("http://www.w3.org/2000/svg", "line"); xAxis.setAttribute("x1", paddingLeft); xAxis.setAttribute("y1", height - paddingBottom); xAxis.setAttribute("x2", width - paddingRight); xAxis.setAttribute("y2", height - paddingBottom); xAxis.setAttribute("stroke", "#ccc"); xAxis.setAttribute("stroke-width", "1"); const yAxis = document.createElementNS("http://www.w3.org/2000/svg", "line"); yAxis.setAttribute("x1", paddingLeft); yAxis.setAttribute("y1", paddingTop); yAxis.setAttribute("x2", paddingLeft); yAxis.setAttribute("y2", height - paddingBottom); yAxis.setAttribute("stroke", "#ccc"); yAxis.setAttribute("stroke-width", "1"); svg.appendChild(xAxis); svg.appendChild(yAxis); // Draw grid lines const gridLinesCount = 5; for (let i = 0; i < gridLinesCount; i++) { const y = paddingTop + (chartHeight / gridLinesCount * i); const gridLine = document.createElementNS("http://www.w3.org/2000/svg", "line"); gridLine.setAttribute("x1", paddingLeft); gridLine.setAttribute("y1", y); gridLine.setAttribute("x2", width - paddingRight); gridLine.setAttribute("y2", y); gridLine.setAttribute("stroke", "#eee"); gridLine.setAttribute("stroke-width", "1"); svg.appendChild(gridLine); // Y-axis labels const label = document.createElementNS("http://www.w3.org/2000/svg", "text"); label.setAttribute("x", paddingLeft - 5); label.setAttribute("y", y + 4); label.setAttribute("text-anchor", "end"); label.setAttribute("font-size", "8"); label.setAttribute("fill", "#999"); const value = max - (max / gridLinesCount * i); label.textContent = Math.round(value); svg.appendChild(label); } // Calculate bar width and spacing const groupCount = labels.length; const barCount = datasets.length; const groupWidth = chartWidth / groupCount; const barWidth = groupWidth * 0.8 / barCount; // 80% of group width for bars const groupPadding = groupWidth * 0.1; // 10% padding on each side of the group // Draw datasets (bars) datasets.forEach((dataset, datasetIndex) => { dataset.data.forEach((value, index) => { const x = paddingLeft + (groupWidth * index) + groupPadding + (barWidth * datasetIndex); const barHeight = (value / max) * chartHeight; const y = height - paddingBottom - barHeight; const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"); rect.setAttribute("x", x); rect.setAttribute("y", height - paddingBottom); rect.setAttribute("width", barWidth); rect.setAttribute("height", 0); rect.setAttribute("fill", dataset.color); rect.setAttribute("data-value", value); rect.setAttribute("data-label", labels[index]); rect.setAttribute("data-set", dataset.label); // Animate bars setTimeout(() => { rect.style.transition = "y 0.5s ease-out, height 0.5s ease-out"; rect.setAttribute("y", y); rect.setAttribute("height", barHeight); }, 100 * index); // Add hover effect rect.addEventListener("mouseenter", function() { this.setAttribute("fill", dataset.hoverColor || lightenColor(dataset.color, 20)); const tooltip = document.getElementById("tooltip"); const value = this.getAttribute("data-value"); const label = this.getAttribute("data-label"); const setName = this.getAttribute("data-set"); tooltip.innerHTML = `${setName}: ${value}<br>${label}`; tooltip.style.opacity = "1"; tooltip.style.left = `${x + barWidth/2}px`; tooltip.style.top = `${y - 30}px`; }); rect.addEventListener("mouseleave", function() { this.setAttribute("fill", dataset.color); document.getElementById("tooltip").style.opacity = "0"; }); svg.appendChild(rect); }); }); // X-axis labels labels.forEach((label, index) => { const x = paddingLeft + (groupWidth * index) + groupWidth / 2; const textLabel = document.createElementNS("http://www.w3.org/2000/svg", "text"); textLabel.setAttribute("x", x); textLabel.setAttribute("y", height - paddingBottom + 15); textLabel.setAttribute("text-anchor", "middle"); textLabel.setAttribute("font-size", "8"); textLabel.setAttribute("fill", "#999"); textLabel.textContent = label; svg.appendChild(textLabel); }); container.innerHTML = ''; container.appendChild(svg); } function lightenColor(color, percent) { let r = parseInt(color.substring(1, 3), 16); let g = parseInt(color.substring(3, 5), 16); let b = parseInt(color.substring(5, 7), 16); r = Math.min(255, r + Math.floor(percent / 100 * (255 - r))); g = Math.min(255, g + Math.floor(percent / 100 * (255 - g))); b = Math.min(255, b + Math.floor(percent / 100 * (255 - b))); return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`; } // Generate initial chart data and draw charts function initializeCharts() { // Sparklines for KPI cards const revenueData = generateRandomData(20, 100, 200, 0.1); drawSparklinesChart( document.querySelector('.revenue-chart'), revenueData, '#3498db' ); const usersData = generateRandomData(20, 50, 150, 0.05); drawSparklinesChart( document.querySelector('.users-chart'), usersData, '#3498db' ); const conversionData = generateRandomData(20, 30, 100, -0.02); drawSparklinesChart( document.querySelector('.conversion-chart'), conversionData, '#e74c3c' ); const growthData = generateRandomData(20, 80, 120, 0.03); drawSparklinesChart( document.querySelector('.growth-chart'), growthData, '#3498db' ); // Line chart for sales trend const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; const currentMonthData = generateRandomData(12, 800, 1500, 0.1); const previousMonthData = generateRandomData(12, 700, 1300, 0.05); drawLineChart( document.querySelector('.sales-trend-chart'), [ { label: 'Current Period', data: currentMonthData, color: '#3498db', fill: true, fillColor: 'rgba(52, 152, 219, 0.1)' }, { label: 'Previous Period', data: previousMonthData, color: 'rgba(52, 152, 219, 0.3)' } ], months ); // Bar chart for performance by market const regions = ['NA', 'EU', 'APAC', 'LATAM', 'MEA']; drawBarChart( document.querySelector('.performance-chart'), [ { label: 'Revenue', data: generateRandomData(5, 500, 1200), color: '#3498db', hoverColor: '#2980b9' }, { label: 'Profit', data: generateRandomData(5, 200, 500), color: '#2ecc71', hoverColor: '#27ae60' }, { label: 'Expenses', data: generateRandomData(5, 300, 700), color: '#e74c3c', hoverColor: '#c0392b' } ], regions ); } // Card interaction function setupCardInteraction() { const cards = document.querySelectorAll('.card'); cards.forEach(card => { card.addEventListener('click', function() { cards.forEach(c => c.classList.remove('active')); this.classList.add('active'); }); }); // Time period buttons const timeButtons = document.querySelectorAll('.time-btn'); timeButtons.forEach(btn => { btn.addEventListener('click', function() { timeButtons.forEach(b => b.classList.remove('active')); this.classList.add('active'); refreshData(this.getAttribute('data-time')); }); }); // Toggle switches const toggles = document.querySelectorAll('.toggle input'); toggles.forEach(toggle => { toggle.addEventListener('change', function() { const card = this.closest('.card'); if (this.checked) { // Auto-refresh data periodically card.dataset.autoRefresh = setInterval(() => { refreshCardData(card); }, 5000); } else { // Stop auto-refresh clearInterval(card.dataset.autoRefresh); } }); }); } // Refresh data when time period changes function refreshData(timePeriod) { document.querySelectorAll('.card').forEach(card => { card.classList.add('data-refreshing'); setTimeout(() => { refreshCardData(card, timePeriod); card.classList.remove('data-refreshing'); }, 500); }); } // Refresh individual card data function refreshCardData(card, timePeriod) { const type = card.getAttribute('data-type'); switch(type) { case 'revenue': const revenueData = generateRandomData(20, 100, 200, 0.1); drawSparklinesChart( card.querySelector('.revenue-chart'), revenueData, '#3498db' ); // Update KPI value based on time period const revenueValue = card.querySelector('.card-value'); if (timePeriod === 'day') revenueValue.textContent = '$843'; else if (timePeriod === 'week') revenueValue.textContent = '$5,926'; else if (timePeriod === 'year') revenueValue.textContent = '$295,138'; else revenueValue.textContent = '$24,580'; break; case 'users': const usersData = generateRandomData(20,
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Wanderlust Journal - Travel Bookings</title> <style> :root { --color-sand: #E8D4B9; --color-terra: #C07F6C; --color-moss: #8A9A5B; --color-sky: #93C4D1; --color-night: #3B4252; --color-paper: #FAF7F2; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: var(--color-paper); color: var(--color-night); padding: 20px; max-width: 700px; margin: 0 auto; height: 100vh; overflow-x: hidden; } header { text-align: center; margin-bottom: 20px; position: relative; } h1 { font-size: 2.2rem; font-weight: 700; margin-bottom: 10px; color: var(--color-terra); position: relative; display: inline-block; } h1::after { content: ""; position: absolute; bottom: -5px; left: 0; width: 100%; height: 3px; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 10" width="100" height="10"><path d="M0 5 Q 25 15, 50 5 Q 75 -5, 100 5" fill="none" stroke="%23C07F6C" stroke-width="2" /></svg>'); background-repeat: repeat-x; background-size: 100px 10px; } .subtitle { font-size: 1rem; color: var(--color-moss); font-style: italic; margin-bottom: 15px; } .search-bar { display: flex; justify-content: space-between; margin-bottom: 25px; background: white; border-radius: 15px; padding: 12px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); position: relative; overflow: hidden; } .search-bar::before { content: ""; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100"><rect x="0" y="0" width="100" height="100" fill="none" stroke="%23E8D4B9" stroke-width="4" stroke-dasharray="5,5" /></svg>'); background-size: 30px 30px; opacity: 0.3; pointer-events: none; } .search-bar input, .search-bar select { border: none; padding: 8px; border-radius: 8px; flex-grow: 1; background-color: var(--color-paper); margin-right: 10px; } .search-bar button { background-color: var(--color-terra); color: white; border: none; padding: 10px 20px; border-radius: 8px; cursor: pointer; transition: all 0.3s ease; font-weight: bold; } .search-bar button:hover { background-color: #A46857; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); } .itinerary-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 20px; margin-top: 20px; } .itinerary-card { background: white; border-radius: 15px; padding: 20px; cursor: pointer; transition: all 0.4s ease; position: relative; } .itinerary-card::before { content: ""; position: absolute; top: -5px; left: -5px; right: -5px; bottom: -5px; border-radius: 18px; background: transparent; border: 3px solid transparent; transition: all 0.4s ease; z-index: -1; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" width="400" height="400"><path d="M10,10 C50,8 90,15 130,10 C170,5 210,0 250,5 C290,10 330,15 390,10 L390,90 C330,95 290,85 250,90 C210,95 170,100 130,95 C90,90 50,85 10,90 L10,10 Z" fill="none" stroke="%23C07F6C" stroke-width="3" /></svg>'); background-size: cover; background-repeat: no-repeat; opacity: 0.8; } .itinerary-card:hover::before { top: -8px; left: -8px; right: -8px; bottom: -8px; opacity: 1; background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" width="400" height="400"><path d="M10,10 C50,5 90,20 130,10 C170,0 210,-5 250,5 C290,15 330,20 390,10 L390,90 C330,100 290,80 250,90 C210,100 170,110 130,95 C90,80 50,75 10,90 L10,10 Z" fill="none" stroke="%238A9A5B" stroke-width="4" stroke-dasharray="3,3" /></svg>'); } .itinerary-card:hover { transform: translateY(-5px); box-shadow: 0 12px 20px rgba(0, 0, 0, 0.1); } .card-selected { background-color: rgba(147, 196, 209, 0.1); } .card-selected::before { background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" width="400" height="400"><path d="M10,10 C50,5 90,20 130,10 C170,0 210,-5 250,5 C290,15 330,20 390,10 L390,90 C330,100 290,80 250,90 C210,100 170,110 130,95 C90,80 50,75 10,90 L10,10 Z" fill="none" stroke="%2393C4D1" stroke-width="4" /></svg>'); opacity: 1; } .destination { font-size: 1.4rem; font-weight: bold; color: var(--color-terra); margin-bottom: 8px; display: flex; align-items: center; } .destination svg { margin-right: 8px; } .dates { font-size: 0.9rem; color: var(--color-night); margin-bottom: 12px; display: flex; align-items: center; } .dates svg { margin-right: 8px; } .price { font-size: 1.2rem; font-weight: bold; color: var(--color-moss); margin-top: 15px; } .accommodation, .activities { font-size: 0.9rem; margin: 10px 0; color: var(--color-night); } .divider { height: 2px; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 2" width="100" height="2"><path d="M0 1 Q 10 0, 20 1 Q 30 2, 40 1 Q 50 0, 60 1 Q 70 2, 80 1 Q 90 0, 100 1" fill="none" stroke="%23E8D4B9" stroke-width="1.5" /></svg>'); background-repeat: repeat-x; background-size: 100px 2px; margin: 12px 0; } .bookmark { position: absolute; top: 15px; right: 15px; cursor: pointer; transition: transform 0.3s ease; } .bookmark:hover { transform: scale(1.2); } .bookmark svg { fill: none; stroke: var(--color-terra); stroke-width: 2; transition: all 0.3s ease; } .bookmark.saved svg { fill: var(--color-terra); } .toggle-view { display: flex; justify-content: center; margin-bottom: 15px; } .toggle-view button { background-color: transparent; border: 2px solid var(--color-terra); color: var(--color-terra); padding: 8px 15px; margin: 0 5px; border-radius: 20px; cursor: pointer; transition: all 0.3s ease; } .toggle-view button.active { background-color: var(--color-terra); color: white; } .flight-details { display: flex; align-items: center; justify-content: space-between; margin-top: 12px; } .flight-time { font-size: 0.8rem; color: var(--color-night); display: flex; flex-direction: column; align-items: center; } .flight-line { flex-grow: 1; height: 2px; background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 2" width="100" height="2"><path d="M0 1 L 100 1" stroke="%238A9A5B" stroke-width="1" stroke-dasharray="2,2" /></svg>'); background-repeat: repeat-x; margin: 0 10px; position: relative; } .flight-line::after { content: "✈️"; position: absolute; top: -10px; left: 50%; transform: translateX(-50%); font-size: 0.9rem; } .pagination { display: flex; justify-content: center; margin-top: 30px; } .pagination button { background: none; border: none; font-size: 0.9rem; color: var(--color-terra); cursor: pointer; padding: 5px 10px; margin: 0 5px; border-radius: 50%; transition: all 0.3s ease; } .pagination button.active { background-color: var(--color-terra); color: white; } .pagination button:hover:not(.active) { background-color: var(--color-sand); } .loading-animation { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(255, 255, 255, 0.8); display: none; justify-content: center; align-items: center; z-index: 1000; } .loading-spinner { width: 50px; height: 50px; border: 5px solid var(--color-sand); border-top-color: var(--color-terra); border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; } .tag { background-color: var(--color-sand); color: var(--color-night); font-size: 0.7rem; padding: 4px 8px; border-radius: 12px; display: inline-block; } @media (max-width: 700px) { .search-bar { flex-direction: column; gap: 10px; } .search-bar input, .search-bar select { margin-right: 0; width: 100%; } .itinerary-cards { grid-template-columns: 1fr; } h1 { font-size: 1.8rem; } .toggle-view button { padding: 6px 12px; font-size: 0.9rem; } } /* Whimsical patterns */ .pattern-element { position: absolute; opacity: 0.1; pointer-events: none; z-index: -1; } .pattern-1 { top: 50px; right: 20px; transform: rotate(20deg); } .pattern-2 { bottom: 80px; left: 30px; transform: rotate(-15deg); } </style> </head> <body> <div class="loading-animation"> <div class="loading-spinner"></div> </div> <div class="pattern-element pattern-1"> <svg width="120" height="120" viewBox="0 0 120 120"> <path d="M20,20 C40,10 80,30 100,20 M20,40 C40,30 80,50 100,40 M20,60 C40,50 80,70 100,60 M20,80 C40,70 80,90 100,80" stroke="#8A9A5B" stroke-width="2" fill="none" /> </svg> </div> <div class="pattern-element pattern-2"> <svg width="100" height="100" viewBox="0 0 100 100"> <circle cx="50" cy="50" r="30" stroke="#C07F6C" stroke-width="2" fill="none" stroke-dasharray="5,5" /> <circle cx="50" cy="50" r="20" stroke="#93C4D1" stroke-width="2" fill="none" /> </svg> </div> <header> <h1>Wanderlust Journal</h1> <div class="subtitle">Curated journeys from dreamers to explorers</div> </header> <div class="toggle-view"> <button class="active" data-view="flights">Flights & Packages</button> <button data-view="stays">Stays</button> </div> <div class="search-bar"> <input type="text" placeholder="Where to? (e.g., Kyoto, Santorini, Machu Picchu)"> <input type="date" placeholder="Departure date"> <input type="date" placeholder="Return date"> <select> <option>2 Travelers</option> <option>1 Traveler</option> <option>3 Travelers</option> <option>4+ Travelers</option> </select> <button id="search-btn">Find Adventure</button> </div> <div class="itinerary-cards"> <div class="itinerary-card"> <div class="bookmark" data-saved="false"> <svg width="20" height="25" viewBox="0 0 20 25"> <path d="M2,2 L18,2 L18,23 L10,17 L2,23 Z" /> </svg> </div> <div class="destination"> <svg width="16" height="16" viewBox="0 0 24 24"> <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" fill="#C07F6C"/> </svg> Kyoto, Japan </div> <div class="dates"> <svg width="14" height="14" viewBox="0 0 24 24"> <path d="M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z" fill="#3B4252"/> </svg> Apr 12 - Apr 20, 2023 </div> <div class="flight-details"> <div class="flight-time">NRT 13:40</div> <div class="flight-line"></div> <div class="flight-time">KIX 15:30</div> </div> <div class="accommodation"> Ryokan Ginkaku - Traditional room with garden view </div> <div class="divider"></div> <div class="activities"> Cherry blossom viewing, Tea ceremony, Fushimi Inari hike </div> <div class="tags"> <span class="tag">Cultural</span> <span class="tag">Spring</span> <span class="tag">Historical</span> </div> <div class="price">$1,890 per person</div> </div> <div class="itinerary-card"> <div class="bookmark" data-saved="false"> <svg width="20" height="25" viewBox="0 0 20 25"> <path d="M2,2 L18,2 L18,23 L10,17 L2,23 Z" /> </svg> </div> <div class="destination"> <svg width="16" height="16" viewBox="0 0 24 24"> <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" fill="#C07F6C"/> </svg> Santorini, Greece </div> <div class="dates"> <svg width="14" height="14" viewBox="0 0 24 24"> <path d="M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z" fill="#3B4252"/> </svg> Jun 5 - Jun 12, 2023 </div> <div class="flight-details"> <div class="flight-time">ATH 09:20</div> <div class="flight-line"></div> <div class="flight-time">JTR 10:10</div> </div> <div class="accommodation"> Oia Sunset Villas - Cave suite with caldera view </div> <div class="divider"></div> <div class="activities"> Sailing tour, Wine tasting, Red beach exploration </div> <div class="tags"> <span class="tag">Beach</span> <span class="tag">Romantic</span> <span class="tag">Food & Wine</span> </div> <div class="price">$2,150 per person</div> </div> <div class="itinerary-card"> <div class="bookmark" data-saved="true"> <svg width="20" height="25" viewBox="0 0 20 25"> <path d="M2,2 L18,2 L18,23 L10,17 L2,23 Z" /> </svg> </div> <div class="destination"> <svg width="16" height="16" viewBox="0 0 24 24"> <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" fill="#C07F6C"/> </svg> Tulum, Mexico </div> <div class="dates"> <svg width="14" height="14" viewBox="0 0 24 24"> <path d="M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z" fill="#3B4252"/> </svg> Nov 15 - Nov 22, 2023 </div> <div class="flight-details"> <div class="flight-time">CUN 11:15</div> <div class="flight-line"></div> <div class="flight-time">TUY 12:30</div> </div> <div class="accommodation"> Jungle Eco Lodge - Beachfront cabana with private terrace </div> <div class="divider"></div> <div class="activities"> Cenote diving, Mayan ruins, Beachside yoga retreats </div> <div class="tags"> <span class="tag">Eco-Friendly</span> <span class="tag">Adventure</span> <span class="tag">Wellness</span> </div> <div class="price">$1,640 per person</div> </div> <div class="itinerary-card"> <div class="bookmark" data-saved="false"> <svg width="20" height="25" viewBox="0 0 20 25"> <path d="M2,2 L18,2 L18,23 L10,17 L2,23 Z" /> </svg> </div> <div class="destination"> <svg width="16" height="16" viewBox="0 0 24 24"> <path d="M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5c-1.38 0-2.5-1.12-2.5-2.5s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5-1.12 2.5-2.5 2.5z" fill="#C07F6C"/> </svg> Marrakech, Morocco </div> <div class="dates"> <svg width="14" height="14" viewBox="0 0 24 24"> <path d="M9 11H7v2h2v-2zm4 0h-2v2h2v-2zm4 0h-2v2h2v-2zm2-7h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99.9-1.99 2L3 20c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 16H5V9h14v11z" fill="#3B4252"/> </svg> Mar 8 - Mar 16, 2023 </div> <div class="flight-details"> <div class="flight-time">RAK 15:00</div> <div class="flight-line"></div> <div class="flight-time">CMN 16:20</div> </div> <div class="accommodation"> Riad Al Makan - Deluxe suite with traditional Moroccan decor </div> <div class="divider"></div> <div class="activities"> Medina exploration, Atlas Mountains trek, Hammam spa experience </div> <div class="tags"> <span class="tag">Cultural</span> <span class="tag">Desert</span> <span class="tag">Artisanal</span> </div> <div class="price">$1,775 per person</div> </div> </div> <div class="pagination"> <button>1</button> <button class="active">2</button> <button>3</button> <button>→</button> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Toggle bookmark const bookmarks = document.querySelectorAll('.bookmark'); bookmarks.forEach(bookmark => { bookmark.addEventListener('click', function() { const saved = this.getAttribute('data-saved') === 'true'; this.setAttribute('data-saved', !saved); if (!saved) { this.classList.add('saved'); } else { this.classList.remove('saved'); } }); }); // Card selection const cards = document.querySelectorAll('.itinerary-card'); cards.forEach(card => { card.addEventListener('click', function(e) { if (!e.target.closest('.bookmark')) { cards.forEach(c => c.classList.remove('card-selected')); this.classList.add('card-selected'); } }); }); // Toggle view buttons const viewButtons = document.querySelectorAll('.toggle-view button'); viewButtons.forEach(button => { button.addEventListener('click', function() { viewButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); }); }); // Simulate loading const searchBtn = document.getElementById('search-btn'); const loadingAnimation = document.querySelector('.loading-animation'); searchBtn.addEventListener('click', function() { loadingAnimation.style.display = 'flex'; setTimeout(() => { loadingAnimation.style.display = 'none'; // Simulate new content cards.forEach(card => { card.style.opacity = '0'; setTimeout(() => { card.style.opacity = '1'; }, 300); }); }, 1500); }); // Pagination const paginationButtons = document.querySelectorAll('.pagination button'); paginationButtons.forEach(button => { button.addEventListener('click', function() { paginationButtons.forEach(btn => btn.classList.remove('active')); if (this.textContent !== '→') { this.classList.add('active'); } // Simulate page change loadingAnimation.style.display = 'flex'; setTimeout(() => { loadingAnimation.style.display = 'none'; // Simulate new content cards.forEach(card => { card.style.opacity = '0'; setTimeout(() => { card.style.opacity = '1'; }, 300); }); }, 800); }); }); // Prevent actual form submission document.querySelector('.search-bar').addEventListener('submit', function(e) { e.preventDefault(); return false; }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Wavelength Social</title> <style> :root { --primary: #a6d8e2; --secondary: #f9c7c7; --tertiary: #c5e1a5; --dark-text: #3a3a3a; --light-text: #6c6c6c; --bg-color: #f8f9fa; --border-radius: 12px; --shadow: 0 4px 15px rgba(0, 0, 0, 0.05); --font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; } * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: var(--font-family); background-color: var(--bg-color); color: var(--dark-text); width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; overflow-x: hidden; } .container { width: 100%; max-width: 700px; height: 100%; max-height: 700px; padding: 20px; display: flex; flex-direction: column; overflow-y: auto; position: relative; } header { text-align: center; margin-bottom: 20px; position: sticky; top: 0; background-color: var(--bg-color); padding: 10px 0; z-index: 10; } .logo { font-size: 24px; font-weight: bold; color: var(--dark-text); margin-bottom: 10px; position: relative; display: inline-block; } .logo:after { content: ''; position: absolute; width: 60%; height: 3px; background: linear-gradient(90deg, var(--primary), var(--secondary), var(--tertiary)); bottom: -5px; left: 20%; border-radius: 3px; } .profile-section { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 16px; margin-bottom: 25px; } .profile-card { flex: 1; min-width: 200px; background-color: white; border-radius: var(--border-radius); box-shadow: var(--shadow); overflow: hidden; position: relative; transition: transform 0.3s ease, box-shadow 0.3s ease; cursor: pointer; } .profile-card:hover { transform: translateY(-5px); box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); } .profile-card.selected { transform: scale(1.02); } .profile-card.selected::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border: 2px solid transparent; border-radius: var(--border-radius); background: linear-gradient(135deg, var(--primary), var(--secondary), var(--tertiary)) border-box; -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask-composite: destination-out; mask-composite: exclude; animation: border-pulse 2s infinite; z-index: 1; } @keyframes border-pulse { 0% { opacity: 0.6; } 50% { opacity: 1; } 100% { opacity: 0.6; } } .profile-image { width: 60px; height: 60px; border-radius: 50%; margin-right: 15px; object-fit: cover; border: 2px solid white; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } .profile-header { display: flex; align-items: center; padding: 15px; background: linear-gradient(45deg, rgba(166, 216, 226, 0.1), rgba(249, 199, 199, 0.1)); } .profile-info { flex: 1; } .profile-name { font-weight: 600; margin-bottom: 2px; } .profile-title { font-size: 0.85rem; color: var(--light-text); } .profile-stats { display: flex; justify-content: space-around; padding: 12px 0; border-top: 1px solid #f3f3f3; background-color: white; } .stat { text-align: center; } .stat-value { font-weight: 600; font-size: 14px; } .stat-label { font-size: 12px; color: var(--light-text); } .content-feed { margin-top: 10px; } .content-card { background-color: white; border-radius: var(--border-radius); box-shadow: var(--shadow); margin-bottom: 16px; overflow: hidden; transition: transform 0.3s ease, box-shadow 0.3s ease; position: relative; cursor: pointer; } .content-card:hover { transform: translateY(-3px); box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08); } .content-card.selected { transform: scale(1.01); } .content-card.selected::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border: 2px solid transparent; border-radius: var(--border-radius); background: linear-gradient(135deg, var(--tertiary), var(--primary), var(--secondary)) border-box; -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask-composite: destination-out; mask-composite: exclude; animation: border-pulse 2s infinite; z-index: 1; } .card-header { display: flex; align-items: center; padding: 15px; border-bottom: 1px solid #f3f3f3; } .card-content { padding: 15px; } .card-content p { margin-bottom: 15px; line-height: 1.5; color: var(--dark-text); } .card-image { width: 100%; height: auto; border-radius: 8px; margin-bottom: 10px; } .card-actions { display: flex; justify-content: space-between; padding: 10px 15px; border-top: 1px solid #f3f3f3; } .action-btn { background: none; border: none; color: var(--light-text); font-size: 14px; cursor: pointer; display: flex; align-items: center; padding: 5px 10px; border-radius: 20px; transition: background-color 0.2s, color 0.2s; } .action-btn:hover { background-color: rgba(166, 216, 226, 0.2); color: var(--dark-text); } .action-btn i { margin-right: 5px; font-size: 16px; } .post-form { background-color: white; border-radius: var(--border-radius); box-shadow: var(--shadow); padding: 15px; margin-bottom: 20px; position: relative; } .post-form::before { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; border: 1px solid transparent; border-radius: var(--border-radius); background: linear-gradient(135deg, var(--primary), var(--secondary)) border-box; -webkit-mask: linear-gradient(#fff 0 0) padding-box, linear-gradient(#fff 0 0); -webkit-mask-composite: destination-out; mask-composite: exclude; pointer-events: none; } .post-input { width: 100%; padding: 12px; border: 1px solid #f1f1f1; border-radius: 8px; margin-bottom: 15px; resize: none; font-family: var(--font-family); } .post-input:focus { outline: none; border-color: var(--primary); } .post-actions { display: flex; justify-content: space-between; align-items: center; } .post-btn { background: linear-gradient(to right, var(--primary), var(--secondary)); color: white; border: none; padding: 8px 20px; border-radius: 20px; font-weight: 600; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 2px 8px rgba(166, 216, 226, 0.4); } .post-btn:hover { box-shadow: 0 4px 12px rgba(166, 216, 226, 0.6); transform: translateY(-2px); } .post-btn:active { transform: translateY(0); box-shadow: 0 2px 4px rgba(166, 216, 226, 0.4); } .tabs { display: flex; justify-content: center; margin-bottom: 15px; background: white; border-radius: 30px; padding: 5px; box-shadow: var(--shadow); } .tab { padding: 8px 20px; border-radius: 20px; cursor: pointer; transition: all 0.3s ease; font-weight: 500; font-size: 14px; color: var(--light-text); } .tab.active { background: linear-gradient(to right, var(--primary), var(--secondary)); color: white; box-shadow: 0 2px 8px rgba(166, 216, 226, 0.4); } /* Animations */ @keyframes slideIn { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } } .profile-card, .content-card { animation: slideIn 0.5s forwards; } .profile-card:nth-child(1) { animation-delay: 0.1s; } .profile-card:nth-child(2) { animation-delay: 0.2s; } .profile-card:nth-child(3) { animation-delay: 0.3s; } .content-card:nth-child(1) { animation-delay: 0.3s; } .content-card:nth-child(2) { animation-delay: 0.4s; } .content-card:nth-child(3) { animation-delay: 0.5s; } /* Responsive Adjustments */ @media (max-width: 600px) { .container { padding: 15px; } .profile-section { flex-direction: column; } .profile-card { min-width: 100%; } .logo { font-size: 20px; } .tabs { width: 100%; } .tab { padding: 6px 12px; font-size: 12px; } } /* Custom Scrollbar */ .container::-webkit-scrollbar { width: 8px; } .container::-webkit-scrollbar-track { background: #f1f1f1; border-radius: 10px; } .container::-webkit-scrollbar-thumb { background: linear-gradient(var(--primary), var(--secondary)); border-radius: 10px; } .container::-webkit-scrollbar-thumb:hover { background: linear-gradient(var(--secondary), var(--primary)); } /* Icons */ .material-icons { font-family: 'Material Icons'; font-weight: normal; font-style: normal; font-size: 24px; line-height: 1; letter-spacing: normal; text-transform: none; display: inline-block; white-space: nowrap; word-wrap: normal; direction: ltr; -webkit-font-feature-settings: 'liga'; -webkit-font-smoothing: antialiased; } </style> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> </head> <body> <div class="container"> <header> <div class="logo">wavelength</div> <div class="tabs"> <div class="tab active" data-tab="feed">Feed</div> <div class="tab" data-tab="discover">Discover</div> <div class="tab" data-tab="bookmarks">Bookmarks</div> </div> </header> <div class="post-form"> <textarea class="post-input" placeholder="Share what's on your mind..."></textarea> <div class="post-actions"> <div> <button class="action-btn"> <i class="material-icons">image</i> </button> <button class="action-btn"> <i class="material-icons">tag</i> </button> </div> <button class="post-btn">Share</button> </div> </div> <div class="profile-section"> <div class="profile-card" data-id="1"> <div class="profile-header"> <img src="https://randomuser.me/api/portraits/women/43.jpg" alt="Profile image" class="profile-image"> <div class="profile-info"> <div class="profile-name">Emma Chen</div> <div class="profile-title">UX Designer</div> </div> </div> <div class="profile-stats"> <div class="stat"> <div class="stat-value">142</div> <div class="stat-label">Posts</div> </div> <div class="stat"> <div class="stat-value">2.5k</div> <div class="stat-label">Followers</div> </div> <div class="stat"> <div class="stat-value">357</div> <div class="stat-label">Following</div> </div> </div> </div> <div class="profile-card" data-id="2"> <div class="profile-header"> <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="Profile image" class="profile-image"> <div class="profile-info"> <div class="profile-name">Alex Rivera</div> <div class="profile-title">Frontend Developer</div> </div> </div> <div class="profile-stats"> <div class="stat"> <div class="stat-value">97</div> <div class="stat-label">Posts</div> </div> <div class="stat"> <div class="stat-value">1.8k</div> <div class="stat-label">Followers</div> </div> <div class="stat"> <div class="stat-value">243</div> <div class="stat-label">Following</div> </div> </div> </div> <div class="profile-card" data-id="3"> <div class="profile-header"> <img src="https://randomuser.me/api/portraits/women/65.jpg" alt="Profile image" class="profile-image"> <div class="profile-info"> <div class="profile-name">Sophia Kim</div> <div class="profile-title">Content Strategist</div> </div> </div> <div class="profile-stats"> <div class="stat"> <div class="stat-value">214</div> <div class="stat-label">Posts</div> </div> <div class="stat"> <div class="stat-value">3.7k</div> <div class="stat-label">Followers</div> </div> <div class="stat"> <div class="stat-value">512</div> <div class="stat-label">Following</div> </div> </div> </div> </div> <div class="content-feed"> <div class="content-card" data-id="1"> <div class="card-header"> <img src="https://randomuser.me/api/portraits/women/43.jpg" alt="Profile image" class="profile-image"> <div class="profile-info"> <div class="profile-name">Emma Chen</div> <div class="profile-title">Just now</div> </div> </div> <div class="card-content"> <p>Just launched a new design system with geometric borders and pastel colors. Perfect balance between playful and professional. Would love your feedback! #DesignSystem #UX</p> <img src="https://images.unsplash.com/photo-1558655146-d09347e92766?ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=80" alt="Design system" class="card-image"> </div> <div class="card-actions"> <button class="action-btn"> <i class="material-icons">favorite_border</i> 127 </button> <button class="action-btn"> <i class="material-icons">chat_bubble_outline</i> 43 </button> <button class="action-btn"> <i class="material-icons">share</i> 12 </button> </div> </div> <div class="content-card" data-id="2"> <div class="card-header"> <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="Profile image" class="profile-image"> <div class="profile-info"> <div class="profile-name">Alex Rivera</div> <div class="profile-title">2 hours ago</div> </div> </div> <div class="card-content"> <p>Just implemented those curved card borders using clip-path and border-radius blend. The subtle mix of straight and curved elements creates a modern look while keeping the UI clean. CSS snippet in comments!</p> </div> <div class="card-actions"> <button class="action-btn"> <i class="material-icons">favorite_border</i> 89 </button> <button class="action-btn"> <i class="material-icons">chat_bubble_outline</i> 32 </button> <button class="action-btn"> <i class="material-icons">share</i> 7 </button> </div> </div> <div class="content-card" data-id="3"> <div class="card-header"> <img src="https://randomuser.me/api/portraits/women/65.jpg" alt="Profile image" class="profile-image"> <div class="profile-info"> <div class="profile-name">Sophia Kim</div> <div class="profile-title">Yesterday</div> </div> </div> <div class="card-content"> <p>Our new content strategy emphasizes visual hierarchy with these gorgeous pastel backgrounds. The light and airy feel has increased engagement by 27% during early testing. Geometric borders provide just enough structure without overwhelming the content.</p> <img src="https://images.unsplash.com/photo-1617791160505-6f00504e3519?ixlib=rb-1.2.1&auto=format&fit=crop&w=700&q=80" alt="Visual hierarchy" class="card-image"> </div> <div class="card-actions"> <button class="action-btn"> <i class="material-icons">favorite_border</i> 204 </button> <button class="action-btn"> <i class="material-icons">chat_bubble_outline</i> 57 </button> <button class="action-btn"> <i class="material-icons">share</i> 29 </button> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded', function() { // Profile card selection const profileCards = document.querySelectorAll('.profile-card'); profileCards.forEach(card => { card.addEventListener('click', function() { // Toggle selected class on this card this.classList.toggle('selected'); // Deselect other cards profileCards.forEach(otherCard => { if (otherCard !== this) { otherCard.classList.remove('selected'); } }); }); }); // Content card selection const contentCards = document.querySelectorAll('.content-card'); contentCards.forEach(card => { card.addEventListener('click', function(e) { // Don't select if clicking action buttons if (e.target.closest('.action-btn')) { return; } // Toggle selected class on this card this.classList.toggle('selected'); // Deselect other cards contentCards.forEach(otherCard => { if (otherCard !== this) { otherCard.classList.remove('selected'); } }); }); }); // Like button functionality const likeButtons = document.querySelectorAll('.action-btn:first-child'); likeButtons.forEach(button => { button.addEventListener('click', function() { const icon = this.querySelector('i'); if (icon.textContent === 'favorite_border') { icon.textContent = 'favorite'; icon.style.color = '#f9c7c7'; const count = this.textContent.trim().split(' ')[1]; this.textContent = ''; this.appendChild(icon); this.append(` ${parseInt(count) + 1}`); } else { icon.textContent = 'favorite_border'; icon.style.color = ''; const count = this.textContent.trim().split(' ')[1]; this.textContent = ''; this.appendChild(icon); this.append(` ${parseInt(count) - 1}`); } }); }); // Tab switching const tabs = document.querySelectorAll('.tab'); tabs.forEach(tab => { tab.addEventListener('click', function() { tabs.forEach(t => t.classList.remove('active')); this.classList.add('active'); }); }); // Post form functionality const postBtn = document.querySelector('.post-btn'); const postInput = document.querySelector('.post-input'); postBtn.addEventListener('click', function() { if (postInput.value.trim() !== '') { // Create new content card const newCard = document.createElement('div'); newCard.className = 'content-card'; newCard.dataset.id = Math.floor(Math.random() * 1000); // Get random profile image const profileImages = document.querySelectorAll('.profile-image'); const randomProfile = profileImages[Math.floor(Math.random() * profileImages.length)].src; newCard.innerHTML = ` <div class="card-header"> <img src="${randomProfile}" alt="Profile image" class="profile-image"> <div class="profile-info"> <div class="profile-name">You</div> <div class="profile-title">Just now</div> </div> </div> <div class="card-content"> <p>${postInput.value}</p> </div> <div class="card-actions"> <button class="action-btn"> <i class="material-icons">favorite_border</i> 0 </button> <button class="action-btn"> <i class="material-icons">chat_bubble_outline</i> 0 </button> <button class="action-btn"> <i class="material-icons">share</i> 0 </button> </div> `; // Add new card to feed const contentFeed = document.querySelector('.content-feed'); contentFeed.insertBefore(newCard, contentFeed.firstChild); // Clear input postInput.value = ''; // Add event listeners to new card newCard.addEventListener('click', function(e) { if (!e.target.closest('.action-btn')) { this.classList.toggle('selected'); contentCards.forEach(otherCard => { if (otherCard !== this) { otherCard.classList.remove('selected'); } }); } }); // Add like functionality const newLikeBtn = newCard.querySelector('.action-btn:first-child'); newLikeBtn.addEventListener('click', function() { const icon = this.querySelector('i'); if (icon.textContent === 'favorite_border') { icon.textContent = 'favorite'; icon.style.color = '#f9c7c7'; const count = this.textContent.trim().split(' ')[1]; this.textContent = ''; this.appendChild(icon); this.append(` ${parseInt(count) + 1}`); } else { icon.textContent = 'favorite_border'; icon.style.color = ''; const count = this.textContent.trim().split(' ')[1]; this.textContent = ''; this.appendChild(icon); this.append(` ${parseInt(count) - 1}`); } }); } }); }); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>IoT Dashboard Control Center</title> <style> :root { --bg-dark: #0a0e17; --bg-panel: #111827; --border-color: #1f2937; --text-primary: #e5e7eb; --text-secondary: #9ca3af; --accent-blue: #0ea5e9; --accent-green: #10b981; --accent-purple: #8b5cf6; --accent-red: #ef4444; --transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); --glow-shadow: 0 0 15px rgba(14, 165, 233, 0.5); } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', 'Segoe UI', system-ui, sans-serif; } body { background-color: var(--bg-dark); color: var(--text-primary); width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; } .dashboard { width: 700px; height: 700px; display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: auto 1fr 1fr 1fr; gap: 12px; padding: 16px; background-color: var(--bg-dark); position: relative; } .panel { background-color: var(--bg-panel); border: 1px solid var(--border-color); border-radius: 8px; padding: 15px; transition: var(--transition); position: relative; overflow: hidden; } .panel:hover { box-shadow: var(--glow-shadow); border-color: var(--accent-blue); } .panel-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; } .panel-title { font-size: 14px; font-weight: 600; color: var(--text-primary); display: flex; align-items: center; gap: 6px; } .header { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; padding: 0 5px; } .logo { display: flex; align-items: center; gap: 10px; } .logo-icon { width: 32px; height: 32px; border: 2px solid var(--accent-blue); border-radius: 8px; display: flex; justify-content: center; align-items: center; } .logo-text { font-size: 20px; font-weight: 700; background: linear-gradient(135deg, var(--accent-blue), var(--accent-purple)); -webkit-background-clip: text; background-clip: text; color: transparent; } .header-controls { display: flex; gap: 12px; } .header-btn { background: transparent; border: 1px solid var(--border-color); color: var(--text-primary); padding: 8px 12px; border-radius: 6px; cursor: pointer; display: flex; align-items: center; gap: 6px; transition: var(--transition); } .header-btn:hover { border-color: var(--accent-blue); box-shadow: var(--glow-shadow); } .header-btn i { font-size: 14px; } .system-status { grid-column: span 2; display: flex; flex-direction: column; justify-content: space-between; } .system-metrics { display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px; margin-top: 10px; } .metric { flex: 1; min-width: 100px; background: rgba(31, 41, 55, 0.5); border-radius: 6px; padding: 10px; display: flex; flex-direction: column; gap: 5px; } .metric-title { font-size: 12px; color: var(--text-secondary); } .metric-value { font-size: 18px; font-weight: 600; } .metric-unit { font-size: 11px; color: var(--text-secondary); } .metric-trend { display: flex; align-items: center; gap: 4px; font-size: 11px; } .trend-up { color: var(--accent-green); } .trend-down { color: var(--accent-red); } .quick-actions { grid-column: span 2; display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; } .action-btn { background: rgba(31, 41, 55, 0.5); border: 1px solid var(--border-color); border-radius: 6px; padding: 12px; display: flex; flex-direction: column; gap: 5px; cursor: pointer; transition: var(--transition); } .action-btn:hover { border-color: var(--accent-blue); box-shadow: var(--glow-shadow); } .action-icon { width: 36px; height: 36px; border-radius: 50%; background: rgba(14, 165, 233, 0.1); color: var(--accent-blue); display: flex; justify-content: center; align-items: center; margin-bottom: 5px; } .action-title { font-size: 13px; font-weight: 600; } .action-desc { font-size: 11px; color: var(--text-secondary); } .chart-container { position: relative; width: 100%; height: 140px; } canvas { position: absolute; bottom: 0; left: 0; } .device-list { grid-column: span 2; grid-row: span 2; overflow-y: auto; } .device { display: flex; justify-content: space-between; align-items: center; padding: 10px; border-bottom: 1px solid var(--border-color); cursor: pointer; transition: var(--transition); } .device:hover { background: rgba(14, 165, 233, 0.05); } .device-info { display: flex; align-items: center; gap: 10px; } .device-icon { width: 32px; height: 32px; border-radius: 6px; background: rgba(14, 165, 233, 0.1); color: var(--accent-blue); display: flex; justify-content: center; align-items: center; } .device-details { display: flex; flex-direction: column; gap: 2px; } .device-name { font-size: 14px; font-weight: 500; } .device-status { font-size: 11px; color: var(--text-secondary); display: flex; align-items: center; gap: 4px; } .status-indicator { width: 8px; height: 8px; border-radius: 50%; } .status-online { background-color: var(--accent-green); } .status-offline { background-color: var(--accent-red); } .status-warning { background-color: #f59e0b; } .device-actions { display: flex; gap: 8px; } .device-btn { background: transparent; border: 1px solid var(--border-color); color: var(--text-secondary); width: 28px; height: 28px; border-radius: 6px; display: flex; justify-content: center; align-items: center; cursor: pointer; transition: var(--transition); } .device-btn:hover { border-color: var(--accent-blue); color: var(--accent-blue); box-shadow: var(--glow-shadow); } .temperature-control { grid-column: span 2; display: flex; flex-direction: column; } .temp-display { display: flex; align-items: center; justify-content: center; height: 100px; margin: 10px 0; } .current-temp { font-size: 48px; font-weight: 700; color: var(--accent-blue); text-shadow: 0 0 10px rgba(14, 165, 233, 0.3); } .temp-unit { font-size: 20px; margin-left: 5px; opacity: 0.7; } .temp-controls { display: flex; justify-content: center; gap: 20px; margin-top: 5px; } .temp-btn { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--border-color); background: rgba(31, 41, 55, 0.5); color: var(--text-primary); display: flex; justify-content: center; align-items: center; cursor: pointer; transition: var(--transition); } .temp-btn:hover { border-color: var(--accent-blue); box-shadow: var(--glow-shadow); } .temp-slider { -webkit-appearance: none; width: 100%; height: 6px; border-radius: 5px; background: linear-gradient(to right, #3b82f6, #ef4444); outline: none; margin-top: 15px; } .temp-slider::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; border-radius: 50%; background: var(--text-primary); border: 2px solid var(--accent-blue); cursor: pointer; box-shadow: 0 0 5px rgba(14, 165, 233, 0.5); } .power-consumption { grid-column: span 2; } .consumption-chart { width: 100%; height: 160px; margin-top: 10px; } .security-panel { grid-column: span 2; display: flex; flex-direction: column; } .security-alerts { margin-top: 10px; flex: 1; overflow-y: auto; } .alert { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border-color); } .alert-icon { width: 28px; height: 28px; border-radius: 50%; display: flex; justify-content: center; align-items: center; } .alert-warning { background: rgba(245, 158, 11, 0.1); color: #f59e0b; } .alert-danger { background: rgba(239, 68, 68, 0.1); color: var(--accent-red); } .alert-info { background: rgba(14, 165, 233, 0.1); color: var(--accent-blue); } .alert-details { flex: 1; } .alert-title { font-size: 13px; font-weight: 500; } .alert-time { font-size: 11px; color: var(--text-secondary); } .settings-toggle { background: transparent; border: none; color: var(--text-secondary); cursor: pointer; } .scrollbar-custom::-webkit-scrollbar { width: 5px; } .scrollbar-custom::-webkit-scrollbar-track { background: var(--bg-panel); } .scrollbar-custom::-webkit-scrollbar-thumb { background: var(--border-color); border-radius: 10px; } .scrollbar-custom::-webkit-scrollbar-thumb:hover { background: var(--accent-blue); } .toggle-switch { position: relative; display: inline-block; width: 46px; height: 22px; } .toggle-switch input { opacity: 0; width: 0; height: 0; } .toggle-slider { position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0; background-color: var(--border-color); transition: var(--transition); border-radius: 34px; } .toggle-slider:before { position: absolute; content: ""; height: 16px; width: 16px; left: 3px; bottom: 3px; background-color: var(--text-primary); transition: var(--transition); border-radius: 50%; } input:checked + .toggle-slider { background-color: var(--accent-blue); box-shadow: 0 0 5px rgba(14, 165, 233, 0.5); } input:checked + .toggle-slider:before { transform: translateX(24px); } .grid-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-image: radial-gradient(rgba(14, 165, 233, 0.03) 1px, transparent 1px), radial-gradient(rgba(14, 165, 233, 0.02) 1px, transparent 1px); background-size: 20px 20px; background-position: 0 0, 10px 10px; pointer-events: none; z-index: -1; } .scan-effect { position: absolute; top: 0; left: 0; width: 100%; height: 3px; background: linear-gradient(90deg, transparent, var(--accent-blue), transparent); animation: scanAnimation 3s linear infinite; opacity: 0.7; z-index: 10; } @keyframes scanAnimation { 0% { top: 0; } 100% { top: 100%; } } .live-indicator { display: flex; align-items: center; gap: 5px; font-size: 12px; color: var(--text-secondary); } .live-dot { width: 8px; height: 8px; border-radius: 50%; background-color: var(--accent-red); animation: pulseDot 1.5s infinite; } @keyframes pulseDot { 0% { transform: scale(0.8); opacity: 0.5; } 50% { transform: scale(1); opacity: 1; } 100% { transform: scale(0.8); opacity: 0.5; } } /* Responsive adjustments */ @media (max-width: 700px) { .dashboard { grid-template-columns: repeat(2, 1fr); grid-template-rows: auto repeat(5, 1fr); height: auto; min-height: 100vh; } .system-status, .quick-actions, .device-list, .temperature-control, .power-consumption, .security-panel { grid-column: span 2; } .device-list { grid-row: span 1; } .metric { min-width: 80px; } } @media (max-width: 500px) { .dashboard { padding: 10px; gap: 8px; } .panel { padding: 10px; } .quick-actions { grid-template-columns: 1fr; } .header { flex-direction: column; gap: 10px; align-items: flex-start; } .header-controls { width: 100%; justify-content: space-between; } } </style> </head> <body> <div class="dashboard"> <div class="grid-overlay"></div> <div class="scan-effect"></div> <header class="header"> <div class="logo"> <div class="logo-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M16.5 9.4l-9-5.19M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path> <polyline points="3.29 7 12 12 20.71 7"></polyline> <line x1="12" y1="22" x2="12" y2="12"></line> </svg> </div> <div class="logo-text">NEXUS IoT</div> </div> <div class="header-controls"> <div class="live-indicator"> <div class="live-dot"></div> LIVE DATA </div> <button class="header-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="3"></circle> <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path> </svg> Settings </button> <button class="header-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <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> Alerts </button> </div> </header> <div class="panel system-status"> <div class="panel-header"> <div class="panel-title"> <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"> <path d="M12 2v4"></path> <path d="M20 12h-4"></path> <path d="M12 18v4"></path> <path d="M4 12H0"></path> <path d="M16.364 16.364L19.2 19.2"></path> <path d="M16.364 7.636L19.2 4.8"></path> <path d="M7.636 16.364L4.8 19.2"></path> <path d="M7.636 7.636L4.8 4.8"></path> </svg> System Status </div> <span class="status-text" style="font-size: 12px; color: var(--accent-green);">All systems nominal</span> </div> <div class="system-metrics"> <div class="metric"> <div class="metric-title">CPU Load</div> <div class="metric-value">27<span class="metric-unit">%</span></div> <div class="metric-trend trend-up"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="18 15 12 9 6 15"></polyline> </svg> 3% </div> </div> <div class="metric"> <div class="metric-title">Memory</div> <div class="metric-value">2.4<span class="metric-unit">GB</span></div> <div class="metric-trend trend-up"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="18 15 12 9 6 15"></polyline> </svg> 0.2GB </div> </div> <div class="metric"> <div class="metric-title">Network</div> <div class="metric-value">4.8<span class="metric-unit">Mbps</span></div> <div class="metric-trend trend-down"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="6 9 12 15 18 9"></polyline> </svg> 0.3Mbps </div> </div> <div class="metric"> <div class="metric-title">Devices</div> <div class="metric-value">12<span class="metric-unit">/16</span></div> <div class="metric-trend trend-up"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="18 15 12 9 6 15"></polyline> </svg> 2 </div> </div> </div> </div> <div class="panel quick-actions"> <div class="panel-header"> <div class="panel-title"> <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"> <path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"></path> </svg> Quick Actions </div> </div> <div class="action-btn" id="scene-morning"> <div class="action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> </div> <div class="action-title">Morning Mode</div> <div class="action-desc">Activate morning routine</div> </div> <div class="action-btn" id="security-lock"> <div class="action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect> <path d="M7 11V7a5 5 0 0 1 10 0v4"></path> </svg> </div> <div class="action-title">Security Lock</div> <div class="action-desc">Lock all entrances</div> </div> <div class="action-btn" id="power-save"> <div class="action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M7 2v11m0 0l3-3m-3 3L4 10"></path> <path d="M17 22v-11m0 0l-3 3m3-3l3 3"></path> </svg> </div> <div class="action-title">Power Save</div> <div class="action-desc">Reduce energy usage</div> </div> <div class="action-btn" id="sync-devices"> <div class="action-icon"> <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <polyline points="1 4 1 10 7 10"></polyline> <polyline points="23 20 23 14 17 14"></polyline> <path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"></path> </svg> </div> <div class="action-title">Sync Devices</div> <div class="action-desc">Update all connections</div> </div> </div> <div class="panel device-list scrollbar-custom"> <div class="panel-header"> <div class="panel-title"> <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"> <rect x="2" y="4" width="20" height="16" rx="2" ry="2"></rect> <line x1="6" y1="12" x2="18" y2="12"></line> </svg> Connected Devices </div> <button class="header-btn" style="font-size: 12px; padding: 4px 8px;"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <line x1="12" y1="5" x2="12" y2="19"></line> <line x1="5" y1="12" x2="19" y2="12"></line> </svg> Add </button> </div> <div class="device"> <div class="device-info"> <div class="device-icon"> <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"> <path d="M5 12.55a11 11 0 0 1 14.08 0"></path> <path d="M1.42 9a16 16 0 0 1 21.16 0"></path> <path d="M8.53 16.11a6 6 0 0 1 6.95 0"></path> <line x1="12" y1="20" x2="12.01" y2="20"></line> </svg> </div> <div class="device-details"> <div class="device-name">Main Sensor Hub</div> <div class="device-status"> <div class="status-indicator status-online"></div> Online - 192.168.1.101 </div> </div> </div> <div class="device-actions"> <button class="device-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path> </svg> </button> <button class="device-btn"> <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="3"></circle> <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Responsive Marketplace</title> <style> :root { --primary-color: #4a5568; --primary-light: #718096; --accent-color: #38b2ac; --neutral-bg: #f7fafc; --light-border: #e2e8f0; --text-dark: #2d3748; --text-light: #a0aec0; --shadow: 0 4px 6px rgba(0, 0, 0, 0.1); --border-inactive: 2px; --border-hover: 4px; --border-active: 6px; } * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; } body { background-color: var(--neutral-bg); height: 100vh; display: flex; flex-direction: column; overflow-x: hidden; max-width: 700px; margin: 0 auto; } .marketplace-header { padding: 1.5rem; background-color: white; box-shadow: var(--shadow); position: relative; z-index: 10; } .marketplace-title { color: var(--text-dark); font-size: 1.5rem; font-weight: 600; margin-bottom: 0.5rem; } .marketplace-subtitle { color: var(--text-light); font-size: 0.875rem; } .filters { display: flex; gap: 0.5rem; margin-top: 1rem; overflow-x: auto; padding-bottom: 0.5rem; } .filter-btn { background-color: white; border: 1px solid var(--light-border); border-radius: 1rem; padding: 0.5rem 1rem; color: var(--text-dark); font-size: 0.75rem; white-space: nowrap; cursor: pointer; transition: all 0.2s ease; } .filter-btn:hover, .filter-btn.active { background-color: var(--primary-light); color: white; } .products-container { padding: 1.5rem; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 1.5rem; align-items: start; } .product-card { background-color: white; border-radius: 8px; overflow: hidden; position: relative; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); box-shadow: var(--shadow); } .product-border { position: absolute; inset: 0; border: var(--border-inactive) solid transparent; border-radius: 8px; transition: border-width 0.3s ease, border-color 0.3s ease; pointer-events: none; z-index: 2; } .product-card:hover .product-border { border-width: var(--border-hover); border-color: var(--accent-color); } .active-product .product-border { border-width: var(--border-active) !important; border-color: var(--accent-color) !important; background-image: linear-gradient(45deg, rgba(255,255,255,.1) 25%, transparent 25%, transparent 50%, rgba(255,255,255,.1) 50%, rgba(255,255,255,.1) 75%, transparent 75%, transparent); background-size: 4px 4px; animation: border-dance 1s linear infinite; } @keyframes border-dance { 0% { background-position: 0 0; } 100% { background-position: 4px 4px; } } .product-image { width: 100%; height: 140px; object-fit: cover; transition: transform 0.3s ease; } .product-card:hover .product-image { transform: scale(1.05); } .product-info { padding: 1rem; } .product-name { font-weight: 600; color: var(--text-dark); margin-bottom: 0.25rem; font-size: 1rem; } .product-seller { display: flex; align-items: center; margin-bottom: 0.5rem; } .seller-avatar { width: 20px; height: 20px; border-radius: 50%; margin-right: 0.5rem; } .seller-name { font-size: 0.75rem; color: var(--text-light); } .product-metrics { display: flex; justify-content: space-between; font-size: 0.75rem; color: var(--text-light); } .engagement-indicator { position: absolute; top: 0.5rem; right: 0.5rem; display: flex; align-items: center; padding: 0.25rem 0.5rem; background-color: rgba(0, 0, 0, 0.6); border-radius: 1rem; color: white; font-size: 0.7rem; font-weight: 500; opacity: 0; transform: translateY(-10px); transition: all 0.3s ease; } .product-card:hover .engagement-indicator, .active-product .engagement-indicator { opacity: 1; transform: translateY(0); } .market-stats { margin-top: 2rem; background-color: white; border-radius: 8px; padding: 1rem; box-shadow: var(--shadow); } .stats-title { color: var(--text-dark); font-size: 1rem; font-weight: 600; margin-bottom: 1rem; } .stats-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; } .stat-card { background-color: var(--neutral-bg); padding: 0.75rem; border-radius: 8px; text-align: center; } .stat-value { font-size: 1.25rem; font-weight: 700; color: var(--primary-color); margin-bottom: 0.25rem; } .stat-label { font-size: 0.7rem; color: var(--text-light); } .engagement-dot { width: 8px; height: 8px; border-radius: 50%; margin-right: 4px; background-color: var(--accent-color); } .tooltip { position: absolute; background: white; padding: 0.5rem 0.75rem; border-radius: 4px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); font-size: 0.75rem; color: var(--text-dark); z-index: 100; pointer-events: none; opacity: 0; transition: opacity 0.2s; white-space: nowrap; max-width: 200px; } @media (max-width: 480px) { .products-container { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 1rem; } .product-image { height: 120px; } .stats-grid { grid-template-columns: 1fr 1fr; } } </style> </head> <body> <header class="marketplace-header"> <h1 class="marketplace-title">Artisan Marketplace</h1> <p class="marketplace-subtitle">Products with more engagement feature thicker responsive borders</p> <div class="filters"> <button class="filter-btn active">All Products</button> <button class="filter-btn">Trending</button> <button class="filter-btn">New Arrivals</button> <button class="filter-btn">Handcrafted</button> <button class="filter-btn">Limited Edition</button> </div> </header> <div class="products-container" id="productsGrid"> <!-- Products will be generated here --> </div> <div class="market-stats"> <h2 class="stats-title">Market Insights</h2> <div class="stats-grid"> <div class="stat-card"> <div class="stat-value">98%</div> <div class="stat-label">Seller Response Rate</div> </div> <div class="stat-card"> <div class="stat-value">3,721</div> <div class="stat-label">Active Listings</div> </div> <div class="stat-card"> <div class="stat-value">24hr</div> <div class="stat-label">Avg. Response Time</div> </div> </div> </div> <div class="tooltip" id="tooltip"></div> <script> // Product data const products = [ { id: 1, name: "Handmade Ceramic Bowl", image: "https://images.unsplash.com/photo-1578749556568-bc2c064d9473?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", seller: { name: "Clay Studios", avatar: "https://randomuser.me/api/portraits/women/32.jpg" }, views: 245, sales: 18, engagement: 87 }, { id: 2, name: "Artisan Wooden Cutting Board", image: "https://images.unsplash.com/photo-1541975902809-04c4402e4395?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", seller: { name: "Forest Crafts", avatar: "https://randomuser.me/api/portraits/men/45.jpg" }, views: 378, sales: 42, engagement: 93 }, { id: 3, name: "Hand-stitched Leather Wallet", image: "https://images.unsplash.com/photo-1563903380166-bb87e06a4c8b?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", seller: { name: "Leather & Thread", avatar: "https://randomuser.me/api/portraits/women/68.jpg" }, views: 189, sales: 15, engagement: 65 }, { id: 4, name: "Woven Basket Set", image: "https://images.unsplash.com/photo-1600369671236-e74521d4b6ad?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", seller: { name: "Weaving Wonders", avatar: "https://randomuser.me/api/portraits/men/22.jpg" }, views: 156, sales: 9, engagement: 42 }, { id: 5, name: "Hand-blown Glass Vase", image: "https://images.unsplash.com/photo-1612196808214-b9304d011b90?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", seller: { name: "Glass & Fire", avatar: "https://randomuser.me/api/portraits/women/55.jpg" }, views: 302, sales: 28, engagement: 78 }, { id: 6, name: "Macramé Wall Hanging", image: "https://images.unsplash.com/photo-1582643382047-f7fd2b7d9f7c?ixlib=rb-1.2.1&auto=format&fit=crop&w=500&q=80", seller: { name: "Knot & Twist", avatar: "https://randomuser.me/api/portraits/men/36.jpg" }, views: 214, sales: 17, engagement: 59 } ]; // Generate product cards const productsGrid = document.getElementById('productsGrid'); const tooltip = document.getElementById('tooltip'); function renderProducts() { productsGrid.innerHTML = ''; products.forEach(product => { const productCard = document.createElement('div'); productCard.className = 'product-card'; productCard.dataset.id = product.id; productCard.dataset.engagement = product.engagement; productCard.innerHTML = ` <div class="product-border"></div> <img src="${product.image}" alt="${product.name}" class="product-image"> <div class="engagement-indicator"> <div class="engagement-dot"></div> ${product.engagement}% engaged </div> <div class="product-info"> <h3 class="product-name">${product.name}</h3> <div class="product-seller"> <img src="${product.seller.avatar}" alt="${product.seller.name}" class="seller-avatar"> <span class="seller-name">${product.seller.name}</span> </div> <div class="product-metrics"> <span>${product.views} views</span> <span>${product.sales} sold</span> </div> </div> `; productsGrid.appendChild(productCard); }); addEventListeners(); } function addEventListeners() { const productCards = document.querySelectorAll('.product-card'); productCards.forEach(card => { // Toggle active state on click card.addEventListener('click', function() { const isActive = this.classList.contains('active-product'); // Remove active class from all cards document.querySelectorAll('.active-product').forEach(activeCard => { activeCard.classList.remove('active-product'); }); // Toggle active state for clicked card if (!isActive) { this.classList.add('active-product'); } }); // Show engagement tooltip on hover card.addEventListener('mouseenter', function(e) { const engagement = this.dataset.engagement; const rect = this.getBoundingClientRect(); tooltip.textContent = `User engagement: ${engagement}% - Border thickness adapts based on this metric`; tooltip.style.top = `${rect.top - 40}px`; tooltip.style.left = `${rect.left + (rect.width / 2) - (tooltip.offsetWidth / 2)}px`; tooltip.style.opacity = '1'; }); card.addEventListener('mouseleave', function() { tooltip.style.opacity = '0'; }); }); // Filter button listeners const filterButtons = document.querySelectorAll('.filter-btn'); filterButtons.forEach(button => { button.addEventListener('click', function() { filterButtons.forEach(btn => btn.classList.remove('active')); this.classList.add('active'); // Simulate filter effect - in a real app, this would filter the products const productCards = document.querySelectorAll('.product-card'); productCards.forEach(card => { card.style.opacity = '0.2'; setTimeout(() => { card.style.opacity = '1'; }, 300); }); }); }); } // Initialize renderProducts(); // Simulate real-time engagement updates setInterval(() => { const cards = document.querySelectorAll('.product-card'); const randomCard = cards[Math.floor(Math.random() * cards.length)]; // Pulse animation for random engagement update const border = randomCard.querySelector('.product-border'); border.style.borderColor = 'var(--accent-color)'; setTimeout(() => { if (!randomCard.classList.contains('active-product')) { border.style.borderColor = 'transparent'; } }, 1000); // Update engagement value const currentEngagement = parseInt(randomCard.dataset.engagement); const changeAmount = Math.floor(Math.random() * 5) + 1; const newEngagement = Math.min(99, currentEngagement + changeAmount); randomCard.dataset.engagement = newEngagement; const indicator = randomCard.querySelector('.engagement-indicator'); indicator.innerHTML = `<div class="engagement-dot"></div>${newEngagement}% engaged`; // Flash animation indicator.style.transform = 'scale(1.2)'; setTimeout(() => { indicator.style.transform = 'scale(1)'; }, 300); }, 5000); </script> </body> </html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> :root { --primary: #2b2b2b; --secondary: #f5f5f5; --accent: #8b0000; --muted-blue: #47597E; --muted-yellow: #DBB98F; --serif: 'Georgia', 'Times New Roman', serif; --sans: 'Helvetica', 'Arial', sans-serif; } * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: var(--serif); background-color: var(--secondary); color: var(--primary); padding: 1rem; max-width: 700px; height: 700px; margin: 0 auto; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--accent) var(--secondary); } body::-webkit-scrollbar { width: 8px; } body::-webkit-scrollbar-track { background: var(--secondary); } body::-webkit-scrollbar-thumb { background-color: var(--accent); } header { text-align: center; border-bottom: 3px solid var(--primary); padding-bottom: 0.75rem; margin-bottom: 1.5rem; position: relative; } .masthead { font-family: 'Times New Roman', serif; font-size: 2.5rem; font-weight: 900; letter-spacing: -1px; margin-bottom: 0.5rem; } .date-weather { display: flex; justify-content: space-between; font-size: 0.7rem; font-family: var(--sans); text-transform: uppercase; letter-spacing: 1px; color: var(--primary); margin-bottom: 0.5rem; } .slogan { font-style: italic; font-size: 0.8rem; margin-bottom: 0.5rem; } nav { display: flex; justify-content: space-around; border-top: 1px solid var(--primary); border-bottom: 1px solid var(--primary); padding: 0.5rem 0; font-family: var(--sans); font-size: 0.8rem; text-transform: uppercase; letter-spacing: 1px; } nav a { color: var(--primary); text-decoration: none; transition: color 0.3s; position: relative; } nav a:after { content: ''; position: absolute; width: 0; height: 2px; bottom: -3px; left: 0; background-color: var(--accent); transition: width 0.3s; } nav a:hover { color: var(--accent); } nav a:hover:after { width: 100%; } .layout { display: grid; grid-template-columns: 2fr 1fr; gap: 1rem; } @media (max-width: 600px) { .layout { grid-template-columns: 1fr; } } .main-content { display: grid; gap: 1.5rem; } article, .editorial { padding: 1rem; position: relative; transition: all 0.3s ease; } article { border: 1px solid var(--primary); } article.featured { border-width: 3px; } .editorial { border: 1px dashed var(--primary); background-color: rgba(219, 185, 143, 0.1); } article:hover, .editorial:hover { box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); transform: translateY(-2px); } .editorial-marker { position: absolute; top: -10px; right: 10px; background-color: var(--primary); color: var(--secondary); font-family: var(--sans); font-size: 0.7rem; padding: 0.2rem 0.5rem; text-transform: uppercase; letter-spacing: 1px; } h1, h2, h3 { font-family: var(--serif); margin-bottom: 0.5rem; } h2 { font-size: 1.5rem; line-height: 1.2; } h3 { font-size: 1.2rem; font-weight: bold; } .article-meta { font-family: var(--sans); font-size: 0.7rem; margin-bottom: 0.7rem; color: #666; display: flex; justify-content: space-between; } .tags { display: flex; gap: 0.5rem; } .tag { background-color: var(--muted-blue); color: white; padding: 0.1rem 0.3rem; border-radius: 3px; font-size: 0.65rem; text-transform: uppercase; } p { line-height: 1.5; margin-bottom: 0.7rem; font-size: 0.9rem; } .sidebar { display: flex; flex-direction: column; gap: 1.5rem; } .sidebar-section { border-left: 2px solid var(--primary); padding-left: 1rem; } .author-info { display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.5rem; } .author-avatar { width: 35px; height: 35px; border-radius: 50%; object-fit: cover; border: 1px solid var(--primary); } .author-name { font-weight: bold; } .read-more { display: inline-block; font-family: var(--sans); font-size: 0.8rem; color: var(--accent); text-decoration: none; font-weight: bold; margin-top: 0.5rem; position: relative; overflow: hidden; } .read-more:after { content: ''; position: absolute; bottom: 0; left: 0; width: 100%; height: 1px; background-color: var(--accent); transform: translateX(-100%); transition: transform 0.3s ease; } .read-more:hover:after { transform: translateX(0); } .trending { list-style-position: inside; margin-left: 0.5rem; } .trending li { margin-bottom: 0.7rem; font-size: 0.9rem; position: relative; counter-increment: trending-counter; } .trending li::before { content: counter(trending-counter); position: absolute; left: -1.5rem; color: var(--accent); font-weight: bold; font-size: 0.8rem; } /* Custom typewriter effect */ .typewriter { overflow: hidden; border-right: 3px solid var(--primary); white-space: nowrap; margin: 0 auto; letter-spacing: 0.1em; animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite; } @keyframes typing { from { width: 0 } to { width: 100% } } @keyframes blink-caret { from, to { border-color: transparent } 50% { border-color: var(--primary); } } .breaking-news { background-color: var(--accent); color: white; padding: 0.5rem; font-family: var(--sans); font-weight: bold; text-transform: uppercase; letter-spacing: 1px; text-align: center; margin-bottom: 1rem; position: relative; overflow: hidden; } .news-ticker { animation: ticker 20s linear infinite; white-space: nowrap; } @keyframes ticker { 0% { transform: translateX(100%); } 100% { transform: translateX(-100%); } } footer { margin-top: 1.5rem; border-top: 3px solid var(--primary); padding-top: 1rem; font-family: var(--sans); font-size: 0.8rem; text-align: center; color: #666; } .quotation { font-size: 1.5rem; line-height: 1.3; font-style: italic; position: relative; padding: 0 2rem; margin: 1rem 0; } .quotation:before, .quotation:after { font-size: 3rem; position: absolute; color: var(--accent); opacity: 0.3; } .quotation:before { content: '"'; top: -20px; left: 0; } .quotation:after { content: '"'; bottom: -40px; right: 0; } /* Dark mode toggle */ .dark-mode-toggle { position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; cursor: pointer; z-index: 100; } body.dark-mode { --primary: #f5f5f5; --secondary: #1a1a1a; --accent: #ff6b6b; --muted-blue: #7289da; --muted-yellow: #ffd369; } /* Theme transition */ body { transition: background-color 0.5s, color 0.5s; } body * { transition: background-color 0.5s, color 0.5s, border-color 0.5s; } </style> </head> <body> <header> <div class="dark-mode-toggle" id="darkModeToggle"> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> </svg> </div> <h1 class="masthead">The Daily Chronicle</h1> <div class="slogan typewriter">Pursuing truth since 1887</div> <div class="date-weather"> <span>Tuesday, May 14, 2023</span> <span>64°F, Partly Cloudy</span> </div> <nav> <a href="#">Politics</a> <a href="#">Business</a> <a href="#">Technology</a> <a href="#">Opinion</a> <a href="#">Arts</a> </nav> </header> <div class="breaking-news"> <div class="news-ticker">Breaking: Senate passes landmark climate legislation with bipartisan support</div> </div> <div class="layout"> <div class="main-content"> <article class="featured"> <h2>Supreme Court To Hear Arguments on Digital Privacy Rights Case</h2> <div class="article-meta"> <span>By James Holloway | May 14, 2023</span> <div class="tags"> <span class="tag">Law</span> <span class="tag">Tech</span> </div> </div> <p>In what legal experts are calling "the most significant Fourth Amendment case of the digital era," the Supreme Court will hear arguments next month on whether government agencies need warrants to access citizens' cloud storage data.</p> <p>The case, <em>United States v. Fischer</em>, centers on whether prosecutors violated defendant Marcus Fischer's constitutional rights when they obtained his Google Drive files without a warrant, using only a subpoena to the company.</p> <p>"This isn't just about one person's files," said civil liberties attorney Eliza Warren. "The Court's decision will establish precedent for how much privacy Americans can expect in their digital lives."</p> <a href="#" class="read-more">Continue reading</a> </article> <div class="editorial"> <span class="editorial-marker">Editorial</span> <h2>The False Promise of Tech Neutrality</h2> <div class="author-info"> <img src="https://randomuser.me/api/portraits/women/44.jpg" alt="Author" class="author-avatar"> <span class="author-name">Diana Chen, Technology Editor</span> </div> <p>For decades, Silicon Valley has hidden behind the shield of "technological neutrality" — the notion that platforms merely provide tools without responsibility for their use. This fiction has finally collapsed.</p> <p>As algorithmic systems increasingly determine what information we see, which job opportunities we find, and how our communities are policed, the idea that these systems are value-neutral is intellectually dishonest.</p> <div class="quotation">To claim neutrality in a world of algorithmic amplification is to deny both reality and responsibility.</div> <p>We need a new framework that acknowledges the power these systems wield, the values embedded in their design, and establishes appropriate guardrails for their deployment.</p> <a href="#" class="read-more">Continue reading</a> </div> <article> <h2>Local Agriculture Faces Climate Adaptation Challenges</h2> <div class="article-meta"> <span>By Sofia Reyes | May 13, 2023</span> <div class="tags"> <span class="tag">Climate</span> <span class="tag">Local</span> </div> </div> <p>Fourth-generation farmer Marcus Wilson walks through rows of drought-resistant sorghum, a crop his grandfather would never have considered planting in the region. "You either adapt or you don't survive," he says, gesturing to irrigation systems powered by solar panels.</p> <p>Across the county, farmers are grappling with rising temperatures, unpredictable rainfall patterns, and new pest pressures. The Midwest Agricultural Extension Service reports that average growing seasons have shifted by nearly two weeks over the past 30 years.</p> <a href="#" class="read-more">Continue reading</a> </article> </div> <div class="sidebar"> <div class="sidebar-section"> <h3>Trending Stories</h3> <ol class="trending"> <li>Federal Reserve signals possible rate pause amid inflation slowdown</li> <li>Breakthrough in quantum computing achieved by university research team</li> <li>Major film studio announces revival of beloved 90s franchise</li> <li>Healthcare spending reaches historic high amid aging population</li> </ol> </div> <div class="editorial sidebar-section"> <span class="editorial-marker">Opinion</span> <h3>Media Literacy Is National Security</h3> <div class="author-info"> <img src="https://randomuser.me/api/portraits/men/32.jpg" alt="Author" class="author-avatar"> <span class="author-name">Robert Lin, National Security Analyst</span> </div> <p>The inability of Americans to distinguish genuine reporting from propaganda isn't just an educational failure—it's a national security vulnerability that rivals any military threat.</p> <p>When coordinated disinformation campaigns can sway elections, provoke civil unrest, and undermine public health measures, media literacy becomes essential infrastructure.</p> <a href="#" class="read-more">Continue reading</a> </div> <div class="sidebar-section"> <h3>Market Update</h3> <p> <strong>Dow:</strong> 36,124 (+0.8%)<br> <strong>S&P 500:</strong> 4,782 (+1.2%)<br> <strong>Nasdaq:</strong> 14,897 (+1.5%)<br> <strong>10-Year Treasury:</strong> 3.52% (-0.05) </p> </div> </div> </div> <footer> <p>© 2023 The Daily Chronicle | Privacy Policy | Subscription Services | Advertise With Us</p> </footer> <script> // Dark mode toggle functionality const darkModeToggle = document.getElementById('darkModeToggle'); const body = document.body; // Check for saved user preference if (localStorage.getItem('darkMode') === 'enabled') { body.classList.add('dark-mode'); updateToggleIcon(true); } darkModeToggle.addEventListener('click', () => { if (body.classList.contains('dark-mode')) { body.classList.remove('dark-mode'); localStorage.setItem('darkMode', 'disabled'); updateToggleIcon(false); } else { body.classList.add('dark-mode'); localStorage.setItem('darkMode', 'enabled'); updateToggleIcon(true); } }); function updateToggleIcon(isDarkMode) { if (isDarkMode) { darkModeToggle.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <circle cx="12" cy="12" r="5"></circle> <line x1="12" y1="1" x2="12" y2="3"></line> <line x1="12" y1="21" x2="12" y2="23"></line> <line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line> <line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line> <line x1="1" y1="12" x2="3" y2="12"></line> <line x1="21" y1="12" x2="23" y2="12"></line> <line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line> <line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line> </svg> `; } else { darkModeToggle.innerHTML = ` <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path> </svg> `; } } // Typewriter effect for headliner const headliners = [ "Pursuing truth since 1887", "Integrity in journalism matters", "Your trusted news source" ]; let headlinerIndex = 0; function changeHeadliner() { const slogan = document.querySelector('.slogan'); slogan.classList.remove('typewriter'); // Trigger reflow to restart animation void slogan.offsetWidth; headlinerIndex = (headlinerIndex + 1) % headliners.length; slogan.textContent = headliners[headlinerIndex]; slogan.classList.add('typewriter'); } setInterval(changeHeadliner, 8000); </script> </body> </html>