/* ==========================================================================
   rusty begin new code | 2026-09-07 18:57
   Action: Styles for the unified /games directory (faceted sidebar + sort bar +
           active-filter chips). Created for the merge of all-services/all,
           all-services-new, rate_cats, rate-services and rate_vip-services.

   HARD CONSTRAINT — this file must never style the 3D game card. It contains
   ZERO rules for .game-3d-case*, .game-rate-item, .case-*, .rating-*. That
   component is owned by macblash-3d-games.css and stays byte-for-byte intact.

   Design language is inherited from macblash-site-theme.css:
     surface  rgba(18, 18, 26, 0.75) + backdrop-filter blur(12px)
     accent   #8B5CF6 (purple)
     text     #e2e8f0
   RTL is the default direction, so all offsets use logical properties.

   Cache busting: currently loaded as ?v={{ time() }} from directory.blade.php
   (per-request, no caching) while the layout stabilises — revert to a pinned
   ?v=N once settled.

   Known Bootstrap conflict this file has to out-specify: the compiled bundle
   ships `.offcanvas-lg .offcanvas-body { padding:0; background-color:transparent
   !important }` (specificity 0,0,2,0) for the >=992px inline state. Any rule here
   that styles the sidebar panel box must match that specificity (or rely on an
   !important Bootstrap utility on the element itself).
   ========================================================================== */

.directory-layout {
    position: relative;
    align-items: flex-start;
}

/* ==========================================================================
   Sidebar
   ========================================================================== */

.directory-sidebar {
    margin-bottom: 30px;
    /* rusty begin update | 2026-09-08 10:12 */
    /* Action: the desktop sticky rule that lived here was removed. The browser/CDN cache
       on this file made it unreliable to iterate on, and the working version now lives
       as an inline <style> in resources/views/site/directory.blade.php @section('style')
       (renders fresh every request, no ?v= bump needed). That version also moved sticky
       onto .directory-sidebar-body and keeps this <aside> as a full-height track. */
    /* rusty end update */
    /* rusty begin update | 2026-09-08 11:15 */
    /* Action: confirms the paragraph above — a later edit briefly moved sticky BACK onto
       this <aside> (with align-self:flex-start) instead, which this comment was not
       updated to reflect. That's reverted; the inline block now matches this comment
       again: this element carries only align-self:stretch (an invisible full-height
       track), and .directory-sidebar-body is the sticky, visible card. */
    /* rusty end update */
}

.directory-sidebar-body {
    display: flex;
    flex-direction: column;
    /* rusty begin update | 2026-09-07 20:29 */
    /* Action: widen the vertical rhythm between facet groups (search / sections /
       categories / platforms / ratings) so they read as separate blocks. This is
       the flex-gap equivalent of a per-group mb-* utility, with no risk of a
       double margin stacking on top of the gap. */
    gap: 1.75rem;
    /* rusty end update */
    /* rusty begin update | 2026-09-07 21:07 */
    /* Action: issue #1 — titles/inputs read as glued to the RTL start edge. Widen
       the panel's horizontal gutter (was 22px) so every facet's content sits well
       inside the accent border. Applied on the body, not per-title, so titles,
       radios and dropdowns all shift in together and stay aligned. */
    padding: 26px 30px;
    /* rusty end update */
    background: rgba(18, 18, 26, 0.75);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(139, 92, 246, 0.15);
    border-radius: 20px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.4);
}

/* rusty begin update | 2026-09-07 21:44 */
/* Action: THE actual cause of the "glued to the edge" report (not the CDN cache).
   Compiled Bootstrap ships, at >=992px (sidebar inline):
       .offcanvas-lg .offcanvas-body { padding: 0; background-color: transparent !important; }
   That selector is specificity (0,0,2,0) and silently out-weighed the single-class
   .directory-sidebar-body rule above — so on desktop the panel rendered with zero
   padding and no glass background. Re-assert both at matching specificity. Padding
   is ALSO pinned by `px-4 py-4` on the element in directory.blade.php, since a
   Bootstrap spacing utility is !important and is the one thing guaranteed to win. */
