/* ==================================================================================
 * 41-v160-mobile.css — v160 MOBILE / TOUCH LAYER
 * ----------------------------------------------------------------------------------
 * Loads LAST (38 foundation -> 39 public -> 40 console -> 41 mobile).
 * Owns every <=640px behaviour for navigation chrome, sheets, sticky CTAs and the
 * console-on-phone experience, plus a tablet reflow pass at <=1024px.
 *
 * Supersedes assets/css/20-mobile.css (legacy 768px "app-ish" layer). Because 20 is
 * still loaded, a small number of rules here must carry `!important` purely to defeat
 * a legacy `!important`. Every such rule names the file it is fighting on the same
 * line. No other `!important` is permitted in this layer.
 *
 * DESIGN CONTRACT (38-v160-foundation.css) — consumed, never redefined:
 *   - tokens: --v160-*  (surfaces / borders / text / accent / elevation / radius /
 *             spacing / typography / control sizing / motion)
 *   - primitives: .v160-btn .v160-input .v160-card .v160-table .v160-chip .v160-badge
 *             .v160-tabs .v160-pagination .v160-empty .v160-kpi .v160-toolbar …
 * This layer only ADDS `.v160-mob-*` classes and re-skins existing `.gab-*` hooks that
 * live in view templates it does not own.
 *
 * BREAKPOINTS (literal values only, per contract)
 *   @media (max-width: 1024px)  tablet and below
 *   @media (max-width:  640px)  phone
 *   @media (min-width: 1025px)  desktop reset
 *
 * SECTION INDEX
 *   1.  Mobile metrics (layer-local custom properties)
 *   2.  Global mobile policy
 *   3.  App header (collapse to logo + search + hamburger)
 *   4.  Full-screen search overlay
 *   5.  Navigation drawer
 *   6.  Bottom tab bar
 *   7.  Bottom-sheet framework
 *   8.  Filter sheet (the primary listing interaction)
 *   9.  Sort sheet
 *   10. Listing: sticky sub-bar + single-column cards
 *   11. Car detail: gallery, accordion, sticky action bar
 *   12. Modals as sheets
 *   13. Console on mobile (off-canvas nav, KPI, STACKED TABLES, bulk dock)
 *   14. Forms on touch
 *   15. Tablet pass (641–1024px)
 *   16. Landscape + short-viewport guards
 *   17. Reduced motion
 *   18. RTL corrections
 *   19. Desktop reset
 * ================================================================================== */


/* ==================================================================================
 * 1. MOBILE METRICS
 * ----------------------------------------------------------------------------------
 * New, layer-local custom properties only (prefix --v160-mob-*). Nothing from PART A
 * or PART B of the design contract is redeclared here. These exist because bar heights
 * and safe-area insets are referenced by dozens of rules below and by view authors who
 * need to reserve space for fixed chrome.
 *
 * View authors: to keep content clear of the bottom chrome use
 *   padding-block-end: calc(var(--v160-mob-tabbar-total) + var(--v160-space-4));
 * ================================================================================== */

:root {
    /* Device safe areas — 0px on everything that is not a notched iOS device. */
    --v160-mob-safe-t: env(safe-area-inset-top, 0px);
    --v160-mob-safe-b: env(safe-area-inset-bottom, 0px);
    --v160-mob-safe-l: env(safe-area-inset-left, 0px);
    --v160-mob-safe-r: env(safe-area-inset-right, 0px);

    /* Fixed chrome heights (content box, safe area added separately). */
    --v160-mob-header-h: 56px;
    --v160-mob-subbar-h: 52px;   /* sticky filter + sort bar under the header */
    --v160-mob-tabbar-h: 56px;
    --v160-mob-action-h: 60px;   /* car-detail sticky action bar             */
    --v160-mob-sheet-head-h: 56px;

    /* Convenience totals (height + bottom safe area). */
    --v160-mob-tabbar-total: calc(var(--v160-mob-tabbar-h) + var(--v160-mob-safe-b));
    --v160-mob-action-total: calc(var(--v160-mob-action-h) + var(--v160-mob-safe-b));

    /* Page gutter for edge-to-edge phone layouts. */
    --v160-mob-gutter: 12px;

    /* Stacking — deliberately reuses the existing --hicm-z-* scale so legacy and new
     * overlays interleave correctly (nav 1200 / backdrop 1290 / sheet 1300 /
     * drawer 1500 / modal 1800 / lightbox 1900 / search 2000). */
    --v160-mob-z-sticky: 190;
    --v160-mob-z-header: 200;
    --v160-mob-z-tabbar: 1200;
    --v160-mob-z-action: 1250;
    --v160-mob-z-backdrop: 1290;
    --v160-mob-z-sheet: 1300;
    --v160-mob-z-drawer: 1500;
    --v160-mob-z-search: 2000;
}


/* ==================================================================================
 * 2. GLOBAL MOBILE POLICY
 * ================================================================================== */

@media (max-width: 1024px) {

    /* Never let a phone scroll sideways. Legacy 20-mobile.css uses `overflow-x:hidden`
     * on <body>, which turns the body into a scroll container and silently breaks
     * `position: sticky` on its descendants (the quick bar, detail tabs and console
     * top bar all rely on it). `overflow-x: clip` suppresses the same overflow without
     * creating a scroll container; browsers that do not support it fall back to the
     * legacy `hidden`, which is still declared on <html>. */
    html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
    body { overflow-x: clip; }

    /* Anchor jumps must clear the sticky header. */
    html { scroll-padding-block-start: calc(var(--v160-mob-header-h) + var(--v160-mob-safe-t) + var(--v160-space-3)); }

    /* Kill the blue tap flash on every interactive element. */
    a,
    button,
    label,
    input,
    select,
    textarea,
    summary,
    [role="button"] { -webkit-tap-highlight-color: transparent; }

    /* Reserve room for the bottom tab bar. Detail pages add the action bar on top
     * (see section 11). Console pages use layout/blank and have no tab bar, so they
     * are excluded. */
    body { padding-block-end: var(--v160-mob-tabbar-total); }
    body.gab-page-admin,
    body.gab-page-dealer,
    body.gab-page-member,
    body.gab-page-auth { padding-block-end: 0; }

    /* Horizontal rails: momentum + hidden scrollbar, everywhere. */
    .v160-tabs,
    .v160-scroll-x,
    .v160-chip-row,
    .gab-sort-tabs,
    .gab-detail-tabs,
    .gab-qbar-chips,
    .gab-quickfilters,
    .gab-rv-tabs {
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        overscroll-behavior-inline: contain;
    }
    .v160-tabs::-webkit-scrollbar,
    .v160-scroll-x::-webkit-scrollbar,
    .v160-chip-row::-webkit-scrollbar,
    .gab-sort-tabs::-webkit-scrollbar,
    .gab-detail-tabs::-webkit-scrollbar,
    .gab-qbar-chips::-webkit-scrollbar,
    .gab-quickfilters::-webkit-scrollbar,
    .gab-rv-tabs::-webkit-scrollbar { display: none; }
}

@media (max-width: 640px) {

    /* Body copy floor — 14px is the smallest readable size on a phone. */
    body { font-size: var(--v160-fs-lg); line-height: var(--v160-lh-base); }
    p, li, dd { font-size: var(--v160-fs-md); line-height: var(--v160-lh-base); }

    /* Korean headlines must not break mid-word. */
    h1, h2, h3, h4,
    .gab-car-card-title,
    .gab-detail-title,
    .v160-table__main { overflow-wrap: break-word; word-break: keep-all; }

    /* Consistent page gutter. */
    .gab-container,
    .v160-container,
    .v160-container--tight {
        padding-inline: max(var(--v160-space-4), var(--v160-mob-safe-l), var(--v160-mob-safe-r));
    }

    /* Media never overflows. */
    img, video, svg, canvas, iframe, table, pre { max-inline-size: 100%; }
    img { background-color: var(--v160-surface-3); }

    /* Utility: hide/show by viewport. View authors may use these directly. */
    .v160-mob-only { display: block; }
    .v160-mob-hide { display: none; }

    /* Utility: full-bleed a block out of its gutter (image rails, card rows). */
    .v160-mob-bleed {
        margin-inline: calc(var(--v160-space-4) * -1);
        padding-inline: var(--v160-space-4);
    }
}

@media (min-width: 641px) {
    .v160-mob-only { display: none; }
}


/* ==================================================================================
 * 3. APP HEADER
 * ----------------------------------------------------------------------------------
 * Phone chrome collapses to: [hamburger] [logo mark] [search] .
 * The desktop utility strip (.gab-top-bar) and the category nav (.gab-nav-bar) are
 * hidden — both are surfaced inside the drawer (section 5).
 * Tapping the search control opens the full-screen overlay (section 4); the existing
 * mobile-search.php script already binds focus/click on #gab-hsearch.
 * ================================================================================== */

@media (max-width: 1024px) {

    .gab-site-header {
        position: sticky;
        inset-block-start: 0;
        z-index: var(--v160-mob-z-header);
        background: var(--v160-surface);
        border-block-end: 1px solid var(--v160-border);
        box-shadow: none;
        padding-block-start: var(--v160-mob-safe-t);
        transition: transform var(--v160-dur-slow) var(--v160-ease);
    }
    /* Auto-hide on scroll-down (class toggled by legacy header script). */
    .gab-site-header.gab-hdr-hidden { transform: translateY(-100%); }

    .gab-main-header {
        block-size: var(--v160-mob-header-h);
        box-shadow: none;
        border-block-end: 0;
    }
    .gab-main-header-inner {
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        block-size: var(--v160-mob-header-h);
    }

    .gab-burger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        flex: 0 0 auto;
        padding: 0;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: var(--v160-text);
        font-size: 22px;
        cursor: pointer;
    }
    .gab-burger:active { background: var(--v160-surface-3); }

    .gab-main-header .gab-logo {
        display: inline-flex;
        align-items: center;
        gap: var(--v160-space-2);
        flex: 0 0 auto;
        min-inline-size: 0;
    }
    /* Logo SVG untouched — only its wrapper is resized. */
    .gab-main-header .gab-logo-icon {
        inline-size: 36px;
        block-size: 36px;
        border-radius: var(--v160-r-sm);
    }
    .gab-main-header .gab-logo-tagline { display: none; }
}

@media (max-width: 640px) {

    /* Utility strip + category nav move into the drawer. */
    .gab-top-bar { display: none; }
    .gab-nav-bar { display: none; }

    /* Wordmark drops; the mark alone carries the brand at 640px. */
    .gab-main-header .gab-logo-text { display: none; }

    /* Search collapses to a 44px icon target. The real <input> stays in the DOM at
     * full size but transparent, so the existing overlay binding still fires and the
     * control remains reachable by keyboard and screen readers. */
    .gab-header-search {
        display: block;
        flex: 0 0 var(--v160-tap);
        inline-size: var(--v160-tap);
        min-inline-size: var(--v160-tap);
        margin-inline-start: auto;
        position: relative;
    }
    .gab-header-search-form {
        position: relative;
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        padding: 0;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        box-shadow: none;
        overflow: hidden;
    }
    .gab-header-search-form:focus-within { background: var(--v160-surface-3); }
    .gab-header-search-input {
        position: absolute;
        inset-block: 0;
        inset-inline: 0;
        inline-size: 100%;
        block-size: 100%;
        padding: 0;
        border: 0;
        background: transparent;
        color: transparent;
        font-size: 16px; /* iOS zoom guard even though the field is visually empty */
        cursor: pointer;
    }
    .gab-header-search-input::placeholder { color: transparent; }
    .gab-header-search-btn {
        position: absolute;
        inset-block: 0;
        inset-inline: 0;
        inline-size: 100%;
        block-size: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 0;
        background: transparent;
        color: var(--v160-text);
        font-size: 20px;
        pointer-events: none; /* taps fall through to the input -> overlay opens */
    }

    /* Header CTAs live in the tab bar and the drawer at phone width. */
    .gab-header-cta { display: none; }

    /* Suggest dropdown becomes a full-width sheet under the header. */
    .gab-main-header .gab-suggest {
        position: fixed;
        inset-inline: 0;
        inset-block-start: calc(var(--v160-mob-header-h) + var(--v160-mob-safe-t));
        inline-size: 100%;
        max-block-size: calc(100vh - var(--v160-mob-header-h) - var(--v160-mob-safe-t));
        border-radius: 0;
        border-inline: 0;
        box-shadow: var(--v160-elev-4);
        overscroll-behavior: contain;
    }
}


/* ==================================================================================
 * 4. FULL-SCREEN SEARCH OVERLAY
 * ----------------------------------------------------------------------------------
 * Re-skins views/partials/mobile-search.php (.gab-msearch). New markup may instead use
 * .v160-mob-search with the same element names; both are styled.
 * ================================================================================== */

@media (max-width: 1024px) {

    .gab-msearch,
    .v160-mob-search {
        display: block;
        position: fixed;
        inset-block: 0;
        inset-inline: 0;
        z-index: var(--v160-mob-z-search);
        background: var(--v160-surface);
        padding-block-start: var(--v160-mob-safe-t);
        padding-block-end: var(--v160-mob-safe-b);
        opacity: 0;
        transform: translateY(8px);
        pointer-events: none;
        transition: opacity var(--v160-dur) var(--v160-ease),
                    transform var(--v160-dur) var(--v160-ease);
    }
    .gab-msearch.is-open,
    .v160-mob-search.is-open {
        opacity: 1;
        transform: translateY(0);
        pointer-events: auto;
    }

    /* Search bar */
    .gab-msearch-bar,
    .v160-mob-search__bar {
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        block-size: var(--v160-mob-header-h);
        padding-inline: var(--v160-space-2);
        border-block-end: 1px solid var(--v160-border);
        background: var(--v160-surface);
    }
    .gab-msearch-back {
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: var(--v160-text);
        font-size: 20px;
        cursor: pointer;
    }
    .gab-msearch-back:active { background: var(--v160-surface-3); }

    .gab-msearch-input-wrap {
        flex: 1 1 auto;
        min-inline-size: 0;
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        block-size: 40px;
        padding-inline: var(--v160-space-3);
        border: 1px solid var(--v160-border-strong);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        transition: border-color var(--v160-dur-fast) var(--v160-ease),
                    box-shadow var(--v160-dur-fast) var(--v160-ease);
    }
    .gab-msearch-input-wrap:focus-within {
        border-color: var(--v160-accent);
        box-shadow: var(--v160-ring);
    }
    .gab-msearch-input-wrap > .bi-search { color: var(--v160-text-subtle); font-size: 16px; }
    .gab-msearch-input {
        flex: 1 1 auto;
        min-inline-size: 0;
        border: 0;
        background: none;
        outline: none;
        font-family: var(--v160-font-sans);
        font-size: 16px;
        color: var(--v160-text);
    }
    .gab-msearch-input::placeholder { color: var(--v160-text-subtle); }
    .gab-msearch-clear,
    .gab-msearch-voice {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        justify-content: center;
        inline-size: 28px;
        block-size: 28px;
        padding: 0;
        border: 0;
        background: none;
        color: var(--v160-text-subtle);
        font-size: 16px;
        cursor: pointer;
    }
    .gab-msearch-voice { color: var(--v160-accent); }
    .gab-msearch-voice.is-listening { color: var(--v160-danger); }

    /* Body */
    .gab-msearch-body,
    .v160-mob-search__body {
        block-size: calc(100% - var(--v160-mob-header-h));
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
        background: var(--v160-surface);
    }
    .gab-msearch-sec { padding: var(--v160-space-5) var(--v160-space-4) var(--v160-space-2); }
    .gab-msearch-sec-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--v160-space-3);
        margin-block-end: var(--v160-space-3);
    }
    .gab-msearch-sec-title {
        display: inline-flex;
        align-items: center;
        gap: var(--v160-space-2);
        font-size: var(--v160-fs-md);
        font-weight: 700;
        letter-spacing: var(--v160-track-snug);
        color: var(--v160-text);
    }
    .gab-msearch-sec-title i { color: var(--v160-text-subtle); font-size: 15px; }
    .gab-msearch-clear-all {
        border: 0;
        background: none;
        padding: var(--v160-space-2);
        margin-inline-end: calc(var(--v160-space-2) * -1);
        color: var(--v160-text-muted);
        font-size: var(--v160-fs-xs);
        font-weight: 600;
        cursor: pointer;
    }

    /* Recent chips */
    .gab-msearch-recent { display: flex; flex-wrap: wrap; gap: var(--v160-space-2); }
    .gab-msearch-rchip {
        display: inline-flex;
        align-items: center;
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-pill);
        background: var(--v160-surface);
        overflow: hidden;
    }
    .gab-msearch-rchip-kw {
        border: 0;
        background: none;
        padding-block: var(--v160-space-2);
        padding-inline: var(--v160-space-3) var(--v160-space-1);
        font-size: var(--v160-fs-sm);
        font-weight: 600;
        color: var(--v160-text-muted);
        cursor: pointer;
    }
    .gab-msearch-rchip-x {
        border: 0;
        background: none;
        padding-inline: var(--v160-space-2) var(--v160-space-3);
        padding-block: var(--v160-space-2);
        color: var(--v160-text-subtle);
        font-size: var(--v160-fs-sm);
        display: flex;
        cursor: pointer;
    }

    /* Popular ranking */
    .gab-msearch-popular {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        column-gap: var(--v160-space-5);
    }
    .gab-msearch-pop {
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        inline-size: 100%;
        min-block-size: var(--v160-tap);
        padding-block: var(--v160-space-2);
        padding-inline: var(--v160-space-1);
        border: 0;
        background: none;
        text-align: start;
        cursor: pointer;
    }
    .gab-msearch-pop-rank {
        inline-size: 18px;
        flex: 0 0 auto;
        text-align: center;
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-md);
        font-weight: 700;
        color: var(--v160-text-subtle);
    }
    .gab-msearch-pop-rank.is-top { color: var(--v160-accent); }
    .gab-msearch-pop-kw {
        flex: 1 1 auto;
        min-inline-size: 0;
        font-size: var(--v160-fs-md);
        font-weight: 600;
        color: var(--v160-text);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .gab-msearch-pop-trend { flex: 0 0 auto; font-size: 10px; font-weight: 700; }
    .gab-msearch-pop-trend.is-up { color: var(--v160-danger); }
    .gab-msearch-pop-trend.is-new {
        color: var(--v160-accent-contrast);
        background: var(--v160-accent);
        border-radius: var(--v160-r-xs);
        padding: 1px 4px;
        line-height: 1.3;
    }

    /* Presets / related */
    .gab-msearch-presets {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--v160-space-2);
    }
    .gab-msearch-preset {
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        min-block-size: var(--v160-tap);
        padding: var(--v160-space-3);
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-lg);
        background: var(--v160-surface);
        color: var(--v160-text);
        font-size: var(--v160-fs-sm);
        font-weight: 600;
        text-decoration: none;
    }
    .gab-msearch-preset i { color: var(--v160-accent); font-size: 15px; flex: 0 0 auto; }
    .gab-msearch-preset span { min-inline-size: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

    .gab-msearch-related { display: flex; flex-wrap: wrap; gap: var(--v160-space-2); }
    .gab-msearch-rel {
        display: inline-flex;
        align-items: center;
        gap: var(--v160-space-2);
        min-block-size: 36px;
        padding-inline: var(--v160-space-3);
        border: 1px solid var(--v160-accent-border);
        border-radius: var(--v160-r-pill);
        background: var(--v160-accent-soft);
        color: var(--v160-accent-hover);
        font-size: var(--v160-fs-sm);
        font-weight: 600;
        cursor: pointer;
    }
    .gab-msearch-rel i { font-size: 12px; opacity: .7; }

    /* Suggestions */
    .gab-msearch-sgcat {
        padding: var(--v160-space-3) var(--v160-space-4) var(--v160-space-1);
        font-size: var(--v160-fs-2xs);
        font-weight: 700;
        letter-spacing: .04em;
        text-transform: uppercase;
        color: var(--v160-text-subtle);
    }
    .gab-msearch-sgrow {
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        inline-size: 100%;
        min-block-size: var(--v160-tap);
        padding: var(--v160-space-3) var(--v160-space-4);
        border: 0;
        border-block-end: 1px solid var(--v160-border-subtle);
        background: none;
        text-align: start;
        font-size: var(--v160-fs-md);
        color: var(--v160-text);
        cursor: pointer;
    }
    .gab-msearch-sgrow:active { background: var(--v160-surface-3); }
    .gab-msearch-sgrow > .bi-search { color: var(--v160-text-subtle); font-size: 15px; flex: 0 0 auto; }
    .gab-msearch-sgrow span { flex: 1 1 auto; min-inline-size: 0; }
    .gab-msearch-sgrow b { color: var(--v160-accent); font-weight: 700; }
    .gab-msearch-sgrow-go { color: var(--v160-text-subtle); font-size: 14px; }
    .gab-msearch-sgcnt {
        flex: 0 0 auto;
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-xs);
        font-weight: 600;
        color: var(--v160-text-subtle);
    }
    .gab-msearch-sgrow--direct {
        color: var(--v160-accent);
        font-weight: 700;
        border-block-start: 1px solid var(--v160-border);
    }
    .gab-msearch-empty {
        padding: var(--v160-space-9) var(--v160-space-4);
        text-align: center;
        color: var(--v160-text-subtle);
        font-size: var(--v160-fs-sm);
    }

    /* Saved searches */
    .gab-msearch-saved { display: flex; flex-direction: column; gap: var(--v160-space-1); }
    .gab-msearch-srow {
        display: flex;
        align-items: center;
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-lg);
        background: var(--v160-surface);
        overflow: hidden;
    }
    .gab-msearch-srow-go {
        flex: 1 1 auto;
        min-inline-size: 0;
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        min-block-size: var(--v160-tap);
        padding: var(--v160-space-3);
        color: var(--v160-text);
        font-size: var(--v160-fs-sm);
        font-weight: 600;
        text-decoration: none;
    }
    .gab-msearch-srow-go i { color: var(--v160-accent); flex: 0 0 auto; }
    .gab-msearch-srow-go span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    .gab-msearch-srow-x {
        flex: 0 0 auto;
        border: 0;
        background: none;
        padding: var(--v160-space-3);
        color: var(--v160-text-subtle);
        font-size: 15px;
        cursor: pointer;
    }
}


/* ==================================================================================
 * 5. NAVIGATION DRAWER
 * ----------------------------------------------------------------------------------
 * Full-height slide-in. Re-skins views/partials/header.php (.gab-drawer …). New markup
 * may use the parallel .v160-mob-drawer API:
 *   .v160-mob-drawer          panel
 *   .v160-mob-drawer__group   grouped link block
 *   .v160-mob-drawer__legend  small uppercase group heading
 * ================================================================================== */

@media (max-width: 1024px) {

    .gab-drawer-overlay,
    .gab-drawer-ov {
        position: fixed;
        inset-block: 0;
        inset-inline: 0;
        z-index: calc(var(--v160-mob-z-drawer) - 1);
        background: var(--v160-surface-overlay);
        opacity: 0;
        visibility: hidden;
        transition: opacity var(--v160-dur) var(--v160-ease),
                    visibility var(--v160-dur) var(--v160-ease);
    }
    .gab-drawer-overlay.is-open,
    .gab-drawer-ov.is-open { opacity: 1; visibility: visible; }

    .gab-drawer,
    .v160-mob-drawer {
        position: fixed;
        inset-block: 0;
        inset-inline-start: 0;
        z-index: var(--v160-mob-z-drawer);
        display: flex;
        flex-direction: column;
        inline-size: 320px;
        max-inline-size: 88vw;
        background: var(--v160-surface);
        border-inline-end: 1px solid var(--v160-border);
        box-shadow: var(--v160-elev-5);
        transform: translateX(-100%);
        transition: transform var(--v160-dur-slow) var(--v160-ease);
        padding-block-start: var(--v160-mob-safe-t);
        padding-block-end: var(--v160-mob-safe-b);
        overscroll-behavior: contain;
    }
    .gab-drawer.is-open,
    .v160-mob-drawer.is-open { transform: translateX(0); }

    .gab-drawer-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--v160-space-3);
        min-block-size: var(--v160-mob-header-h);
        padding-inline: var(--v160-space-4);
        border-block-end: 1px solid var(--v160-border);
        flex: 0 0 auto;
    }
    .gab-drawer-logo {
        display: inline-flex;
        align-items: center;
        gap: var(--v160-space-2);
        font-size: var(--v160-fs-lg);
        font-weight: 700;
        letter-spacing: var(--v160-track-snug);
        color: var(--v160-text);
        text-decoration: none;
    }
    .gab-drawer-logo .accent { color: var(--v160-accent); }
    .gab-drawer-head button,
    .gab-drawer-close,
    .gab-drawer-x {
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: var(--v160-text-muted);
        font-size: 19px;
        cursor: pointer;
        margin-inline-end: calc(var(--v160-space-2) * -1);
    }
    .gab-drawer-head button:active { background: var(--v160-surface-3); }

    .gab-drawer-search {
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        flex: 0 0 auto;
        margin: var(--v160-space-3) var(--v160-space-4) var(--v160-space-1);
        padding-inline: var(--v160-space-3);
        block-size: var(--v160-control-h);
        border: 1px solid var(--v160-border-strong);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
    }
    .gab-drawer-search:focus-within {
        border-color: var(--v160-accent);
        box-shadow: var(--v160-ring);
    }
    .gab-drawer-search i { color: var(--v160-text-subtle); }
    .gab-drawer-search input {
        flex: 1 1 auto;
        min-inline-size: 0;
        border: 0;
        background: none;
        outline: none;
        font-family: var(--v160-font-sans);
        font-size: 16px;
        color: var(--v160-text);
    }

    /* Scrollable link region with momentum. */
    .gab-drawer-nav,
    .v160-mob-drawer__scroll {
        flex: 1 1 auto;
        min-block-size: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
        padding-block: var(--v160-space-2);
    }
    .gab-drawer-nav a,
    .v160-mob-drawer__link {
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        min-block-size: var(--v160-tap);
        padding: var(--v160-space-3) var(--v160-space-4);
        color: var(--v160-text);
        font-size: var(--v160-fs-lg);
        font-weight: 600;
        text-decoration: none;
        transition: background var(--v160-dur-fast) var(--v160-ease);
    }
    .gab-drawer-nav a i,
    .v160-mob-drawer__link i {
        inline-size: 22px;
        flex: 0 0 auto;
        text-align: center;
        font-size: 18px;
        color: var(--v160-text-subtle);
    }
    .gab-drawer-nav a:active,
    .v160-mob-drawer__link:active { background: var(--v160-surface-3); }
    .gab-drawer-nav a[aria-current="page"],
    .v160-mob-drawer__link[aria-current="page"] {
        color: var(--v160-accent);
        background: var(--v160-accent-soft);
        box-shadow: inset 3px 0 0 0 var(--v160-accent);
    }
    .gab-drawer-nav a[aria-current="page"] i,
    .v160-mob-drawer__link[aria-current="page"] i { color: var(--v160-accent); }

    /* Grouping API for rewritten markup. */
    .v160-mob-drawer__group + .v160-mob-drawer__group {
        margin-block-start: var(--v160-space-2);
        padding-block-start: var(--v160-space-2);
        border-block-start: 1px solid var(--v160-border-subtle);
    }
    .v160-mob-drawer__legend {
        padding: var(--v160-space-3) var(--v160-space-4) var(--v160-space-1);
        font-size: var(--v160-fs-2xs);
        font-weight: 700;
        letter-spacing: .06em;
        text-transform: uppercase;
        color: var(--v160-text-subtle);
    }

    /* Language switcher */
    .gab-drawer-lang {
        flex: 0 0 auto;
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: var(--v160-space-2);
        padding: var(--v160-space-3) var(--v160-space-4);
        border-block-start: 1px solid var(--v160-border-subtle);
    }
    .gab-drawer-lang-btn {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--v160-space-1);
        min-block-size: var(--v160-control-h-sm);
        padding-inline: var(--v160-space-2);
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        color: var(--v160-text-muted);
        font-size: var(--v160-fs-xs);
        font-weight: 600;
        text-decoration: none;
        cursor: pointer;
    }
    .gab-drawer-lang-btn.is-active {
        border-color: var(--v160-accent);
        background: var(--v160-accent-soft);
        color: var(--v160-accent-hover);
    }
    .gab-drawer-lang-btn span svg,
    .gab-drawer-lang-btn span img {
        inline-size: 16px;
        block-size: 12px;
        border-radius: 2px;
        object-fit: cover;
        vertical-align: middle;
    }

    /* Login / join footer */
    .gab-drawer-foot {
        flex: 0 0 auto;
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--v160-space-2);
        padding: var(--v160-space-3) var(--v160-space-4)
                 calc(var(--v160-space-3) + var(--v160-mob-safe-b));
        border-block-start: 1px solid var(--v160-border);
        background: var(--v160-surface-2);
    }
    .gab-drawer-login,
    .gab-drawer-join {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--v160-space-2);
        min-block-size: var(--v160-tap);
        border-radius: var(--v160-r-md);
        font-size: var(--v160-fs-md);
        font-weight: 600;
        text-decoration: none;
    }
    .gab-drawer-login {
        border: 1px solid var(--v160-border-strong);
        background: var(--v160-surface);
        color: var(--v160-text);
    }
    .gab-drawer-join {
        border: 1px solid var(--v160-accent);
        background: var(--v160-accent);
        color: var(--v160-accent-contrast);
        box-shadow: var(--v160-elev-1);
    }
    .gab-drawer-join:active { background: var(--v160-accent-active); border-color: var(--v160-accent-active); }
}


