/* ═══════════════════════════════════════════════════════════════
   mobile.css — The phone layout (see js/ui/MobileLayout.js).

   Design by LucyMoth (Scapewatch Mobile), used with her permission.
   Everything here is scoped to html.mobile-layout, which only phones
   get, so the desktop and Steam layouts never see these rules.

   UIRenderer draws the UI 1:1 against the viewport on phones, so the
   HUD pieces below are positioned in real CSS px. Many of them carry
   inline positions from their own modules (drag, windowed mode, the
   desktop dock math), hence the !important on placement.

   Layout: one thing on screen at a time, picked by the m-view-* class
   MobileLayout.sync() sets on <html>:
     m-view-world      the world, with the HUD around it
     m-view-panel      one dock panel as a full-height sheet
     m-view-chat       chat as a sheet
     m-view-map        the world map
     m-view-menu       the Menu sheet
     m-view-modal      a modal (bank, settings, crafting...) full screen
     m-view-dashboard  the dashboard as a sheet
   Portrait keeps the dock at the bottom; landscape (600px+ wide) turns
   it into a rail on the right and shows panels beside the world.
   ═══════════════════════════════════════════════════════════════ */

html.mobile-layout {
    --m-safe-top: env(safe-area-inset-top, 0px);
    --m-safe-bottom: env(safe-area-inset-bottom, 0px);
    --m-safe-left: env(safe-area-inset-left, 0px);
    --m-safe-right: env(safe-area-inset-right, 0px);
    --m-vh: 100vh;
    --m-dock-h: calc(64px + var(--m-safe-bottom));
    --m-rail-w: 0px;
    --m-top: var(--m-safe-top);
    --m-left: calc(8px + var(--m-safe-left));
    --m-right: calc(8px + var(--m-safe-right));
    --m-hp-h: 36px;
    /* MobileLayout measures these; the values here cover the first frame. */
    --m-hud-bottom: calc(var(--m-top) + 140px);
    --m-task-h: 96px;
    --m-sheet-top: calc(var(--m-top) + var(--m-hp-h) + 10px);
    --m-sheet-bottom: calc(var(--m-dock-h) + 8px);
    --m-sheet-left: var(--m-left);
    --m-sheet-right: var(--m-right);
    --panel-width: calc(100vw - 16px);
}

html.mobile-layout.mobile-landscape {
    --m-dock-h: 0px;
    --m-rail-w: calc(72px + var(--m-safe-right));
    --m-right: calc(8px + var(--m-rail-w));
    --m-pane-w: min(380px, 52vw);
    --m-sheet-top: calc(var(--m-top) + 8px);
    --m-sheet-bottom: calc(8px + var(--m-safe-bottom));
    --m-sheet-left: calc(100vw - var(--m-right) - var(--m-pane-w));
    --m-sheet-right: var(--m-right);
    --panel-width: var(--m-pane-w);
}

html.mobile-layout body {
    background: var(--bg-darkest, #1a1a1a);
    overscroll-behavior: none;
}

/* Scrollbars: the desktop's 8px bar (in UI pixels, which a phone draws
   1:1) is too thin to grab with a thumb. Wider here, with a thumb that
   is always at least a fingertip tall. !important because several
   panels size their own bar more specifically; the ones a panel hides
   on purpose (display: none, scrollbar-width: none) stay hidden. */
html.mobile-layout ::-webkit-scrollbar {
    width: 16px !important;
    height: 16px !important;
}
html.mobile-layout ::-webkit-scrollbar-track {
    background: var(--bg-dark) !important;
}
html.mobile-layout ::-webkit-scrollbar-thumb {
    min-height: 48px;
    background: var(--border-secondary) !important;
    border: 3px solid var(--bg-dark) !important;
    border-radius: 8px !important;
    background-clip: padding-box;
}

body.scale-mobile #game-container {
    top: 0;
    left: 0;
    width: 100vw;
    height: var(--m-vh, 100vh);
    transform: none;
}

/* Text inputs at 16px stop mobile browsers zooming in on focus. */
html.mobile-layout #ui-container :is(input:not([type='range']):not([type='checkbox']), select, textarea) {
    font-size: 16px;
}
html.mobile-layout #ui-container :is(input, textarea) {
    user-select: text;
    -webkit-user-select: text;
}
html.mobile-layout #ui-container :is(button, [role='button'], .modal-close) {
    touch-action: manipulation;
}
html.mobile-layout .modal-close {
    min-width: 44px;
    min-height: 44px;
}

/* ── Desktop chrome the dock and Menu replace ─────────────────── */

html.mobile-layout :is(
    .window-controls,
    .floating-tab-strip,
    .panel-tab-bar,
    .panel-tab-hotkey,
    .floating-tab-hotkey,
    .modal-tab-hotkey,
    .chat-resize-handle,
    .chat-resize-handle-right,
    .panel-titlebar,
    .dashboard-titlebar-btns
) {
    display: none !important;
}

/* ── Shell: dock, Menu, sheet title, toast ────────────────────── */

#m-shell {
    font-family: var(--game-font, sans-serif);
    color: var(--text-light, #cccccc);
}
#m-shell * { box-sizing: border-box; }
#m-shell button {
    font-family: inherit;
    cursor: pointer;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
}
html.mobile-layout:not(.m-ready) #m-shell,
body.login-active #m-shell,
body.sleeping #m-shell,
html.mobile-layout:has(.ledger-return-overlay, .ledger-night, .loading-screen.waiting) #m-shell {
    display: none;
}

