/* =============================================================
   kb_aion — mobile responsiveness layer
   Loaded LAST in main.scala.html so its rules override existing
   desktop-first styles. Refines the dark teal / frosted-glass
   aesthetic for small screens; never replaces it.
   Breakpoints:
     900px — tablets & narrow desktops (nav collapses)
     480px — phones (tighter spacing, drop badges, etc.)
   ============================================================= */

/* ---------- Hidden on desktop ----------------------------- */
.nav-toggle,
.nav-backdrop,
.map-sidebar-toggle,
.navbar-brand {
    display: none;
}

/* =============================================================
   Tablet / large phone breakpoint
   ============================================================= */
@media (max-width: 900px) {

    /* ----- Body & containers --------------------------------- */
    html, body { overflow-x: hidden; }
    body { padding: 10px; }
    .contain, .container, .articles-container { max-width: 100%; }

    /* The free-standing big brand above the navbar reads as "wasted
       header" on phones. Hide it; an inline brand inside the navbar
       carries the identity instead. */
    .demo-section > .demo-title { display: none; }
    .demo-section { margin-bottom: 18px; }

    .navbar-brand {
        display: inline-flex;
        align-items: center;
        flex: 1 1 auto;
        min-width: 0;
        margin-right: 10px;
        padding: 0 2px;
        color: #fff;
        font-size: 13.5px;
        font-weight: 700;
        letter-spacing: 0.5px;
        text-transform: uppercase;
        text-decoration: none;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        text-shadow: 0 1px 2px rgba(0, 0, 0, 0.45);
    }
    /* faint gold underline on hover, matches the drawer accent */
    .navbar-brand:hover { color: #f4f7ad; }

    /* ----- NAVBAR -> compact bar + hamburger -----------------
       IMPORTANT: kill backdrop-filter + z-index here. Both create a
       new stacking context AND a new containing block on .navbar,
       which would otherwise trap .nav-menu (position:fixed) below the
       backdrop AND make the drawer expand body.scrollWidth past the
       viewport because translateX(100%) is measured against .navbar
       instead of the viewport. */
    .navbar {
        padding: 8px 14px;
        border-radius: 12px;
        gap: 8px;
        min-height: 56px;
        flex-wrap: nowrap;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        z-index: auto;
    }

    /* Hamburger button — custom three-line that morphs into "X".
       Sized for thumb taps; uses the same frosted-glass language. */
    .nav-toggle {
        --bar: #f4f7ad;                 /* same parchment-gold as map labels */
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        margin-left: auto;
        padding: 0;
        background: rgba(255, 255, 255, 0.08);
        border: 1px solid rgba(255, 255, 255, 0.22);
        border-radius: 12px;
        cursor: pointer;
        position: relative;
        transition: background 0.2s ease, border-color 0.2s ease, transform 0.2s ease;
        -webkit-tap-highlight-color: transparent;
        flex-shrink: 0;
    }
    .nav-toggle:hover,
    .nav-toggle:focus-visible {
        background: rgba(255, 255, 255, 0.15);
        border-color: rgba(244, 247, 173, 0.55);
        outline: none;
    }
    .nav-toggle:active { transform: scale(0.96); }

    .nav-toggle-bars,
    .nav-toggle-bars::before,
    .nav-toggle-bars::after {
        content: '';
        display: block;
        width: 22px;
        height: 2px;
        background: var(--bar);
        border-radius: 2px;
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1),
                    opacity 0.2s ease,
                    top 0.18s ease;
        box-shadow: 0 0 6px rgba(244, 247, 173, 0.35);
    }
    .nav-toggle-bars       { top: calc(50% - 1px); }
    .nav-toggle-bars::before { top: -7px; }
    .nav-toggle-bars::after  { top:  7px; }

    /* When drawer is open, hoist the toggle above the drawer so the
       morphed "X" stays tappable in the same spot. */
    body.nav-open .nav-toggle {
        position: fixed;
        top: 16px;
        right: 16px;
        z-index: 2100;
        background: rgba(255, 255, 255, 0.12);
        border-color: rgba(244, 247, 173, 0.45);
    }

    .nav-toggle[aria-expanded="true"] .nav-toggle-bars {
        background: transparent;
        box-shadow: none;
    }
    .nav-toggle[aria-expanded="true"] .nav-toggle-bars::before {
        top: 0;
        transform: translateX(-50%) rotate(45deg);
    }
    .nav-toggle[aria-expanded="true"] .nav-toggle-bars::after {
        top: 0;
        transform: translateX(-50%) rotate(-45deg);
    }

    /* ----- Drawer container ----------------------------------
       `visibility` flip is essential: with the drawer simply
       translated off-screen, its box-shadow (-18px / 40px blur)
       and backdrop-filter still bleed back into the viewport as a
       dark gradient haze along the right edge. Visibility:hidden
       removes those rendering effects when closed. The 0.32s delay
       on close keeps the slide-out transition visible; on open the
       delay is 0 so visibility flips immediately. */
    .nav-menu,
    .navbar .language-selector {
        position: fixed;
        top: 0;
        right: 0;
        z-index: 2000;
        transform: translateX(100%);
        visibility: hidden;
        transition:
            transform 0.32s cubic-bezier(0.4, 0, 0.2, 1),
            visibility 0s linear 0.32s;
    }

    .nav-menu {
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        height: 100dvh;
        width: min(86vw, 360px);
        /* bottom padding clears the language-selector strip (~70px + safe-area) */
        padding: 80px 16px calc(90px + env(safe-area-inset-bottom)) 16px;
        overflow-y: auto;
        overscroll-behavior: contain;
        background: linear-gradient(180deg,
                    rgba(20, 50, 90, 0.97) 0%,
                    rgba(8, 26, 48, 0.97) 100%);
        backdrop-filter: blur(16px);
        -webkit-backdrop-filter: blur(16px);
        border-left: 1px solid rgba(244, 247, 173, 0.18);
        box-shadow: -18px 0 40px rgba(0, 0, 0, 0.5);
    }
    /* faint gold rail down the drawer's left edge — Aion-y accent */
    .nav-menu::before {
        content: '';
        position: absolute;
        top: 0; bottom: 0; left: 0;
        width: 1px;
        background: linear-gradient(180deg,
                    transparent 0%,
                    rgba(244, 247, 173, 0.55) 18%,
                    rgba(244, 247, 173, 0.15) 80%,
                    transparent 100%);
        pointer-events: none;
    }

    .navbar .language-selector {
        top: auto;
        bottom: 0;
        right: 0;
        width: min(86vw, 360px);
        padding: 18px 20px calc(18px + env(safe-area-inset-bottom));
        background: rgba(8, 26, 48, 0.96);
        backdrop-filter: blur(16px);
        border-top: 1px solid rgba(255, 255, 255, 0.08);
        border-left: 1px solid rgba(244, 247, 173, 0.18);
        justify-content: center;
        gap: 14px;
        margin-top: 0;
    }
    .navbar .language-selector .lang-link {
        font-size: 13px;
        padding: 10px 18px;
        letter-spacing: 0.4px;
    }

    body.nav-open .nav-menu,
    body.nav-open .navbar .language-selector {
        transform: translateX(0);
        visibility: visible;
        transition:
            transform 0.32s cubic-bezier(0.4, 0, 0.2, 1),
            visibility 0s linear 0s;
    }
    body.nav-open { overflow: hidden; }

    /* Backdrop */
    .nav-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(2, 12, 26, 0.55);
        backdrop-filter: blur(2px);
        z-index: 1900;
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.28s ease;
    }
    body.nav-open .nav-backdrop {
        opacity: 1;
        pointer-events: auto;
    }

    /* ----- Drawer items: accordion -------------------------- */
    .nav-item {
        width: 100%;
        margin: 0;
        border-bottom: 1px solid rgba(255, 255, 255, 0.06);
    }
    .nav-item:last-child { border-bottom: none; }

    .nav-item .nav-link {
        justify-content: space-between;
        width: 100%;
        padding: 14px 12px;
        border-radius: 8px;
        font-size: 15px;
        position: relative;
    }
    .nav-item.has-dropdown .nav-link { padding-right: 12px; }

    /* Rotate caret when open */
    .nav-item .dropdown-icon { transition: transform 0.25s ease; }
    .nav-item.is-open .dropdown-icon { transform: rotate(180deg); }
    /* Disable the desktop hover-rotate at this width */
    .nav-item:hover .dropdown-icon { transform: none; }
    .nav-item.is-open:hover .dropdown-icon { transform: rotate(180deg); }

    /* Dropdown panel within drawer — collapsible accordion.
       Override the desktop absolute positioning + hover behavior. */
    .nav-item .dropdown {
        position: static;
        opacity: 1;
        visibility: visible;
        transform: none;
        margin: 0;
        max-height: 0;
        overflow: hidden;
        transition: max-height 0.3s ease;
        background: rgba(0, 0, 0, 0.22);
        backdrop-filter: none;
        border: none;
        border-radius: 0;
        box-shadow: none;
        min-width: 0;
        width: 100%;
        display: block;
    }
    /* The desktop `:hover .dropdown { display:block }` rule still applies
       at the 768px-and-below breakpoint inside main.css. Neutralize it. */
    .nav-item:hover .dropdown { display: block; }
    .nav-item.is-open .dropdown {
        max-height: 2000px;
        transition: max-height 0.6s ease;
    }

    .dropdown-item {
        border-bottom: 1px solid rgba(255, 255, 255, 0.04);
        background: transparent;
    }
    .dropdown-item:last-child { border-bottom: none; }
    .dropdown-link,
    .submenu-link {
        color: #e6f0ff !important;
        padding: 12px 18px;
        font-size: 14px;
        border-radius: 0;
    }
    .dropdown-link:hover,
    .submenu-link:hover {
        background: rgba(244, 247, 173, 0.08) !important;
        color: #fff !important;
    }
    .dropdown-item:first-child .dropdown-link,
    .dropdown-item:last-child  .dropdown-link,
    .submenu-item:first-child  .submenu-link,
    .submenu-item:last-child   .submenu-link {
        border-radius: 0;
    }

    /* Nested submenus — second-level accordion */
    .dropdown-item.has-submenu > .dropdown-link {
        position: relative;
    }
    /* Inline chevron for has-submenu rows is already in markup as
       <span class="submenu-icon">. Just rotate it on open. */
    .dropdown-item .submenu-icon { transition: transform 0.25s ease; }
    .dropdown-item.is-open .submenu-icon { transform: rotate(90deg); }
    .dropdown-item:hover .submenu-icon { transform: none; }
    .dropdown-item.is-open:hover .submenu-icon { transform: rotate(90deg); }

    .dropdown-item .submenu {
        position: static;
        opacity: 1;
        visibility: visible;
        transform: none;
        margin: 0;
        max-height: 0;
        overflow: hidden;
        transition: max-height 0.3s ease;
        background: rgba(0, 0, 0, 0.28);
        backdrop-filter: none;
        border: none;
        border-radius: 0;
        box-shadow: none;
        min-width: 0;
        width: 100%;
        top: auto !important;   /* override inline `style="top:..."` on submenus */
        left: 0;
    }
    .dropdown-item.is-open .submenu {
        max-height: 1600px;
        transition: max-height 0.55s ease;
    }
    .submenu-link { padding-left: 36px; }

    /* ----- Search bar (compact) -----------------------------
       Slim glass pill, navy-tinted to match the page background
       (the desktop purple gradient feels generic and clashes here).
       Left icon = subtle stroke SVG, right button = solid teal disc
       sized as a perfect circle (force width=height=min-width). */
    .search-container-compact {
        margin-top: 12px;
        padding: 4px;
        border-radius: 999px;
        background: rgba(255, 255, 255, 0.92);
        border-color: rgba(120, 180, 255, 0.18);
    }
    .search-container-compact .search-input {
        font-size: 16px;         /* avoid iOS zoom */
        padding: 9px 6px 9px 40px;
        color: #122846;
    }
    .search-container-compact .search-icon {
        left: 14px;
        top: 50%;
        transform: translateY(-50%);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        color: #5d7c9e;
    }
    .search-container-compact.focused .search-icon { color: #1b6fb8; }

    /* Force perfect circle — defeat search.css's min-width:50px @768px */
    .search-container-compact .search-button {
        min-width: 36px;
        width: 36px;
        height: 36px;
        padding: 0;
        flex: 0 0 36px;
        border-radius: 50%;
        background: linear-gradient(135deg, #1f6fbf 0%, #154d8a 100%);
        box-shadow:
            0 2px 8px rgba(20, 60, 110, 0.45),
            inset 0 1px 0 rgba(255, 255, 255, 0.15);
    }
    .search-container-compact .search-button:hover {
        background: linear-gradient(135deg, #2a82d6 0%, #1c5fa5 100%);
    }
    .search-container-compact .search-button:active {
        transform: scale(0.94);
    }
    .search-container-compact .search-button-icon {
        font-size: 0;            /* kill any stray emoji fallback height */
        display: inline-flex;
        align-items: center;
        justify-content: center;
        color: #fff;
    }
    /* "Search" text is hidden on mobile via existing search.css; the
       SVG is the affordance now. */
    .search-context-label { display: none; }

    /* ----- Item detail page (item.scala.html) --------------- */
    .item-main {
        width: 100%;
        padding: 16px;
        flex-direction: column;
        gap: 18px;
    }
    .item-main .item-base { width: 100%; }
    .item-main .item-info ul { width: 100%; }
    .item-main #info-3d { min-height: 360px; }

    /* The share-block input must shrink, not push width */
    .item-main .item-info .share-block input {
        width: 100%;
        min-width: 0;
    }

    /* itembase tables: allow attr rows to wrap rather than overflow */
    .item-main .attributes-info.table .attr-name,
    .item-main .attributes-info.table .attr-value {
        word-break: break-word;
    }

    /* ----- NPC detail page (npc.scala.html) ----------------- */
    .data-container.npc-card { max-width: 100%; }
    .npc-bar { width: 100%; justify-content: center; }
    .npc-stats-grid { grid-template-columns: repeat(2, 1fr); }
    .npc-stat { padding: 10px 14px; }
    .npc-locations { grid-template-columns: 1fr; gap: 14px; }
    .npc-location-map { aspect-ratio: 4 / 3; }
    .npc-locations-section { padding: 0 4px; margin: 22px auto; }

    /* HP bar is a fixed-width sprite (up to 401px). Shrink the
       wrapper and scale via transform-origin so it doesn't push
       horizontal scroll. */
    .column.right .hp-bar {
        transform: scale(0.7);
        transform-origin: left center;
        height: auto;
        min-height: 60px;
    }

    /* ----- Item list rows -----------------------------------
       One-line row: icon | name | level chip. The desktop CSS already
       lays it out as flex, but its `.item-name { flex: 1 }` + fixed
       `.item-badges` widths overflow the 390px viewport. Override so
       the name flex-grows from a 0 basis and the badges stay compact
       at the right edge. */
    .item {
        flex-wrap: nowrap;
        padding: 8px 12px;
        gap: 0 8px;
        min-height: 0;
        align-items: center;
    }
    .item .item-icon { margin-right: 0; }
    .item .item-name {
        flex: 1 1 0;
        min-width: 0;
        margin-right: 0;
        font-size: 0.95rem;
        line-height: 1.25;
        word-break: break-word;
    }
    .item .item-badges {
        flex: 0 0 auto;
        min-width: 0;
        margin: 0 0 0 auto;
        gap: 6px;
        font-size: 0.7rem;
    }
    .item .item-badges .item-quantity {
        margin: 0;
        white-space: nowrap;
    }
    .item .item-status {
        margin-right: 0;
        margin-left: 6px;
        min-width: auto;
        align-self: center;
    }
    /* sort header row — restore the "Level" header (itemlist.css's
       480px rule hides .item-badges; that's intended for data rows,
       not the sort header). */
    .item-sort .item-name.sorting { margin-left: 14px; }
    .item-sort .item-badges.sorting {
        display: flex;
        align-items: center;
        gap: 6px;
        min-width: 0;
        margin-left: auto;
        font-size: 13px;
    }

    /* ----- Filter blocks (range / checkbox) ----------------- */
    .inline {
        gap: 12px;
        margin: 16px auto;
        padding: 0 4px;
    }
    .range-container,
    .checkbox-container {
        max-width: 100%;
        width: 100%;
        padding: 14px;
    }
    .checkbox-wrapper { gap: 6px; }
    .checkbox-display { padding: 6px 10px; font-size: 11px; }

    /* ----- News grid / cards --------------------------------
       Stretched-link pattern: the existing .read-more anchor's
       ::after pseudo expands to the whole card so the entire
       banner becomes one tap target. Only one real <a> exists,
       so screen readers still see a single link. */
    .news-grid { gap: 14px; }
    .news-banner { cursor: pointer; }
    .news-banner .read-more::after {
        content: '';
        position: absolute;
        inset: 0;
        z-index: 2;
    }
    /* Ensure the read-more's own pill stays visually on top of
       its overlay so it still reads as the affordance */
    .news-banner .read-more { position: relative; z-index: 1; }
    .post-content { padding: 1.4rem; border-radius: 14px; }
    /* Wide tables / images inside post content shouldn't push scroll */
    .post-content table {
        display: block;
        overflow-x: auto;
        max-width: 100%;
        -webkit-overflow-scrolling: touch;
    }
    .post-content img { max-width: 100%; height: auto; }
    .post-content img.fr-fic.fr-dib { width: 100% !important; height: auto !important; }

    /* ----- Articles ----------------------------------------- */
    .article-content { flex-wrap: wrap; gap: 8px; }
    .article-title { font-size: 1rem; }

    /* ----- Page H1 — tighter type, subtle gold underline ----- */
    h1 {
        font-size: 1.45rem;
        font-weight: 700;
        line-height: 1.15;
        letter-spacing: -0.005em;
        margin: 18px 0 14px 0;
        padding-bottom: 8px;
        position: relative;
    }
    h1::after {
        content: '';
        position: absolute;
        left: 0;
        bottom: 0;
        width: 32px;
        height: 2px;
        background: linear-gradient(90deg, rgba(244, 247, 173, 0.85), rgba(244, 247, 173, 0));
        border-radius: 2px;
    }

    /* ----- Category filter — single-row scroll strip --------
       Long RU labels would wrap to 5+ rows otherwise. A horizontal
       scroll strip is the familiar mobile pattern (Instagram tabs,
       news app filters) and keeps the strip a single line tall.
       The container bleeds into the body's side padding so the
       scrollable area visually extends to the screen edges. */
    .category-filter {
        padding: 8px 0;
        border-radius: 10px;
        margin-bottom: 14px;
        overflow: hidden;
    }
    .category-filter > div {
        display: flex;
        flex-wrap: nowrap;
        align-items: center;
        gap: 6px;
        padding: 4px 24px 4px 16px;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scroll-snap-type: x proximity;
        scroll-padding-left: 16px;       /* keeps first pill offset when snapped */
        scrollbar-width: none;          /* Firefox */
    }
    .category-filter > div::-webkit-scrollbar { display: none; }
    /* The leading "Category:" label adds clutter on phones — drop it */
    .category-filter > div > span { display: none; }
    .category-button {
        flex-shrink: 0;
        scroll-snap-align: start;
        white-space: nowrap;
        padding: 5px 11px;
        font-size: 0.72rem;
        font-weight: 600;
        border-radius: 999px;
        border-width: 1px;
        box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
    }
    .category-button.active {
        box-shadow: 0 2px 10px rgba(74, 111, 165, 0.45);
    }

    /* ----- Bonus floating block — hide on mobile ------------
       It was covering content (position:fixed bottom). On a small
       viewport there's no spare real estate for a persistent ad. */
    .holder { display: none; }

    /* ----- MAP world picker grid ---------------------------- */
    .map-world-grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 10px;
    }
    .map-world-card img { height: 110px; }
    .map-world-name { padding: 8px 10px; font-size: 0.9rem; }
    .map-index { padding: 16px 8px; }

    /* ----- MAP detail page: bottom-sheet sidebar -------------
       The sidebar becomes a sheet anchored at the bottom of the
       viewport. Collapsed: only the header strip is visible — the
       FILTERS toggle is always within thumb reach. Expanded: the
       sheet slides up over the map. */
    .map-page {
        flex-direction: column;
        position: relative;
        height: auto;
        min-height: 0;
        border-radius: 8px;
        /* Leave room at the bottom for the collapsed sheet's header
           strip so the leaflet attribution + zoom controls aren't
           permanently obscured. */
        padding-bottom: 96px;
    }
    .map-canvas {
        order: 1;
        width: 100%;
        height: calc(100dvh - 200px);
        min-height: 360px;
    }
    /* Note: map.css is loaded from map_view.scala.html in <body>, so
       it comes AFTER mobile.css in the head and would win same-specificity
       ties (e.g. its `width: 300px` rule). All sheet rules below use
       `.map-page .map-sidebar` to outrank it. */
    .map-page .map-sidebar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 1500;
        width: 100%;
        max-height: 78dvh;
        padding: 12px 14px 18px;
        border: none;
        border-top: 1px solid rgba(244, 247, 173, 0.18);
        border-radius: 16px 16px 0 0;
        background: linear-gradient(180deg, rgba(13, 38, 70, 0.98) 0%, rgba(8, 26, 48, 0.98) 100%);
        backdrop-filter: blur(14px);
        -webkit-backdrop-filter: blur(14px);
        box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.45);
        transform: translateY(0);
        transition: transform 0.32s cubic-bezier(0.4, 0, 0.2, 1);
        overflow-y: auto;
        overscroll-behavior: contain;
    }
    /* Grabber affordance — purely visual hint that this strip slides. */
    .map-page .map-sidebar::before {
        content: '';
        position: sticky;
        top: 0;
        display: block;
        width: 36px;
        height: 4px;
        margin: 0 auto 8px;
        border-radius: 2px;
        background: rgba(244, 247, 173, 0.55);
    }
    /* When collapsed, slide the sheet down so only the header strip
       (back-link + title + FILTERS button) peeks above the viewport
       edge. ~96px matches .map-page's padding-bottom reservation. */
    .map-page .map-sidebar.is-collapsed {
        transform: translateY(calc(100% - 96px));
        max-height: 96px;
        overflow: hidden;
    }
    /* Compact header row so the collapsed strip stays short:
       [back link]
       [title]                              [FILTERS] */
    .map-sidebar-header {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 4px 12px;
        margin-bottom: 8px;
        padding-bottom: 8px;
    }
    .map-back-link { flex: 1 1 100%; }
    .map-world-title { flex: 1 1 auto; margin: 0; }
    .map-sidebar-toggle { margin: 0 0 0 auto; }

    .map-sidebar-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 6px;
        margin-top: 6px;
        padding: 7px 12px;
        font-size: 0.78rem;
        font-weight: 600;
        color: #cfe2ff;
        background: rgba(74, 158, 255, 0.12);
        border: 1px solid rgba(120, 180, 255, 0.3);
        border-radius: 6px;
        cursor: pointer;
        letter-spacing: 0.3px;
        text-transform: uppercase;
    }
    .map-sidebar-toggle:hover {
        background: rgba(74, 158, 255, 0.22);
        color: #fff;
    }
    .map-sidebar-toggle::before {
        content: '▾';
        font-size: 0.7rem;
        transition: transform 0.2s ease;
    }
    .map-sidebar.is-collapsed .map-sidebar-toggle::before {
        transform: rotate(-90deg);
    }

    /* SVG drill-down picker — already responsive, just tighten padding */
    .map-select-page { padding: 18px 8px 24px; }
    .map-select-label { font-size: 16px; stroke-width: 3px; }
}

