/* Mobile Responsiveness CSS */
/* Optimized for landscape mobile gaming */

/* ======================================
   CSS Variables
   ====================================== */
:root {
    --mobile-action-btn-size: 48px;
    --mobile-joystick-size: 112px;
    --mobile-hotbar-height: 60px;
    --mobile-header-height: 36px;
    --safe-area-top: env(safe-area-inset-top, 0px);
    --safe-area-bottom: env(safe-area-inset-bottom, 0px);
    --safe-area-left: env(safe-area-inset-left, 0px);
    --safe-area-right: env(safe-area-inset-right, 0px);
}

/* ======================================
   Utility Classes
   ====================================== */
.desktop-only {
    display: block;
}

.mobile-only {
    display: none !important;
}

/* TABTIBIA: only show the mobile HUD when the touch controller enabled mobile mode
   (real mobile UA or the device selector). Keeps desktop clean even on small windows. */
body:not(.mobile-mode) .mobile-only {
    display: none !important;
}

/* ======================================
   Touch Device Detection
   Use max-height for landscape detection
   ====================================== */

/* Landscape mobile: height <= 500px catches most phones in landscape */
@media screen and (max-height: 500px),
screen and (max-width: 768px),
screen and (max-height: 560px) and (pointer: coarse) {

    .desktop-only {
        display: none !important;
    }

    .mobile-only {
        display: flex !important;
    }

    /* Hide the desktop secure mode button where the mobile HUD shows the round #mobile-pk-lock-btn instead. A desktop
       in a small window has no mobile HUD (body:not(.mobile-mode) .mobile-only), so it keeps the desktop button */
    body.mobile-mode #pk-lock-btn,
    body.mobile-mode .secure-mode-separator {
        display: none !important;
    }

    /* Body - prevent scrolling and bouncing */
    body {
        overflow: hidden;
        touch-action: none;
        -webkit-touch-callout: none;
        -webkit-user-select: none;
        user-select: none;
        position: fixed;
        width: 100%;
        height: 100%;
    }

    /* Game wrapper fills entire screen (display controlled by JS showGameInterface) */
    #game-wrapper {
        flex-direction: row !important;
        min-width: unset !important;
        min-height: unset !important;
        width: 100vw;
        height: 100vh;
        height: 100dvh;
        overflow: hidden;
        /* iOS safe area: home indicator bar at bottom, Dynamic Island on sides */
        padding-bottom: var(--safe-area-bottom);
        box-sizing: border-box;
    }

    /* Allow oogwrap to be visible for equipment but hide layout impact */
    #game-wrapper .oogwrap {
        display: block !important;
        position: absolute;
        top: 0;
        right: 0;
        width: 0;
        height: 0;
        overflow: visible;
        pointer-events: none;
        z-index: 9990;
    }

    /* Hide specific desktop elements inside oogwrap */
    .oogwrap .minimap-container,
    .oogwrap .character-status {
        display: none !important;
    }

    /* Ensure equipment wrapper is visible */
    .equipment-options-wrapper {
        display: block !important;
        pointer-events: auto;
    }

    /* Main game area - full width/height */
    #game-wrapper .main {
        flex: 1 1 auto;
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 100%;
        min-height: 0;
        overflow: hidden;
        position: relative;
    }

    /* Hide middle section (desktop hotbar area) */
    #game-wrapper .main .middle {
        display: none !important;
    }

    /* Canvas takes full space */
    #game-wrapper .main .upper {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        overflow: hidden;
    }

    .canvas-wrapper {
        width: 100% !important;
        height: 100% !important;
        position: relative;
    }

    .canvas-notification {
        z-index: 10002 !important;
    }

    #screen {
        width: 100% !important;
        height: 100% !important;
        display: block;
    }

    /* Hide chat resizer on mobile */
    #chat-resizer {
        display: none !important;
    }

    /* Hide original hotbar */
    .hotbar {
        display: none !important;
    }

    /* Context menus - allow on mobile (opened/closed by JS) */

    /* Windows positioned on right side for mobile */
    .window {
        pointer-events: auto !important;
        position: fixed !important;
        top: 170px !important;
        left: auto !important;
        right: 5px !important;
        width: 190px !important;
        max-width: 60vw;
        max-height: 60vh;
        z-index: 9995;
        overflow: visible;
        font-size: 11px;
    }

    /* Battle window stays on the right side */
    #battle-window {
        z-index: 9990 !important;
        top: 170px !important;
        right: 5px !important;
        left: auto !important;
    }

    /* Trade window centered on mobile */
    #trade-window {
        position: fixed !important;
        top: 50% !important;
        left: 50% !important;
        transform: translate(-50%, -50%) !important;
        z-index: 30000 !important;
        width: 240px !important;
        max-height: 70vh !important;
    }

    #trade-window .body {
        max-height: 55vh !important;
        overflow-y: auto !important;
    }

    #trade-window .trade-contents {
        max-height: 30vh !important;
    }

    /* Container windows hidden on mobile — replaced by tabbed panel (except depot) */
    .window[containerIndex] {
        display: none !important;
    }

    /* Depot gets its own floating window on mobile */
    .window[containerIndex="1"] {
        display: flex !important;
        position: fixed !important;
        z-index: 9997 !important;
        width: 180px !important;
        top: 50% !important;
        left: 50% !important;
        right: auto !important;
        transform: translate(-50%, -50%) !important;
        transform-origin: center center !important;
        border: 1px solid #555 !important;
        max-height: 70vh !important;
    }

    .window[containerIndex="1"] > .header {
        cursor: default;
        touch-action: none;
        min-height: 28px;
    }

    .window[containerIndex="1"] > .header > .title {
        font-size: 11px;
    }

    .window[containerIndex="1"] > .header > button {
        min-width: 28px;
        min-height: 28px;
        font-size: 14px;
    }

    .window[containerIndex="1"] > .body {
        max-height: 50vh !important;
        overflow-y: auto !important;
        -webkit-overflow-scrolling: touch;
        /* same as desktop window.css: bottom padding becomes a transparent border so the next row is not visible through it */
        padding-bottom: 0 !important;
        border-bottom: 2px solid transparent;
    }

    .window[containerIndex="1"] .slot {
        width: 40px !important;
        height: 40px !important;
        background-size: 100% 100% !important;
    }

    .window[containerIndex="1"] .slot canvas {
        width: 40px !important;
        height: 40px !important;
    }

    /* Mobile Container Tabbed Panel */
    #mobile-container-panel {
        position: fixed;
        z-index: 9996;
        width: 150px;
        background-image: url("/png/bg3.png");
        transform: scale(0.85);
        flex-direction: column;
        overflow: hidden;
        pointer-events: auto;
        left: 5px;
        right: auto;
        top: 37px;
        transform-origin: top left;
        border: 1px solid #333;
        /* Height clamp like every sibling panel (Awton S24U report
           2026-08-24, raised-DPI viewport): with many containers open the
           panel ran as an unbounded strip off the screen bottom. vh scales
           with the CSS viewport, so this stays sane at any DPI. The body
           scrolls the overflow. */
        max-height: 70vh;
    }

    #mobile-container-panel .mobile-container-body {
        overflow-y: auto;
        max-height: calc(70vh - 56px);
    }

    /* Mobile Depot Panel — centered on screen via the same
       translate(-50%, -50%) trick the old depot floating window used.
       Width 180px, no scale — matches old size exactly. */
    #mobile-depot-panel,
    #mobile-float-panel {
        position: fixed;
        z-index: 9997;
        width: 180px;
        background-image: url("/png/bg3.png");
        flex-direction: column;
        overflow: hidden;
        pointer-events: auto;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        max-height: 70vh;
        border: 1px solid #555;
    }

    /* Subtle drag-handle hint on the depot panel header. The two vertical
       ellipsis glyphs side-by-side read as a "grip" without screaming. */
    #mobile-depot-panel .depot-drag-grip,
    #mobile-float-panel .depot-drag-grip {
        color: #888;
        font-size: 10px;
        letter-spacing: -2px;
        margin-left: 4px;
        margin-right: 2px;
        opacity: 0.7;
        cursor: grab;
        user-select: none;
        pointer-events: none;
    }
    #mobile-depot-panel .mobile-panel-header,
    #mobile-float-panel .mobile-panel-header {
        cursor: grab;
    }
    #mobile-depot-panel .mobile-panel-header:active,
    #mobile-float-panel .mobile-panel-header:active {
        cursor: grabbing;
    }

    .mobile-container-tabs {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        background-image: url("/png/bg4.png");
        min-height: 22px;
        gap: 0;
        scrollbar-width: none;
    }

    .mobile-container-tabs::-webkit-scrollbar {
        display: none;
    }

    .mobile-container-tab {
        flex: 0 0 auto;
        padding: 2px 5px;
        border: none;
        border-right: 1px solid #555;
        background: transparent;
        color: #999;
        font-size: 11px;
        white-space: nowrap;
        cursor: pointer;
        display: flex;
        align-items: center;
        gap: 3px;
        height: 22px;
    }

    .mobile-container-tab.active {
        color: #ffd700;
        border-bottom: 2px solid #d4a017;
    }

    .mobile-container-tab-close {
        font-size: 14px;
        color: #888;
        cursor: pointer;
        padding: 0 2px;
        min-width: 20px;
        min-height: 20px;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    .mobile-container-body {
        overflow-y: auto;
        max-height: 40vh;
    }

    .container-content .body {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        padding: 2px;
    }

    .container-content .slot {
        width: 32px !important;
        height: 32px !important;
        margin: 1px !important;
        border: 1px solid #444;
    }

    .container-content .slot canvas {
        width: 32px !important;
        height: 32px !important;
    }

    .window .header {
        height: 20px !important;
        line-height: 20px !important;
        font-size: 10px !important;
    }

    .window .body {
        max-height: 40vh !important;
        overflow-y: auto !important;
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        padding: 2px !important;
        min-height: 0 !important;
    }

    .window .footer {
        display: none !important;
    }

    .window .slot {
        width: 32px !important;
        height: 32px !important;
        margin: 1px !important;
        border: 1px solid #444;
        /* Add border to see slots better */
    }

    /* Larger touch targets */
    .slot {
        width: 36px !important;
        height: 36px !important;
    }

    .slot canvas {
        width: 36px !important;
        height: 36px !important;
    }

    /* Equipment panel - show in top right on mobile, styled like .window */
    .equipment.wrapper {
        position: fixed !important;
        top: 37px !important;
        right: 5px !important;
        left: auto !important;
        z-index: 9998;
        background-image: url("/png/bg3.png");
        padding: 0 2px 2px 2px !important;
        width: 140px !important;
        flex-wrap: wrap !important;
    }

    .equipment.wrapper > .mobile-panel-header {
        flex: 0 0 100%;
        margin: 0 -2px 0 -2px;
    }

    .equipment-options-wrapper {
        display: block !important;
    }

    .equipment-column {
        gap: 2px !important;
    }

    .equipment.wrapper .fight-mode-selector {
        margin-left: 2px !important;
        padding: 2px !important;
    }

    .equipment.wrapper .slot {
        width: 30px !important;
        height: 30px !important;
    }

    .equipment.wrapper .slot canvas {
        width: 30px !important;
        height: 30px !important;
    }

    #player-capacity {
        font-size: 10px !important;
        padding: 2px !important;
    }

    .equipment-buttons {
        display: none !important;
    }
}

/* ======================================
   Mobile Tab Bar (Inside Status Bar)
   ====================================== */
#mobile-tab-bar {
    display: flex;
    flex-direction: row;
    gap: 0;
    flex-shrink: 0;
}

.mobile-tab {
    height: 100%;
    padding: 0 8px;
    border: none;
    border-left: 1px solid #444;
    background: transparent;
    color: #999;
    font-size: 13px;
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    cursor: pointer;
    border-radius: 0;
}

.mobile-tab:first-child {
    border-radius: 0;
}

.mobile-tab:last-child {
    border-radius: 0;
}

/* ======================================
   Swap Button (Tab Bar)
   ====================================== */
.mobile-tab-swap {
    height: 100%;
    padding: 0 6px;
    border: none;
    border-left: 2px solid #666;
    background: transparent;
    color: #777;
    font-size: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    cursor: pointer;
    border-radius: 0;
}

.mobile-tab-swap:active {
    color: #fff;
    background: rgba(60, 60, 60, 0.95);
}

/* When swap button exists, the last tab no longer gets the right radius */
.mobile-tab:nth-last-child(2) {
    border-radius: 0;
}

.mobile-tab.active {
    background: rgba(255, 255, 255, 0.1);
    color: #fff;
}

/* ======================================
   Mobile Tab Panel Positioning
   ====================================== */