#m-dock {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 6000;
    height: var(--m-dock-h);
    display: flex;
    padding: 4px calc(4px + var(--m-safe-right)) var(--m-safe-bottom) calc(4px + var(--m-safe-left));
    background: var(--bg-dark, #1c1c0e);
    border-top: 1px solid var(--border-primary, #5c4a2a);
}
#m-dock button {
    flex: 1;
    min-width: 44px;
    min-height: 54px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    padding: 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 3px;
    color: var(--text-light, #cccccc);
    font-size: 12px;
    line-height: 1.2;
}
#m-dock button img {
    width: 26px;
    height: 26px;
    object-fit: contain;
    image-rendering: pixelated;
}
#m-dock button[aria-current='page'] {
    background: var(--bg-cell, #3a3226);
    color: var(--text-bright, #ffff00);
    border-color: var(--text-accent, #c8a83e);
}
#m-dock button:active {
    background: var(--bg-hover, #4a4230);
}

#m-menu {
    position: fixed;
    z-index: 5990;
    top: var(--m-top);
    left: var(--m-left);
    right: var(--m-right);
    bottom: var(--m-dock-h);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0 12px 16px;
    background: var(--bg-panel, #2b2216);
}
#m-menu[hidden] { display: none; }
.m-menu-head {
    position: sticky;
    top: 0;
    z-index: 1;
    padding-top: 16px;
    background: var(--bg-panel, #2b2216);
}
#m-menu h2 {
    margin: 0;
    font-size: 20px;
    color: var(--text-bright, #ffff00);
}
.m-menu-tabs {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px;
    padding: 12px 0;
}
.m-menu-tabs button {
    min-height: 44px;
    padding: 8px 4px;
    background: var(--bg-dark, #1c1c0e);
    border: 1px solid var(--border-primary, #5c4a2a);
    border-radius: 3px;
    color: var(--text-light, #cccccc);
    font-size: 14px;
}
.m-menu-tabs button[aria-selected='true'] {
    background: var(--bg-cell, #3a3226);
    border-color: var(--text-accent, #c8a83e);
    color: var(--text-bright, #ffff00);
}
.m-menu-group h3 {
    margin: 14px 0 8px;
    font-size: 13px;
    font-weight: 600;
    color: var(--text-accent, #c8a83e);
}
.m-menu-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
}
.m-menu-item {
    width: 100%;
    min-height: 52px;
    padding: 10px;
    display: flex;
    align-items: center;
    gap: 10px;
    text-align: left;
    background: var(--bg-cell, #3a3226);
    border: 1px solid var(--border-primary, #5c4a2a);
    border-radius: 3px;
    color: var(--text-light, #cccccc);
    font-size: 14px;
    text-decoration: none;
}
.m-menu-item img {
    width: 28px;
    height: 28px;
    flex: 0 0 28px;
    object-fit: contain;
    image-rendering: pixelated;
}
.m-menu-svg {
    width: 28px;
    height: 28px;
    flex: 0 0 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-accent, #c8a83e);
    font-size: 20px;
}
.m-menu-svg svg { width: 22px; height: 22px; }
.m-menu-item:active,
.m-menu-tabs button:active {
    background: var(--bg-hover, #4a4230);
    border-color: var(--text-accent, #c8a83e);
    color: var(--text-bright, #ffff00);
}
.m-link-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.m-link-grid .m-link {
    justify-content: center;
    text-align: center;
    min-height: 48px;
    color: var(--text-accent, #c8a83e);
}
.m-credits {
    justify-content: center;
    margin-top: 16px;
    color: var(--text-accent, #c8a83e);
}
/* Credits opens from the Menu's About tab, so it sits above the Menu. */
html.mobile-layout .cc-credits-overlay {
    z-index: 6000;
}
html.mobile-layout .cc-credits-dialog {
    max-height: calc(var(--m-vh) - 32px);
}
/* Roam Map by Default does something only where the map hands its
   gestures to the page (main.js sets body.roam-touch on touch devices,
   whichever layout they use). */
body:not(.roam-touch) .settings-roam-only {
    display: none !important;
}
.m-thanks {
    margin: 14px 0 4px;
    text-align: center;
    font-size: 15px;
    color: var(--text-light);
}
.m-thanks a {
    color: var(--text-accent, #c8a83e);
}

#m-sheet-head {
    position: fixed;
    z-index: 1200;
    left: var(--m-sheet-left);
    right: var(--m-sheet-right);
    top: var(--m-sheet-top);
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 2px 4px 2px 12px;
    background: var(--bg-panel, #2b2216);
    border: 1px solid var(--border-primary, #5c4a2a);
    border-bottom: 0;
    border-radius: 4px 4px 0 0;
    color: var(--text-accent, #c8a83e);
    font-size: 16px;
}
#m-sheet-head[hidden] { display: none; }
.m-sheet-close {
    width: 44px;
    height: 44px;
    border: 0;
    background: transparent;
    color: var(--text-light, #cccccc);
    font-size: 26px;
    line-height: 1;
}

#m-toast {
    position: fixed;
    z-index: 6010;
    left: 16px;
    right: 16px;
    bottom: calc(var(--m-dock-h) + 12px);
    padding: 12px;
    background: var(--bg-dark, #1c1c0e);
    border: 1px solid var(--border-secondary, #7a6a3a);
    border-radius: 3px;
    font-size: 14px;
    pointer-events: none;
}
#m-toast[hidden] { display: none; }

/* ── World view HUD ───────────────────────────────────────────── */

html.mobile-layout .hp-bar {
    left: var(--m-left) !important;
    right: var(--m-right) !important;
    top: calc(var(--m-top) + 4px) !important;
    bottom: auto !important;
    width: auto !important;
    height: var(--m-hp-h) !important;
    border-radius: 4px !important;
    z-index: 1150 !important;
}
html.mobile-layout .hp-bar-text { font-size: 16px; }

html.mobile-layout .ingame-hud {
    top: calc(var(--m-top) + var(--m-hp-h) + 10px) !important;
    left: var(--m-left) !important;
    max-width: calc(100vw - var(--m-left) - var(--m-right) - 64px);
}
html.mobile-layout .tutorial-checklist,
html.mobile-layout .invite-tray {
    top: var(--m-hud-bottom) !important;
    left: var(--m-left) !important;
    max-width: calc(100vw - var(--m-left) - var(--m-right) - 64px);
}
/* Two invites in landscape ran down over the current-task card and hid
   the second one's buttons; the tray scrolls in the room above it. */
html.mobile-layout .invite-tray {
    max-height: calc(var(--m-vh) - var(--m-hud-bottom) - var(--m-task-h) - var(--m-dock-h) - 24px);
    overflow-y: auto;
}
/* How to Scapewatch: starts collapsed to the next tutorial on phones
   (TutorialChecklist.init). Opened, the list scrolls inside about five
   rows instead of growing down over the world. */
html.mobile-layout .tutorial-checklist {
    padding: 4px 10px 6px;
}
html.mobile-layout .tutorial-checklist-header {
    min-height: 32px;
}
html.mobile-layout .tutorial-checklist-title { font-size: 17px; }
html.mobile-layout .tutorial-checklist-close {
    font-size: 18px;
    padding: 4px 4px 4px 16px;
}
html.mobile-layout .tutorial-checklist-list {
    max-height: min(22vh, 150px);
    overflow-y: auto;
    overscroll-behavior: contain;
}
html.mobile-layout .tutorial-checklist-row {
    font-size: 15px;
    line-height: 1.75;
}
html.mobile-layout .active-potions-pill {
    top: calc(var(--m-top) + var(--m-hp-h) + 10px) !important;
    right: var(--m-right) !important;
    left: auto !important;
    bottom: auto !important;
}
html.mobile-layout .active-potions-panel {
    top: calc(var(--m-top) + var(--m-hp-h) + 64px) !important;
    right: var(--m-right) !important;
    left: auto !important;
    bottom: auto !important;
    max-width: calc(100vw - var(--m-left) - var(--m-right));
}
/* Potion rows at the queue's compact-row height (36px, was 62) with the
   icon at its own size instead of 1.5x: five potions take about 200px
   of the map instead of 330. */
html.mobile-layout .active-potions-body {
    gap: 3px;
}
html.mobile-layout .active-potions-panel .potion-row {
    height: 36px;
    padding: 0 8px 0 4px;
    gap: 6px;
    border-width: 1px;
    border-radius: 4px;
}
html.mobile-layout .active-potions-panel .potion-row-icon-wrap {
    width: 30px;
    height: 30px;
}
html.mobile-layout .active-potions-panel .potion-row-icon {
    width: 30px;
    height: 30px;
    transform: none;
}
html.mobile-layout .active-potions-panel .potion-row-icon-wrap .inv-label {
    font-size: 12px;
}
html.mobile-layout .active-potions-panel :is(.potion-row-stat-val, .potion-row-count-num) {
    font-size: 16px;
}
html.mobile-layout .active-potions-panel .potion-row-stat-icon {
    width: 18px;
    height: 18px;
}
html.mobile-layout .active-potions-panel .potion-row-count-unit {
    font-size: 12px;
}
/* ── Info bar (portrait) ──────────────────────────────────────────
   The player card, the potions panel and How to Scapewatch take turns
   in the row under the HP bar (MobileLayout._buildInfoBar): a ⋮ button
   at the far left opens a menu to pick one, and the pick shows to the
   button's right. With none picked the button is all there is.
   Landscape keeps the three beside the world as before. */
html.mobile-layout {
    --m-info-w: 30px;
}
#m-info {
    display: none;
}
html.mobile-layout:not(.mobile-landscape).m-view-world #m-info {
    position: absolute;
    display: block;
    top: calc(var(--m-top) + var(--m-hp-h) + 10px);
    left: var(--m-left);
    z-index: 1150;
}
body:is(.login-active, .sleeping, .map-active) #m-info {
    display: none !important;
}
.m-info-dots {
    position: relative;
    width: var(--m-info-w);
    height: 44px;
    display: grid;
    place-items: center;
    padding: 0;
    background: var(--bg-panel);
    border: 2px solid var(--border-primary);
    border-radius: 6px;
    color: var(--text-bright);
    font-family: var(--game-font);
    font-size: 26px;
    line-height: 1;
    text-shadow: 1px 1px 0 #000;
}
/* A thumb-sized target around a thin button. */
.m-info-dots::after {
    content: '';
    position: absolute;
    inset: -6px -8px -6px -6px;
}
.m-info-dots[aria-expanded='true'] {
    border-color: var(--text-accent);
    background: var(--bg-hover);
}
/* Opens beside the button, the first row level with it and the rest
   evenly under that, so the menu costs no height above the panels. */
.m-info-menu {
    position: absolute;
    top: 0;
    left: calc(100% + 6px);
    width: calc(100vw - var(--m-left) - var(--m-right) - var(--m-info-w) - 6px);
    max-width: 360px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.m-info-menu[hidden] {
    display: none;
}
.m-info-item {
    display: flex;
    align-items: center;
    gap: 8px;
    height: 44px;
    padding: 0 10px 0 6px;
    background: var(--bg-panel);
    border: 2px solid var(--border-secondary);
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.6);
    color: var(--text-light);
    font-family: var(--game-font);
    font-size: 17px;
    text-align: left;
    text-shadow: 1px 1px 0 #000;
    white-space: nowrap;
}
.m-info-item[hidden] {
    display: none;
}
.m-info-item[aria-checked='true'] {
    border-color: var(--text-accent);
    background: var(--bg-hover);
}
.m-info-check {
    flex: 0 0 auto;
    width: 18px;
    color: var(--text-accent);
    text-align: center;
}
.m-info-item[aria-checked='true'] .m-info-check::before {
    content: '\2713';
}
.m-info-main {
    line-height: 1.15;
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
}
.m-info-label {
    color: var(--text-bright);
}
.m-info-sub {
    display: flex;
    gap: 6px;
    min-width: 0;
    font-size: 14px;
}
.m-info-name {
    flex: 0 0 auto;
    max-width: 50%;
    overflow: hidden;
    text-overflow: ellipsis;
    color: var(--text-accent);
}
.m-info-sep {
    color: var(--text-muted);
}
.m-info-state {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}
.m-info-potions img {
    width: 24px;
    height: 24px;
    image-rendering: pixelated;
}
.m-info-potions.empty img {
    opacity: 0.5;
}
.m-info-count {
    color: var(--text-accent);
    font-variant-numeric: tabular-nums;
}
/* Only the picked one shows, to the right of the button. The potions
   pill is the menu's row now. */
html.mobile-layout:not(.mobile-landscape) .active-potions-pill,
html.mobile-layout:not(.mobile-landscape):not([data-m-info='hud']) .ingame-hud,
html.mobile-layout:not(.mobile-landscape):not([data-m-info='guide']) .tutorial-checklist,
html.mobile-layout:not(.mobile-landscape):not([data-m-info='potions']) .active-potions-panel {
    display: none !important;
}
html.mobile-layout:not(.mobile-landscape) .active-potions-panel {
    padding: 0;
}
html.mobile-layout:not(.mobile-landscape) .active-potions-panel .potion-row {
    width: auto;
}
html.mobile-layout:not(.mobile-landscape) :is(.ingame-hud, .tutorial-checklist, .active-potions-panel) {
    top: calc(var(--m-top) + var(--m-hp-h) + 10px) !important;
    left: calc(var(--m-left) + var(--m-info-w) + 6px) !important;
    right: var(--m-right) !important;
    bottom: auto !important;
    width: auto !important;
    min-width: 0 !important;
    max-width: none !important;
}

html.mobile-layout .floating-current-task {
    left: var(--m-left) !important;
    right: var(--m-right) !important;
    top: auto !important;
    bottom: calc(var(--m-dock-h) + 8px) !important;
    width: auto !important;
    max-width: none !important;
    transform: none !important;
}
/* Centred over the current-task card. */
html.mobile-layout .recenter-camera-btn {
    left: var(--m-left) !important;
    top: auto !important;
    right: var(--m-right) !important;
    bottom: calc(var(--m-dock-h) + var(--m-task-h) + 16px) !important;
    width: fit-content;
    margin: 0 auto;
    transform: none !important;
}
html.mobile-layout .xp-drops-container {
    left: 50% !important;
    top: 22% !important;
    transform: translateX(-50%);
}
/* Centred on what is left of the screen: in landscape the dock rail
   on the right covered the end of a long one ("CONGRATULATIONS!"). */
html.mobile-layout .celebration-container {
    left: var(--m-left) !important;
    width: calc(100% - var(--m-left) - var(--m-right)) !important;
}
/* Clear of the edges, so a tilted one (pet, lucky tool) keeps its
   corners on screen. NotificationManager._fitToScreen shrinks any that
   is still too big. */
html.mobile-layout .celebration-container > [class^="celeb-"] {
    box-sizing: border-box;
    max-width: calc(100% - 24px);
}
html.mobile-layout :is(.raid-contrib-hud, .gauntlet-hud) {
    left: var(--m-left) !important;
    right: auto !important;
    top: var(--m-hud-bottom) !important;
    max-width: calc(100vw - var(--m-left) - var(--m-right));
}

/* The world HUD steps aside for every full-screen view (in landscape a
   panel or chat sits beside the world, so the HUD stays for those). XP
   drops would otherwise float over the sheet the player is reading. */
html.mobile-layout:not(.m-view-world) .xp-drops-container,
html.mobile-layout:not(.mobile-landscape):not(.m-view-world) :is(
    .ingame-hud,
    .tutorial-checklist,
    .invite-tray,
    .floating-current-task,
    .active-potions-pill,
    .active-potions-panel,
    .recenter-camera-btn,
    .xp-drops-container,
    .raid-contrib-hud,
    .gauntlet-hud
),
html.mobile-layout.mobile-landscape:is(.m-view-menu, .m-view-modal, .m-view-map, .m-view-dashboard) :is(
    .ingame-hud,
    .tutorial-checklist,
    .invite-tray,
    .floating-current-task,
    .active-potions-pill,
    .active-potions-panel,
    .recenter-camera-btn,
    .raid-contrib-hud,
    .gauntlet-hud
) {
    display: none !important;
}

/* ── Dock panels as sheets ────────────────────────────────────── */

html.mobile-layout #hud-layer > :is(
    .uq-panel,
    .tasks-panel,
    .slay-tasks-panel,
    .skills-panel,
    .inventory-panel,
    .quests-panel,
    .diary-panel,
    .equipment-panel,
    .friends-panel,
    .barter-panel,
    .dashboard-panel
) {
    position: absolute !important;
    left: var(--m-sheet-left) !important;
    right: var(--m-sheet-right) !important;
    top: var(--m-sheet-top) !important;
    bottom: var(--m-sheet-bottom) !important;
    width: auto !important;
    height: auto !important;
    max-width: none !important;
    max-height: none !important;
    transform: none !important;
    overflow: auto !important;
    overscroll-behavior: contain;
    border-radius: 4px !important;
    z-index: 1100 !important;
}
/* Panels without their own heading sit under the sheet title bar. */
html.mobile-layout.m-view-panel:is(
    [data-m-panel='skills'],
    [data-m-panel='quests'],
    [data-m-panel='diary'],
    [data-m-panel='equipment'],
    [data-m-panel='friends'],
    [data-m-panel='barter']
) #hud-layer > :is(.skills-panel, .quests-panel, .diary-panel, .equipment-panel, .friends-panel, .barter-panel) {
    top: calc(var(--m-sheet-top) + 48px) !important;
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
}

/* Skills: the desktop panel's cells (icon left, level right, bar under),
   with the rows sharing the sheet's height so every skill fits without
   scrolling, in either orientation. */
html.mobile-layout #hud-layer > .skills-panel {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-auto-rows: minmax(0, 1fr);
    align-content: stretch;
    gap: 6px;
    padding: 8px;
    overflow: hidden;
}
html.mobile-layout .skills-panel :is(.skill-cell, .total-cell) {
    height: auto;
    min-height: 0;
    padding: 3px 8px;
}
html.mobile-layout .skills-panel :is(.skill-cell, .total-cell) img {
    width: 36px;
    height: 36px;
}
html.mobile-layout .skills-panel .skill-level {
    font-size: 26px;
}
html.mobile-layout.mobile-landscape #hud-layer > .skills-panel {
    gap: 4px;
    padding: 6px;
}
html.mobile-layout.mobile-landscape .skills-panel :is(.skill-cell, .total-cell) {
    padding: 2px 6px;
}
html.mobile-layout.mobile-landscape .skills-panel :is(.skill-cell, .total-cell) img {
    width: 24px;
    height: 24px;
}
html.mobile-layout.mobile-landscape .skills-panel .skill-level {
    font-size: 20px;
}

html.mobile-layout #hud-layer > .inventory-panel {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    grid-auto-rows: minmax(60px, auto);
    align-content: start;
}

html.mobile-layout .uq-rows {
    overflow-y: auto;
    overflow-x: hidden;
    flex: 1 1 auto;
    min-height: 0;
}
html.mobile-layout .uq-controls {
    flex-wrap: wrap;
    flex: 0 0 auto;
}

/* ── Task queue: QueueSheet instead of popouts ───────────────── */

/* A row's options, the running task's Skip and the slay masters open in
   QueueSheet (QueueSheet.js). The desktop popouts open to the left of
   their icon, which here is off the screen, so every holder keeps
   showing just its picked tile, whatever :hover a tap leaves behind.
   Their hover tooltips go too: the sheet's cards say the same lines. */
html.mobile-layout .uq-panel .icon-container :is(.icon-option:not(.selected), .reroll-option, .master-tile:not(.selected)) {
    display: none !important;
}
html.mobile-layout .uq-panel .icon-container .icons-wrapper {
    background: none !important;
    border: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    top: 0 !important;
}
html.mobile-layout .uq-panel .icon-tooltip {
    display: none !important;
}
html.mobile-layout .uq-panel :is(.icon-option, .master-tile):hover {
    transform: none;
}
/* Pin holds popouts open and collapse gives width back to the map;
   neither means anything with the queue filling the screen. Compact
   does, and takes their corner: drawn close to the desktop size, with
   a wider invisible hit area so a thumb still lands on it. */
html.mobile-layout .uq-panel :is(.queue-pin-btn, .queue-collapse-btn) {
    display: none !important;
}
html.mobile-layout .uq-panel .queue-compact-btn {
    right: 12px;
    bottom: 10px;
    width: 22px;
    height: 22px;
    opacity: 1;
}
html.mobile-layout .uq-panel .queue-compact-btn svg {
    width: 14px;
    height: 14px;
}
html.mobile-layout .uq-panel .queue-compact-btn::after {
    content: '';
    position: absolute;
    inset: -8px;
}

#uq-sheet-back {
    position: fixed;
    inset: 0;
    z-index: 1290;
    background: rgba(0, 0, 0, 0.5);
}
#uq-sheet {
    position: fixed;
    z-index: 1300;
    display: flex;
    flex-direction: column;
    background: var(--bg-panel);
    border: 2px solid var(--border-secondary);
    border-radius: 8px 8px 4px 4px;
    box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.7);
    overflow: hidden;
    font-family: var(--game-font);
    color: var(--text-light);
}
.uq-sheet-head {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 6px 6px 12px;
    border-bottom: 1px solid var(--border-primary);
}
.uq-sheet-title {
    flex: 1;
    min-width: 0;
    font-size: 19px;
    color: var(--text-accent);
}
.uq-sheet-x {
    width: 44px;
    height: 44px;
    font: inherit;
    font-size: 22px;
    color: var(--text-bright);
    background: var(--bg-cell);
    border: 1px solid var(--border-primary);
    border-radius: 4px;
}
.uq-sheet-list {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 12px 6px 6px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.uq-sheet-card {
    position: relative;
    /* Never squeezed below its content: a short sheet scrolls instead. */
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 64px;
    padding: 6px 8px;
    background: var(--bg-cell);
    border: 2px solid var(--border-primary);
    border-radius: 6px;
    cursor: pointer;
}
.uq-sheet-card.picked {
    border-color: var(--text-accent);
    background: var(--bg-hover);
}
.uq-sheet-card.disabled {
    opacity: 0.5;
    cursor: default;
}
.uq-sheet-card:focus-visible {
    outline: 2px solid var(--text-bright);
}
/* The tile copies keep their desktop look, at full size and full
   opacity (unpicked options are dimmed in a popout). */
.uq-sheet-card .uq-sheet-icon {
    flex: 0 0 auto;
    display: flex !important;
    opacity: 1 !important;
    transform: none !important;
    pointer-events: none;
}
.uq-sheet-card .uq-sheet-icon.icon-option {
    width: 56px;
    height: 56px;
}
.uq-sheet-card .uq-sheet-icon .uq-mob-sprite {
    width: 44px;
    height: 44px;
}
.uq-sheet-card .uq-sheet-icon.master-tile {
    width: 48px;
    height: 48px;
    align-items: center;
    justify-content: center;
}
.uq-sheet-text {
    flex: 1 1 auto;
    min-width: 0;
}
.uq-sheet-text .tt-name {
    font-size: 18px;
    color: var(--text-bright);
    white-space: normal;
    text-shadow: 1px 1px 0 #000;
}
.uq-sheet-text .tt-line {
    font-size: 15px;
    color: #ffffff;
    white-space: normal;
    text-shadow: 1px 1px 0 #000;
}
.uq-sheet-text .tt-line[data-mat-line] {
    color: var(--text-muted);
}
.uq-sheet-text .uq-inline-icon {
    width: 20px;
    height: 20px;
}
/* Sits on the card's top-left border like a label, so it takes no
   width from the text. The list's top padding and the gap between
   cards leave room for the half that rides above the border. */
.uq-sheet-tag {
    position: absolute;
    top: -9px;
    left: 10px;
    padding: 0 7px;
    font-size: 12px;
    line-height: 16px;
    white-space: nowrap;
    color: var(--text-accent);
    background: var(--bg-panel);
    border: 1px solid var(--text-accent);
    border-radius: 9px;
    pointer-events: none;
}
.uq-sheet-map {
    position: relative;
    float: right;
    width: 30px;
    height: 30px;
    margin: 0 0 2px 6px;
    display: grid;
    place-items: center;
    padding: 0;
    background: var(--bg-panel);
    border: 1px solid var(--border-primary);
    border-radius: 4px;
}
/* A bigger target than it looks, reaching into the card's corner. */
.uq-sheet-map::after {
    content: '';
    position: absolute;
    inset: -6px;
}
.uq-sheet-map img {
    width: 20px;
    height: 20px;
    image-rendering: pixelated;
}
.uq-sheet-foot {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px;
    border-top: 1px solid var(--border-primary);
}
/* [icon]  Skip this task (-5)            [↻ 1040] */
.uq-sheet-btn {
    min-height: 52px;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 12px 4px 6px;
    font: inherit;
    color: var(--text-bright);
    text-align: left;
    background: var(--bg-cell);
    border: 2px solid var(--border-secondary);
    border-radius: 4px;
}
.uq-sheet-btn[data-lane="skills"] { border-color: #5a8a3a; }
.uq-sheet-btn[data-lane="slay"] { border-color: #b8442d; }
.uq-sheet-btn:disabled {
    opacity: 0.55;
}
.uq-sheet-btn-icon {
    position: relative;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    display: grid;
    place-items: center;
}
.uq-sheet-btn-icon > img {
    width: 34px;
    height: 34px;
    image-rendering: pixelated;
    filter: drop-shadow(1px 1px 0 #000);
    opacity: 0.9;
}
.uq-sheet-btn-icon .uq-reroll-glyph {
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    font-size: 28px;
    line-height: 28px;
    color: var(--text-bright);
    text-shadow: 2px 2px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000;
    pointer-events: none;
}
.uq-sheet-btn-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.uq-sheet-btn-line {
    display: flex;
    align-items: baseline;
    gap: 6px;
    min-width: 0;
}
.uq-sheet-btn-label {
    min-width: 0;
    font-size: 18px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.uq-sheet-btn-cost {
    flex: none;
    font-size: 18px;
    white-space: nowrap;
}
.uq-sheet-btn-note {
    font-size: 13px;
    color: var(--text-muted);
}
/* The same readout as the queue footer's credits. */
.uq-sheet-btn-credits {
    flex: 0 0 auto;
    font-size: 16px;
    white-space: nowrap;
    color: var(--text-bright);
}
/* The row the sheet belongs to, outlined above the dimmed queue. */
html.mobile-layout .uq-sheet-source {
    outline: 2px solid var(--text-bright);
    outline-offset: -2px;
}

/* ── Chat as a sheet ──────────────────────────────────────────── */

html.mobile-layout:not(.m-view-chat) #chat-panel {
    display: none !important;
}
html.mobile-layout.m-view-chat #chat-panel {
    left: var(--m-sheet-left) !important;
    right: var(--m-sheet-right) !important;
    top: var(--m-sheet-top) !important;
    bottom: var(--m-sheet-bottom) !important;
    width: auto !important;
    height: auto !important;
    max-width: none !important;
    max-height: none !important;
    transform: none !important;
    z-index: 1100 !important;
    display: flex !important;
    flex-direction: column;
}

/* The channel filters were seven controls in a 28px strip (A− A+ All
   EN·W1 Proximity Friends Clan Game ▼), labels touching. Here they are
   pills: the font pair stacked at the left, the six channels in a 3 x 2
   grid. The minimize arrow goes; the
   dock's Chat button opens and closes the sheet. */
html.mobile-layout #chat-panel .chat-filter-bar {
    display: grid;
    grid-template-columns: auto repeat(3, minmax(0, 1fr));
    grid-auto-rows: 36px;
    gap: 6px;
    padding: 6px;
}
html.mobile-layout #chat-panel .chat-font-group {
    grid-row: span 2;
    flex-direction: column;
    gap: 6px;
}
html.mobile-layout #chat-panel :is(.chat-font-btn, .chat-filter-btn) {
    height: 36px;
    background: var(--bg-panel);
    border: 1px solid var(--border-primary);
    border-radius: 4px;
}
html.mobile-layout #chat-panel .chat-font-btn {
    width: 44px;
    font-size: 15px;
    color: var(--text-light);
}
html.mobile-layout #chat-panel .chat-filter-btn {
    flex: none;
    min-width: 0;
    padding: 0 6px;
    font-size: 15px;
    white-space: nowrap;
}
html.mobile-layout #chat-panel .chat-filter-btn.active {
    border-color: currentColor;
}
html.mobile-layout #chat-panel .chat-filter-label {
    overflow: hidden;
    text-overflow: ellipsis;
}
html.mobile-layout #chat-panel .chat-toggle-btn {
    display: none;
}

/* ── Modals full screen ───────────────────────────────────────── */

html.mobile-layout .modal-overlay {
    top: var(--m-top) !important;
    left: 0 !important;
    width: 100% !important;
    height: calc(var(--m-vh) - var(--m-top) - var(--m-dock-h)) !important;
    padding: 0 !important;
    align-items: stretch !important;
    justify-content: stretch !important;
}
html.mobile-layout .modal-container {
    width: 100% !important;
    height: 100% !important;
    max-width: none !important;
    max-height: 100% !important;
    min-width: 0 !important;
    border-radius: 0 !important;
}
/* The Menu reaches every tab, so the modal's own tab rail goes. */
html.mobile-layout .modal-container > .modal-tabs {
    display: none !important;
}
html.mobile-layout .modal-main {
    min-width: 0;
    min-height: 0;
    width: 100%;
}
html.mobile-layout .modal-header {
    padding: 8px;
    gap: 8px;
    flex-wrap: wrap;
    min-height: 56px;
}
html.mobile-layout .modal-header .header-left {
    gap: 8px;
    min-width: 0;
    flex: 1;
}
html.mobile-layout .header-icon {
    width: 36px;
    height: 36px;
}
html.mobile-layout .header-name { font-size: 22px; }
html.mobile-layout .header-stats {
    flex-wrap: wrap;
    gap: 6px;
}
html.mobile-layout .modal-close {
    margin-right: 0 !important;
    flex-shrink: 0;
}
html.mobile-layout .processing-nav {
    position: static !important;
    transform: none !important;
    flex-wrap: wrap;
}
html.mobile-layout .modal-body {
    min-height: 0;
    min-width: 0;
    overflow: auto !important;
}
html.mobile-layout .tab-content {
    min-width: 0;
    max-width: 100%;
    overflow: auto;
    padding: 10px;
}
html.mobile-layout .tab-content.active.layout-row {
    flex-direction: column;
}
/* Two-column screens stack: the list, then the detail. */
html.mobile-layout :is(
    .bank-layout,
    .mob-layout,
    .quest-layout,
    .proc-main-layout,
    .skill-custom-tab .main-layout,
    .skill-custom-tab .columns-container
) {
    flex-direction: column !important;
    min-height: 0;
    height: auto !important;
    overflow: visible !important;
    gap: 12px;
}
html.mobile-layout :is(
    .bank-side,
    .equip-side,
    .mob-list-side,
    .mob-detail-side,
    .quest-list-side,
    .quest-detail-side,
    .proc-tier-sidebar,
    .proc-content,
    .settings-section,
    .skill-custom-tab .history-sidebar,
    .skill-custom-tab .column
) {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    flex: 0 0 auto !important;
    height: auto !important;
    overflow: visible !important;
}
html.mobile-layout :is(
    .mob-list,
    .quest-list,
    .bank-grid,
    .proc-tier-list,
    .skill-custom-tab .column-scroll,
    .skill-custom-tab .history-scroll
) {
    max-height: 60vh;
    overflow: auto !important;
    min-height: 0;
}
html.mobile-layout :is(.bank-toolbar, .bank-header, .bank-controls, .settings-toggle-row) {
    flex-wrap: wrap;
    gap: 8px;
}
html.mobile-layout .bank-search {
    min-width: 100px;
    width: auto;
    flex: 1;
}
html.mobile-layout .bank-grid {
    grid-template-columns: repeat(auto-fill, minmax(52px, 1fr)) !important;
}
/* The Ledger's loot groups (New Unlocks, New Collections, Items) reuse
   the bank grid. They sit in a page that scrolls as a whole, so they
   take their full height instead of the bank's capped, scrolling box
   (which drew a scrollbar inside the welcome-back card). */
html.mobile-layout .bank-grid.ledger-lootgrid {
    max-height: none;
    overflow: visible !important;
}
/* Bank equipment side: the 3 x 146px paperdoll is wider than a phone
   (the ammo column was cut off), and the Auto Loadout button pinned in
   the corner covered the loadout name. Here it gets its own row. */
html.mobile-layout .equip-display .paperdoll {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    width: 100%;
}
html.mobile-layout .equip-display > .cd-open-btn {
    position: static;
    margin-bottom: 6px;
}
html.mobile-layout .equip-title { font-size: 28px; }
html.mobile-layout .settings-section {
    padding: 12px !important;
}
html.mobile-layout .settings-toggle-desc { font-size: 14px; }
html.mobile-layout .diary-modal-grid {
    grid-template-columns: 1fr !important;
}
/* Centred items in a scroller overflow both ends and the left end
   can't be scrolled to, so start the row at the left. */
html.mobile-layout .settings-header-nav {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
}

/* Full-screen views have their own headers; the HP bar is world HUD. */
html.mobile-layout:is(.m-view-map, .m-view-menu, .m-view-modal, .m-view-dashboard) .hp-bar {
    display: none !important;
}

/* ── Screens ──────────────────────────────────────────────────── */

/* Every modal header: title and close share the first row; anything
   else the screen puts in its header (the group's icon nav, the Unlocks
   view switcher, the collections count, the ledger greeting...) wraps
   onto its own full-width row below. */
html.mobile-layout .modal-header {
    display: flex !important;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 8px;
}
html.mobile-layout .modal-header > .header-left {
    order: 1;
    flex: 1 1 0;
    min-width: 0;
}
html.mobile-layout .modal-header > .modal-close {
    order: 2;
    flex: 0 0 44px;
    width: 44px;
    height: 44px;
}
html.mobile-layout .modal-header > :not(.header-left):not(.modal-close) {
    order: 3;
    flex: 1 1 100%;
    min-width: 0;
    max-width: 100%;
    margin: 0 !important;
    position: static !important;
    transform: none !important;
}
html.mobile-layout .modal-header > :is(.processing-nav, .unlocks-header-slot) {
    justify-content: flex-start;
    gap: 6px;
    overflow-x: auto;
}
html.mobile-layout .modal-header > .collections-indicator {
    flex: 0 1 auto;
}
html.mobile-layout .processing-nav .processing-nav-btn {
    min-width: 44px;
    height: 44px;
    flex-shrink: 0;
}
html.mobile-layout .processing-nav .processing-nav-tooltip { display: none; }
html.mobile-layout .modal-header .header-info-group { min-width: 0; }
html.mobile-layout #ui-container .modal-header .header-name {
    font-size: 19px;
    line-height: 1.2;
    white-space: normal;
    overflow-wrap: anywhere;
}
html.mobile-layout #ui-container .modal-header .header-stats {
    font-size: 12px;
    gap: 4px 8px;
}

/* Skill setup: one scrolling page. The overview is a two-column grid of
   skill tiles in the desktop grid's pairs (SkillCustomModal.
   _orderTilesForPhone numbers them), each with its own - / + bar. */
html.mobile-layout .skill-custom-tab {
    height: auto;
    min-height: 100%;
    width: 100%;
    min-width: 0;
    overflow: visible;
}
/* The modal's own close button is enough; the tab's second one goes. */
html.mobile-layout .skill-custom-tab > .modal-close { display: none !important; }
html.mobile-layout .skill-custom-tab .skill-custom-navbar {
    width: 100%;
    min-width: 0;
    gap: 4px;
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    flex-shrink: 0;
}
html.mobile-layout .skill-custom-tab .skill-custom-nav-icon {
    width: 44px;
    height: 44px;
    flex: 0 0 44px;
}
/* The skills you can customize first (they carry a credit badge), the
   ten combat skills after them: the strip opened on ten icons that do
   nothing when tapped, with the skill being edited off screen.
   SkillCustomModal._scrollNavToActive brings the current one into view. */
html.mobile-layout .skill-custom-tab .skill-custom-nav-icon.non-rollable {
    order: 1;
}
/* Sideways strips swipe; a 16px scrollbar under them (the phone's wide
   bar, top of this file) only covered the icons. */
html.mobile-layout .skill-custom-tab :is(.skill-custom-navbar, .unlocks-row, .unlocks-grid) {
    scrollbar-width: none;
}
html.mobile-layout .skill-custom-tab :is(.skill-custom-navbar, .unlocks-row, .unlocks-grid)::-webkit-scrollbar {
    display: none !important;
    width: 0 !important;
    height: 0 !important;
}
/* Header: name and reset on one row, credits and tasks on the next, then
   (on a skill's page) the weight lever and its unlocks. */
html.mobile-layout .skill-custom-tab > .modal-header {
    display: grid !important;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 6px 10px;
    padding: 10px 12px !important;
}
html.mobile-layout .skill-custom-tab > .modal-header > * {
    order: 0 !important;
    margin: 0 !important;
    min-width: 0;
}
html.mobile-layout .skill-custom-tab > .modal-header > .header-left { grid-column: 1; grid-row: 1; }
html.mobile-layout .skill-custom-tab > .modal-header > .header-reset-btn {
    grid-column: 2;
    grid-row: 1;
    width: 44px !important;
    height: 44px !important;
    border-radius: 8px !important;
    display: flex !important;
    align-items: center;
    justify-content: center;
}
html.mobile-layout .skill-custom-tab > .modal-header > :is(.header-right, .header-mid-left, .header-mid-right) {
    grid-column: 1 / -1;
}
html.mobile-layout .skill-custom-tab > .modal-header > :is(.header-mid-left, .header-mid-right):empty { display: none !important; }
html.mobile-layout .skill-custom-tab > .modal-header > .header-right {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: baseline;
    gap: 4px 12px;
    text-align: left !important;
}
html.mobile-layout .skill-custom-tab .header-info { min-width: 0; }
html.mobile-layout .skill-custom-tab .header-name {
    font-size: 18px;
    line-height: 1.15;
    white-space: normal;
}
html.mobile-layout .skill-custom-tab .header-stats {
    font-size: 13px;
    flex-wrap: wrap;
}
html.mobile-layout .skill-custom-tab :is(.cred-display, .tasks-completed-text, .skill-weight-label) {
    font-size: 15px;
}
html.mobile-layout .skill-custom-tab .header-mid-left {
    display: flex !important;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}
html.mobile-layout .skill-custom-tab .lever-control {
    width: 100%;
    min-width: 0;
    gap: 6px;
    order: 2;
}
html.mobile-layout .skill-custom-tab .lever-track {
    flex: 1 1 50px;
    min-width: 20px;
    justify-content: space-between;
}
/* The multiplier beside "Skill Weight:" instead of alone on a line. */
html.mobile-layout .skill-custom-tab .header-mid-left .lever-mult {
    order: 1;
    margin-left: auto !important;
}
html.mobile-layout .skill-custom-tab .header-mid-left .lever-value:empty { display: none; }
html.mobile-layout .skill-custom-tab .lever-btn {
    width: 44px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
}
html.mobile-layout .skill-custom-tab .lever-mult { font-size: 15px; }
/* A skill's eight pets and capes share the width (they ran 6px past it
   and scrolled, under a scrollbar). */
html.mobile-layout .skill-custom-tab .header-mid-right .unlocks-row {
    display: flex;
    flex-wrap: nowrap;
    justify-content: space-between;
    gap: 4px;
    width: 100%;
    overflow: hidden;
}
html.mobile-layout .skill-custom-tab .header-mid-right .unlock-item {
    flex: 0 1 40px;
    min-width: 0;
    width: auto;
    height: auto;
    aspect-ratio: 1;
    box-sizing: border-box;
}
html.mobile-layout .skill-custom-tab .header-mid-right .unlock-item img {
    max-width: 100%;
    max-height: 100%;
}
html.mobile-layout .skill-custom-tab :is(.main-layout, .columns-container, .column, .total-content) {
    width: 100%;
    min-width: 0;
    height: auto !important;
    min-height: 0;
    flex: 0 0 auto !important;
    overflow: visible !important;
}
html.mobile-layout .skill-custom-tab :is(.column-scroll, .history-scroll) {
    max-height: none;
    height: auto;
    overflow: visible !important;
}
html.mobile-layout .skill-custom-tab .history-sidebar { order: 2; }
html.mobile-layout .skill-custom-tab .column-title { font-size: 20px; }
html.mobile-layout .skill-custom-tab :is(.unlocks-grid-title, .skill-columns-title) { font-size: 20px; }
html.mobile-layout .skill-custom-tab :is(.unlocks-grid-header, .skill-columns-header) {
    min-height: 40px;
    height: auto;
}

/* Overview: weights first, the unlocks grid after. */
html.mobile-layout .skill-custom-tab .total-content {
    display: flex !important;
    flex-direction: column;
    gap: 8px;
}
html.mobile-layout .skill-custom-tab .skill-columns-section { order: -1; }
html.mobile-layout .skill-custom-tab .skill-columns-grid {
    display: grid !important;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    padding: 8px;
    overflow: visible;
}
html.mobile-layout .skill-custom-tab :is(.skill-col, .skill-col-body) { display: contents; }
html.mobile-layout .skill-custom-tab .skill-col-header { display: none; }
html.mobile-layout .skill-custom-tab .skill-weight-row {
    display: grid;
    grid-template-columns: 30px minmax(0, 1fr) auto;
    grid-template-areas: "icon name pct" "icon lv pct" "ctrl ctrl ctrl";
    gap: 0 8px;
    align-items: center;
    min-height: 0;
    padding: 8px;
    background: var(--bg-cell);
    border: 1px solid var(--border-primary);
    border-radius: 8px;
}
html.mobile-layout .skill-custom-tab .skill-weight-row[data-sc-side="left"] { grid-column: 1; }
html.mobile-layout .skill-custom-tab .skill-weight-row[data-sc-side="right"] { grid-column: 2; }
html.mobile-layout .skill-custom-tab .skill-weight-row .swr-skill { display: contents; }
html.mobile-layout .skill-custom-tab .swr-skill-icon {
    grid-area: icon;
    width: 28px;
    height: 28px;
}
html.mobile-layout .skill-custom-tab .swr-skill-name {
    grid-area: name;
    align-self: end;
    font-size: 16px;
}
html.mobile-layout .skill-custom-tab .swr-level {
    grid-area: lv;
    align-self: start;
    width: auto;
    font-size: 12px;
    color: var(--text-muted);
}
html.mobile-layout .skill-custom-tab .swr-pct {
    grid-area: pct;
    width: auto;
    margin: 0;
    font-size: 18px;
}
html.mobile-layout .skill-custom-tab .swr-weight {
    grid-area: ctrl;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    width: auto;
    margin-top: 8px;
}
html.mobile-layout .skill-custom-tab .swr-weight:empty { display: none; }
html.mobile-layout .skill-custom-tab .swr-weight .control-emoji { display: none; }
html.mobile-layout .skill-custom-tab .swr-weight .ctrl-btn {
    width: auto;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
}
html.mobile-layout .skill-custom-tab .swr-automater-row {
    grid-column: 1 / -1;
    grid-template-areas: "icon name lv" "cells cells cells";
    max-width: none;
}
/* Its level cell holds the turn-all-on button. */
html.mobile-layout .skill-custom-tab .swr-automater-row .swr-level {
    align-self: center;
    font-size: 22px;
    color: var(--text-bright);
}
html.mobile-layout .skill-custom-tab .swr-automater-row .swr-automater-cells {
    grid-area: cells;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 8px;
    position: static;
    width: auto;
}
/* Unlocks: the desktop's 31 columns at a phone size, scrolling sideways. */
html.mobile-layout .skill-custom-tab .unlocks-grid {
    grid-template-columns: repeat(31, 40px);
    grid-auto-rows: 40px;
    justify-content: start;
    overflow-x: auto;
}
html.mobile-layout .skill-custom-tab .unlocks-grid > * {
    width: 40px;
    height: 40px;
}
html.mobile-layout .skill-custom-tab .unlocks-grid img {
    max-width: 32px;
    max-height: 32px;
}

/* A skill's page (Fish, Cook, Slay...): a list. Each activity has its
   details on one line (level, icon, name, %, quantity) and its Weight
   and Quantity buttons on the next; each node is one row with its own
   buttons. The column labels go; Nodes keeps its sort as chips. */
html.mobile-layout .skill-custom-tab .column-header {
    flex-wrap: wrap;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 10px;
}
html.mobile-layout .skill-custom-tab .column-subtitle { font-size: 14px; }
html.mobile-layout .skill-custom-tab .activities-subheader { display: none; }
html.mobile-layout .skill-custom-tab .nodes-subheader {
    gap: 6px;
    padding: 8px 10px;
}
html.mobile-layout .skill-custom-tab .nodes-subheader::before {
    content: "Sort";
    font-size: 14px;
    color: var(--text-muted);
}
html.mobile-layout .skill-custom-tab .nodes-subheader .sh-info-section {
    flex: none;
    gap: 6px;
    overflow: visible;
}
html.mobile-layout .skill-custom-tab .nodes-subheader .sh-sortable {
    flex: none;
    width: auto;
    min-height: 34px;
    display: inline-flex;
    align-items: center;
    padding: 6px 10px;
    font-size: 14px;
    background: var(--bg-cell);
    border: 1px solid var(--border-primary);
    border-radius: 6px;
}
html.mobile-layout .skill-custom-tab .nodes-subheader :is(.sh-nchance, .sh-ctrl-section) { display: none; }
html.mobile-layout .skill-custom-tab .activity-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
    min-height: 0;
    padding: 10px;
}
html.mobile-layout .skill-custom-tab .activity-info {
    gap: 6px 8px;
    overflow: visible;
}
html.mobile-layout .skill-custom-tab .activity-info > * {
    flex: none;
    width: auto;
    font-size: 16px;
}
html.mobile-layout .skill-custom-tab .activity-info > .activity-name {
    flex: 1 1 auto;
    min-width: 0;
}
html.mobile-layout .skill-custom-tab .activity-item-icon {
    width: 28px;
    height: 28px;
}
html.mobile-layout .skill-custom-tab .lock-icon { font-size: 14px; }
html.mobile-layout .skill-custom-tab .activity-row .row-controls {
    justify-content: flex-end;
    gap: 16px;
}
html.mobile-layout .skill-custom-tab .node-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 4px 10px;
    min-height: 0;
    padding: 10px;
}
html.mobile-layout .skill-custom-tab .node-info {
    display: grid;
    grid-template-columns: auto auto 1fr;
    gap: 2px 10px;
    overflow: visible;
}
html.mobile-layout .skill-custom-tab .node-name-wrap { grid-column: 1 / -1; }
html.mobile-layout .skill-custom-tab .node-name { font-size: 16px; }
html.mobile-layout .skill-custom-tab .node-info > :is(.node-bank, .node-dist, .node-chance) {
    width: auto;
    font-size: 13px;
    text-align: left;
}
html.mobile-layout .skill-custom-tab :is(.activity-row, .node-row).hidden { display: none; }
/* Landscape has room for an activity's buttons beside its details. */
html.mobile-layout.mobile-landscape .skill-custom-tab .activity-row {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
}
/* A skill's page shows one list at a time under tabs (SkillCustomModal.
   _renderPhoneTabs): the activities, the nodes or the history. Stacked,
   they made a ~3,500px page with the nodes ~1,500px down. The tabs stay
   at the top while a list scrolls; a chip shows the filter in force
   (a node narrows the activities, an activity highlights its nodes) and
   clears it. */
html.mobile-layout .skill-custom-tab .sc-phone-tabs {
    display: flex;
    flex-direction: column;
    gap: 8px;
    position: sticky;
    top: -10px;
    z-index: 3;
    margin: 0 -10px;
    padding: 10px;
    background: var(--bg-dark);
    border-bottom: 1px solid var(--border-primary);
}
html.mobile-layout .skill-custom-tab .sc-phone-tabs:empty { display: none; }
html.mobile-layout .skill-custom-tab .sc-phone-tabbar {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
}
html.mobile-layout .skill-custom-tab .sc-phone-tab {
    min-height: 44px;
    padding: 0 6px;
    font: inherit;
    font-size: 16px;
    color: var(--text-light);
    background: var(--bg-cell);
    border: 1px solid var(--border-primary);
    border-radius: 6px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
html.mobile-layout .skill-custom-tab .sc-phone-tab.active {
    color: var(--text-accent);
    border-color: var(--text-accent);
    background: var(--bg-panel);
}
html.mobile-layout .skill-custom-tab .sc-phone-chip {
    align-self: flex-start;
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 100%;
    min-height: 36px;
    padding: 0 12px;
    font: inherit;
    font-size: 15px;
    color: var(--text-bright);
    background: var(--bg-cell);
    border: 1px solid var(--text-accent);
    border-radius: 18px;
    box-sizing: border-box;
}
html.mobile-layout .skill-custom-tab .sc-phone-chip-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
html.mobile-layout .skill-custom-tab .sc-phone-chip-x { color: var(--text-accent); }
html.mobile-layout .skill-custom-tab[data-sc-tab="act"] :is(#nodes-column, .history-sidebar),
html.mobile-layout .skill-custom-tab[data-sc-tab="node"] :is(#activities-column, .history-sidebar),
html.mobile-layout .skill-custom-tab[data-sc-tab="hist"] .columns-container {
    display: none !important;
}
/* Slay mobs: the 64px sprite sat in the name line and made every row
   ~130px tall, and names were cut off. Here the sprite stands left of
   both lines and a long name wraps. */
html.mobile-layout .skill-custom-tab[data-skill="slay"] #activities-column .activity-row {
    position: relative;
    padding-left: 70px;
    min-height: 76px;
}
html.mobile-layout .skill-custom-tab[data-skill="slay"] #activities-column .slay-mob-sprite {
    position: absolute;
    left: 6px;
    top: 50%;
    width: 60px;
    height: 60px;
    transform: translateY(-50%);
}
html.mobile-layout .skill-custom-tab[data-skill="slay"] #activities-column .activity-name {
    white-space: normal;
    line-height: 1.15;
}
html.mobile-layout .skill-custom-tab[data-skill="slay"] #activities-column .row-controls {
    gap: 8px;
}

/* Slay Masters: the portraits are sized inline at 128px. */
html.mobile-layout .skill-custom-tab .node-row .node-info > img {
    width: 64px !important;
    height: 64px !important;
}
html.mobile-layout .skill-custom-tab :is(.activity-row, .node-row) .control-group {
    gap: 6px;
    margin-left: 0;
}
html.mobile-layout .skill-custom-tab :is(.activity-row, .node-row) .ctrl-btn {
    width: 44px;
    height: 38px;
    font-size: 22px;
}

/* Appearance: preview on top, the slot pickers below. */
html.mobile-layout #tab-customize.active {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    overflow: hidden;
    padding: 0;
}
html.mobile-layout .character-creator.creator-layout {
    width: 100%;
    min-width: 0;
    height: 100%;
    flex-direction: column;
    overflow-y: auto;
}
html.mobile-layout .character-creator .creator-preview {
    width: 100%;
    min-width: 0;
    max-width: 100%;
    padding: 6px 8px;
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr);
    grid-template-rows: 44px 44px auto;
    gap: 4px 8px;
    align-items: center;
    border-right: 0;
    border-bottom: 2px solid var(--border-primary);
}
html.mobile-layout .character-creator .creator-preview h3 { display: none; }
html.mobile-layout .character-creator .cc-canvas-wrap {
    grid-column: 1;
    grid-row: 1 / 3;
    width: 96px !important;
    height: 96px !important;
}
html.mobile-layout .character-creator .cc-canvas-wrap > canvas {
    width: 100% !important;
    height: 100% !important;
    image-rendering: pixelated;
}
html.mobile-layout .character-creator .cc-dir-btns {
    grid-column: 2;
    grid-row: 1;
    display: grid;
    grid-template-columns: repeat(4, minmax(44px, 1fr));
    gap: 4px;
}
html.mobile-layout .character-creator .cc-play-btn {
    grid-column: 2;
    grid-row: 2;
    min-height: 44px;
}
html.mobile-layout .character-creator .cc-save-area {
    grid-column: 1 / -1;
    grid-row: 3;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
}
html.mobile-layout .character-creator .cc-save-btn {
    min-height: 44px;
    font-size: 14px !important;
    white-space: normal;
}
html.mobile-layout .character-creator .cc-layers-summary {
    grid-column: 1 / -1;
    width: 100%;
    max-height: none;
    padding: 8px 4px;
}
/* The slot categories become a sideways strip above the pickers. */
html.mobile-layout .character-creator .creator-sidebar {
    width: 100% !important;
    min-width: 0 !important;
    flex: 0 0 auto !important;
    height: auto !important;
    display: flex;
    flex-direction: row !important;
    flex-wrap: nowrap;
    gap: 4px;
    padding: 4px;
    overflow-x: auto !important;
    overflow-y: hidden !important;
}
html.mobile-layout .character-creator .creator-sidebar > * { flex: 0 0 auto; }
html.mobile-layout .character-creator .creator-center {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
    flex: 0 0 auto !important;
    height: auto !important;
    overflow: visible !important;
}
html.mobile-layout .character-creator :is(.cc-slot-row, .cc-variant-row) select {
    min-width: 0;
    width: 100%;
    max-width: 100%;
    flex: 1 1 0;
}
/* Pack cards: three across is ~110px each on a phone, so stack them and
   put the Steam button under the text instead of pinned over the title. */
