Add quit confirmation to main menu
Implement a quit confirmation dialog that appears when the QUIT button is selected on the main menu. The dialog displays 'EXIT GAME?' with YES/NO options. YES sends a coAction quit request to the plugin, which hides the overlay, disconnects any active server session, and sets RE::Main::quitGame to exit the game. NO returns to the main menu. Includes full keyboard (arrow keys, Enter, Escape), gamepad (dpad, A/B buttons), and mouse support. Default selection is NO.
This commit is contained in:
@@ -9,6 +9,10 @@ For testing notes, milestone summaries, known issues, and next steps, see [`docs
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Main menu QUIT button now exits Fallout 4 via the engine `quitGame` flag (JS `coAction` bridge + C++ game-thread handler).
|
||||||
|
- Main menu quit confirmation dialog (`EXIT GAME?` with YES to quit and NO to return).
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Server browser UI restyled to match the main menu and settings panels: Futura PT Demibold typography, amber/green palette, yellow selection bars, and shared panel chrome (replaces the old bright-green HUD terminal look and SVG border strips).
|
- Server browser UI restyled to match the main menu and settings panels: Futura PT Demibold typography, amber/green palette, yellow selection bars, and shared panel chrome (replaces the old bright-green HUD terminal look and SVG border strips).
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
@@ -9,6 +9,62 @@ failed experiments, successful tests, and next steps.
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-07-07 - Main Menu Quit Confirmation
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
Selecting QUIT on the custom main menu opens an `EXIT GAME?` confirmation dialog. YES quits to desktop; NO returns to the menu.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
- `ui/views/CommonwealthOnline/main-menu/index.html`
|
||||||
|
- `ui/views/CommonwealthOnline/main-menu/styles.css`
|
||||||
|
- `ui/views/CommonwealthOnline/main-menu/script.js`
|
||||||
|
- `changelog.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
- Added centered quit-confirm modal with YES/NO options and shared menu selection styling.
|
||||||
|
- New `quitConfirm` view mode with keyboard, gamepad, and mouse support; B/Escape cancels like vanilla.
|
||||||
|
- YES sends the `coAction` quit request to the plugin; NO cancels. Default selection is NO.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
- Not run locally (requires Fallout 4 + built plugin).
|
||||||
|
- Expected: QUIT → `EXIT GAME?` appears; NO/B returns to menu; YES exits game.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
- None currently known.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
- None currently known.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-07-07 - Main Menu Quit Button
|
||||||
|
|
||||||
|
### Summary
|
||||||
|
The custom main menu QUIT item now sends a `coAction` to the plugin, which hides the overlay, disconnects any active server session, and sets `RE::Main::quitGame` on the game thread so Fallout 4 exits to desktop.
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
- `ui/views/CommonwealthOnline/main-menu/script.js`
|
||||||
|
- `plugin/src/F4TPrismaUI.cpp`
|
||||||
|
- `changelog.md`
|
||||||
|
- `docs/dev-log.md`
|
||||||
|
|
||||||
|
### Details
|
||||||
|
- JS `activateSelected()` routes `quit` through `sendCoAction({ action: "quit" })` instead of only logging via `onOpenView`.
|
||||||
|
- C++ `RequestQuitFromMainMenu()` hides the PrismaUI overlay, calls `DisconnectFromLocalServer()`, and queues `main->quitGame = true` via `F4SE::GetTaskInterface()->AddTask`.
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
- Not run locally (requires Fallout 4 + built plugin).
|
||||||
|
- Expected: select QUIT on title screen → game closes to desktop; no stuck overlay; server disconnects if connected.
|
||||||
|
|
||||||
|
### Known Issues
|
||||||
|
- None currently known.
|
||||||
|
|
||||||
|
### Next Steps
|
||||||
|
- None currently known (quit confirmation added in follow-up entry).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 2026-07-07 - Fix: Hide Main Menu Overlay During Server Join Load
|
## 2026-07-07 - Fix: Hide Main Menu Overlay During Server Join Load
|
||||||
|
|
||||||
### Summary
|
### Summary
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ namespace F4T::PrismaUI
|
|||||||
// several functions call each other out of definition order).
|
// several functions call each other out of definition order).
|
||||||
void HideMainMenuInternal();
|
void HideMainMenuInternal();
|
||||||
void ShowMainMenuInternal();
|
void ShowMainMenuInternal();
|
||||||
|
void RequestQuitFromMainMenu();
|
||||||
void HideServerBrowserInternal();
|
void HideServerBrowserInternal();
|
||||||
void ShowServerBrowserInternal();
|
void ShowServerBrowserInternal();
|
||||||
void CreateMainMenuView();
|
void CreateMainMenuView();
|
||||||
@@ -619,6 +620,30 @@ namespace F4T::PrismaUI
|
|||||||
RequestNativeCursorRestore();
|
RequestNativeCursorRestore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RequestQuitFromMainMenu()
|
||||||
|
{
|
||||||
|
LogInfo("Quit requested from main menu.");
|
||||||
|
|
||||||
|
HideMainMenuInternal();
|
||||||
|
F4T::Networking::DisconnectFromLocalServer();
|
||||||
|
|
||||||
|
const auto* taskInterface = F4SE::GetTaskInterface();
|
||||||
|
if (!taskInterface) {
|
||||||
|
LogWarning("Game task interface unavailable; cannot queue quit.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskInterface->AddTask([]() {
|
||||||
|
auto* main = RE::Main::GetSingleton();
|
||||||
|
if (!main) {
|
||||||
|
REX::WARN("{} Main singleton unavailable; cannot quit game.", GetLogPrefix());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
main->quitGame = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void OnMainMenuDomReady(PrismaView a_view)
|
void OnMainMenuDomReady(PrismaView a_view)
|
||||||
{
|
{
|
||||||
g_mainMenuDomReady = true;
|
g_mainMenuDomReady = true;
|
||||||
@@ -674,7 +699,7 @@ namespace F4T::PrismaUI
|
|||||||
F4T::MainMenuVanillaSettings::OpenGameSettings();
|
F4T::MainMenuVanillaSettings::OpenGameSettings();
|
||||||
return;
|
return;
|
||||||
} else if (actionName == "quit") {
|
} else if (actionName == "quit") {
|
||||||
LogInfo("quit requested from main menu (not yet implemented).");
|
RequestQuitFromMainMenu();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,23 @@
|
|||||||
<!-- Server browser view (content mounted by ../browser/browser.js) -->
|
<!-- Server browser view (content mounted by ../browser/browser.js) -->
|
||||||
<section class="browser-view" id="browserPanel" aria-label="Server browser" hidden></section>
|
<section class="browser-view" id="browserPanel" aria-label="Server browser" hidden></section>
|
||||||
|
|
||||||
|
<!-- Quit confirmation -->
|
||||||
|
<section class="quit-confirm" id="quitConfirmPanel" aria-label="Quit confirmation" hidden>
|
||||||
|
<div class="quit-confirm__dialog" role="dialog" aria-modal="true" aria-labelledby="quitConfirmTitle">
|
||||||
|
<h2 class="quit-confirm__title" id="quitConfirmTitle">EXIT GAME?</h2>
|
||||||
|
<nav class="quit-confirm__options" id="quitConfirmOptions" aria-label="Quit confirmation options">
|
||||||
|
<button type="button" class="menu-item quit-confirm__option" data-index="0" data-choice="yes">
|
||||||
|
<span class="menu-item__label">YES</span>
|
||||||
|
<span class="menu-item__bar" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
<button type="button" class="menu-item quit-confirm__option" data-index="1" data-choice="no">
|
||||||
|
<span class="menu-item__label">NO</span>
|
||||||
|
<span class="menu-item__bar" aria-hidden="true"></span>
|
||||||
|
</button>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- Bottom controller prompts (main menu) -->
|
<!-- Bottom controller prompts (main menu) -->
|
||||||
<footer class="prompt-bar" id="mainPromptBar" aria-label="Controller prompts">
|
<footer class="prompt-bar" id="mainPromptBar" aria-label="Controller prompts">
|
||||||
<div class="prompt">
|
<div class="prompt">
|
||||||
|
|||||||
@@ -165,10 +165,13 @@
|
|||||||
var menu = document.getElementById("menu");
|
var menu = document.getElementById("menu");
|
||||||
var settingsPanel = document.getElementById("settingsPanel");
|
var settingsPanel = document.getElementById("settingsPanel");
|
||||||
var browserPanel = document.getElementById("browserPanel");
|
var browserPanel = document.getElementById("browserPanel");
|
||||||
|
var quitConfirmPanel = document.getElementById("quitConfirmPanel");
|
||||||
|
var quitConfirmOptions = document.getElementById("quitConfirmOptions");
|
||||||
var mainPromptBar = document.getElementById("mainPromptBar");
|
var mainPromptBar = document.getElementById("mainPromptBar");
|
||||||
var settingsPromptBar = document.getElementById("settingsPromptBar");
|
var settingsPromptBar = document.getElementById("settingsPromptBar");
|
||||||
|
|
||||||
if (!menu || !settingsPanel || !browserPanel || !window.CO_Settings || !window.CO_Browser) {
|
if (!menu || !settingsPanel || !browserPanel || !quitConfirmPanel || !quitConfirmOptions ||
|
||||||
|
!window.CO_Settings || !window.CO_Browser) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,12 +179,17 @@
|
|||||||
var browserController = null;
|
var browserController = null;
|
||||||
|
|
||||||
var items = Array.prototype.slice.call(menu.querySelectorAll(".menu-item"));
|
var items = Array.prototype.slice.call(menu.querySelectorAll(".menu-item"));
|
||||||
|
var quitConfirmItems = Array.prototype.slice.call(
|
||||||
|
quitConfirmOptions.querySelectorAll(".quit-confirm__option")
|
||||||
|
);
|
||||||
var MULTIPLAYER_INDEX = 0;
|
var MULTIPLAYER_INDEX = 0;
|
||||||
var SETTINGS_INDEX = 2;
|
var SETTINGS_INDEX = 2;
|
||||||
|
var QUIT_INDEX = 4;
|
||||||
|
|
||||||
// viewMode: "menu" | "settings" | "browser"
|
// viewMode: "menu" | "settings" | "browser" | "quitConfirm"
|
||||||
var viewMode = "menu";
|
var viewMode = "menu";
|
||||||
var selectedIndex = -1;
|
var selectedIndex = -1;
|
||||||
|
var quitConfirmSelectedIndex = 0;
|
||||||
var PANEL_TRANSITION_MS = 220;
|
var PANEL_TRANSITION_MS = 220;
|
||||||
var settingsHideFallbackId = 0;
|
var settingsHideFallbackId = 0;
|
||||||
var settingsHideOnTransitionEnd = null;
|
var settingsHideOnTransitionEnd = null;
|
||||||
@@ -243,13 +251,13 @@
|
|||||||
enterSettingsMode();
|
enterSettingsMode();
|
||||||
} else if (action === "multiplayer") {
|
} else if (action === "multiplayer") {
|
||||||
enterBrowserMode();
|
enterBrowserMode();
|
||||||
|
} else if (action === "quit") {
|
||||||
|
enterQuitConfirmMode();
|
||||||
} else {
|
} else {
|
||||||
window.CommonwealthOnlineUI.onOpenView(action);
|
window.CommonwealthOnlineUI.onOpenView(action);
|
||||||
if (action !== "quit") {
|
|
||||||
setSelected(-1);
|
setSelected(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
items.forEach(function (item, index) {
|
items.forEach(function (item, index) {
|
||||||
item.addEventListener("click", function () {
|
item.addEventListener("click", function () {
|
||||||
@@ -263,6 +271,11 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
exitBrowserMode();
|
exitBrowserMode();
|
||||||
|
} else if (viewMode === "quitConfirm") {
|
||||||
|
if (index === QUIT_INDEX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
exitQuitConfirmMode();
|
||||||
}
|
}
|
||||||
if (item.classList.contains("is-disabled")) {
|
if (item.classList.contains("is-disabled")) {
|
||||||
return;
|
return;
|
||||||
@@ -472,6 +485,129 @@
|
|||||||
exitBrowserMode(true);
|
exitBrowserMode(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function setQuitConfirmSelected(index) {
|
||||||
|
if (index >= quitConfirmItems.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
quitConfirmSelectedIndex = index < 0 ? 0 : index;
|
||||||
|
|
||||||
|
quitConfirmItems.forEach(function (item, i) {
|
||||||
|
var isSelected = i === quitConfirmSelectedIndex;
|
||||||
|
item.classList.toggle("is-selected", isSelected);
|
||||||
|
item.setAttribute("aria-selected", isSelected ? "true" : "false");
|
||||||
|
item.tabIndex = isSelected ? 0 : -1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveQuitConfirmSelection(delta) {
|
||||||
|
var next = quitConfirmSelectedIndex + delta;
|
||||||
|
if (next < 0) {
|
||||||
|
next = quitConfirmItems.length - 1;
|
||||||
|
} else if (next >= quitConfirmItems.length) {
|
||||||
|
next = 0;
|
||||||
|
}
|
||||||
|
setQuitConfirmSelected(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
function showQuitConfirmPanelAnimated() {
|
||||||
|
if (mainScreen) {
|
||||||
|
mainScreen.classList.add("is-quit-confirm-mode");
|
||||||
|
}
|
||||||
|
quitConfirmPanel.hidden = false;
|
||||||
|
quitConfirmPanel.classList.remove("is-open");
|
||||||
|
void quitConfirmPanel.offsetWidth;
|
||||||
|
quitConfirmPanel.classList.add("is-open");
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideQuitConfirmPanelAnimated(done) {
|
||||||
|
if (quitConfirmPanel.hidden) {
|
||||||
|
if (done) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
quitConfirmPanel.classList.remove("is-open");
|
||||||
|
|
||||||
|
window.setTimeout(function finishHide() {
|
||||||
|
if (viewMode === "quitConfirm" || quitConfirmPanel.classList.contains("is-open")) {
|
||||||
|
if (done) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (mainScreen) {
|
||||||
|
mainScreen.classList.remove("is-quit-confirm-mode");
|
||||||
|
}
|
||||||
|
quitConfirmPanel.hidden = true;
|
||||||
|
if (done) {
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
}, PANEL_TRANSITION_MS + 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
function enterQuitConfirmMode() {
|
||||||
|
if (viewMode === "quitConfirm") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewMode === "settings") {
|
||||||
|
exitSettingsMode();
|
||||||
|
} else if (viewMode === "browser") {
|
||||||
|
exitBrowserMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
viewMode = "quitConfirm";
|
||||||
|
console.log("[CO Main Menu] Entering quit confirmation");
|
||||||
|
|
||||||
|
setSelected(QUIT_INDEX);
|
||||||
|
setQuitConfirmSelected(1);
|
||||||
|
showQuitConfirmPanelAnimated();
|
||||||
|
}
|
||||||
|
|
||||||
|
function exitQuitConfirmMode() {
|
||||||
|
if (viewMode !== "quitConfirm") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
viewMode = "menu";
|
||||||
|
console.log("[CO Main Menu] Exiting quit confirmation");
|
||||||
|
|
||||||
|
hideQuitConfirmPanelAnimated(function () {
|
||||||
|
if (viewMode === "menu") {
|
||||||
|
setSelected(QUIT_INDEX);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function confirmQuit() {
|
||||||
|
console.log("[CO Main Menu] Quit confirmed");
|
||||||
|
sendCoAction({ action: "quit" });
|
||||||
|
}
|
||||||
|
|
||||||
|
function activateQuitConfirmSelected() {
|
||||||
|
var item = quitConfirmItems[quitConfirmSelectedIndex];
|
||||||
|
if (!item) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var choice = item.getAttribute("data-choice");
|
||||||
|
if (choice === "yes") {
|
||||||
|
confirmQuit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
exitQuitConfirmMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
quitConfirmItems.forEach(function (item, index) {
|
||||||
|
item.addEventListener("click", function () {
|
||||||
|
setQuitConfirmSelected(index);
|
||||||
|
activateQuitConfirmSelected();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
window.onMainMenuShown = function () {
|
window.onMainMenuShown = function () {
|
||||||
if (mainScreen) {
|
if (mainScreen) {
|
||||||
mainScreen.classList.remove("is-session-loading");
|
mainScreen.classList.remove("is-session-loading");
|
||||||
@@ -489,11 +625,14 @@
|
|||||||
settingsController.hide();
|
settingsController.hide();
|
||||||
settingsPanel.classList.remove("is-open");
|
settingsPanel.classList.remove("is-open");
|
||||||
settingsPanel.hidden = true;
|
settingsPanel.hidden = true;
|
||||||
|
} else if (viewMode === "quitConfirm") {
|
||||||
|
quitConfirmPanel.classList.remove("is-open");
|
||||||
|
quitConfirmPanel.hidden = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
viewMode = "menu";
|
viewMode = "menu";
|
||||||
if (mainScreen) {
|
if (mainScreen) {
|
||||||
mainScreen.classList.remove("is-browser-mode", "is-settings-mode");
|
mainScreen.classList.remove("is-browser-mode", "is-settings-mode", "is-quit-confirm-mode");
|
||||||
mainScreen.classList.add("is-session-loading");
|
mainScreen.classList.add("is-session-loading");
|
||||||
}
|
}
|
||||||
if (mainPromptBar) {
|
if (mainPromptBar) {
|
||||||
@@ -580,6 +719,30 @@
|
|||||||
|
|
||||||
// ── Keyboard navigation ────────────────────────────────────────
|
// ── Keyboard navigation ────────────────────────────────────────
|
||||||
|
|
||||||
|
function handleQuitConfirmKeydown(event) {
|
||||||
|
switch (event.key) {
|
||||||
|
case "ArrowUp":
|
||||||
|
event.preventDefault();
|
||||||
|
moveQuitConfirmSelection(-1);
|
||||||
|
break;
|
||||||
|
case "ArrowDown":
|
||||||
|
event.preventDefault();
|
||||||
|
moveQuitConfirmSelection(1);
|
||||||
|
break;
|
||||||
|
case "Enter":
|
||||||
|
case " ":
|
||||||
|
event.preventDefault();
|
||||||
|
activateQuitConfirmSelected();
|
||||||
|
break;
|
||||||
|
case "Escape":
|
||||||
|
event.preventDefault();
|
||||||
|
exitQuitConfirmMode();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function handleMenuKeydown(event) {
|
function handleMenuKeydown(event) {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case "ArrowUp":
|
case "ArrowUp":
|
||||||
@@ -614,6 +777,10 @@
|
|||||||
browserController.handleKeydown(event);
|
browserController.handleKeydown(event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (viewMode === "quitConfirm") {
|
||||||
|
handleQuitConfirmKeydown(event);
|
||||||
|
return;
|
||||||
|
}
|
||||||
handleMenuKeydown(event);
|
handleMenuKeydown(event);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -626,6 +793,23 @@
|
|||||||
if (viewMode === "settings") {
|
if (viewMode === "settings") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (viewMode === "quitConfirm") {
|
||||||
|
switch (button) {
|
||||||
|
case "dpad_up":
|
||||||
|
moveQuitConfirmSelection(-1);
|
||||||
|
break;
|
||||||
|
case "dpad_down":
|
||||||
|
moveQuitConfirmSelection(1);
|
||||||
|
break;
|
||||||
|
case "a":
|
||||||
|
activateQuitConfirmSelected();
|
||||||
|
break;
|
||||||
|
case "b":
|
||||||
|
exitQuitConfirmMode();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
switch (button) {
|
switch (button) {
|
||||||
case "dpad_up":
|
case "dpad_up":
|
||||||
moveSelection(-1);
|
moveSelection(-1);
|
||||||
|
|||||||
@@ -441,3 +441,89 @@ body {
|
|||||||
),
|
),
|
||||||
rgba(4, 8, 6, 0.32);
|
rgba(4, 8, 6, 0.32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Quit confirmation modal */
|
||||||
|
|
||||||
|
.quit-confirm {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
z-index: 12;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: calc(24px * var(--co-ui-scale));
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
transition:
|
||||||
|
opacity 220ms ease-out,
|
||||||
|
visibility 0ms linear 220ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quit-confirm.is-open {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
pointer-events: auto;
|
||||||
|
transition:
|
||||||
|
opacity 220ms ease-out,
|
||||||
|
visibility 0ms linear 0ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quit-confirm[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quit-confirm__dialog {
|
||||||
|
width: min(calc(420px * var(--co-ui-scale)), calc(100vw - 80px * var(--co-ui-scale)));
|
||||||
|
padding:
|
||||||
|
calc(32px * var(--co-ui-scale))
|
||||||
|
calc(36px * var(--co-ui-scale))
|
||||||
|
calc(28px * var(--co-ui-scale));
|
||||||
|
background: rgba(6, 12, 8, 0.9);
|
||||||
|
border: 1px solid rgba(201, 168, 74, 0.35);
|
||||||
|
box-shadow:
|
||||||
|
inset 0 0 28px rgba(0, 0, 0, 0.35),
|
||||||
|
0 8px 32px rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quit-confirm__title {
|
||||||
|
margin-bottom: calc(24px * var(--co-ui-scale));
|
||||||
|
font-size: calc(28px * var(--co-ui-scale));
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: 0.22em;
|
||||||
|
text-align: center;
|
||||||
|
color: var(--co-amber);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quit-confirm__options {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: var(--co-menu-gap);
|
||||||
|
}
|
||||||
|
|
||||||
|
.quit-confirm__option .menu-item__bar {
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-screen.is-quit-confirm-mode .scene-overlay {
|
||||||
|
background:
|
||||||
|
linear-gradient(
|
||||||
|
90deg,
|
||||||
|
rgba(6, 10, 8, 0.92) 0%,
|
||||||
|
rgba(6, 10, 8, 0.72) 35%,
|
||||||
|
rgba(6, 10, 8, 0.55) 60%,
|
||||||
|
rgba(6, 10, 8, 0.65) 100%
|
||||||
|
),
|
||||||
|
rgba(4, 8, 6, 0.42);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
.quit-confirm {
|
||||||
|
transition: opacity 120ms ease-out, visibility 0ms linear 120ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quit-confirm.is-open {
|
||||||
|
transition: opacity 120ms ease-out, visibility 0ms linear 0ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user