@media screen and (max-height: 500px),
screen and (max-width: 768px),
screen and (max-height: 560px) and (pointer: coarse) {

    /* Panels shown via tab bar get this class */
    .mobile-tab-panel {
        display: block !important;
        position: fixed !important;
        top: calc(37px + var(--safe-area-top)) !important;
        right: calc(5px + var(--safe-area-right)) !important;
        left: auto !important;
        z-index: 9998 !important;
        pointer-events: auto !important;
    }

    /* Stats/friends panels — wider when opened via tab. Longer labels are
       abbreviated below (Exp/Shld/Dist/Fish/...) so a narrower panel fits. */
    #skill-window.mobile-tab-panel {
        width: 160px !important;
        font-size: 12px !important;
    }

    #friend-window.mobile-tab-panel,
    #battle-window.mobile-tab-panel {
        width: 160px !important;
        max-height: 70vh !important;
        font-size: 12px !important;
    }

    /* Override the default #battle-window position (top: 170px) when the
       window is being shown as a sub-tab of the People panel. Both IDs
       here have the same selector weight as the lone #battle-window rule
       at line ~173, but .mobile-tab-panel adds an extra class giving this
       higher specificity so it wins cleanly. Matches the position of
       #friend-window.mobile-tab-panel so sub-tab switches look like a
       tab swap, not a window jump. */
    #battle-window.mobile-tab-panel {
        top: calc(37px + var(--safe-area-top)) !important;
        right: calc(5px + var(--safe-area-right)) !important;
        left: auto !important;
    }

    /* When the tab bar is swapped to the left side, the People panel
       (whichever sub-tab is showing) anchors to the left too. The generic
       .mobile-tab-panel.mobile-tab-left rule handles friend-window, but
       #battle-window's higher-specificity right:auto/left rules above
       would otherwise win — so mirror the left-anchor explicitly. */
    #battle-window.mobile-tab-panel.mobile-tab-left {
        right: auto !important;
        left: calc(5px + var(--safe-area-left)) !important;
    }

    /* Battle sub-panel length cap — show at most 3 creatures on mobile so
       the merged People panel never eats the screen. Each entry is ~43px
       (40 content + 1 margin + 2 border). Excess creatures scroll.
       On mobile, battle-body lives INSIDE #friend-window (merged via
       WindowManager init), not inside #battle-window. */
    #friend-window.mobile-tab-panel .battle-body {
        overflow-y: auto !important;
        max-height: calc(3 * 43px) !important;
        position: relative !important;
        scrollbar-width: thin !important;
        scrollbar-color: #888 #222 !important;
        /* Rows ran width:100% flush into the scrollbar, crowding the right
           edge of the bars (owner 2026-08-26: "it gets shifted to the left
           slightly"). A hair of right padding ends the rows before the
           scrollbar track. */
        padding-right: 8px !important;
        box-sizing: border-box !important;
    }

    /* "More creatures below" cue — needs a 4th creature AND the Battle
       sub-tab to be the visible one (.battle-active, set by
       setPeopleSubTab). :has() alone matched the HIDDEN battle body, so
       the chevron floated over "+ Add Friend" on the Friends sub-tab
       (owner 2026-08-26). */
    #friend-window.mobile-tab-panel.battle-active .battle-body:has(> :nth-child(4)) {
        box-shadow: inset 0 -10px 10px -6px rgba(0, 0, 0, 0.75) !important;
    }
    #friend-window.mobile-tab-panel.battle-active:has(.battle-body > :nth-child(4))::after {
        content: "▾";
        position: absolute;
        bottom: 2px;
        right: 10px;
        color: rgba(255, 255, 255, 0.7);
        font-size: 11px;
        pointer-events: none;
        z-index: 1;
    }

    #friend-window.mobile-tab-panel .battle-body::-webkit-scrollbar {
        width: 6px !important;
    }
    #friend-window.mobile-tab-panel .battle-body::-webkit-scrollbar-track {
        background: #222 !important;
    }
    #friend-window.mobile-tab-panel .battle-body::-webkit-scrollbar-thumb {
        background: #888 !important;
        border-radius: 3px !important;
    }
    #friend-window.mobile-tab-panel .battle-body::-webkit-scrollbar-thumb:hover {
        background: #aaa !important;
    }

    /* People sub-tab strip (Friends ⇄ Battle). Lives inside both
       #friend-window and #battle-window so whichever is shown gets a
       consistent header. Mobile-only — hidden on desktop via .mobile-only. */
    .people-subtabs {
        display: flex;
        flex-direction: row;
        gap: 2px;
        padding: 2px;
        background: #222;
        border-bottom: 1px solid #111;
    }
    .people-subtab {
        flex: 1;
        padding: 5px 2px;
        background: #333;
        color: #aaa;
        border: 1px solid #111;
        font-size: 11px;
        cursor: pointer;
        font-family: inherit;
    }
    .people-subtab.active {
        background: #555;
        color: #fff;
    }

    /* Tighter tab bar so all three labels (Info / Skills / Professions) fit
       inside the 185px panel without the last tab clipping through the edge. */
    #skill-window.mobile-tab-panel .skill-tabs {
        padding: 0 !important;
    }

    #skill-window.mobile-tab-panel .skill-tab {
        padding: 3px 2px !important;
        font-size: 10px !important;
        min-width: 0 !important;
        letter-spacing: 0 !important;
        white-space: nowrap !important;
        overflow: hidden !important;
    }

    /* "Professions" is too wide at 160px / 3 tabs — abbreviate to "Profs" */
    #skill-window.mobile-tab-panel .skill-tab[data-tab="professions"] {
        font-size: 0 !important;
    }

    #skill-window.mobile-tab-panel .skill-tab[data-tab="professions"]::before {
        content: "Profs";
        font-size: 10px;
    }

    /* Cap body height roughly around the Info tab (6 rows) — other tabs scroll.
       Right padding is intentionally tighter than left because the grid cells
       were getting clipped on the right edge — saves the 2 critical pixels. */
    #skill-window.mobile-tab-panel .body {
        display: block !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        height: auto !important;
        max-height: 170px !important;
        padding: 4px 3px 4px 4px !important;
        box-sizing: border-box !important;
    }

    /* Friend window footer with add button on mobile */
    #friend-window .footer {
        display: block !important;
        height: auto !important;
        cursor: default !important;
        padding: 2px !important;
    }

    /* Minimap override — normally hidden on mobile */
    .minimap-container.mobile-tab-panel {
        display: block !important;
        position: fixed !important;
        pointer-events: auto !important;
        background-image: url("/png/bg3.png");
        width: auto !important;
        margin: 0 !important;
        padding: 4px !important;
        padding-right: 4px !important;
    }

    /* Minimap canvas and wrapper fill available space.
       Display size 115px = 10% smaller than the old 128px. The internal
       canvas resolution stays 160 (all render math is hardcoded to 80/
       160/320), so this is a pure display downscale; touch mapping self-
       corrects via scaleX = canvas.width/rect.width in __getCanvasCoordinates. */
    .minimap-container.mobile-tab-panel .minimap-wrapper {
        width: 115px !important;
        height: 115px !important;
    }

    .minimap-container.mobile-tab-panel .minimap-wrapper canvas {
        width: 115px !important;
        height: 115px !important;
        /* Red frame halved vs the desktop base (3/5/7/9px + 20px glow) to
           reclaim space on the smaller mobile map. */
        box-shadow:
            0 0 0 1.5px #1a0a0a,
            0 0 0 2.5px #8b2020,
            0 0 0 3.5px #5a1515,
            0 0 0 4.5px #2a0808,
            0 0 10px rgba(139, 32, 32, 0.5) !important;
    }

    /* Minimap buttons horizontal row underneath the map */
    .minimap-container.mobile-tab-panel .button-stack {
        position: relative !important;
        right: auto !important;
        top: auto !important;
        width: 100% !important;
        flex-direction: row !important;
        justify-content: center !important;
        margin-top: 4px !important;
    }

    .minimap-container.mobile-tab-panel .button-stack .symbol-button {
        width: 22px !important;
        height: 22px !important;
        font-size: 11px !important;
    }

    /* Minimap crosshair centered for canvas (115px display: center 57.5,
       glyph half-offset ~4/8 → 54/50). */
    .minimap-container.mobile-tab-panel .crosshair {
        left: 54px !important;
        top: 50px !important;
    }

    /* Skill window touch-friendly */
    #skill-window.mobile-tab-panel .skill-wrapper {
        padding: 2px 8px 2px 4px !important;
        box-sizing: border-box !important;
        font-size: 12px !important;
        color: #fff !important;
        text-shadow: 0 0 3px #000, 0 0 3px #000, 0 1px 2px #000 !important;
        /* Belt for the compact-number fix (owner 2026-08-26: values jutting
           past the window edge): flex children default to min-width:auto and
           refuse to shrink below their nowrap content (the flex-basis trap),
           so an over-wide value ESCAPED the window instead of clipping.
           min-width:0 + hidden overflow keeps any residual overflow inside. */
        overflow: hidden !important;
    }
    #skill-window.mobile-tab-panel .skill-wrapper > span,
    #skill-window.mobile-tab-panel .skill-wrapper > .skill {
        min-width: 0;
        overflow: hidden;
    }

    /* Abbreviate the longer labels on mobile so the panel can be narrower.
       Original text node stays for screen readers (font-size: 0 hides it
       visually but leaves it in DOM), then ::before injects the short form. */
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="experience"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="shielding"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="distance"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="fishing"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="woodcutting"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="smithing"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="cooking"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="mining"] .skill-wrapper > span:first-child {
        font-size: 0 !important;
    }

    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="experience"] .skill-wrapper > span:first-child::before   { content: "Exp"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="shielding"] .skill-wrapper > span:first-child::before    { content: "Shld"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="distance"] .skill-wrapper > span:first-child::before     { content: "Dist"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="fishing"] .skill-wrapper > span:first-child::before      { content: "Fish"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="woodcutting"] .skill-wrapper > span:first-child::before  { content: "Wood"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="smithing"] .skill-wrapper > span:first-child::before     { content: "Smith"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="cooking"] .skill-wrapper > span:first-child::before      { content: "Cook"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="mining"] .skill-wrapper > span:first-child::before       { content: "Mine"; font-size: 12px; }

    /* Combat skills tab: 2-column grid. Only applies when the Skills tab is
       the active one — the default .skill-tab-content { display:none } still
       hides inactive tabs. column-gap tightened from 4px → 2px so the right
       column doesn't overflow the panel on narrow phones. */
    #skill-window.mobile-tab-panel .skill-tab-content.active[data-tab="skills"] {
        display: grid !important;
        grid-template-columns: 1fr 1fr !important;
        column-gap: 2px !important;
        row-gap: 1px !important;
    }

    #skill-window.mobile-tab-panel .bar-wrapper {
        display: block !important;
        position: relative !important;
        /* White outline around each skill cell so the end of the progress
           fill is visible — without it, the green bar just fades into the
           panel background and you can't tell whether a skill is at 30% or
           70% of the way to the next level. */
        border: 1px solid rgba(255, 255, 255, 0.5) !important;
        box-sizing: border-box !important;
    }

    #skill-window.mobile-tab-panel .bar-wrapper > .skill-wrapper {
        position: relative;
        z-index: 1;
    }

    #skill-window.mobile-tab-panel .bar-wrapper > .bar {
        position: absolute !important;
        left: 0 !important;
        right: 0 !important;
        top: 0 !important;
        bottom: 0 !important;
        width: 100% !important;
        height: auto !important;
        border-color: rgba(0, 0, 0, 0.4) !important;
        /* Bump from 0.4 → 0.7 so the overlay bar still reads green rather
           than muddy olive. 0.4 made the fill look nearly grey next to
           desktop's solid #2ecc40. Text on top stays legible because of
           the z-index stacking and the dark track underneath. */
        opacity: 0.7 !important;
        z-index: 0 !important;
    }

    #skill-window.mobile-tab-panel .bar-wrapper > .bar > .value {
        height: 100% !important;
    }
}

/* Landscape tab panel adjustments */
@media screen and (max-height: 500px) and (orientation: landscape) {
    .mobile-tab-panel {
        top: 33px !important;
    }

}

/* ======================================
   Mobile Status Bar (Top)
   ====================================== */
#mobile-status-bar {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--mobile-header-height);
    background: linear-gradient(to bottom, rgba(0, 0, 0, 0.85), rgba(0, 0, 0, 0.6));
    border-bottom: 1px solid #444;
    z-index: 10001;
    flex-direction: row;
    align-items: center;
    justify-content: center;
    padding: 2px calc(12px + var(--safe-area-right)) 2px calc(12px + var(--safe-area-left));
    box-sizing: border-box;
    gap: 12px;
}

@media screen and (max-height: 500px),
screen and (max-width: 768px),
screen and (max-height: 560px) and (pointer: coarse) {
    #mobile-status-bar {
        display: flex;
    }
}

.mobile-bar-container {
    flex: 1 1 auto;
    max-width: 400px;
    display: flex;
    flex-direction: row;
    gap: 8px;
    align-items: center;
}

.mobile-bar {
    flex: 1;
    height: 18px;
    background: #1a1a1a;
    border: 1px solid #333;
    border-radius: 4px;
    overflow: hidden;
    position: relative;
}

.mobile-bar-fill {
    height: 100%;
    transition: width 0.2s ease;
}

.mobile-bar-fill.health {
    background: linear-gradient(to bottom, #22cc22, #118811);
}

.mobile-bar-fill.mana {
    background: linear-gradient(to bottom, #3388ff, #2255aa);
}

.mobile-bar-text {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    text-align: center;
    font-size: 11px;
    line-height: 18px;
    color: white;
    text-shadow: 1px 1px 2px black, -1px -1px 2px black;
    font-weight: bold;
}

/* Magic Shield indicator icon — persistent on mobile health bars */
.magic-shield-indicator {
    position: absolute;
    right: 2px;
    top: 50%;
    transform: translateY(-50%);
    width: 12px;
    height: 12px;
    image-rendering: pixelated;
    z-index: 2;
    pointer-events: none;
    filter: drop-shadow(0 0 2px rgba(50, 140, 255, 0.8));
    animation: magic-shield-pulse 2s ease-in-out infinite;
}

@keyframes magic-shield-pulse {
    0%, 100% { filter: drop-shadow(0 0 2px rgba(50, 140, 255, 0.8)); }
    50% { filter: drop-shadow(0 0 5px rgba(50, 140, 255, 1)); }
}

/* Portrait-only HP/Mana bars (below canvas in portrait mode only) */
#portrait-bars {
    display: none !important;
}

.portrait-bar {
    flex: 1;
    height: 18px;
    background: #1a1a1a;
    border: 1px solid #333;
    border-radius: 4px;
    overflow: hidden;
    position: relative;
}

.portrait-bar-fill {
    height: 100%;
    transition: width 0.2s ease;
}

.portrait-bar-fill.health {
    background: linear-gradient(to bottom, #22cc22, #118811);
}

.portrait-bar-fill.mana {
    background: linear-gradient(to bottom, #3388ff, #2255aa);
}

.portrait-bar-text {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    text-align: center;
    font-size: 11px;
    line-height: 18px;
    color: white;
    text-shadow: 1px 1px 2px black, -1px -1px 2px black;
    font-weight: bold;
}

#mobile-menu-btn {
    width: 32px;
    height: 32px;
    border-radius: 6px;
    font-size: 16px;
    flex-shrink: 0;
    min-height: 32px;
    padding: 0;
}

/* ======================================
   Mobile Action Bar (Bottom Overlay)
   Overlay style - doesn't take space from game
   ====================================== */
#mobile-action-bar {
    display: none;
    position: fixed;
    bottom: calc(15px + var(--safe-area-bottom));
    left: 10px;
    right: 10px;
    height: auto;
    background: transparent;
    z-index: 10001;
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    padding: 0;
    padding-left: var(--safe-area-left);
    padding-right: var(--safe-area-right);
    box-sizing: border-box;
    pointer-events: none;
}

#mobile-action-bar>* {
    pointer-events: auto;
}


@media screen and (max-height: 500px),
screen and (max-width: 768px),
screen and (max-height: 560px) and (pointer: coarse) {
    #mobile-action-bar {
        display: flex;
    }
}

/* ======================================
   Virtual Joystick (Left Side)
   ====================================== */
#mobile-joystick-zone {
    width: var(--mobile-joystick-size);
    height: var(--mobile-joystick-size);
    position: relative;
    flex-shrink: 0;
}

/* Dynamic Joystick capture area — left half of the screen below the top
   bar. Sits above the game canvas (z100) so movement touches never walk
   the character, below all buttons (10001) so controls keep priority. */
/* Mobile PK Lock button — above chat button */

#mobile-pk-lock-btn {
    position: fixed;
    bottom: calc(62px + var(--safe-area-bottom));
    right: 170px;
    z-index: 10001;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 2px solid #555;
    border-radius: 50%;
    background-color: rgba(30, 30, 30, 0.9);
    cursor: pointer;
    color: #888;
    display: flex;
    justify-content: center;
    align-items: center;
    pointer-events: auto;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
}

/* Hotkey preset cycle button — sits 8px above the PK lock with the same
   round 44×44 styling. Tap cycles to next preset. */
#mobile-hotbar-preset-btn {
    position: fixed;
    bottom: calc(114px + var(--safe-area-bottom)); /* 62 + 44 + 8px gap */
    right: 170px;
    z-index: 10001;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 2px solid #555;
    border-radius: 50%;
    background-color: rgba(30, 30, 30, 0.9);
    cursor: pointer;
    color: #ddd;
    font-size: 13px;
    font-weight: bold;
    display: flex;
    justify-content: center;
    align-items: center;
    pointer-events: auto;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
    user-select: none;
}

/* Brief flash on switch so the player knows the tap registered. */
#mobile-hotbar-preset-btn.flash {
    background-color: rgba(212, 160, 23, 0.9);
    color: #fff;
    transition: background-color 0.2s, color 0.2s;
}

#mobile-pk-lock-btn svg {
    pointer-events: none;
}

/* Icon toggle — the secure mode button (FightModeSelector, same states as the desktop #pk-lock-btn in fight-mode.css):
   .active = secure mode on, green shield; neither = secure mode off, red skull. (.skulled and .peaceful are unused.) */