html.mobile-layout .character-creator .cc-pack-banner {
    flex-direction: column;
    gap: 8px;
}
html.mobile-layout .character-creator .cc-pack-card {
    /* Desktop's flex: 1 1 0 collapses a hidden-overflow card to its
       padding once the row turns into a column. */
    flex: 0 0 auto;
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr);
    align-items: start;
    height: auto;
    gap: 6px 10px;
    padding: 8px 10px;
}
html.mobile-layout .character-creator .cc-pack-icon { grid-row: span 2; align-self: center; }
html.mobile-layout .character-creator .cc-pack-text { padding-top: 0; }
html.mobile-layout .character-creator .cc-pack-title {
    padding-right: 0;
    font-size: 17px;
    line-height: 22px;
}
html.mobile-layout .character-creator .cc-pack-status { white-space: normal; }
html.mobile-layout .character-creator .cc-pack-cue {
    position: static;
    grid-column: 2;
    justify-self: start;
    min-height: 36px;
}

/* Ledger: greeting on one row, the auto-open switches and period tabs
   on the next, scrolling sideways. On one row they ran over each other. */
html.mobile-layout .modal-header .ledger-header-slot { margin: 0; }
html.mobile-layout .ledger-top {
    flex-wrap: wrap;
    gap: 6px;
}
html.mobile-layout .ledger-top-left {
    flex: 1 1 100%;
    flex-wrap: wrap;
    gap: 2px 12px;
}
html.mobile-layout .modal-header .ledger-header-slot .ledger-title {
    font-size: 18px;
    white-space: normal;
}
/* The four periods share the row evenly (a long name wraps inside its
   tab); the two auto-open switches sit under them. */