/* =============================================================
   Phone breakpoint — tighter still
   ============================================================= */
@media (max-width: 480px) {
    body { padding: 6px; }
    .demo-title { font-size: 14px; }

    h1 { font-size: 1.4rem; }
    .header-title { font-size: 18px; }

    .item .item-badges .badge-trading,
    .item .item-badges .badge-shopkeeper { font-size: 0.65rem; padding: 1px 5px; }

    /* one column for npc stats below 380px feels right; keep 2-up to 480 */
    .npc-stats-grid { grid-template-columns: repeat(2, 1fr); }
    .npc-stat-value { font-size: 0.9rem; }

    .post-content { padding: 1rem; }

    .map-world-grid { grid-template-columns: repeat(2, 1fr); }
    .map-world-card img { height: 90px; }

    .map-canvas { height: calc(100dvh - 220px); min-height: 300px; }

    .npc-bar { transform: scale(0.85); transform-origin: center; }

    /* itemlist.css's 480px rule hides .item-badges entirely. Override
       that so the level chip stays visible; only suppress the verbose
       trading/shopkeeper sub-badges. */
    .item .item-badges { display: flex; }
    .item .badge-trading,
    .item .badge-shopkeeper { display: none; }
    /* the explicit ".item-status" hide from itemlist.css is fine */
}

/* =============================================================
   Touch-pointer safety: even on wider screens, if the primary
   pointer is coarse, neutralize hover-only nav reveal so taps
   don't get a sticky open state.
   ============================================================= */
@media (hover: none) and (pointer: coarse) and (min-width: 901px) {
    .nav-item:hover .dropdown,
    .dropdown-item:hover .submenu {
        opacity: 0;
        visibility: hidden;
    }
    .nav-item.is-open > .dropdown,
    .dropdown-item.is-open > .submenu {
        opacity: 1;
        visibility: visible;
        transform: none;
    }
}