/* ==================================================================================
 * 6. BOTTOM TAB BAR
 * ----------------------------------------------------------------------------------
 * 5 items, 56px + safe area. Active = filled icon + accent label. The centre item
 * (.gab-tabbar-item--cta) is raised. Re-skins views/partials/mobile-tabbar.php; new
 * markup may use .v160-mob-tabbar with the same element names.
 * ================================================================================== */

@media (max-width: 1024px) {

    /* Legacy 20-mobile.css hides the tab bar above 768px with `display:none !important`;
     * v160 keeps app navigation through the whole tablet band. */
    .gab-tabbar { display: flex !important; } /* defeats 20-mobile.css @media(min-width:769px) */

    .gab-tabbar,
    .v160-mob-tabbar {
        position: fixed;
        inset-inline: 0;
        inset-block-end: 0;
        z-index: var(--v160-mob-z-tabbar);
        display: flex;
        align-items: stretch;
        block-size: var(--v160-mob-tabbar-total);
        padding-block-end: var(--v160-mob-safe-b);
        padding-inline: max(0px, var(--v160-mob-safe-l), var(--v160-mob-safe-r));
        background: var(--v160-surface);
        border-block-start: 1px solid var(--v160-border);
        box-shadow: 0 -1px 2px rgba(15, 23, 42, .06);
    }

    .gab-tabbar-item,
    .v160-mob-tabbar__item {
        position: relative;
        flex: 1 1 0;
        min-inline-size: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 2px;
        padding-block: var(--v160-space-1);
        min-block-size: var(--v160-mob-tabbar-h);
        color: var(--v160-text-subtle);
        font-size: var(--v160-fs-2xs);
        font-weight: 600;
        letter-spacing: var(--v160-track-snug);
        text-decoration: none;
        transition: color var(--v160-dur-fast) var(--v160-ease);
    }
    .gab-tabbar-ic,
    .v160-mob-tabbar__ic {
        display: flex;
        align-items: center;
        justify-content: center;
        block-size: 22px;
        font-size: 21px;
        line-height: 1;
    }
    .gab-tabbar-ic-on { display: none; }
    .gab-tabbar-ic-off { display: inline-flex; }
    .gab-tabbar-label,
    .v160-mob-tabbar__label {
        max-inline-size: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    /* Active — filled glyph + accent label. Driven by aria-current, with .is-active
     * kept as a fallback for the existing script. */
    .gab-tabbar-item.is-active,
    .gab-tabbar-item[aria-current="page"],
    .v160-mob-tabbar__item[aria-current="page"] { color: var(--v160-accent); }
    .gab-tabbar-item.is-active .gab-tabbar-ic-on,
    .gab-tabbar-item[aria-current="page"] .gab-tabbar-ic-on { display: inline-flex; }
    .gab-tabbar-item.is-active .gab-tabbar-ic-off,
    .gab-tabbar-item[aria-current="page"] .gab-tabbar-ic-off { display: none; }

    /* Raised centre CTA */
    .gab-tabbar-item--cta { color: var(--v160-accent); }
    .gab-tabbar-cta-btn,
    .v160-mob-tabbar__cta {
        display: flex;
        align-items: center;
        justify-content: center;
        inline-size: 46px;
        block-size: 46px;
        margin-block-start: -20px;
        border: 3px solid var(--v160-surface);
        border-radius: var(--v160-r-2xl);
        background: var(--v160-accent);
        color: var(--v160-accent-contrast);
        font-size: 22px;
        box-shadow: var(--gab-glow-brand, 0 10px 28px -14px rgba(176, 35, 24, .34));
    }
    .gab-tabbar-item--cta:active .gab-tabbar-cta-btn { background: var(--v160-accent-active); }
    .gab-tabbar-item--cta .gab-tabbar-label { margin-block-start: 1px; }

    /* Badge */
    .gab-tabbar-badge,
    .v160-mob-tabbar__badge {
        position: absolute;
        inset-block-start: 4px;
        inset-inline-start: 50%;
        margin-inline-start: 6px;
        min-inline-size: 16px;
        block-size: 16px;
        padding-inline: 4px;
        border-radius: var(--v160-r-pill);
        background: var(--v160-danger);
        color: var(--v160-text-inverse);
        font-variant-numeric: tabular-nums;
        font-size: 10px;
        font-weight: 700;
        line-height: 16px;
        text-align: center;
    }

    /* Focus ring must not be clipped by the bar edge. */
    .gab-tabbar-item:focus-visible,
    .v160-mob-tabbar__item:focus-visible {
        outline: 2px solid var(--v160-accent);
        outline-offset: -3px;
        border-radius: var(--v160-r-md);
    }

    /* Legacy 20-mobile.css hides the footer below 768px; v160 keeps it (see 6b). */
    .gab-footer { display: block; }
}


/* ----------------------------------------------------------------------------------
 * 6b. FOOTER ON TOUCH
 * Legacy 20-mobile.css hides .gab-footer entirely below 768px. That also removes the
 * business-registration / legal block, which a Korean marketplace must keep reachable.
 * v160 keeps the footer but compresses it to a single column and drops the decorative
 * marketing blocks. Detailed footer typography is owned by 39-v160-public.
 * ---------------------------------------------------------------------------------- */
@media (max-width: 640px) {

    .gab-footer {
        padding-block: var(--v160-space-6) var(--v160-space-5);
        background: var(--v160-surface-2);
        border-block-start: 1px solid var(--v160-border);
    }
    .gab-footer-grid {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--v160-space-5) var(--v160-space-4);
    }
    .gab-footer-brand { grid-column: 1 / -1; }
    .gab-footer-brand-desc { font-size: var(--v160-fs-xs); }
    .gab-footer-col-title { font-size: var(--v160-fs-sm); }
    .gab-footer-col-list a { display: inline-flex; min-block-size: 32px; align-items: center; font-size: var(--v160-fs-xs); }

    /* Marketing furniture that has no job on a phone. */
    .gab-footer-news,
    .gab-footer-global,
    .gab-footer-payment,
    .gab-footer-flags { display: none; }

    .gab-footer-social { display: flex; flex-wrap: wrap; gap: var(--v160-space-2); }
    .gab-footer-social-btn {
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        color: var(--v160-text-muted);
    }

    .gab-footer-bottom {
        display: flex;
        flex-direction: column;
        gap: var(--v160-space-2);
        margin-block-start: var(--v160-space-5);
        padding-block-start: var(--v160-space-4);
        border-block-start: 1px solid var(--v160-border);
    }
    .gab-footer-legal { display: flex; flex-wrap: wrap; gap: var(--v160-space-3); }
    .gab-footer-legal a { min-block-size: 32px; display: inline-flex; align-items: center; font-size: var(--v160-fs-xs); }
    .gab-footer-copyright,
    .gab-footer-made { font-size: var(--v160-fs-2xs); color: var(--v160-text-subtle); }
}


/* ==================================================================================
 * 7. BOTTOM-SHEET FRAMEWORK
 * ----------------------------------------------------------------------------------
 * Shared shell for the filter sheet, the sort sheet and any modal converted to a
 * sheet. `window.gabSheet(id, open)` (assets/js/main.js) creates the backdrop element
 * `<div class="gab-sheet-backdrop" id="<id>-bd">` and toggles `.is-open`.
 *
 * New markup API:
 *   <section class="v160-mob-sheet v160-mob-sheet--full" id="…">
 *     <header class="v160-mob-sheet__head">
 *       <h2 class="v160-mob-sheet__title">…</h2>
 *       <button class="v160-mob-sheet__reset">…</button>
 *       <button class="v160-mob-sheet__close" aria-label="닫기">…</button>
 *     </header>
 *     <div class="v160-mob-sheet__body">…</div>
 *     <footer class="v160-mob-sheet__foot">…</footer>
 *   </section>
 * ================================================================================== */

@media (max-width: 1024px) {

    .gab-sheet-backdrop,
    .v160-mob-sheet-backdrop {
        position: fixed;
        inset-block: 0;
        inset-inline: 0;
        z-index: var(--v160-mob-z-backdrop);
        background: var(--v160-surface-overlay);
        -webkit-backdrop-filter: blur(2px);
        backdrop-filter: blur(2px);
        opacity: 0;
        visibility: hidden;
        transition: opacity var(--v160-dur-slow) var(--v160-ease),
                    visibility var(--v160-dur-slow) var(--v160-ease);
    }
    .gab-sheet-backdrop.is-open,
    .v160-mob-sheet-backdrop.is-open { opacity: 1; visibility: visible; }

    .v160-mob-sheet {
        position: fixed;
        inset-inline: 0;
        inset-block-end: 0;
        z-index: var(--v160-mob-z-sheet);
        display: flex;
        flex-direction: column;
        max-block-size: 88vh;
        background: var(--v160-surface);
        border-start-start-radius: var(--v160-r-2xl);
        border-start-end-radius: var(--v160-r-2xl);
        box-shadow: var(--v160-elev-5);
        transform: translateY(100%);
        transition: transform var(--v160-dur-slow) var(--v160-ease-out);
        overscroll-behavior: contain;
    }
    .v160-mob-sheet.is-open { transform: translateY(0); }

    /* Full-screen variant — used by the filter sheet. */
    .v160-mob-sheet--full {
        inset-block-start: 0;
        max-block-size: none;
        block-size: 100%;
        border-start-start-radius: 0;
        border-start-end-radius: 0;
        padding-block-start: var(--v160-mob-safe-t);
    }

    /* Grab handle (bottom variant only). */
    .v160-mob-sheet__handle {
        flex: 0 0 auto;
        inline-size: 40px;
        block-size: 4px;
        margin: var(--v160-space-2) auto var(--v160-space-1);
        border-radius: var(--v160-r-pill);
        background: var(--v160-border-strong);
    }
    .v160-mob-sheet--full .v160-mob-sheet__handle { display: none; }

    .v160-mob-sheet__head {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        min-block-size: var(--v160-mob-sheet-head-h);
        padding-inline: var(--v160-space-2) var(--v160-space-2);
        border-block-end: 1px solid var(--v160-border);
        background: var(--v160-surface);
    }
    .v160-mob-sheet__title {
        flex: 1 1 auto;
        min-inline-size: 0;
        margin: 0;
        padding-inline-start: var(--v160-space-2);
        font-size: var(--v160-fs-xl);
        font-weight: 700;
        letter-spacing: var(--v160-track-tight);
        color: var(--v160-text);
    }
    .v160-mob-sheet__reset {
        flex: 0 0 auto;
        min-block-size: var(--v160-tap);
        padding-inline: var(--v160-space-3);
        border: 0;
        background: none;
        color: var(--v160-text-muted);
        font-size: var(--v160-fs-md);
        font-weight: 600;
        text-decoration: none;
        cursor: pointer;
    }
    .v160-mob-sheet__close {
        flex: 0 0 auto;
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: var(--v160-text-muted);
        font-size: 18px;
        cursor: pointer;
    }
    .v160-mob-sheet__close:active { background: var(--v160-surface-3); }

    .v160-mob-sheet__body {
        flex: 1 1 auto;
        min-block-size: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
        padding: var(--v160-space-4);
    }

    .v160-mob-sheet__foot {
        flex: 0 0 auto;
        display: flex;
        gap: var(--v160-space-2);
        padding: var(--v160-space-3) var(--v160-space-4)
                 calc(var(--v160-space-3) + var(--v160-mob-safe-b));
        border-block-start: 1px solid var(--v160-border);
        background: var(--v160-surface);
        box-shadow: 0 -1px 2px rgba(15, 23, 42, .06);
    }
    .v160-mob-sheet__foot .v160-btn { flex: 1 1 auto; min-block-size: 48px; }
}