html.mobile-layout .ledger-tabs {
    flex: 1 1 100%;
    min-width: 0;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 4px;
}
html.mobile-layout .ledger-opens {
    grid-column: 1 / -1;
    order: 1;
    gap: 16px;
    margin: 0;
}
html.mobile-layout :is(.ledger-tab, .ledger-toggle) {
    display: inline-flex;
    align-items: center;
    min-height: 40px;
}
html.mobile-layout .ledger-tab {
    justify-content: center;
    padding: 4px;
    font-size: 13px;
    line-height: 1.15;
    text-align: center;
}
html.mobile-layout .ledger-toggle {
    min-height: 34px;
    white-space: nowrap;
}
/* Landscape is short: the switches go on the tabs' row. */
html.mobile-layout.mobile-landscape .ledger-tabs {
    grid-template-columns: auto repeat(4, minmax(0, 1fr));
}
html.mobile-layout.mobile-landscape .ledger-opens {
    grid-column: auto;
    order: 0;
    gap: 12px;
    margin-right: 6px;
}
html.mobile-layout.mobile-landscape .ledger-tab { min-height: 36px; }

/* The page itself: the welcome-back card's shape. On the desktop it is
   three fixed columns (380 + 640 + the rest), which put Skills and Loot
   off a phone's right edge under a 192px portrait. Here the overview is
   the card's identity row (small portrait, the two badges; the header
   already greets by name), then Milestones, Skills and Loot down one
   scrolling page, two columns in landscape like the card. */