#mobile-pk-lock-btn .pk-icon-shield,
#mobile-pk-lock-btn .pk-icon-cracked,
#mobile-pk-lock-btn .pk-icon-skull,
#mobile-pk-lock-btn .pk-icon-peace { display: none; }
#mobile-pk-lock-btn.active .pk-icon-shield { display: block; }
#mobile-pk-lock-btn.skulled .pk-icon-cracked { display: block; }
#mobile-pk-lock-btn.active.skulled .pk-icon-cracked { display: none; }
#mobile-pk-lock-btn:not(.active):not(.skulled):not(.peaceful) .pk-icon-skull { display: block; }
/* Peaceful world (non-PvP) — declared last and with .peaceful excluded from
   the red fallback above, so this state can never show a skull. */
#mobile-pk-lock-btn.peaceful .pk-icon-shield,
#mobile-pk-lock-btn.peaceful .pk-icon-cracked,
#mobile-pk-lock-btn.peaceful .pk-icon-skull { display: none; }
#mobile-pk-lock-btn.peaceful .pk-icon-peace { display: block; }

/* PK Lock ON (safe) — green glow */
#mobile-pk-lock-btn.active {
    border-color: #4CAF50;
    box-shadow: 0 0 8px rgba(76, 175, 80, 0.6);
    color: #c8e6c9;
    background-color: rgba(51, 51, 51, 0.9);
}

/* PK Lock SKULLED (partial) — amber glow. Before the red rule so :not(.active)
   cannot also claim this state. */
#mobile-pk-lock-btn.skulled {
    border-color: #FFC107;
    box-shadow: 0 0 8px rgba(255, 193, 7, 0.6);
    color: #ffe9a8;
    background-color: rgba(51, 51, 51, 0.9);
}

/* PK Lock OFF (PVP enabled) — red glow */
#mobile-pk-lock-btn:not(.active):not(.skulled):not(.peaceful) {
    border-color: #ff3333;
    box-shadow: 0 0 8px rgba(255, 51, 51, 0.6);
    color: #ffcccc;
    background-color: rgba(51, 51, 51, 0.9);
}

/* Peaceful world (non-PvP) — calm blue, no glow: a resting state, not an
   armed one. Tap explains the world instead of toggling. */
#mobile-pk-lock-btn.peaceful {
    border-color: #5b87a6;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
    color: #b8d4e8;
    background-color: rgba(51, 51, 51, 0.9);
}

#virtual-joystick {
    position: absolute;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(40, 40, 40, 0.85) 0%, rgba(20, 20, 20, 0.7) 100%);
    border: 3px solid rgba(100, 100, 100, 0.6);
    box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
}

#joystick-knob {
    position: absolute;
    width: 45%;
    height: 45%;
    top: 27.5%;
    left: 27.5%;
    border-radius: 50%;
    background: radial-gradient(circle at 30% 30%, #888 0%, #444 50%, #333 100%);
    border: 2px solid #999;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5);
    transition: transform 0.05s ease-out;
}

/* ======================================
   Virtual D-Pad
   ====================================== */
#virtual-dpad {
    position: absolute;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(40, 40, 40, 0.85) 0%, rgba(20, 20, 20, 0.7) 100%);
    border: 3px solid rgba(100, 100, 100, 0.6);
    box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
}

.dpad-arrow {
    position: absolute;
    color: rgba(180, 180, 180, 0.7);
    font-size: 16px;
    text-align: center;
    pointer-events: none;
    transition: color 0.1s ease, text-shadow 0.1s ease;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
}

.dpad-arrow.active {
    color: rgba(255, 200, 60, 0.95);
    text-shadow: 0 0 8px rgba(255, 200, 60, 0.5);
}

.dpad-up {
    top: 6%;
    left: 50%;
    transform: translateX(-50%);
}

.dpad-right {
    right: 6%;
    top: 50%;
    transform: translateY(-50%);
}

.dpad-down {
    bottom: 6%;
    left: 50%;
    transform: translateX(-50%);
}

.dpad-left {
    left: 6%;
    top: 50%;
    transform: translateY(-50%);
}

/* 8-Way D-Pad (movement style "dpad8"): diagonal corner arrows. Purely visual —
   the d-pad's 8-zone angle math already walks diagonally; these make the corner
   press targets visible and light up on a diagonal. Hidden in classic 4-way.
   15% ≈ on the circular rim at 45° (cardinals sit at 6% on the axes). */
.dpad-diag {
    display: none;
    font-size: 13px;
}
#virtual-dpad.dpad8 .dpad-diag {
    display: block;
}
.dpad-upleft    { top: 15%;    left: 15%; }
.dpad-upright   { top: 15%;    right: 15%; }
.dpad-downleft  { bottom: 15%; left: 15%; }
.dpad-downright { bottom: 15%; right: 15%; }

.dpad-center {
    position: absolute;
    width: 20%;
    height: 20%;
    top: 40%;
    left: 40%;
    border-radius: 50%;
    background: rgba(60, 60, 60, 0.6);
    border: 1px solid rgba(100, 100, 100, 0.4);
    transition: background 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

.dpad-center.turn-active {
    background: rgba(255, 200, 60, 0.3);
    border-color: rgba(255, 200, 60, 0.7);
    box-shadow: 0 0 8px rgba(255, 200, 60, 0.5);
}

/* ======================================
   Mobile Hotbar (Center) - Skill slots
   ====================================== */
#mobile-hotbar {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 5px;
    padding: 0;
    background: none;
    border: none;
    border-radius: 0;
    max-width: none;
}

.mobile-hotbar-slot {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    background: radial-gradient(circle at 35% 35%, #3a3a3a, #1a1a1a);
    border: 2px solid #555;
    border-radius: 50%;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: none;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

.mobile-hotbar-slot:active {
    transform: scale(0.95);
    border-color: #888;
}

.mobile-hotbar-slot canvas {
    width: 32px;
    height: 32px;
}

.hotbar-count {
    position: absolute;
    bottom: 1px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 10px;
    font-weight: bold;
    color: #88ff88;
    text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
    pointer-events: none;
    z-index: 1;
}

.mobile-hotbar-duration {
    position: absolute;
    top: 1px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 9px;
    font-weight: bold;
    color: #ffcc00;
    text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
    pointer-events: none;
    z-index: 2;
    white-space: nowrap;
}

/* Text-hotkey preview label on mobile. Discriminator matches the desktop
   pattern (see hotbar.css) — touch.js applies data-text-label + custom
   inline styles when a slot is text-bound. Inline styles set top/left/
   transform to re-center the label over the slot; this rule just keeps
   the text-shadow + line-height so the centered label stays legible. */
.mobile-hotbar-duration[data-text-label] {
    text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
    line-height: 1;
}

/* Two-line text-hotkey label on mobile (mirrors hotbar.css .hk-cmd/.hk-name):
   tiny command tag (exiva / sio) stacked above the compressed target name, for
   name-targeted commands. touch.js builds the child spans. */
.mobile-hotbar-duration[data-text-label] .hk-cmd {
    display: block;
    font-size: 6px;
    font-weight: normal;
    line-height: 1;
    opacity: 0.8;
}
.mobile-hotbar-duration[data-text-label] .hk-name {
    display: block;
    font-size: 9px;
    font-weight: bold;
    line-height: 1;
    margin-top: 1px;
}

.mobile-slot-key {
    position: absolute;
    bottom: 2px;
    right: 2px;
    font-size: 10px;
    color: #999;
    font-weight: bold;
    text-shadow: 1px 1px 1px black;
}

/* Edit mode toggle button - styled as a hotbar slot */
#mobile-hotbar-edit-btn {
    font-size: 18px;
    color: #999;
}

#mobile-hotbar-edit-btn.active {
    background: radial-gradient(circle at 35% 35%, #4a3000, #1a1000) !important;
    border-color: #ffa000 !important;
    color: #ffa000;
}

/* Hotbar slot feedback animations */
.mobile-hotbar-slot.hotbar-success {
    animation: mobile-hotbar-success 0.2s ease-out;
}

.mobile-hotbar-slot.hotbar-reject {
    animation: mobile-hotbar-reject 0.3s ease-out;
}

@keyframes mobile-hotbar-success {
    0% { transform: scale(1); border-color: #555; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); }
    40% { transform: scale(1.3); border-color: #ffaa00; box-shadow: 0 0 14px 3px rgba(255, 170, 0, 0.8); }
    100% { transform: scale(1); border-color: #555; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); }
}

@keyframes shake {
    0%, 100% { transform: translateX(0); }
    15% { transform: translateX(-5px); }
    30% { transform: translateX(5px); }
    45% { transform: translateX(-4px); }
    60% { transform: translateX(4px); }
    75% { transform: translateX(-2px); }
    90% { transform: translateX(0); }
}

@keyframes mobile-hotbar-reject {
    0%, 100% { transform: translateX(0); border-color: #555; }
    15% { transform: translateX(-4px); border-color: #ff4444; }
    30% { transform: translateX(4px); border-color: #ff4444; }
    45% { transform: translateX(-3px); border-color: #ff3333; }
    60% { transform: translateX(3px); border-color: #ff3333; }
    75% { transform: translateX(-1px); border-color: #ff2222; }
    90% { transform: translateX(0); border-color: #555; }
}

/* Edit mode visual indicator on slots */
.mobile-hotbar-slot.edit-mode {
    border-color: #ffa000 !important;
    animation: edit-pulse 1.5s ease-in-out infinite;
}

@keyframes edit-pulse {
    0%, 100% { box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); }
    50% { box-shadow: 0 0 8px rgba(255, 160, 0, 0.4); }
}

/* Selected slot in edit mode */
.mobile-hotbar-slot.edit-selected {
    border-color: #fff !important;
    box-shadow: 0 0 12px rgba(255, 255, 255, 0.6) !important;
    animation: none !important;
}

/* Extra Mobile Hotbar — 3 additional slots (toggle via Settings > Controls) */
#mobile-extra-hotbar,
#mobile-extra-hotbar-2 {
    display: none;
    grid-template-columns: repeat(3, 1fr);
    gap: 5px;
    padding: 0;
    background: none;
    border: none;
    position: fixed;
    z-index: 10000;
    pointer-events: auto;
}

#mobile-extra-hotbar.visible,
#mobile-extra-hotbar-2.visible {
    display: grid;
}

/* Landscape: stack extra hotbar vertically */
@media screen and (orientation: landscape) {
    #mobile-extra-hotbar,
    #mobile-extra-hotbar-2 {
        grid-template-columns: 1fr !important;
    }
}

/* Portrait: row layout */
@media screen and (orientation: portrait) {
    #mobile-extra-hotbar,
    #mobile-extra-hotbar-2 {
        grid-template-columns: repeat(3, 1fr) !important;
    }
}

/* Layout-editor per-bar orientation override: #id.class outweighs the
   media-query #id defaults above, so a saved choice wins in either
   screen orientation */
#mobile-extra-hotbar.orient-v,
#mobile-extra-hotbar-2.orient-v {
    grid-template-columns: 1fr !important;
}

#mobile-extra-hotbar.orient-h,
#mobile-extra-hotbar-2.orient-h {
    grid-template-columns: repeat(3, 1fr) !important;
}

.mobile-extra-hotbar-slot {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    background: radial-gradient(circle at 35% 35%, #2a2a3a, #0a0a1a);
    border: 2px solid #6655aa;
    border-radius: 50%;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: none;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    user-select: none;
}

.mobile-extra-hotbar-slot:active {
    transform: scale(0.95);
    border-color: #9988cc;
}

.mobile-extra-hotbar-slot canvas {
    width: 32px;
    height: 32px;
}

.mobile-extra-hotbar-slot .mobile-hotbar-duration {
    position: absolute;
    top: 1px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 9px;
    font-weight: bold;
    color: #ffcc00;
    text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
    pointer-events: none;
    z-index: 2;
    white-space: nowrap;
}

.mobile-extra-hotbar-slot .mobile-slot-key {
    position: absolute;
    bottom: 2px;
    right: 2px;
    font-size: 10px;
    color: #7766bb;
    font-weight: bold;
    text-shadow: 1px 1px 1px black;
}

/* Extra hotbar feedback animations */
.mobile-extra-hotbar-slot.hotbar-success {
    animation: mobile-hotbar-success 0.2s ease-out;
}

.mobile-extra-hotbar-slot.hotbar-reject {
    animation: mobile-hotbar-reject 0.3s ease-out;
}

.mobile-extra-hotbar-slot.edit-mode {
    border-color: #ffa000 !important;
    animation: edit-pulse 1.5s ease-in-out infinite;
}

.mobile-extra-hotbar-slot.edit-selected {
    border-color: #fff !important;
    box-shadow: 0 0 12px rgba(255, 255, 255, 0.6) !important;
    animation: none !important;
}

.mobile-action-btn {
    width: var(--mobile-action-btn-size);
    height: var(--mobile-action-btn-size);
    min-width: var(--mobile-action-btn-size);
    min-height: var(--mobile-action-btn-size);
    border-radius: 50%;
    border: 3px solid;
    color: white;
    font-size: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.5);
    padding: 0;
}

#mobile-fullscreen-btn {
    border: none;
    border-radius: 0;
    box-shadow: none;
    background: transparent;
}

.mobile-action-btn:active {
    transform: scale(0.9);
    filter: brightness(1.2);
}


/* ======================================
   Mobile Chat Button
   ====================================== */
#mobile-chat-btn {
    position: fixed;
    bottom: calc(12px + var(--safe-area-bottom));
    right: 170px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    background: radial-gradient(circle at 35% 35%, #3a3a3a, #1a1a1a);
    border: 2px solid #555;
    font-size: 20px;
    z-index: 9999;
    align-items: center;
    justify-content: center;
    touch-action: none;
    -webkit-tap-highlight-color: transparent;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
    padding: 0;
}

#mobile-chat-btn:active {
    transform: scale(0.95);
    border-color: #888;
}

/* ======================================
   Mobile Use-With Targeting Indicator
   ====================================== */
#mobile-use-indicator {
    display: none !important;
    position: fixed;
    top: 42px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, 0.55);
    color: #ddb944;
    font-size: 11px;
    padding: 3px 10px;
    border-radius: 10px;
    z-index: 9999;
    font-family: "Martel", serif;
    -webkit-tap-highlight-color: transparent;
}

#mobile-use-indicator.active {
    display: block !important;
}

.mobile-chat-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    background: #ff4444;
    color: white;
    font-size: 9px;
    font-weight: bold;
    min-width: 16px;
    height: 16px;
    border-radius: 8px;
    display: none;
    align-items: center;
    justify-content: center;
    padding: 0 3px;
    box-sizing: border-box;
}

.mobile-dm-badge {
    right: auto;
    left: -4px;
    background: #44aaff;
}

.mobile-guild-badge {
    top: auto;
    bottom: -4px;
    right: -4px;
    background: #d4a017;
}

/* ======================================
   Mobile Chat — Desktop .lower is hidden on mobile
   (New dedicated mobile chat system uses #mobile-chat instead)
   ====================================== */
@media screen and (max-height: 500px),
screen and (max-width: 768px),
screen and (max-height: 560px) and (pointer: coarse) {

    /* Desktop chat panel hidden on mobile — replaced by #mobile-chat */
    #game-wrapper .main .lower {
        display: none !important;
    }

}

/* Menu button in action bar */
#mobile-menu-btn.mobile-action-btn {
    background: linear-gradient(145deg, #555, #333);
    border-color: #888;
    font-size: 18px;
}

/* ======================================
   Landscape Specific Optimizations
   ====================================== */