@media (min-width: 992px) {
    .directory-sidebar .directory-sidebar-body {
        padding: 26px 30px;
        background: rgba(18, 18, 26, 0.75) !important;
    }
}
/* rusty end update */

/* Below lg the aside becomes a real offcanvas: drop the rounded card look so
   the panel fills the viewport edge to edge. */
@media (max-width: 991.98px) {
    .directory-sidebar {
        background: rgba(10, 10, 15, 0.98);
        backdrop-filter: blur(16px);
        -webkit-backdrop-filter: blur(16px);
        width: 320px;
        max-width: 88vw;
    }

    .directory-sidebar-body {
        border: 0;
        border-radius: 0;
        box-shadow: none;
        background: transparent;
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
        overflow-y: auto;
    }

    .directory-sidebar .offcanvas-header {
        border-bottom: 1px solid rgba(139, 92, 246, 0.2);
        padding: 18px 22px;
    }

    .directory-sidebar .offcanvas-title {
        color: #f1f5f9;
        font-weight: 700;
        margin: 0;
    }

    .directory-sidebar .btn-close {
        filter: invert(1) grayscale(1) brightness(2);
        opacity: 0.7;
    }
}

/* --- Facet groups --- */

.directory-facet {
    border: 0;
    padding: 0;
    margin: 0;
    min-width: 0; /* fieldset defaults to min-content; without this it refuses to shrink */
}

.directory-facet-title {
    /* rusty begin update | 2026-09-07 21:44 */
    /* Action: <legend> is a cursed box — Bootstrap Reboot gives it
       `float:left; width:100%`, so even with float undone a block legend still
       spans the full content width and visually touches both edges. Force it to
       shrink-wrap its text (max-content) so it clearly starts at the inline-start
       and ends after the label. max-width:100% keeps a long title from overflowing
       the narrow mobile offcanvas. */
    float: none !important;
    display: block;
    width: max-content !important;
    max-width: 100%;
    /* rusty end update */
    font-size: 13px;
    font-weight: 700;
    letter-spacing: 0.3px;
    color: #8B5CF6;
    text-transform: uppercase;
    /* rusty begin update | 2026-09-07 21:07 */
    /* Action: separation between the facet title and its control (also set via the
       `mb-3` utility on the element), plus a hair of inline padding so the label
       optically lines up with the field text inside the rounded controls below. */
    margin-bottom: 14px;
    padding: 0 2px;
    /* rusty end update */
}

/* --- Collection radios --- */

.directory-radio {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 12px;
    margin-bottom: 6px;
    border-radius: 12px;
    color: #cbd5e1;
    font-size: 14px;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background 0.25s ease, border-color 0.25s ease, color 0.25s ease;
}

.directory-radio:last-child {
    margin-bottom: 0;
}

.directory-radio:hover {
    background: rgba(139, 92, 246, 0.1);
    color: #f1f5f9;
}

.directory-radio input[type="radio"] {
    accent-color: #8B5CF6;
    width: 16px;
    height: 16px;
    margin: 0;
    flex: 0 0 auto;
    cursor: pointer;
}

.directory-radio:has(input[type="radio"]:checked) {
    background: rgba(139, 92, 246, 0.18);
    border-color: rgba(139, 92, 246, 0.45);
    color: #fff;
    font-weight: 600;
}

/* --- Search input + selects ---
   plugin.js initCustomDropdowns() hides each .chats-select and injects a
   .wrapper-dropdown sibling. The theme only styles that wrapper when it sits
   inside .search-secondary-filters, so the sidebar needs its own box styling.
   The dropdown LIST (.wrapper-dropdown .dropdown) is already styled globally. */

/* rusty begin update | 2026-09-07 20:29 */
/* Action: plugin.js initCustomDropdowns() only ADDS .custom-dropdown-hidden to the
   native <select>; the rule that actually hides it (macblash-site-theme.css:3225)
   is scoped to .chats-categories-search-wrap, which this page does not use. Without
   this, every facet renders the native select AND the generated .wrapper-dropdown
   side by side, which also makes the sidebar and top bar look cramped/broken.
   Fallback stays correct: before JS runs the native select is still shown. */