/* ==================================================================================
 * 8. FILTER SHEET
 * ----------------------------------------------------------------------------------
 * The single most important mobile interaction on an Encar-class marketplace.
 * Full-screen, own header (title / reset / close), scrollable body, fixed footer whose
 * button carries the live result count ("N대 보기" — #gab-sheet-count).
 *
 * Re-skins views/pages/car-list.php: .gab-filter-sidebar / .gab-filter-header /
 * .gab-filter-reset / .gab-filter-sheet-close / .gab-filter-sheet-foot /
 * .gab-filter-sheet-apply / .gab-sheet-count.
 * ================================================================================== */

@media (max-width: 1024px) {

    /* --- panel shell ------------------------------------------------------------ */
    .gab-filter-sidebar {
        position: fixed;
        /* legacy 20-mobile.css pins top:auto/height:auto/max-height:86vh with
         * !important; v160 needs a true full-screen sheet. */
        inset-block-start: 0 !important;      /* defeats 20-mobile.css `top: auto !important` */
        inset-block-end: 0 !important;        /* defeats 20-mobile.css `bottom: 0 !important` */
        inset-inline-start: 0;
        inset-inline-end: 0;
        z-index: var(--v160-mob-z-sheet);
        inline-size: 100%;
        max-inline-size: 100%;
        block-size: 100% !important;          /* defeats 20-mobile.css `height: auto !important` */
        max-block-size: none;
        border: 0;
        border-radius: 0 !important;          /* defeats 20-mobile.css `border-radius: 20px 20px 0 0 !important` */
        background: var(--v160-surface);
        box-shadow: none;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
        transform: translateY(100%);
        transition: transform var(--v160-dur-slow) var(--v160-ease-out) !important; /* defeats 20-mobile.css F4 transition !important */
        padding-block: var(--v160-mob-safe-t)
                       calc(var(--v160-mob-action-h) + var(--v160-space-4) + var(--v160-mob-safe-b));
        padding-inline: 0;
    }
    .gab-filter-sidebar.is-open { transform: translateY(0); }

    /* The legacy drag handle has no meaning on a full-screen sheet. */
    .gab-filter-sidebar::before { display: none; }

    /* --- sheet header ----------------------------------------------------------- */
    .gab-filter-header {
        position: sticky;
        inset-block-start: 0;
        z-index: 2;
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        min-block-size: var(--v160-mob-sheet-head-h);
        margin: 0;
        padding-block: 0;
        padding-inline: var(--v160-space-4) calc(var(--v160-tap) + var(--v160-space-1));
        border-block-end: 1px solid var(--v160-border);
        background: var(--v160-surface);
        touch-action: auto;
    }
    .gab-filter-header-title {
        flex: 1 1 auto;
        min-inline-size: 0;
        display: inline-flex;
        align-items: center;
        gap: var(--v160-space-2);
        font-size: var(--v160-fs-xl);
        font-weight: 700;
        letter-spacing: var(--v160-track-tight);
        color: var(--v160-text);
    }
    .gab-filter-header-title .gab-title-mark { inline-size: 20px; block-size: 20px; }

    .gab-filter-reset {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        min-block-size: var(--v160-tap);
        padding-inline: var(--v160-space-2);
        color: var(--v160-text-muted);
        font-size: var(--v160-fs-md);
        font-weight: 600;
        text-decoration: none;
    }
    .gab-filter-reset:active { color: var(--v160-accent); }

    .gab-filter-sheet-close {
        display: inline-flex;
        position: absolute;
        inset-block-start: calc(var(--v160-mob-safe-t) + 6px);
        inset-inline-end: var(--v160-space-2);
        z-index: 3;
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: var(--v160-text-muted);
        font-size: 18px;
        cursor: pointer;
    }
    .gab-filter-sheet-close:active { background: var(--v160-surface-3); }

    /* --- groups ----------------------------------------------------------------- */
    .gab-filter-group {
        margin: 0;
        padding: 0 var(--v160-space-4);
        border: 0;
        border-block-end: 1px solid var(--v160-border-subtle);
        background: transparent;
    }
    .gab-filter-group-title {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--v160-space-2);
        min-block-size: 52px;
        margin: 0;
        font-size: var(--v160-fs-lg);
        font-weight: 700;
        letter-spacing: var(--v160-track-snug);
        color: var(--v160-text);
        cursor: pointer;
    }
    .gab-filter-group-title i {
        color: var(--v160-text-subtle);
        font-size: 13px;
        transition: transform var(--v160-dur) var(--v160-ease);
    }
    .gab-filter-options,
    .gab-filter-gbody { padding-block-end: var(--v160-space-3); }

    .gab-filter-option,
    .gab-filter-checkbox {
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        min-block-size: var(--v160-tap);
        font-size: var(--v160-fs-md);
        color: var(--v160-text-muted);
        cursor: pointer;
    }
    .gab-filter-option.is-checked { color: var(--v160-text); font-weight: 600; }

    .gab-filter-chips,
    .gab-filter-colors {
        display: flex;
        flex-wrap: wrap;
        gap: var(--v160-space-2);
        padding-block-end: var(--v160-space-3);
    }
    .gab-filter-chip,
    .gab-fchip,
    .gab-fb-otab {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-block-size: 38px;
        padding-inline: var(--v160-space-3);
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        color: var(--v160-text-muted);
        font-size: var(--v160-fs-sm);
        font-weight: 600;
        cursor: pointer;
    }
    .gab-filter-chip.is-on,
    .gab-fchip.is-on,
    .gab-fb-otab.is-on {
        border-color: var(--v160-accent);
        background: var(--v160-accent-soft);
        color: var(--v160-accent-hover);
    }

    /* Brand list inside the sheet gets its own scroll region. */
    .gab-fb-scroll {
        max-block-size: 44vh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
    }
    .gab-fb-row {
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        min-block-size: var(--v160-tap);
        border-block-end: 1px solid var(--v160-border-subtle);
    }
    .gab-fb-name { flex: 1 1 auto; min-inline-size: 0; font-size: var(--v160-fs-md); }
    .gab-fb-cnt {
        flex: 0 0 auto;
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-xs);
        color: var(--v160-text-subtle);
    }

    /* --- fixed footer with live count ------------------------------------------- */
    .gab-filter-sheet-foot {
        display: block;
        position: fixed;
        inset-inline: 0;
        inset-block-end: 0;
        z-index: 4;
        margin: 0;
        padding: var(--v160-space-3) var(--v160-space-4)
                 calc(var(--v160-space-3) + var(--v160-mob-safe-b));
        border-block-start: 1px solid var(--v160-border);
        background: var(--v160-surface);
        box-shadow: 0 -1px 2px rgba(15, 23, 42, .06);
    }
    .gab-filter-sheet-apply {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 2px;
        inline-size: 100%;
        min-block-size: 48px;
        padding-inline: var(--v160-space-4);
        border: 1px solid var(--v160-accent);
        border-radius: var(--v160-r-md);
        background: var(--v160-accent);
        color: var(--v160-accent-contrast);
        font-family: var(--v160-font-sans);
        font-size: var(--v160-fs-lg);
        font-weight: 700;
        letter-spacing: var(--v160-track-snug);
        cursor: pointer;
        transition: background var(--v160-dur-fast) var(--v160-ease);
    }
    .gab-filter-sheet-apply:active {
        background: var(--v160-accent-active);
        border-color: var(--v160-accent-active);
    }
    .gab-sheet-count {
        font-variant-numeric: tabular-nums;
        font-weight: 800;
        unicode-bidi: isolate;
    }

    /* The quick bar (section 10) already carries a filter button, so the legacy
     * inline toggle is a duplicate control. */
    .gab-filter-mtoggle { display: none !important; } /* defeats 20-mobile.css `display: inline-flex !important` */
}


/* ==================================================================================
 * 9. SORT SHEET
 * ================================================================================== */

@media (max-width: 1024px) {

    .gab-sort-sheet {
        display: block;
        position: fixed;
        inset-inline: 0;
        inset-block-end: 0;
        z-index: var(--v160-mob-z-sheet);
        background: var(--v160-surface);
        border-start-start-radius: var(--v160-r-2xl);
        border-start-end-radius: var(--v160-r-2xl);
        box-shadow: var(--v160-elev-5);
        transform: translateY(100%);
        transition: transform var(--v160-dur-slow) var(--v160-ease-out);
        padding-block-end: calc(var(--v160-space-3) + var(--v160-mob-safe-b));
        overscroll-behavior: contain;
    }
    .gab-sort-sheet.is-open { transform: translateY(0); }
    .gab-sort-sheet::before {
        content: '';
        display: block;
        inline-size: 40px;
        block-size: 4px;
        margin: var(--v160-space-2) auto var(--v160-space-1);
        border-radius: var(--v160-r-pill);
        background: var(--v160-border-strong);
    }
    .gab-sort-sheet-head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--v160-space-2);
        padding-block: var(--v160-space-2) var(--v160-space-3);
        padding-inline: var(--v160-space-4) var(--v160-space-2);
        border-block-end: 1px solid var(--v160-border-subtle);
    }
    .gab-sort-sheet-title {
        display: inline-flex;
        align-items: center;
        gap: var(--v160-space-2);
        font-size: var(--v160-fs-xl);
        font-weight: 700;
        letter-spacing: var(--v160-track-tight);
        color: var(--v160-text);
    }
    .gab-sort-sheet-title i { color: var(--v160-text-subtle); font-size: 16px; }
    .gab-sort-sheet-x {
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: var(--v160-text-muted);
        font-size: 18px;
        cursor: pointer;
    }
    .gab-sort-sheet-list { padding: var(--v160-space-2); }
    .gab-sort-opt {
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        inline-size: 100%;
        min-block-size: var(--v160-tap);
        padding: var(--v160-space-3);
        border: 0;
        border-radius: var(--v160-r-md);
        background: none;
        text-align: start;
        font-family: var(--v160-font-sans);
        font-size: var(--v160-fs-lg);
        font-weight: 600;
        color: var(--v160-text-muted);
        cursor: pointer;
    }
    .gab-sort-opt:active { background: var(--v160-surface-3); }
    .gab-sort-opt-ic { inline-size: 20px; flex: 0 0 auto; font-size: 16px; color: var(--v160-text-subtle); }
    .gab-sort-opt span { flex: 1 1 auto; min-inline-size: 0; }
    .gab-sort-opt-check { flex: 0 0 auto; font-size: 16px; color: var(--v160-accent); opacity: 0; }
    .gab-sort-opt.is-on,
    .gab-sort-opt[aria-checked="true"] {
        background: var(--v160-accent-soft);
        color: var(--v160-accent-hover);
    }
    .gab-sort-opt.is-on .gab-sort-opt-ic,
    .gab-sort-opt[aria-checked="true"] .gab-sort-opt-ic { color: var(--v160-accent); }
    .gab-sort-opt.is-on .gab-sort-opt-check,
    .gab-sort-opt[aria-checked="true"] .gab-sort-opt-check { opacity: 1; }
}


/* ==================================================================================
 * 10. LISTING
 * ----------------------------------------------------------------------------------
 * Sticky compact filter + sort bar directly under the header, then a single column of
 * cards with a 16:9 image and a prominent price.
 * ================================================================================== */

@media (max-width: 1024px) {

    .gab-list-layout { display: block; }
    .gab-list-results { padding-inline: var(--v160-mob-gutter); padding-block-end: var(--v160-space-3); }

    /* The verbose desktop toolbar collapses; the quick bar below replaces it. */
    .gab-list-toolbar {
        position: static;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--v160-space-2);
        padding: var(--v160-space-3) var(--v160-mob-gutter);
        border: 0;
        border-block-end: 1px solid var(--v160-border-subtle);
        background: transparent;
    }
    .gab-list-controls { display: none; }
    .gab-list-count {
        font-size: var(--v160-fs-sm);
        color: var(--v160-text-muted);
    }
    .gab-list-count strong,
    .gab-list-range {
        font-variant-numeric: tabular-nums;
        color: var(--v160-text);
        font-weight: 700;
        unicode-bidi: isolate;
    }

    /* --- sticky quick bar (filter + sort + chips) -------------------------------- */
    .gab-qbar,
    .v160-mob-subbar {
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        position: sticky;
        inset-block-start: calc(var(--v160-mob-header-h) + var(--v160-mob-safe-t));
        z-index: var(--v160-mob-z-sticky);
        min-block-size: var(--v160-mob-subbar-h);
        margin-inline: calc(var(--v160-mob-gutter) * -1);
        padding: var(--v160-space-2) var(--v160-mob-gutter);
        background: var(--v160-surface);
        border-block-end: 1px solid var(--v160-border);
    }
    .gab-qbar-filter,
    .gab-qbar-sort {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        gap: var(--v160-space-1);
        min-block-size: 36px;
        padding-inline: var(--v160-space-3);
        border: 1px solid var(--v160-border-strong);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        color: var(--v160-text);
        font-family: var(--v160-font-sans);
        font-size: var(--v160-fs-sm);
        font-weight: 600;
        white-space: nowrap;
        cursor: pointer;
    }
    .gab-qbar-filter i,
    .gab-qbar-sort > .bi-arrow-down-up { font-size: 14px; color: var(--v160-text-muted); }
    .gab-qbar-sort-caret { font-size: 10px; color: var(--v160-text-subtle); }
    .gab-qbar-badge {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-inline-size: 16px;
        block-size: 16px;
        padding-inline: 4px;
        margin-inline-start: 2px;
        border-radius: var(--v160-r-pill);
        background: var(--v160-accent);
        color: var(--v160-accent-contrast);
        font-variant-numeric: tabular-nums;
        font-size: 10px;
        font-weight: 700;
    }
    .gab-qbar-reset {
        flex: 0 0 auto;
        inline-size: 36px;
        block-size: 36px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        color: var(--v160-text-muted);
        font-size: 14px;
        cursor: pointer;
    }
    .gab-qbar-divider {
        flex: 0 0 auto;
        inline-size: 1px;
        block-size: 20px;
        background: var(--v160-border);
    }
    .gab-qbar-chips {
        flex: 1 1 auto;
        min-inline-size: 0;
        display: flex;
        gap: var(--v160-space-2);
        overflow-x: auto;
        scroll-snap-type: x proximity;
        padding-inline-end: var(--v160-space-1);
    }
    .gab-qchip {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        min-block-size: 34px;
        padding-inline: var(--v160-space-3);
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-pill);
        background: var(--v160-surface);
        color: var(--v160-text-muted);
        font-family: var(--v160-font-sans);
        font-size: var(--v160-fs-sm);
        font-weight: 600;
        white-space: nowrap;
        scroll-snap-align: start;
        cursor: pointer;
        transition: border-color var(--v160-dur-fast) var(--v160-ease),
                    background var(--v160-dur-fast) var(--v160-ease),
                    color var(--v160-dur-fast) var(--v160-ease);
    }
    .gab-qchip.is-on,
    .gab-qchip[aria-pressed="true"] {
        border-color: var(--v160-accent);
        background: var(--v160-accent-soft);
        color: var(--v160-accent-hover);
    }
    .gab-qbar-view {
        flex: 0 0 auto;
        display: inline-flex;
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-md);
        overflow: hidden;
    }
    .gab-qbar-view-btn {
        inline-size: 34px;
        block-size: 34px;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 0;
        background: var(--v160-surface);
        color: var(--v160-text-subtle);
        font-size: 15px;
        cursor: pointer;
    }
    .gab-qbar-view-btn.is-active,
    .gab-qbar-view-btn[aria-pressed="true"] {
        background: var(--v160-accent-soft);
        color: var(--v160-accent);
    }

    /* --- applied filter strip ---------------------------------------------------- */
    .gab-active-filters {
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        padding: var(--v160-space-2) var(--v160-mob-gutter);
        border-block-end: 1px solid var(--v160-border-subtle);
        overflow-x: auto;
    }
    .gab-active-filters-label { display: none; }
    .gab-af-actions { flex: 0 0 auto; display: inline-flex; gap: var(--v160-space-2); }
    .gab-af-save {
        display: inline-flex;
        align-items: center;
        gap: var(--v160-space-1);
        min-block-size: 32px;
        padding-inline: var(--v160-space-3);
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-pill);
        background: var(--v160-surface);
        color: var(--v160-text-muted);
        font-size: var(--v160-fs-xs);
        font-weight: 600;
        cursor: pointer;
    }
    .gab-af-save.is-saved {
        border-color: var(--v160-accent);
        background: var(--v160-accent-soft);
        color: var(--v160-accent-hover);
    }
    .gab-af-share {
        inline-size: 32px;
        block-size: 32px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-pill);
        background: var(--v160-surface);
        color: var(--v160-text-muted);
        font-size: 13px;
        cursor: pointer;
    }
}

@media (max-width: 640px) {

    /* --- single column -----------------------------------------------------------
     * The mobile card silhouette (Encar-style edge-to-edge divided rows) is owned by
     * 39-v160-public.css. Do NOT set `gap` here: 39 uses `gap: 0` plus a per-row
     * bottom hairline, and re-introducing a gap detaches those dividers into floating
     * lines. This block only adds what 39 does not cover. */
    .gab-cars-grid,
    .gab-cars-grid-3,
    .gab-reco-grid {
        grid-template-columns: minmax(0, 1fr);
        margin-inline: 0;
    }
    /* Legacy 20-mobile.css pulls the grid out of its gutter; v160 keeps real cards. */
    .gab-list-results .gab-cars-grid,
    .gab-list-results .gab-cars-grid-3 { margin-inline: 0; }

    /* Card chrome (row layout, hairline divider, no radius, no shadow) is defined once
     * in 39-v160-public.css at (0,2,0) specificity. 39's selector list covers
     * `.gab-cars-grid` and `.gab-cars-grid-3` only, so mirror it for `.gab-reco-grid`
     * here — same declarations, same specificity — and every rail renders identically. */
    .gab-reco-grid .gab-car-card {
        flex-direction: row;
        align-items: stretch;
        border: 0 !important;                                 /* defeats 20-mobile.css / 25-hicm-skin.css sticker chrome */
        border-block-end: 1px solid var(--v160-border) !important;
        border-radius: 0 !important;
        box-shadow: none !important;
        background: var(--v160-surface);
    }
    /* Press feedback is a background tint, not elevation — a flat row has no shadow to lift. */
    .gab-cars-grid .gab-car-card,
    .gab-cars-grid-3 .gab-car-card,
    .gab-reco-grid .gab-car-card {
        transition: background-color var(--v160-dur-fast) var(--v160-ease);
    }
    .gab-cars-grid .gab-car-card:active,
    .gab-cars-grid-3 .gab-car-card:active,
    .gab-reco-grid .gab-car-card:active {
        background: var(--v160-surface-2);
    }

    /* Thumbnail rail hidden; the 132px 4:3 gallery column comes from 39. */
    .gab-ccg-thumbs { display: none; }
    .gab-ccg-main {
        inline-size: 100%;
        min-inline-size: 0;
        min-block-size: 0;
    }
    .gab-ccg-main-img,
    .gab-car-card-image-placeholder {
        inline-size: 100%;
        block-size: 100%;
        object-fit: cover;
    }
    .gab-ccg-ribbon {
        font-size: var(--v160-fs-2xs);
        font-weight: 700;
        padding: 3px var(--v160-space-2);
        border-radius: var(--v160-r-xs);
    }
    .gab-ccg-meta { inset-block-end: var(--v160-space-2); inset-inline-end: var(--v160-space-2); }

    .gab-car-card-fav {
        inline-size: 40px;
        block-size: 40px;
        inset-block-start: var(--v160-space-2);
        inset-inline-end: var(--v160-space-2);
        inset-inline-start: auto;
        display: flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-pill);
        background: rgba(255, 255, 255, .92);
        color: var(--v160-text-muted);
        font-size: 17px;
        box-shadow: var(--v160-elev-2);
    }

    /* Card body */
    .gab-car-card-body {
        display: block;
        padding: var(--v160-space-3) var(--v160-space-4) var(--v160-space-4);
    }
    .gab-car-card-brand {
        font-size: var(--v160-fs-2xs);
        font-weight: 600;
        letter-spacing: .04em;
        color: var(--v160-text-subtle);
        text-transform: uppercase;
    }
    .gab-car-card-title {
        margin-block: 2px var(--v160-space-2);
        font-size: var(--v160-fs-lg);
        font-weight: 700;
        line-height: var(--v160-lh-tight);
        letter-spacing: var(--v160-track-tight);
        color: var(--v160-text);
    }
    .gab-car-card-specs {
        display: flex;
        flex-wrap: wrap;
        gap: var(--v160-space-2);
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-xs);
        color: var(--v160-text-muted);
    }
    .gab-car-card-location {
        margin-block-start: var(--v160-space-2);
        font-size: var(--v160-fs-xs);
        color: var(--v160-text-subtle);
    }

    /* Price row — the loudest thing in the card. */
    .gab-car-card-price-row {
        position: static;
        transform: none;
        display: flex;
        flex-direction: row;
        align-items: flex-end;
        justify-content: space-between;
        gap: var(--v160-space-2);
        margin-block-start: var(--v160-space-3);
        padding-block-start: var(--v160-space-3);
        border-block-start: 1px solid var(--v160-border-subtle);
        border-inline: 0;
    }
    .gab-car-card-price-value {
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-2xl);
        font-weight: 800;
        letter-spacing: var(--v160-track-tight);
        color: var(--v160-accent);
        unicode-bidi: isolate;
    }
    .gab-car-card-price-tag { font-size: var(--v160-fs-xs); color: var(--v160-text-subtle); }

    /* Section headers / hero padding */
    .gab-page-hero { padding: var(--v160-space-7) var(--v160-space-4); }
    .gab-reco-section { padding: var(--v160-space-4) var(--v160-mob-gutter) var(--v160-space-5); margin-block-end: var(--v160-space-4); }
    .gab-reco-title { font-size: var(--v160-fs-xl); }

    /* Infinite scroll replaces pagination inside the results column. */
    #gab-results-col .gab-pagination { display: none; }
    .gab-infinite { padding-block: var(--v160-space-1) var(--v160-space-3); }
    .gab-infinite-retry {
        display: block;
        margin: var(--v160-space-3) auto;
        min-block-size: var(--v160-tap);
        padding-inline: var(--v160-space-6);
        border: 1px solid var(--v160-border-strong);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        color: var(--v160-text);
        font-size: var(--v160-fs-md);
        font-weight: 600;
        cursor: pointer;
    }

    /* Skeleton cards match the real card silhouette. */
    .gab-skel-card {
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-xl);
        background: var(--v160-surface);
        overflow: hidden;
        margin-block-end: var(--v160-space-3);
    }
    .gab-skel-img { inline-size: 100%; aspect-ratio: 16 / 9; background: var(--v160-surface-3); }
    .gab-skel-body { padding: var(--v160-space-3) var(--v160-space-4); }
    .gab-skel-line {
        block-size: 12px;
        border-radius: var(--v160-r-xs);
        background: var(--v160-surface-3);
        margin-block-end: var(--v160-space-2);
    }
    .gab-skel-line:last-child { margin-block-end: 0; }
}


/* ==================================================================================
 * 11. CAR DETAIL
 * ----------------------------------------------------------------------------------
 * Gallery: the legacy markup is a single <img> plus prev/next. When a view is rewritten
 * as a swipeable rail, use this API — the CSS below drives it with no JS beyond dot
 * synchronisation:
 *
 *   <div class="v160-mob-gallery">
 *     <div class="v160-mob-gallery__rail">
 *       <figure class="v160-mob-gallery__slide"><img …></figure> …
 *     </div>
 *     <div class="v160-mob-gallery__dots" role="tablist">
 *       <button class="v160-mob-gallery__dot" aria-current="true" aria-label="1"></button> …
 *     </div>
 *     <span class="v160-mob-gallery__counter"><span class="v160-num">1</span> / 12</span>
 *   </div>
 *
 * Collapsible spec sections use native <details> so they work without JS:
 *   <details class="v160-mob-acc" open>
 *     <summary class="v160-mob-acc__sum">기본 정보<i class="bi bi-chevron-down"></i></summary>
 *     <div class="v160-mob-acc__body">…</div>
 *   </details>
 * ================================================================================== */

