Update logo.png with new project logo

Replaced the old logo image asset with a new version. No code or logic changes were made; only the logo.png file was updated.
This commit is contained in:
Michal Vrba
2026-08-28 10:17:48 +02:00
parent cd3874c7be
commit ca8e8d0dea
8 changed files with 148 additions and 26 deletions
+87 -16
View File
@@ -9,7 +9,14 @@
<main class="game-shell @(_isTransitioning ? "transitioning" : "") @(_systemFlash ? "system-alert" : "")" tabindex="0" @ref="_shell" @onkeydown="HandleKey">
@if (!_ready)
{
<section class="loading-screen"><span>NULL DEPTH // BOOTING</span></section>
<section class="loading-screen">
<div class="wasm-logo-wrapper" style="width:110px;height:110px;margin-bottom:1.2rem;">
<div class="wasm-scanner-ring ring-outer"></div>
<div class="wasm-scanner-ring ring-inner"></div>
<img class="wasm-logo" style="width:78px;height:78px;" src="logo.png" alt="NULL DEPTH" />
</div>
<span>NULL DEPTH // BOOTING</span>
</section>
}
else if (_screen == Screen.Title)
{
@@ -93,9 +100,21 @@
@if (_interaction is not null)
{
var availableChoices = _interaction.Choices.Where(c => Game.HasAll(c.RequiresFlags)).ToList();
<div class="modal-layer" role="dialog" aria-modal="true"><article class="terminal-card interaction-modal">
<button class="close-button" aria-label="Close" @onclick="CloseOverlays">×</button><p class="eyebrow">@_interaction.Type.ToUpperInvariant() // @_interaction.Id.ToUpperInvariant()</p><h2>@Game.T(_interaction.LabelKey)</h2><p class="terminal-copy">@Game.T(_interaction.ContentKey)</p>
@if (_interaction.Choices.Count > 0) { <div class="choice-list">@foreach (var choice in _interaction.Choices.Where(c => Game.HasAll(c.RequiresFlags))) { <button @onclick="() => ResolveChoice(choice)">@Game.T(choice.LabelKey)</button> }</div> }
@if (availableChoices.Count > 0)
{
<div class="choice-list">
@for (var index = 0; index < availableChoices.Count; index++)
{
var choiceIndex = index;
var choice = availableChoices[index];
<button class="@(choiceIndex == _choiceIndex ? "selected" : "")" @onclick="() => ResolveChoice(choice)"><kbd>@(choiceIndex + 1)</kbd> @Game.T(choice.LabelKey)</button>
}
</div>
<small>↑ ↓ / W S SELECT // ENTER CONFIRM // 1-@availableChoices.Count SELECT</small>
}
else { <button class="primary-action" @onclick="ResolveInteraction">@Game.T("common.confirm")</button> }
</article></div>
}
@@ -162,6 +181,7 @@
private bool _savePulse;
private int _savePulseVersion;
private int _interactionIndex;
private int _choiceIndex;
private string? _titleNotice;
private SaveLoadResult? _saveError;
private Confirmation? _confirmation;
@@ -213,7 +233,7 @@
_showInteractionPicker = true;
_notice = null;
}
private void OpenInteraction(InteractionDefinition interaction) { _showInteractionPicker = false; _interaction = interaction; _notice = null; }
private void OpenInteraction(InteractionDefinition interaction) { _showInteractionPicker = false; _interaction = interaction; _choiceIndex = 0; _notice = null; }
private void SelectInteraction(InteractionDefinition interaction) => OpenInteraction(interaction);
private async Task ResolveInteraction()
{
@@ -288,31 +308,82 @@
private async Task HandleKey(KeyboardEventArgs args)
{
if (!_ready) return;
if (_confirmation is not null || _saveError is not null) { if (args.Key == "Escape") { _confirmation = null; _saveError = null; } return; }
if (_confirmation is not null || _saveError is not null)
{
if (args.Key == "Escape") { _confirmation = null; _saveError = null; }
else if (args.Key is "Enter" or " ")
{
if (_confirmation is not null) await ConfirmPendingAction();
else if (_saveError is not null) await DeleteBrokenSave();
}
return;
}
if (_showSettings) { if (args.Key == "Escape") await CloseSettings(); return; }
var keyLower = args.Key.ToLowerInvariant();
if (_showInteractionPicker)
{
var actions = AvailableActions;
if (args.Key == "Escape") CloseOverlays();
else if (args.Key is "ArrowDown" or "ArrowUp") { var delta = args.Key == "ArrowDown" ? 1 : -1; _interactionIndex = (_interactionIndex + delta + actions.Count) % actions.Count; }
else if (args.Key == "Enter" && actions.Count > 0) OpenInteraction(actions[_interactionIndex]);
else if (args.Key is "ArrowDown" or "Down" || keyLower == "s") { _interactionIndex = (_interactionIndex + 1) % actions.Count; }
else if (args.Key is "ArrowUp" or "Up" || keyLower == "w") { _interactionIndex = (_interactionIndex - 1 + actions.Count) % actions.Count; }
else if (args.Key is "Enter" or " " && actions.Count > 0) OpenInteraction(actions[_interactionIndex]);
else if (int.TryParse(args.Key, out var number) && number > 0 && number <= actions.Count) OpenInteraction(actions[number - 1]);
return;
}
if (_interaction is not null || _showMap || _showInventory || _showArchive) { if (args.Key == "Escape") CloseOverlays(); return; }
if (_showPause) { if (args.Key == "Escape") CloseOverlays(); return; }
if (_screen == Screen.Title)
if (_interaction is not null)
{
if (args.Key is "ArrowDown" or "ArrowUp") { var delta = args.Key == "ArrowDown" ? 1 : -1; do { _menuIndex = (_menuIndex + delta + 3) % 3; } while (_menuIndex == 1 && !Game.HasSave); }
else if (args.Key == "Enter") { if (_menuIndex == 0) await StartNewGame(); else if (_menuIndex == 1) await ContinueGame(); else await OpenSettings(); }
var choices = _interaction.Choices.Where(c => Game.HasAll(c.RequiresFlags)).ToList();
if (args.Key == "Escape") { CloseOverlays(); return; }
if (choices.Count > 0)
{
if (args.Key is "ArrowDown" or "Down" || keyLower == "s") { _choiceIndex = (_choiceIndex + 1) % choices.Count; return; }
if (args.Key is "ArrowUp" or "Up" || keyLower == "w") { _choiceIndex = (_choiceIndex - 1 + choices.Count) % choices.Count; return; }
if (args.Key is "Enter" or " ") { await ResolveChoice(choices[_choiceIndex]); return; }
if (int.TryParse(args.Key, out var number) && number > 0 && number <= choices.Count) { await ResolveChoice(choices[number - 1]); return; }
}
else
{
if (args.Key is "Enter" or " " || keyLower == "e") { await ResolveInteraction(); return; }
}
return;
}
if (_screen == Screen.Briefing && args.Key == "Enter") { await BeginPlay(); return; }
if (_screen != Screen.Game) return;
switch (args.Key.ToLowerInvariant())
if (_showMap || _showInventory || _showArchive) { if (args.Key == "Escape") CloseOverlays(); return; }
if (_showPause) { if (args.Key == "Escape") CloseOverlays(); return; }
if (_screen == Screen.Title)
{
case "arrowup": await Move("north"); break; case "arrowdown": await Move("south"); break; case "arrowleft": await Move("west"); break; case "arrowright": await Move("east"); break;
case "e": OpenInteractionSelector(); break; case "m": _showMap = true; break; case "i": _showInventory = true; break; case "l": _showArchive = true; break; case "escape": _showPause = true; break;
if (args.Key is "ArrowDown" or "Down" || keyLower == "s") { do { _menuIndex = (_menuIndex + 1) % 3; } while (_menuIndex == 1 && !Game.HasSave); }
else if (args.Key is "ArrowUp" or "Up" || keyLower == "w") { do { _menuIndex = (_menuIndex - 1 + 3) % 3; } while (_menuIndex == 1 && !Game.HasSave); }
else if (args.Key is "Enter" or " ") { if (_menuIndex == 0) await StartNewGame(); else if (_menuIndex == 1) await ContinueGame(); else await OpenSettings(); }
else if (int.TryParse(args.Key, out var num))
{
if (num == 1) await StartNewGame();
else if (num == 2 && Game.HasSave) await ContinueGame();
else if (num == 3) await OpenSettings();
}
return;
}
if (_screen == Screen.Briefing && args.Key is "Enter" or " ") { await BeginPlay(); return; }
if (_screen == Screen.Death && (args.Key is "Enter" or " " || keyLower == "r")) { await RestoreCheckpoint(); return; }
if (_screen == Screen.Ending && args.Key is "Enter" or "Escape" or " ") { await ReturnToTitle(); return; }
if (_screen != Screen.Game) return;
switch (keyLower)
{
case "w" or "arrowup": await Move("north"); break;
case "s" or "arrowdown": await Move("south"); break;
case "a" or "arrowleft": await Move("west"); break;
case "d" or "arrowright": await Move("east"); break;
case "e": OpenInteractionSelector(); break;
case "m": _showMap = true; break;
case "i": _showInventory = true; break;
case "l": _showArchive = true; break;
case "escape": _showPause = true; break;
}
}
public void Dispose() => Game.Saved -= OnSaved;
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

+2 -2
View File
@@ -19,7 +19,7 @@ kbd { color:var(--cyan); background:none; padding:0; }
@keyframes system-flash { 0%,100% { opacity:0; } 15%,45% { opacity:1; } 30%,65% { opacity:.18; } }
.screen-image { position:absolute; inset:0; min-height:100%; background-position:center; background-size:cover; isolation:isolate; }
.vignette { position:absolute; inset:0; z-index:-1; background:linear-gradient(90deg,rgba(0,4,6,.87) 0%,rgba(0,4,6,.28) 40%,rgba(0,4,6,.15) 65%,rgba(0,4,6,.64) 100%),linear-gradient(0deg,rgba(0,3,5,.82) 0%,transparent 40%,rgba(0,3,5,.3) 100%); }
.loading-screen { height:100%; display:grid; place-items:center; color:var(--cyan); font:500 .8rem 'IBM Plex Mono'; letter-spacing:.35em; animation:pulse 1.6s infinite; }
.loading-screen { height:100%; display:flex; flex-direction:column; align-items:center; justify-content:center; color:var(--cyan); font:500 .8rem 'IBM Plex Mono'; letter-spacing:.35em; animation:pulse 1.6s infinite; }
@keyframes pulse { 50% { opacity:.35; } }
.title-card { position:absolute; left:6vw; top:9vh; }
.title-card h1 { margin:.25rem 0; font-size:clamp(3rem,7vw,7rem); font-weight:300; letter-spacing:.19em; line-height:.95; text-shadow:0 2px 32px #000; }
@@ -53,7 +53,7 @@ kbd { color:var(--cyan); background:none; padding:0; }
.interaction-modal, .overlay-card { width:min(43rem,92vw); max-height:86vh; overflow:auto; padding:2rem; }.terminal-copy { white-space:pre-line; color:#bfe6ea; line-height:1.75; }
.close-button { position:absolute; top:.65rem; right:.65rem; border:0; font-size:1.3rem; padding:.35rem .6rem; }
.choice-list { display:flex; flex-direction:column; gap:.6rem; margin-top:1.5rem; }.choice-list button { text-align:left; }
.action-picker small { display:block; margin-top:1.25rem; color:var(--muted); letter-spacing:.12em; }
.action-picker small, .interaction-modal small { display:block; margin-top:1.25rem; color:var(--muted); letter-spacing:.12em; }
.map-card { width:min(62rem,94vw); }.map-grid { display:grid; grid-template-columns:repeat(9,minmax(2.5rem,1fr)); grid-template-rows:repeat(4,3.6rem); gap:.35rem; margin:2rem 0; }
.map-cell { display:grid; place-items:center; border:1px solid rgba(158,239,255,.1); color:#44565a; font:1rem 'IBM Plex Mono'; }.map-cell.visited { color:var(--cyan); background:rgba(65,213,240,.06); border-color:var(--line); }.map-cell.current { color:#021014; background:var(--cyan); box-shadow:0 0 24px rgba(66,216,244,.4); }
.inventory-card ul { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:.65rem; list-style:none; margin:1.5rem 0 0; padding:0; }.inventory-card li { padding:1rem; border:1px solid var(--line); }.inventory-card li small { display:block; color:var(--muted); font-size:.58rem; letter-spacing:.16em; }.inventory-card li strong { display:block; margin:.3rem 0; color:var(--cyan); font-weight:500; letter-spacing:.06em; }.inventory-card li p { margin:.25rem 0 0; color:#b8c8cb; font-size:.78rem; line-height:1.5; }
+57 -6
View File
@@ -4,7 +4,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="theme-color" content="#03080a" />
<meta name="theme-color" content="#020507" />
<title>NullDepth</title>
<base href="/" />
<link rel="preload" id="webassembly" />
@@ -15,15 +15,66 @@
<link rel="manifest" href="manifest.webmanifest" />
<link href="NullDepth.styles.css" rel="stylesheet" />
<script type="importmap"></script>
<style>
/* Immediate loader styles to prevent FOUC */
html, body { width: 100%; height: 100%; margin: 0; background: #020507; overflow: hidden; }
.wasm-loader { position: fixed; inset: 0; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: #020507; color: #e9f5f6; font-family: 'IBM Plex Mono', Consolas, monospace; overflow: hidden; z-index: 1000; }
.wasm-loader-bg { position: absolute; inset: 0; background: radial-gradient(circle at 50% 42%, rgba(15, 45, 58, 0.45), #020507 65%), linear-gradient(rgba(158, 239, 255, 0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(158, 239, 255, 0.03) 1px, transparent 1px); background-size: 100% 100%, 32px 32px, 32px 32px; pointer-events: none; }
.wasm-loader-content { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; text-align: center; padding: 2rem; max-width: 90vw; }
.wasm-logo-wrapper { position: relative; width: 150px; height: 150px; display: grid; place-items: center; margin-bottom: 1.8rem; }
.wasm-logo { width: 112px; height: 112px; filter: drop-shadow(0 0 20px rgba(66, 216, 244, 0.75)) drop-shadow(0 0 45px rgba(66, 216, 244, 0.35)); animation: wasm-logo-breathe 3s ease-in-out infinite alternate; object-fit: contain; }
@keyframes wasm-logo-breathe { 0% { transform: scale(0.96); filter: drop-shadow(0 0 16px rgba(66, 216, 244, 0.55)) drop-shadow(0 0 35px rgba(66, 216, 244, 0.25)); } 100% { transform: scale(1.04); filter: drop-shadow(0 0 30px rgba(66, 216, 244, 0.95)) drop-shadow(0 0 65px rgba(66, 216, 244, 0.5)); } }
.wasm-scanner-ring { position: absolute; border-radius: 50%; pointer-events: none; }
.ring-outer { inset: -10px; border: 1px dashed rgba(158, 239, 255, 0.4); animation: wasm-spin 16s linear infinite; }
.ring-inner { inset: 6px; border: 1px dotted rgba(66, 216, 244, 0.35); animation: wasm-spin-reverse 10s linear infinite; }
@keyframes wasm-spin { to { transform: rotate(360deg); } }
@keyframes wasm-spin-reverse { to { transform: rotate(-360deg); } }
.wasm-title-block { margin-bottom: 1.8rem; }
.wasm-eyebrow { margin: 0 0 0.4rem; color: #9eefff; font-size: 0.7rem; letter-spacing: 0.28em; text-transform: uppercase; }
.wasm-title { margin: 0.15rem 0 0.4rem; font-family: Inter, Segoe UI, sans-serif; font-size: clamp(2rem, 5vw, 3.2rem); font-weight: 300; letter-spacing: 0.22em; line-height: 1; color: #ffffff; text-shadow: 0 0 24px rgba(158, 239, 255, 0.4); }
.wasm-subtitle { margin: 0; color: #8fa7ac; font-size: 0.68rem; letter-spacing: 0.3em; text-transform: uppercase; }
.wasm-progress-box { width: min(24rem, 82vw); margin-bottom: 1.8rem; }
.wasm-progress-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.55rem; font-size: 0.66rem; letter-spacing: 0.15em; color: #8fa7ac; }
.wasm-status-text { color: #9eefff; }
.wasm-percentage { color: #ffffff; font-weight: 500; }
.wasm-percentage:empty::after, .loading-progress-text:empty::after { content: var(--blazor-load-percentage-text, "INITIALIZING..."); }
.wasm-progress-track { width: 100%; height: 6px; background: rgba(4, 16, 20, 0.9); border: 1px solid rgba(158, 239, 255, 0.3); overflow: hidden; position: relative; }
.wasm-progress-fill { height: 100%; width: var(--blazor-load-percentage, 0%); min-width: 4%; background: linear-gradient(90deg, #0d829d, #9eefff, #ffffff); box-shadow: 0 0 12px rgba(66, 216, 244, 0.85); transition: width 0.18s ease-out; }
.wasm-telemetry { display: flex; gap: 1rem; font-size: 0.58rem; letter-spacing: 0.18em; color: rgba(143, 167, 172, 0.65); flex-wrap: wrap; justify-content: center; }
</style>
</head>
<body>
<div id="app">
<svg class="loading-progress">
<circle r="40%" cx="50%" cy="50%" />
<circle r="40%" cx="50%" cy="50%" />
</svg>
<div class="loading-progress-text"></div>
<div class="wasm-loader" role="status" aria-label="Loading NULL DEPTH">
<div class="wasm-loader-bg"></div>
<div class="wasm-loader-content">
<div class="wasm-logo-wrapper">
<div class="wasm-scanner-ring ring-outer"></div>
<div class="wasm-scanner-ring ring-inner"></div>
<img class="wasm-logo" src="logo.png" alt="NULL DEPTH Logo" width="112" height="112" />
</div>
<div class="wasm-title-block">
<p class="wasm-eyebrow">FACILITY 03 // SUBLEVEL 03</p>
<h1 class="wasm-title">NULL DEPTH</h1>
<p class="wasm-subtitle">INITIALIZING SUBSYSTEM MATRIX</p>
</div>
<div class="wasm-progress-box">
<div class="wasm-progress-header">
<span class="wasm-status-text">SYSTEM INTEGRITY</span>
<span class="wasm-percentage loading-progress-text"></span>
</div>
<div class="wasm-progress-track">
<div class="wasm-progress-fill loading-progress"></div>
</div>
</div>
<div class="wasm-telemetry">
<span>[NET_ID: ISOLATED]</span>
<span>[SECURITY: ALPHA]</span>
<span>[TERMINAL: BOOT]</span>
</div>
</div>
</div>
</div>
<div id="blazor-error-ui">
+1 -1
View File
@@ -1,5 +1,5 @@
{
"menu.newGame": "NEW GAME", "menu.continue": "CONTINUE", "menu.settings": "SETTINGS", "menu.controlsHint": "↑ ↓ SELECT ENTER CONFIRM",
"menu.newGame": "NEW GAME", "menu.continue": "CONTINUE", "menu.settings": "SETTINGS", "menu.controlsHint": "↑ ↓ / W S SELECT ENTER CONFIRM",
"common.continue": "ENTER — CONTINUE", "common.confirm": "CONFIRM", "common.cancel": "CANCEL", "common.back": "BACK", "common.mainMenu": "MAIN MENU",
"briefing.header": "CONTRACT // 7841-B", "briefing.clientLabel": "CLIENT", "briefing.siteLabel": "SITE", "briefing.assignmentLabel": "ASSIGNMENT", "briefing.assignment": "CENTRAL CORE DIAGNOSTICS", "briefing.compensationLabel": "COMPENSATION", "briefing.infoLabel": "ADDITIONAL INFORMATION", "briefing.none": "NONE", "briefing.story": "Elias Venn accepted the contract at 04:17. Five hours later, he is standing at the entrance to Facility 03. No further message has arrived from the client.",
"game.autosave": "AUTOSAVE // ONLINE", "game.autosaveSaving": "AUTOSAVE // SAVING", "game.autosaveSaved": "AUTOSAVE // SAVED", "game.interact": "INTERACT", "game.map": "MAP", "game.inventory": "INVENTORY", "game.archive": "ARCHIVE", "game.pause": "PAUSE", "game.exit.locked": "Access is blocked.",
+1 -1
View File
@@ -1,5 +1,5 @@
{
"menu.newGame": "NOVÁ HRA", "menu.continue": "POKRAČOVAŤ", "menu.settings": "NASTAVENIA", "menu.controlsHint": "↑ ↓ VÝBER ENTER POTVRDIŤ",
"menu.newGame": "NOVÁ HRA", "menu.continue": "POKRAČOVAŤ", "menu.settings": "NASTAVENIA", "menu.controlsHint": "↑ ↓ / W S VÝBER ENTER POTVRDIŤ",
"common.continue": "ENTER — POKRAČOVAŤ", "common.confirm": "POTVRDIŤ", "common.cancel": "ZRUŠIŤ", "common.back": "SPÄŤ", "common.mainMenu": "HLAVNÉ MENU",
"briefing.header": "ZMLUVA // 7841-B", "briefing.clientLabel": "KLIENT", "briefing.siteLabel": "LOKALITA", "briefing.assignmentLabel": "ÚLOHA", "briefing.assignment": "DIAGNOSTIKA CENTRÁLNEHO JADRA", "briefing.compensationLabel": "ODMENA", "briefing.infoLabel": "DODATOČNÉ INFORMÁCIE", "briefing.none": "ŽIADNE", "briefing.story": "Elias Venn prijal zákazku o 04:17. O päť hodín neskôr stojí pri vstupe do Facility 03. Od klienta odvtedy neprišla žiadna ďalšia správa.",
"game.autosave": "AUTOSAVE // ONLINE", "game.autosaveSaving": "AUTOSAVE // UKLADÁM", "game.autosaveSaved": "AUTOSAVE // ULOŽENÉ", "game.interact": "INTERAKCIA", "game.map": "MAPA", "game.inventory": "INVENTÁR", "game.archive": "ARCHÍV", "game.pause": "PAUZA", "game.exit.locked": "Prístup je zablokovaný.",
Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB