/*
 * AlienTech vehicles — Round F overrides. Loaded AFTER the existing
 * alientech-overrides.css, which is in turn loaded after the vendored
 * attnvl.css. Rules here are scoped to .attnvl-archive / .attnvl-landing
 * to avoid leaking outside the plugin's UI surface.
 *
 * Sections:
 *   1. CSS variables (pill background, transmission pill colour)
 *   2. F3: tool pill restyle (logo + label, light-grey bg)
 *   3. F4: transmission pill in version cell
 *   4. F5: toolbar Row A / Row B layout + Reset button
 *   5. F6: mobile search icon button + full-bleed modal animation
 */

/* ---------------------------------------------------------------------
 * 0. Elementor kit isolation.
 *
 *    The router enqueues Elementor's per-kit stylesheet wrapped in
 *    `@layer elementor-kit { … }` (see AT_Vehicle_Router::layer_elementor_kit_css).
 *    Because layered author rules ALWAYS lose to unlayered author rules
 *    (regardless of specificity), every existing `.attnvl-*` selector in
 *    attnvl.css and these overrides automatically wins over the kit's
 *    blanket `.elementor-kit-{id} button|a|h1|input[type=submit]` rules.
 *    The kit's `--e-global-*` custom properties are still set on <body>,
 *    so the Elementor header/footer widgets continue to read them via
 *    var(...) and look identical to the rest of the site.
 *
 *    Two thin resets remain for raw <a>/<h1> elements that have no
 *    .attnvl-* class to win on their own — without these, the layered
 *    kit rule still beats the user-agent default.
 * ------------------------------------------------------------------- */
.attnvl a:not([class*="attnvl-"]) {
    color: inherit;
    text-decoration: none;
}
.attnvl h1:not([class*="attnvl-"]) {
    color: inherit;
}

/* ---------------------------------------------------------------------
 * 1. CSS variables for override-scoped colours. Defined here, NEVER in
 *    the vendored attnvl.css.
 * ------------------------------------------------------------------- */
:root {
    --attnvl-pill-bg: #f3f4f6;
    --attnvl-pill-fg: #1f2937;
    --attnvl-pill-transmission-bg: #e0f2fe;
    --attnvl-pill-transmission-fg: #1f2937;
}

/* Tooltip bubbles use absolute positioning relative to their trigger and
 * `max-width: min(280px, 80vw)`. On mobile, a trigger sitting near the
 * viewport edge lets the bubble extend past the page edge, which causes
 * a horizontal page scroll. Clip horizontal overflow at the archive root
 * so the page can't scroll sideways. `clip` (vs `hidden`) avoids creating
 * a scroll container, so position: sticky on the table thead and absolute
 * tooltip/dropdown positioning keep working as before. */
.attnvl-archive {
    overflow-x: clip;
}

/* ---------------------------------------------------------------------
 * 2. F3 — Tool pill restyle. Replace the upstream yellow text-only
 *    pill with a light-grey bg, mini-logo on the left, name on the
 *    right, vertically centred.
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px 4px 6px;
    background-color: var(--attnvl-pill-bg);
    color: var(--attnvl-pill-fg);
    border: none;
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: 0.01em;
    white-space: nowrap;
    vertical-align: middle;
}

.attnvl-archive .attnvl-pill__logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 18px;
    height: 18px;
}

.attnvl-archive .attnvl-pill__logo svg {
    width: 100%;
    height: 100%;
    display: block;
}

.attnvl-archive .attnvl-pill__label {
    display: inline-block;
    line-height: 1;
}

/* Pills row spacing */
.attnvl-archive .attnvl-pills {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* ---------------------------------------------------------------------
 * 3. F4 — Transmission pill in the Version cell. Smaller than the tool
 *    pills, light-blue bg so it reads as secondary info, sits BELOW
 *    the version text on desktop and INLINE on mobile (in the
 *    mobile-card paragraph).
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-pill--transmission {
    background-color: #919191;
    color: var(--attnvl-pill-transmission-fg);
    border-color: #919191;
    font-size: 0.65rem;
    text-transform: capitalize;
    padding: 2px 8px;
}

.attnvl-archive .attnvl-version-cell {
    /* Stack the raw version + transmission pill on desktop. */
    line-height: 1.35;
}

.attnvl-archive .attnvl-version-cell .attnvl-version-text {
    display: block;
}

.attnvl-archive .attnvl-version-cell .attnvl-pill--transmission {
    margin-top: 4px;
}

/* Round-F follow-up: split the transmission pill into TWO segments so
 * the eye reads speed (6-Speed) + type (Automatic) as distinct. The
 * outer pill keeps its rounded shell; segments share that shell with
 * a divider. The type segment carries a data-type slug we colour-code
 * (auto = blue, manual = green, dual-clutch = purple, cvt = amber,
 * auto-manual = teal). When there's no speed (DSG / CVT / MTA / etc.)
 * only the type segment renders.
 */
.attnvl-archive .attnvl-pill--transmission {
    /* Segments butt against each other inside the same pill shell. */
    padding: 0;
    overflow: hidden;
    gap: 0;
}

.attnvl-archive .attnvl-pill__speed,
.attnvl-archive .attnvl-pill__trans-type {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    line-height: 1.2;
}

.attnvl-archive .attnvl-pill__speed {
    background-color: #e5e7eb;
    color: #374151;
    font-weight: 600;
}

.attnvl-archive .attnvl-pill__trans-type {
    /* Default — automatic-style blue tint. Overridden per data-type. */
    background-color: var(--attnvl-pill-transmission-bg);
    color: var(--attnvl-pill-transmission-fg);
    font-weight: 600;
}

.attnvl-archive .attnvl-pill__trans-type[data-type="automatic"] {
    background-color: #dbeafe;
    color: #1e3a8a;
}

.attnvl-archive .attnvl-pill__trans-type[data-type="manual"] {
    background-color: #919191;
    color: #f9f9f9;
}

.attnvl-archive .attnvl-pill__trans-type[data-type="dual-clutch"] {
    background-color: #ede9fe;
    color: #5b21b6;
}

.attnvl-archive .attnvl-pill__trans-type[data-type="cvt"] {
    background-color: #fef3c7;
    color: #92400e;
}

.attnvl-archive .attnvl-pill__trans-type[data-type="auto-manual"] {
    background-color: #ccfbf1;
    color: #115e59;
}

/* ---------------------------------------------------------------------
 * 6. Round-F follow-up — Custom div-based dropdowns. The native
 *    <select> remains in the DOM (visually hidden) for form submission
 *    and progressive enhancement; our JS mirrors its value. Initialised
 *    by the `attnvl-select--enhanced` flag added by JS, so non-JS
 *    users still see the plain select.
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-select-host {
    /* Wraps a native <select> + the enhanced trigger/panel. The native
     * select is hidden (sr-only) so screen readers fall through to the
     * combobox button. */
    position: relative;
    display: inline-flex;
    flex: 1 1 auto;
    min-width: 0;
}

.attnvl-archive .attnvl-select-host > select.attnvl-select {
    /* Visually hide but keep accessible to forms; JS syncs value on
     * pick + dispatches a `change` event so existing cascade JS still
     * runs unchanged. */
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
    pointer-events: none;
    opacity: 0;
}