@media screen and (max-height: 500px) and (orientation: landscape) {

    :root {
        --mobile-action-btn-size: 44px;
        --mobile-joystick-size: 115px;
        --mobile-hotbar-height: 50px;
        --mobile-header-height: 32px;
    }

    /* Compact status bar */
    #mobile-status-bar {
        height: 28px;
    }


    .mobile-bar {
        height: 16px;
    }

    .mobile-bar-text {
        font-size: 10px;
        line-height: 16px;
    }

    #mobile-menu-btn {
        order: 1;
        width: 28px;
        height: 28px;
        min-height: 28px;
        font-size: 14px;
    }

    #mobile-fullscreen-btn {
        order: 2;
        width: 28px;
        height: 28px;
        min-height: 28px;
        font-size: 14px;
    }

    .mobile-bar-container {
        order: 3;
    }

    #mobile-tab-bar {
        order: 4;
    }

    /* Action bar positioning for landscape */
    #mobile-action-bar {
        bottom: calc(12px + var(--safe-area-bottom));
        left: 8px;
        right: 8px;
    }

    /* Smaller touch targets in compact landscape */
    .mobile-action-btn {
        font-size: 16px;
    }

    .mobile-hotbar-slot {
        width: 42px;
        height: 42px;
    }

    .mobile-hotbar-slot canvas {
        width: 29px;
        height: 29px;
    }

    .mobile-extra-hotbar-slot {
        width: 42px;
        height: 42px;
    }

    .mobile-extra-hotbar-slot canvas {
        width: 29px;
        height: 29px;
    }

    #mobile-hotbar {
        gap: 4px;
    }

    #mobile-extra-hotbar {
        gap: 4px;
    }

    /* Canvas: maintain aspect ratio — fill height, auto width */
    #screen {
        width: auto !important;
        height: 100% !important;
        aspect-ratio: 480 / 352;
        max-width: 100%;
    }

    .canvas-wrapper {
        width: auto !important;
        height: 100% !important;
        display: flex !important;
        justify-content: center !important;
        align-items: center !important;
    }
}

/* ======================================
   Portrait Mode (Phone Upright)
   ====================================== */
@media screen and (max-width: 768px) and (orientation: portrait) {

    :root {
        --mobile-action-btn-size: 56px;
        --mobile-joystick-size: 110px;
    }

    /* Swap login background to portrait version */
    #login-wrapper #login-inner img.bg-landscape { display: none !important; }
    #login-wrapper #login-inner img.bg-portrait { display: block !important; }

    /* Portrait layout: column with canvas centered vertically */
    #game-wrapper .main {
        background-color: #444;
        background-image: url("/png/bg.png");
        height: 100dvh !important;
        min-height: 100dvh !important;
        justify-content: center !important;
    }

    /* Canvas: maintain landscape aspect ratio instead of stretching */
    #screen {
        width: 100% !important;
        height: auto !important;
        aspect-ratio: 480 / 352;
    }

    /* Canvas wrapper: don't force full height, let canvas size naturally */
    .canvas-wrapper {
        width: 100% !important;
        height: auto !important;
    }

    /* Upper area: shrink to fit canvas, don't stretch to fill */
    #game-wrapper .main .upper {
        flex: 0 0 auto !important;
    }

    /* Hide HP/mana from top status bar in portrait (shown below canvas instead) */
    #mobile-status-bar .mobile-bar-container {
        display: none !important;
    }

    .mobile-container-body {
        max-height: 172px !important;
    }

    /* Portrait bars: show below canvas */
    #portrait-bars {
        display: flex !important;
        flex-direction: row;
        gap: 8px;
        padding: 4px 8px;
        background: #111;
        border-top: 1px solid #333;
        flex: 0 0 auto;
    }

    /* Status-bar-at-bottom (user toggle) or iphone-notch: the status bar is a
       FIXED opaque overlay at bottom:0 — and in portrait its HP/mana content
       is hidden (swapped into #portrait-bars above). Without clearance the
       relocated-but-EMPTY bar covers the portrait bars and HP/mana vanishes
       entirely (owner 2026-08-03, foldable folded in + setting enabled).
       Margin on this in-flow flex child shrinks the canvas by the same
       amount, so the bars sit visibly above the fixed bar. */
    html.status-bar-bottom:not(.iphone-notch) body.force-mobile #portrait-bars,
    html.iphone-notch.status-bar-bottom body.force-mobile #portrait-bars {
        margin-bottom: calc(var(--mobile-header-height) + 14px);
    }

    /* Bottom bar positions — more room in portrait */
    #mobile-action-bar {
        bottom: calc(20px + var(--safe-area-bottom));
    }

    /* Smaller hotbar in portrait — 10% reduction */
    .mobile-hotbar-slot {
        width: 43px;
        height: 43px;
    }

    .mobile-hotbar-slot canvas {
        width: 29px;
        height: 29px;
    }

    .mobile-extra-hotbar-slot {
        width: 43px;
        height: 43px;
    }

    .mobile-extra-hotbar-slot canvas {
        width: 29px;
        height: 29px;
    }

    #mobile-hotbar {
        gap: 4px;
    }

    #mobile-extra-hotbar {
        gap: 4px;
    }

}

/* ======================================
   iOS Safari / Notch Support
   ====================================== */
@supports (padding: env(safe-area-inset-top)) {
    #mobile-status-bar {
        padding-top: env(safe-area-inset-top);
        height: calc(var(--mobile-header-height) + env(safe-area-inset-top));
        /* Opaque background so iOS status bar text (clock/battery) is readable over it */
        background: linear-gradient(to bottom, rgba(0, 0, 0, 0.95), rgba(0, 0, 0, 0.8));
    }
}

/* Prevent iOS rubber banding */
@supports (-webkit-touch-callout: none) {

    html,
    body {
        height: 100%;
        overflow: hidden;
    }

    #game-wrapper {
        height: -webkit-fill-available;
    }
}

/* ======================================
   iPhone Notch/Home Indicator Fallback
   JS adds .iphone-notch class when env() safe area values are unreliable.
   Since 2026-08-22 (Daggs report) the notch rules are GATED on the
   status-bar-bottom SETTING class: notch supplies the 14px safe-area
   flavor of the bottom layout, but the SETTING decides top vs bottom —
   unchecking it on a notched iPhone genuinely returns the bar to the top.
   (iOS users are seeded status-bar-bottom=true, so defaults are unchanged.)
   ====================================== */
.iphone-notch {
    background: #000 !important;
}

/* Cancel messages ("You cannot use this object yet.") sit at the BOTTOM of
   the canvas (.canvas-notification { bottom: 2px }) — with the status bar
   moved down there they render ON TOP of the HP/mana bars (player report
   2026-08-17, iOS screenshot). Lift them clear of the bar in BOTH
   bottom-bar layouts; each offset matches that layout's own bar height
   (notch: header + 14px padding, toggle: header + 4px) plus a 4px gap. */
html.iphone-notch.status-bar-bottom .canvas-notification {
    bottom: calc(var(--mobile-header-height) + 18px);
}

html.status-bar-bottom:not(.iphone-notch) body.force-mobile .canvas-notification {
    bottom: calc(var(--mobile-header-height) + 8px);
}

/* Move status bar to bottom */
html.iphone-notch.status-bar-bottom #mobile-status-bar {
    top: auto;
    bottom: 0;
    padding-bottom: 14px;
    height: calc(var(--mobile-header-height) + 14px);
    border-bottom: none;
    border-top: 1px solid #444;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.95), rgba(0, 0, 0, 0.8));
}

/* Panels that normally sit below the top bar — move to top edge */
html.iphone-notch.status-bar-bottom #mobile-container-panel {
    top: 5px !important;
}

html.iphone-notch.status-bar-bottom .equipment.wrapper {
    top: 5px !important;
}

html.iphone-notch.status-bar-bottom .mobile-tab-panel {
    top: 5px !important;
}

/* Bottom elements sit above the status bar */
html.iphone-notch.status-bar-bottom #mobile-action-bar {
    bottom: calc(15px + var(--mobile-header-height) + 14px) !important;
}

html.iphone-notch.status-bar-bottom #mobile-chat-btn {
    bottom: calc(12px + var(--mobile-header-height) + 14px) !important;
}

html.iphone-notch.status-bar-bottom #mobile-pk-lock-btn {
    bottom: calc(62px + var(--mobile-header-height) + 14px) !important;
}

/* ======================================
   USER OPT-IN: Status bar at bottom
   --------------------------------------
   Toggle in Settings → Optimization → Layout. Adds .status-bar-bottom on
   <html> and mirrors the .iphone-notch positioning for the status bar +
   the bottom-anchored elements that need to clear it. Useful on any phone
   whose top-edge gestures (Control Center, notification shade, OS back
   swipe) keep eating taps in the top status-bar area.
   Skipped if the device is already a notched iPhone — .iphone-notch
   already does this and stacking would double the offsets.
   ====================================== */
html.status-bar-bottom:not(.iphone-notch) #mobile-status-bar {
    top: auto;
    bottom: 0;
    padding-bottom: 4px;
    height: calc(var(--mobile-header-height) + 4px);
    border-bottom: none;
    border-top: 1px solid #444;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.95), rgba(0, 0, 0, 0.8));
}

html.status-bar-bottom:not(.iphone-notch) #mobile-container-panel {
    top: 5px !important;
    /* Clip the bottom so a tall container stack (many tabs / large bp)
       doesn't grow under the bottom-anchored status bar. Reported in
       landscape mobile 2026-05-03. */
    max-height: calc(100vh - var(--mobile-header-height) - 10px) !important;
}

html.status-bar-bottom:not(.iphone-notch) .equipment.wrapper {
    top: 5px !important;
    max-height: calc(100vh - var(--mobile-header-height) - 10px) !important;
}

html.status-bar-bottom:not(.iphone-notch) .mobile-tab-panel {
    top: 5px !important;
    max-height: calc(100vh - var(--mobile-header-height) - 10px) !important;
}

html.status-bar-bottom:not(.iphone-notch) #mobile-action-bar {
    bottom: calc(15px + var(--mobile-header-height) + 4px) !important;
}

html.status-bar-bottom:not(.iphone-notch) #mobile-chat-btn {
    bottom: calc(12px + var(--mobile-header-height) + 4px) !important;
}

html.status-bar-bottom:not(.iphone-notch) #mobile-pk-lock-btn {
    bottom: calc(62px + var(--mobile-header-height) + 4px) !important;
}

/* Hotbar preset cycle button — sits 8px above the PK lock. Without this
   override it kept its safe-area-only offset and floated low when the
   status bar moved to the bottom. Reported 2026-05-02. */
html.status-bar-bottom:not(.iphone-notch) #mobile-hotbar-preset-btn {
    bottom: calc(114px + var(--mobile-header-height) + 4px) !important;
}

/* Foldable + status-bar-bottom: the rules above use base-mobile
   44px-button math (12 / 62 / 114 base offsets). On foldable the chat
   /PK/preset buttons grow to 50×50, so those offsets leave chat-top
   touching PK-bottom (zero gap) and preset only 2px above PK instead
   of 6px — the bottom-right column looks crushed. Re-derive for 50px
   buttons with 6px gaps; chat is unchanged (66+header top works for
   both sizes since chat's bottom is 12+header+4 in both, and its top
   just shifts up by 6 when height grows from 44→50). PK and preset
   need explicit 50px-aware bottoms. !important required to beat the
   generic html.status-bar-bottom rules above. */
html.status-bar-bottom:not(.iphone-notch) body.force-foldable #mobile-pk-lock-btn {
    bottom: calc(72px + var(--mobile-header-height)) !important;
}
html.status-bar-bottom:not(.iphone-notch) body.force-foldable #mobile-hotbar-preset-btn {
    bottom: calc(128px + var(--mobile-header-height)) !important;
}

/* Chat window must clear the bottom-anchored status bar — without
   this it sits at bottom:0 too, and the status bar (z-index 10001)
   covers it. Reported on tablet 2026-05-02. */
html.status-bar-bottom:not(.iphone-notch) #mobile-chat {
    bottom: calc(var(--mobile-header-height) + 4px) !important;
}

/* ==========================================================================
   IPHONE DYNAMIC ISLAND FIX — LAYOUT/KEYBOARD EDITOR TOOLBARS (added 2026-04-16)
   --------------------------------------------------------------------------
   Pushes the Save/Cancel toolbars below the Dynamic Island on iPhones with
   notch (.iphone-notch class added by JS in index.html based on UA).
   Without this, the buttons at top:0 are covered by the island and untappable.
   DOES NOT affect Android, desktop, iPads, or older iPhones without notch.
   If this causes issues on any iPhone model, DELETE this block — the default
   top:0 positioning will return.
   ========================================================================== */
/* #layout-editor-toolbar is centered on screen (top:50%). #keyboard-editor-
   toolbar is now anchored above the virtual keyboard (bottom: var(...)), so
   neither needs a notch-specific offset anymore. */
/* END IPHONE DYNAMIC ISLAND FIX */

/* ======================================
   Layout Tip Toast
   ====================================== */
#layout-tip-toast {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    z-index: 10002;
    background: rgba(0, 0, 0, 0.85);
    border: 1px solid #555;
    border-radius: 8px;
    padding: 10px 14px;
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 13px;
    color: #ccc;
    white-space: nowrap;
    animation: toast-fade-in 0.4s ease;
    pointer-events: auto;
    touch-action: manipulation;
}

#layout-tip-toast.toast-hiding {
    animation: toast-fade-out 0.4s ease forwards;
}

#layout-tip-btn {
    background: #cc8800;
    color: #fff;
    border: none;
    border-radius: 4px;
    padding: 6px 12px;
    font-size: 12px;
    font-weight: bold;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

#layout-tip-close {
    background: none;
    border: none;
    color: #888;
    font-size: 16px;
    cursor: pointer;
    padding: 2px 4px;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

@keyframes toast-fade-in {
    from { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }
    to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

@keyframes toast-fade-out {
    from { opacity: 1; transform: translate(-50%, -50%) scale(1); }
    to { opacity: 0; transform: translate(-50%, -50%) scale(0.95); }
}

/* ======================================
   Debug Statistics - Make Smaller on Mobile
   ====================================== */
@media screen and (max-height: 500px),
screen and (max-width: 768px),
screen and (max-height: 560px) and (pointer: coarse) {
    #debug-statistics {
        font-size: 8px !important;
        top: 4px !important;
        left: 4px !important;
        margin: 0 !important;
        /* Above the equipment/tab panels (z 9998), which flip to the LEFT in
           landscape and otherwise hide the HUD entirely; below the top controls
           (z 10001+). Also pin it to the actual top-left corner (was top:40px,
           which pushed it down out of the corner in portrait). */
        z-index: 9999 !important;
        max-width: 200px;
        background: rgba(0, 0, 0, 0.7);
        padding: 4px;
        border-radius: 4px;
    }
    #debug-statistics:empty {
        display: none;
    }
}

/* ======================================
   Left-Side Tab Position (.mobile-tab-left)
   ====================================== */
@media screen and (max-height: 500px),
screen and (max-width: 768px),
screen and (max-height: 560px) and (pointer: coarse) {

    /* Equipment panel: flip to left */
    .equipment.wrapper.mobile-tab-left {
        right: auto !important;
        left: 5px !important;
        transform-origin: top left !important;
    }

    /* Tab panels: flip to left */
    .mobile-tab-panel.mobile-tab-left {
        right: auto !important;
        left: 5px !important;
        transform-origin: top left;
    }

}