html.mobile-layout #tab-ledger { padding: 8px; }
html.mobile-layout .ledger {
    height: auto;
    gap: 10px;
}
html.mobile-layout .ledger-body {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 10px;
    flex: none;
}
html.mobile-layout.mobile-landscape .ledger-body {
    display: grid;
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    grid-template-rows: auto;
    align-items: start;
}
html.mobile-layout.mobile-landscape .ledger-col-left { grid-row: span 2; }
html.mobile-layout .ledger-col { gap: 10px; }
html.mobile-layout :is(.ledger-col-mid, .ledger-col-right) { max-height: none; }
html.mobile-layout #tab-ledger .ledger-sec { padding: 10px 12px; }
/* Natural height: the page scrolls, not each section. */
html.mobile-layout :is(.ledger-skills, .ledger-loot) > .ledger-sec-body {
    max-height: none;
    overflow-y: visible !important;
}
html.mobile-layout .ledger-skills > .ledger-sec-body { overflow-x: auto !important; }
html.mobile-layout .ledger-hero .ledger-sec-body {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    padding: 0;
}
html.mobile-layout .ledger-hero :is(.ledger-portrait, .ledger-portrait-canvas) {
    width: 64px;
    height: 64px;
    flex: 0 0 64px;
}
html.mobile-layout .ledger-hero .ledger-name { display: none; }
html.mobile-layout .ledger-hero .ledger-badges {
    flex-wrap: wrap;
    gap: 8px;
    margin: 0;
}

/* Diary: desktop heading sizes read as shouting on a phone. */
html.mobile-layout .diary-modal-title { font-size: 20px !important; }
html.mobile-layout #ui-container .diary-modal-sub { font-size: 14px; }
html.mobile-layout .diary-modal-help {
    font-size: 14px !important;
    line-height: 1.5;
}
html.mobile-layout .diary-modal-card :is(.diary-bank-name, .diary-bank-count) { font-size: 16px; }
html.mobile-layout .diary-modal-card .diary-step { font-size: 14px; }

/* Settings: one column, the section tabs scroll sideways. */
html.mobile-layout #tab-settings.active {
    display: block;
    padding: 8px;
    overflow-x: hidden;
    overflow-y: auto;
}
html.mobile-layout #tab-settings .settings-section {
    width: 100% !important;
    margin: 0 0 16px;
    padding: 12px !important;
    scroll-margin-top: 108px;
}
html.mobile-layout #tab-settings .settings-search-bar {
    width: auto;
    gap: 6px;
}
html.mobile-layout #tab-settings .settings-nav-btn {
    flex: 0 0 auto;
    min-height: 44px;
    font-size: 14px;
    white-space: nowrap;
}
html.mobile-layout #tab-settings :is(.settings-section-header, .settings-subheading) {
    font-size: 20px;
    line-height: 1.3;
    overflow-wrap: anywhere;
}
html.mobile-layout #tab-settings .settings-toggle-row {
    min-height: 56px;
    align-items: center;
    gap: 8px;
}
html.mobile-layout #tab-settings .settings-toggle-text {
    min-width: 0;
    flex: 1 1 140px;
    margin: 0;
}
html.mobile-layout #tab-settings .settings-toggle-label { font-size: 15px; }
html.mobile-layout #tab-settings .settings-toggle-desc { font-size: 13px; line-height: 1.4; }
html.mobile-layout #tab-settings :is(.settings-quality-control, .settings-sound-controls, .settings-icon-size-control, .settings-account-row) {
    min-width: 0;
    max-width: 100%;
    flex-wrap: wrap;
    gap: 6px;
}

/* Hiscores: categories scroll sideways above the table. */
html.mobile-layout #tab-hiscores.active {
    display: flex;
    flex-direction: column;
    min-height: 0;
    height: 100%;
    padding: 8px;
    gap: 8px;
    overflow: hidden;
}
html.mobile-layout .hiscores-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto minmax(0, 1fr);
    flex: 1;
    min-height: 0;
    gap: 8px;
    overflow: hidden;
    padding: 0;
}
html.mobile-layout .hs-categories {
    display: flex;
    gap: 4px;
    width: auto;
    min-width: 0;
    padding: 4px;
    overflow-x: auto;
    overflow-y: hidden;
}
html.mobile-layout .hs-categories :is(.hs-cat-title, .hs-cat-divider) { display: none; }
html.mobile-layout .hs-cat-item {
    flex: 0 0 auto;
    min-height: 44px;
    padding: 8px;
    margin: 0;
    font-size: 14px;
}
html.mobile-layout .hs-controls {
    grid-row: 2;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    width: auto;
    min-width: 0;
    padding: 6px;
    gap: 6px;
}
html.mobile-layout .hs-search-section {
    min-width: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 52px;
    gap: 4px;
}
html.mobile-layout .hs-search-section label { grid-column: 1 / -1; font-size: 12px; margin: 0; }
html.mobile-layout #ui-container .hs-search-input { min-width: 0; width: 100%; margin: 0; }
html.mobile-layout .hs-your-rank-btn { grid-column: 1 / -1; min-height: 44px; }
html.mobile-layout .hs-leaderboard {
    grid-row: 3;
    width: 100%;
    min-width: 0;
    min-height: 0;
    overflow-x: hidden;
    overflow-y: auto;
}
html.mobile-layout .hs-leaderboard .hs-table {
    width: 100%;
    table-layout: fixed;
    font-size: 13px;
}
html.mobile-layout .hs-leaderboard .hs-table :is(th, td) {
    padding: 8px 4px;
    white-space: normal;
    overflow-wrap: anywhere;
}
/* Fixed widths for the number columns; the name takes the rest. */
html.mobile-layout .hs-leaderboard .hs-table .rank-col { width: 44px; }
html.mobile-layout .hs-leaderboard .hs-table .level-col { width: 64px; }
html.mobile-layout .hs-leaderboard .hs-table .xp-col { width: 96px; }
html.mobile-layout .hs-leaderboard .hs-table .name-col { width: auto; overflow-wrap: normal; word-break: normal; }

/* Monsters: the list, then the selected monster's details. */
html.mobile-layout #tab-mobs.active {
    display: block;
    overflow-x: hidden;
}
html.mobile-layout .mob-list-scroll {
    max-height: 38vh;
    overflow-x: hidden;
}
html.mobile-layout .mob-detail-top {
    flex-direction: column;
    overflow: visible;
}
html.mobile-layout :is(.mob-info-panel, .mob-config-panel) {
    min-width: 0;
    width: 100%;
    overflow: visible;
}
html.mobile-layout .mob-two-col {
    flex-direction: column;
    min-width: 0;
}

/* Raids and PvP: stacked columns. */
html.mobile-layout #tab-raid.active,
html.mobile-layout #tab-pvp.active {
    display: flex;
    flex-direction: column;
    padding: 8px;
    overflow: auto;
}
html.mobile-layout #tab-raid :is(.raid-content, .raid-browse-section) {
    flex: 0 0 auto;
    min-width: 0;
    overflow: visible;
}
html.mobile-layout #tab-raid .raid-browse-columns {
    grid-template-columns: minmax(0, 1fr);
    overflow: visible;
    gap: 12px;
}
html.mobile-layout #tab-raid .raid-browse-col { min-width: 0; padding: 10px; }
html.mobile-layout #tab-raid .raid-browse-section { padding: 0; }
/* Lobby rows: the desktop's fixed columns (difficulty 118px, status,
   actions 160px) added up to ~400px and pushed Peek / Join off a phone's
   right edge. Here a row is two lines: who and how full, then the
   difficulty with Peek / Join. */
html.mobile-layout #tab-raid .raid-browse-row {
    flex-wrap: wrap;
    gap: 6px 10px;
    padding: 8px 10px;
}
html.mobile-layout #tab-raid .raid-browse-host { flex: 1 1 120px; }
html.mobile-layout #tab-raid .raid-browse-diff { order: 5; flex: 1 1 auto; }
html.mobile-layout #tab-raid .raid-browse-actions {
    order: 6;
    flex: 0 0 auto;
    margin-left: auto;
}
html.mobile-layout #tab-raid :is(.raid-browse-actions .raid-browse-join, .raid-browse-row > .raid-browse-join) {
    min-height: 40px;
    padding: 0 14px;
    display: flex;
    align-items: center;
}
html.mobile-layout #tab-raid .raid-browse-col-header {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
    text-align: left;
}
html.mobile-layout #tab-raid .raid-colhdr-title {
    grid-row: 1;
    white-space: normal;
    font-size: 17px;
}
html.mobile-layout #tab-raid .raid-colhdr-side {
    min-width: 0;
    font-size: 13px;
}
html.mobile-layout #tab-raid :is(.loadout-sel, .loadout-sel-families, .loadout-sel-slots) {
    flex-wrap: wrap;
    min-width: 0;
}
/* Lobby browser controls: wrapping left the sort buttons and the lobby
   buttons sharing ragged lines. Here they are two even rows, the sorts
   (each already shows its ▲/▼, so the "Sort:" label goes) and then
   Create Lobby beside Refresh. data-sorts is set by _buildSortButtons. */
html.mobile-layout #tab-raid .raid-browse-sortrow {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 6px;
    min-width: 0;
}
html.mobile-layout #tab-raid .raid-browse-sortlabel {
    display: none;
}
html.mobile-layout #tab-raid .raid-browse-sortrow[data-sorts='3'] .raid-browse-sortbtn { grid-column: span 2; }
html.mobile-layout #tab-raid .raid-browse-sortrow[data-sorts='2'] .raid-browse-sortbtn { grid-column: span 3; }
html.mobile-layout #tab-raid .raid-browse-sortrow .raid-browse-create { grid-column: 1 / span 4; }
html.mobile-layout #tab-raid .raid-browse-sortrow .raid-browse-refresh { grid-column: span 2; }
html.mobile-layout #tab-raid .raid-browse-sortrow > :is(.raid-browse-sortbtn, .raid-browse-create, .raid-browse-refresh) {
    min-width: 0;
    min-height: 40px;
    margin: 0;
    padding: 0 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 15px;
}
/* Raid lobby: two desktop columns (difficulty, invites, actions and the
   drop table on the left; a party list of ~860px-wide cards on the
   right). Squeezed onto a phone they overlapped: the difficulty names ran
   into each other, the lobby name and invite inputs sat on top of each
   other, and the party cards were cut off at the right edge. Here it is
   one column, in the order a host works through it: difficulty, party,
   lobby name and actions, invites, drop table. The columns and the
   control grid dissolve (display: contents) so their parts can be
   ordered. */
html.mobile-layout #tab-raid .raid-lobby-grid {
    display: flex;
    flex-direction: column;
    gap: 14px;
    flex: 0 0 auto;
    min-width: 0;
}
html.mobile-layout #tab-raid :is(.raid-lobby-col, .raid-ctrl-grid, .raid-ctrl-col) {
    display: contents;
}
html.mobile-layout #tab-raid .raid-diff-section { order: 1; }
html.mobile-layout #tab-raid .raid-party-section { order: 2; min-height: 0; }
html.mobile-layout #tab-raid .raid-name-row { order: 3; margin: 0; }
html.mobile-layout #tab-raid .raid-action-row { order: 4; margin: 0; gap: 8px; }
html.mobile-layout #tab-raid .raid-invite-row { order: 5; }
html.mobile-layout #tab-raid .raid-invite-lists { order: 6; flex: 0 0 auto; max-height: 40vh; }
html.mobile-layout #tab-raid .raid-droptable { order: 7; flex: 0 0 auto; overflow: visible; }
html.mobile-layout #tab-raid :is(.raid-name-row, .raid-action-row, .raid-invite-row, .raid-invite-lists, .raid-droptable, .raid-party-section, .raid-diff-section) {
    min-width: 0;
    max-width: 100%;
}
/* Difficulties: a 3 x 2 grid, portrait beside its name. */
html.mobile-layout #tab-raid .raid-diff-row {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}
html.mobile-layout #tab-raid .raid-diff-btn {
    min-height: 44px;
    padding: 6px 4px;
    box-sizing: border-box;
}
html.mobile-layout #tab-raid .raid-diff-name {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* A Fortress lobby has one fixed difficulty: its banner spans the row. */
html.mobile-layout #tab-raid .raid-diff-row > .tier-gauntlet {
    grid-column: 1 / -1;
}
/* Drop table: the desktop header and item names are sized for a wide
   column; on a phone each name wrapped a word per line. */
html.mobile-layout #tab-raid .raid-droptable .loot-table th {
    font-size: 14px;
}
html.mobile-layout #tab-raid .raid-droptable .loot-table td {
    font-size: 15px;
}
/* Actions: Start across the full width, the rest two to a row. */
html.mobile-layout #tab-raid .raid-action-row > * {
    flex: 1 1 calc(50% - 4px);
    min-width: 0;
    min-height: 44px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
}
html.mobile-layout #tab-raid .raid-action-row > .raid-start-btn { flex-basis: 100%; }
html.mobile-layout #tab-raid :is(.raid-name-edit, .raid-invite-row) {
    display: flex;
    gap: 8px;
}
html.mobile-layout #tab-raid :is(.raid-name-input, .raid-invite-input) {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    min-height: 44px;
    box-sizing: border-box;
}
/* Party cards: the desktop row (info | sprite | stats | paperdoll |
   equipment) wraps into rows the width of the phone. */