.attnvl-archive .attnvl-select__trigger {
    display: inline-flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    width: 100%;
    min-width: 0;
    height: 44px;
    padding: 0 12px;
    background-color: #fff;
    color: var(--attnvl-text-dark, #1f2937);
    border: 1px solid var(--attnvl-border-color, #e5e7eb);
    border-radius: 8px;
    font: inherit;
    font-weight: 500;
    line-height: 1;
    text-align: left;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.attnvl-archive .attnvl-select__trigger:hover {
    background-color: #f9fafb;
    border-color: var(--attnvl-text-dark, #1f2937);
}

.attnvl-archive .attnvl-select__trigger:focus-visible {
    outline: 2px solid var(--attnvl-text-dark, #111);
    outline-offset: 2px;
}

.attnvl-archive .attnvl-select__trigger[aria-expanded="true"] {
    border-color: var(--attnvl-text-dark, #1f2937);
    background-color: #f9fafb;
}

.attnvl-archive .attnvl-select__value {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.attnvl-archive .attnvl-select__value--placeholder {
    color: var(--attnvl-text-muted, #6b7280);
    font-weight: 400;
}

.attnvl-archive .attnvl-select__chevron {
    flex-shrink: 0;
    width: 14px;
    height: 14px;
    color: var(--attnvl-text-muted, #6b7280);
    transition: transform 0.15s ease;
}

.attnvl-archive .attnvl-select__trigger[aria-expanded="true"] .attnvl-select__chevron {
    transform: rotate(180deg);
}

.attnvl-archive .attnvl-select__panel {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 50;
    /* The DB has 400+ brands; 280px showed ~7 at a time and the user
     * read that as truncation. 60vh keeps the panel within the viewport
     * on short laptop screens while showing ~14 options on a 1080p
     * display, which is enough to feel "all of them are there" for
     * scrollable lists. min(60vh, 480px) caps it on tall portrait
     * screens. */
    max-height: min(60vh, 480px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 4px;
    background-color: #fff;
    border: 1px solid var(--attnvl-border-color, #e5e7eb);
    border-radius: 8px;
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.10);
    /* "Growing" open animation. We can't transition from `display: none`
     * to `display: block`, so the closed state uses
     * visibility:hidden + opacity:0 + pointer-events:none + a small
     * scaleY/translate so the panel is in the layout (no display:none)
     * but invisible and inert. transform-origin: top center makes it
     * read as "blooming downward" from the trigger. On close, the
     * visibility transition is delayed until after the fade so it
     * stays paintable mid-animation. */
    transform-origin: top center;
    transform: scaleY(0.92) translateY(-4px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition:
        opacity 200ms cubic-bezier(0.16, 1, 0.3, 1),
        transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
        visibility 0s linear 200ms;
}

/* Loader state for an in-flight cascade (model fetch after a brand
 * pick). Adds a small CSS-only spinner inside the trigger; suppress
 * the chevron while busy. The host gets `data-busy="true"` from JS;
 * it clears as soon as the panel rebuilds. */
.attnvl-archive .attnvl-select-host[data-busy="true"] .attnvl-select__chevron {
    display: none;
}
.attnvl-archive .attnvl-select-host[data-busy="true"] .attnvl-select__trigger::after {
    content: "";
    flex-shrink: 0;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid var(--attnvl-border-color, #e5e7eb);
    border-top-color: var(--attnvl-text-dark, #1f2937);
    animation: attnvl-spin 0.7s linear infinite;
}
.attnvl-archive .attnvl-select-host[data-busy="true"] .attnvl-select__trigger {
    cursor: progress;
    opacity: 0.85;
}
@keyframes attnvl-spin {
    to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
    .attnvl-archive .attnvl-select-host[data-busy="true"] .attnvl-select__trigger::after {
        animation: none;
    }
}

.attnvl-archive .attnvl-select-host[data-open="true"] .attnvl-select__panel {
    transform: scaleY(1) translateY(0);
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    /* On open, drop the visibility delay so it becomes interactive
     * immediately while opacity/transform animate in. */
    transition:
        opacity 200ms cubic-bezier(0.16, 1, 0.3, 1),
        transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
        visibility 0s linear 0s;
}

/* Reduced motion: instant show/hide for the dropdown panels. */
@media (prefers-reduced-motion: reduce) {
    .attnvl-archive .attnvl-select__panel {
        transition: none;
    }
    .attnvl-archive .attnvl-select-host[data-open="true"] .attnvl-select__panel {
        transition: none;
    }
}

.attnvl-archive .attnvl-select__option {
    display: block;
    padding: 8px 10px;
    /* Square corners by default so the row dividers read as a clean
     * vertical stack. The rounded corners only surface on hover /
     * is-active / aria-selected (rules below) where the highlighted
     * row stands out as a "card" shape. */
    border-radius: 0;
    color: var(--attnvl-text-dark, #1f2937);
    font-size: 0.92rem;
    line-height: 1.3;
    cursor: pointer;
    user-select: none;
    transition: border-radius 0.12s ease, background-color 0.12s ease;
}

.attnvl-archive .attnvl-select__option:hover,
.attnvl-archive .attnvl-select__option.is-active {
    background-color: #f3f4f6;
    border-radius: 6px;
}

.attnvl-archive .attnvl-select__option[aria-selected="true"] {
    background-color: #e0f2fe;
    color: #075985;
    font-weight: 600;
    border-radius: 6px;
}

.attnvl-archive .attnvl-select__option[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Disabled-state host (mirrors native [disabled]) — dim the trigger,
 * block panel open. */
.attnvl-archive .attnvl-select-host[aria-disabled="true"] .attnvl-select__trigger {
    opacity: 0.55;
    pointer-events: none;
}

/* ---------------------------------------------------------------------
 * 4. F5 — Toolbar Row A (cascade + Apply) and Row B (search + per-page
 *    + pagination + Reset). Desktop: each row is inline; mobile
 *    (≤768px): cascade selects fall to a 2-col grid, Apply spans, and
 *    Row B reads Search-icon / per-page+pagination / Reset.
 * ------------------------------------------------------------------- */

/* The container's existing flex-direction: column is what stacks the
 * two rows. Override its row-mode at >= 1024px so we get a single row
 * per row-band rather than the existing wrap-everything behaviour. */
@media (min-width: 1024px) {
    .attnvl-archive .attnvl-toolbar {
        flex-direction: column;
        align-items: stretch;
    }
}

.attnvl-archive .attnvl-toolbar__row--b {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 8px;
    width: 100%;
}

@media (min-width: 1024px) {
    .attnvl-archive .attnvl-toolbar__row--b {
        flex-wrap: nowrap;
        gap: 12px;
    }
}

/* The controls-form stays first in row B and is the elastic element.
 * Its internal layout (search input + per-page) is already handled by
 * alientech-overrides.css; we just push pagination + reset rightwards. */
.attnvl-archive .attnvl-toolbar__row--b .attnvl-controls-form {
    flex: 1 1 100%;
}

@media (min-width: 1024px) {
    .attnvl-archive .attnvl-toolbar__row--b .attnvl-controls-form {
        flex: 1 1 auto;
    }
}

/* Pagination form sits between per-page and Reset on desktop. */
.attnvl-archive .attnvl-toolbar__row--b .attnvl-pagination-form {
    flex: 0 0 auto;
}

/* Reset button — always rightmost. */
.attnvl-archive .attnvl-toolbar__reset {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 44px;
    margin-left: auto;
    padding: 0 14px;
    font: inherit;
    font-weight: 600;
    color: var(--attnvl-text-dark, #1f2937);
    background-color: #fff;
    border: 1px solid var(--attnvl-border-color, #e5e7eb);
    border-radius: 8px;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.attnvl-archive .attnvl-toolbar__reset:hover {
    background-color: #f3f4f6;
    border-color: var(--attnvl-text-dark, #1f2937);
}

.attnvl-archive .attnvl-toolbar__reset--disabled {
    opacity: 0.45;
    pointer-events: none;
}

/* Desktop (≥1024px): keep the bottombar inline with the controls form so
 * pagination + reset sit on the SAME row as search + per-page. The
 * bottombar wraps three things (active-filter chips, pagination form,
 * reset button); without explicit layout it stacks them vertically and
 * the whole bottombar pushes itself onto a new flex line above the form.
 *
 * Pattern: bottombar = flex item with margin-left:auto pushing right;
 * its inner bottombar-row already arranges pagination + reset
 * horizontally. The chips strip flows above on a wrap when present.
 */
@media (min-width: 1024px) {
    .attnvl-archive .attnvl-toolbar__bottombar {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        justify-content: flex-end;
        gap: 8px 12px;
        margin-left: auto;
        flex: 0 1 auto;
    }
    .attnvl-archive .attnvl-toolbar__bottombar-row {
        display: flex;
        align-items: end;
        gap: 12px;
    }
    /* Reset button keeps its own margin-left:auto rule (line 477) — that
     * pushes it to the right within bottombar-row. Override here so it
     * stays snug against the pagination instead of stretching. */
    .attnvl-archive .attnvl-toolbar__bottombar-row .attnvl-toolbar__reset {
        margin-left: 0;
    }
}

/* Mobile (≤768px): compress the row-B grid. Pattern:
 *   [Search-icon]
 *   [Per-page]   [Pagination]   [Reset]
 *
 * Achieved by:
 *   - hide the desktop inline search field, show search icon button
 *   - keep per-page + pagination on one line
 *   - reset stays on the right (margin-left:auto)
 */
.attnvl-archive .attnvl-search-icon-btn {
    display: none;
}

@media (max-width: 1023.98px) {
    .attnvl-archive .attnvl-controls--desktop {
        display: none !important;
    }
    .attnvl-archive .attnvl-search-icon-btn {
        display: inline-flex;
    }
    /* Controls-form + Reset on the same row. Force the row to nowrap
     * (default mobile is wrap which pushed Reset to its own line)
     * and let the form take the remaining space (flex: 1 1 0). The
     * form's own content is icon buttons + a compact per-page
     * select that fit comfortably alongside Reset on a 360px+
     * viewport. */
    .attnvl-archive .attnvl-toolbar__row--b {
        flex-wrap: nowrap;
        align-items: center;
    }
    .attnvl-archive .attnvl-toolbar__row--b .attnvl-controls-form {
        flex: 1 1 0;
        min-width: 0;
    }
    /* Bottom toolbar bar — pagination + active-filter chips + reset.
     * Pinned to the bottom edge of the viewport so users can see what's
     * filtering, paginate, and reset without scrolling back up to the
     * cascade. Bottom-of-results pagination (parts/pagination.php with
     * position=bottom) keeps its in-flow layout because that's a
     * separate render branch. */
    .attnvl-archive .attnvl-toolbar__bottombar {
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 100;
        margin: 0;
        padding: 8px 12px env(safe-area-inset-bottom, 8px);
        background-color: #fff;
        border-top: 1px solid var(--attnvl-border-color, #e5e7eb);
        box-shadow: 0 -4px 14px rgba(0, 0, 0, 0.08);
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        gap: 6px;
    }
    .attnvl-archive .attnvl-toolbar__bottombar-row {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
    }
    .attnvl-archive .attnvl-toolbar__bottombar .attnvl-pagination-form--top {
        margin: 0;
        flex: 0 0 auto;
    }
    .attnvl-archive .attnvl-toolbar__bottombar .attnvl-pagination-form--top .attnvl-pagination {
        justify-content: center;
    }
    /* Tighten the mobile fixed-bottom paginator so the prev/next chevrons +
     * page input stack with breathing room above and below but don't pad
     * sideways (the bottombar's own padding already handles horizontal
     * gutters). */
    .attnvl-archive .attnvl-pagination {
        padding: 10px 0 !important;
    }
    .attnvl-archive .attnvl-toolbar__bottombar .attnvl-toolbar__reset {
        flex-shrink: 0;
    }
    /* Buffer so the last result row + the bottom-of-results paginator
     * aren't tucked under the sticky bar. The bar is taller now (chips
     * row + pagination row) so add headroom — calc keeps the buffer
     * proportional whether or not chips are present. */
    .attnvl-archive .attnvl-results {
        padding-bottom: 110px;
    }
}

/* Relaxed-search notice — surfaced when the strict query yields zero
 * results but a progressively-relaxed query found matches. Reads as
 * informational ("we broadened your search"), not as an error. */
.attnvl-archive-relaxed {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    margin: 8px 0 12px;
    padding: 10px 12px;
    background-color: #eff6ff;
    border: 1px solid #bfdbfe;
    border-radius: 8px;
    color: #1e3a8a;
    font-size: 0.875rem;
    line-height: 1.4;
}
.attnvl-archive-relaxed__icon {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    margin-top: 1px;
    color: #2563eb;
}
.attnvl-archive-relaxed__text {
    flex: 1 1 auto;
    min-width: 0;
}

/* Active-filter chips strip. Lives inside `.attnvl-toolbar__bottombar`
 * which is bottom-fixed on mobile. Hidden on desktop because the
 * cascade dropdowns + breadcrumb already convey the active state there.
 * Each chip is a link to a URL with that one filter (and its
 * descendants) removed. */
.attnvl-archive .attnvl-active-filters {
    display: none;
}
@media (max-width: 1023.98px) {
    .attnvl-archive .attnvl-active-filters {
        display: block;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        /* Hide the scrollbar visually — chips already hint at horizontal
         * scroll via clipping, and a thin bar across the sticky strip
         * is visually noisy. */
        scrollbar-width: none;
    }
    .attnvl-archive .attnvl-active-filters::-webkit-scrollbar {
        display: none;
    }
    .attnvl-archive .attnvl-active-filters__list {
        list-style: none;
        margin: 0;
        padding: 0;
        display: flex;
        gap: 6px;
        flex-wrap: nowrap;
    }
    .attnvl-archive .attnvl-active-filters__item {
        margin: 0;
        padding: 0;
        flex-shrink: 0;
    }
    .attnvl-archive .attnvl-active-filters__item::before {
        content: none;
    }
    .attnvl-archive .attnvl-active-filters__chip {
        display: inline-flex;
        align-items: center;
        gap: 4px;
        padding: 4px 8px 4px 10px;
        background-color: #f3f4f6;
        color: #1f2937;
        border-radius: 999px;
        font-size: 0.78rem;
        line-height: 1;
        text-decoration: none;
        border: 1px solid #e5e7eb;
        transition: background-color 0.15s ease, border-color 0.15s ease;
    }
    .attnvl-archive .attnvl-active-filters__chip:hover,
    .attnvl-archive .attnvl-active-filters__chip:focus-visible {
        background-color: #e5e7eb;
        border-color: #d1d5db;
        text-decoration: none;
    }
    .attnvl-archive .attnvl-active-filters__chip:focus-visible {
        outline: 2px solid var(--attnvl-accent-color, #1d86da);
        outline-offset: 2px;
    }
    .attnvl-archive .attnvl-active-filters__remove {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 16px;
        height: 16px;
        opacity: 0.6;
    }
    .attnvl-archive .attnvl-active-filters__chip:hover .attnvl-active-filters__remove {
        opacity: 1;
    }
}

/* Cascade Apply takes its own line on mobile, full-width tap target. */
@media (max-width: 768px) {
    .attnvl-archive .attnvl-cascade {
        flex-wrap: wrap;
    }
    .attnvl-archive button.attnvl-cascade__submit {
        flex: 1 1 100%;
        width: 100%;
    }
}

/* Generic icon button shared between desktop search submit + mobile
 * search-open + modal close. */
.attnvl-archive .attnvl-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background-color: #fff;
    color: var(--attnvl-text-muted, #6b7280);
    border: 1px solid var(--attnvl-border-color, #e5e7eb);
    border-radius: 8px;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.attnvl-archive .attnvl-icon-btn:hover,
.attnvl-archive .attnvl-icon-btn:focus-visible {
    background-color: #f3f4f6;
    color: var(--attnvl-text-dark, #1f2937);
    border-color: var(--attnvl-text-dark, #1f2937);
}

.attnvl-archive .attnvl-icon-btn svg {
    width: 18px;
    height: 18px;
}

/* ---------------------------------------------------------------------
 * 5. F6 — Mobile search modal. Hidden on desktop; on viewports ≤ 768px
 *    the .is-open class slides the panel in from the top with a
 *    spring-easing transform. Suggestions stagger-fade in.
 *    Easing chosen: cubic-bezier(0.16, 1, 0.3, 1) — Apple-style spring,
 *    a touch springy without being bouncy. Duration ~280ms.
 * ------------------------------------------------------------------- */
.attnvl-search-modal {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: none;
    pointer-events: none;
}

@media (max-width: 1023.98px) {
    .attnvl-search-modal {
        display: block;
    }
}

.attnvl-search-modal[aria-hidden="true"] .attnvl-search-modal__backdrop,
.attnvl-search-modal[aria-hidden="true"] .attnvl-search-modal__panel {
    opacity: 0;
    pointer-events: none;
}

.attnvl-search-modal.is-open {
    pointer-events: auto;
}

.attnvl-search-modal__backdrop {
    position: absolute;
    inset: 0;
    background-color: rgba(17, 24, 39, 0.55);
    opacity: 0;
    transition: opacity 240ms cubic-bezier(0.4, 0, 0.2, 1);
}

.attnvl-search-modal.is-open .attnvl-search-modal__backdrop {
    opacity: 1;
}

.attnvl-search-modal__panel {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    background-color: #fff;
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.18);
    padding: 16px 14px 24px;
    transform: translateY(-16px) scale(0.98);
    opacity: 0;
    transition:
        transform 280ms cubic-bezier(0.16, 1, 0.3, 1),
        opacity 220ms cubic-bezier(0.4, 0, 0.2, 1);
    max-height: 90vh;
    overflow-y: auto;
    border-bottom-left-radius: 16px;
    border-bottom-right-radius: 16px;
}

.attnvl-search-modal.is-open .attnvl-search-modal__panel {
    transform: translateY(0) scale(1);
    opacity: 1;
}

.attnvl-search-modal__row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.attnvl-search-modal__input {
    flex: 1 1 auto;
    height: 48px;
    padding: 0 14px;
    font-size: 1rem;
    border: 1px solid var(--attnvl-border-color, #e5e7eb);
    border-radius: 10px;
    background-color: #fff;
}

.attnvl-search-modal__input:focus-visible {
    outline: 2px solid var(--attnvl-text-dark, #111);
    outline-offset: 2px;
}

.attnvl-search-modal__close {
    flex-shrink: 0;
}

.attnvl-search-modal__suggestions {
    list-style: none;
    margin: 12px 0 0;
    padding: 0;
}

.attnvl-search-modal__suggestion {
    margin: 0;
    padding: 0;
    list-style: none;
    /* Stagger fade+slide. The stagger index is set by JS via
     * --attnvl-stagger. Cap at ~10 items so the last delay is ~400ms. */
    opacity: 0;
    transform: translateY(8px);
    animation: attnvl-suggestion-in 260ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
    animation-delay: calc(var(--attnvl-stagger, 0) * 35ms);
    /* Light-grey divider between results so the mobile modal reads as
     * a list, not a slab. Last item drops the line. */
    border-bottom: 1px solid var(--attnvl-border-color, #e5e7eb);
}
.attnvl-search-modal__suggestion:last-child {
    border-bottom: none;
}

.attnvl-search-modal__suggestion::before {
    content: none;
}

@keyframes attnvl-suggestion-in {
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.attnvl-search-modal__suggestion-link {
    /* Layout (display:flex, flex-direction:row by default, align-items:center,
     * gap:12px) is set by the shared rule below at line ~1352 alongside the
     * desktop suggestion item, so icon | body | tools sit on a single row.
     * The body itself stacks label + sub vertically via
     * .attnvl-search-modal__suggestion-body (line ~1383). */
    padding: 12px 12px;
    color: var(--attnvl-text-dark, #1f2937);
    text-decoration: none;
    border-radius: 8px;
    transition: background-color 0.12s ease;
    text-align: left;
}

.attnvl-search-modal__suggestion-link:hover,
.attnvl-search-modal__suggestion-link:focus-visible {
    background-color: #f3f4f6;
    text-decoration: none;
}

.attnvl-search-modal__suggestion-label {
    font-weight: 600;
    font-size: 0.95rem;
}

.attnvl-search-modal__suggestion-version {
    font-size: 0.85rem;
    color: var(--attnvl-text-muted, #6b7280);
}

/* Lock background scroll when modal is open. */
body.attnvl-search-modal-open {
    overflow: hidden;
}

/* ---------------------------------------------------------------------
 * 5b. Desktop inline search suggestions. Mirrors the custom-select
 *     "growing/blooming" open animation (cubic-bezier(0.16, 1, 0.3, 1),
 *     ~200ms, transform-origin: top center) for visual consistency.
 *     Uses visibility + opacity + transform — never display:none — so
 *     pure CSS transitions can drive both open and close gracefully.
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-controls--desktop {
    position: relative; /* anchor for the suggestion panel */
}

.attnvl-archive .attnvl-search-suggest {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 60; /* above sticky thead (which is z-index ~30 in vendor) */
    max-height: 400px;
    overflow-y: auto;
    overscroll-behavior: contain;
    background-color: #fff;
    border: 1px solid var(--attnvl-border-color, #e5e7eb);
    border-radius: 8px;
    box-shadow: 0 10px 24px rgba(0, 0, 0, 0.10);
    padding: 4px;
    margin: 0;
    list-style: none;
    transform-origin: top center;
    transform: scaleY(0.92) translateY(-4px);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition:
        opacity 200ms cubic-bezier(0.16, 1, 0.3, 1),
        transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
        visibility 0s linear 200ms;
}

/* The `hidden` HTML attribute would set display:none and break the
 * transition. JS removes it whenever the panel has any state to show;
 * this rule keeps the element in flow even when `hidden` is present
 * so the closed-state transform/opacity can paint. */
.attnvl-archive .attnvl-search-suggest[hidden] {
    display: block;
}

.attnvl-archive .attnvl-search-suggest.is-open {
    transform: scaleY(1) translateY(0);
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition:
        opacity 200ms cubic-bezier(0.16, 1, 0.3, 1),
        transform 200ms cubic-bezier(0.16, 1, 0.3, 1),
        visibility 0s linear 0s;
}

.attnvl-archive .attnvl-search-suggest__item {
    display: block;
    padding: 8px 10px;
    color: var(--attnvl-text-dark, #1f2937);
    text-decoration: none;
    border-radius: 6px;
    cursor: pointer;
    line-height: 1.3;
}

.attnvl-archive .attnvl-search-suggest__item:hover,
.attnvl-archive .attnvl-search-suggest__item.is-active,
.attnvl-archive .attnvl-search-suggest__item:focus-visible {
    background-color: #f3f4f6;
    text-decoration: none;
    outline: none;
}

.attnvl-archive .attnvl-search-suggest__label {
    display: block;
    font-weight: 600;
    font-size: 0.92rem;
}

.attnvl-archive .attnvl-search-suggest__sub {
    display: block;
    font-size: 0.82rem;
    color: var(--attnvl-text-muted, #6b7280);
}

.attnvl-archive .attnvl-search-suggest__empty {
    padding: 10px;
    color: var(--attnvl-text-muted, #6b7280);
    font-size: 0.9rem;
    text-align: center;
}

@media (max-width: 768px) {
    /* Mobile uses the modal — hide the inline suggest container. */
    .attnvl-archive .attnvl-search-suggest {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .attnvl-archive .attnvl-search-suggest,
    .attnvl-archive .attnvl-search-suggest.is-open {
        transition: none;
    }
}

/* Reduced motion — instant show/hide, no stagger. */
@media (prefers-reduced-motion: reduce) {
    .attnvl-search-modal__backdrop,
    .attnvl-search-modal__panel {
        transition: none;
    }
    .attnvl-search-modal__suggestion {
        animation: none;
        opacity: 1;
        transform: none;
    }
}

/* ---------------------------------------------------------------------
 * 6. Table overflow fix — vendor switches to desktop table at 800px,
 *    but the 9-column layout (Type, Brand, Model, Version+pill, kW,
 *    Fuel, Engine Code, Control Units, Clonable) does not fit below
 *    ~1200px and causes horizontal overflow on the page.
 *
 *    Decision: bump the mobile-card threshold to 1024px. Tablets and
 *    narrow laptops (800–1023px) get the existing card layout, which
 *    already surfaces every datum (Type, Fuel, Engine Code are inside
 *    the card). At ≥1024px the full desktop table renders as before.
 *
 *    Strategy: a plain `(max-width: 1023.98px)` query — at ≤799 the
 *    vendor's BASE rules (no media query, lines ~497–545 of attnvl.css)
 *    already render the mobile/card layout, so re-asserting the same
 *    display values in this band is a no-op below 800. From 800 to
 *    1023.98 our rules override the vendor's `@media (min-width: 800px)`
 *    desktop block.
 *
 *    Specificity climb: every selector is prefixed with `.attnvl-archive`
 *    (the page wrapper class — confirmed present in the rendered HTML)
 *    so each selector is one tier above the vendor's `.attnvl-table …`
 *    rules. Combined with `!important` on the `display` property — which
 *    vendor also sets `!important` on `.attnvl-mobile-row` and
 *    `.attnvl-desktop-cell` — this guarantees a win regardless of which
 *    plugin happens to load CSS after us in the cascade.
 * ------------------------------------------------------------------- */
@media (max-width: 1023.98px) {
    /* ----- Display switches: card mode on, desktop table off. -----
     * Vendor base (no MQ) defines the card layout (attnvl.css ~497–877).
     * Vendor `(min-width: 800px)` block (attnvl.css ~883+) overrides
     * those to a real table. Below 1024 we want the card layout, so we
     * re-assert every property the desktop block touches.
     *
     * Bug history: previous version only re-asserted `display`, not the
     * spacing properties — desktop block's `tr { margin: 0 }` and
     * `td { padding: calc(12px+16px) 8px 0 8px }` still applied, so the
     * tbody cards collapsed to zero vertical separation and stacked
     * directly on top of each other. The smoking gun is the `tr` margin
     * — without `margin: 16px 0` the cards have no gap. */

    .attnvl-archive .attnvl-table .attnvl-desktop-cell {
        display: none !important;
    }
    .attnvl-archive .attnvl-table thead {
        display: none !important;
    }
    .attnvl-archive .attnvl-table .attnvl-pills-row {
        /* Desktop-only sibling tr; mobile card embeds its own pills. */
        display: none !important;
    }

    /* table / tbody / tr / td → block (vendor desktop sets these to
       table / table-row-group / table-row / table-cell). */
    .attnvl-archive .attnvl-table,
    .attnvl-archive .attnvl-table tbody,
    .attnvl-archive .attnvl-table tr {
        display: block !important;
        width: 100% !important;
    }

    /* tr — restore vendor base spacing. Vendor desktop wipes
       `margin: 16px 0` to `margin: 0`, which is why cards stacked. */
    .attnvl-archive .attnvl-table tr {
        padding: 0 16px !important;
        margin: 16px 0 !important;
        border: none !important;
        border-radius: 0 !important;
        height: auto !important;
        overflow: visible !important;
        vertical-align: baseline !important;
    }

    /* All non-mobile-row td → block, no padding/border that vendor
       desktop adds. mobile-row td handled separately below. */
    .attnvl-archive .attnvl-table td {
        display: block !important;
        width: 100% !important;
        padding: 0 !important;
        border: none !important;
        vertical-align: baseline !important;
    }

    /* tbody.attnvl-vehicle-group — kill desktop padding-top. */
    .attnvl-archive .attnvl-vehicle-group {
        display: block !important;
        padding-top: 0 !important;
    }
    .attnvl-archive .attnvl-vehicle-group > tr:first-child {
        height: auto !important;
    }
    /* Keep vertical-align reset, but DROP the `border-bottom: none` —
     * on mobile each vehicle is rendered as a card and we WANT a
     * divider between cards. The vendor's desktop rule (attnvl.css
     * line ~1096, inside `@media (min-width: 800px)`) only fires on
     * desktop, so removing the override here doesn't break the
     * desktop pills-row layout. */
    .attnvl-archive .attnvl-vehicle-group > tr:first-child td:not([rowspan]),
    .attnvl-archive .attnvl-vehicle-group > tr:first-child td[rowspan] {
        vertical-align: baseline !important;
    }
    /* Card divider — overrides the broad `.attnvl-table td { border:
     * none !important }` rule above so mobile vehicle cards are
     * visually separated. */
    .attnvl-archive .attnvl-table td.attnvl-mobile-row {
        border-bottom: 1px solid var(--attnvl-border-color, #e5e7eb) !important;
    }

    /* td.attnvl-mobile-row — full vendor card-layout replication.
       This is THE card. grid-template-columns is the geometry that
       gives every child its width; without it the grid collapses. */
    .attnvl-archive .attnvl-table td.attnvl-mobile-row {
        display: grid !important;
        grid-template-columns: 32px 1fr !important;
        gap: 12px !important;
        padding: 8px !important;
        width: 100% !important;
        background-color: #ffffff !important;
        border: 1px solid var(--attnvl-border-color) !important;
        border-radius: 8px !important;
        box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.05) !important;
    }

    /* ECU cards + pills span both grid columns inside the card. */
    .attnvl-archive .attnvl-ecu-cards,
    .attnvl-archive .attnvl-mobile-row .attnvl-pills {
        grid-column: span 2 !important;
    }

    /* Suppress sticky positioning that vendor desktop applies to the
       toolbar/promo/filters/pagination wrapper — sticky behaviour is
       fine on a real table but breaks layering over the card stack. */
    .attnvl-archive .attnvl-controls,
    .attnvl-archive .attnvl-archive-promo,
    .attnvl-archive .attnvl-filters,
    .attnvl-archive .attnvl-pagination {
        position: static !important;
    }
}

/* Width safety nets — prevent any single cell from forcing overflow at
   the desktop table sizes (≥1024px). Version cell can wrap; the table
   itself never exceeds its container. */
.attnvl-archive .attnvl-table {
    max-width: 100%;
    table-layout: auto;
}
.attnvl-archive .attnvl-version-cell {
    white-space: normal;
    word-break: break-word;
}

/* ---------------------------------------------------------------------
 * Round-F follow-up: option icons in custom selects (Type, Tool).
 * The custom-select JS prepends `<span class="attnvl-select__icon">SVG</span>`
 * inside the option row + the trigger value when a native <option>
 * carries a `data-icon-html` attribute. We constrain the icon box to
 * roughly the same dimensions as the in-pill tool logos from F3 (18px)
 * so the visual weight matches the existing pills.
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-select__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    margin-right: 8px;
    vertical-align: middle;
}
.attnvl-archive .attnvl-select__icon svg {
    width: 100%;
    height: 100%;
    display: block;
}

/* Option rows that carry an icon: align icon + label baseline. The
 * default option row is text-only so we apply the flex layout only
 * to icon-bearing rows so non-icon selects (Brand / Model / Year)
 * stay byte-identical. */
.attnvl-archive .attnvl-select__option--has-icon {
    display: flex;
    align-items: center;
}
.attnvl-archive .attnvl-select__option--has-icon .attnvl-select__option-text {
    display: inline-block;
    line-height: 1.2;
}

/* Trigger value: when an icon is rendered, lay it out flex so the
 * SVG sits at the left, the label to the right. The base
 * .attnvl-select__value is text-only by default; only switch when
 * the JS adds `--has-icon`. */
.attnvl-archive .attnvl-select__value--has-icon {
    display: inline-flex;
    align-items: center;
    min-width: 0;
}
.attnvl-archive .attnvl-select__value--has-icon .attnvl-select__value-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ---------------------------------------------------------------
 * Bottom pagination — mirrors the Row-B control underneath the
 * table so users don't have to scroll back up to navigate. The
 * per-page select and Reset stay top-only; only prev / page input
 * / next / "of N" appear here.
 * --------------------------------------------------------------- */
.attnvl-archive .attnvl-pagination-bottom {
    display: flex;
    justify-content: center;
    margin-top: 16px;
    margin-bottom: 8px;
}
.attnvl-archive .attnvl-pagination-bottom .attnvl-pagination-form {
    display: inline-flex;
}
.attnvl-archive .attnvl-pagination-bottom .attnvl-pagination {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

/* ---------------------------------------------------------------------
 * F7. Inter-group divider — robust against suppressed pills row.
 *     Vendored attnvl.css attaches the row separator to
 *     `.attnvl-pills-row td { border-bottom: 1px solid … }` and
 *     strips the bottom border from the data row above it. When a
 *     vehicle has no tool support, our template suppresses the pills
 *     row entirely (D2) and the divider goes with it — adjacent
 *     vehicle groups visually merge. Anchor the divider on the
 *     wrapping <tbody class="attnvl-vehicle-group"> instead, so it
 *     is present whether or not the pills row renders.
 *
 *     Desktop-only: in mobile-card mode (≤1023.98px) each tbody is
 *     its own block-level card with its own border/shadow, so an
 *     extra bottom border would be redundant.
 * ------------------------------------------------------------------- */
@media (min-width: 1024px) {
    .attnvl-archive .attnvl-vehicle-group:not(:last-child) {
        border-bottom: 1px solid var(--attnvl-border-color);
    }
}

/*
 * UI polish migrated from direct edits of the vendored attnvl.css.
 * The vendored bundle is byte-identical to upstream v1.8.0 by
 * contract — local UI adjustments live here. Migrated as part of
 * the round-G prep commit.
 *
 * Each rule below mirrors a rule in assets/vendored/attnvl/attnvl.css
 * and overrides specific properties to match the desired UX.
 *
 * Scope notes: the upstream rules are unscoped, so prefixing with
 * .attnvl-archive / .attnvl-landing raises specificity and keeps the
 * override contained to the vehicle UI surface.
 * ------------------------------------------------------------------- */

/* (a) Vehicle-type icon at desktop breakpoint — fluid sizing with a
 *     min floor instead of a fixed 32x32. Mirrors the @media block
 *     around line 591 of vendored attnvl.css. */
@media (min-width: 800px) {
    .attnvl-archive .attnvl-type-icon,
    .attnvl-landing .attnvl-type-icon {
        width: 100%;
        height: 100%;
        min-width: 28px;
        min-height: 28px;
    }
}

/* (b) Tighter top padding on desktop table cells (calc(12px + 16px)
 *     → calc(2px + 16px)). Mirrors the rule around line 936 of
 *     vendored attnvl.css. */
@media (min-width: 800px) {
    .attnvl-archive .attnvl-table th,
    .attnvl-archive .attnvl-table td {
        padding: calc(2px + 16px) 8px 0 8px;
    }
}

/* (c) Tighter top padding on the vehicle-type cell on desktop
 *     (calc(8px + 16px) → calc(2px + 16px)). Mirrors the rule
 *     around line 967 of vendored attnvl.css. */
@media (min-width: 800px) {
    .attnvl-archive .attnvl-table .attnvl-cell--type {
        padding-top: calc(2px + 16px);
    }
}

/* (d) Legend / info button — explicit line-height matches the
 *     fixed 20px box for vertical centring of the glyph. Mirrors
 *     the rule around line 2621 of vendored attnvl.css. */
.attnvl-archive button.attnvl-legend-btn,
.attnvl-landing button.attnvl-legend-btn {
    line-height: 20px;
}

/* ---------------------------------------------------------------------
 * Round G — search suggestion polish.
 *
 * Both the desktop inline suggest and the mobile modal share the
 * same row anatomy emitted by buildSuggestionContent() in JS:
 *
 *   <a class="...item">
 *     <span class="...icon">{vehicle-type SVG}</span>
 *     <span class="...body">
 *       <span class="...label">{label, with <mark> wrapping query tokens}</span>
 *       <span class="...sub">{version}</span>
 *     </span>
 *     <span class="...tools">
 *       <span class="attnvl-pill attnvl-pill--kess3"><logo/><label/></span>
 *       <span class="attnvl-pill attnvl-pill--powergate"><logo/><label/></span>
 *     </span>
 *   </a>
 * ------------------------------------------------------------------- */

/* Highlight colour: brand yellow #ffee00, dark text on top. */
.attnvl-search-suggest__item mark,
.attnvl-search-modal__suggestion mark {
    background: #ffee00;
    color: inherit;
    padding: 0 2px;
    border-radius: 2px;
    font-weight: 600;
}

/* Row layout — icon | body | tools, vertically centred. The
 * existing .attnvl-search-suggest__item / __suggestion-link rules
 * already set padding + colour; we only add cross-axis flow here. */
.attnvl-archive .attnvl-search-suggest__item,
.attnvl-search-modal__suggestion-link {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* The icon column is fixed-width so labels align across rows. */
.attnvl-search-suggest__icon,
.attnvl-search-modal__suggestion-icon {
    flex: 0 0 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    color: var(--attnvl-vehicle-type-color, #1f2937);
}
.attnvl-search-suggest__icon .attnvl-type-icon,
.attnvl-search-modal__suggestion-icon .attnvl-type-icon {
    width: 100%;
    height: 100%;
}
.attnvl-search-suggest__icon svg,
.attnvl-search-modal__suggestion-icon svg {
    width: 100%;
    height: 100%;
}

/* Label + sub (version) stack vertically and take the available
 * space between icon and pills. */
.attnvl-search-suggest__body,
.attnvl-search-modal__suggestion-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* Tool pills row sits at the right on desktop, wraps below on
 * narrow widths. */
.attnvl-search-suggest__tools,
.attnvl-search-modal__suggestion-tools {
    flex: 0 0 auto;
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

/* Inline-pill compact variant — round-F .attnvl-pill is sized for
 * the vehicle-row pills cell; in a tight suggestion list we want
 * something smaller. Logo size scales with the label. */
.attnvl-search-suggest__tools .attnvl-pill,
.attnvl-search-modal__suggestion-tools .attnvl-pill {
    padding: 2px 8px 2px 4px;
    font-size: 0.7rem;
    line-height: 1.4;
    gap: 4px;
}
.attnvl-search-suggest__tools .attnvl-pill__logo,
.attnvl-search-modal__suggestion-tools .attnvl-pill__logo {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.attnvl-search-suggest__tools .attnvl-pill__logo svg,
.attnvl-search-modal__suggestion-tools .attnvl-pill__logo svg {
    width: 100%;
    height: 100%;
}

/* ---------------------------------------------------------------------
 * Round G — mobile search modal: behave like a real modal.
 *
 * Round F6 styled the panel as a top-anchored slide-down (top:0
 * inset, full bleed). Per Round-G feedback, the modal should be
 * vertically centred with side margins so it reads as a dialog,
 * not an edge-to-edge sheet. Override the F6 panel rules below.
 * ------------------------------------------------------------------- */
.attnvl-search-modal {
    /* Make the modal a flex container so the panel can centre. The
     * backdrop sits in its own fixed-position child so the flex
     * centring doesn't interfere with it. */
    display: none; /* default — overridden by the existing breakpoint rule below */
}
@media (max-width: 1023.98px) {
    .attnvl-search-modal {
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 16px;
    }
}

.attnvl-search-modal__panel {
    /* Override F6's top-anchored panel positioning. The panel is now
     * a normal flex child centred by the parent. */
    position: relative;
    top: auto; left: auto; right: auto;
    width: 100%;
    max-width: 520px;
    max-height: min(80vh, 640px);
    border-radius: 16px; /* all four corners now, not just bottom */
    transform: translateY(8px) scale(0.98);
}
.attnvl-search-modal.is-open .attnvl-search-modal__panel {
    transform: translateY(0) scale(1);
}

/* ---------------------------------------------------------------------
 * Round G — pills-row (desktop) sits flush against the
 * vehicle-group bottom border with no breathing room. Give the
 * <td> a bottom pad so the KESS3 / Powergate pills don't kiss
 * the divider line. Scoped to .attnvl-pills-row > td so we don't
 * touch any other cells.
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-table tr.attnvl-pills-row > td {
    padding-bottom: 12px;
}

/* Pills-row cell — sits under row 1 spanning columns 1–7 (Type through
 * EngineCode). The cell is a positioning anchor only: its content (an
 * absolutely-positioned <div>) is removed from normal flow so the pills'
 * intrinsic width does NOT influence column widths. Without this, the
 * KESS3+Powergate+transmission strip is wider than the natural Type
 * column and the auto table layout grows columns to fit. */
.attnvl-archive .attnvl-table tr.attnvl-pills-row > .attnvl-pills-row__cell {
    position: relative;
    /* Reserve enough vertical space for the pill strip (pill height ≈ 24px
     * + 8px top pad + 12px bottom pad from the existing pills-row td rule). */
    height: 44px;
    padding: 8px 8px 12px 8px;
    text-align: left;
    vertical-align: middle;
}
.attnvl-archive .attnvl-pills-row__content {
    position: absolute;
    left: 8px;
    top: 8px;
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 8px;
    /* Don't constrain width; pills extend rightwards as needed without
     * pushing any column. overflow:visible is the default but state it
     * for clarity. */
    overflow: visible;
    white-space: nowrap;
}
/* The inner .attnvl-pills wrapper holds kess3 + powergate. Keep it
 * inline, no-wrap, and with the same gap so it visually merges with
 * the trailing transmission pill into a single horizontal strip:
 *   [KESS3] [Powergate] [6-Speed Automatic]
 */
.attnvl-archive .attnvl-pills-row__content .attnvl-pills {
    display: inline-flex;
    flex-wrap: nowrap;
    justify-content: flex-start;
    gap: 8px;
}

/* Mobile vehicle card — stack the info paragraphs in a tight flex
 * column so each label/value sits on its own line with consistent
 * spacing instead of relying on inherited <p> margins. Pair Fuel and
 * kW on a single horizontal row to save vertical space. Both wrappers
 * exist only inside `.attnvl-mobile-row` (display:none at >=800px),
 * so these rules are implicitly mobile-scoped. */
.attnvl-archive .attnvl-vehicle-info {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.attnvl-archive .attnvl-vehicle-info__row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 16px;
}
.attnvl-archive .attnvl-vehicle-info__row > p {
    margin: 0;
}

/* Engine-code paragraph in the mobile card — keep the manufacturer
 * subtitle (e.g. "Fiat") inline with the engine code value instead of
 * dropping it onto its own line. The base `.attnvl-sub` rule sets
 * `display: block` for the desktop column where the subtitle stacks
 * under the value; here we override to inline. Scoped to this specific
 * <p> so other `.attnvl-sub` usages (model subtitle, ECU
 * microprocessor) stay on their own line. */
.attnvl-archive .attnvl-vehicle-info__engine .attnvl-sub,
.attnvl-archive .attnvl-vehicle-info__model .attnvl-sub {
    display: inline;
    margin-left: 6px;
}

/* Tagline count badge — highlights the vehicle count (e.g. "1574")
 * inside the catalogue tagline with the brand's yellow accent and
 * black text. Falls back to the literal hex if the kit variable is
 * unavailable (older themes / non-Elementor pages). */
.attnvl-archive .attnvl-tagline__count {
    display: inline-block;
    padding: 1px 8px;
    background-color: var(--e-global-color-accent, #FFEE00);
    color: #000;
    font-weight: 700;
    border-radius: 4px;
    line-height: 1.4;
}

/* Legend modal — shrink type + icons on mobile so each row takes less
 * vertical space and the whole modal fits on one screen without too
 * much scrolling. Scoped to <=767.98px (single-column phone layout);
 * tablet/desktop keep the base 1rem reading size. */
@media (max-width: 767.98px) {
    .attnvl-modal .attnvl-modal__body {
        padding: 16px;
    }
    .attnvl-modal .attnvl-legend-section {
        margin-bottom: 16px;
    }
    .attnvl-modal .attnvl-legend-section h3,
    .attnvl-modal .attnvl-legend-section .attnvl-h3 {
        margin: 0 0 10px 0;
        font-size: 0.95rem;
    }
    .attnvl-modal .attnvl-legend-list {
        gap: 6px;
    }
    .attnvl-modal .attnvl-legend-item {
        gap: 6px;
    }
    .attnvl-modal .attnvl-legend-item dt {
        font-size: 0.8rem;
        gap: 6px;
    }
    .attnvl-modal .attnvl-legend-item dd {
        font-size: 0.8rem;
        line-height: 1.3;
    }
    .attnvl-modal .attnvl-legend-item .attnvl-conn-icon,
    .attnvl-modal .attnvl-legend-item .attnvl-conn-icon svg,
    .attnvl-modal .attnvl-legend-item .attnvl-method,
    .attnvl-modal .attnvl-legend-item .attnvl-method svg {
        width: 20px;
        height: 20px;
    }
    .attnvl-modal .attnvl-legend-item dt .attnvl-fn,
    .attnvl-modal .attnvl-legend-item dt .attnvl-fn svg {
        width: 24px;
        height: 24px;
    }
    .attnvl-modal .attnvl-legend-note {
        font-size: 0.75rem;
        line-height: 1.35;
    }
}

/* ---------------------------------------------------------------------
 * Round-G polish — Issue 1.
 * Show only ONE search surface at any width: the inline desktop input
 * at >=1024px, the mobile search-icon button at <=1023.98px. The
 * markup ships both (the same form contains the inline <search>
 * element AND the modal-trigger <button>). Round-G G2 wired the icon
 * to open the modal but didn't gate its visibility — so on desktop
 * the icon was rendering next to the inline input.
 * ------------------------------------------------------------------- */
@media (min-width: 1024px) {
    .attnvl-archive .attnvl-search-icon-btn {
        display: none;
    }
}
@media (max-width: 1023.98px) {
    /* The inline search panel is the upstream <search class="attnvl-controls
     * attnvl-controls--desktop">; hide the WHOLE wrapper, including its
     * suggestion box, so the modal flow is the only path on mobile. */
    .attnvl-archive .attnvl-controls--desktop {
        display: none !important;
    }
}

/* ---------------------------------------------------------------------
 * Round-G polish — Issue 3.
 * .attnvl-cascade is a flex-row form (.attnvl-cascade > .attnvl-cascade__row)
 * that previously carried `align-items: end`. When the parent
 * .attnvl-toolbar gave the cascade more cross-axis height than its
 * single __row child needs (mobile column-flex sharing, desktop
 * wrapping with align-items: flex-end), the row got pushed to the
 * bottom of the cascade — leaving a visible empty band above the
 * Brand/Model/Year/Tool/Apply pickers.
 *
 * Fix: stretch the row to fill the cascade's available height so
 * there's nowhere for the empty band to live. The inner grid
 * (.attnvl-cascade__row) keeps its own align-items: end which is
 * what aligns the field inputs at a common baseline.
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-cascade {
    align-items: stretch;
}

/* ---------------------------------------------------------------------
 * Round-G polish — Issue 2.
 * Stylized growing tooltip for any element carrying
 * `data-attnvl-tooltip="…"`. Light theme. Spring easing
 * (cubic-bezier(0.34, 1.56, 0.64, 1)) gives the satisfying overshoot.
 * Hover + keyboard focus + touch (.is-touch-open class wired by JS)
 * all share the same active state. Reduced motion drops the spring
 * and keeps just an instant fade. Long copy uses
 * `data-attnvl-tooltip-wrap` for the wrap variant.
 * ------------------------------------------------------------------- */
[data-attnvl-tooltip] {
    position: relative;
}

[data-attnvl-tooltip]::after {
    content: attr(data-attnvl-tooltip);
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    /* `--attnvl-tooltip-shift` is set by alientech-vehicles.js when the
     * default centered position would push the bubble past a viewport
     * edge (mostly mobile, where triggers can sit near the screen edge).
     * Default 0 keeps the original centered behaviour. */
    transform: translateX(calc(-50% + var(--attnvl-tooltip-shift, 0px))) scale(0.85);
    transform-origin: bottom center;
    background: #ffffff;
    color: #1a1a1a;
    font-size: 0.78rem;
    font-weight: 500;
    line-height: 1.35;
    padding: 8px 12px;
    border-radius: 8px;
    box-shadow:
        0 8px 24px rgba(0, 0, 0, 0.12),
        0 2px 6px rgba(0, 0, 0, 0.08),
        0 0 0 1px rgba(0, 0, 0, 0.04);
    white-space: nowrap;
    max-width: min(280px, 80vw);
    opacity: 0;
    pointer-events: none;
    z-index: 50;
    transition:
        transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1),
        opacity 160ms ease-out;
}

/* Soft pointing arrow — single colour matches the panel so it reads
 * as a continuous shape; drop-shadow trails the panel shadow. */
[data-attnvl-tooltip]::before {
    content: '';
    position: absolute;
    bottom: calc(100% + 2px);
    left: 50%;
    transform: translateX(-50%) scale(0);
    transform-origin: bottom center;
    width: 0;
    height: 0;
    border-left: 6px solid transparent;
    border-right: 6px solid transparent;
    border-top: 6px solid #ffffff;
    filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.08));
    opacity: 0;
    pointer-events: none;
    z-index: 51;
    transition:
        transform 220ms cubic-bezier(0.34, 1.56, 0.64, 1),
        opacity 160ms ease-out;
}

[data-attnvl-tooltip]:hover::after,
[data-attnvl-tooltip]:focus-visible::after,
[data-attnvl-tooltip].is-touch-open::after {
    transform: translateX(calc(-50% + var(--attnvl-tooltip-shift, 0px))) scale(1);
    opacity: 1;
}
[data-attnvl-tooltip]:hover::before,
[data-attnvl-tooltip]:focus-visible::before,
[data-attnvl-tooltip].is-touch-open::before {
    transform: translateX(-50%) scale(1);
    opacity: 1;
}

/* Long descriptions wrap rather than overflow horizontally. */
[data-attnvl-tooltip][data-attnvl-tooltip-wrap]::after {
    white-space: normal;
    width: 240px;
}

/* Right-edge alignment for icons in the right-most table cells —
 * keeps the panel inside the viewport instead of overflowing. */
.attnvl-archive .attnvl-table td:last-child [data-attnvl-tooltip]::after,
.attnvl-archive .attnvl-table td:nth-last-child(2) [data-attnvl-tooltip]::after,
.attnvl-archive .attnvl-table td:last-child [data-attnvl-tooltip]::before,
.attnvl-archive .attnvl-table td:nth-last-child(2) [data-attnvl-tooltip]::before {
    left: auto;
    right: 0;
    transform: translateX(0) scale(0.85);
    transform-origin: bottom right;
}
.attnvl-archive .attnvl-table td:last-child [data-attnvl-tooltip]:hover::after,
.attnvl-archive .attnvl-table td:nth-last-child(2) [data-attnvl-tooltip]:hover::after,
.attnvl-archive .attnvl-table td:last-child [data-attnvl-tooltip]:focus-visible::after,
.attnvl-archive .attnvl-table td:nth-last-child(2) [data-attnvl-tooltip]:focus-visible::after,
.attnvl-archive .attnvl-table td:last-child [data-attnvl-tooltip].is-touch-open::after,
.attnvl-archive .attnvl-table td:nth-last-child(2) [data-attnvl-tooltip].is-touch-open::after {
    transform: translateX(0) scale(1);
}

@media (prefers-reduced-motion: reduce) {
    [data-attnvl-tooltip]::after,
    [data-attnvl-tooltip]::before {
        transition: opacity 80ms linear;
        transform: translateX(-50%) scale(1);
    }
    .attnvl-archive .attnvl-table td:last-child [data-attnvl-tooltip]::after,
    .attnvl-archive .attnvl-table td:last-child [data-attnvl-tooltip]::before {
        transform: translateX(0) scale(1);
    }
}

/* ---------------------------------------------------------------------
 * Round-G polish — Issue 4.
 * Suggestion-list footer: small light-text result count plus a
 * "Filter to {brand}" jump link. Lives at the bottom of the desktop
 * suggest panel and the mobile modal's suggestion list.
 * ------------------------------------------------------------------- */
.attnvl-search-suggest-footer {
    padding: 8px 12px 10px;
    margin-top: 4px;
    border-top: 1px solid #f1f5f9;
    font-size: 0.78rem;
    color: var(--attnvl-text-muted, #6b7280);
    line-height: 1.45;
}
.attnvl-search-suggest-footer__count {
    margin: 0 0 2px;
}
.attnvl-search-suggest-footer__jump {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    align-items: baseline;
}
.attnvl-search-suggest-footer__jump-prefix {
    color: inherit;
}
.attnvl-search-suggest-footer__jump-link {
    color: var(--attnvl-text-dark, #1f2937);
    font-weight: 600;
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    transition: color 0.12s ease;
}
.attnvl-search-suggest-footer__jump-link:hover,
.attnvl-search-suggest-footer__jump-link:focus-visible {
    color: #000000;
    text-decoration-thickness: 2px;
}

/* Modal footer must follow the modal's open/closed state. JS appends it
 * once on first render and reuses it on subsequent searches; the close
 * handler doesn't strip it from the DOM, so without this rule the
 * "1,210 results for «magneti»" line and the "Filter to FIAT" jump link
 * stay painted on top of the page after the user closes the modal.
 * Tying visibility to the modal's `.is-open` / `aria-hidden` state hides
 * it as soon as the panel fades out, while still letting JS reuse the
 * same node on the next open. */
.attnvl-search-modal:not(.is-open) .attnvl-search-suggest-footer--modal,
.attnvl-search-modal[aria-hidden="true"] .attnvl-search-suggest-footer--modal {
    display: none !important;
}

/* ---------------------------------------------------------------------
 * Round-G polish — Suggested-brands banner.
 *
 * Surfaces the brand buckets matching ?q=… above the archive table so
 * a search like "john deere" can be one-click-focused to the John
 * Deere archive. Hidden by the template when no $search or when a
 * brand filter is already active.
 *
 * Layout: label + chips. On mobile the label sits above; on desktop
 * everything is inline.
 * ------------------------------------------------------------------- */
.attnvl-archive-suggestions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
    margin: 0 0 12px;
    padding: 10px 12px;
    background: #fafafa;
    border: 1px solid var(--attnvl-border-color, #e5e7eb);
    border-radius: 10px;
}
.attnvl-archive-suggestions__label {
    flex: 0 0 auto;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--attnvl-text-muted, #6b7280);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.attnvl-archive-suggestions__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}
.attnvl-archive-suggestions__item {
    margin: 0;
    padding: 0;
    list-style: none;
}
.attnvl-archive-suggestions__item::before {
    content: none;
}
.attnvl-archive-suggestions__link {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 6px 12px;
    background: #ffffff;
    color: var(--attnvl-text-dark, #1f2937);
    border: 1px solid var(--attnvl-border-color, #e5e7eb);
    border-radius: 999px;
    text-decoration: none;
    font-size: 0.85rem;
    line-height: 1.2;
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.05s ease;
}
.attnvl-archive-suggestions__link:hover,
.attnvl-archive-suggestions__link:focus-visible {
    background: var(--attnvl-accent-color, #ffee00);
    border-color: var(--attnvl-accent-color, #ffee00);
    color: var(--attnvl-text-dark, #1f2937);
    text-decoration: none;
}
.attnvl-archive-suggestions__link:active {
    transform: translateY(1px);
}
.attnvl-archive-suggestions__brand {
    font-weight: 600;
}
.attnvl-archive-suggestions__count {
    color: var(--attnvl-text-muted, #6b7280);
    font-size: 0.78rem;
}
.attnvl-archive-suggestions__link:hover .attnvl-archive-suggestions__count,
.attnvl-archive-suggestions__link:focus-visible .attnvl-archive-suggestions__count {
    color: var(--attnvl-text-dark, #1f2937);
}

/* ---------------------------------------------------------------------
 * Round-G polish — Empty state.
 *
 * The "no results" cell is rendered inside the regular results table
 * but unstyled — just two paragraphs and a bare link. Give it a
 * proper centred empty-state layout: icon + heading + hint copy +
 * primary/secondary action buttons. Same design language as the
 * cascade Apply button (brand-yellow primary, neutral secondary).
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 12px;
    padding: 56px 24px;
    text-align: center;
    color: var(--attnvl-text-dark, #1f2937);
}
.attnvl-archive .attnvl-empty__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 88px;
    height: 88px;
    margin-bottom: 4px;
    color: var(--attnvl-text-muted, #94a3b8);
    background: #f3f4f6;
    border-radius: 50%;
}
.attnvl-archive .attnvl-empty__icon svg {
    width: 56px;
    height: 56px;
}
.attnvl-archive .attnvl-empty__title {
    margin: 0;
    font-size: 1.25rem;
    font-weight: 700;
    line-height: 1.25;
    color: var(--attnvl-text-dark, #1f2937);
}
.attnvl-archive .attnvl-empty__hint {
    margin: 0;
    max-width: 520px;
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--attnvl-text-muted, #6b7280);
}
.attnvl-archive .attnvl-empty__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    justify-content: center;
    margin-top: 8px;
}
.attnvl-archive .attnvl-empty__action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 44px;
    padding: 0 20px;
    border-radius: 10px;
    font-weight: 700;
    font-size: 0.92rem;
    text-decoration: none;
    transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.05s ease;
}
.attnvl-archive .attnvl-empty__action.attnvl-btn--primary {
    color: var(--attnvl-text-dark, #1f2937);
    background: var(--attnvl-accent-color, #ffee00);
    border: 1px solid var(--attnvl-accent-color, #ffee00);
}
.attnvl-archive .attnvl-empty__action.attnvl-btn--primary:hover,
.attnvl-archive .attnvl-empty__action.attnvl-btn--primary:focus-visible {
    background: #ffd900;
    border-color: #ffd900;
    text-decoration: none;
}
.attnvl-archive .attnvl-empty__action--secondary {
    color: var(--attnvl-text-dark, #1f2937);
    background: #ffffff;
    border: 1px solid var(--attnvl-border-color, #e5e7eb);
}
.attnvl-archive .attnvl-empty__action--secondary:hover,
.attnvl-archive .attnvl-empty__action--secondary:focus-visible {
    background: #f3f4f6;
    text-decoration: none;
}
.attnvl-archive .attnvl-empty__action:active {
    transform: translateY(1px);
}

/* The empty cell spans every column — strip the borders/striping
 * the table would otherwise apply so the empty state reads as a
 * standalone panel, not a table row. */
.attnvl-archive .attnvl-table tbody tr td:has(> .attnvl-empty),
.attnvl-archive .attnvl-table tbody tr:has(> td > .attnvl-empty) {
    background: transparent;
    border: none;
}

/* Mobile: scale the icon down + stack the actions full-width so
 * they're easy taps. */
@media (max-width: 1023.98px) {
    .attnvl-archive .attnvl-empty {
        padding: 40px 16px;
    }
    .attnvl-archive .attnvl-empty__icon {
        width: 72px;
        height: 72px;
    }
    .attnvl-archive .attnvl-empty__icon svg {
        width: 44px;
        height: 44px;
    }
    .attnvl-archive .attnvl-empty__actions {
        flex-direction: column;
        width: 100%;
        max-width: 320px;
    }
    .attnvl-archive .attnvl-empty__action {
        width: 100%;
    }
}

/* ---------------------------------------------------------------------
 * ECU type pill in search suggestions — smaller than the archive-table
 * / ECU-detail-page version. Same colour palette + dark chip look,
 * just denser to suit the inline sub-line context. Scoped to the
 * desktop suggest panel + the mobile search modal so the same
 * `.attnvl-ecu-type` chip elsewhere keeps its full size.
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-search-suggest__sub .attnvl-ecu-type,
.attnvl-archive .attnvl-search-modal__suggestion-version .attnvl-ecu-type {
    display: inline-block;
    padding: 1px 6px;
    min-width: 0;
    font-size: 0.7rem;
    line-height: 1.3;
    border-radius: 3px;
    vertical-align: baseline;
    margin-right: 4px;
}

/* ---------------------------------------------------------------------
 * Mobile filter modal — wraps the cascade form (Type/Brand/Model/Year/
 * Tool). Mirrors the F6 search-modal pattern: transparent shell on
 * desktop (display: contents lets the form render in its normal flow
 * with no positioning), full-screen modal on viewports ≤ 1023.98px
 * toggled by the .attnvl-filter-icon-btn funnel button.
 *
 * Why display:contents on desktop instead of a separate inline form
 * + a duplicated modal form: keeps a single <form data-attnvl-filters>
 * in the DOM so the cascade JS bind + auto-submit listener don't
 * have to be duplicated.
 * ------------------------------------------------------------------- */
.attnvl-archive .attnvl-filter-modal {
    display: contents;
}
.attnvl-archive .attnvl-filter-modal__backdrop,
.attnvl-archive .attnvl-filter-modal__header {
    display: none;
}

.attnvl-archive .attnvl-filter-icon-btn {
    display: none;
    position: relative;
}
.attnvl-archive .attnvl-filter-icon-btn__dot {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 8px;
    height: 8px;
    background-color: var(--attnvl-accent-color, #ffee00);
    border: 2px solid #fff;
    border-radius: 50%;
}

@media (max-width: 1023.98px) {
    /* Show the funnel button + hide the inline cascade. The modal
     * shell goes from display:contents (transparent) to a fixed
     * full-screen overlay that the JS toggles via .is-open. */
    .attnvl-archive .attnvl-filter-icon-btn {
        display: inline-flex;
    }
    .attnvl-archive .attnvl-filter-modal {
        position: fixed;
        inset: 0;
        z-index: 9999;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 16px;
        pointer-events: none;
    }
    .attnvl-archive .attnvl-filter-modal[aria-hidden="true"] .attnvl-filter-modal__backdrop,
    .attnvl-archive .attnvl-filter-modal[aria-hidden="true"] .attnvl-filter-modal__panel {
        opacity: 0;
        /* `visibility: hidden` — unlike pointer-events: none on the panel,
         * this kills clicks AND focus on every descendant regardless of
         * whether attnvl's custom-select trigger buttons re-set
         * pointer-events: auto on themselves. Without it, the cascade
         * triggers stayed clickable while the modal was visually hidden,
         * blocking the toolbar/pagination underneath them. The
         * .visibility transition is delayed by the panel's slide
         * duration so the fade-out finishes before the panel goes
         * un-clickable. */
        visibility: hidden;
        pointer-events: none;
    }
    .attnvl-archive .attnvl-filter-modal__backdrop,
    .attnvl-archive .attnvl-filter-modal__panel {
        transition-property: opacity, transform, visibility;
        transition-duration: 240ms, 280ms, 0s;
        transition-delay: 0s, 0s, 280ms;
        transition-timing-function:
            cubic-bezier(0.4, 0, 0.2, 1),
            cubic-bezier(0.16, 1, 0.3, 1),
            linear;
    }
    .attnvl-archive .attnvl-filter-modal.is-open .attnvl-filter-modal__backdrop,
    .attnvl-archive .attnvl-filter-modal.is-open .attnvl-filter-modal__panel {
        visibility: visible;
        transition-delay: 0s;
    }
    .attnvl-archive .attnvl-filter-modal.is-open {
        pointer-events: auto;
    }
    .attnvl-archive .attnvl-filter-modal__backdrop {
        display: block;
        position: absolute;
        inset: 0;
        background-color: rgba(17, 24, 39, 0.55);
        opacity: 0;
        transition: opacity 240ms cubic-bezier(0.4, 0, 0.2, 1);
    }
    .attnvl-archive .attnvl-filter-modal.is-open .attnvl-filter-modal__backdrop {
        opacity: 1;
    }
    .attnvl-archive .attnvl-filter-modal__panel {
        position: relative;
        width: 100%;
        max-width: 480px;
        background-color: #fff;
        box-shadow: 0 12px 36px rgba(0, 0, 0, 0.18);
        padding: 16px 14px 24px;
        transform: translateY(8px) scale(0.98);
        opacity: 0;
        transition:
            transform 280ms cubic-bezier(0.16, 1, 0.3, 1),
            opacity 220ms cubic-bezier(0.4, 0, 0.2, 1);
        max-height: calc(100vh - 32px);
        border-radius: 16px;
    }
    .attnvl-archive .attnvl-filter-modal.is-open .attnvl-filter-modal__panel {
        transform: translateY(0) scale(1);
        opacity: 1;
    }
    .attnvl-archive .attnvl-filter-modal__header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 12px;
    }
    .attnvl-archive .attnvl-filter-modal__title {
        margin: 0;
        font-size: 1rem;
        font-weight: 600;
    }
    .attnvl-archive .attnvl-filter-modal__close {
        flex-shrink: 0;
    }
    /* Inside the modal, stack cascade fields vertically + show the
     * Apply button (JS hides it on desktop because auto-submit makes
     * it redundant; on mobile we want an explicit confirm before the
     * page reloads, so we re-show it from CSS via the modal context).
     */
    .attnvl-archive .attnvl-filter-modal .attnvl-cascade__row {
        flex-direction: column;
        gap: 12px;
    }
    .attnvl-archive .attnvl-filter-modal .attnvl-cascade__field {
        width: 100%;
    }
    .attnvl-archive .attnvl-filter-modal .attnvl-cascade__submit {
        display: block !important;
        width: 100%;
        margin-top: 8px;
    }
}

/* Lock background scroll when filter (or search) modal is open.
 * Locking only `body` isn't enough — the WP admin bar's `.display-name`
 * span overflows the viewport on small screens, which makes <html>
 * the scrolling element and `body { overflow: hidden }` does nothing
 * for it. Locking <html> too kills the horizontal scrollbar that
 * otherwise pops in when either modal opens. :has() lets us target
 * <html> from a body-class signal. */
body.attnvl-filter-modal-open,
body.attnvl-search-modal-open {
    overflow: hidden;
}
html:has(body.attnvl-filter-modal-open),
html:has(body.attnvl-search-modal-open) {
    overflow: hidden;
}

/* ECU/TCU accordion toggle overflow on mobile.
 *
 * Vendor layout uses `grid-template-columns: auto 1fr auto`. Grid items
 * default to `min-width: auto` (= min-content), so a long unbreakable
 * token in the name/micro row (e.g. "SPC564A80", "Magneti") forces the
 * 1fr track wider than its share and pushes the chevron + content past
 * the container edge. `min-width: 0` lets the track actually shrink, and
 * `overflow-wrap: anywhere` allows long tokens to break onto the next
 * line as a last resort. We also tighten the title font on narrow
 * viewports so the badge + name + chevron fit a typical phone width
 * without wrapping in normal cases. */
@media (max-width: 799.98px) {
    button.attnvl-accordion__toggle {
        /* Tighten side padding + column gap on narrow viewports so the
         * badge + title + chevron fit a phone width without overflow. */
        padding-left: 12px;
        padding-right: 12px;
        column-gap: 8px;
        /* Belt-and-braces: keep any descendant overflow contained inside
         * the toggle's own box so the page can't scroll horizontally even
         * if a child fails to shrink. */
        max-width: 100%;
        overflow: hidden;
    }
    /* Every grid child gets `min-width: 0` — without it grid items default
     * to min-content, which means a single long token forces the 1fr track
     * wider than its share and pushes the chevron off-screen. */
    button.attnvl-accordion__toggle > * {
        min-width: 0;
    }
    button.attnvl-accordion__toggle .attnvl-h2,
    button.attnvl-accordion__toggle .attnvl-accordion__micro {
        overflow-wrap: anywhere;
        word-break: break-word;
    }
    /* Vendor sets `font-size: var(--attnvl-font-size-4) !important` on
     * `.attnvl-h2`, so we need !important to win on narrow viewports. */
    button.attnvl-accordion__toggle .attnvl-h2 {
        font-size: 1rem !important;
        line-height: 1.25 !important;
    }
    button.attnvl-accordion__toggle .attnvl-accordion__micro {
        font-size: 0.8rem;
    }
}

/* Vehicle landing H1 — structured title.
 *
 * The title has four logical parts (brand / model / year / version) that
 * render as adjacent spans. Vendor `.attnvl-h1` forces uppercase + heavy
 * weight on the whole heading, which loses hierarchy and overflows on
 * narrow viewports. We:
 *   - lay out the spans with flex-wrap so long titles break cleanly,
 *   - give each part its own weight so brand reads as primary, model as
 *     secondary, and year/version as supporting metadata,
 *   - keep the year in regular case (parentheses look weird in caps),
 *   - and step the size down on mobile so a typical phone fits one or
 *     two lines instead of four. */
.attnvl-h1.attnvl-h1--vehicle {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    column-gap: 0.45em;
    row-gap: 0.15em;
    overflow-wrap: anywhere;
}
.attnvl-h1--vehicle .attnvl-h1__brand {
    font-weight: 800 !important;
}
.attnvl-h1--vehicle .attnvl-h1__model {
    font-weight: 700 !important;
}
.attnvl-h1--vehicle .attnvl-h1__year {
    font-weight: 500 !important;
    text-transform: none !important;
    opacity: 0.78;
}
.attnvl-h1--vehicle .attnvl-h1__version {
    font-weight: 500 !important;
    text-transform: none !important;
    font-size: 0.72em;
    letter-spacing: 0.01em;
    opacity: 0.85;
    /* Push version to its own line so the brand/model/year cluster
     * stays as the dominant heading. */
    flex: 1 0 100%;
}
@media (max-width: 799.98px) {
    .attnvl-h1.attnvl-h1--vehicle {
        font-size: 1.35rem !important;
        line-height: 1.2 !important;
    }
    .attnvl-h1--vehicle .attnvl-h1__version {
        font-size: 0.78rem;
    }
}

/* ---------------------------------------------------------------------
 * Mobile gutter consistency.
 *
 * `.attnvl-vehicle-hero` has `padding: 0 16px 24px 16px` from the vendor
 * stylesheet, which produces a 16px gutter to the screen edge on mobile.
 * Other sections on the landing page (breadcrumbs, specs, ecus, related,
 * SEO links, historical note) inherit zero side padding and end up flush
 * with the viewport edge — visually inconsistent and uncomfortable on
 * touch. Same gap on the archive page's breadcrumb.
 *
 * We standardise on a single token (`--attnvl-mobile-gutter`) so future
 * tweaks happen in one place. Applied at <800px only — the desktop
 * vendor layout already centres content via `.attnvl-wrap` max-width.
 * ------------------------------------------------------------------- */
.attnvl-landing,
.attnvl-archive {
    --attnvl-mobile-gutter: 16px;
}

@media (max-width: 799.98px) {
    .attnvl-landing > .attnvl-wrap > .attnvl-breadcrumbs,
    .attnvl-archive > .attnvl-wrap > .attnvl-breadcrumbs,
    .attnvl-landing .attnvl-vehicle-detail > .attnvl-vehicle-specs,
    .attnvl-landing .attnvl-vehicle-detail > .attnvl-historical-note,
    .attnvl-landing .attnvl-vehicle-detail > .attnvl-vehicle-ecus,
    .attnvl-landing .attnvl-vehicle-detail > .attnvl-related,
    .attnvl-landing .attnvl-vehicle-detail > .attnvl-seo {
        padding-left: var(--attnvl-mobile-gutter);
        padding-right: var(--attnvl-mobile-gutter);
    }
    /* Topbar already has 16px inline padding from the vendor; force it
     * through the same token so any future change to the gutter cascades
     * here too. */
    .attnvl-landing .attnvl-vehicle-detail > .attnvl-topbar {
        padding-left: var(--attnvl-mobile-gutter);
        padding-right: var(--attnvl-mobile-gutter);
    }

    /* Breadcrumb polish: vendor margin pushes a 16px buffer above the
     * crumbs and 8px below, which combined with the topbar's 32px top
     * padding gives ~48px of empty space before "Home / Vehicles…".
     * Halve the top margin and tighten the separator so the crumbs read
     * as a tight inline strip on phones. */
    .attnvl .attnvl-breadcrumbs {
        margin-top: 8px;
        margin-bottom: 4px;
        font-size: 0.8125rem;
    }
    .attnvl .attnvl-breadcrumbs__sep {
        margin: 0 6px;
    }
    /* The vendor topbar uses `padding: 32px 16px` — too generous on a
     * phone and stacks awkwardly with the breadcrumb above. Trim it. */
    .attnvl-landing .attnvl-vehicle-detail > .attnvl-topbar {
        padding-top: 12px;
        padding-bottom: 12px;
    }
    /* Tighten the inter-section rhythm so the page doesn't feel like a
     * pile of disconnected slabs. Hero already has 24px bottom padding;
     * reset section top margins so we control gaps from one direction. */
    .attnvl-landing .attnvl-vehicle-detail > section + section,
    .attnvl-landing .attnvl-vehicle-detail > section + .attnvl-historical-note,
    .attnvl-landing .attnvl-vehicle-detail > .attnvl-historical-note + section {
        margin-top: 16px;
    }

    /* Compact tool header (KESS3 / Powergate strip inside each accordion
     * panel) on phones — vendor sizing eats vertical space inside an
     * already cramped card. Shrink the logo, drop the title to base
     * size, and tighten the surrounding margins/paddings. */
    .attnvl-tool-header {
        gap: 8px;
        margin-top: 4px;
        margin-bottom: 4px;
    }
    .attnvl-tool-logo {
        width: 24px;
        height: 24px;
    }
    .attnvl-tool-name {
        font-size: 0.95rem !important;
        line-height: 1.2 !important;
    }
    .attnvl-tool-link__icon {
        width: 12px;
        height: 12px;
    }
    .attnvl-tool-container {
        padding-top: 4px;
        padding-bottom: 4px;
    }

    /* Hide the vehicle topbar (back button + Alientech Suite promo) on
     * phones — the back button duplicates browser navigation, the promo
     * eats vertical space above the hero, and the breadcrumb already
     * provides a way back. Desktop keeps the topbar. */
    .attnvl-landing .attnvl-topbar {
        display: none;
    }

    /* Connection rows — pair the icon with the LABEL line only.
     *
     * Vendor markup is `[icon] [div > label + desc]` and the cell is a
     * flex row with `align-items: center`, which vertically centres the
     * icon against the combined label+description block — on mobile,
     * where the description wraps to multiple lines, the icon ends up
     * floating somewhere in the middle of the paragraph.
     *
     * Use a 2-column grid so the icon sits in row 1 (alongside the
     * label) and the description flows in row 2 of column 2 only,
     * leaving column 1 empty under the icon. The label is then visually
     * paired with its icon and the description hangs naturally below. */
    .attnvl-conn-cell {
        display: grid;
        grid-template-columns: auto 1fr;
        column-gap: 8px;
        row-gap: 2px;
        align-items: start;
    }
    .attnvl-conn-cell > .attnvl-conn-icon {
        grid-column: 1;
        grid-row: 1;
        margin-top: 0;
    }
    /* Vendor wraps the label + description in an unclassed `<div>` —
     * flatten it across both grid rows in column 2 so its children land
     * in the right cells. */
    .attnvl-conn-cell > div {
        grid-column: 2;
        grid-row: 1 / span 2;
        display: contents;
    }
    .attnvl-conn-cell .attnvl-conn-label {
        grid-column: 2;
        grid-row: 1;
    }
    .attnvl-conn-cell .attnvl-conn-desc,
    .attnvl-conn-cell .attnvl-conn-desc-wrap {
        grid-column: 2;
        grid-row: 2;
    }
}

/* ---------------------------------------------------------------------
 * Control Units list — push the type pill (`ECU` / `TCU` / `BCM` /
 * `Extra`) to the RIGHT end of each row instead of the left, while
 * keeping the same DOM order (markup stays semantic: type first, name,
 * methods). The vendor `.attnvl-ecu-item { display:flex; align-items:
 * center; gap:12px }` rule already gives us the row layout — we just
 * reorder children visually with `order` and use `margin-inline-start:
 * auto` to claim the slack space so the pill hugs the far right.
 *
 * Targets every context the list appears in (archive table cell,
 * landing page panel, ECU detail page) by NOT scoping to .attnvl-archive.
 * ------------------------------------------------------------------- */
.attnvl-ecu-list .attnvl-ecu-item .attnvl-ecu-name {
    order: 1;
}
.attnvl-ecu-list .attnvl-ecu-item .attnvl-ecu-methods,
.attnvl-ecu-list .attnvl-ecu-item .attnvl-ecu-spacer {
    order: 2;
}
.attnvl-ecu-list .attnvl-ecu-item .attnvl-ecu-type {
    order: 3;
    margin-inline-start: auto;
    flex-shrink: 0;
}

/* Custom-select option with a trailing "(count)" — JS splits the label
 * and the count into two spans (.attnvl-select__option-text and
 * .attnvl-select__option-count) and adds the .--with-count modifier.
 * Used by the Control Units cascade ("Bosch (17,439)").
 *
 * Layout: 2-column / 2-row CSS grid.
 *   row 1, col 1 : brand label (truncates with ellipsis)
 *   row 1, col 2 : count pill (right-aligned)
 *   row 2, full  : type chip strip ("ECU", "TCU", …) — only present
 *                  when the option carries `data-types="…"`. The
 *                  `--with-types` modifier triggers the second row;
 *                  options without types collapse to a single row
 *                  via grid-auto-rows.
 */
.attnvl-archive .attnvl-select__option--with-count {
    display: grid;
    grid-template-columns: 1fr auto;
    column-gap: 8px;
    row-gap: 4px;
    align-items: center;
}
.attnvl-archive .attnvl-select__option--with-count .attnvl-select__option-text {
    grid-column: 1;
    grid-row: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.attnvl-archive .attnvl-select__option--with-count .attnvl-select__option-count {
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    padding: 1px 8px;
    background-color: #f3f4f6;
    color: #1f2937;
    font-size: 0.78rem;
    font-weight: 600;
    border-radius: 999px;
    line-height: 1.4;
}

/* Type chip strip — sits on the SECOND row, spanning the full width of
 * the option, beneath the brand label and count. Each chip mirrors
 * `.attnvl-ecu-type` from the table-cell listing (vendor attnvl.css
 * line 1278): accent-coloured text on the darker `ecu-badge`
 * background, 4px-rounded, 600-weight. Same visual language across
 * dropdown + listing so the user reads them as the same kind of badge. */
.attnvl-archive .attnvl-select__option--with-count .attnvl-select__option-types {
    grid-column: 1 / -1;
    grid-row: 2;
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    justify-self: start;
}
.attnvl-select__option-type {
    display: inline-block;
    padding: 2px 8px;
    color: var(--attnvl-accent-color);
    background-color: var(--attnvl-ecu-badge-background-color);
    font-size: 0.75rem;
    font-weight: 600;
    border-radius: 4px;
    line-height: 1.4;
    text-align: center;
    min-width: 32px;
    /* Faded by default — most users scan the brand+count first; the
     * type buckets are secondary metadata. Wake them up on row hover
     * so it's clear what each brand offers without being noisy. */
    opacity: 0.25;
    transition: opacity 0.15s ease;
}
.attnvl-select__option:hover .attnvl-select__option-type,
.attnvl-select__option.is-active .attnvl-select__option-type,
.attnvl-select__option[aria-selected="true"] .attnvl-select__option-type {
    opacity: 1;
}

/* Light-grey hairline between dropdown options so the list reads as
 * separate rows rather than one solid slab. Last child drops the
 * line. Scoped to the panel + --with-count modifier so we don't
 * touch other custom-select usages on the page.
 *
 * The divider hides on hover / is-active / aria-selected so the
 * highlighted row reads as a clean rounded "card" without a
 * remaining hairline at the bottom edge. */
.attnvl-archive .attnvl-select__panel .attnvl-select__option--with-count {
    border-bottom: 1px solid var(--attnvl-border-color, #e5e7eb);
}
.attnvl-archive .attnvl-select__panel .attnvl-select__option--with-count:last-child,
.attnvl-archive .attnvl-select__panel .attnvl-select__option--with-count:hover,
.attnvl-archive .attnvl-select__panel .attnvl-select__option--with-count.is-active,
.attnvl-archive .attnvl-select__panel .attnvl-select__option--with-count[aria-selected="true"] {
    border-bottom-color: transparent;
}

/* Custom-select panel — clip horizontal overflow so a stray long brand
 * (e.g. "Continental-Siemens-VDO") can't push the inner option wider
 * than the panel and surface a horizontal scrollbar. The label span
 * already truncates with ellipsis (rule above) but only inside its
 * flex slot; the panel needs the explicit clip too. */
.attnvl-archive .attnvl-select__panel {
    overflow-x: hidden;
}

/* ---------------------------------------------------------------------
 * Re-apply the kit's `.elementor-button` styling as UNLAYERED CSS so
 * it wins over the layered version emitted by layer_elementor_kit_css().
 *
 * Background: the router wraps post-{kit_id}.css inside `@layer
 * elementor-kit { … }` to stop blanket selectors like
 * `.elementor-kit-12 button` from bleeding into the .attnvl-* archive
 * markup. Side effect: the kit's compound selector
 * `.elementor-kit-12 .elementor-button` (the one styling Elementor
 * Button widgets — e.g. the header Contact button) also became
 * layered and lost to Elementor's unlayered base `.elementor-button`
 * rule, so the Contact button reverted to grey defaults instead of
 * the brand-yellow rounded pill.
 *
 * Re-emitting just the `.elementor-button` selector here (NOT the
 * raw `button` / `input[type=submit]` siblings) restores the widget
 * appearance everywhere on the vehicles page WITHOUT re-introducing
 * the bleed into the cascade dropdown / sort buttons / icon buttons.
 * Property values must be kept in sync with the kit; on a kit-import
 * change the values below need a manual refresh.
 * ------------------------------------------------------------------- */
.elementor-kit-12 .elementor-button {
    background-color: var( --e-global-color-accent );
    font-family: "Roboto Flex", Sans-serif;
    font-size: 16px;
    font-weight: 500;
    text-transform: uppercase;
    color: var( --e-global-color-text );
    border-style: solid;
    border-width: 1px 1px 1px 1px;
    border-color: var( --e-global-color-accent );
    border-radius: 50px 50px 50px 50px;
    padding: 0.8em 1.3em 0.8em 1.3em;
}
.elementor-kit-12 .elementor-button:hover,
.elementor-kit-12 .elementor-button:focus {
    background-color: #414141;
    color: var( --e-global-color-secondary );
    border-style: solid;
    border-width: 1px 1px 1px 1px;
    border-color: #414141;
    border-radius: 50px 50px 50px 50px;
}