/* ======================================
   Mobile Panel Headers (Close/Minimize)
   ====================================== */
.mobile-panel-header {
    display: none;
}

@media screen and (max-height: 500px),
screen and (max-width: 768px),
screen and (max-height: 560px) and (pointer: coarse) {

    .mobile-panel-header {
        display: flex;
        align-items: center;
        height: 22px;
        padding-left: 4px;
        background-image: url("/png/bg4.png");
        color: grey;
    }

    .mobile-panel-header > .symbol-button {
        flex: 0 0 auto;
    }

    .mobile-panel-header > .title {
        flex: 1 1 auto;
        padding-left: 8px;
        pointer-events: none;
    }

    /* Minimized state - hide all content except header */
    .mobile-minimized > :not(.mobile-panel-header) {
        display: none !important;
    }

    /* Item drag highlight on drop target slot */
    .slot.mobile-drag-target {
        outline: 2px solid #44ff44 !important;
        outline-offset: -2px;
        background-color: rgba(68, 255, 68, 0.15) !important;
    }
}

/* ======================================
   Mobile Login Screen
   ====================================== */
@media screen and (max-height: 500px),
screen and (max-width: 768px),
screen and (max-height: 560px) and (pointer: coarse) {

    /* Remove min-width constraints */
    #login-wrapper {
        min-width: unset !important;
        min-height: unset !important;
        width: 100vw;
        height: 100vh;
        height: 100dvh;
        overflow: hidden;
    }

    #login-wrapper #login-inner {
        min-width: unset !important;
        min-height: unset !important;
        width: 100%;
        height: 100%;
        overflow: hidden;
    }

    /* Background image covers screen */
    #login-wrapper #login-inner > img {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        z-index: 0;
    }

    /* Version info - smaller, top-left */
    #login-wrapper #login-inner .login-version {
        z-index: 2;
        font-size: 10px;
        top: 4px;
        left: 6px;
        text-shadow: 1px 1px 3px black, -1px -1px 3px black;
    }

    /* Buttons - centered on screen */
    #login-wrapper #login-inner .login-settings {
        z-index: 2;
        position: absolute;
        left: 50% !important;
        top: 50% !important;
        bottom: auto !important;
        transform: translate(-50%, -50%);
        width: auto !important;
        padding: 8px !important;
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 4px;
        background-color: rgba(0, 0, 0, 0.6);
        border-radius: 8px;
        max-width: 90vw;
    }

    #login-wrapper #login-inner .login-settings button {
        width: auto !important;
        min-width: 80px;
        height: 28px !important;
        font-size: 11px;
        margin: 0 !important;
    }

    #login-wrapper #login-inner .login-settings #login-display-mode {
        width: auto !important;
        min-width: 80px;
        height: 28px !important;
        font-size: 11px;
        margin: 0 !important;
    }

    /* Login modals - fit mobile screen */
    #login-wrapper .modal {
        max-width: 85vw !important;
        z-index: 30000;
    }

    #login-wrapper .modal .modal-body {
        padding: 8px;
    }

    #login-wrapper .modal .modal-body input,
    #login-wrapper .modal .modal-body select {
        width: 100%;
        box-sizing: border-box;
        font-size: 14px;
        padding: 6px;
    }

    #login-wrapper .modal .modal-body button {
        font-size: 12px;
        padding: 6px 12px;
    }
}

/* ======================================
   Foldable-Specific Overrides
   Square-ish unfolded screens (Z Fold ~1.16:1, Pixel 9 Pro Fold ~1.04:1,
   OnePlus Open ~1.08:1, Honor Magic V ~1.09:1, Xiaomi Mix Fold ~1.13:1).
   Effective CSS viewport ~720–1080 wide unfolded. Narrower than a typical
   tablet landscape (1024+) but wider than a phone portrait.

   touch.js applies body.force-mobile + body.force-tablet + body.force-foldable
   when Foldable is picked, so all tablet rules apply by default. The rules
   below are *additional narrowing* on top of tablet — they fire after the
   tablet block (later in the cascade) and override only the few measurements
   that don't fit a square viewport. Tablet behavior itself is unchanged
   because body.force-tablet alone (without force-foldable) never matches
   these selectors.

   Targets the median square aspect (~1.1:1). Big foldables (Pixel 9 Pro
   Fold unfolded, ~1076 CSS px wide) get a bit more whitespace; small ones
   (Z Fold 6, ~822 CSS px) get a slightly cramped but functional layout.
   To-test list:
     - Side panels not overlapping the canvas at default zoom.
     - Equipment 4-col grid not wrapping in portrait orientation.
     - Chat + PK buttons not crowding the hotbar.
   ====================================== */
body.force-foldable {

    /* --- Panels: narrower to fit ~720-1080 CSS px viewport --- */
    .window {
        width: 220px !important;
    }

    #mobile-container-panel {
        width: 190px;
    }

    /* Equipment grid stays 4-col like tablet but with tighter column gap
       so it fits in the narrower window. Slot sizes unchanged — touch
       targets stay at the 40px tablet baseline. */
    .equipment.wrapper {
        column-gap: 2px;
    }

    /* --- Bottom-right action buttons: pull in from tablet's 200px right
       offset since foldable landscape has less horizontal real estate.
       Preset btn stays at the base 170px (mobile default) — match the
       chat / PK btn at 170px so the three line up vertically. Size the
       preset btn at 50×50 to match the tablet-inherited PK / chat sizes
       so their centers line up (tablet baseline has them mismatched —
       PK/chat are 50×50, preset stays 44×44 from base mobile, giving a
       3px horizontal-center offset; fixed here for foldable users). --- */
    #mobile-chat-btn {
        right: 170px;
    }

    #mobile-pk-lock-btn {
        right: 170px;
    }

    #mobile-hotbar-preset-btn {
        width: 50px;
        height: 50px;
        /* Bottom stack math when preset, PK, chat are all 50×50:
           chat at 12, PK at 12+50+6 = 68, preset at 68+50+6 = 124. */
        bottom: calc(124px + var(--safe-area-bottom));
    }

    /* PK btn needs to scoot up too so chat+PK+preset stack as a 6px-gap
       column when all three are 50px tall. Tablet has bottom:68, which
       was already designed for the 50px PK. Keep it. */


    /* --- Portrait orientation tweaks. Keep equipment at 4-col like
       tablet so the helmet/amulet/weapon/armor/etc. slots stay in their
       expected cells — earlier 3-col attempt scrambled the layout
       because the equipment grid relies on specific 4-col positions.
       Window width matches landscape; the side panels were already
       narrow enough at 220px. --- */
    @media (orientation: portrait) {

        /* The canvas has a fixed aspect ratio (~15×11 tiles) so on a
           square viewport in portrait it doesn't fill the screen
           vertically — the flex-center canvas-wrapper from tablet
           leaves the canvas floating in the middle. When the user
           has status bar at bottom (.status-bar-bottom or .iphone-notch),
           the gap appears between the canvas bottom and the status bar.
           Anchor the canvas to the bottom of the wrapper so it touches
           the bottom-anchored status bar with no gap. Empty space
           collects above the canvas instead. */
        .canvas-wrapper {
            align-items: flex-end !important;
        }
    }

    /* --- Tab buttons (skill tabs, friends/battle sub-tabs) live inside
       an @media (max-width:768px) block by default — foldable landscape
       (~1080px wide) and portrait (~880px wide) don't match, so the
       tabs fall back to desktop styling and look like plain text rather
       than buttons. Mirror the mobile-block rules here so foldable
       users get the same tab styling regardless of viewport size.
       Tablet is intentionally not changed — same pre-existing bug
       there, but the user explicitly asked to leave tablet alone. --- */
    .people-subtabs {
        display: flex;
        flex-direction: row;
        gap: 2px;
        padding: 2px;
        background: #222;
        border-bottom: 1px solid #111;
    }

    .people-subtab {
        flex: 1;
        padding: 5px 2px;
        background: #333;
        color: #aaa;
        border: 1px solid #111;
        font-size: 11px;
        cursor: pointer;
        font-family: inherit;
    }

    .people-subtab.active {
        background: #555;
        color: #fff;
    }

    #skill-window.mobile-tab-panel .skill-tabs {
        padding: 0 !important;
    }

    #skill-window.mobile-tab-panel .skill-tab {
        padding: 3px 2px !important;
        font-size: 10px !important;
        min-width: 0 !important;
        letter-spacing: 0 !important;
        white-space: nowrap !important;
        overflow: hidden !important;
    }

    #skill-window.mobile-tab-panel .skill-tab[data-tab="professions"] {
        font-size: 0 !important;
    }

    #skill-window.mobile-tab-panel .skill-tab[data-tab="professions"]::before {
        content: "Profs";
        font-size: 10px;
    }

    /* --- Skill window body sizing + label abbreviations.
       These live inside @media (max-width: 768px) by default. On
       foldable the viewport is wider than that (~880-1080px), so the
       full-length skill labels render at desktop size in the 220px
       panel and overflow horizontally — "character skills > skills
       goes out of bounds" report. Mirror the abbreviation rules so
       the labels fit. --- */
    #skill-window.mobile-tab-panel .body {
        display: block !important;
        overflow-y: auto !important;
        overflow-x: hidden !important;
        height: auto !important;
        max-height: 280px !important;
        padding: 4px 3px 4px 4px !important;
        box-sizing: border-box !important;
    }

    #skill-window.mobile-tab-panel .skill-wrapper {
        padding: 2px 4px !important;
        font-size: 12px !important;
        color: #fff !important;
    }

    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="experience"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="shielding"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="distance"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="fishing"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="woodcutting"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="smithing"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="cooking"] .skill-wrapper > span:first-child,
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="mining"] .skill-wrapper > span:first-child {
        font-size: 0 !important;
    }

    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="experience"] .skill-wrapper > span:first-child::before   { content: "Exp"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="shielding"] .skill-wrapper > span:first-child::before    { content: "Shld"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="distance"] .skill-wrapper > span:first-child::before     { content: "Dist"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="fishing"] .skill-wrapper > span:first-child::before      { content: "Fish"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="woodcutting"] .skill-wrapper > span:first-child::before  { content: "Wood"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="smithing"] .skill-wrapper > span:first-child::before     { content: "Smith"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="cooking"] .skill-wrapper > span:first-child::before      { content: "Cook"; font-size: 12px; }
    #skill-window.mobile-tab-panel .outer-skill-wrapper[skill="mining"] .skill-wrapper > span:first-child::before       { content: "Mine"; font-size: 12px; }

}

/* ======================================
   Tablet-Specific Overrides
   Touch device with screen larger than phone
   ====================================== */
body.force-tablet {

    /* Canvas: don't stretch to fill — use CSS transform scaling instead.
       This prevents double-scaling (CSS stretch + transform) and preserves aspect ratio.
       The transform is applied by JS getResolutionScale() via setScale(). */
    #screen {
        width: auto !important;
        height: auto !important;
        image-rendering: pixelated;
        image-rendering: -moz-crisp-edges;
        image-rendering: crisp-edges;
    }

    /* Center the canvas within its wrapper */
    .canvas-wrapper {
        display: flex !important;
        justify-content: center !important;
        align-items: center !important;
    }

    /* --- CSS Variable Overrides --- */
    :root {
        --mobile-action-btn-size: 60px;
        --mobile-joystick-size: 120px;
        --mobile-header-height: 44px;
    }

    /* --- Status Bar (taller, bigger text) --- */
    #mobile-status-bar {
        height: 44px;
        padding: 4px 16px;
        gap: 16px;
    }

    .mobile-bar {
        height: 24px;
    }

    .mobile-bar-text {
        font-size: 13px;
        line-height: 24px;
    }

    #mobile-menu-btn {
        width: 36px;
        height: 36px;
        min-height: 36px;
        font-size: 18px;
    }

    /* Tab bar buttons */
    .mobile-tab {
        padding: 0 12px;
        font-size: 15px;
    }

    /* --- Panels: remove phone cramping --- */
    .window {
        width: 250px !important;
        transform: none !important;
        top: 50px !important;
        font-size: 12px;
    }

    .equipment.wrapper {
        display: grid !important;
        grid-template-columns: auto auto auto auto;
        width: max-content !important;
        transform: none !important;
        top: 50px !important;
        align-items: start !important;
    }

    .equipment.wrapper > .mobile-panel-header {
        grid-column: 1 / -1;
    }

    #mobile-container-panel {
        width: 210px;
        transform: none !important;
        top: 50px;
        left: 5px;
        right: auto;
    }

    .minimap-container.mobile-tab-panel {
        width: auto !important;
    }

    #battle-window {
        top: 50px !important;
    }

    /* Panel headers */
    .mobile-panel-header {
        height: 26px;
    }

    /* --- Slot Sizes (larger touch targets) --- */
    .slot {
        width: 44px !important;
        height: 44px !important;
    }

    .slot canvas {
        width: 44px !important;
        height: 44px !important;
    }

    /* Equipment slots */
    .equipment.wrapper .slot {
        width: 40px !important;
        height: 40px !important;
    }

    .equipment.wrapper .slot canvas {
        width: 40px !important;
        height: 40px !important;
    }

    /* Container / window slots */
    .container-content .slot {
        width: 40px !important;
        height: 40px !important;
        margin: 2px !important;
    }

    .container-content .slot canvas {
        width: 40px !important;
        height: 40px !important;
    }

    .window .slot {
        width: 40px !important;
        height: 40px !important;
        margin: 2px !important;
    }

    .window .slot canvas {
        width: 40px !important;
        height: 40px !important;
    }

    /* --- Hotbar Slots (bigger for tablet) --- */
    .mobile-hotbar-slot {
        width: 56px;
        height: 56px;
    }

    #mobile-hotbar {
        gap: 8px;
    }

    .mobile-hotbar-slot canvas {
        width: 36px;
        height: 36px;
    }

    /* --- Chat Button (bigger, repositioned) --- */
    #mobile-chat-btn {
        width: 50px;
        height: 50px;
        font-size: 22px;
        right: 200px;
    }

    /* --- PK Lock Button (above chat) --- */
    #mobile-pk-lock-btn {
        bottom: 68px;
        right: 200px;
        width: 50px;
        height: 50px;
    }

    .mobile-chat-badge {
        min-width: 18px;
        height: 18px;
        font-size: 10px;
    }

    /* --- Mobile Container Tabs (bigger touch targets) --- */
    .mobile-container-tab {
        padding: 3px 6px;
        font-size: 11px;
        height: 24px;
    }

    /* --- Capacity text --- */
    #player-capacity {
        font-size: 12px !important;
    }

    /* --- Equipment column spacing --- */
    .equipment-column {
        gap: 4px !important;
    }

    /* --- Left-side overrides for tablet --- */
    .equipment.wrapper.mobile-tab-left {
        transform: none !important;
    }

    .mobile-tab-panel.mobile-tab-left {
        transform: none !important;
    }

    /* --- Login screen: bigger buttons for tablet --- */
    #login-wrapper #login-inner .login-settings button {
        min-width: 100px;
        height: 36px !important;
        font-size: 13px;
    }

    #login-wrapper .modal {
        max-width: 500px !important;
    }

    #login-wrapper .modal .modal-body input,
    #login-wrapper .modal .modal-body select {
        font-size: 16px;
        padding: 8px;
    }

    #login-wrapper .modal .modal-body button {
        font-size: 14px;
        padding: 8px 16px;
    }
}

/* ======================================
   Layout Editor Mode
   ====================================== */