html.mobile-layout #tab-raid .raid-party-list {
    flex: 0 0 auto;
    overflow: visible;
    gap: 8px;
}
html.mobile-layout #tab-raid .raid-party-row-item {
    flex-wrap: wrap;
    justify-content: center;
    height: auto !important;
    min-height: 0;
    gap: 8px;
    padding: 10px;
    overflow: visible !important;
}
html.mobile-layout #tab-raid :is(.raid-row-info, .raid-row-leftgroup) {
    width: 100%;
    flex: 1 1 100%;
}
/* Sprite beside the skill grid, paperdoll beside the equipment. */
html.mobile-layout #tab-raid .raid-row-sprite {
    width: 112px;
    height: 120px;
}
html.mobile-layout #tab-raid .raid-row-stats {
    flex: 1 1 160px;
    width: auto;
    min-width: 0;
}
html.mobile-layout #tab-raid .raid-row-equip-stats {
    min-width: 0;
    flex: 1 1 180px;
    font-size: 14px;
}
html.mobile-layout #tab-raid .raid-party-row-item.empty {
    flex-wrap: nowrap;
    justify-content: space-between;
    align-items: center;
}
html.mobile-layout #tab-raid .raid-clone-add-hint {
    flex: 1 1 0;
    min-width: 0;
    margin: 0;
}
html.mobile-layout #tab-raid .raid-clone-add-btn {
    margin: 0;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
}
html.mobile-layout #tab-pvp :is(.pvp-layout, .pvp-cols) {
    display: flex !important;
    flex-direction: column !important;
    min-width: 0;
    gap: 12px;
}
html.mobile-layout #tab-pvp :is(.pvp-left, .pvp-right) {
    width: 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
}

/* Alms: the donate pane, then the reward path. */
html.mobile-layout #tab-alms.active {
    display: block;
    overflow-x: hidden;
    overflow-y: auto;
    padding: 8px;
}
html.mobile-layout .alms-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
}
html.mobile-layout :is(.alms-donate-pane, .alms-path) {
    min-width: 0;
    width: 100% !important;
    overflow: visible;
}
html.mobile-layout :is(.alms-input-section, .alms-input-row, .alms-presets, .alms-preview, .alms-divider) {
    width: 100% !important;
    min-width: 0;
    max-width: 100%;
}
html.mobile-layout .alms-presets { flex-wrap: wrap; gap: 4px; }

/* ── Smith / Craft / Imbue / Brew ─────────────────────────────────
   On the desktop a tall tier list sits beside the recipe grid. Stacked
   on a phone the list took the whole screen and the grid was left 20px
   tall, so no recipe could be seen. Here the tiers are a grid of chips
   (the material with its tier, the bank count under it; a locked tier
   shows its level), the page scrolls as one, and the material and
   Amount bar sticks to the top while the recipes scroll under it. */
html.mobile-layout :is(.proc-layout, .proc-main-layout, .proc-recipes-area, .brew-layout, .brew-recipes-area) {
    height: auto !important;
    max-height: none !important;
    flex: none !important;
    overflow: visible !important;
}
html.mobile-layout :is(.proc-recipes-grid-scroll, .brew-recipes-scroll) {
    height: auto !important;
    max-height: none !important;
    flex: none !important;
    overflow: visible !important;
}
html.mobile-layout .proc-tier-sidebar {
    padding: 6px !important;
}
html.mobile-layout .proc-tier-sidebar-title {
    display: none;
}
html.mobile-layout .proc-tier-sidebar-scroll {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
    gap: 4px;
    max-height: none;
    overflow: visible;
}
html.mobile-layout .proc-tier-row {
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 2px;
    height: auto;
    min-height: 0;
    margin: 0;
    padding: 4px 2px;
}
html.mobile-layout .proc-tier-row :is(.proc-tier-badge, .proc-tier-info) {
    display: none;
}
html.mobile-layout .proc-tier-row.locked .proc-tier-info {
    display: block;
    width: auto;
    text-align: center;
}
html.mobile-layout .proc-tier-row.locked .proc-tier-info > :not(.proc-tier-level) {
    display: none;
}
html.mobile-layout .proc-tier-row .proc-tier-level {
    font-size: 12px;
}
html.mobile-layout .proc-tier-bank-qty {
    width: auto;
    min-width: 0;
    font-size: 13px;
    text-align: center;
}
html.mobile-layout :is(.proc-recipes-header, .brew-recipes-header) {
    position: sticky;
    top: -10px;
    z-index: 30;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
    flex-wrap: wrap;
    height: auto;
    gap: 8px;
    padding: 8px;
    background: var(--bg-panel);
    border-bottom: 1px solid var(--border-primary);
}
html.mobile-layout .proc-recipes-material-display {
    flex: 1 1 auto;
    min-width: 0;
}
/* Landscape is short: the material and Amount share one row, and Brew's
   taller bar (styles + Amount) scrolls away instead of sticking. */
html.mobile-layout.mobile-landscape .proc-recipes-header {
    flex-wrap: nowrap;
}
html.mobile-layout.mobile-landscape .proc-recipes-header .proc-amount-control {
    flex: 1 1 auto;
}
html.mobile-layout.mobile-landscape .brew-recipes-header {
    position: static;
}
html.mobile-layout .proc-mat-label {
    white-space: normal;
    font-size: 16px;
    line-height: 1.15;
}
/* Two lines rather than an ellipsis: "Platebody", "Robe Top". */
html.mobile-layout .proc-recipe-item-name {
    font-size: 18px;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    line-height: 1.1;
}
html.mobile-layout .proc-amount-control {
    flex: 1 1 100%;
    width: auto;
    min-width: 0;
    margin: 0;
    gap: 6px;
}
html.mobile-layout .proc-amount-control :is(.proc-amount-max-btn, .proc-amount-reset-btn) {
    flex: 1 1 0;
    min-width: 0;
    height: 40px;
    padding: 0 4px;
    white-space: nowrap;
}
html.mobile-layout .proc-amount-input {
    width: 64px;
    flex: none;
}
html.mobile-layout .proc-recipes-grid {
    grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)) !important;
    gap: 8px;
}
html.mobile-layout .proc-recipe-card {
    min-width: 0;
    width: auto;
}
/* Brew: the potion styles wrap into rows of chips above the Amount bar
   (on one line they ran 900px past the screen's edge). */
html.mobile-layout .brew-style-filters {
    order: -1;
    flex: 1 1 100%;
    /* ProcessingModal shows the row with an inline display: flex. */
    display: grid !important;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    width: auto;
    min-width: 0;
    gap: 4px;
    margin: 0;
}
html.mobile-layout.mobile-landscape .brew-style-filters {
    grid-template-columns: repeat(8, minmax(0, 1fr));
}
html.mobile-layout .brew-style-tab {
    justify-content: center;
    gap: 3px;
    min-width: 0;
    min-height: 38px;
    padding: 2px 3px;
}
html.mobile-layout .brew-style-tab .style-dot {
    flex: none;
    width: 6px;
    height: 6px;
}
html.mobile-layout .brew-style-tab-name {
    font-size: 13px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
html.mobile-layout .brew-recipes-grid {
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)) !important;
    gap: 8px;
}
html.mobile-layout .brew-recipe-card {
    width: auto;
    min-width: 0;
}

/* Alms: the reward path. Its rows are laid out for a wide pane (120px
   of spine on the left, a 300px reward on the right), so on a phone the
   reward and its Claim button ran off the edge. Here the spine is
   narrower and each row stacks: perks, then the reward under them. */
html.mobile-layout .alms-path {
    padding: 12px 8px;
}
html.mobile-layout .alms-path-header {
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 8px;
}
html.mobile-layout .alms-path-title {
    font-size: 26px;
}
html.mobile-layout .alms-path-next {
    font-size: 16px;
}
html.mobile-layout .alms-path-controls {
    flex: 1 1 100%;
    flex-wrap: wrap;
    gap: 6px;
}
html.mobile-layout .alms-path-controls :is(.alms-path-filter, .alms-path-claim-btn) {
    min-height: 40px;
    font-size: 16px;
}
html.mobile-layout .alms-path-list {
    max-height: none;
    overflow: visible;
}
html.mobile-layout .alms-path-row {
    flex-wrap: wrap;
    gap: 6px;
    min-height: 72px;
    padding: 8px 8px 8px 60px;
}
html.mobile-layout .alms-path-row::before,
html.mobile-layout .alms-path-row.current::after {
    left: 26px;
}
html.mobile-layout .alms-path-node {
    left: 8px;
    width: 44px;
    height: 44px;
    font-size: 18px;
}
html.mobile-layout .alms-path-perks {
    flex: 1 1 100%;
    flex-wrap: wrap;
    gap: 6px;
}
html.mobile-layout .alms-path-perk {
    flex: 1 1 140px;
    height: auto;
    min-height: 56px;
}
html.mobile-layout .alms-path-reward {
    flex: 1 1 100%;
    width: auto;
    min-width: 0;
}
html.mobile-layout :is(.alms-path-reward-name, .alms-path-reward-status) {
    font-size: 15px;
}
html.mobile-layout .alms-path-perk {
    gap: 6px;
    padding: 4px 6px;
}
html.mobile-layout .alms-path-perk-name {
    font-size: 15px;
    line-height: 1.1;
    white-space: normal;
    overflow: visible;
}
html.mobile-layout .alms-path-perk-sub {
    font-size: 13px;
}

/* Quests: the detail's bottom bar is rewards then the Begin / Abandon
   buttons on one row, and on a phone the rewards took the whole width
   and pushed Begin Quest off the right edge (a quest could not be
   started, and the Quests tutorial waited on it). Here the rewards wrap
   and the buttons get their own row underneath, full width. */
html.mobile-layout .quest-bottom-bar {
    flex-wrap: wrap;
    gap: 10px;
    padding: 10px;
}
html.mobile-layout .quest-rewards-section {
    flex: 1 1 100%;
    min-width: 0;
    flex-wrap: wrap;
    gap: 8px;
}
html.mobile-layout .quest-reward-items {
    flex-wrap: wrap;
}
html.mobile-layout .quest-actions {
    flex: 1 1 100%;
    min-width: 0;
}
html.mobile-layout .quest-actions .quest-btn {
    flex: 1 1 0;
    min-width: 0;
    padding: 8px 10px;
    font-size: 22px;
}
/* The list and the detail stacked, so a quest's Begin / Complete button
   sat under the whole quest list, thousands of pixels down. Here the
   screen shows the list, or one quest (QuestModal._syncPhoneView) with
   a way back, and its buttons stay on screen at the bottom. */
html.mobile-layout .quest-layout.m-has-detail .quest-list-side,
html.mobile-layout .quest-layout:not(.m-has-detail) .quest-detail-side {
    display: none !important;
}
html.mobile-layout .quest-back-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    align-self: flex-start;
    min-height: 44px;
    margin: 0 0 8px;
    padding: 0 14px;
    font-size: 18px;
    color: var(--text-accent);
    background: var(--bg-cell);
    border: 1px solid var(--border-primary);
    border-radius: 6px;
    cursor: pointer;
    box-sizing: border-box;
}
html.mobile-layout .quest-bottom-bar {
    position: sticky;
    bottom: -10px;
    z-index: 2;
    margin-bottom: -10px;
    box-shadow: 0 -8px 14px rgba(0, 0, 0, 0.45);
}

/* ── Combat ───────────────────────────────────────────────────────
   A fight's side panels are 400 x 640px: on a portrait phone the two of
   them stacked over the whole screen and hid the arena, and their tab
   bars (which hang outside each panel) were off screen, so a panel could
   not even be closed. Here one panel at a time is a sheet: over the lower
   half in portrait, a pane on the right in landscape, with its tabs and
   a close button along its top edge. The camera moves the arena clear of
   it (CombatEncounterModal.sheetLift / sheetShiftX), and the fight's zoom
   fits the arena to the screen (CombatWorldRenderer.fitZoom). */
html.mobile-layout .combat-encounter .panel-wrapper {
    position: absolute;
    top: auto;
    transform: none;
    left: var(--m-left);
    right: var(--m-right);
    bottom: var(--m-sheet-bottom);
    width: auto;
}
html.mobile-layout .combat-encounter .combat-panel {
    width: auto;
    height: calc(var(--m-vh) * 0.5 - var(--m-sheet-bottom) - 48px);
    padding: 10px;
    box-sizing: border-box;
}
html.mobile-layout .combat-encounter .combat-panel.panel-hidden {
    height: 0;
    padding: 0 10px;
}
/* The desktop window-tab strip shares the .panel-tab-bar class and is
   hidden on the phone (Desktop chrome above); the sheet's own tabs show. */
html.mobile-layout .combat-encounter .panel-tab-bar.visible {
    display: flex !important;
}
html.mobile-layout .combat-encounter .panel-tab-bar {
    top: -48px;
    left: 0;
    right: 0;
    transform: none;
    flex-direction: row;
    width: auto;
    height: 42px;
    gap: 6px;
}
html.mobile-layout .combat-encounter .panel-tab {
    width: 42px;
    height: 42px;
}
html.mobile-layout .combat-encounter .panel-tab-close {
    display: flex;
    margin-left: auto;
    font-size: 22px;
    color: var(--text-bright);
}
/* Landscape: a pane on the right, under the HP bar (which spans the top). */
html.mobile-layout.mobile-landscape .combat-encounter .panel-wrapper {
    top: calc(var(--m-top) + var(--m-hp-h) + 10px + 48px);
    left: var(--m-sheet-left);
    right: var(--m-sheet-right);
}
html.mobile-layout.mobile-landscape .combat-encounter .combat-panel {
    height: calc(var(--m-vh) - var(--m-top) - var(--m-hp-h) - 10px - var(--m-sheet-bottom) - 48px);
}
/* Kill count (and a raid's End Combat) sat at the bottom of the screen,
   under the dock. Here it sits just above the task card. */
html.mobile-layout .combat-encounter .combat-hud {
    bottom: calc(var(--m-dock-h) + var(--m-task-h) + 16px);
}
/* While a sheet is open it has the bottom of the screen to itself: the
   task card, the kill count and the recenter button would sit on it. */
html.mobile-layout.m-combat-sheet :is(.floating-current-task, .recenter-camera-btn, .combat-encounter .combat-hud) {
    visibility: hidden;
}

/* ── World map ────────────────────────────────────────────────── */