@media (max-width: 1024px) {

    .gab-detail-layout { display: block; }
    .gab-detail-main { inline-size: 100%; }
    .gab-detail-sidebar {
        position: static;
        inline-size: 100%;
        margin-block-start: var(--v160-space-5);
    }

    /* Detail tabs -> sticky horizontal rail under the header. */
    .gab-detail-tabs {
        position: sticky;
        inset-block-start: calc(var(--v160-mob-header-h) + var(--v160-mob-safe-t));
        z-index: var(--v160-mob-z-sticky);
        display: flex;
        flex-wrap: nowrap;
        gap: 0;
        overflow-x: auto;
        background: var(--v160-surface);
        border-block-end: 1px solid var(--v160-border);
    }
    .gab-detail-tab {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        min-block-size: var(--v160-tap);
        padding-inline: var(--v160-space-4);
        border: 0;
        border-block-end: 2px solid transparent;
        background: none;
        color: var(--v160-text-muted);
        font-family: var(--v160-font-sans);
        font-size: var(--v160-fs-md);
        font-weight: 600;
        white-space: nowrap;
        cursor: pointer;
    }
    .gab-detail-tab.is-active,
    .gab-detail-tab[aria-selected="true"] {
        color: var(--v160-accent);
        border-block-end-color: var(--v160-accent);
    }

    /* --- gallery (legacy hooks) --------------------------------------------------- */
    .gab-gallery-main,
    .gab-detail-gallery-main,
    .gab-detail-main-image {
        inline-size: 100%;
        aspect-ratio: 4 / 3;
        border-radius: 0;
        background: var(--v160-surface-3);
    }
    .gab-gallery-nav {
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        border: 0;
        border-radius: var(--v160-r-pill);
        background: rgba(255, 255, 255, .9);
        color: var(--v160-text);
        box-shadow: var(--v160-elev-2);
    }
    .gab-gallery-counter,
    .v160-mob-gallery__counter {
        position: absolute;
        inset-block-end: var(--v160-space-3);
        inset-inline-end: var(--v160-space-3);
        padding: 3px var(--v160-space-2);
        border-radius: var(--v160-r-pill);
        background: rgba(15, 23, 42, .68);
        color: var(--v160-text-inverse);
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-xs);
        font-weight: 600;
        unicode-bidi: isolate;
    }
    .gab-gallery-expand {
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        border: 0;
        border-radius: var(--v160-r-pill);
        background: rgba(15, 23, 42, .55);
        color: var(--v160-text-inverse);
    }
    /* Thumbnails become a snap rail. */
    .gab-gallery-thumbs {
        display: flex;
        flex-wrap: nowrap;
        gap: var(--v160-space-2);
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        padding: var(--v160-space-2) var(--v160-space-4);
    }
    .gab-gallery-thumbs::-webkit-scrollbar { display: none; }
    .gab-gallery-thumb {
        flex: 0 0 auto;
        inline-size: 68px;
        block-size: 50px;
        scroll-snap-align: start;
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-sm);
        overflow: hidden;
    }
    .gab-gallery-thumb.is-active { border-color: var(--v160-accent); box-shadow: var(--v160-ring); }

    /* --- gallery (new swipe API) -------------------------------------------------- */
    .v160-mob-gallery { position: relative; background: var(--v160-surface-3); }
    .v160-mob-gallery__rail {
        display: flex;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-inline: contain;
        scrollbar-width: none;
    }
    .v160-mob-gallery__rail::-webkit-scrollbar { display: none; }
    .v160-mob-gallery__slide {
        flex: 0 0 100%;
        inline-size: 100%;
        margin: 0;
        scroll-snap-align: center;
        scroll-snap-stop: always;
        aspect-ratio: 4 / 3;
    }
    .v160-mob-gallery__slide img {
        inline-size: 100%;
        block-size: 100%;
        object-fit: cover;
        display: block;
    }
    .v160-mob-gallery__dots {
        position: absolute;
        inset-block-end: var(--v160-space-3);
        inset-inline-start: 50%;
        transform: translateX(-50%);
        display: flex;
        align-items: center;
        gap: 6px;
        padding: 5px var(--v160-space-2);
        border-radius: var(--v160-r-pill);
        background: rgba(15, 23, 42, .38);
    }
    .v160-mob-gallery__dot {
        inline-size: 6px;
        block-size: 6px;
        padding: 0;
        border: 0;
        border-radius: var(--v160-r-pill);
        background: rgba(255, 255, 255, .55);
        cursor: pointer;
        transition: inline-size var(--v160-dur-fast) var(--v160-ease),
                    background var(--v160-dur-fast) var(--v160-ease);
    }
    .v160-mob-gallery__dot[aria-current="true"],
    .v160-mob-gallery__dot.is-active {
        inline-size: 16px;
        background: var(--v160-text-inverse);
    }

    /* --- collapsible spec sections ------------------------------------------------ */
    .v160-mob-acc {
        border-block-end: 1px solid var(--v160-border-subtle);
        background: var(--v160-surface);
    }
    .v160-mob-acc__sum {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--v160-space-2);
        min-block-size: 52px;
        padding-inline: var(--v160-space-4);
        font-size: var(--v160-fs-lg);
        font-weight: 700;
        letter-spacing: var(--v160-track-snug);
        color: var(--v160-text);
        cursor: pointer;
        list-style: none;
    }
    .v160-mob-acc__sum::-webkit-details-marker { display: none; }
    .v160-mob-acc__sum i {
        color: var(--v160-text-subtle);
        font-size: 13px;
        transition: transform var(--v160-dur) var(--v160-ease);
    }
    .v160-mob-acc[open] .v160-mob-acc__sum i { transform: rotate(180deg); }
    .v160-mob-acc__body { padding: 0 var(--v160-space-4) var(--v160-space-4); }

    /* Spec grid reflows to 2-up with tabular values. */
    .gab-spec-grid,
    .gab-keyspecs { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--v160-space-2); }
    .gab-spec-item,
    .gab-keyspec {
        padding: var(--v160-space-3);
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-lg);
        background: var(--v160-surface);
    }
    .gab-spec-item--wide { grid-column: 1 / -1; }
    .gab-spec-item-label,
    .gab-keyspec-l { font-size: var(--v160-fs-xs); color: var(--v160-text-subtle); }
    .gab-spec-item-value,
    .gab-keyspec-v {
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-md);
        font-weight: 600;
        color: var(--v160-text);
        unicode-bidi: isolate;
    }
    .gab-options-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

    /* --- sticky action bar (찜 / 비교 / 문의하기) ---------------------------------- */
    /* Legacy 20-mobile.css hides the tab bar on detail pages; v160 docks the action bar
     * directly above it so primary navigation is never lost. */
    body.gab-has-mbar .gab-tabbar { display: flex !important; } /* defeats 20-mobile.css `display:none !important` */
    body.gab-has-mbar {
        padding-block-end: calc(var(--v160-mob-tabbar-h) + var(--v160-mob-action-h) + var(--v160-mob-safe-b));
    }

    .gab-mbar,
    .v160-mob-actionbar {
        position: fixed;
        inset-inline: 0;
        inset-block-end: var(--v160-mob-tabbar-total);
        z-index: var(--v160-mob-z-action);
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        min-block-size: var(--v160-mob-action-h);
        padding: var(--v160-space-2) var(--v160-space-3);
        background: var(--v160-surface);
        border-block-start: 1px solid var(--v160-border);
        box-shadow: 0 -1px 2px rgba(15, 23, 42, .06);
    }
    .gab-mbar-price {
        flex: 0 0 auto;
        display: flex;
        flex-direction: column;
        justify-content: center;
        min-inline-size: 0;
        margin-inline-end: var(--v160-space-1);
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-lg);
        font-weight: 800;
        letter-spacing: var(--v160-track-tight);
        color: var(--v160-accent);
        unicode-bidi: isolate;
    }
    .gab-mbar-price small {
        font-size: var(--v160-fs-2xs);
        font-weight: 600;
        color: var(--v160-text-subtle);
        letter-spacing: 0;
    }
    .gab-mbar-btn {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--v160-space-2);
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        border: 1px solid var(--v160-border-strong);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        color: var(--v160-text-muted);
        font-family: var(--v160-font-sans);
        font-size: 18px;
        cursor: pointer;
    }
    /* car-detail.php 는 찜 상태를 .is-active 로 출력한다(1697행). 세 표기 모두 지원. */
    .gab-mbar-btn.is-on,
    .gab-mbar-btn.is-active,
    .gab-mbar-btn[aria-pressed="true"] {
        border-color: var(--v160-accent);
        background: var(--v160-accent-soft);
        color: var(--v160-accent);
    }
    .gab-mbar-btn--inq {
        flex: 1 1 auto;
        inline-size: auto;
        min-inline-size: 0;
        padding-inline: var(--v160-space-4);
        border-color: var(--v160-accent);
        /* Legacy 20-mobile.css paints this with the brand gradient wash; v160 uses a
         * flat accent fill. */
        background: var(--v160-accent) !important; /* defeats 20-mobile.css `background: var(--gab-grad-brand) !important` */
        color: var(--v160-accent-contrast);
        font-size: var(--v160-fs-lg);
        font-weight: 700;
        letter-spacing: var(--v160-track-snug);
    }
    .gab-mbar-btn--inq:active { background: var(--v160-accent-active) !important; } /* same legacy rule */

    /* Floating helpers must clear both bars. */
    .gab-scroll-top,
    .gab-fab,
    .gab-floating-cta,
    .gab-to-top {
        inset-block-end: calc(var(--v160-mob-tabbar-total) + var(--v160-space-3));
    }
    body.gab-has-mbar .gab-scroll-top,
    body.gab-has-mbar .gab-fab,
    body.gab-has-mbar .gab-floating-cta,
    body.gab-has-mbar .gab-to-top {
        inset-block-end: calc(var(--v160-mob-tabbar-total) + var(--v160-mob-action-h) + var(--v160-space-3));
    }
    .gab-toast-container { inset-block-end: calc(var(--v160-mob-tabbar-total) + var(--v160-space-3)); }
}


/* ==================================================================================
 * 12. MODALS AS SHEETS
 * ================================================================================== */

@media (max-width: 640px) {

    .gab-modal-backdrop {
        align-items: flex-end;
        padding: 0;
    }
    .gab-modal-backdrop .gab-modal,
    .gab-modal-box,
    .gab-modal-card {
        inline-size: 100%;
        max-inline-size: 100%;
        max-block-size: 92vh;
        overflow-y: auto;
        overscroll-behavior: contain;
        border: 0;
        border-start-start-radius: var(--v160-r-2xl);
        border-start-end-radius: var(--v160-r-2xl);
        border-end-start-radius: 0;
        border-end-end-radius: 0;
        box-shadow: var(--v160-elev-5);
        padding-block-end: calc(var(--v160-space-4) + var(--v160-mob-safe-b));
        animation: v160MobSheetUp var(--v160-dur-slow) var(--v160-ease-out);
    }
    @keyframes v160MobSheetUp {
        from { transform: translateY(100%); }
        to   { transform: translateY(0); }
    }
    .gab-modal-backdrop .gab-modal::before,
    .gab-modal-box::before {
        content: '';
        display: block;
        inline-size: 40px;
        block-size: 4px;
        margin: var(--v160-space-2) auto var(--v160-space-1);
        border-radius: var(--v160-r-pill);
        background: var(--v160-border-strong);
    }
    .gab-modal-x,
    .gab-modal-close {
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: var(--v160-text-muted);
        font-size: 18px;
    }
    .gab-modal-grid { grid-template-columns: minmax(0, 1fr); }
    .gab-modal-submit {
        inline-size: 100%;
        min-block-size: 48px;
        border-radius: var(--v160-r-md);
    }
}


/* ==================================================================================
 * 13. CONSOLE ON MOBILE  (admin / dealer / member back office)
 * ----------------------------------------------------------------------------------
 * Console pages render through layout/blank (body.gab-page-admin / -dealer / -member)
 * so there is no site header and no bottom tab bar. The dashboard supplies its own
 * top bar (.gab-dash-mbar) and off-canvas nav (.gab-dash-side + .gab-dash-nav-backdrop).
 * ================================================================================== */

/* --- 13a. off-canvas sidebar ------------------------------------------------------ */
@media (max-width: 1024px) {

    .gab-dash { grid-template-columns: minmax(0, 1fr); }

    .gab-dash-mbar {
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        position: sticky;
        inset-block-start: 0;
        z-index: var(--v160-mob-z-header);
        min-block-size: var(--v160-mob-header-h);
        padding-block: var(--v160-mob-safe-t) 0;
        padding-inline: max(var(--v160-space-3), var(--v160-mob-safe-l))
                        max(var(--v160-space-3), var(--v160-mob-safe-r));
        background: var(--v160-surface);
        border-block-end: 1px solid var(--v160-border);
        color: var(--v160-text);
    }
    .gab-dash-burger,
    .gab-dash-mbar-home {
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: var(--v160-text);
        font-size: 20px;
        cursor: pointer;
        text-decoration: none;
    }
    .gab-dash-burger:active,
    .gab-dash-mbar-home:active { background: var(--v160-surface-3); }
    .gab-dash-mbar-title {
        flex: 1 1 auto;
        min-inline-size: 0;
        font-size: var(--v160-fs-lg);
        font-weight: 700;
        letter-spacing: var(--v160-track-tight);
        color: var(--v160-text);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .gab-dash-mbar-title .accent { color: var(--v160-accent); }

    .gab-dash-nav-backdrop {
        display: block;
        position: fixed;
        inset-block: 0;
        inset-inline: 0;
        z-index: calc(var(--v160-mob-z-drawer) - 1);
        background: var(--v160-surface-overlay);
        opacity: 0;
        visibility: hidden;
        transition: opacity var(--v160-dur) var(--v160-ease),
                    visibility var(--v160-dur) var(--v160-ease);
    }
    .gab-dash-nav-backdrop.is-open { opacity: 1; visibility: visible; }

    .gab-dash-side {
        position: fixed;
        inset-block: 0;
        inset-inline-start: 0;
        z-index: var(--v160-mob-z-drawer);
        display: flex;
        flex-direction: column;
        inline-size: 288px;
        max-inline-size: 86vw;
        block-size: 100%;
        background: var(--v160-surface);
        border-inline-end: 1px solid var(--v160-border);
        box-shadow: var(--v160-elev-5);
        transform: translateX(-100%);
        transition: transform var(--v160-dur-slow) var(--v160-ease);
        padding-block-start: var(--v160-mob-safe-t);
        padding-block-end: var(--v160-mob-safe-b);
        overscroll-behavior: contain;
    }
    .gab-dash-side.is-open { transform: translateX(0); }

    .gab-dash-close {
        display: inline-flex;
        position: absolute;
        inset-block-start: calc(var(--v160-mob-safe-t) + var(--v160-space-2));
        inset-inline-end: var(--v160-space-2);
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: var(--v160-text-muted);
        font-size: 18px;
        cursor: pointer;
    }
    .gab-dash-brand {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        min-block-size: var(--v160-mob-header-h);
        padding-inline: var(--v160-space-4) calc(var(--v160-tap) + var(--v160-space-2));
        border-block-end: 1px solid var(--v160-border);
        text-decoration: none;
    }
    .gab-dash-brand-icon { inline-size: 32px; block-size: 32px; flex: 0 0 auto; }
    .gab-dash-brand-name {
        display: block;
        font-size: var(--v160-fs-lg);
        font-weight: 700;
        color: var(--v160-text);
    }
    .gab-dash-brand-name .accent { color: var(--v160-accent); }
    .gab-dash-brand-role { display: block; font-size: var(--v160-fs-xs); color: var(--v160-text-subtle); }

    .gab-dash-nav {
        flex: 1 1 auto;
        min-block-size: 0;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior: contain;
        padding-block: var(--v160-space-2);
    }
    .gab-dash-nav-label {
        padding: var(--v160-space-3) var(--v160-space-4) var(--v160-space-1);
        font-size: var(--v160-fs-2xs);
        font-weight: 700;
        letter-spacing: .06em;
        text-transform: uppercase;
        color: var(--v160-text-subtle);
    }
    .gab-dash-nav-item {
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        min-block-size: var(--v160-tap);
        padding: var(--v160-space-2) var(--v160-space-4);
        color: var(--v160-text-muted);
        font-size: var(--v160-fs-md);
        font-weight: 600;
        text-decoration: none;
    }
    .gab-dash-nav-item i { inline-size: 20px; flex: 0 0 auto; text-align: center; font-size: 16px; }
    .gab-dash-nav-item:active { background: var(--v160-surface-3); }
    .gab-dash-nav-item.is-active,
    .gab-dash-nav-item[aria-current="page"] {
        color: var(--v160-accent);
        background: var(--v160-accent-soft);
        box-shadow: inset 3px 0 0 0 var(--v160-accent);
    }
    .gab-dash-nav-badge {
        margin-inline-start: auto;
        min-inline-size: 20px;
        padding-inline: 6px;
        border-radius: var(--v160-r-pill);
        background: var(--v160-danger);
        color: var(--v160-text-inverse);
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-2xs);
        font-weight: 700;
        line-height: 20px;
        text-align: center;
    }

    .gab-dash-user {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        gap: var(--v160-space-3);
        padding: var(--v160-space-3) var(--v160-space-4)
                 calc(var(--v160-space-3) + var(--v160-mob-safe-b));
        border-block-start: 1px solid var(--v160-border);
        background: var(--v160-surface-2);
    }
    .gab-dash-user-info { flex: 1 1 auto; min-inline-size: 0; }
    .gab-dash-user-name {
        font-size: var(--v160-fs-md);
        font-weight: 600;
        color: var(--v160-text);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .gab-dash-user-role { font-size: var(--v160-fs-xs); color: var(--v160-text-subtle); }
    .gab-dash-user-logout {
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        color: var(--v160-text-muted);
        font-size: 16px;
        text-decoration: none;
    }

    .gab-dash-main,
    .gab-dpro {
        padding-block: var(--v160-space-4) var(--v160-space-9);
        padding-inline: max(var(--v160-space-4), var(--v160-mob-safe-l))
                        max(var(--v160-space-4), var(--v160-mob-safe-r));
    }
    .gab-dash-header {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: var(--v160-space-3);
    }
    .gab-dash-title { font-size: var(--v160-fs-2xl); letter-spacing: var(--v160-track-tight); }
    .gab-dash-subtitle { font-size: var(--v160-fs-sm); color: var(--v160-text-muted); }
    .gab-dash-header-actions { display: flex; flex-wrap: wrap; gap: var(--v160-space-2); }
    .gab-dash-header-actions .v160-btn,
    .gab-dash-hbtn { flex: 1 1 auto; min-block-size: var(--v160-tap); justify-content: center; }
}

/* --- 13b. KPI cards --------------------------------------------------------------- */
@media (max-width: 640px) {

    .v160-kpi-grid,
    .gab-dash-stats,
    .gab-astat-row,
    .gab-astat-row--6,
    .gab-kpi-row {
        display: grid;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--v160-space-2);
    }
    .gab-dash-stat,
    .gab-astat {
        display: flex;
        flex-direction: column;
        gap: 2px;
        padding: var(--v160-space-3);
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-xl);
        background: var(--v160-surface);
        box-shadow: var(--v160-elev-1);
    }
    .gab-dash-stat-icon,
    .gab-astat-icon { display: none; }
    .gab-dash-stat-label,
    .gab-astat-lbl {
        order: -1;
        font-size: var(--v160-fs-xs);
        font-weight: 600;
        color: var(--v160-text-muted);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .gab-dash-stat-value,
    .gab-astat-val,
    .gab-astat-value {
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-2xl);
        font-weight: 700;
        letter-spacing: var(--v160-track-tight);
        color: var(--v160-text);
        unicode-bidi: isolate;
    }
    .gab-dms-grid2 { grid-template-columns: minmax(0, 1fr); }
}

/* ----------------------------------------------------------------------------------
 * 13c. STACKED DATA TABLES  —  REQUIRED MARKUP CONTRACT FOR VIEW AUTHORS
 * ----------------------------------------------------------------------------------
 * At <=640px a wide admin table is unusable as a table. Opt a table into the stacked
 * card presentation by putting `v160-mob-stack` on the SCROLL WRAPPER, and give every
 * <td> a `data-label` matching its column header:
 *
 *   <div class="v160-table-wrap v160-mob-stack">
 *     <table class="v160-table v160-table--hover">
 *       <thead>
 *         <tr><th>회원명</th><th>유형</th><th class="is-numeric">등록 매물</th><th class="is-actions">관리</th></tr>
 *       </thead>
 *       <tbody>
 *         <tr>
 *           <td data-label="회원명"    class="is-primary">홍길동</td>
 *           <td data-label="유형">딜러</td>
 *           <td data-label="등록 매물"  class="is-numeric">12</td>
 *           <td data-label="관리"      class="is-actions"> … </td>
 *         </tr>
 *       </tbody>
 *     </table>
 *   </div>
 *
 * RULES
 *   - `data-label` MUST be the translated column header (all 5 languages), because it
 *     replaces <thead>, which is hidden in this mode.
 *   - Add `class="is-primary"` to the one cell that acts as the card title; it renders
 *     full width, bold, without a label.
 *   - Add `class="is-actions"` to the button cell; it renders as a full-width footer row.
 *   - Add `class="v160-mob-hide-cell"` to any cell that is noise on a phone.
 *   - A cell with no `data-label` still renders correctly — it simply shows no label.
 *   - Tables NOT carrying `v160-mob-stack` keep the default horizontal scroll from
 *     `.v160-table-wrap`, which remains a legitimate choice for narrow numeric tables.
 * ---------------------------------------------------------------------------------- */
@media (max-width: 640px) {

    .v160-mob-stack {
        overflow-x: visible;
        border: 0;
        border-radius: 0;
        background: transparent;
    }
    .v160-mob-stack .v160-table,
    .v160-mob-stack .gab-atable,
    .v160-mob-stack table {
        display: block;
        inline-size: 100%;
        min-inline-size: 0;
        border-collapse: separate;
        background: transparent;
    }
    .v160-mob-stack thead {
        position: absolute;
        inline-size: 1px;
        block-size: 1px;
        padding: 0;
        margin: -1px;
        overflow: hidden;
        clip: rect(0 0 0 0);
        clip-path: inset(50%);
        white-space: nowrap;
        border: 0;
    }
    .v160-mob-stack tbody { display: block; }
    .v160-mob-stack tbody tr {
        display: block;
        margin-block-end: var(--v160-space-2);
        padding: var(--v160-space-1) var(--v160-space-3);
        border: 1px solid var(--v160-border);
        border-radius: var(--v160-r-xl);
        background: var(--v160-surface);
        box-shadow: var(--v160-elev-1);
    }
    .v160-mob-stack tbody tr.is-selected {
        border-color: var(--v160-accent);
        background: var(--v160-accent-soft);
    }
    .v160-mob-stack tbody td {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--v160-space-3);
        inline-size: auto;
        min-block-size: 40px;
        padding: var(--v160-space-2) 0;
        border: 0;
        border-block-end: 1px solid var(--v160-border-subtle);
        text-align: start;
        font-size: var(--v160-fs-md);
        color: var(--v160-text);
        white-space: normal;
    }
    .v160-mob-stack tbody td:last-child { border-block-end: 0; }
    .v160-mob-stack tbody td::before {
        content: attr(data-label);
        flex: 0 0 auto;
        max-inline-size: 45%;
        font-size: var(--v160-fs-xs);
        font-weight: 600;
        color: var(--v160-text-subtle);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    /* Card title row */
    .v160-mob-stack tbody td.is-primary {
        display: block;
        padding-block: var(--v160-space-3) var(--v160-space-2);
        font-size: var(--v160-fs-lg);
        font-weight: 700;
        letter-spacing: var(--v160-track-tight);
    }
    .v160-mob-stack tbody td.is-primary::before { display: none; }
    /* Numeric cells keep tabular figures and isolate from RTL text flow. */
    .v160-mob-stack tbody td.is-numeric {
        font-variant-numeric: tabular-nums;
        text-align: end;
        unicode-bidi: isolate;
    }
    .v160-mob-stack tbody td.is-center { justify-content: space-between; }
    /* Action cell becomes a full-width footer */
    .v160-mob-stack tbody td.is-actions {
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-start;
        gap: var(--v160-space-2);
        padding-block: var(--v160-space-3);
        border-block-end: 0;
    }
    .v160-mob-stack tbody td.is-actions::before { display: none; }
    .v160-mob-stack tbody td.is-actions .v160-btn,
    .v160-mob-stack tbody td.is-actions button,
    .v160-mob-stack tbody td.is-actions a {
        flex: 1 1 auto;
        min-block-size: var(--v160-tap);
        justify-content: center;
    }
    /* Author-controlled noise removal */
    .v160-mob-stack tbody td.v160-mob-hide-cell { display: none; }
    /* In-cell helpers keep working */
    .v160-mob-stack .v160-table__main { font-weight: 700; }
    .v160-mob-stack .v160-table__sub { font-size: var(--v160-fs-xs); color: var(--v160-text-subtle); }

    /* Tables that did NOT opt in keep horizontal scroll, but get a clear affordance. */
    .v160-table-wrap,
    .gab-atable-wrap,
    .gab-table-wrap {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-inline: contain;
    }
    .gab-atable { min-inline-size: 640px; }
}

/* --- 13d. console toolbars / filter bars ------------------------------------------ */
@media (max-width: 640px) {

    /* A console filter bar collapses to: [search input] [필터 버튼]. The button is
     * expected to open a .v160-mob-sheet (section 7). */
    .v160-toolbar,
    .gab-afilter {
        flex-wrap: wrap;
        gap: var(--v160-space-2);
        padding-inline: 0;
    }
    .v160-toolbar__lead,
    .v160-toolbar__main,
    .v160-toolbar__end { inline-size: 100%; }
    .v160-toolbar__end { justify-content: stretch; }
    .v160-toolbar__end .v160-btn { flex: 1 1 auto; }

    .v160-mob-filterbar {
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        position: sticky;
        inset-block-start: calc(var(--v160-mob-header-h) + var(--v160-mob-safe-t));
        z-index: var(--v160-mob-z-sticky);
        margin-inline: calc(var(--v160-space-4) * -1);
        padding: var(--v160-space-2) var(--v160-space-4);
        background: var(--v160-surface);
        border-block-end: 1px solid var(--v160-border);
    }
    .v160-mob-filterbar .v160-input,
    .v160-mob-filterbar .v160-input-group { flex: 1 1 auto; min-inline-size: 0; }
    .v160-mob-filterbar .v160-btn { flex: 0 0 auto; }

    /* Console tabs scroll instead of wrapping. */
    .gab-dtabs {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
    }

    /* Pagination compacts. */
    .v160-pagination,
    .gab-pagination { flex-wrap: wrap; justify-content: center; gap: var(--v160-space-1); }
    .gab-pagination a,
    .gab-pagination button {
        min-inline-size: var(--v160-tap);
        min-block-size: var(--v160-tap);
    }
    .v160-pagination__summary { inline-size: 100%; text-align: center; }
}

/* --- 13e. bulk action dock -------------------------------------------------------- */
@media (max-width: 640px) {

    .gab-abulk,
    .v160-mob-bulkbar {
        position: fixed;
        inset-inline: 0;
        inset-block-end: 0;
        z-index: var(--v160-mob-z-action);
        display: flex;
        align-items: center;
        gap: var(--v160-space-2);
        min-block-size: var(--v160-mob-action-h);
        padding: var(--v160-space-2) var(--v160-space-4)
                 calc(var(--v160-space-2) + var(--v160-mob-safe-b));
        background: var(--v160-surface-dark);
        border-block-start: 1px solid var(--v160-border-inverse);
        box-shadow: var(--v160-elev-4);
    }
    .gab-abulk-count,
    .v160-mob-bulkbar__count {
        flex: 0 0 auto;
        font-variant-numeric: tabular-nums;
        font-size: var(--v160-fs-sm);
        font-weight: 700;
        color: var(--v160-text-inverse);
        unicode-bidi: isolate;
    }
    .gab-abulk-actions,
    .v160-mob-bulkbar__actions {
        flex: 1 1 auto;
        min-inline-size: 0;
        display: flex;
        gap: var(--v160-space-2);
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
    }
    .gab-abulk-actions::-webkit-scrollbar,
    .v160-mob-bulkbar__actions::-webkit-scrollbar { display: none; }
    .gab-abulk-btn {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: var(--v160-space-1);
        min-block-size: 38px;
        padding-inline: var(--v160-space-3);
        border: 1px solid var(--v160-border-inverse);
        border-radius: var(--v160-r-md);
        background: rgba(255, 255, 255, .08);
        color: var(--v160-text-inverse);
        font-family: var(--v160-font-sans);
        font-size: var(--v160-fs-sm);
        font-weight: 600;
        white-space: nowrap;
        cursor: pointer;
    }
    .gab-abulk-btn--warn {
        border-color: var(--v160-danger);
        background: var(--v160-danger);
        color: var(--v160-text-inverse);
    }
    .gab-abulk-clear {
        flex: 0 0 auto;
        inline-size: var(--v160-tap);
        block-size: var(--v160-tap);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: var(--v160-r-md);
        background: transparent;
        color: rgba(255, 255, 255, .7);
        font-size: 16px;
        cursor: pointer;
    }

    /* Reserve space so the last table card is never covered by the dock. The script
     * that shows the bulk bar must also toggle `v160-mob-has-bulkbar` on <body>. */
    body.v160-mob-has-bulkbar .gab-dash-main,
    body.v160-mob-has-bulkbar .gab-dpro {
        padding-block-end: calc(var(--v160-mob-action-total) + var(--v160-space-4));
    }
}


/* ==================================================================================
 * 14. FORMS ON TOUCH
 * ----------------------------------------------------------------------------------
 * 16px inputs (below that iOS zooms the viewport on focus), 44px targets, full-width
 * primary buttons. View authors should still set the right `inputmode`/`autocomplete`:
 *   phone   -> inputmode="tel"      autocomplete="tel"
 *   price   -> inputmode="numeric"  pattern="[0-9]*"
 *   mileage -> inputmode="numeric"
 *   email   -> inputmode="email"    autocomplete="email"
 *   search  -> inputmode="search"   enterkeyhint="search"
 * ================================================================================== */

@media (max-width: 640px) {

    input[type="text"],
    input[type="email"],
    input[type="tel"],
    input[type="url"],
    input[type="password"],
    input[type="number"],
    input[type="search"],
    input[type="date"],
    select,
    textarea,
    .gab-field__input,
    .gab-modal-in,
    .gab-modal-input {
        font-size: 16px; /* iOS focus-zoom guard */
        min-block-size: var(--v160-tap);
    }
    textarea { min-block-size: 96px; }

    /* Native pickers get room for the finger. */
    select { padding-inline-end: var(--v160-space-8); }

    .v160-field + .v160-field { margin-block-start: var(--v160-space-4); }
    .v160-field__label { font-size: var(--v160-fs-sm); }

    /* Checkbox / radio rows are full-width tap targets. */
    .v160-check-row,
    .gab-filter-option,
    .gab-filter-checkbox { min-block-size: var(--v160-tap); }

    /* Form footers dock their primary action full width. Views that need this on a
     * non-card container should add .v160-mob-actions to the wrapper. */
    .v160-card__foot,
    .v160-mob-actions {
        display: flex;
        flex-wrap: wrap;
        gap: var(--v160-space-2);
    }
    .v160-card__foot .v160-btn,
    .v160-mob-actions .v160-btn { flex: 1 1 100%; min-block-size: 48px; justify-content: center; }

    /* A form's sticky submit bar, when a view opts in. */
    .v160-mob-formbar {
        position: sticky;
        inset-block-end: 0;
        z-index: var(--v160-mob-z-sticky);
        display: flex;
        gap: var(--v160-space-2);
        margin-inline: calc(var(--v160-space-4) * -1);
        padding: var(--v160-space-3) var(--v160-space-4)
                 calc(var(--v160-space-3) + var(--v160-mob-safe-b));
        background: var(--v160-surface);
        border-block-start: 1px solid var(--v160-border);
        box-shadow: 0 -1px 2px rgba(15, 23, 42, .06);
    }
    .v160-mob-formbar .v160-btn { flex: 1 1 auto; min-block-size: 48px; }

    /* Upload grids */
    .gab-img-upload { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--v160-space-2); }
    .gab-form-grid,
    .gab-form-grid--2,
    .v160-fieldset--2,
    .v160-fieldset--3 { grid-template-columns: minmax(0, 1fr); }
}


/* ==================================================================================
 * 15. TABLET PASS (641–1024px)
 * ----------------------------------------------------------------------------------
 * Between phone and desktop the site keeps app navigation but regains two columns.
 * ================================================================================== */

@media (min-width: 641px) and (max-width: 1024px) {

    .gab-cars-grid,
    .gab-cars-grid-3,
    .gab-reco-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--v160-space-4); }

    .gab-dash-stats,
    .gab-astat-row,
    .v160-kpi-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }

    /* Filter sheet is comfortable as an inline-end panel rather than full screen.
     * The three !important flags below exist only for the 641–768px sliver where
     * 20-mobile.css still forces width/max-width/left with !important. */
    .gab-filter-sidebar {
        inline-size: 420px !important;      /* defeats 20-mobile.css `width: 100% !important` */
        max-inline-size: 92vw !important;   /* defeats 20-mobile.css `max-width: 100% !important` */
        inset-inline-start: auto !important;/* defeats 20-mobile.css `left: 0 !important` */
        border-inline-start: 1px solid var(--v160-border);
        box-shadow: var(--v160-elev-5);
        transform: translateX(100%);
    }
    .gab-filter-sidebar.is-open { transform: translateX(0); }
    .gab-filter-sheet-foot {
        inline-size: 420px;
        max-inline-size: 92vw;
        inset-inline-start: auto;
    }

    /* Header keeps the wordmark and a real search field at tablet width. */
    .gab-main-header .gab-logo-text { display: block; }
    .gab-header-search {
        flex: 1 1 auto;
        inline-size: auto;
        min-inline-size: 0;
        max-inline-size: 420px;
        margin-inline: auto;
    }
    .gab-header-search-form {
        inline-size: 100%;
        block-size: var(--v160-control-h);
        padding-inline: var(--v160-space-3) var(--v160-space-1);
        border: 1px solid var(--v160-border-strong);
        border-radius: var(--v160-r-md);
        background: var(--v160-surface);
        overflow: visible;
    }
    .gab-header-search-input {
        position: static;
        inline-size: 100%;
        block-size: 100%;
        color: var(--v160-text);
        cursor: text;
    }
    .gab-header-search-input::placeholder { color: var(--v160-text-subtle); }
    .gab-header-search-btn {
        position: static;
        inline-size: 32px;
        block-size: 32px;
        color: var(--v160-text-muted);
        pointer-events: auto;
    }
    .gab-header-cta { display: flex; gap: var(--v160-space-2); }
    .gab-header-cta .gab-btn-primary { display: inline-flex; }

    .gab-spec-grid,
    .gab-keyspecs,
    .gab-options-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* ==================================================================================
 * 16. LANDSCAPE + SHORT-VIEWPORT GUARDS
 * ----------------------------------------------------------------------------------
 * Fixed chrome must not eat a short viewport (landscape phone, split view, on-screen
 * keyboard raised). Below 560px of height the tab bar yields to the page.
 * ================================================================================== */

@media (max-width: 1024px) and (max-height: 560px) {

    /* On a detail page the action bar is the priority; the tab bar steps aside. */
    body.gab-has-mbar .gab-tabbar { display: none !important; } /* restores 20-mobile.css behaviour on short viewports */
    body.gab-has-mbar { padding-block-end: var(--v160-mob-action-total); }
    .gab-mbar,
    .v160-mob-actionbar { inset-block-end: 0; }
    body.gab-has-mbar .gab-scroll-top,
    body.gab-has-mbar .gab-fab,
    body.gab-has-mbar .gab-floating-cta,
    body.gab-has-mbar .gab-to-top {
        inset-block-end: calc(var(--v160-mob-action-total) + var(--v160-space-3));
    }

    /* Sheets take the whole viewport — 88vh of 400px is not usable. */
    .v160-mob-sheet { max-block-size: 100%; }
    .gab-sort-sheet { max-block-size: 100%; overflow-y: auto; }

    /* Search overlay body recalculates against the shorter bar. */
    .gab-msearch-body,
    .v160-mob-search__body { block-size: calc(100% - var(--v160-mob-header-h)); }
}

@media (max-width: 1024px) and (orientation: landscape) and (max-height: 480px) {

    /* Slimmer chrome so content still gets a usable band. */
    :root {
        --v160-mob-header-h: 48px;
        --v160-mob-tabbar-h: 48px;
        --v160-mob-action-h: 52px;
        --v160-mob-subbar-h: 46px;
    }
    .gab-tabbar-label,
    .v160-mob-tabbar__label { display: none; }
    .gab-tabbar-cta-btn,
    .v160-mob-tabbar__cta { inline-size: 40px; block-size: 40px; margin-block-start: -14px; font-size: 19px; }
    .gab-page-hero { padding-block: var(--v160-space-5); }

    /* Two-up cards use the extra width. */
    .gab-cars-grid,
    .gab-cars-grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .gab-gallery-main,
    .v160-mob-gallery__slide { aspect-ratio: 16 / 9; }
}


/* ==================================================================================
 * 17. REDUCED MOTION
 * ----------------------------------------------------------------------------------
 * Layer 38 already ships a global prefers-reduced-motion block; this only covers the
 * transforms introduced above, which must still change state instantly.
 * ================================================================================== */

@media (prefers-reduced-motion: reduce) {

    .gab-drawer,
    .v160-mob-drawer,
    .gab-dash-side,
    .gab-filter-sidebar,
    .gab-sort-sheet,
    .v160-mob-sheet,
    .gab-msearch,
    .v160-mob-search,
    .gab-site-header { transition: none; }

    .gab-modal-backdrop .gab-modal,
    .gab-modal-box,
    .gab-modal-card { animation: none; }

    .gab-msearch,
    .v160-mob-search { transform: none; }

    .v160-mob-gallery__rail,
    .gab-gallery-thumbs,
    .gab-qbar-chips { scroll-behavior: auto; }
}


/* ==================================================================================
 * 18. RTL CORRECTIONS
 * ----------------------------------------------------------------------------------
 * Everything above uses logical properties. These rules cover only what logical
 * properties cannot express: translateX direction, absolute 50% offsets, and shadow
 * x-offsets. There is no separate RTL stylesheet.
 * ================================================================================== */

@media (max-width: 1024px) {

    [dir="rtl"] .gab-drawer,
    [dir="rtl"] .v160-mob-drawer,
    [dir="rtl"] .gab-dash-side { transform: translateX(100%); box-shadow: var(--v160-elev-5); }
    [dir="rtl"] .gab-drawer.is-open,
    [dir="rtl"] .v160-mob-drawer.is-open,
    [dir="rtl"] .gab-dash-side.is-open { transform: translateX(0); }

    [dir="rtl"] .gab-tabbar-badge,
    [dir="rtl"] .v160-mob-tabbar__badge {
        inset-inline-start: auto;
        inset-inline-end: 50%;
        margin-inline-start: 0;
        margin-inline-end: 6px;
    }

    [dir="rtl"] .v160-mob-gallery__dots { transform: translateX(50%); }

    /* Mirrored glyphs that carry direction meaning. */
    [dir="rtl"] .gab-msearch-back .bi-arrow-left,
    [dir="rtl"] .gab-qbar-sort-caret,
    [dir="rtl"] .gab-gallery-nav i { transform: scaleX(-1); }
}

@media (min-width: 641px) and (max-width: 1024px) {
    /* Tablet filter panel slides in from the inline-end edge in both directions. */
    [dir="rtl"] .gab-filter-sidebar { transform: translateX(-100%); }
    [dir="rtl"] .gab-filter-sidebar.is-open { transform: translateX(0); }
}


/* ==================================================================================
 * 19. DESKTOP RESET
 * ----------------------------------------------------------------------------------
 * Nothing in this layer may leak above 1024px.
 * ================================================================================== */

@media (min-width: 1025px) {

    .gab-tabbar,
    .v160-mob-tabbar,
    .gab-msearch,
    .v160-mob-search,
    .v160-mob-sheet,
    .v160-mob-sheet-backdrop,
    .v160-mob-actionbar,
    .v160-mob-bulkbar,
    .v160-mob-filterbar,
    .v160-mob-formbar,
    .v160-mob-only { display: none; }

    .v160-mob-hide { display: revert; }

    /* Stacked tables are a phone-only presentation. */
    .v160-mob-stack { overflow-x: auto; }
}