/* Toolbar floats in the middle of the screen so it doesn't overlay the top
   mobile-tab-bar (needed to switch between Skills/Friends/Minimap during edit).
   Shown via JS (display:flex when active). */
#layout-editor-toolbar {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    height: auto;
    min-height: 44px;
    max-width: calc(100vw - 20px);
    padding: 6px 14px;
    background: rgba(0, 0, 0, 0.55);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 2px solid rgba(255, 160, 0, 0.7);
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35);
    display: none;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 8px 10px;
    z-index: 20000;
    color: #fff;
    font-size: 14px;
    font-family: "Martel", serif;
    pointer-events: auto;
}

#layout-editor-toolbar button {
    padding: 6px 14px;
    border: 1px solid #666;
    background: #333;
    color: #fff;
    border-radius: 4px;
    font-size: 13px;
    cursor: pointer;
}

#layout-editor-toolbar #layout-save-btn {
    border-color: #ffa000;
    color: #ffa000;
}

#layout-editor-toolbar #layout-reset-btn {
    border-color: #ff4444;
    color: #ff4444;
}

#layout-editor-toolbar #layout-center-btn {
    border-color: #b266ff;
    color: #b266ff;
}

#layout-center-menu {
    position: fixed;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px;
    background: rgba(0, 0, 0, 0.9);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    border: 2px solid #b266ff;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
    z-index: 20001;
    pointer-events: auto;
    font-family: "Martel", serif;
}

#layout-center-menu button {
    padding: 8px 20px;
    min-width: 120px;
    border: 1px solid #666;
    background: #333;
    color: #b266ff;
    border-radius: 4px;
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
}

@media (max-width: 480px) {
    #layout-editor-toolbar {
        gap: 6px 8px;
        padding: 6px 10px;
    }
    #layout-editor-toolbar > span {
        flex-basis: 100%;
        text-align: center;
        font-size: 12px;
    }
    #layout-editor-toolbar button {
        padding: 5px 10px;
        font-size: 12px;
    }
}

/* Drag handle overlay on each configurable element */
.layout-editor-handle {
    position: absolute;
    top: -4px;
    left: -4px;
    right: -4px;
    bottom: -4px;
    border: 2px dashed #ffa000;
    border-radius: 8px;
    animation: edit-pulse 1.5s ease-in-out infinite;
    z-index: 20001;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    pointer-events: auto;
    touch-action: none;
    background: rgba(255, 160, 0, 0.08);
}

.layout-editor-handle .handle-label {
    color: #ffa000;
    font-size: 11px;
    font-weight: bold;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
    margin-bottom: 4px;
    pointer-events: none;
}

.layout-editor-handle .handle-scale-controls {
    display: flex;
    gap: 10px;
    pointer-events: auto;
}

.layout-editor-handle .handle-scale-btn {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: 2px solid #ffa000;
    background: rgba(0, 0, 0, 0.8);
    color: #ffa000;
    font-size: 18px;
    font-weight: bold;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    line-height: 1;
}

/* Allow handle border to show outside container during editing */
body.layout-edit-mode #mobile-container-panel,
body.force-mobile.layout-edit-mode #mobile-container-panel,
body.layout-edit-mode #mobile-container-panel-2,
body.force-mobile.layout-edit-mode #mobile-container-panel-2 {
    overflow: visible !important;
}

/* Dim game canvas during layout editing */
body.layout-edit-mode #screen {
    opacity: 0.3;
    pointer-events: none;
}

/* Hide status bar interaction during editing */
body.layout-edit-mode #mobile-status-bar {
    opacity: 0.3;
    pointer-events: none;
}

/* Custom layout: make joystick and hotbar independently positioned */
body.layout-custom #mobile-joystick-zone {
    position: fixed !important;
    z-index: 10001;
    pointer-events: auto;
}

body.layout-custom #mobile-hotbar {
    position: fixed !important;
    z-index: 10001;
    pointer-events: auto;
}

body.layout-custom #mobile-extra-hotbar {
    z-index: 10001;
}

body.layout-custom #mobile-equipment-panel {
    position: fixed !important;
    z-index: 10001;
    pointer-events: auto;
    top: auto !important;
    right: auto !important;
    transform-origin: bottom left !important;
}

body.layout-custom #mobile-container-panel,
body.layout-custom #mobile-container-panel-2 {
    position: fixed !important;
    z-index: 10001;
    pointer-events: auto;
    top: auto !important;
    right: auto !important;
    transform-origin: bottom left !important;
}

/* Tab-panel windows (Skills, Friends, Minimap) repositioned via LayoutEditor.
   The default .mobile-tab-panel rule pins them to top/right — the inline
   left/bottom/transform styles need auto top/right to win. Scoping by
   body.layout-custom keeps this from leaking to the normal tab-panel flow. */
body.layout-custom #skill-window,
body.layout-custom #friend-window,
body.layout-custom .minimap-container {
    position: fixed !important;
    z-index: 10001;
    pointer-events: auto;
    top: auto !important;
    right: auto !important;
    transform-origin: bottom left !important;
}

/* ======================================
   Forced Display Mode Overrides
   Applied via JS body class when user manually selects display mode
   ====================================== */

/* --- Force Desktop: undo mobile CSS even when media queries match --- */
body.force-desktop .desktop-only { display: block !important; }
body.force-desktop .mobile-only { display: none !important; }
body.force-desktop { overflow: auto !important; touch-action: auto !important; position: static !important; }
body.force-desktop #game-wrapper { flex-direction: row !important; min-width: 960px !important; min-height: 600px !important; width: auto !important; height: 100% !important; }
body.force-desktop #game-wrapper .oogwrap { display: flex !important; position: static !important; width: auto !important; height: auto !important; overflow: visible !important; pointer-events: auto !important; z-index: auto !important; }
body.force-desktop .oogwrap .minimap-container,
body.force-desktop .oogwrap .character-status { display: block !important; }
body.force-desktop #game-wrapper .main .middle { display: flex !important; }
body.force-desktop .hotbar { display: flex !important; }
body.force-desktop #screen { width: auto !important; height: auto !important; }
body.force-desktop .canvas-wrapper { width: auto !important; height: auto !important; }
body.force-desktop .window { position: relative !important; top: auto !important; left: auto !important; right: auto !important; transform: none !important; width: auto !important; max-width: none !important; max-height: none !important; font-size: inherit !important; z-index: auto !important; }
body.force-desktop .window[containerIndex] { display: block !important; }
body.force-desktop #mobile-status-bar { display: none !important; }
body.force-desktop #mobile-action-bar { display: none !important; }
body.force-desktop #mobile-container-panel { display: none !important; }
body.force-desktop #game-wrapper .main .lower { display: flex !important; }
body.force-desktop .mobile-panel-header { display: none !important; }
body.force-desktop #chat-resizer { display: block !important; }
body.force-desktop .equipment-buttons { display: flex !important; }
body.force-desktop .equipment.wrapper { position: static !important; top: auto !important; right: auto !important; left: auto !important; width: auto !important; transform: none !important; }
body.force-desktop #battle-window { position: relative !important; top: auto !important; right: auto !important; left: auto !important; }
body.force-desktop .mobile-tab-panel { display: none !important; }
body.force-desktop #debug-statistics { font-size: inherit !important; top: auto !important; left: auto !important; }
body.force-desktop #login-wrapper { min-width: 960px !important; min-height: 600px !important; width: auto !important; height: auto !important; }
body.force-desktop #login-wrapper #login-inner { min-width: 640px !important; min-height: 480px !important; }
body.force-desktop #login-wrapper #login-inner img.bg-landscape { display: block !important; }
body.force-desktop #login-wrapper #login-inner img.bg-portrait { display: none !important; }

/* --- Force Mobile: apply mobile CSS even when media queries don't match --- */
body.force-mobile .desktop-only { display: none !important; }
body.force-mobile .mobile-only { display: flex !important; }
body.force-mobile #portrait-bars { display: none !important; }

body.force-mobile {
    overflow: hidden !important;
    touch-action: none !important;
    -webkit-touch-callout: none !important;
    -webkit-user-select: none !important;
    user-select: none !important;
    position: fixed !important;
    width: 100% !important;
    height: 100% !important;
}

body.force-mobile #game-wrapper {
    flex-direction: row !important;
    min-width: unset !important;
    min-height: unset !important;
    width: 100vw !important;
    height: 100vh !important;
    height: 100dvh !important;
    overflow: hidden !important;
    padding-bottom: var(--safe-area-bottom) !important;
    box-sizing: border-box !important;
}

body.force-mobile #game-wrapper .oogwrap {
    display: block !important;
    position: absolute !important;
    top: 0 !important;
    right: 0 !important;
    width: 0 !important;
    height: 0 !important;
    overflow: visible !important;
    pointer-events: none !important;
    z-index: 9990 !important;
}

body.force-mobile .oogwrap .minimap-container,
body.force-mobile .oogwrap .character-status { display: none !important; }
body.force-mobile .equipment-options-wrapper { display: block !important; pointer-events: auto !important; }

body.force-mobile #game-wrapper .main {
    flex: 1 1 auto !important;
    display: flex !important;
    flex-direction: column !important;
    width: 100% !important;
    height: 100% !important;
    min-height: 0 !important;
    overflow: hidden !important;
    position: relative !important;
}

body.force-mobile #game-wrapper .main .middle { display: none !important; }

body.force-mobile #game-wrapper .main .upper {
    flex: 1 1 auto !important;
    min-height: 0 !important;
    display: flex !important;
    justify-content: center !important;
    align-items: center !important;
    overflow: hidden !important;
}

body.force-mobile .canvas-wrapper { width: 100% !important; height: 100% !important; position: relative !important; }
body.force-mobile #pk-lock-btn, body.force-mobile .secure-mode-separator { display: none !important; }
body.force-mobile .canvas-notification { z-index: 10002 !important; }
body.force-mobile #screen { width: 100% !important; height: 100% !important; display: block !important; }
body.force-mobile #chat-resizer { display: none !important; }
body.force-mobile .hotbar { display: none !important; }

body.force-mobile .window {
    pointer-events: auto !important;
    position: fixed !important;
    top: 170px !important;
    left: auto !important;
    right: 5px !important;
    width: 190px !important;
    max-width: 60vw !important;
    max-height: 60vh !important;
    z-index: 9995 !important;
    overflow: visible !important;
    font-size: 11px !important;
}

body.force-mobile #battle-window { z-index: 9990 !important; top: 170px !important; right: 5px !important; left: auto !important; }
/* When shown as a People sub-tab, override the default 170px anchor so
   the window lands in the same spot as Friends. Specificity must match
   the body.force-mobile #battle-window rule above (body+id) — the added
   .mobile-tab-panel class bumps us one class higher so this wins. */
body.force-mobile #battle-window.mobile-tab-panel {
    top: calc(37px + var(--safe-area-top)) !important;
    right: calc(5px + var(--safe-area-right)) !important;
    left: auto !important;
}
body.force-mobile #battle-window.mobile-tab-panel.mobile-tab-left {
    right: auto !important;
    left: calc(5px + var(--safe-area-left)) !important;
}
body.force-mobile #trade-window { position: fixed !important; top: 50% !important; left: 50% !important; transform: translate(-50%, -50%) !important; z-index: 30000 !important; width: 240px !important; }
body.force-mobile #trade-window .body { max-height: 55vh !important; overflow-y: auto !important; }
body.force-mobile #trade-window .trade-contents { max-height: 30vh !important; }
body.force-mobile .window[containerIndex] { display: none !important; }
body.force-mobile .window[containerIndex="1"] { display: flex !important; position: fixed !important; z-index: 9997 !important; width: 180px !important; top: 50% !important; left: 50% !important; right: auto !important; transform: translate(-50%, -50%) !important; max-height: 70vh !important; border: 1px solid #555 !important; }
body.force-mobile .window[containerIndex="1"] > .header > button { min-width: 28px; min-height: 28px; }
body.force-mobile .window[containerIndex="1"] > .body { max-height: 50vh !important; overflow-y: auto !important; padding-bottom: 0 !important; border-bottom: 2px solid transparent; }
body.force-mobile .window[containerIndex="1"] .slot { width: 40px !important; height: 40px !important; }
body.force-mobile .window[containerIndex="1"] .slot canvas { width: 40px !important; height: 40px !important; }

body.force-mobile #mobile-container-panel {
    position: fixed !important;
    z-index: 9996 !important;
    width: 150px !important;
    background-image: url("/png/bg3.png") !important;
    transform: scale(0.85) !important;
    flex-direction: column !important;
    overflow: hidden !important;
    pointer-events: auto !important;
    left: 5px !important;
    right: auto !important;
    top: 37px !important;
    transform-origin: top left !important;
    border: 1px solid #333 !important;
}

/* Mobile depot panel — desktop force-mobile mode. Mirrors the @media block
   at line 273 so it has positioning/centering on desktop where the media
   query won't match. Centered floating popup (translate -50%, -50%). */
body.force-mobile #mobile-depot-panel,
body.force-mobile #mobile-float-panel {
    position: fixed !important;
    z-index: 9997 !important;
    width: 180px !important;
    background-image: url("/png/bg3.png") !important;
    flex-direction: column !important;
    overflow: hidden !important;
    pointer-events: auto !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    max-height: 70vh !important;
    border: 1px solid #555 !important;
}