html.mobile-layout .map-overlay {
    top: 0 !important;
    left: 0 !important;
    width: 100% !important;
    height: calc(var(--m-vh) - var(--m-dock-h)) !important;
}
/* Filters and the route list hide behind the two toggles in #m-map-bar. */
html.mobile-layout:not(.m-map-filters) .map-filter-panel,
html.mobile-layout:not(.m-map-route) .map-legend-panel {
    display: none !important;
}
html.mobile-layout :is(.map-filter-panel, .map-legend-panel) {
    top: calc(var(--m-top) + 60px) !important;
    left: var(--m-left) !important;
    right: var(--m-right) !important;
    bottom: auto !important;
    width: auto !important;
    max-width: none !important;
    max-height: calc(var(--m-vh) - var(--m-top) - var(--m-dock-h) - 76px);
    overflow: auto;
}
#m-map-bar {
    position: fixed;
    z-index: 5980;
    top: calc(var(--m-top) + 8px);
    right: var(--m-right);
    display: none;
    gap: 6px;
}
html.mobile-layout.m-view-map #m-map-bar { display: flex; }
#m-map-bar button {
    min-height: 44px;
    padding: 6px 14px;
    background: var(--bg-panel, #2b2216);
    border: 1px solid var(--border-secondary, #7a6a3a);
    border-radius: 3px;
    color: var(--text-light, #cccccc);
    font-size: 14px;
}
#m-map-bar button[aria-pressed='true'] {
    background: var(--bg-cell, #3a3226);
    border-color: var(--text-accent, #c8a83e);
    color: var(--text-bright, #ffff00);
}

/* ── Overlays that cover the screen ───────────────────────────── */

html.mobile-layout :is(.chest-overlay, .lamp-overlay) {
    width: 100% !important;
    height: 100% !important;
}
html.mobile-layout :is(.chest-panel, .lamp-panel) {
    max-width: calc(100vw - 24px) !important;
    max-height: calc(var(--m-vh) - 24px);
    overflow: auto;
}
/* A chest's rewards scroll inside the panel and Collect stays put. Only
   a haul of more than 20 rewards gets that on the desktop (.multi); the
   compact panel below it scrolled as a whole here, so a big-but-not-
   huge open, or any open in landscape, left Collect below the fold. */
html.mobile-layout .chest-overlay .chest-panel {
    display: flex;
    flex-direction: column;
    align-items: center;
    overflow: hidden;
    padding: 20px 14px 14px;
    /* The dock stays on top of the overlay, so keep clear of it too. */
    max-height: calc(var(--m-vh) - var(--m-dock-h) - 24px);
}
html.mobile-layout .chest-overlay {
    padding-bottom: var(--m-dock-h);
    box-sizing: border-box;
}
html.mobile-layout .chest-overlay .chest-loot-grid {
    flex: 0 1 auto;
    width: 100%;
    min-height: 56px;
    overflow-y: auto;
    align-content: flex-start;
}
html.mobile-layout .chest-overlay.multi .chest-loot-grid {
    flex: 1 1 auto;
}
html.mobile-layout .chest-overlay .chest-btn {
    flex: 0 0 auto;
}

/* The Steam prompt ("Congratulations on total level N"): a 720px card
   with desktop type ran off the top and bottom of a phone, with Later
   and Don't ask again under the dock, so a player could not close it.
   Here it fits the screen beside the dock, the thank-you scrolls, and
   the two buttons stay pinned to the card's bottom edge. */
html.mobile-layout .steam-prompt-overlay {
    box-sizing: border-box;
    padding: calc(var(--m-top) + 10px) var(--m-right) calc(var(--m-dock-h) + 10px) var(--m-left);
}
html.mobile-layout .steam-prompt-card {
    box-sizing: border-box;
    width: 100%;
    max-width: 520px;
    max-height: 100%;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 16px 18px 0;
}
html.mobile-layout .steam-prompt-hero {
    margin-bottom: 4px;
}
html.mobile-layout .steam-prompt-hero img {
    width: 52px;
    height: 52px;
}
html.mobile-layout .steam-prompt-headline {
    font-size: 22px;
    margin-bottom: 8px;
}
html.mobile-layout .steam-prompt-deco {
    margin-bottom: 10px;
}
html.mobile-layout .steam-prompt-deco img {
    width: 26px;
    height: 26px;
}
html.mobile-layout :is(.steam-prompt-note, .steam-prompt-signoff, .steam-prompt-line) {
    font-size: 16px;
}
html.mobile-layout .steam-prompt-buttons {
    position: sticky;
    bottom: 0;
    margin-top: 12px;
    padding: 10px 0 14px;
    background: var(--bg-panel);
}
html.mobile-layout .steam-prompt-btn {
    font-size: 16px;
    padding: 10px 16px;
}

/* The roadmap (ThanksButton.showRoadmap, opened from the Menu): phones
   get the portrait image at the screen's width, scrolling down, with the
   close hint above it. It is mounted on the page, not #ui-container, so
   it covers the dock and rail (6000) and only pads for the safe areas. */
html.mobile-layout .roadmap-overlay {
    position: fixed;
    box-sizing: border-box;
    justify-content: flex-start;
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: calc(var(--m-top) + 10px) calc(8px + var(--m-safe-right)) calc(16px + var(--m-safe-bottom)) calc(8px + var(--m-safe-left));
}
html.mobile-layout .roadmap-image {
    flex: none;
    width: 100%;
    max-width: 540px;
    max-height: none;
    height: auto;
}
html.mobile-layout .roadmap-close-hint {
    order: -1;
    margin: 0 0 10px;
    font-size: 15px;
}

/* The lamp's skill picker ran under the dock like the chest did, hiding
   the last row of skills (Luck, Alms). */
html.mobile-layout .lamp-overlay {
    padding-bottom: var(--m-dock-h);
    box-sizing: border-box;
}
html.mobile-layout .lamp-panel {
    max-height: calc(var(--m-vh) - var(--m-dock-h) - 24px);
}

/* Confirm dialogs: centred between the screen's edges and the dock rail
   rather than edge to edge. Customize's pack popup is parked on purpose
   and keeps its own placement. */
html.mobile-layout .ctx-confirm-overlay:not(.cc-dlc-popup) {
    box-sizing: border-box;
    padding: calc(var(--m-top) + 10px) var(--m-right) calc(var(--m-dock-h) + 10px) var(--m-left);
}
html.mobile-layout .ctx-confirm-overlay:not(.cc-dlc-popup) .ctx-confirm-dialog {
    box-sizing: border-box;
    min-width: 0;
    max-width: 100%;
    max-height: 100%;
    overflow-y: auto;
}

/* Holiday NPC: a 760px strip centred on the 1920 grid hung off both
   sides of a phone, Next/Close included. Here it spans the screen above
   the dock with a smaller portrait, and scrolls if the reward list runs
   long. */
html.mobile-layout .holiday-dialog {
    left: var(--m-left);
    right: var(--m-right);
    bottom: calc(var(--m-dock-h) + 10px);
    width: auto;
    max-height: calc(var(--m-vh) - var(--m-top) - var(--m-dock-h) - 20px);
    overflow-y: auto;
    transform: none;
    box-sizing: border-box;
    gap: 10px;
    padding: 12px;
}
html.mobile-layout .holiday-dialog-portrait {
    width: 64px;
    height: 64px;
}
html.mobile-layout .holiday-dialog-name {
    font-size: 18px;
}
html.mobile-layout .holiday-dialog-text {
    font-size: 15px;
    min-height: 0;
}
html.mobile-layout .holiday-dialog-reward {
    font-size: 14px;
}
html.mobile-layout .holiday-dialog-buttons {
    flex-wrap: wrap;
}
html.mobile-layout .holiday-dialog-btn {
    font-size: 15px;
    padding: 8px 14px;
}

/* Gear Calc: a fixed 1820 x 1000 frame. On a phone its header, and the
   only X that closes it, sat above the top of the screen. */
html.mobile-layout .gc-modal-overlay {
    box-sizing: border-box;
    padding: calc(var(--m-top) + 8px) var(--m-right) calc(var(--m-dock-h) + 8px) var(--m-left);
}
html.mobile-layout .gc-modal-dialog {
    width: 100%;
    height: 100%;
}
html.mobile-layout .gc-modal-close {
    width: 40px;
    height: 40px;
    font-size: 24px;
}

/* Chat rules gate: in landscape the rules fill the screen, which left
   "I agree" and Accept below the fold. They stay pinned to the dialog's
   bottom edge while the rules scroll. (The tutorial shows the same
   block inside its own bubble, which pins its own footer.) */
html.mobile-layout .chat-rules-dialog .chat-rules-agreement {
    position: sticky;
    bottom: -20px;
    margin: 0 -28px -20px;
    padding: 10px 28px 20px;
    background: var(--bg-panel);
}

/* The sleep screen's 260px moon scene, timer, note and Wake Up stacked
   taller than a landscape phone, with Wake Up below the bottom edge. */
html.mobile-layout.mobile-landscape .sleep-overlay {
    gap: 8px;
}
html.mobile-layout.mobile-landscape .sleep-overlay .sleep-scene {
    zoom: 0.55;
}

/* Popovers that grew taller than a landscape phone scroll instead. */
html.mobile-layout :is(.ingame-hud-offline-pop, .chat-room-menu) {
    max-height: calc(var(--m-vh) - var(--m-dock-h) - 16px);
    overflow-y: auto;
    box-sizing: border-box;
}
html.mobile-layout .reconnect-box {
    box-sizing: border-box;
    max-width: calc(100vw - var(--m-left) - var(--m-right));
    max-height: calc(var(--m-vh) - 24px);
    overflow-y: auto;
}

/* Recipe info (Smith, Craft, Imbue): built 520px wide in desktop type,
   it ran off the side and bottom of a phone. Here it sits as a card
   above the dock, the width of the screen. */
html.mobile-layout .proc-recipe-info-pop {
    position: fixed;
    left: var(--m-left) !important;
    right: var(--m-right);
    top: auto !important;
    bottom: calc(var(--m-dock-h) + 10px);
    min-width: 0;
    max-width: none;
    max-height: calc(var(--m-vh) - var(--m-top) - var(--m-dock-h) - 20px);
    overflow-y: auto;
    box-sizing: border-box;
    font-size: 15px;
}
html.mobile-layout .proc-recipe-info-title {
    font-size: 17px;
}
html.mobile-layout :is(.proc-recipe-info-line, .proc-recipe-info-name, .proc-recipe-info-qty) {
    font-size: 15px;
}
html.mobile-layout .proc-recipe-info-row {
    white-space: normal;
}

/* ── Test panel (test server only) ────────────────────────────────
   The desktop's TEST tab hangs off the right edge over the game, and
   its 480px panel opened past the left edge of a phone. Here the tab is
   gone and the panel opens from Menu > Settings > Test panel, as a
   sheet like the others. Only a server with debug commands on mounts
   either (TestPanel.setEnabled). */
html.mobile-layout .test-tab {
    display: none !important;
}
html.mobile-layout .test-panel {
    position: fixed;
    left: var(--m-left);
    right: var(--m-right);
    top: calc(var(--m-top) + 8px);
    bottom: calc(var(--m-dock-h) + 8px);
    width: auto;
    max-height: none;
}
html.mobile-layout .test-panel-header {
    padding: 4px 4px 4px 12px;
}
html.mobile-layout .test-panel-close {
    min-width: 44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
}
html.mobile-layout .test-panel-body {
    min-height: 0;
    overscroll-behavior: contain;
}
html.mobile-layout .test-tabs {
    flex-wrap: wrap;
}

/* ── Menus wider than a phone ─────────────────────────────────────
   The bank's filter list (900px, three columns) and the potions
   panel's filter menu (920px, four columns) are placed at the cursor in
   desktop UI pixels, so on a phone they ran off the right edge. Here
   each is a sheet across the screen that scrolls when it is taller. */
html.mobile-layout :is(.bank-filter-menu, .potions-filter-menu) {
    position: fixed !important;
    left: var(--m-left) !important;
    right: var(--m-right) !important;
    top: calc(var(--m-top) + 8px) !important;
    width: auto !important;
    min-width: 0 !important;
    max-height: calc(var(--m-vh) - var(--m-top) - var(--m-dock-h) - 16px);
    overflow-y: auto;
    overscroll-behavior: contain;
}
/* Portrait stacks the bank's three columns; landscape has room for them. */
html.mobile-layout:not(.mobile-landscape) .bank-filter-cols {
    flex-direction: column;
    align-items: stretch;
}
html.mobile-layout .bank-filter-cols > div {
    min-width: 0;
}
html.mobile-layout:not(.mobile-landscape) .bank-filter-cols > div + div {
    border-left: 0;
    border-top: 1px solid var(--border-primary);
}
html.mobile-layout .bank-filter-label {
    white-space: normal;
}
/* Potions: one column in portrait, two in landscape. */
html.mobile-layout .potions-filter-cols {
    grid-template-columns: 1fr;
}
html.mobile-layout.mobile-landscape .potions-filter-cols {
    grid-template-columns: 1fr 1fr;
}
html.mobile-layout .potions-filter-col + .potions-filter-col {
    border-left: 0;
    border-top: 1px solid var(--border-primary);
}
html.mobile-layout.mobile-landscape .potions-filter-col:nth-child(even) {
    border-left: 1px solid var(--border-primary);
}
html.mobile-layout.mobile-landscape .potions-filter-col:nth-child(2) {
    border-top: 0;
}
html.mobile-layout .potions-filter-title {
    flex-wrap: wrap;
}
/* Chat's category filters (long-press a channel): 22px rows at the
   finger, the same sheet across the screen as the menus above, with
   rows a thumb can hit. One column in portrait, three in landscape. */
html.mobile-layout .chat-category-menu {
    position: fixed !important;
    left: var(--m-left) !important;
    right: var(--m-right) !important;
    top: calc(var(--m-top) + 8px) !important;
    bottom: auto !important;
    min-width: 0;
    max-height: calc(var(--m-vh) - var(--m-top) - var(--m-dock-h) - 16px);
    overflow-y: auto;
    overscroll-behavior: contain;
    display: grid;
    grid-template-columns: 1fr;
    gap: 4px;
    padding: 0 8px 8px;
}
html.mobile-layout.mobile-landscape .chat-category-menu {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}
html.mobile-layout .chat-category-title {
    grid-column: 1 / -1;
    position: sticky;
    top: 0;
    z-index: 1;
    margin: 0 -8px 4px;
    padding: 12px 16px 10px;
    font-size: 18px;
    background: var(--bg-panel);
}
html.mobile-layout .chat-category-row {
    min-height: 44px;
    gap: 10px;
    padding: 4px 10px;
    font-size: 17px;
    background: var(--bg-cell);
    border: 1px solid var(--border-primary);
    border-radius: 4px;
}
html.mobile-layout .chat-category-dot {
    width: 14px;
    height: 14px;
}
html.mobile-layout .chat-category-check {
    width: 24px;
    height: 24px;
}
html.mobile-layout .chat-category-check.checked::after {
    top: 1px;
    left: 4px;
    font-size: 17px;
}
/* The ✕ MobileLayout puts in each of those menus' headers, which stay
   put while the menu scrolls under them. */
html.mobile-layout :is(.bank-filter-head, .potions-filter-header, .chat-category-title) {
    position: sticky;
    top: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--bg-panel);
}
html.mobile-layout :is(.bank-filter-head, .potions-filter-header, .chat-category-title) > :first-child:not(.m-menu-x) {
    flex: 1 1 auto;
    min-width: 0;
}
.m-menu-x {
    display: none;
}
html.mobile-layout .m-menu-x {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 40px;
    height: 40px;
    margin-left: auto;
    padding: 0;
    font: inherit;
    font-size: 20px;
    color: var(--text-bright);
    background: var(--bg-cell);
    border: 1px solid var(--border-primary);
    border-radius: 4px;
}
/* Patch notes open from Menu > Settings; on the login screen they would
   cover the sign-in buttons. */
html.mobile-layout:not(.m-notes) .patch-notes-panel {
    display: none !important;
}
html.mobile-layout .patch-notes-panel {
    left: var(--m-left) !important;
    right: var(--m-right) !important;
    top: var(--m-sheet-top) !important;
    bottom: var(--m-sheet-bottom) !important;
    width: auto !important;
    height: auto !important;
    max-height: none !important;
    transform: none !important;
    overflow: auto;
}
html.mobile-layout body.login-active .patch-notes-panel {
    top: calc(var(--m-top) + 8px) !important;
    bottom: 8px !important;
}

/* Advanced Combat's worked fight (CombatChalkboard) is two 430px
   columns side by side. Here they stack in a board that scrolls, above
   any open sheet, leaving the lower half of the screen to the step's
   bubble; CombatChalkboard.focus scrolls each step's numbers into view. */
html.mobile-layout .chalk-board {
    top: calc(var(--m-top) + 8px);
    left: var(--m-left);
    right: var(--m-right);
    transform: none;
    flex-direction: column;
    gap: 8px;
    padding: 8px;
    max-height: 52%;
    overflow-y: auto;
    overscroll-behavior: contain;
    z-index: 1150;
}
html.mobile-layout .chalk-col {
    width: auto;
    flex: none;
}

/* Tutorial bubble controls. The bubble is drawn at 0.65 on a phone
   (TutorialOverlay's MOBILE_BUBBLE_SCALE), which left Next and the
   choice buttons about 31px tall; 68px here is a 44px target on screen.
   Next and Exit carry inline styles, hence the !important sizes. */
html.mobile-layout :is(.tutorial-next-btn, .tutorial-choice-btn) {
    min-height: 68px;
    min-width: 136px;
    font-size: 26px !important;
}
html.mobile-layout .tutorial-choice-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
html.mobile-layout .tutorial-exit-link {
    font-size: 22px !important;
    padding: 16px 0;
}

/* ── Ledger welcome-back screens (LedgerReturn) ────────────────── */

/* Welcome back card: built 1240px wide and up to 1000px tall, so on a
   phone its right column and, in landscape, its buttons were off the
   screen. Here it fits the screen: milestones, skills and loot scroll in
   one column (two in landscape) and Open Ledger / Continue stay put. */
html.mobile-layout .ledger-return-overlay {
    box-sizing: border-box;
    padding: calc(var(--m-top) + 8px) calc(8px + var(--m-safe-right)) calc(8px + var(--m-safe-bottom)) calc(8px + var(--m-safe-left));
}
html.mobile-layout .ledger-card {
    box-sizing: border-box;
    width: 100%;
    max-width: 640px;
    max-height: 100%;
    padding: 12px;
    gap: 10px;
    overflow: hidden;
}
html.mobile-layout .ledger-card > .ledger-compact {
    flex: 1 1 auto;
    min-height: 0;
    grid-template-columns: minmax(0, 1fr);
    overflow-y: auto;
    overscroll-behavior: contain;
}
html.mobile-layout.mobile-landscape .ledger-card { max-width: none; }
html.mobile-layout.mobile-landscape .ledger-card > .ledger-compact {
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
}
html.mobile-layout .ledger-card :is(.ledger-sec-skills, .ledger-sec-loot) > .ledger-sec-body { max-height: none; }
html.mobile-layout .ledger-card-portrait,
html.mobile-layout .ledger-card-portrait .ledger-portrait-canvas {
    width: 64px;
    height: 64px;
    flex-basis: 64px;
}
html.mobile-layout .ledger-card-name { font-size: 22px; }
html.mobile-layout .ledger-card-foot { flex: none; }
html.mobile-layout .ledger-card-foot .ledger-btn {
    flex: 1 1 0;
    min-height: 44px;
}
/* The skills table is wider than a phone column: it scrolls sideways. */
html.mobile-layout :is(.ledger-card, .ledger-night) .ledger-sec-skills > .ledger-sec-body { overflow-x: auto; }

/* While you slept: the welcome-back card's shape on the sleep screen's
   black. On the desktop it is a 1080p page with the sleeping character
   gliding from the middle to the top-left and Wake Up pinned 700px down
   (off a landscape screen). Here it is a card: the moon and character
   small beside "Slept for", Milestones, Skills and Loot scrolling in the
   middle (two columns in landscape), and Open Ledger / Sleep / Wake Up
   as the card's buttons along the bottom. No glide: the picture is too
   small to follow. */
html.mobile-layout .ledger-night {
    padding: calc(var(--m-top) + 8px) calc(8px + var(--m-safe-right)) calc(8px + var(--m-safe-bottom)) calc(8px + var(--m-safe-left));
}
html.mobile-layout .ledger-night-card {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 12px;
    overflow: hidden;
    background: var(--bg-panel);
    border: 2px solid var(--border-secondary);
    border-radius: 10px;
}
html.mobile-layout .ledger-night-top { min-height: 0; }
html.mobile-layout .ledger-night-title { font-size: 22px; }
html.mobile-layout .ledger-night-body {
    position: static;
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
    overflow-y: auto;
    overscroll-behavior: contain;
}
html.mobile-layout.mobile-landscape .ledger-night-body {
    display: grid;
    grid-template-columns: minmax(0, 300px) minmax(0, 1fr);
    grid-template-rows: auto;
    align-items: start;
}
html.mobile-layout.mobile-landscape .ledger-night-col-left { grid-row: span 2; }
html.mobile-layout .ledger-night-col { gap: 10px; min-height: auto; }
html.mobile-layout .ledger-night .ledger-sec {
    padding: 10px 12px;
    background: var(--bg-dark);
}
html.mobile-layout .ledger-night .ledger-sec > .ledger-sec-body {
    max-height: none;
    overflow-y: visible !important;
}
html.mobile-layout .ledger-night .ledger-sec-skills > .ledger-sec-body { overflow-x: auto !important; }
html.mobile-layout .ledger-night :is(.ledger-table th, .ledger-total-row td) { background: var(--bg-dark); }
/* The stack: moon and character at 78px, "Slept for" beside them. */
html.mobile-layout .ledger-night .ledger-night-stack {
    flex-direction: row;
    align-items: center;
    gap: 12px;
    transform: none !important;
    transition: none;
}
html.mobile-layout .ledger-night .ledger-night-stack .sleep-scene {
    height: 260px;
    margin: 0 -182px -182px 0;
    transform: scale(.3) !important;
    transform-origin: top left;
    transition: none;
}
html.mobile-layout .ledger-night .ledger-night-stack :is(.sleep-note, .sleep-status) { display: none; }
html.mobile-layout .ledger-night .sleep-timer {
    font-size: 20px;
    white-space: normal;
}
/* "Sleeping for 01:23:45" in the sleep screen's 34px Cinzel is wider
   than a phone held upright and wrapped onto a second line. One line,
   sized to the screen. */
html.mobile-layout .sleep-timer {
    white-space: nowrap;
    letter-spacing: 0;
}
html.mobile-layout .sleep-overlay .sleep-timer {
    font-size: min(28px, 6vw);
}
html.mobile-layout .sleep-overlay .sleep-note {
    padding: 0 16px;
}
html.mobile-layout .ledger-night-actions {
    position: static;
    flex: none;
    transform: none;
    flex-direction: row;
    gap: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--border-primary);
}
html.mobile-layout.mobile-landscape .ledger-night-actions { justify-content: flex-end; }
html.mobile-layout .ledger-night-actions > * {
    flex: 1 1 0;
    min-height: 44px;
    margin: 0;
    padding: 8px 10px;
    font-family: var(--game-font);
    font-size: 15px;
    text-align: center;
    border-radius: 6px;
    border: 1px solid var(--border-secondary);
    background: var(--bg-cell);
    color: var(--text-light);
    opacity: 1;
}
html.mobile-layout.mobile-landscape .ledger-night-actions > * { flex: 0 0 auto; padding: 8px 18px; }
/* Wake Up is the card's primary button: last, like Continue. */
html.mobile-layout .ledger-night-actions .sleep-wake-btn {
    order: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-hover);
    color: var(--text-bright);
    font-weight: 700;
}
html.mobile-layout .ledger-night.ledger-night-leaving .ledger-night-actions { transform: none; }

/* ── Login and loading ────────────────────────────────────────── */

html.mobile-layout .login-screen {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 16px;
    width: 100% !important;
    height: 100% !important;
    padding: calc(var(--m-top) + 16px) calc(16px + var(--m-safe-right)) 16px calc(16px + var(--m-safe-left));
    box-sizing: border-box;
    overflow-y: auto;
    overflow-x: hidden;
    overscroll-behavior: contain;
}
html.mobile-layout .login-area {
    order: 1;
    flex: 0 0 auto;
    width: 100%;
    max-width: 640px;
    height: auto;
    min-height: 0;
    margin: 0 auto;
    padding: 0;
    justify-content: flex-start;
    gap: 16px;
}
html.mobile-layout .login-logo {
    width: min(200px, 50vw) !important;
    height: auto !important;
}
html.mobile-layout :is(.login-hero, .login-box, .login-form, .login-signup) {
    max-width: 100%;
    width: 100%;
    min-width: 0;
}
html.mobile-layout .login-box {
    max-width: 420px;
    padding: 12px;
    box-sizing: border-box;
}
html.mobile-layout .login-signup-input {
    width: 100%;
    min-width: 0;
    min-height: 44px;
    box-sizing: border-box;
}
html.mobile-layout #ui-container .login-screen .login-btn {
    width: 100%;
    min-width: 0 !important;
    min-height: 56px;
    padding: 12px 16px;
    gap: 12px;
    font-size: 16px;
    line-height: 1.35;
    box-sizing: border-box;
}
html.mobile-layout .login-social {
    order: 2;
    position: static;
    flex: 0 0 auto;
    align-self: center;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
    gap: 12px;
    margin: 0;
    transform: none !important;
}
html.mobile-layout .login-social-link {
    min-height: 44px;
    align-items: center;
    font-size: 13px;
}
html.mobile-layout .login-version-block {
    order: 3;
    position: static;
    flex: 0 0 auto;
    align-self: center;
    font-size: 12px;
    line-height: 1.4;
    transform: none !important;
}
html.mobile-layout .login-online {
    order: 0;
    position: static;
    flex: 0 0 auto;
    align-self: flex-end;
    font-size: 12px;
    transform: none !important;
}
html.mobile-layout :is(.login-world-picker, .login-world-row) {
    width: 100%;
    max-width: 100%;
}
html.mobile-layout .login-world-row {
    flex-wrap: wrap;
    gap: 8px;
}
html.mobile-layout .login-screen > .screen-tip {
    order: 4;
    position: static;
    flex: 0 0 auto;
    align-self: center;
    width: 100%;
    max-width: 640px;
    margin: 0;
    padding: 8px 12px;
    border: 0;
    background: none;
    font-size: 13px;
    line-height: 1.5;
    text-align: left;
    white-space: normal;
    animation: none;
    transform: none !important;
    opacity: 1 !important;
}
html.mobile-layout .loading-screen {
    left: 0 !important;
    top: 0 !important;
    width: 100% !important;
    height: 100% !important;
}
/* Logo high, status and tip low, in every orientation: the desktop
   offsets (logo 100px down, bar 130px up) overlap in a 412px-tall
   landscape screen, and its 420px bar is wider than a portrait one. */
html.mobile-layout .loading-screen {
    padding-top: calc(var(--m-top) + 64px);
}
html.mobile-layout .loading-screen .loading-bottom {
    bottom: calc(96px + var(--m-safe-bottom));
    width: calc(100% - 48px);
}
html.mobile-layout .loading-screen .loading-bar-track { width: 100%; max-width: 420px; }
html.mobile-layout .loading-screen .loading-status {
    font-size: 16px;
    text-align: center;
}
html.mobile-layout .loading-screen > .screen-tip {
    bottom: calc(24px + var(--m-safe-bottom));
    max-width: calc(100% - 32px);
    font-size: 13px;
}
/* Portrait: the status and its bar sit mid-screen, between the logo and
   the tip. At the bottom, "Connecting to server..." ran into a "Did you
   know?" tip that wrapped onto three or four lines. */
html.mobile-layout:not(.mobile-landscape) .loading-screen .loading-bottom {
    top: 50%;
    bottom: auto;
}
/* Landscape: just under the logo (150px, from --m-top + 20px). */
html.mobile-layout.mobile-landscape .loading-screen .loading-bottom {
    top: calc(var(--m-top) + 186px);
    bottom: auto;
}
html.mobile-layout.mobile-landscape .loading-screen { padding-top: calc(var(--m-top) + 20px); }
html.mobile-layout.mobile-landscape .loading-screen .login-logo {
    width: 150px !important;
    height: 150px !important;
}
html.mobile-layout.mobile-landscape .loading-screen > .screen-tip { bottom: calc(12px + var(--m-safe-bottom)); }
html.mobile-layout.mobile-landscape .login-area {
    display: grid;
    grid-template-columns: 180px minmax(0, 1fr);
    align-items: center;
    gap: 24px;
    max-width: 760px;
}
html.mobile-layout.mobile-landscape .login-logo { width: 180px !important; }
html.mobile-layout.mobile-landscape .login-box { max-width: none; }

/* ── Landscape: a rail on the right, panels beside the world ──── */

html.mobile-layout.mobile-landscape #m-dock {
    top: 0;
    bottom: 0;
    left: auto;
    right: 0;
    width: var(--m-rail-w);
    height: auto;
    flex-direction: column;
    justify-content: flex-start;
    gap: 4px;
    padding: calc(6px + var(--m-safe-top)) calc(6px + var(--m-safe-right)) 6px 6px;
    border-top: 0;
    border-left: 1px solid var(--border-primary, #5c4a2a);
    overflow-y: auto;
}
html.mobile-layout.mobile-landscape #m-dock button {
    flex: 0 0 auto;
    min-height: 48px;
    gap: 2px;
    font-size: 11px;
}
html.mobile-layout.mobile-landscape #m-dock button img {
    width: 22px;
    height: 22px;
}
html.mobile-layout.mobile-landscape #m-menu {
    top: calc(var(--m-top) + 8px);
    bottom: 8px;
    border: 1px solid var(--border-primary, #5c4a2a);
    border-radius: 4px;
}
html.mobile-layout.mobile-landscape .m-menu-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}
html.mobile-layout.mobile-landscape .hp-bar {
    right: calc(var(--m-right) + var(--m-pane-w) + 8px) !important;
}
html.mobile-layout.mobile-landscape.m-view-world .hp-bar {
    right: var(--m-right) !important;
}
html.mobile-layout.mobile-landscape .ingame-hud,
html.mobile-layout.mobile-landscape .tutorial-checklist {
    max-width: 320px;
}
html.mobile-layout.mobile-landscape .floating-current-task {
    right: auto !important;
    width: min(360px, 45vw) !important;
    bottom: 8px !important;
}
/* Centred in the strip right of the current-task card. */
html.mobile-layout.mobile-landscape .recenter-camera-btn {
    left: calc(var(--m-left) + min(360px, 45vw) + 8px) !important;
    bottom: 12px !important;
}
html.mobile-layout.mobile-landscape .modal-overlay {
    top: calc(var(--m-top) + 8px) !important;
    left: var(--m-left) !important;
    width: calc(100vw - var(--m-left) - var(--m-right)) !important;
    height: calc(var(--m-vh) - var(--m-top) - 16px) !important;
}
html.mobile-layout.mobile-landscape .modal-container {
    border-radius: 4px !important;
}
html.mobile-layout.mobile-landscape .modal-header {
    min-height: 48px;
    padding: 4px 8px;
}
html.mobile-layout.mobile-landscape .header-icon {
    width: 28px;
    height: 28px;
}
html.mobile-layout.mobile-landscape .map-overlay {
    width: calc(100vw - var(--m-rail-w)) !important;
    height: var(--m-vh) !important;
}
html.mobile-layout.mobile-landscape #m-toast {
    right: calc(var(--m-rail-w) + 16px);
    bottom: 12px;
}
