dg-rpg / index.html
weltenschmid's picture
Update index.html
2c2c4d6 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nexus Protocol - Sci-Fi RPG</title>
<style>
/* Inlined Tailwind CSS */
:root {
--primary: #0a192f;
--secondary: #172a45;
--accent: #64ffda;
--dark: #020c1b;
--light: #ccd6f6;
--highlight: #1e90ff;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Roboto', sans-serif;
background-color: var(--dark);
color: var(--light);
height: 100vh;
width: 100vw;
overflow: hidden;
}
.absolute {
position: absolute;
}
.relative {
position: relative;
}
.fixed {
position: fixed;
}
.inset-0 {
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.top-0 {
top: 0;
}
.right-0 {
right: 0;
}
.bottom-0 {
bottom: 0;
}
.left-0 {
left: 0;
}
.flex {
display: flex;
}
.hidden {
display: none;
}
.items-center {
align-items: center;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.flex-col {
flex-direction: column;
}
.flex-1 {
flex: 1 1 0%;
}
.w-full {
width: 100%;
}
.h-full {
height: 100%;
}
.w-16 {
width: 4rem;
}
.h-16 {
height: 4rem;
}
.w-10 {
width: 2.5rem;
}
.h-10 {
height: 2.5rem;
}
.w-12 {
width: 3rem;
}
.h-12 {
height: 3rem;
}
.rounded-full {
border-radius: 9999px;
}
.rounded-lg {
border-radius: 0.5rem;
}
.rounded-md {
border-radius: 0.375rem;
}
.overflow-hidden {
overflow: hidden;
}
.overflow-y-auto {
overflow-y: auto;
}
.bg-black {
background-color: #000;
}
.bg-gray-900 {
background-color: #111827;
}
.bg-blue-900 {
background-color: #1e3a8a;
}
.bg-opacity-40 {
opacity: 0.4;
}
.bg-opacity-80 {
opacity: 0.8;
}
.bg-opacity-90 {
opacity: 0.9;
}
.border-2 {
border-width: 2px;
}
.border-blue-500 {
border-color: #3b82f6;
}
.border-transparent {
border-color: transparent;
}
.text-center {
text-align: center;
}
.text-xs {
font-size: 0.75rem;
line-height: 1rem;
}
.text-sm {
font-size: 0.875rem;
line-height: 1.25rem;
}
.text-lg {
font-size: 1.125rem;
line-height: 1.75rem;
}
.text-xl {
font-size: 1.25rem;
line-height: 1.75rem;
}
.text-blue-400 {
color: #60a5fa;
}
.text-gray-300 {
color: #d1d5db;
}
.text-gray-400 {
color: #9ca3af;
}
.font-bold {
font-weight: 700;
}
.leading-relaxed {
line-height: 1.625;
}
.px-4 {
padding-left: 1rem;
padding-right: 1rem;
}
.py-2 {
padding-top: 0.5rem;
padding-bottom: 0.5rem;
}
.px-3 {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
.py-1 {
padding-top: 0.25rem;
padding-bottom: 0.25rem;
}
.mb-1 {
margin-bottom: 0.25rem;
}
.mb-2 {
margin-bottom: 0.5rem;
}
.mb-4 {
margin-bottom: 1rem;
}
.mt-1 {
margin-top: 0.25rem;
}
.mt-2 {
margin-top: 0.5rem;
}
.mt-4 {
margin-top: 1rem;
}
.mr-2 {
margin-right: 0.5rem;
}
.mr-3 {
margin-right: 0.75rem;
}
.space-x-1 > * + * {
margin-left: 0.25rem;
}
.space-x-2 > * + * {
margin-left: 0.5rem;
}
.space-x-3 > * + * {
margin-left: 0.75rem;
}
.space-x-4 > * + * {
margin-left: 1rem;
}
.space-y-1 > * + * {
margin-top: 0.25rem;
}
.space-y-2 > * + * {
margin-top: 0.5rem;
}
.grid {
display: grid;
}
.grid-cols-1 {
grid-template-columns: repeat(1, minmax(0, 1fr));
}
.grid-cols-2 {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
.grid-cols-4 {
grid-template-columns: repeat(4, minmax(0, 1fr));
}
.gap-2 {
gap: 0.5rem;
}
.gap-3 {
gap: 0.75rem;
}
.cursor-pointer {
cursor: pointer;
}
.pointer-events-none {
pointer-events: none;
}
.object-cover {
object-fit: cover;
}
.z-20 {
z-index: 20;
}
.z-30 {
z-index: 30;
}
.z-50 {
z-index: 50;
}
.transform {
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.-translate-x-1\/2 {
--tw-translate-x: -50%;
}
.transition {
transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.transition-all {
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}
.duration-300 {
transition-duration: 300ms;
}
.ease-in {
transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
.ease-out {
transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
}
.group:hover .group-hover\:opacity-100 {
opacity: 1;
}
.opacity-0 {
opacity: 0;
}
.opacity-50 {
opacity: 0.5;
}
.opacity-70 {
opacity: 0.7;
}
.opacity-100 {
opacity: 1;
}
.panel-hidden {
opacity: 0;
pointer-events: none;6
}
.panel-visible {
opacity: 1;
pointer-events: auto;
}
/* Custom Fonts */
@font-face {
font-family: 'Orbitron';
font-style: normal;
font-weight: 400;
src: url(Orbitron400.woff2) format('woff2');
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: url(Roboto400.woff2) format('woff2');
}
.tech-font {
font-family: 'Orbitron', sans-serif;
}
/* Custom Components */
.health-bar {
height: 6px;
background: linear-gradient(to right, #ff5555, #ff0000);
border-radius: 3px;
transition: width 0.3s ease;
}
.energy-bar {
height: 6px;
background: linear-gradient(to right, #64ffda, #1e90ff);
border-radius: 3px;
transition: width 0.3s ease;
}
.action-btn {
background: rgba(10, 25, 47, 0.8);
border: 1px solid var(--accent);
transition: all 0.2s ease;
color: var(--accent);
}
.action-btn:hover {
background: rgba(23, 42, 69, 0.8);
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(100, 255, 218, 0.3);
}
.character-card {
transition: all 0.3s ease;
border: 1px solid transparent;
}
.character-card:hover {
border-color: var(--accent);
transform: translateY(-5px);
}
.character-card.active {
border-color: var(--highlight);
box-shadow: 0 0 15px rgba(30, 144, 255, 0.5);
}
.node {
width: 12px;
height: 12px;
background-color: var(--accent);
border-radius: 50%;
position: absolute;
cursor: pointer;
transition: all 0.3s ease;
}
.node:hover {
transform: scale(1.5);
box-shadow: 0 0 10px var(--accent);
}
.node.visited {
background-color: var(--highlight);
}
.node.current {
transform: scale(1.8);
box-shadow: 0 0 15px var(--highlight);
}
.node.available {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(100, 255, 218, 0.7); }
70% { box-shadow: 0 0 0 8px rgba(100, 255, 218, 0); }
100% { box-shadow: 0 0 0 0 rgba(100, 255, 218, 0); }
}
.fade-in {
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
.damage-text {
position: absolute;
color: #ff5555;
font-weight: bold;
animation: floatUp 1s forwards;
pointer-events: none;
text-shadow: 1px 1px 2px black;
font-family: 'Orbitron', sans-serif;
}
@keyframes floatUp {
0% { transform: translateY(0); opacity: 1; }
100% { transform: translateY(-50px); opacity: 0; }
}
.ui-panel {
transition: all 0.4s cubic-bezier(0.22, 1, 0.36, 1);
}
.bottom-panel {
transform: translateY(100%);
}
.right-panel {
transform: translateX(100%);
}
.left-panel {
transform: translateX(-100%);
}
.panel-visible {
transform: translate(0);
}
.panel-hidden {
opacity: 0;
pointer-events: none;
}
.first-person-overlay {
position: absolute;
inset: 0;
pointer-events: none;
background: radial-gradient(circle at center, transparent 70%, rgba(2, 12, 27, 0.7) 100%);
z-index: 5;
}
.weapon-effect {
animation: weaponFire 0.3s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
}
@keyframes weaponFire {
0% { opacity: 0; transform: scale(0.5); }
50% { opacity: 1; transform: scale(1.2); }
100% { opacity: 0; transform: scale(0.8); }
}
.dialog-box {
background: rgba(10, 25, 47, 0.9);
border: 1px solid var(--accent);
box-shadow: 0 0 20px rgba(100, 255, 218, 0.3);
}
.dialog-option:hover {
background: rgba(23, 42, 69, 0.7);
border-left: 3px solid var(--accent);
}
.character-avatar {
transition: all 0.3s ease;
border: 2px solid transparent;
}
.character-avatar:hover {
border-color: var(--accent);
transform: scale(1.05);
}
.character-avatar.active {
border-color: var(--highlight);
box-shadow: 0 0 15px rgba(30, 144, 255, 0.5);
}
.map-transition {
animation: mapFade 1s ease-in-out;
}
@keyframes mapFade {
0% { opacity: 0; transform: scale(0.9); }
100% { opacity: 1; transform: scale(1); }
}
.scene-transition {
animation: sceneFade 0.8s ease-in-out;
}
@keyframes sceneFade {
0% { opacity: 0; }
100% { opacity: 1; }
}
.notification {
animation: notificationPop 0.3s cubic-bezier(0.68, -0.55, 0.265, 1.55) both;
}
@keyframes notificationPop {
0% { transform: scale(0); opacity: 0; }
100% { transform: scale(1); opacity: 1; }
}
.fade-out {
animation: fadeOut 0.3s ease-out forwards;
}
@keyframes fadeOut {
to { opacity: 0; }
}
.hud-element {
background: rgba(10, 25, 47, 0.5);
border: 1px solid rgba(100, 255, 218, 0.3);
backdrop-filter: blur(5px);
}
.scene-container {
background-size: cover;
background-position: center;
transition: background-image 0.5s ease;
}
/* Font Awesome Icons */
.fa,
.fas {
font-family: 'Font Awesome 6 Free';
font-weight: 900;
}
.fa-map:before {
content: "\f279";
}
.fa-cog:before {
content: "\f013";
}
.fa-book:before {
content: "\f02d";
}
.fa-shield-alt:before {
content: "\f3ed";
}
.fa-bolt:before {
content: "\f0e7";
}
.fa-microchip:before {
content: "\f2db";
}
.fa-cogs:before {
content: "\f085";
}
.fa-hourglass-end:before {
content: "\f253";
}
.fa-flag:before {
content: "\f024";
}
.fa-user-astronaut:before {
content: "\f4fb";
}
.fa-comment:before {
content: "\f075";
}
.fa-satellite-dish:before {
content: "\f7c0";
}
.fa-times:before {
content: "\f00d";
}
.fa-heartbeat:before {
content: "\f21e";
}
.fa-atom:before {
content: "\f5d2";
}
.fa-map-marked-alt:before {
content: "\f5a0";
}
.fa-history:before {
content: "\f1da";
}
.fa-lock:before {
content: "\f023";
}
.fa-battery-half:before {
content: "\f242";
}
</style>
</head>
<body class="relative h-full">
<!-- Main Game View -->
<div id="gameView" class="absolute inset-0 overflow-hidden">
<!-- Current Scene Background -->
<div id="sceneContainer" class="scene-container absolute inset-0 bg-gray-900 flex items-end justify-center scene-transition" style="background-image: url('https://i.imgur.com/Dw6qY7a.png')">
<!-- Scene content will be dynamically loaded here -->
<!-- Characters in Scene (max 15) -->
<div id="sceneCharacters" class="absolute inset-0 pointer-events-none">
<!-- Characters will be dynamically positioned here -->
</div>
<!-- First-Person Overlay Effect -->
<div class="first-person-overlay"></div>
<!-- Weapon Effects -->
<div id="weaponEffects" class="absolute inset-0 pointer-events-none"></div>
<!-- Damage Numbers -->
<div id="damageContainer" class="absolute inset-0 pointer-events-none"></div>
</div>
<!-- Player Status Bar (Minimal - expands on hover) -->
<div id="playerStatus" class="absolute bottom-0 left-0 right-0 h-16 bg-black bg-opacity-40 flex justify-center items-center transition-all duration-300 hover:h-24">
<div class="flex items-center space-x-6 px-4">
<!-- Avatar -->
<div class="character-avatar w-12 h-12 rounded-full bg-gray-800 border-2 border-blue-500 overflow-hidden">
<img src="https://i.imgur.com/JQ9qy0E.png" alt="Player" class="w-full h-full object-cover">
</div>
<!-- Health -->
<div class="w-32">
<div class="flex justify-between text-xs mb-1">
<span>INTEGRITY</span>
<span>85%</span>
</div>
<div class="health-bar" style="width: 85%"></div>
</div>
<!-- Energy -->
<div class="w-32">
<div class="flex justify-between text-xs mb-1">
<span>POWER</span>
<span>64%</span>
</div>
<div class="energy-bar" style="width: 64%"></div>
</div>
<!-- Quick Stats -->
<div class="hidden md:flex space-x-4 text-xs">
<div class="text-center">
<div class="tech-font text-blue-400">Lv.12</div>
<div>NEXUS</div>
</div>
<div class="text-center">
<div class="tech-font text-green-400">24</div>
<div>ATK</div>
</div>
<div class="text-center">
<div class="tech-font text-purple-400">18</div>
<div>DEF</div>
</div>
</div>
<!-- Expanded Info (shown on hover) -->
<div class="hidden md:flex items-center space-x-4 opacity-0 transition-opacity duration-300 group-hover:opacity-100">
<div class="text-xs">
<div class="flex items-center space-x-1">
<i class="fas fa-shield-alt text-blue-400"></i>
<span>Shield: 85/100</span>
</div>
<div class="flex items-center space-x-1">
<i class="fas fa-bolt text-yellow-400"></i>
<span>Energy: 32/50</span>
</div>
</div>
<div class="text-xs">
<div class="flex items-center space-x-1">
<i class="fas fa-microchip text-green-400"></i>
<span>RAM: 4/6</span>
</div>
<div class="flex items-center space-x-1">
<i class="fas fa-cogs text-red-400"></i>
<span>Heat: 42°</span>
</div>
</div>
</div>
</div>
</div>
<!-- Player Team (Callable Cards) -->
<div id="teamPanel" class="absolute bottom-20 left-0 right-0 flex justify-center space-x-2 px-4">
<!-- Team member cards (5 total) -->
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer active">
<div class="h-12 bg-blue-900 flex items-center justify-center">
<img src="https://i.imgur.com/3QZ2Q0X.png" alt="Teammate" class="w-full h-full object-cover">
</div>
<div class="p-1">
<div class="health-bar w-full mb-1" style="width: 80%"></div>
<p class="text-xs truncate text-center">Elandra</p>
</div>
</div>
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer">
<div class="h-12 bg-purple-900 flex items-center justify-center">
<img src="https://i.imgur.com/5t5wY9j.png" alt="Teammate" class="w-full h-full object-cover">
</div>
<div class="p-1">
<div class="health-bar w-full mb-1" style="width: 45%"></div>
<p class="text-xs truncate text-center">Thorgar</p>
</div>
</div>
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer">
<div class="h-12 bg-green-900 flex items-center justify-center">
<img src="https://i.imgur.com/7VvX7Qq.png" alt="Teammate" class="w-full h-full object-cover">
</div>
<div class="p-1">
<div class="energy-bar w-full mb-1" style="width: 30%"></div>
<p class="text-xs truncate text-center">Merlin</p>
</div>
</div>
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer">
<div class="h-12 bg-red-900 flex items-center justify-center">
<img src="https://i.imgur.com/9t5wY9j.png" alt="Teammate" class="w-full h-full object-cover">
</div>
<div class="p-1">
<div class="health-bar w-full mb-1" style="width: 90%"></div>
<p class="text-xs truncate text-center">Lydia</p>
</div>
</div>
<div class="character-card w-16 h-20 bg-gray-900 bg-opacity-70 rounded-md overflow-hidden cursor-pointer">
<div class="h-12 bg-yellow-900 flex items-center justify-center">
<img src="https://i.imgur.com/JQ9qy0E.png" alt="Teammate" class="w-full h-full object-cover">
</div>
<div class="p-1">
<div class="health-bar w-full mb-1" style="width: 60%"></div>
<p class="text-xs truncate text-center">Rook</p>
</div>
</div>
</div>
<!-- Quick Access Menu (Top Right) -->
<div id="quickMenu" class="absolute top-4 right-4 flex space-x-2">
<button class="hud-element w-10 h-10 rounded-full flex items-center justify-center text-blue-400 hover:text-blue-300">
<i class="fas fa-map"></i>
</button>
<button class="hud-element w-10 h-10 rounded-full flex items-center justify-center text-green-400 hover:text-green-300">
<i class="fas fa-cog"></i>
</button>
<button class="hud-element w-10 h-10 rounded-full flex items-center justify-center text-purple-400 hover:text-purple-300">
<i class="fas fa-book"></i>
</button>
</div>
<!-- Round Indicator (Top Left) -->
<div id="roundIndicator" class="absolute top-4 left-4 hud-element px-3 py-1 rounded-full">
<span class="tech-font text-blue-400">ROUND <span id="roundNumber">1</span></span>
</div>
<!-- Action Points (Top Center) -->
<div id="actionPointsDisplay" class="absolute top-4 left-1/2 transform -translate-x-1/2 hud-element px-4 py-1 rounded-full flex items-center space-x-2">
<i class="fas fa-bolt text-yellow-400"></i>
<span class="tech-font">AP: <span id="apCount">4</span>/6</span>
</div>
</div>
<!-- World Map Panel (Hidden by default) -->
<div id="mapPanel" class="absolute inset-0 bg-black bg-opacity-90 z-20 flex items-center justify-center panel-hidden">
<div class="relative w-full h-full max-w-4xl max-h-4xl">
<button id="closeMap" class="absolute top-4 right-4 text-2xl text-blue-400 hover:text-blue-300 z-30">
<i class="fas fa-times"></i>
</button>
<!-- Map Background -->
<div class="absolute inset-0 bg-gray-900 rounded-lg overflow-hidden">
<!-- This would be your map background image -->
<div class="absolute inset-0 opacity-20" style="background-image: url('https://i.imgur.com/Dw6qY7a.png'); background-size: cover;"></div>
<!-- Node Connections -->
<svg id="mapConnections" class="absolute inset-0 w-full h-full" xmlns="http://www.w3.org/2000/svg">
<!-- Connections between nodes will be drawn here -->
<line x1="20%" y1="30%" x2="35%" y2="45%" stroke="#64ffda" stroke-width="2" stroke-dasharray="5,3" />
<line x1="35%" y1="45%" x2="50%" y2="40%" stroke="#64ffda" stroke-width="2" />
<line x1="50%" y1="40%" x2="65%" y2="55%" stroke="#64ffda" stroke-width="2" />
<line x1="65%" y1="55%" x2="80%" y2="50%" stroke="#64ffda" stroke-width="2" />
</svg>
<!-- Map Nodes -->
<div class="node visited" style="top: 30%; left: 20%;" data-scene="start"></div>
<div class="node visited" style="top: 45%; left: 35%;" data-scene="hub1"></div>
<div class="node current" style="top: 40%; left: 50%;" data-scene="current"></div>
<div class="node available" style="top: 55%; left: 65%;" data-scene="lab"></div>
<div class="node" style="top: 50%; left: 80%;" data-scene="boss"></div>
</div>
<!-- Map Info Panel -->
<div class="absolute bottom-4 left-4 hud-element p-4 max-w-xs">
<h3 class="tech-font text-xl text-blue-400 mb-2">SECTOR 7-GRID</h3>
<p class="text-sm">Current Location: Research Outpost</p>
<p class="text-sm mt-2">Available Paths:</p>
<ul class="text-xs space-y-1 mt-1">
<li class="flex items-center">
<div class="w-2 h-2 rounded-full bg-blue-500 mr-2"></div>
<span>Main Laboratory (1.2km)</span>
</li>
<li class="flex items-center opacity-50">
<div class="w-2 h-2 rounded-full bg-gray-500 mr-2"></div>
<span>Command Center (Locked)</span>
</li>
</ul>
</div>
</div>
</div>
<!-- Dialog Panel (Hidden by default) -->
<div id="dialogPanel" class="absolute bottom-0 left-0 right-0 h-1/3 bg-black bg-opacity-80 z-20 panel-hidden">
<div class="h-full flex flex-col">
<!-- Speaker Info -->
<div class="flex items-center p-4 border-b border-blue-900">
<div class="w-12 h-12 rounded-full bg-gray-800 overflow-hidden mr-3">
<img src="https://i.imgur.com/3QZ2Q0X.png" alt="Speaker" class="w-full h-full object-cover">
</div>
<div>
<h3 class="tech-font text-blue-400">Commander Elandra</h3>
<p class="text-xs text-gray-400">Nexus Protocol Officer</p>
</div>
</div>
<!-- Dialog Text -->
<div class="flex-1 p-4 overflow-y-auto">
<p class="text-lg leading-relaxed">
"The quantum destabilization in Sector 7 is worse than we thought. Our scans show the anomaly is spreading at an exponential rate. We need to act now before it breaches the containment field."
</p>
</div>
<!-- Dialog Options -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-2 p-4 border-t border-blue-900">
<div class="dialog-option p-3 cursor-pointer border-l-3 border-transparent">
<p class="text-sm">"What's the plan? How can we stop it?"</p>
</div>
<div class="dialog-option p-3 cursor-pointer border-l-3 border-transparent">
<p class="text-sm">"Is this related to the missing research team?"</p>
</div>
<div class="dialog-option p-3 cursor-pointer border-l-3 border-transparent">
<p class="text-sm">"What are the risks if we fail?"</p>
</div>
<div class="dialog-option p-3 cursor-pointer border-l-3 border-transparent">
<p class="text-sm">"I need more resources to handle this."</p>
</div>
</div>
</div>
</div>
<!-- Action Panel (Hidden by default) -->
<div id="actionPanel" class="absolute bottom-0 left-0 right-0 bg-black bg-opacity-80 z-20 panel-hidden">
<div class="p-4">
<h3 class="tech-font text-xl text-blue-400 mb-4 text-center">COMBAT ACTIONS</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
<!-- Attack Actions -->
<div class="action-btn p-3 rounded-lg cursor-pointer group">
<div class="flex items-center space-x-2">
<div class="w-10 h-10 rounded-full bg-red-900 flex items-center justify-center">
<i class="fas fa-bolt text-red-300"></i>
</div>
<div>
<p class="tech-font text-blue-400">Plasma Shot</p>
<div class="flex items-center space-x-1 text-xs">
<i class="fas fa-bolt text-yellow-400"></i>
<span>1 AP</span>
<i class="fas fa-battery-half text-green-400"></i>
<span>5E</span>
</div>
</div>
</div>
<p class="text-xs mt-1 text-gray-300 opacity-0 group-hover:opacity-100 transition">
Fire a concentrated plasma bolt (12-18 damage)
</p>
</div>
<!-- Tech Actions -->
<div class="action-btn p-3 rounded-lg cursor-pointer group">
<div class="flex items-center space-x-2">
<div class="w-10 h-10 rounded-full bg-blue-900 flex items-center justify-center">
<i class="fas fa-shield-alt text-blue-300"></i>
</div>
<div>
<p class="tech-font text-blue-400">Deflector</p>
<div class="flex items-center space-x-1 text-xs">
<i class="fas fa-bolt text-yellow-400"></i>
<span>1 AP</span>
<i class="fas fa-battery-half text-green-400"></i>
<span>8E</span>
</div>
</div>
</div>
<p class="text-xs mt-1 text-gray-300 opacity-0 group-hover:opacity-100 transition">
Raise deflector shield (+15 DEF for 1 round)
</p>
</div>
<!-- Special Actions -->
<div class="action-btn p-3 rounded-lg cursor-pointer group">
<div class="flex items-center space-x-2">
<div class="w-10 h-10 rounded-full bg-purple-900 flex items-center justify-center">
<i class="fas fa-atom text-purple-300"></i>
</div>
<div>
<p class="tech-font text-blue-400">Overload</p>
<div class="flex items-center space-x-1 text-xs">
<i class="fas fa-bolt text-yellow-400"></i>
<span>2 AP</span>
<i class="fas fa-battery-half text-green-400"></i>
<span>15E</span>
</div>
</div>
</div>
<p class="text-xs mt-1 text-gray-300 opacity-0 group-hover:opacity-100 transition">
Overcharge systems (Next attack +50% damage)
</p>
</div>
<!-- Utility Actions -->
<div class="action-btn p-3 rounded-lg cursor-pointer group">
<div class="flex items-center space-x-2">
<div class="w-10 h-10 rounded-full bg-green-900 flex items-center justify-center">
<i class="fas fa-heartbeat text-green-300"></i>
</div>
<div>
<p class="tech-font text-blue-400">Repair</p>
<div class="flex items-center space-x-1 text-xs">
<i class="fas fa-bolt text-yellow-400"></i>
<span>2 AP</span>
<i class="fas fa-battery-half text-green-400"></i>
<span>12E</span>
</div>
</div>
</div>
<p class="text-xs mt-1 text-gray-300 opacity-0 group-hover:opacity-100 transition">
Emergency repair (Restore 15-25 INT)
</p>
</div>
</div>
<div class="mt-4 flex justify-between items-center">
<button id="endTurnBtn" class="action-btn px-4 py-2 rounded flex items-center space-x-2">
<i class="fas fa-hourglass-end"></i>
<span>END TURN</span>
</button>
<div class="flex items-center space-x-4">
<div class="flex items-center space-x-2 text-sm">
<i class="fas fa-bolt text-yellow-400"></i>
<span>AP: <span class="tech-font">4</span>/6</span>
</div>
<div class="flex items-center space-x-2 text-sm">
<i class="fas fa-battery-half text-green-400"></i>
<span>Energy: <span class="tech-font">32</span>/50</span>
</div>
</div>
</div>
</div>
</div>
<!-- Notification System -->
<div id="notificationContainer" class="fixed top-4 right-4 space-y-2 z-50"></div>
<script>
// Game state
let currentRound = 1;
let actionPoints = 4;
let currentScene = 'research_outpost';
let mapVisible = false;
let dialogVisible = false;
let actionPanelVisible = false;
// Initialize UI
document.addEventListener('DOMContentLoaded', () => {
// Setup event listeners
document.getElementById('closeMap').addEventListener('click', toggleMap);
document.querySelectorAll('.node').forEach(node => {
node.addEventListener('click', navigateToNode);
});
// Setup quick menu buttons
document.querySelectorAll('#quickMenu button').forEach((btn, index) => {
btn.addEventListener('click', () => {
if (index === 0) toggleMap();
if (index === 1) showNotification('Settings panel would open here', 'fas fa-cog');
if (index === 2) showNotification('Codex would open here', 'fas fa-book');
});
});
// Setup team panel interactions
document.querySelectorAll('.character-card').forEach(card => {
card.addEventListener('click', selectTeamMember);
});
// Setup action panel
document.getElementById('endTurnBtn').addEventListener('click', endTurn);
// Load initial scene
loadScene(currentScene);
// Show welcome notification
setTimeout(() => {
showNotification('Nexus Protocol initialized', 'fas fa-satellite-dish', 'text-blue-400');
}, 500);
});
// Scene management
function loadScene(sceneId) {
const sceneContainer = document.getElementById('sceneContainer');
const sceneCharacters = document.getElementById('sceneCharacters');
// Clear existing characters
sceneCharacters.innerHTML = '';
// Add characters to scene (max 15)
const characters = [
{ id: 'elandra', x: '70%', y: '60%', image: 'https://i.imgur.com/3QZ2Q0X.png' },
{ id: 'scientist', x: '30%', y: '50%', image: 'https://i.imgur.com/5t5wY9j.png' },
{ id: 'drone', x: '50%', y: '40%', image: 'https://i.imgur.com/7VvX7Qq.png' }
];
characters.slice(0, 15).forEach(char => {
const charElement = document.createElement('div');
charElement.className = 'absolute w-16 h-16 rounded-full overflow-hidden border-2 border-blue-500 cursor-pointer';
charElement.style.left = char.x;
charElement.style.top = char.y;
charElement.innerHTML = `<img src="${char.image}" alt="${char.id}" class="w-full h-full object-cover">`;
charElement.addEventListener('click', () => interactWithCharacter(char.id));
sceneCharacters.appendChild(charElement);
});
sceneContainer.classList.add('scene-transition');
setTimeout(() => {
sceneContainer.classList.remove('scene-transition');
}, 800);
}
function interactWithCharacter(charId) {
if (charId === 'elandra') {
showDialog(
'Commander Elandra',
'Nexus Protocol Officer',
'https://i.imgur.com/3QZ2Q0X.png',
'"The quantum destabilization in Sector 7 is worse than we thought. Our scans show the anomaly is spreading at an exponential rate. We need to act now before it breaches the containment field."'
);
} else {
showNotification(`Interacting with ${charId}`, 'fas fa-comment');
}
}
// Navigation
function toggleMap() {
const mapPanel = document.getElementById('mapPanel');
mapVisible = !mapVisible;
if (mapVisible) {
mapPanel.classList.remove('panel-hidden');
mapPanel.classList.add('panel-visible', 'map-transition');
} else {
mapPanel.classList.remove('panel-visible');
mapPanel.classList.add('panel-hidden');
}
}
function navigateToNode(e) {
const node = e.currentTarget;
const sceneId = node.getAttribute('data-scene');
if (node.classList.contains('available') || node.classList.contains('current')) {
showNotification(`Navigating to ${sceneId}...`, 'fas fa-map-marked-alt');
setTimeout(() => {
toggleMap();
loadScene(sceneId);
}, 1000);
} else if (node.classList.contains('visited')) {
showNotification('Returning to previous location...', 'fas fa-history');
setTimeout(() => {
toggleMap();
loadScene(sceneId);
}, 1000);
} else {
showNotification('Location not yet available', 'fas fa-lock', 'text-red-400');
}
}
// Dialog system
function showDialog(speaker, title, image, text) {
const dialogPanel = document.getElementById('dialogPanel');
const speakerImg = dialogPanel.querySelector('img');
const speakerName = dialogPanel.querySelector('h3');
const speakerTitle = dialogPanel.querySelector('p.text-xs');
const dialogText = dialogPanel.querySelector('p.text-lg');
speakerImg.src = image;
speakerName.textContent = speaker;
speakerTitle.textContent = title;
dialogText.textContent = text;
dialogPanel.classList.remove('panel-hidden');
dialogPanel.classList.add('panel-visible');
dialogVisible = true;
}
function closeDialog() {
const dialogPanel = document.getElementById('dialogPanel');
dialogPanel.classList.remove('panel-visible');
dialogPanel.classList.add('panel-hidden');
dialogVisible = false;
}
// Combat system
function toggleActionPanel() {
const actionPanel = document.getElementById('actionPanel');
actionPanelVisible = !actionPanelVisible;
if (actionPanelVisible) {
actionPanel.classList.remove('panel-hidden');
actionPanel.classList.add('panel-visible');
} else {
actionPanel.classList.remove('panel-visible');
actionPanel.classList.add('panel-hidden');
}
}
function endTurn() {
currentRound++;
document.getElementById('roundNumber').textContent = currentRound;
actionPoints = 6;
document.getElementById('apCount').textContent = actionPoints;
showNotification(`Round ${currentRound} started`, 'fas fa-flag', 'text-blue-400');
toggleActionPanel();
}
// Team management
function selectTeamMember(e) {
const card = e.currentTarget;
// Deselect all
document.querySelectorAll('.character-card').forEach(c => {
c.classList.remove('active');
});
// Select clicked
card.classList.add('active');
showNotification(`${card.querySelector('p').textContent} selected`, 'fas fa-user-astronaut');
}
// Notification system
function showNotification(message, icon, textColor = 'text-blue-400') {
const container = document.getElementById('notificationContainer');
const notification = document.createElement('div');
notification.className = `notification hud-element px-4 py-2 rounded-lg flex items-center space-x-2 ${textColor}`;
notification.innerHTML = `
<i class="${icon}"></i>
<span>${message}</span>
`;
container.appendChild(notification);
// Remove after delay
setTimeout(() => {
notification.classList.add('fade-out');
setTimeout(() => {
notification.remove();
}, 300);
}, 3000);
}
// Keyboard shortcuts
document.addEventListener('keydown', (e) => {
// Toggle map with M key
if (e.key === 'm' || e.key === 'M') {
e.preventDefault();
toggleMap();
}
// Toggle action panel with Space key
if (e.key === ' ') {
e.preventDefault();
toggleActionPanel();
}
// Close dialogs with Escape
if (e.key === 'Escape') {
if (dialogVisible) closeDialog();
if (actionPanelVisible) toggleActionPanel();
if (mapVisible) toggleMap();
}
});
</script>
</body>
</html>