body.force-mobile .window .header { height: 20px !important; line-height: 20px !important; font-size: 10px !important; }
body.force-mobile .window .body { max-height: 40vh !important; overflow-y: auto !important; display: flex !important; flex-wrap: wrap !important; justify-content: center !important; padding: 2px !important; min-height: 0 !important; }
body.force-mobile .window .footer { display: none !important; }
body.force-mobile #friend-window .footer { display: block !important; }
body.force-mobile .window .slot { width: 32px !important; height: 32px !important; margin: 1px !important; border: 1px solid #444 !important; }
body.force-mobile .container-content .slot { width: 32px !important; height: 32px !important; margin: 1px !important; border: 1px solid #444 !important; }
body.force-mobile .container-content .slot canvas { width: 32px !important; height: 32px !important; }
body.force-mobile .slot { width: 36px !important; height: 36px !important; }
body.force-mobile .slot canvas { width: 36px !important; height: 36px !important; }

body.force-mobile .equipment.wrapper {
    position: fixed !important;
    top: 37px !important;
    right: 5px !important;
    left: auto !important;
    z-index: 9998 !important;
    background-image: url("/png/bg3.png") !important;
    padding: 0 2px 2px 2px !important;
    width: 140px !important;
    flex-wrap: wrap !important;
}

body.force-mobile .equipment.wrapper .slot { width: 30px !important; height: 30px !important; }
body.force-mobile .equipment.wrapper .slot canvas { width: 30px !important; height: 30px !important; }
body.force-mobile #player-capacity { font-size: 10px !important; padding: 2px !important; }
body.force-mobile .equipment-buttons { display: none !important; }
body.force-mobile .equipment-column { gap: 2px !important; }

body.force-mobile #mobile-status-bar { display: flex !important; }
body.force-mobile #mobile-action-bar { display: flex !important; }

/* Desktop .lower hidden in force-mobile — replaced by #mobile-chat */
body.force-mobile #game-wrapper .main .lower { display: none !important; }

/* Physical Keyboard mode (tablet + Bluetooth/Magic keyboard): re-show the
 * desktop chat input bar at the bottom and hide the mobile chat trigger
 * button. Keystrokes from a hardware keyboard then route naturally to the
 * focused chat input (Press Enter to unlock → type → Press Enter to send).
 * Touch UI for everything else stays as the tablet layout.
 */
body.force-mobile.has-keyboard #game-wrapper .main .lower { display: flex !important; }
body.force-mobile.has-keyboard #mobile-chat-btn { display: none !important; }

body.force-mobile .mobile-panel-header {
    display: flex !important;
    align-items: center !important;
    height: 22px !important;
    padding-left: 4px !important;
    background-image: url("/png/bg4.png") !important;
    color: grey !important;
}

body.force-mobile .mobile-tab-panel {
    display: block !important;
    position: fixed !important;
    top: 37px !important;
    right: 5px !important;
    left: auto !important;
    z-index: 9998 !important;
    pointer-events: auto !important;
}

body.force-mobile .minimap-container.mobile-tab-panel {
    display: block !important;
    position: fixed !important;
    pointer-events: auto !important;
    background-image: url("/png/bg3.png") !important;
    width: auto !important;
    margin: 0 !important;
    padding: 4px !important;
}

body.force-mobile .mobile-minimized > :not(.mobile-panel-header) { display: none !important; }
body.force-mobile .slot.mobile-drag-target { outline: 2px solid #44ff44 !important; outline-offset: -2px; background-color: rgba(68, 255, 68, 0.15) !important; }

body.force-mobile #debug-statistics { font-size: 8px !important; top: 4px !important; left: 4px !important; margin: 0 !important; z-index: 9999 !important; max-width: 200px !important; background: rgba(0, 0, 0, 0.7) !important; padding: 4px !important; border-radius: 4px !important; }
body.force-mobile #debug-statistics:empty { display: none !important; }

/* Performance HUD (#debug-statistics) in LANDSCAPE: the canvas fills the full
   height, so .upper's top-left sits at the screen top — UNDER the fixed top
   status bar (z 10001) — and top:4px hides the HUD behind it ("way up there",
   owner report 2026-06-19). Push it below the bar (+ notch inset) so it lands
   at the canvas's visible top-left. PORTRAIT is intentionally untouched: there
   the canvas is letterboxed and top:4px already pins it to the corner (the
   reason it was 4px and not 40px — see the media-query rule above). Must come
   after the rule above (same specificity) to win when landscape matches. */
@media screen and (orientation: landscape) {
  body.force-mobile #debug-statistics {
    top: calc(var(--mobile-header-height) + env(safe-area-inset-top, 0px) + 6px) !important;
  }
}

body.force-mobile #login-wrapper { min-width: unset !important; min-height: unset !important; width: 100vw !important; height: 100vh !important; height: 100dvh !important; overflow: hidden !important; }

/* --- Force Tablet: override phone-sized force-mobile with tablet sizing --- */
/* Applied alongside force-mobile for larger panels, no scaling, bigger touch targets */
body.force-tablet #screen { width: auto !important; height: auto !important; image-rendering: pixelated; image-rendering: -moz-crisp-edges; image-rendering: crisp-edges; }
body.force-tablet .canvas-wrapper { display: flex !important; justify-content: center !important; align-items: center !important; }
body.force-tablet #mobile-status-bar { height: 44px !important; padding: 4px 16px !important; gap: 16px !important; }
body.force-tablet .mobile-bar { height: 24px !important; }
body.force-tablet .mobile-bar-text { font-size: 13px !important; line-height: 24px !important; }
body.force-tablet #mobile-menu-btn { width: 36px !important; height: 36px !important; min-height: 36px !important; font-size: 18px !important; }
body.force-tablet .mobile-tab { padding: 0 12px !important; font-size: 15px !important; }
body.force-tablet .window { width: 250px !important; transform: none !important; top: 50px !important; font-size: 12px !important; }
body.force-tablet .equipment.wrapper { display: grid !important; grid-template-columns: auto auto auto auto; width: max-content !important; transform: none !important; top: 50px !important; align-items: start !important; }
body.force-tablet .equipment.wrapper > .mobile-panel-header { grid-column: 1 / -1; }
body.force-tablet #mobile-container-panel { width: 210px !important; transform: none !important; top: 50px !important; left: 5px !important; right: auto !important; }

/* Tablet depot panel — needs full styling because the @media block at
   line 273 won't match wide-landscape tablets (iPad Pro etc.) or desktop
   force-tablet. Slightly wider than mobile (210px to match container
   panels on tablet) but still a centered popup, not a docked panel. */
body.force-tablet #mobile-depot-panel,
body.force-tablet #mobile-float-panel {
    position: fixed !important;
    z-index: 9997 !important;
    width: 210px !important;
    background-image: url("/png/bg3.png") !important;
    flex-direction: column !important;
    overflow: hidden !important;
    pointer-events: auto !important;
    top: 50% !important;
    left: 50% !important;
    transform: translate(-50%, -50%) !important;
    max-height: 70vh !important;
    border: 1px solid #555 !important;
}

/* Second container panel — tablet only. Mobile/desktop never show it; on
   tablet it matches panel 1's styling so the backpack sits at left and
   extras stack to the right of it. The default left offset (225px) puts
   them flush, but the layout editor's "Container 2" handle lets the user
   drag / save a preferred position per orientation. */
#mobile-container-panel-2 {
    display: none;
}
body.force-tablet #mobile-container-panel-2 {
    position: fixed;
    z-index: 9996;
    width: 210px;
    background-image: url("/png/bg3.png");
    flex-direction: column;
    overflow: hidden;
    pointer-events: auto;
    /* Default stacks under panel 1 (same left column, below its max body
       height). Layout editor's "Container 2" handle lets users drag
       elsewhere and save per orientation. */
    top: 60vh !important;
    left: 5px !important;
    right: auto !important;
    transform: none !important;
    transform-origin: top left;
    border: 1px solid #333;
}
body.force-tablet .mobile-container-body { max-height: 50vh !important; overflow-y: auto !important; -webkit-overflow-scrolling: touch !important; }
/* Skills / friends windows open via the tab bar. Use a moderately narrower
   width than the generic 250px .window so they don't eat the screen, and
   mirror the mobile bar-wrapper layout so skill progress bars span the full
   row width as a background (visible fill %) instead of the desktop's
   narrow inline bar. */
/* BASELINE for the skill tab-panel at ANY viewport (outside the <=768px
   media query): tab panels only exist in mobile/tablet UI, so this styling
   must be CLASS-gated, not viewport-gated. Large tablets (e.g. 1280x800)
   run the mobile UI but match no media query — the skill panel rendered
   unstyled there: very wide window, unconstrained rows, labels colliding
   with values ("Shielding42", tablet report 2026-06-11). Width matches the
   force-tablet tier; the <=768px phone tier (160px + abbreviated labels)
   still overrides inside the query. */
body.force-mobile #skill-window.mobile-tab-panel {
    width: 220px;
}
body.force-mobile #skill-window.mobile-tab-panel .skill-wrapper,
body.force-tablet #skill-window.mobile-tab-panel .skill-wrapper {
    /* padding-right 8px: values sat FLUSH against the window's right border
       on forced-mode devices (owner fold screenshots 2026-08-26 - the
       media-query tier got this polish, the force tiers did not). The
       min-width/overflow belt mirrors the media tier's flex-basis-trap fix. */
    padding: 2px 8px 2px 4px !important;
    /* border-box or the padding WIDENS the 100%-width row instead of
       insetting the text - the values kept sitting exactly on the window
       edge and the fix was invisible (owner 2026-08-26, third report). */
    box-sizing: border-box !important;
    overflow: hidden !important;
}
body.force-mobile #skill-window.mobile-tab-panel .skill-wrapper > span,
body.force-mobile #skill-window.mobile-tab-panel .skill-wrapper > .skill,
body.force-tablet #skill-window.mobile-tab-panel .skill-wrapper > span,
body.force-tablet #skill-window.mobile-tab-panel .skill-wrapper > .skill {
    min-width: 0;
    overflow: hidden;
}

/* Battle body parity for the media-query-less tiers (owner fold,
   2026-08-26): scroll cap, thin scrollbar, and the padding-right that
   ends rows before the scrollbar track - all previously phone-media-only,
   so forced modes on large viewports never got them. The "more creatures"
   chevron follows, gated on .battle-active exactly like the media tier. */
body.force-mobile #friend-window.mobile-tab-panel .battle-body,
body.force-tablet #friend-window.mobile-tab-panel .battle-body {
    overflow-y: auto !important;
    max-height: calc(3 * 43px) !important;
    position: relative !important;
    scrollbar-width: thin !important;
    scrollbar-color: #888 #222 !important;
    padding-right: 8px !important;
    box-sizing: border-box !important;
}
body.force-mobile #friend-window.mobile-tab-panel.battle-active .battle-body:has(> :nth-child(4)),
body.force-tablet #friend-window.mobile-tab-panel.battle-active .battle-body:has(> :nth-child(4)) {
    box-shadow: inset 0 -10px 10px -6px rgba(0, 0, 0, 0.75) !important;
}
body.force-mobile #friend-window.mobile-tab-panel.battle-active:has(.battle-body > :nth-child(4))::after,
body.force-tablet #friend-window.mobile-tab-panel.battle-active:has(.battle-body > :nth-child(4))::after {
    content: "\25BE";
    position: absolute;
    bottom: 2px;
    right: 10px;
    color: rgba(255, 255, 255, 0.7);
    font-size: 11px;
    pointer-events: none;
    z-index: 1;
}

/* Position for the media-query-less tiers (2026-08-23, owner tablet
   report): the .mobile-tab-panel position block lives inside the phone
   media query, and a tablet matches NEITHER arm — the 2026-06-11 fix
   duplicated the WIDTH out here but not the POSITION, so tab panels on
   tablets fell to default window flow (and the hunt/stats tab swap moved
   the whole window). Same top-anchored fixed placement as the query. */
body.force-mobile .mobile-tab-panel,
body.force-tablet .mobile-tab-panel {
    display: block !important;
    position: fixed !important;
    top: calc(37px + var(--safe-area-top)) !important;
    right: calc(5px + var(--safe-area-right)) !important;
    left: auto !important;
    z-index: 9998 !important;
    pointer-events: auto !important;
}

body.force-tablet #skill-window.mobile-tab-panel { width: 220px !important; }
body.force-tablet #friend-window.mobile-tab-panel { width: 220px !important; }

body.force-tablet #skill-window.mobile-tab-panel .bar-wrapper {
    display: block !important;
    position: relative !important;
    border: 1px solid rgba(255, 255, 255, 0.5) !important;
    box-sizing: border-box !important;
}

body.force-tablet #skill-window.mobile-tab-panel .bar-wrapper > .skill-wrapper {
    position: relative;
    z-index: 1;
}

body.force-tablet #skill-window.mobile-tab-panel .bar-wrapper > .bar {
    position: absolute !important;
    left: 0 !important;
    right: 0 !important;
    top: 0 !important;
    bottom: 0 !important;
    width: 100% !important;
    height: auto !important;
    border-color: rgba(0, 0, 0, 0.4) !important;
    opacity: 0.7 !important;
    z-index: 0 !important;
}

body.force-tablet #skill-window.mobile-tab-panel .bar-wrapper > .bar > .value {
    height: 100% !important;
}

body.force-tablet .minimap-container.mobile-tab-panel { width: auto !important; padding: 4px !important; }
body.force-tablet .minimap-container.mobile-tab-panel .minimap-wrapper { width: 150px !important; height: 150px !important; }
body.force-tablet .minimap-container.mobile-tab-panel .minimap-wrapper canvas { width: 150px !important; height: 150px !important; }
body.force-tablet .minimap-container.mobile-tab-panel .button-stack { position: relative !important; right: auto !important; top: auto !important; width: 100% !important; flex-direction: row !important; justify-content: center !important; margin-top: 4px !important; }
body.force-tablet .minimap-container.mobile-tab-panel .button-stack .symbol-button { width: 26px !important; height: 26px !important; font-size: 13px !important; }
body.force-tablet .minimap-container.mobile-tab-panel .crosshair { left: 71px !important; top: 67px !important; }
/* Tab-bar panels use EQUIPMENT'S default placement on every touch tier
   (owner 2026-08-26: "statistics and battle/friend list windows seem to
   show up under the status bar per default. cant it use the same default
   placement as equipment?"). The generic .mobile-tab-panel top:37px rule
   lives inside the PHONE media query, so tablets and foldables never
   matched it and fell back to base positions under the status bar - and
   the old force-tablet #battle-window rule stopped mattering when the
   merge moved the battle list into #friend-window. Foldable inherits via
   force-tablet (the classes stack). safe-area keeps notched devices clear. */
/* PER-TIER equipment parity (owner 2026-08-26 follow-up: on regular mobile
   the panels sat LOWER than equipment): equipment's default is 37px on the
   phone tier and 50px on the tablet tier, so the panels match EACH tier
   rather than sharing one number. force-tablet wins for foldables because
   the classes stack and it reads later with equal specificity. */
body.force-mobile #skill-window.mobile-tab-panel,
body.force-mobile #friend-window.mobile-tab-panel,
body.force-mobile #battle-window.mobile-tab-panel {
  top: calc(37px + var(--safe-area-top)) !important;
}
body.force-tablet #skill-window.mobile-tab-panel,
body.force-tablet #friend-window.mobile-tab-panel,
body.force-tablet #battle-window.mobile-tab-panel {
  top: calc(50px + var(--safe-area-top)) !important;
}
body.force-tablet #battle-window { top: 50px !important; }
/* Tablet: People sub-tab uses the same geometry as friend-window (220px).
   top matches the equipment-style placement block above (owner 2026-08-26)
   - this later rule would otherwise win the cascade with the old 37px. */