select.chats-select.custom-dropdown-hidden {
    display: none !important;
}
/* rusty end update */

/* rusty begin update | 2026-09-07 21:07 */
/* Action: The rule above depends on plugin.js having added .custom-dropdown-hidden.
   If that class is ever absent (init timing, a plugin.js error thrown by another
   widget before it reaches these selects, a stale cached plugin.js) the native
   <select> shows through the custom .wrapper-dropdown — which is issue #2, still
   reported after the conditional rule shipped. This unconditional, id-scoped rule
   removes the native control outright. plugin.js still builds and drives the
   .wrapper-dropdown (that is what the user actually clicks); the native element is
   only a form-value carrier and works fine while display:none. Scoped to
   #servicesSearchForm so no other page's .chats-select is touched. */
#servicesSearchForm select.chats-select {
    display: none !important;
    visibility: hidden !important;
}
/* rusty end update */

.directory-search-input,
.directory-facet .wrapper-dropdown {
    width: 100%;
    height: 45px;
    display: flex;
    align-items: center;
    padding: 0 18px;
    background: rgba(10, 10, 16, 0.7);
    border: 1px solid rgba(139, 92, 246, 0.15);
    border-radius: 14px;
    color: #e2e8f0;
    font-size: 14px;
    position: relative;
    z-index: 1;
    cursor: pointer;
    outline: none;
    user-select: none;
    box-sizing: border-box;
    transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.directory-search-input {
    cursor: text;
    /* rusty begin update | 2026-09-07 20:29 */
    /* Action: style.css:2453 .chats-categories-search-input forces width:90% and
       text-indent:15px on this element. Neutralise the indent, lock full width and
       set real horizontal box padding so the placeholder/value is not flush to the
       edge of the field. Kept horizontal-only so the 45px height still lines up
       with the select fields below it. */
    width: 100% !important;
    text-indent: 0;
    padding-inline: 1rem !important;
    /* rusty end update */
}

.directory-search-input::placeholder {
    color: #64748b;
}

.directory-search-input:hover,
.directory-search-input:focus,
.directory-facet .wrapper-dropdown:hover,
.directory-facet .wrapper-dropdown.active {
    background: rgba(24, 24, 36, 0.9);
    border-color: #8B5CF6;
    box-shadow: 0 0 14px rgba(139, 92, 246, 0.35);
}

/* The sidebar stacks vertically, so an open dropdown must float above the
   facets beneath it rather than pushing them down. */
.directory-facet {
    position: relative;
    z-index: 1;
}

.directory-facet:has(.wrapper-dropdown.active) {
    z-index: 20;
}

/* ==========================================================================
   rusty begin new code | 2026-09-07 23:41
   Action: Dark-glass theming for the Select2 multi-select facets (Sections /
   Categories / Platforms). Scoped to the .directory-select2-* classes passed via
   selectionCssClass / dropdownCssClass in macblash-directory.js, so no other
   Select2 instance on the site inherits any of this. The dropdown is appended to
   <body>, which is why it cannot be nested under .directory-sidebar here.
   Palette matches the rest of the panel: surface rgba(10,10,16,.7), accent #8B5CF6.
   ========================================================================== */

/* --- Closed control (the tag box) --- */

.directory-select2-selection.select2-selection--multiple {
    min-height: 45px;
    padding: 5px 8px;
    background: rgba(10, 10, 16, 0.7) !important;
    border: 1px solid rgba(139, 92, 246, 0.15) !important;
    border-radius: 14px !important;
    cursor: pointer;
    transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.select2-container--default:hover .directory-select2-selection.select2-selection--multiple,
.select2-container--default.select2-container--open .directory-select2-selection.select2-selection--multiple,
.select2-container--default.select2-container--focus .directory-select2-selection.select2-selection--multiple {
    background: rgba(24, 24, 36, 0.9) !important;
    border-color: #8B5CF6 !important;
    box-shadow: 0 0 14px rgba(139, 92, 246, 0.35);
}

/* --- Selected tags --- */

/* rusty begin update | 2026-09-08 00:52 */
/* Action: FIX — the X overlapped the Arabic label. Two causes, both in my own CSS:
     1. Select2 4.1 styles these at
          .select2-container--default .select2-selection--multiple .select2-selection__choice
        => specificity (0,0,3,0), and its RTL block is (0,0,4,0). My old selectors were
        (0,0,2,0), so every property NOT marked !important silently lost: display
        :inline-flex fell back to Select2's inline-block (which made gap / align-items /
        order inert), and my padding lost to Select2's `padding:0; padding-left:20px`.
     2. Select2 pins the remove control with `position:absolute; left:0; top:0` and
        reserves that 20px through the pill's padding-left. Its RTL block flips only the
        BORDERS — never left->right — so once my padding fought the gutter, the button
        landed on top of the text.
   Fix: match Select2's specificity, force real flex layout on the pill, and pull the
   remove button back into normal flow with position:static. `order` then handles
   placement correctly in both directions with no physical offsets. */

.select2-container--default .directory-select2-selection.select2-selection--multiple .select2-selection__choice,
.select2-container--default[dir="rtl"] .directory-select2-selection.select2-selection--multiple .select2-selection__choice {
    display: inline-flex !important;
    align-items: center !important;
    gap: 8px !important;
    float: none !important;            /* kill Select2's legacy float */
    position: relative !important;
    margin: 4px 4px 0 0 !important;
    padding: 4px 12px !important;      /* replaces the reserved padding-left:20px gutter */
    max-width: 100%;
    overflow: visible !important;      /* Select2 sets hidden; it clips the pill radius */
    background: rgba(139, 92, 246, 0.18) !important;
    border: 1px solid rgba(139, 92, 246, 0.45) !important;
    border-radius: 50rem !important;
    color: #e2e8f0 !important;
    font-size: 12.5px;
    line-height: 1.7;
    white-space: nowrap;
    vertical-align: middle !important;
}

/* The label span. Select2 gives it its own padding and flips it in RTL — zero it so the
   flex `gap` above is the single source of spacing between label and X. */
.select2-container--default .directory-select2-selection.select2-selection--multiple .select2-selection__choice__display,
.select2-container--default[dir="rtl"] .directory-select2-selection.select2-selection--multiple .select2-selection__choice__display {
    order: 1;
    padding: 0 !important;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}

/* The X. Select2 4.0 renders a <span>, 4.1 a <button> — both are covered. */
.select2-container--default .directory-select2-selection.select2-selection--multiple .select2-selection__choice__remove,
.select2-container--default[dir="rtl"] .directory-select2-selection.select2-selection--multiple .select2-selection__choice__remove {
    order: 2;                          /* inline END: left in RTL, right in LTR */
    position: static !important;       /* <- the actual overlap fix */
    inset: auto !important;            /* clears the left/top from the absolute rule */
    left: auto !important;             /* longhands too, for pre-`inset` browsers */
    right: auto !important;
    top: auto !important;
    transform: none !important;
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    width: auto !important;
    height: auto !important;
    margin: 0 !important;
    padding: 0 !important;
    border: none !important;
    border-radius: 0 !important;
    background: transparent !important;
    background-color: transparent !important;
    color: rgba(255, 255, 255, 0.6) !important;
    font-size: 16px !important;
    font-weight: normal !important;
    line-height: 1 !important;
    cursor: pointer;
    transition: color 0.2s ease;
}

.select2-container--default .directory-select2-selection.select2-selection--multiple .select2-selection__choice__remove:hover,
.select2-container--default .directory-select2-selection.select2-selection--multiple .select2-selection__choice__remove:focus,
.select2-container--default[dir="rtl"] .directory-select2-selection.select2-selection--multiple .select2-selection__choice__remove:hover {
    color: #dc3545 !important;         /* destructive action reads red on hover */
    background: transparent !important;
    background-color: transparent !important;
    outline: none !important;
}

/* 4.1 wraps the glyph in <span aria-hidden="true">x</span>; keep it metric-neutral and
   let clicks fall through to the button itself. */
.select2-container--default .directory-select2-selection.select2-selection--multiple .select2-selection__choice__remove span {
    line-height: 1;
    pointer-events: none;
}
/* rusty end update */

/* --- Placeholder + inline search --- */

.directory-select2-selection .select2-selection__placeholder {
    color: #64748b !important;
    line-height: 33px;
}

.directory-select2-selection .select2-search--inline .select2-search__field {
    margin-top: 6px;
    color: #e2e8f0 !important;
    background: transparent !important;
    font-family: inherit;
    font-size: 14px;
}

.directory-select2-selection .select2-search--inline .select2-search__field::placeholder {
    color: #64748b;
}

/* --- Dropdown panel --- */

.directory-select2-dropdown.select2-dropdown {
    background: rgba(14, 14, 22, 0.98) !important;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid rgba(139, 92, 246, 0.35) !important;
    border-radius: 14px !important;
    box-shadow: 0 12px 34px rgba(0, 0, 0, 0.55);
    overflow: hidden;
    z-index: 2000;
}

.directory-select2-dropdown .select2-results__options {
    max-height: 260px;
    padding: 6px;
}

.directory-select2-dropdown .select2-results__option {
    padding: 9px 14px;
    border-radius: 10px;
    color: #cbd5e1;
    font-size: 14px;
    background: transparent;
}

.directory-select2-dropdown .select2-results__option--highlighted[aria-selected],
.directory-select2-dropdown .select2-results__option--highlighted {
    background: rgba(139, 92, 246, 0.22) !important;
    color: #fff !important;
}

.directory-select2-dropdown .select2-results__option[aria-selected="true"],
.directory-select2-dropdown .select2-results__option[data-selected="true"] {
    background: rgba(139, 92, 246, 0.32) !important;
    color: #fff !important;
    font-weight: 600;
}

.directory-select2-dropdown .select2-results__option--disabled,
.directory-select2-dropdown .select2-results__message {
    color: #64748b;
}

/* Custom scrollbar to match the sidebar's dropdowns */
.directory-select2-dropdown .select2-results__options::-webkit-scrollbar {
    width: 6px;
}

.directory-select2-dropdown .select2-results__options::-webkit-scrollbar-thumb {
    background: rgba(139, 92, 246, 0.5);
    border-radius: 3px;
}

/* rusty begin update | 2026-09-08 00:14 */
/* Action: the reported beige box was the browser's default <select multiple> picking
   up the theme accent (--primary-color: #e4c59e in style.css) because this fallback
   was only single-class specific and lost the cascade. Forced dark now so it can
   never render beige again.

   Kept rather than deleted, deliberately: Select2 is the primary UI, but if it ever
   fails to mount again this is the only thing standing between the user and an
   unreadable native control — deleting it makes that failure mode worse, not better.
   Once Select2 does mount it adds .select2-hidden-accessible, whose clip styles in
   select2.min.css carry !important and neutralise this block on their own, so it
   deliberately does NOT force display:none (that would pull the original select out
   of the accessibility tree Select2 depends on). */
.directory-facet select.directory-multiselect,
.directory-sidebar .directory-facet select.directory-multiselect {
    width: 100% !important;
    min-height: 110px;
    padding: 8px !important;
    background: rgba(10, 10, 16, 0.7) !important;
    background-image: none !important;
    border: 1px solid rgba(139, 92, 246, 0.15) !important;
    border-radius: 14px !important;
    color: #e2e8f0 !important;
    font-size: 14px;
    -webkit-appearance: none;
    appearance: none;
}

.directory-facet select.directory-multiselect option {
    background: #0e0e16 !important;
    color: #e2e8f0 !important;
    padding: 6px 8px;
}

.directory-facet select.directory-multiselect option:checked {
    background: rgba(139, 92, 246, 0.35) !important;
    color: #fff !important;
}
/* rusty end update */
/* rusty end new code */

/* --- Reset button --- */

.directory-reset-btn {
    width: 100%;
    height: 45px;
    border: 1px solid rgba(139, 92, 246, 0.35);
    border-radius: 14px;
    background: transparent;
    color: #8B5CF6;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.3s ease, color 0.3s ease, box-shadow 0.3s ease;
}

.directory-reset-btn:hover {
    background: #8B5CF6;
    color: #fff;
    box-shadow: 0 0 18px rgba(139, 92, 246, 0.5);
}

/* ==========================================================================
   Main column — top bar
   ========================================================================== */

.directory-topbar {
    display: flex;
    align-items: center;
    /* rusty begin update | 2026-09-07 21:07 */
    /* Action: consistent 20px inset matching the sidebar panel so the count and
       sort control are not flush against the edges; sort stays pinned to the far
       side via .directory-sort-wrap margin-inline-start:auto. */
    gap: 1rem;
    padding: 20px;
    margin-bottom: 1.25rem;
    /* rusty end update */
    flex-wrap: wrap;
    background: rgba(18, 18, 26, 0.75);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1px solid rgba(139, 92, 246, 0.15);
    border-radius: 18px;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.4);
}

.directory-filters-toggle {
    height: 40px;
    padding: 0 16px;
    border: 1px solid rgba(139, 92, 246, 0.35);
    border-radius: 12px;
    background: transparent;
    color: #8B5CF6;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.3s ease, color 0.3s ease;
}

.directory-filters-toggle:hover {
    background: #8B5CF6;
    color: #fff;
}

.directory-count {
    color: #94a3b8;
    font-size: 14px;
    font-weight: 600;
    white-space: nowrap;
}

.directory-sort-wrap {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-inline-start: auto; /* pushes the sort control to the far edge in both directions */
    min-width: 0;
}

.directory-sort-label {
    color: #94a3b8;
    font-size: 13px;
    white-space: nowrap;
    margin: 0;
}

/* Same treatment as the sidebar selects; plugin.js skins this one too. */
.directory-sort-wrap .wrapper-dropdown {
    min-width: 190px;
    height: 40px;
    display: flex;
    align-items: center;
    padding: 0 18px;
    background: rgba(10, 10, 16, 0.7);
    border: 1px solid rgba(139, 92, 246, 0.15);
    border-radius: 12px;
    color: #e2e8f0;
    font-size: 14px;
    position: relative;
    z-index: 1;
    cursor: pointer;
    outline: none;
    user-select: none;
    transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.directory-sort-wrap .wrapper-dropdown:hover,
.directory-sort-wrap .wrapper-dropdown.active {
    background: rgba(24, 24, 36, 0.9);
    border-color: #8B5CF6;
    box-shadow: 0 0 14px rgba(139, 92, 246, 0.35);
}

.directory-topbar:has(.wrapper-dropdown.active) {
    z-index: 30;
    position: relative;
}

/* ==========================================================================
   Active-filter chips
   ========================================================================== */

.directory-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 18px;
}

.directory-chips:empty {
    display: none;
}

.directory-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 14px;
    background: rgba(139, 92, 246, 0.15);
    border: 1px solid rgba(139, 92, 246, 0.4);
    border-radius: 999px;
    color: #e2e8f0;
    font-size: 13px;
    line-height: 1.6;
}

