Spaces:
Sleeping
Sleeping
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Knowledge Graph</title> | |
| <style> | |
| /* Reset and base styles */ | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; | |
| height: 100vh; | |
| overflow: hidden; | |
| position: relative; | |
| background: linear-gradient(180deg, #F8F3E7 35%, #708686 90%); | |
| } | |
| /* Background Graph Network */ | |
| .background-network { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| z-index: 1; | |
| pointer-events: none; | |
| } | |
| .network-lines { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| z-index: 1; | |
| } | |
| .network-nodes { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| z-index: 3; | |
| } | |
| .network-node { | |
| position: absolute; | |
| border-radius: 50%; | |
| opacity: 1; | |
| } | |
| .network-line { | |
| position: absolute; | |
| background-color: #5f6b7a; | |
| height: 1.5px; | |
| opacity: 0.4; | |
| transform-origin: left center; | |
| } | |
| /* Node colors and sizes - exact match to your design */ | |
| .node-teal { background-color: #A9C5C5; } | |
| .node-purple-light { background-color: #DBCAE1; } | |
| .node-blue-light { background-color: #B0C4DE; } | |
| .node-small { width: 35px; height: 35px; } | |
| .node-medium { width: 50px; height: 50px; } | |
| .node-large { width: 85px; height: 85px; } | |
| /* Login Button as Network Node */ | |
| .login-node { | |
| position: absolute; | |
| background-color: #64748b; | |
| border-radius: 50%; | |
| width: 80px; | |
| height: 80px; | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| font-size: 12px; | |
| font-weight: 500; | |
| color: white; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); | |
| z-index: 100; | |
| pointer-events: auto; | |
| opacity: 1; | |
| } | |
| .login-node:hover { | |
| background-color: #475569; | |
| transform: translateY(-2px); | |
| box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2); | |
| } | |
| .login-icon { | |
| font-size: 20px; | |
| margin-bottom: 2px; | |
| } | |
| /* Main Content */ | |
| .main-content { | |
| position: relative; | |
| z-index: 10; | |
| height: 100vh; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| align-items: center; | |
| text-align: center; | |
| padding: 0 40px; | |
| } | |
| /* Title Section */ | |
| .title-section { | |
| margin-bottom: 0px; | |
| } | |
| .main-title { | |
| font-family: 'Kumbh Sans', sans-serif; | |
| font-size: 4.5rem; | |
| font-weight: 700; | |
| color: #4D536D; | |
| letter-spacing: -0.02em; | |
| margin-top: 120px; | |
| line-height: 1.1; | |
| } | |
| .subtitle { | |
| font-family: 'Mandali', sans-serif; | |
| font-size: 1.125rem; | |
| color: #4D536D; | |
| font-weight: 400; | |
| line-height: 1.6; | |
| max-width: 500px; | |
| margin: 0 auto 10px; | |
| } | |
| .subtitle-second { | |
| font-family: 'Mandali', sans-serif; | |
| font-size: 1.125rem; | |
| color: #4D536D; | |
| font-weight: 400; | |
| } | |
| /* Search Section */ | |
| /* Ganti max-width kalo mau ubah lebar */ | |
| .search-container { | |
| width: 100%; | |
| max-width: 740px; | |
| margin-top: 20px; | |
| } | |
| .search-input { | |
| width: 100%; | |
| padding: 16px 22px; | |
| font-size: 1rem; | |
| border: none; | |
| border-radius: 25px; | |
| background-color: rgb(243, 231, 221); | |
| color: #64748b; | |
| outline: none; | |
| transition: all 0.3s ease; | |
| box-shadow: 0 4px 4px rgba(0, 0, 0, 0.3); | |
| margin-bottom: 15px; | |
| } | |
| .search-input::placeholder { | |
| color: #797979; | |
| font-weight: 400; | |
| } | |
| .search-input:focus { | |
| background-color: rgba(255, 255, 255, 1); | |
| box-shadow: 0 6px 30px rgba(0, 0, 0, 0.15); | |
| transform: translateY(-2px); | |
| } | |
| .search-btn { | |
| background-color: #4D536D; | |
| color: white; | |
| border: none; | |
| border-radius: 20px; | |
| padding: 12px 32px; | |
| font-size: 1rem; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| box-shadow: 0 4px 4px rgba(0, 0, 0, 0.3); | |
| } | |
| .search-btn:hover { | |
| background-color: #475569; | |
| transform: translateY(-2px); | |
| box-shadow: 0 6px 20px rgba(100, 116, 139, 0.4); | |
| } | |
| .search-btn:active { | |
| transform: translateY(0); | |
| } | |
| /* Divider */ | |
| .divider-container { | |
| display: flex; | |
| align-items: center; | |
| width: 100%; | |
| max-width: 400px; | |
| margin: 30px 0; | |
| margin-top: 15px; | |
| } | |
| .divider-line { | |
| flex: 1; | |
| height: 1px; | |
| background-color: rgb(255 255 255); | |
| } | |
| .divider-text { | |
| margin: 0 20px; | |
| color: #FFFFFF; | |
| font-size: 1rem; | |
| font-weight: 500; | |
| } | |
| /* Explore Button */ | |
| .explore-btn { | |
| background-color: #4D536D; | |
| color: white; | |
| border: none; | |
| border-radius: 25px; | |
| padding: 16px 48px; | |
| font-size: 1rem; | |
| font-weight: 500; | |
| cursor: pointer; | |
| transition: all 0.3s ease; | |
| box-shadow: 0 4px 4px rgba(0, 0, 0, 0.3); | |
| width: 100%; | |
| max-width: 520px; | |
| } | |
| .explore-btn:hover { | |
| background-color: #475569; | |
| transform: translateY(-3px); | |
| box-shadow: 0 8px 30px rgba(100, 116, 139, 0.4); | |
| } | |
| .explore-btn:active { | |
| transform: translateY(-1px); | |
| } | |
| /* Responsive Design */ | |
| @media (max-width: 768px) { | |
| .main-title { | |
| font-size: 3rem; | |
| } | |
| .subtitle, .subtitle-second { | |
| font-size: 1rem; | |
| } | |
| .main-content { | |
| padding: 0 20px; | |
| } | |
| .login-btn { | |
| width: 60px; | |
| height: 60px; | |
| font-size: 10px; | |
| } | |
| .login-icon { | |
| font-size: 16px; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| .main-title { | |
| font-size: 2.5rem; | |
| } | |
| .login-container { | |
| top: 20px; | |
| right: 20px; | |
| } | |
| } | |
| /* Animation for network elements */ | |
| @keyframes float { | |
| 0%, 100% { transform: translateY(0px); } | |
| 50% { transform: translateY(-10px); } | |
| } | |
| .network-node { | |
| animation: float 6s ease-in-out infinite; | |
| } | |
| .network-node:nth-child(2n) { | |
| animation-delay: -2s; | |
| } | |
| .network-node:nth-child(3n) { | |
| animation-delay: -4s; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <!-- Background Network --> | |
| <div class="background-network" id="backgroundNetwork"> | |
| <div class="network-lines" id="networkLines"></div> | |
| <div class="network-nodes" id="networkNodes"></div> | |
| </div> | |
| <!-- Main Content --> | |
| <div class="main-content"> | |
| <div class="title-section"> | |
| <h1 class="main-title">KNOWLEDGE GRAPH</h1> | |
| <p class="subtitle">Explore health insights powered by national news</p> | |
| <p class="subtitle-second">ask, discover, and learn.</p> | |
| </div> | |
| <div class="search-container"> | |
| <input | |
| type="text" | |
| class="search-input" | |
| id="queryInput" | |
| placeholder="Type Query" | |
| onkeypress="handleKeyPress(event)" | |
| > | |
| <button class="search-btn" onclick="handleSearch()">Search</button> | |
| </div> | |
| <div class="divider-container"> | |
| <div class="divider-line"></div> | |
| <span class="divider-text">OR</span> | |
| <div class="divider-line"></div> | |
| </div> | |
| <button class="explore-btn" onclick="handleExplore()">Explore Knowledge Graph</button> | |
| </div> | |
| <script> | |
| // Create background network - exact placement matching your image | |
| function createBackgroundNetwork() { | |
| const linesContainer = document.getElementById('networkLines'); | |
| const nodesContainer = document.getElementById('networkNodes'); | |
| const nodes = []; | |
| // Exact node positions from your image | |
| const nodeConfigs = [ | |
| // Top row (left to right, some truncated) | |
| { x: -1, y: -3, size: 'large', color: 'blue-light' }, | |
| { x: 16, y: 3, size: 'medium', color: 'purple-light' }, | |
| { x: 32, y: -5, size: 'large', color: 'teal' }, | |
| { x: 55, y: 2, size: 'medium', color: 'blue-light' }, | |
| { x: 68, y: -4, size: 'small', color: 'purple-light' }, | |
| { x: 86, y: -1, size: 'small', color: 'purple-light' }, | |
| { x: 100, y: -1, size: 'small', color: 'blue-light' }, | |
| // Login node (top right as in image) | |
| { x: 92, y: 2, size: 'login', color: 'login' }, | |
| // Second row | |
| { x: 7, y: 15, size: 'small', color: 'teal' }, | |
| { x: 25, y: 12, size: 'small', color: 'blue-light' }, | |
| { x: 44, y: 12, size: 'medium', color: 'purple-light' }, | |
| { x: 58, y: 15, size: 'small', color: 'teal' }, | |
| { x: 72, y: 6, size: 'large', color: 'purple-light' }, | |
| { x: 82, y: 11, size: 'small', color: 'teal' }, | |
| // Third row (more scattered) | |
| { x: 32, y: 18, size: 'medium', color: 'blue-light' }, | |
| { x: 100, y: 15, size: 'small', color: 'teal' }, | |
| ]; | |
| // Create nodes including login | |
| nodeConfigs.forEach((config, index) => { | |
| if (config.color === 'login') { | |
| const loginNode = document.createElement('div'); | |
| loginNode.className = 'login-node'; | |
| loginNode.style.left = `${config.x}%`; | |
| loginNode.style.top = `${config.y}%`; | |
| loginNode.style.animation = 'float 6s ease-in-out infinite'; | |
| loginNode.style.animationDelay = '-2s'; | |
| loginNode.onclick = handleLogin; | |
| loginNode.innerHTML = ` | |
| <div class="login-icon">👤</div> | |
| <div>Login</div> | |
| `; | |
| nodesContainer.appendChild(loginNode); | |
| } else { | |
| const node = document.createElement('div'); | |
| node.className = `network-node node-${config.size} node-${config.color}`; | |
| node.style.left = `${config.x}%`; | |
| node.style.top = `${config.y}%`; | |
| nodesContainer.appendChild(node); | |
| } | |
| nodes.push({ | |
| x: config.x, | |
| y: config.y, | |
| index: index, | |
| isLogin: config.color === 'login' | |
| }); | |
| }); | |
| // Connections matching your image exactly | |
| const connections = [ | |
| // Top row main connections | |
| [0, 1], [1, 2], [2, 3], [3, 4], [4, 5], | |
| // Login connections (as shown in image) | |
| [7, 5], [7, 13], [7, 6], [7, 15], | |
| // Vertical connections from top to second row | |
| [0, 8], [1, 9], [2, 9], [3, 10], [5, 12], [12, 13], [3, 12], | |
| // Second row horizontal connections | |
| [8, 9], [10, 11], [11, 12], | |
| // Connections to third row | |
| [9, 14], [10, 14], | |
| // Some cross connections for the web-like structure | |
| [2, 10], [4, 12] | |
| ]; | |
| // Create connection lines | |
| connections.forEach(([startIdx, endIdx]) => { | |
| const startNode = nodes[startIdx]; | |
| const endNode = nodes[endIdx]; | |
| if (startNode && endNode) { | |
| const line = document.createElement('div'); | |
| line.className = 'network-line'; | |
| const startSize = startNode.isLogin ? 40 : 20; | |
| const endSize = endNode.isLogin ? 40 : 20; | |
| const startX = (startNode.x * window.innerWidth) / 100 + startSize; | |
| const startY = (startNode.y * window.innerHeight) / 100 + startSize; | |
| const endX = (endNode.x * window.innerWidth) / 100 + endSize; | |
| const endY = (endNode.y * window.innerHeight) / 100 + endSize; | |
| const length = Math.sqrt(Math.pow(endX - startX, 2) + Math.pow(endY - startY, 2)); | |
| const angle = Math.atan2(endY - startY, endX - startX) * 180 / Math.PI; | |
| line.style.left = `${startX}px`; | |
| line.style.top = `${startY}px`; | |
| line.style.width = `${length}px`; | |
| line.style.transform = `rotate(${angle}deg)`; | |
| linesContainer.appendChild(line); | |
| } | |
| }); | |
| } | |
| // Event handlers | |
| function handleLogin() { | |
| alert('Login functionality will be implemented when you provide the login page design.'); | |
| console.log('Login clicked'); | |
| } | |
| function handleSearch() { | |
| const query = document.getElementById('queryInput').value.trim(); | |
| if (query) { | |
| // Navigate to results page with query parameter | |
| window.location.href = `search.html?q=${encodeURIComponent(query)}`; | |
| } else { | |
| alert('Please enter a query to search.'); | |
| } | |
| } | |
| function handleExplore() { | |
| // alert('Explore Knowledge Graph functionality will be implemented when you provide the graph page design.'); | |
| console.log('Explore Knowledge Graph clicked'); | |
| window.location.href = 'explorepage.html'; // Change this line | |
| } | |
| function handleKeyPress(event) { | |
| if (event.key === 'Enter') { | |
| handleSearch(); | |
| } | |
| } | |
| // Initialize the background network when page loads | |
| window.addEventListener('load', () => { | |
| createBackgroundNetwork(); | |
| }); | |
| // Recreate network on window resize | |
| window.addEventListener('resize', () => { | |
| document.getElementById('networkLines').innerHTML = ''; | |
| document.getElementById('networkNodes').innerHTML = ''; | |
| createBackgroundNetwork(); | |
| }); | |
| // Add some interactivity to the input | |
| document.addEventListener('DOMContentLoaded', () => { | |
| const input = document.getElementById('queryInput'); | |
| input.addEventListener('focus', () => { | |
| input.style.transform = 'translateY(-2px)'; | |
| }); | |
| input.addEventListener('blur', () => { | |
| input.style.transform = 'translateY(0)'; | |
| }); | |
| }); | |
| </script> | |
| </body> | |
| </html> |