Refocus responsive layouts on compact desktop use
All checks were successful
Deploy Sokko G / deploy (push) Successful in 19s
All checks were successful
Deploy Sokko G / deploy (push) Successful in 19s
This commit is contained in:
parent
96d058293d
commit
0ac1a0974e
27 changed files with 610 additions and 190 deletions
|
|
@ -8,9 +8,7 @@
|
|||
"toolboxes": "Toolboxes",
|
||||
"games": "Jeux",
|
||||
"library": "Librairie",
|
||||
"about": "C'est quoi Sokko G ?",
|
||||
"mobileLibrary": "Lib.",
|
||||
"mobileGames": "Infos"
|
||||
"about": "C'est quoi Sokko G ?"
|
||||
},
|
||||
"sidebar": {
|
||||
"badge": "Local only",
|
||||
|
|
@ -20,7 +18,10 @@
|
|||
"dashboard": "Dashboard",
|
||||
"toolbox": "Toolboxes",
|
||||
"library": "Librairie",
|
||||
"games": "Informations jeu"
|
||||
"games": "Informations jeu",
|
||||
"gameViewLabel": "Vue de la page jeu",
|
||||
"guideView": "Guide",
|
||||
"toolboxView": "Toolbox"
|
||||
},
|
||||
"gamesPage": {
|
||||
"eyebrow": "Pages informatives",
|
||||
|
|
|
|||
|
|
@ -1,18 +1,48 @@
|
|||
// Rôle : structure le layout global avec sidebar, topbar, navigation et contenu.
|
||||
import { useEffect, useRef } from "react";
|
||||
import { Icon } from "./Icon.jsx";
|
||||
import { ImportButton } from "./ImportButton.jsx";
|
||||
import { Tooltip } from "./Tooltip.jsx";
|
||||
|
||||
export function Shell({ route, content, games, drawerGameId = "", actions, children }) {
|
||||
export function Shell({ route, content, games, drawerGameId = "", drawerVisible = false, compactGameLayout = false, reducedSidebar = false, actions, children }) {
|
||||
const gameId = route.split("/")[1] === "games" ? route.split("/")[2] || "" : "";
|
||||
const game = games.find((item) => item.id === gameId);
|
||||
const topbarLabel = route === "/design-system" && import.meta.env.DEV ? "Design system" : route.startsWith("/toolbox") ? content.topbar.toolbox : route.startsWith("/games") ? content.topbar.games : route === "/library" ? content.topbar.library : content.topbar.dashboard;
|
||||
const toolboxOpen = Boolean(game && drawerGameId === game.id);
|
||||
const toolboxOpen = Boolean(game && drawerGameId === game.id && drawerVisible);
|
||||
const toolboxLabel = toolboxOpen ? "Masquer la toolbox" : "Afficher la toolbox";
|
||||
const compactSidebar = Boolean(drawerGameId);
|
||||
const compactSidebar = Boolean(reducedSidebar || (!compactGameLayout && toolboxOpen));
|
||||
const compactToolboxVisible = Boolean(compactGameLayout && toolboxOpen);
|
||||
const guideTabRef = useRef(null);
|
||||
const toolboxTabRef = useRef(null);
|
||||
const wideToolboxButtonRef = useRef(null);
|
||||
const focusedViewControlRef = useRef("");
|
||||
const previousCompactLayoutRef = useRef(compactGameLayout);
|
||||
|
||||
useEffect(() => {
|
||||
const trackFocus = (event) => {
|
||||
if (event.target.closest?.(".compact-game-view-switch")) focusedViewControlRef.current = "compact";
|
||||
else if (event.target.closest?.(".toolbox-button")) focusedViewControlRef.current = "wide";
|
||||
else focusedViewControlRef.current = "";
|
||||
};
|
||||
document.addEventListener("focusin", trackFocus);
|
||||
return () => document.removeEventListener("focusin", trackFocus);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const activeElement = document.activeElement;
|
||||
const layoutChanged = previousCompactLayoutRef.current !== compactGameLayout;
|
||||
previousCompactLayoutRef.current = compactGameLayout;
|
||||
if (layoutChanged && compactGameLayout && focusedViewControlRef.current === "wide") {
|
||||
(compactToolboxVisible ? toolboxTabRef.current : guideTabRef.current)?.focus();
|
||||
} else if (compactGameLayout && !compactToolboxVisible && activeElement?.closest?.("#toolbox-drawer")) {
|
||||
guideTabRef.current?.focus();
|
||||
} else if (layoutChanged && !compactGameLayout && focusedViewControlRef.current === "compact") {
|
||||
wideToolboxButtonRef.current?.focus();
|
||||
}
|
||||
}, [compactGameLayout, compactToolboxVisible]);
|
||||
|
||||
return (
|
||||
<div className={`app-shell ${compactSidebar ? "sidebar-compact" : ""} ${drawerGameId ? "toolbox-drawer-open" : ""}`}>
|
||||
<div className={`app-shell ${compactSidebar ? "sidebar-compact" : ""} ${!compactGameLayout && toolboxOpen ? "toolbox-drawer-open" : ""} ${compactToolboxVisible ? "compact-toolbox-visible" : ""}`}>
|
||||
<aside className="sidebar" data-variant={compactSidebar ? "compact" : undefined}>
|
||||
<a className="brand" href="#/" aria-label={content.brand.homeAriaLabel}>
|
||||
<span className="brand-mark" aria-hidden="true" />
|
||||
|
|
@ -47,8 +77,12 @@ export function Shell({ route, content, games, drawerGameId = "", actions, child
|
|||
<div><strong>{topbarLabel}</strong></div>
|
||||
{game && (
|
||||
<div className="topbar-actions">
|
||||
<button
|
||||
{compactGameLayout ? <div className="compact-game-view-switch nds-radio-button-group" role="tablist" aria-label={content.topbar.gameViewLabel}>
|
||||
<button ref={guideTabRef} type="button" role="tab" aria-selected={!compactToolboxVisible} className={!compactToolboxVisible ? "active" : ""} onClick={() => actions.setDrawerGameId("")}>{content.topbar.guideView}</button>
|
||||
<button ref={toolboxTabRef} type="button" role="tab" aria-selected={compactToolboxVisible} className={compactToolboxVisible ? "active" : ""} onClick={() => actions.setDrawerGameId(game.id)}>{content.topbar.toolboxView}</button>
|
||||
</div> : <button
|
||||
className={`drawer-button toolbox-button nds-button ${toolboxOpen ? "active" : ""}`}
|
||||
ref={wideToolboxButtonRef}
|
||||
data-size="sm"
|
||||
data-variant="primary"
|
||||
onClick={() => actions.setDrawerGameId(toolboxOpen ? "" : game.id)}
|
||||
|
|
@ -58,19 +92,12 @@ export function Shell({ route, content, games, drawerGameId = "", actions, child
|
|||
>
|
||||
<img src="/static/icons/toolbox.svg" alt="" aria-hidden="true" />
|
||||
<span>{toolboxLabel}</span>
|
||||
</button>
|
||||
</button>}
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
<main>{children}</main>
|
||||
</div>
|
||||
<nav className="mobile-nav" aria-label="Navigation mobile">
|
||||
<a className={route === "/" ? "active" : ""} href="#/">{content.navigation.home}</a>
|
||||
<a className={route.startsWith("/toolboxes") || route.startsWith("/toolbox") ? "active" : ""} href="#/toolboxes">{content.navigation.toolboxes}</a>
|
||||
<button className="nds-button" data-size="sm" data-variant="primary" onClick={() => actions.setCreateModal({})}>+</button>
|
||||
<a className={route === "/library" ? "active" : ""} href="#/library">{content.navigation.mobileLibrary}</a>
|
||||
<a className={route.startsWith("/games") ? "active" : ""} href="#/games">{content.navigation.mobileGames}</a>
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -442,7 +442,7 @@ function ToolboxView({ siteContent, toolbox, toolboxGame, embedded, actions, sto
|
|||
);
|
||||
}
|
||||
|
||||
export function ToolboxDrawer({ gameId, game, siteContent, toolboxes, links, actions, storageUsage, storageReady = true, getModuleData, updateToolbox, updateModuleData, addImageFiles }) {
|
||||
export function ToolboxDrawer({ gameId, game, siteContent, toolboxes, links, actions, storageUsage, storageReady = true, getModuleData, updateToolbox, updateModuleData, addImageFiles, visible = true, compact = false }) {
|
||||
const checklist = useGuideChecklist();
|
||||
const guideChecklist = checklist.available && checklist.guideId.split("/")[0] === gameId ? checklist : undefined;
|
||||
const selectedId = links[gameId] || "";
|
||||
|
|
@ -483,7 +483,7 @@ export function ToolboxDrawer({ gameId, game, siteContent, toolboxes, links, act
|
|||
}
|
||||
|
||||
return (
|
||||
<aside className="drawer" id="toolbox-drawer" aria-hidden="false" style={{ "--drawer-panel-width": `${width}px` }}>
|
||||
<aside className={`drawer ${compact ? "is-compact" : ""}`} id="toolbox-drawer" aria-hidden={!visible} inert={!visible || undefined} style={{ "--drawer-panel-width": `${width}px` }}>
|
||||
<span className="drawer-resize-handle nds-drawer-resize-handle" aria-hidden="true" onPointerDown={startResize} />
|
||||
<section className="drawer-panel nds-drawer-panel legacy-scrollbar" ref={panelRef}>
|
||||
<div className="drawer-content">
|
||||
|
|
|
|||
16
website/src/hooks/useMediaQuery.js
Normal file
16
website/src/hooks/useMediaQuery.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Rôle : expose l'état réactif d'une media query pour synchroniser comportement et mise en page.
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function useMediaQuery(query) {
|
||||
const [matches, setMatches] = useState(() => window.matchMedia(query).matches);
|
||||
|
||||
useEffect(() => {
|
||||
const mediaQuery = window.matchMedia(query);
|
||||
const update = () => setMatches(mediaQuery.matches);
|
||||
update();
|
||||
mediaQuery.addEventListener("change", update);
|
||||
return () => mediaQuery.removeEventListener("change", update);
|
||||
}, [query]);
|
||||
|
||||
return matches;
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@ import { getCalendarAlertOffsets, getCurrentCalendarOccurrence, getNextCalendarA
|
|||
import { getCountdownTargetMs } from "../features/toolboxes/modules/timerUtils.js";
|
||||
import { moduleStorageKey } from "../features/toolboxes/storage/toolboxStorage.js";
|
||||
|
||||
function getVisibleToolboxIds(route, drawerGameId, links) {
|
||||
export function getVisibleToolboxIds(route, drawerGameId, links) {
|
||||
const visibleIds = new Set();
|
||||
const toolboxMatch = route.match(/^\/toolbox\/([^/]+)/);
|
||||
if (toolboxMatch?.[1]) visibleIds.add(toolboxMatch[1]);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ import { useHashRoute } from "./router/hashRouter.js";
|
|||
import { normalizeCalendarData, normalizeTimerData } from "./features/toolboxes/storage/toolboxStorage.js";
|
||||
import { useAutoBackup } from "./features/toolboxes/storage/useAutoBackup.js";
|
||||
import { GlobalMemosTicker } from "./features/toolboxes/GlobalMemosTicker.jsx";
|
||||
import { useMediaQuery } from "./hooks/useMediaQuery.js";
|
||||
|
||||
const assetRecoveryUrl = new URL(window.location.href);
|
||||
if (assetRecoveryUrl.searchParams.has("_asset-recovery")) {
|
||||
|
|
@ -43,6 +44,8 @@ function getNotificationDuration(message, options = {}) {
|
|||
|
||||
function App() {
|
||||
const route = useHashRoute();
|
||||
const compactGameLayout = useMediaQuery("(max-width: 1439px)");
|
||||
const reducedSidebar = useMediaQuery("(max-width: 1024px)");
|
||||
const { siteContent, siteContentError, games, gamesError, mhwilds, diablo4, aniimo } = useAppData(route);
|
||||
const [filters, setFilters] = useGameFilters();
|
||||
const [confirmModal, setConfirmModal] = useState(null);
|
||||
|
|
@ -50,7 +53,8 @@ function App() {
|
|||
const [autoBackupModalOpen, setAutoBackupModalOpen] = useState(false);
|
||||
const [linkModalGameId, setLinkModalGameId] = useState("");
|
||||
const [drawerGameId, setDrawerGameId] = useState("");
|
||||
const [drawerRoute, setDrawerRoute] = useState(route);
|
||||
const [drawerVisible, setDrawerVisible] = useState(false);
|
||||
const [drawerContext, setDrawerContext] = useState({ route, compactGameLayout });
|
||||
const [image, setImage] = useState(null);
|
||||
const [pendingTutorialToolboxId, setPendingTutorialToolboxId] = useState("");
|
||||
const [notifications, setNotifications] = useState([]);
|
||||
|
|
@ -61,11 +65,33 @@ function App() {
|
|||
const autoBackup = useAutoBackup(store);
|
||||
const { backupNeeded, requestPermission: requestBackupPermission } = autoBackup;
|
||||
const guideChecklistStorage = useGuideChecklistStorage(store);
|
||||
const guideScrollRef = useRef(0);
|
||||
|
||||
if (drawerRoute !== route) {
|
||||
setDrawerRoute(route);
|
||||
const setGameToolbox = useCallback((gameId) => {
|
||||
if (gameId) {
|
||||
if (compactGameLayout && !drawerVisible) guideScrollRef.current = window.scrollY;
|
||||
setDrawerGameId(gameId);
|
||||
setDrawerVisible(true);
|
||||
if (compactGameLayout) window.requestAnimationFrame(() => window.scrollTo({ top: 0, behavior: "auto" }));
|
||||
return;
|
||||
}
|
||||
setDrawerVisible(false);
|
||||
if (compactGameLayout) {
|
||||
window.requestAnimationFrame(() => window.scrollTo({ top: guideScrollRef.current, behavior: "auto" }));
|
||||
} else {
|
||||
setDrawerGameId("");
|
||||
}
|
||||
}, [compactGameLayout, drawerVisible]);
|
||||
|
||||
if (drawerContext.route !== route || drawerContext.compactGameLayout !== compactGameLayout) {
|
||||
setDrawerContext({ route, compactGameLayout });
|
||||
const activeGameId = route.match(/^\/games\/([^/]+)/)?.[1] || "";
|
||||
if (activeGameId !== drawerGameId) setDrawerGameId("");
|
||||
if (activeGameId !== drawerGameId) {
|
||||
setDrawerGameId("");
|
||||
setDrawerVisible(false);
|
||||
} else if (!compactGameLayout && !drawerVisible && drawerGameId) {
|
||||
setDrawerGameId("");
|
||||
}
|
||||
}
|
||||
|
||||
const notify = useCallback((message, options = {}) => {
|
||||
|
|
@ -126,7 +152,7 @@ function App() {
|
|||
setCreateModal,
|
||||
setConfirmModal,
|
||||
setLinkModalGameId,
|
||||
setDrawerGameId,
|
||||
setDrawerGameId: setGameToolbox,
|
||||
setImage
|
||||
});
|
||||
|
||||
|
|
@ -135,7 +161,7 @@ function App() {
|
|||
moduleData: store.moduleData,
|
||||
links: store.links,
|
||||
route,
|
||||
drawerGameId,
|
||||
drawerGameId: drawerVisible ? drawerGameId : "",
|
||||
normalizeTimerData,
|
||||
normalizeCalendarData,
|
||||
textContent: siteContent?.toolboxes?.modules,
|
||||
|
|
@ -173,9 +199,19 @@ function App() {
|
|||
|
||||
return (
|
||||
<GuideChecklistContext.Provider value={{ route, aniimo, mhwilds, diablo4, siteContent, toolboxes: store.toolboxes, links: store.links, moduleData: store.moduleData, guideChecklistStorage, actions }}>
|
||||
<Shell route={route} content={siteContent} games={games} toolboxes={store.toolboxes} links={store.links} drawerGameId={drawerGameId} actions={actions}>
|
||||
<AppErrorBoundary route={route}>
|
||||
<RouteContent
|
||||
<Shell
|
||||
route={route}
|
||||
content={siteContent}
|
||||
games={games}
|
||||
drawerGameId={drawerGameId}
|
||||
drawerVisible={drawerVisible}
|
||||
compactGameLayout={compactGameLayout}
|
||||
reducedSidebar={reducedSidebar}
|
||||
actions={actions}
|
||||
>
|
||||
<div className="route-content-view" aria-hidden={compactGameLayout && drawerVisible || undefined} inert={compactGameLayout && drawerVisible || undefined}>
|
||||
<AppErrorBoundary route={route}>
|
||||
<RouteContent
|
||||
route={route}
|
||||
siteContent={siteContent}
|
||||
games={games}
|
||||
|
|
@ -202,8 +238,9 @@ function App() {
|
|||
addImageFiles={actions.addImageFiles}
|
||||
pendingTutorialToolboxId={pendingTutorialToolboxId}
|
||||
setPendingTutorialToolboxId={setPendingTutorialToolboxId}
|
||||
/>
|
||||
</AppErrorBoundary>
|
||||
/>
|
||||
</AppErrorBoundary>
|
||||
</div>
|
||||
{drawerGameId && (
|
||||
<Suspense fallback={null}>
|
||||
<ToolboxDrawer
|
||||
|
|
@ -219,6 +256,8 @@ function App() {
|
|||
updateToolbox={actions.updateToolbox}
|
||||
updateModuleData={store.updateModuleData}
|
||||
addImageFiles={actions.addImageFiles}
|
||||
visible={drawerVisible}
|
||||
compact={compactGameLayout}
|
||||
/>
|
||||
</Suspense>
|
||||
)}
|
||||
|
|
@ -238,7 +277,7 @@ function App() {
|
|||
setCreateModal={setCreateModal}
|
||||
linkModalGameId={linkModalGameId}
|
||||
setLinkModalGameId={setLinkModalGameId}
|
||||
setDrawerGameId={setDrawerGameId}
|
||||
setDrawerGameId={setGameToolbox}
|
||||
storageError={storageError}
|
||||
setStorageError={setStorageError}
|
||||
image={image}
|
||||
|
|
|
|||
|
|
@ -251,7 +251,3 @@
|
|||
height: 14px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,69 @@
|
|||
.about-reminders-list {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.home-onboarding-layout,
|
||||
.library-doc-layout {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.library-example-layout,
|
||||
.hero,
|
||||
.origin-section {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.hero-stats {
|
||||
align-self: start;
|
||||
justify-self: start;
|
||||
width: min(520px, 100%);
|
||||
}
|
||||
|
||||
.home-visual {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.origin-copy {
|
||||
padding-right: 0;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.library-doc-nav {
|
||||
position: static;
|
||||
max-height: none;
|
||||
}
|
||||
|
||||
.page-heading,
|
||||
.toolbox-head {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.game-heading-actions,
|
||||
.guide-checklist-page-controls {
|
||||
width: 100%;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.guide-checklist-page-actions,
|
||||
.toolbar,
|
||||
.page-heading .actions,
|
||||
.toolbox-head .actions {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1439px) {
|
||||
main {
|
||||
width: min(100% - 40px, 1280px);
|
||||
padding-top: var(--space-6);
|
||||
}
|
||||
|
||||
.toolbar,
|
||||
.page-heading .actions,
|
||||
.toolbox-head .actions {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-height: 760px) and (min-width: 1025px) {
|
||||
|
|
@ -58,22 +121,14 @@
|
|||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
.drawer {
|
||||
--drawer-top-offset: 110px;
|
||||
.topbar {
|
||||
padding-inline: var(--space-4);
|
||||
}
|
||||
|
||||
.app-shell {
|
||||
display: block;
|
||||
padding-bottom: 76px;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
.topbar:has(.compact-game-view-switch) > div:first-child {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.topbar,
|
||||
.page-heading,
|
||||
.toolbox-head,
|
||||
.module .module-header {
|
||||
align-items: stretch;
|
||||
flex-direction: column;
|
||||
|
|
@ -109,24 +164,6 @@
|
|||
order: 2;
|
||||
}
|
||||
|
||||
.topbar {
|
||||
padding: var(--space-4);
|
||||
}
|
||||
|
||||
.topbar-actions {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.topbar-actions > * {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.game-heading-actions,
|
||||
.guide-checklist-page-controls {
|
||||
width: 100%;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.guide-checklist-page-controls {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
|
@ -144,11 +181,8 @@
|
|||
width: 100%;
|
||||
}
|
||||
|
||||
.hero,
|
||||
.game-hero,
|
||||
.page-hero,
|
||||
.origin-section,
|
||||
.home-onboarding-layout,
|
||||
.home-onboarding-cards,
|
||||
.about-story-section,
|
||||
.about-story-list,
|
||||
|
|
@ -231,10 +265,6 @@
|
|||
-webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0, 0, 0, 0.14) 30%, #000 70%);
|
||||
}
|
||||
|
||||
.home-visual {
|
||||
width: min(320px, 100%);
|
||||
}
|
||||
|
||||
.origin-section {
|
||||
padding: var(--space-5);
|
||||
}
|
||||
|
|
@ -243,13 +273,6 @@
|
|||
padding-left: 0;
|
||||
}
|
||||
|
||||
.origin-copy {
|
||||
padding-right: 0;
|
||||
padding-bottom: var(--space-5);
|
||||
border-right: 0;
|
||||
border-bottom: 2px solid rgba(246, 196, 83, 0.66);
|
||||
}
|
||||
|
||||
.dialogue-line {
|
||||
max-width: 92%;
|
||||
}
|
||||
|
|
@ -322,7 +345,6 @@
|
|||
max-height: none;
|
||||
}
|
||||
|
||||
.library-example-layout,
|
||||
.library-tool-feature-list dl > div {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
|
@ -413,59 +435,12 @@
|
|||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.mobile-nav {
|
||||
position: fixed;
|
||||
right: 12px;
|
||||
bottom: 12px;
|
||||
left: 12px;
|
||||
z-index: 60;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 52px 1fr;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--radius-xl);
|
||||
background: rgba(11, 14, 27, 0.9);
|
||||
backdrop-filter: blur(10px);
|
||||
box-shadow: var(--shadow-lg);
|
||||
}
|
||||
|
||||
.mobile-nav a,
|
||||
.mobile-nav button {
|
||||
min-height: 44px;
|
||||
padding: 0 8px;
|
||||
border-radius: var(--radius-md);
|
||||
font-size: var(--font-size-sm);
|
||||
}
|
||||
|
||||
.mobile-nav a {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.mobile-nav a.active {
|
||||
background: var(--color-primary-soft);
|
||||
color: var(--color-text-primary);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 699px) {
|
||||
.drawer-panel {
|
||||
width: 100vw;
|
||||
min-width: 0;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.drawer-link-existing form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.drawer-resize-handle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
|
|
|
|||
|
|
@ -359,7 +359,7 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
@media (min-width: 700px) {
|
||||
@media (min-width: 1440px) {
|
||||
.app-shell.toolbox-drawer-open .content-shell {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 700px;
|
||||
|
|
@ -404,9 +404,19 @@
|
|||
|
||||
.topbar-actions {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.compact-game-view-switch {
|
||||
display: inline-flex;
|
||||
min-width: 184px;
|
||||
}
|
||||
|
||||
.compact-game-view-switch > button {
|
||||
flex: 1 1 0;
|
||||
}
|
||||
|
||||
.toolbox-button {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
@ -426,3 +436,11 @@ main {
|
|||
margin: 0 auto;
|
||||
padding: var(--space-8) 0 var(--space-12);
|
||||
}
|
||||
|
||||
.route-content-view {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.app-shell.compact-toolbox-visible .route-content-view {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,4 +57,3 @@
|
|||
max-width: 920px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -99,3 +99,22 @@ body.is-resizing-drawer * {
|
|||
.drawer-panel .modules {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 1439px) {
|
||||
.drawer.is-compact .drawer-panel {
|
||||
inset: 68px 0 0 248px;
|
||||
width: auto;
|
||||
min-width: 0;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.drawer.is-compact .drawer-resize-handle {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1024px) {
|
||||
.drawer.is-compact .drawer-panel {
|
||||
left: 72px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,11 +90,11 @@
|
|||
.global-memos-ticker { left: 84px; }
|
||||
}
|
||||
|
||||
@media (max-width: 760px) {
|
||||
@media (max-width: 767px) {
|
||||
.global-memos-ticker {
|
||||
right: 12px;
|
||||
bottom: 84px;
|
||||
left: 12px;
|
||||
bottom: 12px;
|
||||
left: 84px;
|
||||
}
|
||||
|
||||
.memos-settings label {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@
|
|||
align-items: start;
|
||||
}
|
||||
|
||||
.toolbox-page {
|
||||
container-name: toolbox-page;
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
.modules[data-layout-cols="1"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
|
@ -21,6 +26,20 @@
|
|||
min-width: 0;
|
||||
}
|
||||
|
||||
@container toolbox-page (max-width: 899px) {
|
||||
.modules-toolbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.modules[data-layout-cols="2"] {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.modules[data-layout-cols="2"] .module-column {
|
||||
display: contents;
|
||||
}
|
||||
}
|
||||
|
||||
.module-column.is-empty-warning {
|
||||
min-height: 132px;
|
||||
border: 1px dashed rgba(246, 196, 83, 0.26);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue