mmo-app
1 symbole · générée le 27 Oct 2026
mmo-app
mmo-app.jhs:1The application shell. One element, three templates, chosen by the host's class: <mmo-app class="admin">, class="landing" or class="blog".
- Étend
- CustomShadowElement
Index
| template | the template to use (admin, landing, blog). | |
| template accessor | The active template. | |
| constructor() | ||
| init() | ||
| initPanelResize() | Let the side panel be dragged wider or narrower by its left edge. | |
| resizePanelByKey(event) | Resize the panel from the keyboard: left and right by 16px, 4px with shift, Home back to its default width. | |
| setPanelWidth(width) | ||
| placePanel() | Beside the page or over it: a panel that would leave the page less than 420px (a 640px form on a 1024px screen left 100px to a table, #284) goes over it, with the class panel-over. | |
| fitPanel() | Give the panel the width its shown panel asks for (showPanel's width), unless the user chose one by dragging its edge. | |
| resetPanelWidth() | Put the panel back to the width the stylesheet gives it. | |
| updateRegions() | Reflect which optional regions the page filled, as host classes: a hero, a page header or a rail that no slot fills is removed from the layout instead of holding empty space. | |
| load(config) | Load the application configuration, the object the theme writes into MMO.config. | |
| addBreadcrumb(label, url, index) | Add a breadcrumb, closest to the root first. | |
| clearTabs() | Remove every page tab. | |
| getTabs() | Every page tab currently in the strip. | |
| addTab(label, url, icon, order) | Add a page tab. | |
| scrollTabs(direction) | Scroll the tab strip. | |
| updateTabsOverflow() | Show the tab scrollers only when the strip actually overflows. | |
| getMenu(url) | Find a rail entry by the url it points at. | |
| setActiveMenu(url) | Mark a menu entry, and every accordion above it, as active. | |
| revealMenu(node) | Scroll a rail entry into view, in the rail's own scroller. | |
| addMenu(group, label, url, icon, order) | Add a menu entry, creating the accordion hierarchy its url implies. | |
| bindAccordionToggle(accordion) | Keep the open state a user gave an accordion across pages, and keep its title a link. | |
| toggleMenu() | Collapse or expand the rail. | |
| shortcut(event) | Global shortcuts: alt+/ opens the palette, escape closes what is open. | |
| initCommands() | The commands the shell always has: what its own buttons do, when the template has those buttons. | |
| initModes() | The display modes the user may choose (MMO.modes): a level, and the layers over it, in the account card and in the palette; the layers on, as chips in the top bar, which turn them off. | |
| addCommand(label, run, icon, keywords) | Add a command to the palette, listed under « Commandes ». | |
| addSearchSource(source) | Add a remote source to the palette: its results are listed under their own heading, after the pages and the commands. | |
| openPalette(query) | Open the command palette, on the whole menu or already searching. | |
| paletteBackdrop(event) | Close the command palette when the click is on the veil around it, not in its box. | |
| closePalette() | Close the command palette. | |
| filterPalette(query) | Filter the palette on what has been typed, one group per category: the text of the page itself first (searchPage), then the pages of the menu, the commands, and each remote source (addSea… | |
| searchPage(query, limit) | Find a text in the page: accents and case do not count. | |
| indexPage() | Read the text of the page once, when the palette opens, so a search is a lookup rather than a walk through the whole document at every key. | |
| pageMatch(entry, at, length) | One match in the page, as a palette item: the words around it, the match marked. | |
| revealPageMatch(node, at, length) | Scroll to a match in the page, and select it: the selection is the browser's own highlight, and nothing is written into the page. | |
| fold(text) static | Fold a text for searching: lower case, accents dropped -- one character for one character, so an offset in the folded text is the same offset in the original. | |
| searchRemote(source, query) | Ask a remote source, and read its answer as palette items. | |
| appendPaletteGroup(parent, title, items) | Add a group of results to the palette. | |
| updatePaletteEmpty(query) | Keep one result selected, and say so when there is none left -- once no source is still searching. | |
| paletteKey(event) | Move through the results, across the groups, and follow the selected one. | |
| showPanel(title, body, options) | Open a panel in the side drawer, in a tab of its own. | |
| createPanelTab(panel) | the tab of a panel: its title, which shows it, and a button closing it | |
| selectPanel(id) | Show an open panel. | |
| updatePanel(id, changes) | Change an open panel: the title of its tab, or its key (showPanel). | |
| onPanelTabsKey(event) | the tab strip from the keyboard: arrows go from tab to tab, Delete closes one | |
| closePanel(value, id) | Close a panel, resolving its promise. | |
| closeAllPanels(value) | Close every panel. | |
| showNotification(css, content) | Show a notification. | |
| watchNotifications() | Keep the stack of notifications off the buttons while it holds any: the page scrolls, the window changes size, a click redraws a step (placeNotifications). | |
| placeNotifications() | Move the stack of notifications off every button under it (#227): from its place in the bottom right corner it goes up, above the buttons in its way; when the column has no room for it, it tries th… | |
| visibleButtons() | ||
| notify(content, title, button, butIcon) | Show a notification with a title and a dismiss button. | |
| showModal(css, content) | Show a modal dialog. | |
| answer(node, value) | Wire a dialog's buttons to its result: any <button value="..."> closes the dialog with that value, and the promise resolves with it -- false when the dialog is dismissed (escape, a click outsid… | |
| ask(title, content) | Ask for a value: one input, and the answer. | |
| confirm(title, content) | Ask a yes/no question. | |
| alert(title, content) | Say something, with one button to dismiss it. | |
| error(title, content) | The same, in the error tone. | |
| describeError(error) | An error as a user reads it: what happened, in French; the server's message when it is meant for a user (the framework's own name what they are about in [brackets], an id or a path is no such thi… | |
| toggleUserCard() | Toggle the account card. | |
| toggleConsole() | Toggle the developer drawer. | |
| showConsoleTab(name) | Show one pane of the developer drawer, and open the drawer if it was closed. | |
| loadServerInfo(reload) | Fill the server pane with what the server is made of: php, its extensions and every package the framework included, as AdminController::routeServerInfo answers them. | |
| toggleTOC() | Toggle the table of contents. | |
| updateConsoleTags(console) | Update the warning and error counters of the status bar. | |
| gotoTop(event) | Scroll back to the top of whichever container actually scrolls. | |
| blockScreen(active) | Block the screen while something runs. | |
| setThemeMode(scheme) | Apply a colour scheme. | |
| toggleDarkMode() | Switch between the dark and light schemes. | |
| (default) | the page itself | |
| logo | the mark at the top of the rail | |
| menu | rail entries written by hand, next to the ones MMO.config.menus adds | |
| side-foot | the foot of the rail, on the row the scheme switch ends | |
| user-info | the account line next to the account button, at the end of the top bar | |
| user-card-body | what the account card shows when it is opened | |
| brand | the brand in the top bar, for the landing and blog templates | |
| nav | links in the top bar | |
| actions | buttons on the right of the top bar | |
| header | anything else on the top bar, after the actions | |
| hero | the band above the page, for a landing | |
| page-title | the page header's title | |
| page-actions | the page header's buttons | |
| navigation | a strip between the header and the content (filters, a sub-navigation) | |
| aside | the rail on the right of the content, for an article | |
| footer | the footer, for the landing and blog templates | |
| panel-title | extra content at the end of the side panel's tab strip (its tabs are built by showPanel) | |
| panel | the body of the side panel | |
| status | the status bar, left of the log button | |
| logs | the lines the server log tab of the developer drawer shows | |
| notifications | the notifications stacked in the corner | |
| screen-blocker | what covers the page while it is blocked (blockScreen) | |
| .admin | the application shell: rail, breadcrumb, page tabs, side panel, status bar | |
| .landing | the marketing shell: sticky translucent header, hero, sections, large footer | |
| .blog | the editorial shell: header, content column, sticky rail, footer | |
| .menu-collapsed | the rail is reduced to icons | |
| .menu-open | the rail is open, on a small screen | |
| .has-tabs | the page has tabs: a small screen gives them a row of their own under the top bar | |
| .panel-open | the side panel is open | |
| .panel-over | the side panel is over the page rather than beside it: it left the page too little room (placePanel) | |
| .console-open | the developer drawer (server log, server information) is open | |
| .toc-open | the table of contents is open | |
| .palette-open | the command palette is open, over the page | |
| .has-hero | the page filled the hero region, so the shell makes room for it | |
| .has-user-card | the page filled the account card, so it gets a body above the logout link |
Attributs1
template
mmo-app.jhsthe template to use (admin, landing, blog). Defaults to the host's class.
template
Propriétés1
template
accessormmo-app.jhs:1572The active template.
- Type
string
Méthodes69
constructor()
mmo-app.jhs:1352init()
mmo-app.jhs:1369initPanelResize()
mmo-app.jhs:1452Let the side panel be dragged wider or narrower by its left edge.
| retourne | void |
resizePanelByKey(event)
mmo-app.jhs:1487Resize the panel from the keyboard: left and right by 16px, 4px with shift, Home back to its default width.
| event | KeyboardEvent | |
| retourne | void |
setPanelWidth(width)
mmo-app.jhs:1507| width | number | - in pixels |
| retourne | void |
placePanel()
mmo-app.jhs:1521Beside the page or over it: a panel that would leave the page less than 420px (a 640px form on a 1024px screen left 100px to a table, #284) goes over it, with the class panel-over. A small screen's panel always covers the whole screen (the small screens' styles).
| retourne | void |
fitPanel()
mmo-app.jhs:1537Give the panel the width its shown panel asks for (showPanel's width), unless the user chose one by dragging its edge. The panel's own max-width still caps it.
| retourne | void |
resetPanelWidth()
mmo-app.jhs:1545Put the panel back to the width the stylesheet gives it. @return {void}
updateRegions()
mmo-app.jhs:1556Reflect which optional regions the page filled, as host classes: a hero, a page header or a rail that no slot fills is removed from the layout instead of holding empty space.
load(config)
mmo-app.jhs:1594Load the application configuration, the object the theme writes into MMO.config.
| config | object | - breadcrumbs, navigations, menus and logs |
addBreadcrumb(label, url, index)
mmo-app.jhs:1643Add a breadcrumb, closest to the root first.
| label | string | - html, from the application's config (load) |
| url | string | |
| index = 0 | number | - the depth of this crumb |
| retourne | HTMLAnchorElement |
clearTabs()
mmo-app.jhs:1652Remove every page tab.
getTabs()
mmo-app.jhs:1661Every page tab currently in the strip.
| retourne | NodeList | the page tabs |
addTab(label, url, icon, order)
mmo-app.jhs:1673Add a page tab.
| label | string | - html, from the application's config (load) |
| url | string | |
| icon = null | ?string | |
| order = 0 | number | |
| retourne | HTMLAnchorElement |
scrollTabs(direction)
mmo-app.jhs:1689Scroll the tab strip.
| direction | number | - -1 left, 1 right |
updateTabsOverflow()
mmo-app.jhs:1695Show the tab scrollers only when the strip actually overflows.
getMenu(url)
mmo-app.jhs:1712Find a rail entry by the url it points at.
| url | string | |
| retourne | ?HTMLElement | the menu entry for this url |
setActiveMenu(url)
mmo-app.jhs:1730Mark a menu entry, and every accordion above it, as active.
| url | string |
revealMenu(node)
mmo-app.jhs:1773Scroll a rail entry into view, in the rail's own scroller.
| node | HTMLElement |
addMenu(group, label, url, icon, order)
mmo-app.jhs:1794Add a menu entry, creating the accordion hierarchy its url implies.
| group | string | - the section of the rail this entry belongs to, html (load) |
| label | string | - html, from the application's config (load) |
| url | string | |
| icon | string | |
| order = 0 | number |
bindAccordionToggle(accordion)
mmo-app.jhs:1880Keep the open state a user gave an accordion across pages, and keep its title a link.
| accordion | HTMLElement |
toggleMenu()
mmo-app.jhs:1916Collapse or expand the rail. On a small screen it opens as a drawer instead.
shortcut(event)
mmo-app.jhs:1937Global shortcuts: alt+/ opens the palette, escape closes what is open.
| event | KeyboardEvent |
initCommands()
mmo-app.jhs:1958The commands the shell always has: what its own buttons do, when the template has those buttons.
initModes()
mmo-app.jhs:1970The display modes the user may choose (MMO.modes): a level, and the layers over it, in the account card and in the palette; the layers on, as chips in the top bar, which turn them off. A user with no choice gets none.
addCommand(label, run, icon, keywords)
mmo-app.jhs:2038Add a command to the palette, listed under « Commandes ».
| label | string | - text |
| run | Function | - called when the command is picked, once the palette is closed |
| icon = null | ?string | - an <mmo-icon> name |
| keywords = '' | string | - other words the command is found by |
| retourne | label: string, run: Function, icon: ?string, keywords: string | } the command |
addSearchSource(source)
mmo-app.jhs:2054Add a remote source to the palette: its results are listed under their own heading, after the pages and the commands. The server is asked url?q=…&limit=… (plus params) and answers {results: [{url, label | shortName | name, kind, hint | namespace, icon}]}, or the same wrapped in data. The server usually declares its sources in MMO.config.searches (load).
| source | ||
| retourne | Object | the source |
openPalette(query)
mmo-app.jhs:2065Open the command palette, on the whole menu or already searching.
| query = '' | string | - what the palette starts with |
paletteBackdrop(event)
mmo-app.jhs:2077Close the command palette when the click is on the veil around it, not in its box.
| event | MouseEvent |
closePalette()
mmo-app.jhs:2082Close the command palette.
filterPalette(query)
mmo-app.jhs:2097Filter the palette on what has been typed, one group per category: the text of the page itself first (searchPage), then the pages of the menu, the commands, and each remote source (addSearchSource), which only answers once typing pauses.
| query | string |
searchPage(query, limit)
mmo-app.jhs:2166Find a text in the page: accents and case do not count. Each match is listed with its context and the heading it sits under; picking it scrolls to it and selects it (revealPageMatch).
| query | string | |
| limit = 20 | number | |
| retourne | Array<Object> | palette items |
indexPage()
mmo-app.jhs:2188Read the text of the page once, when the palette opens, so a search is a lookup rather than a walk through the whole document at every key. The page is what the default slot and the page's own regions hold -- never the menu, the panels or the notifications -- open shadow roots included, and only what is visible.
| retourne | Array<{node: Text, text: string, heading: string | >} each text node, folded (fold), with the heading it sits under |
pageMatch(entry, at, length)
mmo-app.jhs:2230One match in the page, as a palette item: the words around it, the match marked.
| entry | ||
| at | number | - where the match starts in the text node |
| length | number | |
| retourne | Object |
revealPageMatch(node, at, length)
mmo-app.jhs:2254Scroll to a match in the page, and select it: the selection is the browser's own highlight, and nothing is written into the page.
| node | Text | |
| at | number | |
| length | number |
fold(text)
staticmmo-app.jhs:2275Fold a text for searching: lower case, accents dropped -- one character for one character, so an offset in the folded text is the same offset in the original.
| text | string | |
| retourne | string |
searchRemote(source, query)
mmo-app.jhs:2287Ask a remote source, and read its answer as palette items.
| source | ||
| query | string | |
| retourne | Promise<Array<Object>> |
appendPaletteGroup(parent, title, items)
mmo-app.jhs:2307Add a group of results to the palette.
| parent | HTMLElement | |
| title | string | - the category |
| items |
updatePaletteEmpty(query)
mmo-app.jhs:2342Keep one result selected, and say so when there is none left -- once no source is still searching.
| query | string |
paletteKey(event)
mmo-app.jhs:2359Move through the results, across the groups, and follow the selected one.
| event | KeyboardEvent |
showPanel(title, body, options)
mmo-app.jhs:2409Open a panel in the side drawer, in a tab of its own.
- Voir
selectPanel,updatePanel).
| title | string | - text |
| body | ?(Node | string | MMO.core.dom.Html) | - a node, or text; markup you wrote goes through MMO.core.dom.html() |
| options = {} | object | - key: what identifies the panel, to show it again rather than open it twice; width: the width it wants, in pixels, while it is shown (an edit form needing room), unless the user dragged the panel to a width of their own |
| retourne | Promise | resolved with the value the panel is closed with. promise.node is the panel's body element, for a caller that has to reach into it, and promise.id its id (closePanel, |
createPanelTab(panel)
mmo-app.jhs:2437the tab of a panel: its title, which shows it, and a button closing it
| panel |
selectPanel(id)
mmo-app.jhs:2461Show an open panel.
| id | string | - the panel's id (promise.id of showPanel) |
| retourne | void |
updatePanel(id, changes)
mmo-app.jhs:2481Change an open panel: the title of its tab, or its key (showPanel).
| id | string | - the panel's id |
| changes = {} | object | - title (text) and/or key |
| retourne | void |
onPanelTabsKey(event)
mmo-app.jhs:2495the tab strip from the keyboard: arrows go from tab to tab, Delete closes one
| event |
closePanel(value, id)
mmo-app.jhs:2522Close a panel, resolving its promise. The panel shown is the one closed unless another is named: a button inside a panel closes its own (the one shown, since it was clicked).
| value = null | * | - what showPanel's promise resolves with |
| id = null | ?string | - the panel to close, the one shown by default |
closeAllPanels(value)
mmo-app.jhs:2543Close every panel.
| value = null | * | - what each panel's promise resolves with |
showNotification(css, content)
mmo-app.jhs:2562Show a notification.
| css | string | - a tone class: success, warning, error, info |
| ...content | ...* | - its children (MMO.core.dom.appendChildren); one with a slot goes to that part of the card, title or footer (mmo-notification) |
| retourne | HTMLElement |
watchNotifications()
mmo-app.jhs:2579Keep the stack of notifications off the buttons while it holds any: the page scrolls, the window changes size, a click redraws a step (placeNotifications). Set up with the first notification.
placeNotifications()
mmo-app.jhs:2602Move the stack of notifications off every button under it (#227): from its place in the bottom right corner it goes up, above the buttons in its way; when the column has no room for it, it tries the left of the content the same way, and otherwise keeps its corner -- what stays there is closed by itself (mmo-notification's duration) or by its ✕.
visibleButtons()
mmo-app.jhs:2649| retourne | DOMRect[] | the boxes of the buttons on screen, in the page and in the shell, open shadow roots included -- not the notifications' own, nor those inside a field. A button whose container floats (position: fixed or sticky: the bar of a workflow on a phone) counts for the whole container, once: the stack covering the bar around its buttons hid it all the same (#266). |
notify(content, title, button, butIcon)
mmo-app.jhs:2687Show a notification with a title and a dismiss button.
| content | * | - the body: text, a node, or MMO.core.dom.html() (showNotification) |
| title | string | - text |
| button = MMO.i18n.$('OK') | string | - the dismiss label, text |
| butIcon = 'eye' | string | - the dismiss icon |
| retourne | HTMLElement |
showModal(css, content)
mmo-app.jhs:2711Show a modal dialog.
- Voir
error,showNotification,notifyandshowPanel. Markup the caller wrote itself goes throughMMO.core.dom.html().
| css | string | |
| ...content | ...* | - its children, MMO.core.dom.appendChildren |
| retourne | HTMLDialogElement |
answer(node, value)
mmo-app.jhs:2727Wire a dialog's buttons to its result: any <button value="..."> closes the dialog with that value, and the promise resolves with it -- false when the dialog is dismissed (escape, a click outside), so a caller can always tell "no" from "not answered".
| node | HTMLDialogElement | |
| value | function(HTMLDialogElement, string):* | - what to resolve with, from the button's value |
| retourne | Promise |
ask(title, content)
mmo-app.jhs:2756Ask for a value: one input, and the answer.
| title | string | - text |
| ...content | ...* | - shown above the input: text unless it is a node (showModal) |
| retourne | Promise<string | false> | what was typed, false when cancelled |
confirm(title, content)
mmo-app.jhs:2779Ask a yes/no question.
| title | string | - text |
| ...content | ...* | - text unless it is a node (showModal) |
| retourne | Promise<boolean> |
alert(title, content)
mmo-app.jhs:2794Say something, with one button to dismiss it.
| title | string | - text |
| ...content | ...* | - text unless it is a node (showModal) |
| retourne | Promise<boolean> | true when it was acknowledged |
error(title, content)
mmo-app.jhs:2816The same, in the error tone.
| title | string | Error | - text, or an Error (then titled Une erreur est survenue) |
| ...content | ...* | - text unless it is a node (showModal); an Error is described |
| retourne | Promise<boolean> |
describeError(error)
mmo-app.jhs:2863An error as a user reads it: what happened, in French; the server's message when it is meant for a user (the framework's own name what they are about in [brackets], an id or a path is no such thing); the rest -- url, status, message, stack -- folded under « Détail technique ».
| error | Error | |
| retourne | HTMLElement[] | its paragraph and its folded detail |
toggleUserCard()
mmo-app.jhs:2903Toggle the account card.
toggleConsole()
mmo-app.jhs:2908Toggle the developer drawer.
showConsoleTab(name)
mmo-app.jhs:2917Show one pane of the developer drawer, and open the drawer if it was closed. The server pane is fetched the first time it is asked for, not on every page load: it is a tool, not a page region.
| name | string | - logs or server |
loadServerInfo(reload)
mmo-app.jhs:2932Fill the server pane with what the server is made of: php, its extensions and every package the framework included, as AdminController::routeServerInfo answers them.
| reload = false | boolean | - fetch again even if the pane was already filled |
| retourne | Promise |
toggleTOC()
mmo-app.jhs:2964Toggle the table of contents.
updateConsoleTags(console)
mmo-app.jhs:2974Update the warning and error counters of the status bar.
| console | HTMLElement |
gotoTop(event)
mmo-app.jhs:2983Scroll back to the top of whichever container actually scrolls.
| event = null | ?Event |
blockScreen(active)
mmo-app.jhs:2993Block the screen while something runs.
| active = true | boolean |
setThemeMode(scheme)
mmo-app.jhs:3001Apply a colour scheme.
| scheme = 'default' | string | - dark, light or default to follow the system |
toggleDarkMode()
mmo-app.jhs:3018Switch between the dark and light schemes.
Slots22
(default)
mmo-app.jhsthe page itself
<slot>
logo
mmo-app.jhsthe mark at the top of the rail
<slot name="logo">
menu
mmo-app.jhsrail entries written by hand, next to the ones MMO.config.menus adds
<slot name="menu">
side-foot
mmo-app.jhsthe foot of the rail, on the row the scheme switch ends
<slot name="side-foot">
user-info
mmo-app.jhsthe account line next to the account button, at the end of the top bar
<slot name="user-info">
user-card-body
mmo-app.jhswhat the account card shows when it is opened
<slot name="user-card-body">
brand
mmo-app.jhsthe brand in the top bar, for the landing and blog templates
<slot name="brand">
nav
mmo-app.jhslinks in the top bar
<slot name="nav">
actions
mmo-app.jhsbuttons on the right of the top bar
<slot name="actions">
header
mmo-app.jhsanything else on the top bar, after the actions
<slot name="header">
hero
mmo-app.jhsthe band above the page, for a landing
<slot name="hero">
page-title
mmo-app.jhsthe page header's title
<slot name="page-title">
page-actions
mmo-app.jhsthe page header's buttons
<slot name="page-actions">
navigation
mmo-app.jhsa strip between the header and the content (filters, a sub-navigation)
<slot name="navigation">
aside
mmo-app.jhsthe rail on the right of the content, for an article
<slot name="aside">
footer
mmo-app.jhsthe footer, for the landing and blog templates
<slot name="footer">
panel-title
mmo-app.jhsextra content at the end of the side panel's tab strip (its tabs are built by showPanel)
<slot name="panel-title">
panel
mmo-app.jhsthe body of the side panel
<slot name="panel">
status
mmo-app.jhsthe status bar, left of the log button
<slot name="status">
logs
mmo-app.jhsthe lines the server log tab of the developer drawer shows
<slot name="logs">
notifications
mmo-app.jhsthe notifications stacked in the corner
<slot name="notifications">
screen-blocker
mmo-app.jhswhat covers the page while it is blocked (blockScreen)
<slot name="screen-blocker">
Points d'accroche CSS13
.admin
mmo-app.jhsthe application shell: rail, breadcrumb, page tabs, side panel, status bar
.admin
.landing
mmo-app.jhsthe marketing shell: sticky translucent header, hero, sections, large footer
.landing
.blog
mmo-app.jhsthe editorial shell: header, content column, sticky rail, footer
.blog
.menu-collapsed
mmo-app.jhsthe rail is reduced to icons
.menu-collapsed
.menu-open
mmo-app.jhsthe rail is open, on a small screen
.menu-open
.has-tabs
mmo-app.jhsthe page has tabs: a small screen gives them a row of their own under the top bar
.has-tabs
.panel-open
mmo-app.jhsthe side panel is open
.panel-open
.panel-over
mmo-app.jhsthe side panel is over the page rather than beside it: it left the page too little room (placePanel)
.panel-over
.console-open
mmo-app.jhsthe developer drawer (server log, server information) is open
.console-open
.toc-open
mmo-app.jhsthe table of contents is open
.toc-open
.palette-open
mmo-app.jhsthe command palette is open, over the page
.palette-open
.has-hero
mmo-app.jhsthe page filled the hero region, so the shell makes room for it
.has-hero
.has-user-card
mmo-app.jhsthe page filled the account card, so it gets a body above the logout link
.has-user-card