body.force-tablet #battle-window.mobile-tab-panel {
    top: calc(50px + var(--safe-area-top)) !important;
    width: 220px !important;
}
body.force-tablet .mobile-panel-header { height: 26px !important; }
body.force-tablet .slot { width: 44px !important; height: 44px !important; background-size: 100% 100% !important; }
body.force-tablet .slot canvas { width: 44px !important; height: 44px !important; }
body.force-tablet .equipment.wrapper .slot { width: 40px !important; height: 40px !important; background-size: 100% 100% !important; }
body.force-tablet .equipment.wrapper .slot canvas { width: 40px !important; height: 40px !important; }
body.force-tablet .container-content .body { display: flex !important; flex-wrap: wrap !important; justify-content: center !important; padding: 2px !important; }
body.force-tablet .container-content .slot { width: 44px !important; height: 44px !important; margin: 2px !important; }
body.force-tablet .container-content .slot canvas { width: 44px !important; height: 44px !important; }
body.force-tablet .window .slot { width: 40px !important; height: 40px !important; margin: 2px !important; }
body.force-tablet .window .slot canvas { width: 40px !important; height: 40px !important; }
body.force-tablet .mobile-hotbar-slot { width: 56px; height: 56px; }
body.force-tablet #mobile-hotbar { gap: 8px; }
body.force-tablet .mobile-hotbar-slot canvas { width: 36px; height: 36px; }
body.force-tablet .mobile-action-btn { width: 60px !important; height: 60px !important; min-width: 60px !important; min-height: 60px !important; }
body.force-tablet #mobile-joystick-zone { width: 120px !important; height: 120px !important; }
body.force-tablet #mobile-chat-btn { width: 50px !important; height: 50px !important; font-size: 22px !important; right: 200px !important; }
body.force-tablet #mobile-pk-lock-btn { bottom: 68px !important; right: 200px !important; width: 50px !important; height: 50px !important; }
body.force-tablet .mobile-chat-badge { min-width: 18px !important; height: 18px !important; font-size: 10px !important; }
body.force-tablet .mobile-container-tab { padding: 3px 6px !important; font-size: 11px !important; height: 24px !important; border: none; border-right: 1px solid #555; background: transparent; color: #999; white-space: nowrap; display: flex; align-items: center; gap: 3px; cursor: pointer; }
body.force-tablet .mobile-container-tab.active { color: #ffd700; border-bottom: 2px solid #d4a017; }
body.force-tablet .mobile-container-tab-close { font-size: 14px; color: #888; cursor: pointer; padding: 0 2px; }
body.force-tablet #player-capacity { font-size: 12px !important; }
body.force-tablet .equipment-column { gap: 4px !important; }
body.force-tablet #login-wrapper .modal { max-width: 500px !important; }
body.force-tablet #login-wrapper #login-inner .login-settings button { min-width: 100px !important; height: 36px !important; font-size: 13px !important; }

/* --- Force Mobile: portrait aspect ratio fix --- */
@media screen and (orientation: portrait) {
    body.force-mobile #game-wrapper .main { background-color: #444 !important; background-image: url("/png/bg.png") !important; }
    body.force-mobile #screen { width: 100% !important; height: auto !important; aspect-ratio: 480 / 352; }
    body.force-mobile .canvas-wrapper { width: 100% !important; height: auto !important; }
    body.force-mobile #game-wrapper .main .upper { flex: 0 0 auto !important; }
    body.force-mobile #mobile-status-bar .mobile-bar-container { display: none !important; }
    body.force-mobile #portrait-bars { display: flex !important; flex-direction: row; gap: 8px; padding: 4px 8px; background: #111; border-top: 1px solid #333; flex: 0 0 auto; }
    body.force-mobile #mobile-action-bar { bottom: 20px !important; }
    body.force-mobile #login-wrapper #login-inner img.bg-landscape { display: none !important; }
    body.force-mobile #login-wrapper #login-inner img.bg-portrait { display: block !important; }
}

/* --- Force Mobile: landscape aspect ratio fix --- */
@media screen and (orientation: landscape) {
    body.force-mobile #screen { width: auto !important; height: 100% !important; aspect-ratio: 480 / 352; max-width: 100%; }
    body.force-mobile .canvas-wrapper { width: auto !important; height: 100% !important; display: flex !important; justify-content: center !important; align-items: center !important; }
}

/* --- Force Tablet: override force-mobile media queries for transform-based scaling ---
   Tablet uses CSS transform: scale(N) on a 480x352 canvas, centered in wrapper.
   Force-mobile rules set width/height/aspect-ratio for CSS-based stretching which
   conflicts with the transform approach. Override them back to auto. */
@media screen and (orientation: portrait) {
    body.force-tablet #screen { width: auto !important; height: auto !important; aspect-ratio: unset !important; }
    body.force-tablet .canvas-wrapper { width: 100% !important; height: 100% !important; }
    body.force-tablet #game-wrapper .main .upper { flex: 1 1 auto !important; }
}

@media screen and (orientation: landscape) {
    body.force-tablet #screen { width: auto !important; height: auto !important; aspect-ratio: unset !important; max-width: unset !important; }
    body.force-tablet .canvas-wrapper { width: 100% !important; height: 100% !important; }
}

/* ======================================
   Aspect Ratio: Stretch Mode Override
   When body.canvas-stretch is set, revert to full stretch (no aspect-ratio)
   ====================================== */
body.canvas-stretch #screen {
    aspect-ratio: unset !important;
    width: 100% !important;
    height: 100% !important;
    max-width: none !important;
}

body.canvas-stretch .canvas-wrapper {
    width: 100% !important;
    height: 100% !important;
}

body.canvas-stretch #game-wrapper .main .upper {
    flex: 1 1 auto !important;
}

body.canvas-stretch #game-wrapper .main {
    background-color: unset !important;
    background-image: unset !important;
}

/* --- Force Tablet Stretch: disable CSS transform, let width/height 100% handle sizing --- */
body.canvas-stretch.force-tablet #screen {
    transform: none !important;
}

/* ======================================
   Mobile Push Indicator (Creature Drag)
   Shown when long-press dragging a creature
   ====================================== */
.mobile-push-float {
    background: rgba(255, 170, 0, 0.25);
    border: 2px solid rgba(255, 170, 0, 0.7);
    border-radius: 4px;
}

/* ======================================
   Mobile Condition Bubble
   Floating popup showing active conditions
   when tapping the health bar
   ====================================== */
#condition-bubble {
    position: fixed;
    transform: translateX(-50%) translateY(-100%);
    margin-top: -6px;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 4px;
    padding: 5px 8px;
    background: rgba(15, 15, 15, 0.92);
    border: 1px solid #555;
    border-radius: 6px;
    z-index: 10002;
    pointer-events: none;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0.2s ease;
}

/* Landscape: show below the health bar */
#condition-bubble.below {
    transform: translateX(-50%);
    margin-top: 6px;
}

#condition-bubble.visible {
    opacity: 1;
    visibility: visible;
    /* Re-enable pointer events when shown so the icon tap-to-describe
       handler in status-bar.js actually fires. The base rule keeps
       pointer-events: none so the invisible bubble doesn't block
       canvas taps while dismissed. */
    pointer-events: auto;
}

#condition-bubble img {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

/* Arrow pointing down toward the health bar (portrait/above) */
#condition-bubble::after {
    content: "";
    position: absolute;
    bottom: -5px;
    left: 50%;
    transform: translateX(-50%);
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 5px solid rgba(15, 15, 15, 0.92);
    border-bottom: none;
}

/* Arrow pointing up toward the health bar (landscape/below) */
#condition-bubble.below::after {
    bottom: auto;
    top: -5px;
    border-top: none;
    border-bottom: 5px solid rgba(15, 15, 15, 0.92);
}

/* ==========================================================================
   Foldable late-cascade overrides
   These MUST sit at end-of-file. Earlier foldable rules inside
   body.force-foldable { ... } get out-cascaded by the flat
   body.force-tablet flat rules at lines 3243-3244 (which have
   !important on right/width/height) and the tablet canvas-wrapper rule
   at line 3122 (align-items: center !important). Since foldable users
   carry BOTH body.force-tablet AND body.force-foldable classes, those
   tablet rules apply and outrank the in-block foldable rules by being
   later in the cascade with !important.

   Putting these flat rules at the bottom of the file gives them the
   final say. !important matches tablet's, and the chained class
   specificity (body.force-foldable) is enough to win same-specificity
   tiebreaks via cascade order.
   ========================================================================== */

/* Bottom-right button column on foldable. All three buttons aligned
   at the same right offset (matches tablet's 200px so the column sits
   inset from the screen edge with room for swipe gestures). Original
   foldable attempt used 170px which felt crowded against the edge. */
body.force-foldable #mobile-chat-btn { right: 220px !important; }
body.force-foldable #mobile-pk-lock-btn { right: 220px !important; }

/* Preset btn grows to 50×50 (matching tablet-inherited PK/chat sizes)
   and re-stacks at bottom 124+safe to keep a 6px gap above the PK btn.
   Without these the preset stays 44×44 at base bottom 114, leaving a
   3px horizontal-center mismatch and a tight 4px vertical gap. */
body.force-foldable #mobile-hotbar-preset-btn {
    width: 50px !important;
    height: 50px !important;
    right: 220px !important;
    bottom: calc(124px + var(--safe-area-bottom)) !important;
}

/* Status-bar-bottom variant: re-derive the PK/preset bottoms for 50px
   buttons (existing html.status-bar-bottom rules use 44px base math
   which leaves chat-top touching PK-bottom with no gap). chat is
   unchanged because its base offset of 12+header+4 already works for
   both heights. */
html.status-bar-bottom:not(.iphone-notch) body.force-foldable #mobile-pk-lock-btn {
    bottom: calc(72px + var(--mobile-header-height)) !important;
}
html.status-bar-bottom:not(.iphone-notch) body.force-foldable #mobile-hotbar-preset-btn {
    bottom: calc(128px + var(--mobile-header-height)) !important;
}

/* Portrait orientation: anchor the canvas to the bottom of its
   wrapper so it sits flush with the bottom-anchored status bar
   instead of floating in the middle of the available vertical
   space. The flat body.force-tablet .canvas-wrapper rule at line
   3122 sets align-items: center !important — overrides the in-block
   foldable rule because tablet's rule is later. This flat rule is
   later still, so it wins.
   When the player has the status bar at the bottom (status-bar-bottom
   class or .iphone-notch), the bottom-anchored status bar sits at
   viewport bottom 0 with fixed positioning, so the wrapper extends
   behind it. Without padding-bottom the canvas at flex-end ends up
   half-overlapped by the status bar (~48px hidden). Padding-bottom
   matching the status bar height lifts the canvas up so its bottom
   edge sits flush AGAINST the status bar's top edge, no overlap. */
@media (orientation: portrait) {
    /* Only anchor canvas to flex-end + add status-bar padding when the
       status bar is actually at the bottom. If status-bar-bottom is
       off (status bar at top), keep the default center alignment so
       canvas doesn't slam against the screen's bottom edge. */
    html.status-bar-bottom:not(.iphone-notch) body.force-foldable .canvas-wrapper,
    html.iphone-notch body.force-foldable .canvas-wrapper {
        align-items: flex-end !important;
        /* Hardcoded 48px instead of var(--mobile-header-height)+4px:
           the tablet :root override (line 2424, intended 44px) is
           nested under body.force-tablet, which is invalid CSS Nesting
           since :root is an ancestor of body — variable stays at the
           base 36px, calc would give 40px, leaving an 8px overlap.
           Tablet/foldable status bar is hardcoded 44px height + 4px
           padding-bottom = 48px total via the line-2432 and line-1877
           rules. Mirror that hardcode here. */
        padding-bottom: 48px !important;
        box-sizing: border-box !important;
    }
}

/* iOS input-zoom belt (round 5): even with maximum-scale=1, some iOS
   versions still zoom on focusing a sub-16px field. 16px on natively
   editable fields removes the trigger entirely. Touch tiers only - the
   VirtualKeyboard's readonly fields never trigger it, but the experimental
   device-keyboard setting and the login screen use real editable inputs. */
@media screen and (max-height: 500px), screen and (max-width: 768px), screen and (max-height: 560px) and (pointer: coarse) {
    input[type="text"], input[type="password"], input[type="number"], input:not([type]), textarea {
        font-size: 16px !important;
    }
}
body.force-mobile input[type="text"], body.force-mobile input[type="password"], body.force-mobile input[type="number"], body.force-mobile input:not([type]), body.force-mobile textarea,
body.force-tablet input[type="text"], body.force-tablet input[type="password"], body.force-tablet input[type="number"], body.force-tablet input:not([type]), body.force-tablet textarea {
    font-size: 16px !important;
}

/* Secure mode button in portrait: the hotbar sits under the chat button there, so the button goes above the hotbar,
   where a tap meant for a hotbar slot cannot switch secure mode off. Last in the file so it beats the rules above. */
@media screen and (max-width: 768px) and (orientation: portrait) {
    #mobile-pk-lock-btn {
        bottom: calc(126px + var(--safe-area-bottom));
    }

    html.iphone-notch.status-bar-bottom #mobile-pk-lock-btn {
        bottom: calc(126px + var(--mobile-header-height) + 14px) !important;
    }

    html.status-bar-bottom:not(.iphone-notch) #mobile-pk-lock-btn {
        bottom: calc(126px + var(--mobile-header-height) + 4px) !important;
    }
}

/* Mobile container panel (src/ui/mobile-container-panel.js): the windows of the open containers sit in the panel body, one
   at a time under their tabs; the tab replaces the window's own header and footer. Desktop never shows the panel */
body.force-mobile #mobile-container-panel .window {
    position: static !important;
    transform: none !important;
    left: auto !important;
    top: auto !important;
    right: auto !important;
    width: auto !important;
    min-height: 0 !important;
    max-height: none !important;
    margin: 0 !important;
    border: none !important;
    flex-direction: column;
}

body.force-mobile #mobile-container-panel .window > .header,
body.force-mobile #mobile-container-panel .window > .footer {
    display: none !important;
}

body.force-mobile #mobile-container-panel.minimized .mobile-container-tabs,
body.force-mobile #mobile-container-panel.minimized .mobile-container-body {
    display: none !important;
}

/* Mobile tab bar (src/ui/mobile-tab-bar.js): the menu of the star */
#mobile-menu-modal .mobile-menu-entries {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 200px;
    padding: 10px;
}

#mobile-menu-modal .mobile-menu-entries > button {
    min-height: 40px;
    font-size: 14px;
}

/* The swapped side (src/ui/mobile-tab-bar.js): the body.force-mobile rules place the equipment and the panels on the
   right one class stronger than the .mobile-tab-left rules, so the left side needs the same weight */
body.force-mobile .equipment.wrapper.mobile-tab-left,
body.force-mobile .mobile-tab-panel.mobile-tab-left,
body.force-mobile #skill-window.mobile-tab-panel.mobile-tab-left,
body.force-mobile #friend-window.mobile-tab-panel.mobile-tab-left,
body.force-mobile .minimap-container.mobile-tab-panel.mobile-tab-left {
    left: 5px !important;
    right: auto !important;
    transform-origin: top left !important;
}

/* Mobile game screen (a phone: the tablet HUD scales the canvas with that transform, body.force-tablet): the
   force-mobile rules above already fit #screen to its area (aspect ratio kept), so the scale
   transform of Interface.handleResize must not apply on top of them (it overflowed the screen: 598x439 in a 393 high
   landscape, 480 wide in a 393 wide portrait), and the 480px minimum of the desktop wrapper (canvas.css) must not
   push the canvas out of a narrow portrait screen. Hit testing and the names follow the rendered rect. */
body.force-mobile:not(.force-tablet) #screen {
    transform: none !important;
}

body.force-mobile:not(.force-tablet) .canvas-wrapper {
    min-width: 0 !important;
}

/* Portrait: the wrapper hugs the canvas (no 352px minimum), so the names layer (#text-wrapper) covers exactly the game
   screen and the HP / mana bars sit right below it */
@media screen and (orientation: portrait) {
    body.force-mobile:not(.force-tablet) .canvas-wrapper {
        min-height: 0 !important;
    }
}

/* Mobile chat (src/ui/mobile-chat.js): the desktop chat (.lower, hidden on mobile above) opens as a panel docked to the
   bottom of the visible screen, right above the phone keyboard while it is up (--mobile-keyboard-inset), over the d-pad
   and the hotbar (10001) and under the windows */
body.force-mobile #game-wrapper .main .lower.mobile-chat-active {
    display: block !important;
    position: fixed !important;
    left: 0;
    right: 0;
    bottom: var(--mobile-keyboard-inset, 0px);
    height: var(--mobile-chat-height, 45vh) !important;
    max-height: none !important;
    z-index: 10002;
    border-top: 2px solid #555;
    box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.6);
}

body.force-mobile .lower.mobile-chat-active .wrapper-header {
    height: 34px;
}

/* Resizing the chat is a desktop thing */
body.force-mobile .lower.mobile-chat-active #chat-lock-resize {
    display: none !important;
}

#mobile-chat-close {
    font-size: 16px;
}

/* 16px keeps iOS from zooming the page when the input takes the focus */
body.force-mobile .lower.mobile-chat-active #chat-input {
    font-size: 16px;
    min-height: 34px;
}

body.force-mobile .lower.mobile-chat-active #send-chat-message {
    min-width: 60px;
}
