Consolidate shared UI assets

Move common logo and controller glyphs into `ui/views/CommonwealthOnline/shared/` and update the pause menu, main menu, and browser glyph loader to use the shared paths. Also add a sync script and update deploy/staging scripts to copy controller icons once into the shared folder.
This commit is contained in:
2026-07-05 22:46:38 +12:00
parent 8acdb4f555
commit c3f5afe7f6
15 changed files with 1048 additions and 26 deletions
@@ -0,0 +1,109 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Commonwealth Online — Main Menu</title>
<link rel="stylesheet" href="styles.css">
<link rel="stylesheet" href="../settings/settings.css">
</head>
<body>
<div class="main-screen" id="mainScreen">
<!-- Title-screen scenic background -->
<div class="scene-layer" aria-hidden="true"></div>
<div class="scene-overlay" aria-hidden="true"></div>
<!-- CRT / HUD texture overlays -->
<div class="screen-effects" aria-hidden="true"></div>
<!-- Left main menu panel -->
<aside class="left-panel">
<img
class="brand-logo"
src="../shared/logo.svg"
alt="Commonwealth Online"
width="220"
height="54"
>
<nav class="menu" id="menu" aria-label="Main menu">
<button type="button" class="menu-item" data-index="0" data-action="multiplayer">
<span class="menu-item__label">MULTIPLAYER</span>
<span class="menu-item__bar" aria-hidden="true"></span>
</button>
<button type="button" class="menu-item" data-index="1" data-action="creations">
<span class="menu-item__label">CREATIONS</span>
<span class="menu-item__bar" aria-hidden="true"></span>
</button>
<button type="button" class="menu-item" data-index="2" data-action="settings">
<span class="menu-item__label">SETTINGS</span>
<span class="menu-item__bar" aria-hidden="true"></span>
</button>
<button type="button" class="menu-item" data-index="3" data-action="help">
<span class="menu-item__label">HELP</span>
<span class="menu-item__bar" aria-hidden="true"></span>
</button>
<button type="button" class="menu-item" data-index="4" data-action="quit">
<span class="menu-item__label">QUIT</span>
<span class="menu-item__bar" aria-hidden="true"></span>
</button>
</nav>
</aside>
<!-- Settings view (content mounted by ../settings/settings.js) -->
<section class="settings-view" id="settingsPanel" aria-label="Settings" hidden></section>
<!-- Bottom controller prompts (main menu) -->
<footer class="prompt-bar" id="mainPromptBar" aria-label="Controller prompts">
<div class="prompt">
<span class="prompt__glyph prompt__glyph--icon" aria-hidden="true">
<img class="prompt__glyph-img" data-glyph-src="../shared/icons/Xbox/T_X_A_White_Alt.png" src="../shared/icons/Xbox/T_X_A_White_Alt.png" alt="" draggable="false">
</span>
<span class="prompt__label">SELECT</span>
</div>
<div class="prompt">
<span class="prompt__glyph prompt__glyph--icon" aria-hidden="true">
<img class="prompt__glyph-img" data-glyph-src="../shared/icons/Xbox/T_X_B_White_Alt.png" src="../shared/icons/Xbox/T_X_B_White_Alt.png" alt="" draggable="false">
</span>
<span class="prompt__label">BACK</span>
</div>
</footer>
<!-- Settings mode prompt bar -->
<footer class="prompt-bar prompt-bar--settings" id="settingsPromptBar" aria-label="Settings prompts" hidden>
<div class="prompt" data-prompt="move">
<span class="prompt__glyph prompt__glyph--text" aria-hidden="true">↑↓</span>
<span class="prompt__label">MOVE</span>
</div>
<div class="prompt" data-prompt="change">
<span class="prompt__glyph prompt__glyph--text" aria-hidden="true">←→</span>
<span class="prompt__label">CHANGE</span>
</div>
<div class="prompt" data-prompt="select">
<span class="prompt__glyph prompt__glyph--icon" aria-hidden="true">
<img class="prompt__glyph-img" data-glyph-src="../shared/icons/Xbox/T_X_A_White_Alt.png" src="../shared/icons/Xbox/T_X_A_White_Alt.png" alt="" draggable="false">
</span>
<span class="prompt__label">SELECT</span>
</div>
<div class="prompt" data-prompt="back">
<span class="prompt__glyph prompt__glyph--icon" aria-hidden="true">
<img class="prompt__glyph-img" data-glyph-src="../shared/icons/Xbox/T_X_B_White_Alt.png" src="../shared/icons/Xbox/T_X_B_White_Alt.png" alt="" draggable="false">
</span>
<span class="prompt__label">BACK</span>
</div>
<div class="prompt" data-prompt="tab">
<span class="prompt__glyph prompt__glyph--text" aria-hidden="true">TAB</span>
<span class="prompt__label">SWITCH FOCUS</span>
</div>
</footer>
</div>
<script src="../settings/settings-data.js"></script>
<script src="../settings/settings.js"></script>
<script src="script.js"></script>
</body>
</html>
@@ -0,0 +1,399 @@
(function () {
"use strict";
// ── C++ / F4SE bridge placeholders ─────────────────────────────
window.CommonwealthOnlineUI = {
openGameSettings: function () {
console.log("[CO UI] Request open vanilla Fallout 4 SettingsMenu");
},
setMultiplayerSetting: function (key, value) {
console.log("[CO UI] Multiplayer setting changed:", key, value);
},
onBack: function () {
console.log("[CO UI] Back requested from main menu");
},
onOpenView: function (viewName) {
console.log("[CO UI] Open view:", viewName);
}
};
// ── Compute UI scale ───────────────────────────────────────────
function updateScale() {
var MIN_SCALE = 0.5;
var MAX_SCALE = 1.6;
var BASELINE_WIDTH = 1920;
var BASELINE_HEIGHT = 1080;
var scale = Math.min(
window.innerWidth / BASELINE_WIDTH,
window.innerHeight / BASELINE_HEIGHT
);
scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale));
document.documentElement.style.setProperty("--co-ui-scale", String(scale));
}
updateScale();
window.addEventListener("resize", updateScale);
// ── Tint Xbox prompt glyphs to menu amber ──────────────────────
var GLYPH_WHITE_THRESHOLD = 200;
var GLYPH_BLACK_THRESHOLD = 40;
var glyphTintCache = {};
function getAmberTint() {
var style = getComputedStyle(document.documentElement);
var amber = style.getPropertyValue("--co-amber").trim() || "#c9a84a";
var hex = amber.replace("#", "");
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
return {
r: parseInt(hex.slice(0, 2), 16) || 201,
g: parseInt(hex.slice(2, 4), 16) || 168,
b: parseInt(hex.slice(4, 6), 16) || 74
};
}
function classifyGlyphPixel(r, g, b) {
if (r >= GLYPH_WHITE_THRESHOLD && g >= GLYPH_WHITE_THRESHOLD && b >= GLYPH_WHITE_THRESHOLD) {
return "white";
}
if (r <= GLYPH_BLACK_THRESHOLD && g <= GLYPH_BLACK_THRESHOLD && b <= GLYPH_BLACK_THRESHOLD) {
return "black";
}
return "edge";
}
function tintGlyphImageData(imageData, color) {
var data = imageData.data;
for (var i = 0; i < data.length; i += 4) {
if (data[i + 3] < 4) {
data[i + 3] = 0;
continue;
}
var kind = classifyGlyphPixel(data[i], data[i + 1], data[i + 2]);
if (kind === "white") {
data[i] = color.r;
data[i + 1] = color.g;
data[i + 2] = color.b;
} else if (kind === "black") {
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;
} else {
var lum = (data[i] + data[i + 1] + data[i + 2]) / (3 * 255);
data[i] = Math.round(lum * color.r);
data[i + 1] = Math.round(lum * color.g);
data[i + 2] = Math.round(lum * color.b);
}
}
return imageData;
}
function tintGlyphImage(url, color, done) {
var key = url + "|" + color.r + "," + color.g + "," + color.b;
if (glyphTintCache[key]) {
done(glyphTintCache[key]);
return;
}
var img = new Image();
img.onload = function () {
var canvas = document.createElement("canvas");
canvas.width = img.naturalWidth;
canvas.height = img.naturalHeight;
var ctx = canvas.getContext("2d");
if (!ctx) {
done(null);
return;
}
ctx.drawImage(img, 0, 0);
try {
ctx.putImageData(
tintGlyphImageData(ctx.getImageData(0, 0, canvas.width, canvas.height), color),
0,
0
);
} catch (err) {
done(null);
return;
}
var dataUrl = canvas.toDataURL("image/png");
glyphTintCache[key] = dataUrl;
done(dataUrl);
};
img.onerror = function () {
done(null);
};
img.src = url;
}
function hydratePromptGlyphs() {
var color = getAmberTint();
var imgs = document.querySelectorAll(".prompt__glyph-img[data-glyph-src]");
for (var i = 0; i < imgs.length; i++) {
(function (img) {
var src = img.getAttribute("data-glyph-src");
if (!src) {
return;
}
tintGlyphImage(src, color, function (dataUrl) {
if (dataUrl) {
img.src = dataUrl;
}
});
})(imgs[i]);
}
}
hydratePromptGlyphs();
// ── DOM refs ───────────────────────────────────────────────────
var mainScreen = document.getElementById("mainScreen");
var menu = document.getElementById("menu");
var settingsPanel = document.getElementById("settingsPanel");
var mainPromptBar = document.getElementById("mainPromptBar");
var settingsPromptBar = document.getElementById("settingsPromptBar");
if (!menu || !settingsPanel || !window.CO_Settings) {
return;
}
var settingsController = null;
var items = Array.prototype.slice.call(menu.querySelectorAll(".menu-item"));
var SETTINGS_INDEX = 2;
// viewMode: "menu" | "settings"
var viewMode = "menu";
var selectedIndex = -1;
var SETTINGS_TRANSITION_MS = 220;
var settingsHideFallbackId = 0;
var settingsHideOnTransitionEnd = null;
// ── Main menu selection ────────────────────────────────────────
function setSelected(index) {
if (index >= items.length) {
return;
}
selectedIndex = index < 0 ? -1 : index;
items.forEach(function (item, i) {
var isSelected = i === selectedIndex;
item.classList.toggle("is-selected", isSelected);
item.setAttribute("aria-selected", isSelected ? "true" : "false");
item.tabIndex = isSelected ? 0 : -1;
});
}
function moveSelection(delta) {
var next = selectedIndex + delta;
if (selectedIndex < 0) {
next = delta > 0 ? 0 : items.length - 1;
} else if (next < 0) {
next = items.length - 1;
} else if (next >= items.length) {
next = 0;
}
// Skip disabled items
var guard = 0;
while (items[next] && items[next].classList.contains("is-disabled") && guard < items.length) {
next += delta > 0 ? 1 : -1;
if (next < 0) {
next = items.length - 1;
} else if (next >= items.length) {
next = 0;
}
guard += 1;
}
setSelected(next);
}
function activateSelected() {
var item = items[selectedIndex];
if (!item || item.classList.contains("is-disabled")) {
return;
}
var action = item.getAttribute("data-action");
console.log("[CO Main Menu] Selected:", action);
if (action === "settings") {
enterSettingsMode();
} else {
window.CommonwealthOnlineUI.onOpenView(action);
if (action !== "quit") {
setSelected(-1);
}
}
}
items.forEach(function (item, index) {
item.addEventListener("click", function () {
if (viewMode === "settings") {
if (index === SETTINGS_INDEX) {
return;
}
exitSettingsMode();
}
if (item.classList.contains("is-disabled")) {
return;
}
setSelected(index);
activateSelected();
});
});
// ── View mode transitions ──────────────────────────────────────
function cancelSettingsPanelHide() {
if (settingsHideFallbackId) {
window.clearTimeout(settingsHideFallbackId);
settingsHideFallbackId = 0;
}
if (settingsHideOnTransitionEnd) {
settingsPanel.removeEventListener("transitionend", settingsHideOnTransitionEnd);
settingsHideOnTransitionEnd = null;
}
}
function showSettingsPanelAnimated() {
cancelSettingsPanelHide();
if (mainScreen) {
mainScreen.classList.add("is-settings-mode");
}
settingsPanel.hidden = false;
settingsPanel.classList.remove("is-open");
void settingsPanel.offsetWidth;
settingsPanel.classList.add("is-open");
}
function hideSettingsPanelAnimated(done) {
if (settingsPanel.hidden) {
if (done) {
done();
}
return;
}
cancelSettingsPanelHide();
settingsPanel.classList.remove("is-open");
var completed = false;
function finishHide() {
if (completed) {
return;
}
completed = true;
cancelSettingsPanelHide();
if (viewMode === "settings" || settingsPanel.classList.contains("is-open")) {
if (done) {
done();
}
return;
}
if (mainScreen) {
mainScreen.classList.remove("is-settings-mode");
}
settingsPanel.hidden = true;
if (done) {
done();
}
}
settingsHideOnTransitionEnd = function (event) {
if (event.target !== settingsPanel || event.propertyName !== "opacity") {
return;
}
finishHide();
};
settingsPanel.addEventListener("transitionend", settingsHideOnTransitionEnd);
settingsHideFallbackId = window.setTimeout(finishHide, SETTINGS_TRANSITION_MS + 80);
}
function enterSettingsMode() {
viewMode = "settings";
console.log("[CO Main Menu] Entering settings mode");
window.CommonwealthOnlineUI.onOpenView("settings");
setSelected(SETTINGS_INDEX);
showSettingsPanelAnimated();
if (mainPromptBar) {
mainPromptBar.hidden = true;
}
settingsController.show();
}
function exitSettingsMode() {
if (viewMode !== "settings") {
return;
}
viewMode = "menu";
console.log("[CO Main Menu] Exiting settings mode");
window.CommonwealthOnlineUI.onBack();
settingsController.hide();
hideSettingsPanelAnimated(function () {
if (mainPromptBar) {
mainPromptBar.hidden = false;
}
setSelected(SETTINGS_INDEX);
});
}
settingsController = window.CO_Settings.create({
mount: settingsPanel,
promptBar: settingsPromptBar,
bridge: window.CommonwealthOnlineUI,
layout: "embedded",
onBack: function () {
exitSettingsMode();
}
});
// ── Keyboard navigation ────────────────────────────────────────
function handleMenuKeydown(event) {
switch (event.key) {
case "ArrowUp":
event.preventDefault();
moveSelection(-1);
break;
case "ArrowDown":
event.preventDefault();
moveSelection(1);
break;
case "Enter":
case " ":
event.preventDefault();
activateSelected();
break;
case "Escape":
event.preventDefault();
console.log("[CO Main Menu] Back");
window.CommonwealthOnlineUI.onBack();
break;
default:
break;
}
}
document.addEventListener("keydown", function (event) {
if (viewMode === "settings") {
settingsController.handleKeydown(event);
return;
}
handleMenuKeydown(event);
});
})();
@@ -0,0 +1,28 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Commonwealth Online — Main Menu Shell</title>
<link rel="stylesheet" href="styles.css">
<style>
/* Shell-only: left panel is layout chrome with no logo or menu content */
.left-panel--shell {
pointer-events: none;
}
</style>
</head>
<body>
<div class="main-screen" id="mainScreen">
<!-- Title-screen scenic background -->
<div class="scene-layer" aria-hidden="true"></div>
<div class="scene-overlay" aria-hidden="true"></div>
<!-- CRT / HUD texture overlays -->
<div class="screen-effects" aria-hidden="true"></div>
<!-- Left panel chrome (no logo, no menu items) -->
<aside class="left-panel left-panel--shell" aria-hidden="true"></aside>
</div>
</body>
</html>
@@ -0,0 +1,408 @@
/* Commonwealth Online — main menu concept (1920×1080 baseline) */
@font-face {
font-family: "Futura PT Demibold";
src: url("../../fonts/futura-pt-demibold.otf") format("opentype");
font-weight: 600;
font-display: swap;
}
:root {
--co-ui-scale: 1;
--co-black: #0a0c0a;
--co-panel-bg: rgba(8, 14, 10, 0.72);
--co-panel-fade: rgba(8, 14, 10, 0);
--co-green: #3ecf4a;
--co-green-dim: rgba(62, 207, 74, 0.35);
--co-amber: #c9a84a;
--co-amber-muted: rgba(201, 168, 74, 0.55);
--co-text-pale: #d8ddd0;
--co-text-muted: #9aa898;
--co-select-yellow: #c4a84b;
--co-select-yellow-bright: #d4bc62;
--co-select-text: #1a1c18;
--co-border: rgba(201, 168, 74, 0.45);
--co-font: "Futura PT Demibold", "Roboto Condensed", "Bahnschrift", "Arial Narrow", Arial, sans-serif;
--co-transition: 120ms ease-out;
--co-panel-width: 28%;
--co-menu-size: calc(26px * var(--co-ui-scale));
--co-menu-gap: calc(6px * var(--co-ui-scale));
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
width: 100vw;
height: 100vh;
overflow: hidden;
font-family: var(--co-font);
font-weight: 600;
color: var(--co-text-pale);
background: var(--co-black);
user-select: none;
-webkit-font-smoothing: antialiased;
}
/* ── Root layout ─────────────────────────────────────────────── */
.main-screen {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
/* ── Title-screen scenic background ──────────────────────────── */
.scene-layer {
position: absolute;
inset: 0;
z-index: 1;
background:
radial-gradient(
ellipse 80% 60% at 72% 42%,
rgba(62, 207, 74, 0.08) 0%,
transparent 55%
),
radial-gradient(
ellipse 55% 45% at 35% 70%,
rgba(201, 168, 74, 0.06) 0%,
transparent 50%
),
linear-gradient(
165deg,
#0b120d 0%,
#141a12 28%,
#1a2218 48%,
#121810 72%,
#080c08 100%
);
filter: brightness(0.82) contrast(1.05) saturate(0.65);
}
.scene-overlay {
position: absolute;
inset: 0;
z-index: 2;
pointer-events: none;
background:
linear-gradient(
90deg,
rgba(6, 10, 8, 0.82) 0%,
rgba(6, 10, 8, 0.38) 28%,
rgba(6, 10, 8, 0.12) 58%,
rgba(6, 10, 8, 0.22) 100%
),
rgba(4, 8, 6, 0.15);
}
/* ── Screen effects: vignette, scanlines, HUD grid ─────────── */
.screen-effects {
position: absolute;
inset: 0;
z-index: 4;
pointer-events: none;
}
.screen-effects::before {
content: "";
position: absolute;
inset: 0;
background:
radial-gradient(
ellipse at center,
transparent 40%,
rgba(0, 0, 0, 0.55) 100%
);
opacity: 0.9;
}
.screen-effects::after {
content: "";
position: absolute;
inset: 0;
background:
repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0, 0, 0, 0.12) 2px,
rgba(0, 0, 0, 0.12) 3px
),
repeating-linear-gradient(
90deg,
transparent,
transparent 79px,
rgba(62, 207, 74, 0.03) 79px,
rgba(62, 207, 74, 0.03) 80px
),
repeating-linear-gradient(
0deg,
transparent,
transparent 79px,
rgba(62, 207, 74, 0.03) 79px,
rgba(62, 207, 74, 0.03) 80px
);
opacity: 0.65;
mix-blend-mode: overlay;
}
.main-screen::after {
content: "";
position: absolute;
inset: 0;
z-index: 20;
pointer-events: none;
background:
url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.08'/%3E%3C/svg%3E");
opacity: 0.35;
}
/* ── Left panel ──────────────────────────────────────────────── */
.left-panel {
position: absolute;
top: 0;
left: 0;
bottom: 0;
z-index: 10;
width: var(--co-panel-width);
min-width: calc(280px * var(--co-ui-scale));
max-width: 36%;
display: flex;
flex-direction: column;
padding:
calc(28px * var(--co-ui-scale))
calc(32px * var(--co-ui-scale))
calc(72px * var(--co-ui-scale))
calc(28px * var(--co-ui-scale));
background:
linear-gradient(
90deg,
var(--co-panel-bg) 0%,
rgba(8, 14, 10, 0.55) 70%,
var(--co-panel-fade) 100%
);
}
.brand-logo {
width: calc(200px * var(--co-ui-scale));
height: auto;
margin-bottom: calc(36px * var(--co-ui-scale));
opacity: 0.88;
filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.5));
}
/* ── Menu list ───────────────────────────────────────────────── */
.menu {
display: flex;
flex-direction: column;
gap: var(--co-menu-gap);
flex: 1;
}
.menu-item {
position: relative;
display: flex;
align-items: center;
gap: calc(14px * var(--co-ui-scale));
width: 100%;
padding:
calc(10px * var(--co-ui-scale))
calc(12px * var(--co-ui-scale));
border: none;
background: transparent;
color: var(--co-text-muted);
font-family: inherit;
font-size: var(--co-menu-size);
font-weight: 700;
letter-spacing: 0.14em;
text-align: left;
cursor: pointer;
transition:
color var(--co-transition),
transform var(--co-transition);
outline: none;
}
.menu-item__label {
position: relative;
z-index: 2;
}
.menu-item__bar {
position: absolute;
left: calc(-28px * var(--co-ui-scale));
top: 50%;
transform: translateY(-50%) scaleX(0);
transform-origin: left center;
width: calc(100% + 80px * var(--co-ui-scale));
height: calc(100% + 4px);
background: linear-gradient(
90deg,
var(--co-select-yellow) 0%,
var(--co-select-yellow-bright) 85%,
#e0cc6e 100%
);
clip-path: polygon(
0 0,
calc(100% - 18px) 0,
100% 50%,
calc(100% - 18px) 100%,
0 100%
);
opacity: 0;
transition:
opacity var(--co-transition),
transform var(--co-transition);
z-index: 1;
box-shadow: 0 0 12px rgba(196, 168, 75, 0.25);
}
.menu-item:hover {
color: var(--co-text-pale);
}
.menu-item:hover .menu-item__bar {
opacity: 1;
transform: translateY(-50%) scaleX(1);
}
.menu-item:focus-visible {
color: var(--co-text-pale);
outline: 1px solid var(--co-green-dim);
outline-offset: 2px;
}
.menu-item.is-selected {
color: var(--co-select-text);
}
.menu-item.is-selected .menu-item__bar {
opacity: 1;
transform: translateY(-50%) scaleX(1);
}
.menu-item.is-disabled {
opacity: 0.38;
cursor: default;
pointer-events: none;
}
/* ── Bottom prompt bar ───────────────────────────────────────── */
.prompt-bar {
position: absolute;
left: 0;
right: 0;
bottom: 0;
z-index: 10;
display: flex;
align-items: center;
justify-content: center;
gap: calc(40px * var(--co-ui-scale));
padding:
calc(10px * var(--co-ui-scale))
calc(24px * var(--co-ui-scale));
background: linear-gradient(
180deg,
transparent 0%,
rgba(6, 10, 8, 0.75) 30%,
rgba(6, 10, 8, 0.88) 100%
);
border-top: 1px solid rgba(201, 168, 74, 0.15);
transition: opacity 200ms ease-out, visibility 200ms ease-out;
}
.prompt-bar[hidden] {
opacity: 0;
visibility: hidden;
}
.prompt {
display: flex;
align-items: center;
gap: calc(8px * var(--co-ui-scale));
}
.prompt__glyph {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: calc(22px * var(--co-ui-scale));
height: calc(22px * var(--co-ui-scale));
font-size: calc(11px * var(--co-ui-scale));
font-weight: 700;
color: var(--co-amber);
border: 1px solid var(--co-amber-muted);
border-radius: 50%;
background: rgba(0, 0, 0, 0.35);
line-height: 1;
}
.prompt__glyph--icon {
border: none;
border-radius: 0;
background: transparent;
min-width: calc(28px * var(--co-ui-scale));
width: calc(28px * var(--co-ui-scale));
height: calc(28px * var(--co-ui-scale));
padding: 0;
}
.prompt__glyph-img {
width: 100%;
height: 100%;
display: block;
pointer-events: none;
user-select: none;
}
.prompt__label {
font-size: calc(11px * var(--co-ui-scale));
font-weight: 600;
letter-spacing: 0.16em;
color: var(--co-text-pale);
opacity: 0.85;
}
/* Settings mode: keep main nav, dim background more */
.main-screen.is-settings-mode .left-panel {
overflow: hidden;
background:
linear-gradient(
90deg,
rgba(8, 14, 10, 0.9) 0%,
rgba(8, 14, 10, 0.78) 65%,
rgba(8, 14, 10, 0.15) 100%
);
}
.main-screen.is-settings-mode .menu-item__bar {
width: calc(100% + 28px * var(--co-ui-scale));
}
.main-screen.is-settings-mode .scene-overlay {
background:
linear-gradient(
90deg,
rgba(6, 10, 8, 0.88) 0%,
rgba(6, 10, 8, 0.55) 24%,
rgba(6, 10, 8, 0.4) 55%,
rgba(6, 10, 8, 0.48) 100%
),
rgba(4, 8, 6, 0.32);
}