.directory-chip-label {
    color: #a78bfa;
    font-weight: 600;
}

.directory-chip-remove {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.12);
    color: #e2e8f0;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease;
}

.directory-chip-remove:hover {
    background: #8B5CF6;
    color: #fff;
}

/* ==========================================================================
   Loading state for the AJAX grid swap
   ========================================================================== */

#servicesGridContainer {
    transition: opacity 0.2s ease;
}

#servicesGridContainer.is-loading {
    opacity: 0.5;
    pointer-events: none;
}

/* ==========================================================================
   Mobile (<=768px)
   Scoped strictly to directory chrome. No 3D-card rules here — the card's own
   mobile behaviour (the K.I.S.S. flat-plane rule) lives in macblash-3d-games.css
   and macblash-3d-games.js and must not be shadowed from this file.
   ========================================================================== */

@media (max-width: 768px) {
    .directory-topbar {
        gap: 10px;
        padding: 12px 14px;
    }

    .directory-sort-wrap {
        width: 100%;
        margin-inline-start: 0;
    }

    .directory-sort-wrap .wrapper-dropdown {
        flex: 1 1 auto;
        min-width: 0;
    }

    .directory-count {
        margin-inline-start: auto;
    }

    .directory-chips {
        margin-bottom: 14px;
    }
}
/* rusty end new code */
