/* ---------------------------------------------------------------------------
   Homepage sections.

   Ported from the legacy /v2 mockup, whose stylesheet lived inline in the view
   and carried every layout variant at once — 8,180 lines covering eleven
   sections with two to five alternatives each. This is the subset the chosen
   variants use: a rule survives only if something on the ported page still
   names its class.

   Tokens, typography, buttons, header, footer, section shell, request tray and
   the closing band are in site.css, which every page loads. Nothing is
   duplicated between the two files.

   Selectors keep the mockup's .gqv2 scope — see the note at the top of
   site.css for why.

   Block order follows the mockup, not the page; the running order is set by
   app/Views/website/home/index.php.
   --------------------------------------------------------------------------- */

.gqv2 .gqv2-slide-badge {
        display: inline-block;
        border: 1.5px solid var(--gq-gold);
        color: var(--gq-gold);
        font-size: 11px;
        font-weight: 800;
        letter-spacing: 2px;
        text-transform: uppercase;
        padding: 6px 16px;
        border-radius: 999px;
        margin-bottom: 16px;
}

/* vibe-colored badge (background set inline from the vibe system) */
    .gqv2 .gqv2-slide-badge-vibe {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        color: #fff;
        box-shadow: 0 8px 20px -8px rgba(0, 0, 0, .45);
}

.gqv2 .gqv2-slide-badge-vibe i {
        font-size: 12px;
}

.gqv2 .gqv2-slide-actions {
        display: flex;
        flex-wrap: wrap;
        gap: 14px;
}

/* ==================== SEARCH SECTION (below hero) ==================== */
    /* ==================== VALUE PROP BAND ====================
       A slim strip under the hero whose only job is to correct the category
       assumption before the visitor reaches the search bar. */
    /* .gqv2-section is declared later in this sheet with 78px block padding, so
       these need the extra class to win — a value-prop strip should read as part
       of the hero, not as a full content section. */
    .gqv2 .gqv2-section.gqv2-vp {
        background: var(--gq-sand);
        border-top: 1px solid rgba(18, 59, 99, .08);
        border-bottom: 1px solid rgba(18, 59, 99, .08);
        padding: 20px 0;
}

/* --- Option B: what you can do --- */
    .gqv2 .gqv2-vp-list {
        margin: 0;
        padding: 0;
        list-style: none;
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        align-items: center;
        gap: 10px 26px;
}

.gqv2 .gqv2-vp-list li {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        font-size: 15px;
        font-weight: 600;
        color: var(--gq-navy);
        white-space: nowrap;
}

.gqv2 .gqv2-vp-list i {
        font-size: 13px;
        color: var(--gq-orange);
}

/* separator dots between items — drawn, not typed, so they never wrap alone */
    .gqv2 .gqv2-vp-list li + li::before {
        content: "";
        width: 4px;
        height: 4px;
        border-radius: 50%;
        background: rgba(18, 59, 99, .28);
        margin-right: 18px;
}

@media (max-width: 760px) {
    .gqv2 .gqv2-section.gqv2-vp { padding: 14px 0;
    }

    .gqv2 .gqv2-vp-list { gap: 8px 16px;
    }

    .gqv2 .gqv2-vp-list li { font-size: 13.5px;
    }

    /* stacked on a phone, the dots read as bullets pointing at nothing */
        .gqv2 .gqv2-vp-list li + li::before { display: none;
    }
}

.gqv2 .gqv2-searchbar {
        position: relative;
        /* NOT overflow:hidden. The place dropdown lives in here and is routinely
           taller than the room left below the bar — "ohio" returns a dozen
           rows — and a clip on this element cut it off at the section edge.
           No z-index escapes a clip, so the clip moved to .gqv2-search-deco,
           which holds every decorative layer and nothing else. */
        overflow: visible;
        background: linear-gradient(180deg, #ffffff 0%, #f1f8fc 100%);
        border-bottom: 1px solid var(--gq-line);
        padding: 46px 0 42px;
        text-align: center;
}

/* The clipping layer. Exactly the section's box, holding the aurora, the dot
   texture and the animated route — everything that is allowed to be cut off at
   the section edge, and nothing that is not. */
    .gqv2 .gqv2-search-deco {
        position: absolute;
        inset: 0;
        overflow: hidden;
        pointer-events: none;
        z-index: 0;
}

/* animated aurora — soft travel-toned washes drifting slowly behind the search */
    .gqv2 .gqv2-search-deco::before {
        content: "";
        position: absolute;
        inset: -25%;
        /* washes kept very faint — this is texture behind the search, not a feature */
        background:
            radial-gradient(28% 40% at 20% 30%, rgba(36, 116, 166, .05), transparent 70%),
            radial-gradient(26% 38% at 82% 24%, rgba(0, 131, 143, .04), transparent 70%),
            radial-gradient(30% 42% at 68% 78%, rgba(255, 118, 0, .025), transparent 70%),
            radial-gradient(24% 36% at 32% 82%, rgba(95, 143, 114, .035), transparent 70%);
        animation: gqv2SearchAurora 24s ease-in-out infinite alternate;
        pointer-events: none;
        z-index: 0;
}

@keyframes gqv2SearchAurora {
        0%   { transform: translate3d(0, 0, 0) scale(1); }
        50%  { transform: translate3d(2.5%, -2%, 0) scale(1.08); }
        100% { transform: translate3d(-2%, 2%, 0) scale(1.04); }
}

/* faint dot texture on top, masked to fade at the edges */
    .gqv2 .gqv2-search-deco::after {
        content: "";
        position: absolute;
        inset: 0;
        background-image: radial-gradient(circle, rgba(18, 59, 99, .032) 1px, transparent 1.6px);
        background-size: 26px 26px;
        -webkit-mask-image: radial-gradient(ellipse 80% 74% at 50% 44%, #000 34%, transparent 100%);
        mask-image: radial-gradient(ellipse 80% 74% at 50% 44%, #000 34%, transparent 100%);
        pointer-events: none;
        z-index: 0;
}

/* animated flight path over the aurora */
    .gqv2 .gqv2-search-anim {
        position: absolute; inset: 0; width: 100%; height: 100%;
        pointer-events: none; z-index: 0;
}

/* the car is the one moving object the eye locks onto, so it drops the most */
    .gqv2 .gqv2-route-flow { opacity: .065; animation: gqv2RouteFlow 1.1s linear infinite;
}

.gqv2 .gqv2-route-pins { opacity: .055;
}

.gqv2 .gqv2-car { opacity: .12;
}

/* the camp sits between the pins and the car: scenery, not the focal point */
    .gqv2 .gqv2-camp { opacity: .09;
}

/* fill-box so the origin is the shape's own bbox — the default is the whole
   SVG viewport, which would swing these around the far side of the section */
    .gqv2 .gqv2-camp-flame {
        transform-box: fill-box; transform-origin: 50% 100%;
        animation: gqv2Flame 1.4s ease-in-out infinite;
}

.gqv2 .gqv2-camp-dancer {
        transform-box: fill-box; transform-origin: 50% 100%;
        animation: gqv2Dance 1.6s ease-in-out infinite;
}

/* offset so the two are never in lockstep, which reads as a mechanism */
    .gqv2 .gqv2-camp-dancer--b { animation-duration: 1.9s; animation-delay: -.7s;
}

@keyframes gqv2Flame {
    0%, 100% { transform: scale(1, 1);
    }

    25% { transform: scale(.88, 1.14);
    }

    50% { transform: scale(1.08, .92);
    }

    75% { transform: scale(.94, 1.06);
    }
}

@keyframes gqv2Dance {
    0%, 100% { transform: rotate(-9deg);
    }

    50% { transform: rotate(9deg);
    }
}

@media (prefers-reduced-motion: reduce) {
    .gqv2 .gqv2-search-deco::before { animation: none;
    }

    .gqv2 .gqv2-route-flow { animation: none;
    }

    .gqv2 .gqv2-car { display: none;
    }

    /* the camp stays — only its motion stops, which is the whole reason the
       fire and the dancers are CSS and not SMIL */
    .gqv2 .gqv2-camp-flame,
    .gqv2 .gqv2-camp-dancer { animation: none;
    }
}

/* Above the background decoration behind it, AND above the sections after it.

   This z-index is a stacking context, so the place dropdown inside it can never
   climb out of it however high its own z-index goes — it was 1 here, Swiper sets
   1 on its own root further down the page, and equal z-index means the later
   element paints on top. A 340px-tall menu reached into the guides carousel and
   went behind it. 20 clears every content layer on the page and stays well under
   the sticky header's 1000. */
    .gqv2 .gqv2-searchbar > .gqv2-wrap { position: relative; z-index: 20;
}

.gqv2 .gqv2-searchbar h2 {
        font-size: clamp(24px, 3vw, 36px);
        font-weight: 700;
        margin: 0 0 10px;
}

.gqv2 .gqv2-search-intro {
        font-size: 16px;
        line-height: 1.55;
        color: var(--gq-mist);
        max-width: 640px;
        margin: 0 auto 26px;
}

/* mode tabs */
    .gqv2 .gqv2-search-tabs {
        display: inline-flex;
        gap: 4px;
        background: #fff;
        border: 1px solid var(--gq-line);
        /* rounded rectangle (matches the 16px location card below), not a stadium */
        border-radius: 16px;
        padding: 5px;
        margin-bottom: 22px;
        position: relative;   /* anchor for the sliding pill */
        /* the section behind is near-white, so lift the track off it with a soft
           shadow rather than an inset groove — reads as a floating control */
        box-shadow: 0 6px 22px -10px rgba(18, 59, 99, .22), 0 1px 2px rgba(18, 59, 99, .05);
}

/* The pill is one element that MOVES, rather than a background that turns on
       and off per tab — that's what makes the switch read as a single object
       travelling instead of two things blinking. Width animates too, because the
       three labels aren't the same length. */
    .gqv2 .gqv2-tab-pill {
        position: absolute;
        top: 0;
        left: 0;
        /* size comes from JS (offsetWidth/offsetHeight of the active tab) so the
           pill is correct whether the tabs sit in a row or stack */
        /* 11px = track's 16px minus its 5px padding, so the pill's corners run
           parallel to the track's inner edge and nest evenly */
        border-radius: 11px;
        /* soft diagonal gradient + a top highlight give the pill depth */
        background: linear-gradient(135deg, var(--gq-blue) 0%, var(--gq-blue-dark) 100%);
        box-shadow: 0 6px 16px -6px rgba(36, 116, 166, .7),
                    inset 0 1px 0 rgba(255, 255, 255, .18);
        transition: transform .38s cubic-bezier(.4, 0, .2, 1),
                    width     .38s cubic-bezier(.4, 0, .2, 1),
                    height    .38s cubic-bezier(.4, 0, .2, 1);
        pointer-events: none;
        z-index: 0;
}

/* first paint must not fly in from the left */
    .gqv2 .gqv2-tab-pill.no-anim { transition: none;
}

@media (prefers-reduced-motion: reduce) {
    .gqv2 .gqv2-tab-pill { transition: none;
    }
}

.gqv2 .gqv2-search-tab {
        border: 0;
        background: transparent;
        /* a shade darker than --gq-slate for a bit more presence on the white track */
        color: #3f4b60;
        position: relative;   /* sit above the pill */
        z-index: 1;
        font-family: var(--gq-font);
        font-weight: 700;
        font-size: 14px;
        letter-spacing: .2px;
        padding: 11px 24px;
        border-radius: 11px;
        cursor: pointer;
        display: inline-flex;
        align-items: center;
        gap: 9px;
        white-space: nowrap;
        transition: color .18s ease;
}

.gqv2 .gqv2-search-tab i {
        font-size: 13px;
        opacity: .85;
        transition: opacity .18s ease, transform .18s ease;
}

.gqv2 .gqv2-search-tab:hover { color: var(--gq-navy);
}

.gqv2 .gqv2-search-tab:hover i { opacity: 1;
}

/* The pill paints the background now, so the active tab only owns its label. */
    .gqv2 .gqv2-search-tab.is-active {
        background: transparent;
        color: #fff;
        box-shadow: none;
}

.gqv2 .gqv2-search-tab.is-active i { opacity: 1;
}

.gqv2 .gqv2-search-tab.is-active:hover { color: #fff;
}

.gqv2 .gqv2-search-panel[hidden] { display: none;
}

/* animatable panels container (height transitions on tab switch) */
    /* overflow visible so the vibe hover popovers aren't clipped; the panel
       crossfade is opacity-only and never needed clipping */
    .gqv2 .gqv2-panels { overflow: visible;
}

.gqv2 .gqv2-search-panel.gqv2-panel-in { animation: gqv2PanelIn .26s ease both;
}

.gqv2 .gqv2-loc-status {
        font-size: 11px;
        font-weight: 700;
        color: var(--gq-blue-dark);   /* was the dead --gq-teal-dark: no status colour at all */
        white-space: nowrap;
        opacity: 0;
        transition: opacity .3s ease;
}

.gqv2 .gqv2-loc-status.show { opacity: 1;
}

/* ---- resolved-location card ---- */
    /* position: relative because the place dropdown (assets/shared
       /place-picker.css) hangs off the card and is measured against it */
    .gqv2 .gqv2-loccard {
        position: relative;
        display: flex;
        align-items: center;
        gap: 16px;
        max-width: 620px;
        margin: 0 auto;
        padding: 12px 16px 12px 20px;
        background: #fff;
        border: 1px solid var(--gq-line);
        border-radius: 16px;
        box-shadow: var(--gq-shadow-sm);
        text-align: left;
}

.gqv2 .gqv2-loccard[hidden] { display: none;
}

.gqv2 .gqv2-loccard-pin {
        flex-shrink: 0;
        font-size: 22px;
        color: var(--gq-navy);
}

/* the text is a button so it's clickable (and keyboard-focusable) to edit;
       reset the native chrome and keep the two-line layout */
    .gqv2 .gqv2-loccard-text {
        flex: 1;
        min-width: 0;
        display: flex;
        flex-direction: column;
        align-items: flex-start;
        gap: 1px;
        padding: 2px 4px;
        margin: -2px 0;
        border: 0;
        border-radius: 8px;
        background: none;
        font-family: var(--gq-font);
        line-height: 1.25;
        text-align: left;
        cursor: text;
        transition: background .15s ease;
}

/* The field around it carries the hover now; two overlapping tints read as
   a box inside a box. */
.gqv2 .gqv2-loccard-text:hover { background: none;
}

/* inline edit input — sits in the same slot as the text */
    .gqv2 .gqv2-loccard-input {
        flex: 1;
        min-width: 0;
        border: 0;
        outline: 0;
        background: none;
        font-family: var(--gq-font);
        font-size: 15.5px;
        font-weight: 700;
        color: var(--gq-navy);
        padding: 4px 0;
}

.gqv2 .gqv2-loccard-input[hidden] { display: none;
}

.gqv2 .gqv2-loccard-input::placeholder { color: var(--gq-mist); font-weight: 500;
}

/* edit state: swap the text for the input, in the same slot, so the field
       keeps its shape while it is being typed in */
    .gqv2 .gqv2-loccard[data-loc-state="edit"] .gqv2-loccard-text { display: none;
}

.gqv2 .gqv2-loccard[data-loc-state="edit"] { border-color: var(--gq-blue); box-shadow: var(--gq-shadow);
}

/* and the field itself is the focused one */
.gqv2 .gqv2-loccard[data-loc-state="edit"] .gqv2-loccard-who { border-color: var(--gq-blue); background: #fff;
}

.gqv2 .gqv2-loccard-city {
        font-size: 15.5px;
        font-weight: 800;
        color: var(--gq-navy);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
}

.gqv2 .gqv2-loccard-region {
        font-size: 13.5px;
        font-weight: 500;
        color: var(--gq-slate);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
}

.gqv2 .gqv2-loccard-region:empty { display: none;
}

/* Pin, place and input are one field.
 *
 * There is no separate edit control: the box is clicked and typed in, which is
 * how every travel site's location box works, and it only works because the box
 * LOOKS like one. A bare label with a pencil beside it says neither thing.
 *
 * flex-basis 0, not auto: with auto the field claims the width of its own
 * content, so a long place name took the whole row and pushed the controls
 * after it onto a line of their own. At 0 it shrinks and the name ellipsises
 * instead, so nothing moves — only the text gives way. min-width:0 is what
 * allows that shrink at all; without it a flex item will not go below its
 * content width. */
.gqv2 .gqv2-loccard-who {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 14px;
    border: 1px solid var(--gq-line);
    border-radius: 12px;
    background: var(--gq-cloud);
    cursor: text;
    transition: border-color .18s ease, background .18s ease;
}

.gqv2 .gqv2-loccard-who:hover { border-color: var(--gq-blue); background: #fff;
}

/* Shrink, but do not grow: the base rule is flex:1, which had the text claim
   every spare pixel and stretched the field far past the name inside it.
   Shrinking is still allowed, so a long name ellipsises. */
.gqv2 .gqv2-loccard-who .gqv2-loccard-text {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
}

.gqv2 .gqv2-loccard-city,
.gqv2 .gqv2-loccard-region {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* both actions live inside the card on the right */
    .gqv2 .gqv2-loccard-actions {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        gap: 6px;
}

/* "Nearby" — the GPS action, as a text link matching "Change location" so
       the two actions read as a consistent pair rather than mixed styles.
       The compound selector (.gqv2-loccard-near.gqv2-near) outranks the shared
       .gqv2-near pill rule that also lands on this button. */
    .gqv2 .gqv2-loccard-near.gqv2-near {
        display: inline-flex;
        align-items: center;
        gap: 7px;
        padding: 4px 10px;
        border: 0;
        background: none;
        color: var(--gq-blue);
        font-family: var(--gq-font);
        font-size: 13.5px;
        font-weight: 800;
        cursor: pointer;
        white-space: nowrap;
        border-radius: 8px;
        transition: color .18s ease, background .18s ease;
}

.gqv2 .gqv2-loccard-near.gqv2-near i { color: var(--gq-blue); font-size: 13px;
}

.gqv2 .gqv2-loccard-near.gqv2-near:hover { color: var(--gq-blue-dark); background: var(--gq-blue-tint); border-color: transparent;
}

/* The action. Solid, so nothing else on the bar competes with it. */
.gqv2 .gqv2-loccard-go {
        flex-shrink: 0;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 9px;
        height: 44px;
        padding: 0 24px;
        border: 0;
        border-radius: 999px;
        background: var(--gq-navy);
        color: #fff;
        font-family: var(--gq-font);
        font-size: 13px;
        font-weight: 800;
        letter-spacing: .6px;
        text-transform: uppercase;
        cursor: pointer;
        box-shadow: 0 10px 22px -10px rgba(18, 59, 99, .65);
        transition: background .18s ease, transform .18s ease;
}

.gqv2 .gqv2-loccard-go:hover { background: var(--gq-blue); transform: translateY(-1px);
}

/* Nothing to search for until a place is known. */
.gqv2 .gqv2-loccard[data-loc-state="detecting"] .gqv2-loccard-go { opacity: .45; pointer-events: none;
}

/* nothing to change or search for until the place is known */
    .gqv2 .gqv2-loccard[data-loc-state="detecting"] .gqv2-loccard-city { color: var(--gq-mist); font-weight: 600;
}

.gqv2 .gqv2-loccard[data-loc-state="detecting"] .gqv2-loccard-who { cursor: default;
}

.gqv2 .gqv2-loccard[data-loc-state="detecting"] .gqv2-loccard-who:hover {
    border-color: var(--gq-line);
    background: var(--gq-cloud);
}

/* ---- somewhere to start ----
   For the visitor the bar cannot help: it asks for a location, which is no use
   to someone who has not got one in mind. Chips rather than cards because they
   are places, not categories, and because a place name is the whole content —
   there is nothing else a card would carry. */
.gqv2 .gqv2-popular {
        /* Wider than the bar above it on purpose: at the bar's 620px these wrap
           to three ragged rows and stop reading as a short list. */
        max-width: 820px;
        margin: 24px auto 0;
}

.gqv2 .gqv2-popular-lead {
        margin: 0 0 14px;
        font-size: 13.5px;
        font-weight: 600;
        color: var(--gq-slate);
}

.gqv2 .gqv2-popular-row {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 10px;
}

.gqv2 .gqv2-poprchip {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        padding: 11px 20px;
        border: 1px solid var(--gq-line);
        border-radius: 999px;
        background: #fff;
        font-family: var(--gq-font);
        font-size: 14px;
        font-weight: 700;
        line-height: 1;
        color: var(--gq-navy);
        text-decoration: none;
        transition: background .18s ease, border-color .18s ease, transform .18s ease;
}

.gqv2 .gqv2-poprchip i { font-size: 12px; color: var(--gq-mist); transition: color .18s ease;
}

.gqv2 .gqv2-poprchip:hover { background: var(--gq-blue-tint); border-color: transparent; transform: translateY(-1px);
}

.gqv2 .gqv2-poprchip:hover i { color: var(--gq-blue);
}

@media (max-width: 620px) {
    /* Row 1 is the place and the crosshair; the action wraps to row 2. */
        .gqv2 .gqv2-loccard { flex-wrap: wrap; gap: 4px 12px; padding: 12px 16px;
    }

    .gqv2 .gqv2-loccard-pin { font-size: 18px;
    }

    .gqv2 .gqv2-loccard-city { font-size: 14px;
    }

    .gqv2 .gqv2-loccard-region { font-size: 12.5px;
    }

    /* Nearby loses its words here. At this width the label pushes the place
       into an ellipsis, and the crosshair is the one icon a phone reader
       already takes for "where I am" — it keeps its title and aria-label. */
    .gqv2 .gqv2-loccard-near.gqv2-near {
        /* flex:0 0 auto because the shared .gqv2-near rule below sets flex:1
           for the vibe panel, which stretched this to half the row. */
        flex: 0 0 auto;
        width: 40px;
        height: 40px;
        padding: 0;
        gap: 0;
        justify-content: center;
        border-radius: 50%;
    }

    .gqv2 .gqv2-loccard-neartxt { display: none;
    }

    /* The action takes a row of its own, so it is a full-width target and the
       place above it is never squeezed to make room. */
    .gqv2 .gqv2-loccard-go {
        flex: 1 1 100%;
        margin-top: 10px;
    }

    /* Chips wrap to four or five rows at this width and stop reading as a short
       list of suggestions. Scrolled sideways instead, in one row that runs off
       the edge so it is visibly scrollable. */
    .gqv2 .gqv2-popular-row {
        flex-wrap: nowrap;
        justify-content: flex-start;
        overflow-x: auto;
        scroll-snap-type: x proximity;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        /* full-bleed, so the row reaches the screen edge and the cut-off chip
           says there is more */
        margin-inline: -16px;
        padding-inline: 16px;
    }

    .gqv2 .gqv2-popular-row::-webkit-scrollbar { display: none;
    }

    .gqv2 .gqv2-poprchip { flex: 0 0 auto; scroll-snap-align: start;
    }
}

/* Near me button */
    .gqv2 .gqv2-near {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        white-space: nowrap;
        border: 1.5px solid var(--gq-line);
        background: #fff;
        color: var(--gq-navy);
        font-family: var(--gq-font);
        font-weight: 800;
        font-size: 13.5px;
        padding: 0 18px;
        border-radius: 999px;
        cursor: pointer;
        transition: border-color .18s ease, background .18s ease, color .18s ease;
}

.gqv2 .gqv2-near i { color: var(--gq-blue);
}

/* The old teal token was never defined, so this border reset to nothing while
       a mint wash stayed behind — that's why the button looked wrong rather than
       merely off-palette. Location is blue now, same family as the pill, so
       "where" reads as one idea across the whole bar. */
    .gqv2 .gqv2-near:hover,
.gqv2 .gqv2-near:focus-visible {
        border-color: var(--gq-blue);
        background: var(--gq-blue-tint);
        color: var(--gq-blue-dark);
}

.gqv2 .gqv2-near:hover i,
.gqv2 .gqv2-near:focus-visible i { color: var(--gq-blue-dark);
}

.gqv2 .gqv2-near.locating {
        pointer-events: none;
        opacity: .7;
}

.gqv2 .gqv2-near.locating i {
        animation: gqv2Spin .8s linear infinite;
}

@keyframes gqv2Spin { to { transform: rotate(360deg); }
}

/* ---- explore cards: what am I searching for? ----
       Picking one retargets the search (reads the location box, opens that
       type's /search route) rather than jumping down the page. */
    .gqv2 .gqv2-ecards-head {
        text-align: center;
        margin: 30px 0 4px;
}

.gqv2 .gqv2-ecards-head h3 {
        font-size: 20px;
        font-weight: 800;
        color: var(--gq-navy);
        margin: 0 0 5px;
}

.gqv2 .gqv2-ecards-head p {
        font-size: 14px;
        color: var(--gq-slate);
        margin: 0;
}

.gqv2 .gqv2-ecards {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 14px;
        max-width: 780px;            /* a touch smaller than before */
        margin: 16px auto 0;
}

.gqv2 .gqv2-ecard {
        display: flex;
        flex-direction: column;
        padding: 0 0 15px;
        border: 1px solid var(--gq-line);
        border-radius: 14px;
        background: #fff;
        overflow: hidden;            /* clips the image to the card's top corners */
        cursor: pointer;
        text-align: center;
        box-shadow: var(--gq-shadow-sm);
        transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}

.gqv2 .gqv2-ecard:hover {
        transform: translateY(-5px);
        box-shadow: var(--gq-shadow);
        border-color: var(--card-color);
}

.gqv2 .gqv2-ecard-media {
        display: block;
        position: relative;          /* anchors the tint + hover CTA */
        aspect-ratio: 3 / 2;
}

.gqv2 .gqv2-ecard-media img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
        transition: transform .35s ease;
}

.gqv2 .gqv2-ecard:hover .gqv2-ecard-media img { transform: scale(1.06);
}

/* card-colour wash that fades in on hover, behind the CTA */
    .gqv2 .gqv2-ecard-media::after {
        content: "";
        position: absolute;
        inset: 0;
        background: color-mix(in srgb, var(--card-color) 34%, transparent);
        opacity: 0;
        transition: opacity .25s ease;
        z-index: 1;
}

.gqv2 .gqv2-ecard:hover .gqv2-ecard-media::after { opacity: 1;
}

/* hover call-to-action — a colour pill centred on the image, no layout shift */
    .gqv2 .gqv2-ecard-cta {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, calc(-50% + 9px));
        z-index: 2;
        display: inline-flex;
        align-items: center;
        gap: 7px;
        padding: 8px 17px;
        border-radius: 999px;
        background: var(--card-color);
        color: #fff;
        font-size: 12.5px;
        font-weight: 800;
        white-space: nowrap;
        box-shadow: 0 10px 22px -8px rgba(18, 59, 99, .55);
        opacity: 0;
        pointer-events: none;        /* clicks pass through to the card button */
        transition: opacity .25s ease, transform .25s ease;
}

.gqv2 .gqv2-ecard-cta i { font-size: 10px;
}

.gqv2 .gqv2-ecard:hover .gqv2-ecard-cta { opacity: 1; transform: translate(-50%, -50%);
}

/* circular icon badge straddling the image's bottom edge */
    .gqv2 .gqv2-ecard-badge {
        width: 48px;
        height: 48px;
        margin: -24px auto 0;        /* pull up to overlap the image by half */
        position: relative;
        z-index: 3;                  /* above the media tint */
        border-radius: 50%;
        background: #fff;
        display: grid;
        place-items: center;
        color: var(--card-color);
        font-size: 18px;
        box-shadow: 0 6px 16px -6px rgba(18, 59, 99, .4);
}

.gqv2 .gqv2-ecard-title {
        margin: 11px 12px 4px;
        font-size: 15.5px;
        font-weight: 800;
        color: var(--card-color);
}

.gqv2 .gqv2-ecard-desc {
        margin: 0 12px;
        font-size: 12px;
        line-height: 1.5;
        color: var(--gq-slate);
}

@media (max-width: 760px) {
    .gqv2 .gqv2-ecards { grid-template-columns: repeat(2, 1fr); gap: 12px; max-width: 420px;
    }

    .gqv2 .gqv2-ecards-head h3 { font-size: 18px;
    }

    .gqv2 .gqv2-ecards-head p { font-size: 13px;
    }
}

/* ---- Free Guides: pick-a-state grid ---- */
    .gqv2 .gqv2-guide-prompt {
        text-align: center;
        font-size: 15px;
        font-weight: 600;
        color: var(--gq-navy);
        margin: 4px 0 18px;
}

/* Mini postcard tiles — a shrunk-down Explore-by-State (Option B). The unique
       2-letter badge replaces the repeating book icon; colour comes from the
       per-state --gc (a soft tint fill + the coloured abbreviation). */
    .gqv2 .gqv2-guide-states {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 10px;
        /* 1080 fits 9 per row, so 17 states land 9+8 instead of stranding a
           single chip on its own row (8+8+1) */
        max-width: 1080px;
        margin: 0 auto;
}

.gqv2 .gqv2-guide-states > * { flex: 0 1 110px;
}

/* same compaction as the state postcards: the desktop basis only fits two
       across on a phone, which makes this a very long scroll */
    @media (max-width: 640px) {
    .gqv2 .gqv2-guide-states { gap: 8px;
    }

    .gqv2 .gqv2-guide-states > * { flex: 0 1 96px;
    }

    .gqv2 .gqv2-gstate { padding: 10px 6px 9px;
    }

    .gqv2 .gqv2-gstate-abbr { font-size: 21px;
    }

    .gqv2 .gqv2-gstate-name { font-size: 11px; margin-top: 3px;
    }
}

.gqv2 .gqv2-gstate {
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 2px;
        padding: 13px 8px 11px;
        border: 1px solid var(--gq-line);
        border-radius: 12px;
        background: #fff;
        text-decoration: none;
        color: var(--gq-navy);
        transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}

.gqv2 .gqv2-gstate:hover,
.gqv2 .gqv2-gstate:focus-visible {
        transform: translateY(-3px);
        border-color: var(--gq-gold);
        box-shadow: var(--gq-shadow-sm);
}

/* the abbreviation is the only colour — a restrained 4-colour cycle, exactly
       like Option B's postcard letters. Each hue clears white/light backgrounds. */
    .gqv2 .gqv2-gstate-abbr {
        font-family: var(--gq-head-font);
        font-weight: 800;
        font-size: 27px;
        line-height: 1;
        color: var(--gq-navy);
}

.gqv2 .gqv2-gstate:nth-child(4n+1) .gqv2-gstate-abbr { color: var(--gq-blue);
}

.gqv2 .gqv2-gstate:nth-child(4n+2) .gqv2-gstate-abbr { color: var(--gq-green);
}

.gqv2 .gqv2-gstate:nth-child(4n+3) .gqv2-gstate-abbr { color: var(--gq-gold-dark);
}

.gqv2 .gqv2-gstate:nth-child(4n)   .gqv2-gstate-abbr { color: var(--gq-navy);
}

.gqv2 .gqv2-gstate-name {
        font-weight: 800;
        font-size: 12px;
        margin-top: 5px;
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
}

.gqv2 .gqv2-gstate-cnt {
        font-size: 10.5px;
        font-weight: 600;
        color: var(--gq-mist);
}

/* vibe chips */
    .gqv2 .gqv2-vibe-prompt {
        color: var(--gq-mist);
        font-size: 14.5px;
        font-weight: 600;
        margin: 0 0 18px;
}

.gqv2 .gqv2-vibe-chips {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 10px;
        max-width: 820px;
        margin: 0 auto;
}

.gqv2 .gqv2-vibe-chip {
        position: relative;          /* anchor for the hover popover */
        display: inline-flex;
        align-items: center;
        gap: 8px;
        border: 1.5px solid var(--gq-line);
        color: var(--gq-navy);
        font-weight: 800;
        font-size: 13.5px;
        padding: 10px 18px;
        border-radius: 999px;
        transition: transform .18s ease, background .18s ease, border-color .18s ease, color .18s ease;
}

.gqv2 .gqv2-vibe-chip > i {
        color: var(--vc, var(--gq-navy));
        font-size: 14px;
        transition: color .18s ease;
}

.gqv2 .gqv2-vibe-chip:hover {
        transform: translateY(-3px);
        background: var(--vc);
        border-color: var(--vc);
        color: #fff;
        z-index: 5;                  /* keep the hovered chip + its popover on top */
}

.gqv2 .gqv2-vibe-chip:hover > i { color: #fff;
}

/* ---- reactive prompt line: swaps to the hovered vibe, reverts on leave ----
       min-height reserves 2 lines so the chips never jump when the text grows,
       and the whole line cross-fades on each swap */
    .gqv2 .gqv2-vibe-prompt[data-vibe-prompt] {
        display: flex;
        align-items: center;
        justify-content: center;
        min-height: 2.9em;
        max-width: 560px;
        margin-left: auto;
        margin-right: auto;
        line-height: 1.45;
        transition: opacity .16s ease;
}

.gqv2 .gqv2-vibe-prompt[data-vibe-prompt].is-swapping { opacity: 0;
}

/* one flex item; its inline children flow and wrap as a single sentence */
    .gqv2 .gqv2-vibe-prompt-swap { display: inline;
}

.gqv2 .gqv2-vibe-prompt-name {
        font-weight: 800;
        white-space: nowrap;   /* keep the vibe name + icon together */
}

.gqv2 .gqv2-vibe-prompt-name i { margin-right: 6px;
}

.gqv2 .gqv2-vibe-prompt-desc { color: var(--gq-slate); font-weight: 500;
}

.gqv2 .gqv2-guide-note {
        margin: 16px 0 0;
        font-size: 13.5px;
        font-weight: 700;
        color: var(--gq-green-dark);
}

.gqv2 .gqv2-guide-note i { margin-right: 5px;
}

@media (max-width: 620px) {
    /* Tabs stay in a row. Stacking them cost three rows of height and forced
           the pill to track a moving target; dropping "Search by " fits instead. */
        .gqv2 .gqv2-search-tabs {
            width: 100%;
            justify-content: center;
    }

    .gqv2 .gqv2-tab-long { display: none;
    }

    .gqv2 .gqv2-search-tab {
            justify-content: center;
            padding: 10px 15px;
            font-size: 13px;
            gap: 6px;
    }

    /* trim the header block — it was eating most of the first screen */
        .gqv2 .gqv2-searchbar h2 { font-size: 22px; margin-bottom: 8px;
    }

    .gqv2 .gqv2-search-intro { font-size: 14px; margin-bottom: 18px;
    }

    .gqv2 .gqv2-near { flex: 1; justify-content: center; padding: 13px 14px;
    }
}

/* ---- "Surprise me" element (shared across search options) ---- */
    .gqv2 .gqv2-surprise-wrap {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 12px;
        flex-wrap: wrap;
        margin-top: 24px;
}

.gqv2 .gqv2-surprise-wrap > span {
        color: var(--gq-mist);
        font-size: 14px;
        font-weight: 600;
}

.gqv2 .gqv2-surprise {
        display: inline-flex;
        align-items: center;
        gap: 9px;
        border: 1.5px dashed var(--gq-gold);
        background: rgba(214, 166, 58, .1);
        color: var(--gq-gold-dark);
        font-family: var(--gq-font);
        font-weight: 800;
        font-size: 14px;
        padding: 11px 22px;
        border-radius: 999px;
        cursor: pointer;
        transition: background .18s ease, color .18s ease, border-color .18s ease, transform .18s ease;
}

.gqv2 .gqv2-surprise:hover {
        background: var(--gq-gold);
        color: var(--gq-navy);
        border-style: solid;
        transform: translateY(-2px);
}

.gqv2 .gqv2-surprise i { transition: transform .3s ease;
}

.gqv2 .gqv2-surprise:hover i { transform: rotate(-18deg) scale(1.15);
}

/* brief highlight when a search option scrolls you to a section */
    .gqv2 .gqv2-flash { animation: gqv2Flash 1.4s ease;
}

@keyframes gqv2Flash {
        0%   { box-shadow: inset 0 0 0 3px rgba(214, 166, 58, 0); }
        25%  { box-shadow: inset 0 0 0 3px rgba(214, 166, 58, .9); }
        100% { box-shadow: inset 0 0 0 3px rgba(214, 166, 58, 0); }
}

/* ==================== MINI VISITOR GUIDE BOOK ==================== */
    .gqv2 .gqv2-vg {
        position: relative;
        z-index: 6;
}

/* the cover is a button, so strip the native chrome and keep the artwork */
/* Both triggers are a <button> while the guide is still rendering and an <a>
   once it has somewhere to open — see web_guide_book(). text-decoration is the
   only thing the anchor brings that the button did not. */
    .gqv2 .gqv2-vg-open {
        display: block;
        position: relative;
        padding: 0;
        border: 0;
        background: none;
        cursor: pointer;
        text-decoration: none;
        transition: transform .22s ease;
}

.gqv2 .gqv2-vg-open:hover { transform: translateY(-4px);
}

.gqv2 .gqv2-vg-open:focus-visible { outline: 3px solid var(--gq-gold); outline-offset: 6px; border-radius: 10px;
}

.gqv2 .gqv2-vg-book {
        position: relative;
        width: 158px;
        aspect-ratio: 3 / 4.1;
        border-radius: 7px;
        overflow: hidden;
        transform: rotate(6deg);
        box-shadow: 0 28px 48px -14px rgba(0, 0, 0, .62), 0 6px 14px rgba(0, 0, 0, .3);
        background-size: cover;
        background-position: center;
        display: flex;
        flex-direction: column;
        align-items: center;
        text-align: center;
        padding: 16px 12px;
}

/* real guide cover — its own artwork, so no readability scrim and no padding */
    .gqv2 .gqv2-vg-book.is-real {
        padding: 0;
        background-position: top center;
        background-color: #0d2c4b;
}

.gqv2 .gqv2-vg-book.is-real::before { content: none;
}

.gqv2 .gqv2-vg-book::before {
        content: "";
        position: absolute;
        inset: 0;
        background: linear-gradient(to bottom, rgba(13, 44, 75, .8) 0%, rgba(13, 44, 75, .2) 42%, rgba(13, 44, 75, .82) 100%);
}

.gqv2 .gqv2-vg-book > * {
        position: relative;
        z-index: 2;
}

.gqv2 .gqv2-vg-top {
        display: block;
        font-family: var(--gq-script-font);
        font-size: 16px;
        color: var(--gq-gold);
        line-height: 1;
        margin-bottom: 4px;
}

.gqv2 .gqv2-vg-title {
        display: block;          /* was an <h3>; a button can only hold spans */
        font-family: var(--gq-head-font);
        font-size: 18px;
        font-weight: 800;
        line-height: 1.05;
        color: #fff;
        text-transform: uppercase;
        letter-spacing: .4px;
        margin: 0 0 6px;
}

.gqv2 .gqv2-vg-sub {
        font-size: 6.5px;
        font-weight: 800;
        letter-spacing: 1.8px;
        text-transform: uppercase;
        color: rgba(255, 255, 255, .9);
        border-top: 1px solid rgba(255, 255, 255, .5);
        padding-top: 6px;
}

.gqv2 .gqv2-vg-tagline {
        margin-top: auto;
        font-size: 7px;
        font-weight: 700;
        letter-spacing: 1px;
        text-transform: uppercase;
        color: rgba(255, 255, 255, .92);
}

/* gold circular "Official Travel Guide" badge on the corner */
    .gqv2 .gqv2-vg-badge {
        position: absolute;
        /* Bottom corner, not the top one: over the top of a real cover it sat
           on the destination's own masthead. Trello card AM4w6jpt. */
        bottom: -12px;
        right: -18px;
        width: 66px;
        height: 66px;
        border-radius: 50%;
        background: var(--gq-gold);
        /* Navy on this gold measures 3.3:1 at 7px — legible as a shape, not as
           words. The gold is fixed, so the lift has to come from the type:
           white, a point larger, and a soft dark shadow to hold its edges
           against the orange. */
        color: #fff;
        text-shadow: 0 1px 2px rgba(0, 0, 0, .45);
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 2px;
        text-align: center;
        font-size: 8px;
        font-weight: 800;
        letter-spacing: .6px;
        text-transform: uppercase;
        line-height: 1.2;
        padding: 7px;
        transform: rotate(-8deg);
        box-shadow: 0 8px 18px -6px rgba(0, 0, 0, .45);
        z-index: 3;
}

.gqv2 .gqv2-vg-badge i {
        font-size: 11px;
}

/* mobile-only trigger — the cover itself is hidden on narrow screens */
    .gqv2 .gqv2-vg-mobilebtn {
        display: none;
        align-items: center;
        gap: 9px;
        margin-top: 16px;
        padding: 11px 18px;
        border-radius: 999px;
        border: 1.5px solid rgba(255, 255, 255, .5);
        background: rgba(255, 255, 255, .12);
        color: #fff;
        font-family: var(--gq-font);
        font-size: 13.5px;
        font-weight: 800;
        cursor: pointer;
        text-decoration: none;
        transition: background .2s ease, border-color .2s ease;
}

.gqv2 .gqv2-vg-mobilebtn:hover { background: rgba(255, 255, 255, .24); border-color: #fff;
}

/* ---------- visitor guide viewer ---------- */
    .gqv2-gm {
        position: fixed;
        inset: 0;
        z-index: 9999;
        display: grid;
        place-items: center;
        padding: 24px;
}

.gqv2-gm[hidden] { display: none;
}

.gqv2-gm-backdrop {
        position: absolute;
        inset: 0;
        background: rgba(6, 18, 32, .86);
        backdrop-filter: blur(6px);
        animation: gqv2ShmFade .25s ease;
}

.gqv2-gm-dialog {
        position: relative;
        z-index: 1;
        display: flex;
        align-items: center;
        gap: 30px;
        max-width: 720px;
        width: 100%;
        padding: 30px;
        border-radius: 20px;
        background: #fff;
        box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .7);
        animation: gqv2ShmRise .28s cubic-bezier(.22, .61, .36, 1);
}

.gqv2-gm-cover {
        flex: 0 0 200px;
        aspect-ratio: 3 / 4.1;
        border-radius: 10px;
        overflow: hidden;
        box-shadow: 0 20px 40px -14px rgba(0, 0, 0, .5);
}

.gqv2-gm-cover img { width: 100%; height: 100%; object-fit: cover; display: block;
}

.gqv2-gm-body { min-width: 0;
}

.gqv2-gm-kicker {
        font-family: var(--gq-script-font);
        font-size: 22px;
        color: var(--gq-gold-dark);
        display: block;
}

.gqv2-gm-title {
        margin: 2px 0 6px;
        font-family: var(--gq-head-font);
        font-size: 26px;
        font-weight: 800;
        color: var(--gq-navy);
        line-height: 1.15;
}

.gqv2-gm-tag {
        display: block;
        font-size: 11px;
        font-weight: 800;
        letter-spacing: 1.2px;
        text-transform: uppercase;
        color: var(--gq-blue);
}

.gqv2-gm-copy {
        margin: 12px 0 18px;
        font-size: 14.5px;
        line-height: 1.6;
        color: var(--gq-slate);
}

.gqv2-gm-close {
        position: absolute;
        top: 12px;
        right: 12px;
        width: 36px;
        height: 36px;
        border-radius: 50%;
        border: 1px solid var(--gq-line);
        background: #fff;
        color: var(--gq-navy);
        cursor: pointer;
        display: grid;
        place-items: center;
        transition: background .2s ease;
}

.gqv2-gm-close:hover { background: var(--gq-cloud);
}

@media (max-width: 620px) {
    .gqv2-gm { padding: 14px;
    }

    .gqv2-gm-dialog { flex-direction: column; gap: 18px; padding: 24px 20px; text-align: center;
    }

    .gqv2-gm-cover { flex: 0 0 auto; width: 150px;
    }

    .gqv2-gm-title { font-size: 21px;
    }
}

/* ---------- travel-vibe dialog (phones) ----------
   Takes the guide viewer's shell — .gqv2-gm centres it, -backdrop scrims it,
   -close closes it — and only replaces the body, which is a narrow centred
   column rather than a cover beside a block of text. The vibe's own colour
   arrives from the tapped tile as --vibe. */
.gqv2-vm-dialog {
        flex-direction: column;
        align-items: center;
        gap: 0;
        max-width: 380px;
        padding: 34px 24px 26px;
        text-align: center;
}

.gqv2-vm-icon {
        display: grid;
        place-items: center;
        width: 62px;
        height: 62px;
        margin-bottom: 16px;
        border-radius: 50%;
        font-size: 24px;
        /* The tile's colour at a tint, so the badge reads as the vibe without
           competing with the button below it. */
        color: var(--vibe, var(--gq-navy));
        background: color-mix(in srgb, var(--vibe, var(--gq-navy)) 12%, #fff);
}

.gqv2-vm-title {
        font-family: var(--gq-head-font);
        font-size: 24px;
        font-weight: 700;
        line-height: 1.15;
        margin: 0 0 10px;
}

.gqv2-vm-copy {
        font-size: 14.5px;
        line-height: 1.6;
        color: var(--gq-mist);
        margin: 0 0 22px;
}

/* Scoped with .gqv2 so it outranks `.gqv2 a { color: inherit }` — one class on
   its own loses to a class plus an element, and the button kept the dialog's
   dark text on its coloured fill. */
.gqv2 .gqv2-vm-cta {
        color: #fff;
        justify-content: center;
        width: 100%;
}

/* placement — straddles the seam: roughly half the cover sits over the photo */
    .gqv2 .gqv2-vg.vg-b { position: absolute; right: -74px; bottom: 24px;
}

@media (max-width: 900px) {
    /* the cover art is dropped, but the guide stays reachable: the wrapper
           returns to normal flow and the text button takes its place */
        .gqv2 .gqv2-vg.vg-b {
            position: static;
            right: auto;
            bottom: auto;
    }

    .gqv2 .gqv2-vg-open { display: none;
    }

    .gqv2 .gqv2-vg-mobilebtn { display: inline-flex;
    }
}

/* ==================== HERO — OPTION B: split panel ==================== */
    .gqv2 .gqv2-hb-stage {
        position: relative;
        display: grid;
        grid-template-columns: 46% 54%;
        height: 520px;
        border-radius: 24px;
        overflow: hidden;
        box-shadow: var(--gq-shadow);
        background: var(--gq-navy);
}

.gqv2 .gqv2-hb-left {
        position: relative;
        z-index: 3;
        background: linear-gradient(160deg, #16456f 0%, var(--gq-navy) 70%);
}

/* diagonal edge cutting into the photo */
    .gqv2 .gqv2-hb-left::after {
        content: "";
        position: absolute;
        top: -5%;
        bottom: -5%;
        right: -56px;
        width: 112px;
        background: inherit;
        transform: skewX(-5deg);
}

.gqv2 .gqv2-hb-text {
        position: absolute;
        inset: 0;
        z-index: 2;
        /* right padding keeps the copy clear of the guide cover below it */
        padding: 46px 96px 96px 46px;
        display: flex;
        flex-direction: column;
        justify-content: center;
        opacity: 0;
        transition: opacity .6s ease;
        pointer-events: none;
}

/* the badge is inline-block, but as a flex child in a column it stretches to
       the full panel width — it has to opt out to stay a pill */
    .gqv2 .gqv2-hb-text .gqv2-slide-badge { align-self: flex-start;
}

.gqv2 .gqv2-hb-text.is-active {
        opacity: 1;
        pointer-events: auto;
}

.gqv2 .gqv2-hb-text h3 {
        font-family: var(--gq-head-font);
        font-size: clamp(26px, 2.6vw, 40px);
        font-weight: 800;
        line-height: 1.1;
        color: #fff;
        margin: 0 0 12px;
}

.gqv2 .gqv2-hb-text p {
        font-size: 15px;
        line-height: 1.6;
        color: rgba(255, 255, 255, .85);
        margin: 0 0 22px;
        display: -webkit-box;
        -webkit-line-clamp: 3;
        line-clamp: 3;
        -webkit-box-orient: vertical;
        overflow: hidden;
}

.gqv2 .gqv2-hb-photos {
        position: relative;
        z-index: 1;
}

.gqv2 .gqv2-hb-photos img {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        opacity: 0;
        transition: opacity .7s ease;
}

.gqv2 .gqv2-hb-photos img.is-active {
        opacity: 1;
}

/* controls: arrows + counter pinned bottom-left */
    .gqv2 .gqv2-hb-controls {
        position: absolute;
        left: 46px;
        bottom: 28px;
        z-index: 4;
        display: flex;
        align-items: center;
        gap: 12px;
}

.gqv2 .gqv2-hb-controls button {
        width: 40px;
        height: 40px;
        border-radius: 50%;
        border: 1.5px solid rgba(255, 255, 255, .45);
        background: transparent;
        color: #fff;
        font-size: 13px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        transition: background .2s ease, border-color .2s ease, color .2s ease;
}

.gqv2 .gqv2-hb-controls button:hover {
        background: var(--gq-gold);
        border-color: var(--gq-gold);
        color: var(--gq-navy);
}

.gqv2 .gqv2-hb-count {
        font-size: 12px;
        font-weight: 800;
        letter-spacing: 2px;
        color: rgba(255, 255, 255, .75);
}

.gqv2 .gqv2-hb-count b {
        color: var(--gq-gold);
        font-size: 15px;
}

@media (max-width: 900px) {
    .gqv2 .gqv2-hb-stage {
            grid-template-columns: 1fr;
            height: auto;
    }

    .gqv2 .gqv2-hb-left::after {
            display: none;
    }

    .gqv2 .gqv2-hb-photos {
            order: -1;
            aspect-ratio: 3 / 2;
    }

    .gqv2 .gqv2-hb-text {
            position: relative;
            padding: 26px 24px 86px;
    }

    .gqv2 .gqv2-hb-text:not(.is-active) {
            display: none;
    }

    .gqv2 .gqv2-hb-controls {
            left: 24px;
            bottom: 22px;
    }
}

/* the ACTIVE hero (chosen in the drawer → moved right after the hero slot):
       drop the comparison framing so it sits tight, with the search bar right below */
    .gqv2 #gqv2-hero-slot + section.gqv2-section {
        padding: 18px 0 22px;
}

/* ==================== COVER STORY — LIGHT VARIANTS (C / D / E) ====================
       Airy, low-contrast alternatives to the dark spotlight looks. Fresh class
       prefixes (lcov / lcard / llist) so they never touch the older cover CSS. */

    /* --- C: light feature + thumbnail rail --- */
    .gqv2 .gqv2-lcov-feature {
        display: grid;
        grid-template-columns: 1fr 1.4fr;   /* narrower image (shorter 3:2) + wider text */
        gap: 34px;
        align-items: center;
        background: #fff;
        border: 1px solid var(--gq-line);
        border-radius: 22px;
        padding: 18px;
        box-shadow: var(--gq-shadow-sm);
}

/* single feature photo, 3:2, full column width */
    .gqv2 .gqv2-lcov-media {
        aspect-ratio: 3 / 2; width: 100%;
        border-radius: 16px; overflow: hidden; background: var(--gq-sky);
}

.gqv2 .gqv2-lcov-img {
        width: 100%; height: 100%; object-fit: cover; display: block;
        transition: opacity .3s ease;
}

.gqv2 .gqv2-lcov-text { padding: 8px 24px 8px 6px;
}

.gqv2 .gqv2-lcov-kicker {
        display: inline-flex; align-items: center; gap: 6px;
        font-size: 12.5px; font-weight: 800; letter-spacing: .4px; text-transform: uppercase;
        color: var(--gq-blue);
}

.gqv2 .gqv2-lcov-title {
        font-family: var(--gq-head-font);
        font-size: 30px; line-height: 1.18; margin: 10px 0 12px; color: var(--gq-navy);
        font-weight: 600;
}

.gqv2 .gqv2-lcov-excerpt {
        font-size: 15px; line-height: 1.7; color: var(--gq-charcoal); margin: 0 0 18px;
        display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden;
}

/* rail: nav arrows flank a flex track. Chip basis is responsive so a whole
       number fit the width — 8 desktop, 4 tablet, 2 mobile; the rest scroll. */
    .gqv2 .gqv2-lcov-railwrap {
        position: relative;
        display: flex;
        align-items: stretch;
        gap: 6px;
        margin-top: 18px;
}

.gqv2 .gqv2-lcov-rail {
        display: flex;
        gap: 10px;
        flex: 1;
        min-width: 0;
        overflow-x: auto;
        padding: 4px 2px 10px;
        scroll-snap-type: x mandatory;
        scroll-behavior: smooth;
        scrollbar-width: none;
        /* The chips are sized to fit eight across, so a month with fewer left
           them bunched against the left edge with a hole beside them.

           `safe` is doing the work, not `center`: on a scroll container plain
           centring pushes the overflow off BOTH ends, and whatever spills past
           the left edge can never be scrolled back to — scrollLeft 0 is already
           the far left. `safe` centres only while everything fits and reverts
           to flex-start the moment it does not, which is the state the arrows
           below appear in. A browser too old for it ignores the declaration and
           gets today's left-aligned rail, which is the right fallback. */
        justify-content: safe center;
}

.gqv2 .gqv2-lcov-rail::-webkit-scrollbar { display: none;
}

.gqv2 .gqv2-lcov-chip {
        position: relative;
        flex: 0 0 calc((100% - 7 * 10px) / 8);   /* 8 across on desktop */
        scroll-snap-align: start;
        display: flex; flex-direction: column; gap: 7px;
        background: #fff; border: 1px solid var(--gq-line); border-radius: 14px;
        padding: 7px 7px 9px; overflow: hidden;
        cursor: pointer; text-align: left;
        transition: transform .15s ease, border-color .15s ease, box-shadow .15s ease;
}

.gqv2 .gqv2-lcov-chip-img { display: block; border-radius: 9px; overflow: hidden; background: var(--gq-sky);
}

.gqv2 .gqv2-lcov-chip-img img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; display: block;
}

/* city / state label (was the title) */
    .gqv2 .gqv2-lcov-loc-lbl {
        display: flex; align-items: center; gap: 5px;
        font-size: 11px; font-weight: 700; line-height: 1.25; color: var(--gq-navy);
        padding: 0 2px 2px;
        white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.gqv2 .gqv2-lcov-loc-lbl i { color: var(--gq-blue); font-size: 10px; flex-shrink: 0;
}

.gqv2 .gqv2-lcov-chip:hover { transform: translateY(-3px); box-shadow: var(--gq-shadow-sm);
}

.gqv2 .gqv2-lcov-chip.is-active { border-color: var(--gq-blue); box-shadow: 0 0 0 2px color-mix(in srgb, var(--gq-blue) 30%, transparent);
}

/* full cover title on hover */
    .gqv2 .gqv2-lcov-chip::after {
        content: attr(data-title);
        position: absolute; left: 50%; bottom: calc(100% + 8px); transform: translateX(-50%) translateY(4px);
        background: rgba(7, 20, 35, .95); color: #fff; font-size: 12px; font-weight: 700; line-height: 1.3;
        text-align: center; padding: 7px 11px; border-radius: 8px; width: max-content; max-width: 220px;
        pointer-events: none; opacity: 0; transition: opacity .18s ease, transform .18s ease; z-index: 6;
        box-shadow: 0 10px 22px -8px rgba(0, 0, 0, .55);
}

.gqv2 .gqv2-lcov-chip:hover::after { opacity: 1; transform: translateX(-50%) translateY(0);
}

/* time bar — fills over the autoplay interval on the active chip */
    .gqv2 .gqv2-lcov-bar {
        position: absolute; left: 0; bottom: 0; height: 3px; width: 0;
        background: var(--gq-blue); border-radius: 0 3px 0 0;
}

.gqv2 .gqv2-lcov-chip.is-active .gqv2-lcov-bar { animation: gqv2LcovBar var(--gqv2-cov-ms, 6500ms) linear forwards;
}

.gqv2 .gqv2-lcov-rail.is-paused .gqv2-lcov-chip.is-active .gqv2-lcov-bar { animation-play-state: paused;
}

@keyframes gqv2LcovBar { from { width: 0; } to { width: 100%; }
}

/* prev / next arrows — shown only when the rail overflows */
    .gqv2 .gqv2-lcov-nav {
        flex: 0 0 auto; align-self: center;
        width: 38px; height: 38px; border-radius: 50%;
        border: 1px solid var(--gq-line); background: #fff; color: var(--gq-navy);
        cursor: pointer; display: none; align-items: center; justify-content: center;
        box-shadow: var(--gq-shadow-sm); transition: background .15s ease, color .15s ease;
}

.gqv2 .gqv2-lcov-nav:hover { background: var(--gq-navy); color: #fff;
}

@media (max-width: 860px) {
    .gqv2 .gqv2-lcov-feature { grid-template-columns: 1fr; gap: 6px;
    }

    .gqv2 .gqv2-lcov-text { padding: 12px 14px 16px;
    }

    .gqv2 .gqv2-lcov-title { font-size: 24px;
    }
}

/* 4 across on smaller screens */
    @media (max-width: 1000px) {
    .gqv2 .gqv2-lcov-chip { flex-basis: calc((100% - 3 * 10px) / 4);
    }

    .gqv2 .gqv2-lcov-nav { display: inline-flex;
    }
}

/* 2 across on mobile, with the arrows */
    @media (max-width: 600px) {
    .gqv2 .gqv2-lcov-chip { flex-basis: calc((100% - 1 * 10px) / 2);
    }
}

/* ==================== GET INSPIRED (stories) ==================== */
    /* aside + scrollable guide carousel (slides-per-view set in Swiper config) */
    .gqv2 .gqv2-inspired {
        display: grid;
        grid-template-columns: 200px minmax(0, 1fr);
        gap: 16px;
        align-items: stretch;
}

/* shell holds the carousel with side gutters; arrows live in the gutters */
    .gqv2 .gqv2-guides-shell {
        position: relative;
        padding: 0 48px;
        min-width: 0;
}

.gqv2 .gqv2-guidesSwiper {
        width: 100%;
}

.gqv2 .gqv2-guides-shell .swiper-button-prev,
.gqv2 .gqv2-guides-shell .swiper-button-next {
        width: 38px;
        height: 38px;
        border-radius: 50%;
        background: #fff;
        color: var(--gq-navy);
        border: 1px solid var(--gq-line);
        box-shadow: var(--gq-shadow-sm);
        top: 50%;
        margin-top: -19px;
}

.gqv2 .gqv2-guides-shell .swiper-button-prev {
        left: 0;
}

.gqv2 .gqv2-guides-shell .swiper-button-next {
        right: 0;
}

.gqv2 .gqv2-guides-shell .swiper-button-prev::after,
.gqv2 .gqv2-guides-shell .swiper-button-next::after {
        font-size: 13px;
        font-weight: 800;
}

.gqv2 .gqv2-inspired-aside {
        display: flex;
        flex-direction: column;
        justify-content: center;
}

.gqv2 .gqv2-inspired-aside .gqv2-script {
        font-size: 40px;
        line-height: 1;
        margin-bottom: 14px;
        display: block;
}

.gqv2 .gqv2-inspired-aside p {
        color: var(--gq-mist);
        font-size: 15px;
        font-weight: 500;
        line-height: 1.6;
        margin: 0 0 18px;
}

/* .gqv2-textlink moved to site.css — the story page uses it too. */

.gqv2 .gqv2-story {
        position: relative;
        border-radius: var(--gq-radius);
        overflow: hidden;
        aspect-ratio: 2 / 3;
        display: flex;
        align-items: flex-end;
        color: #fff;
        box-shadow: var(--gq-shadow-sm);
        transition: transform .22s ease;
}

.gqv2 .gqv2-story:hover {
        transform: translateY(-6px);
        color: #fff;
}

.gqv2 .gqv2-story {
        background: #0d2c4b;
}

.gqv2 .gqv2-story img {
        position: absolute;
        top: 0;
        left: 0;
        /* guide covers: fill the full width at natural ratio, anchored to the top —
           never cropped horizontally; any leftover space at the bottom shows the navy bg */
        width: 100%;
        height: auto;
        transition: transform .5s ease;
}

.gqv2 .gqv2-story:hover img {
        transform: scale(1.07);
}

.gqv2 .gqv2-story::after {
        content: "";
        position: absolute;
        inset: 0;
        background: linear-gradient(to top, rgba(13, 34, 58, .97) 10%, rgba(13, 34, 58, .55) 42%, rgba(13, 34, 58, .05) 72%);
}

.gqv2 .gqv2-story-body {
        position: relative;
        z-index: 2;
        padding: 16px 10px;
        width: 100%;
}

/* small state line above the title */
    .gqv2 .gqv2-story-loc {
        display: flex;
        align-items: center;
        gap: 5px;
        font-size: 11px;
        font-weight: 800;
        letter-spacing: .8px;
        text-transform: uppercase;
        color: #FFD98A;
        text-shadow: 0 1px 6px rgba(0, 0, 0, .65);
        margin: 0 0 5px;
}

.gqv2 .gqv2-story-loc i {
        font-size: 10px;
        color: var(--gq-gold);
}

.gqv2 .gqv2-story-body h3 {
        font-family: var(--gq-font);
        font-size: 14.5px;
        font-weight: 800;
        line-height: 1.3;
        margin: 0 0 5px;
        color: #fff;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
}

.gqv2 .gqv2-story-body .gqv2-readmore {
        font-size: 10.5px;
        font-weight: 800;
        letter-spacing: 1px;
        text-transform: uppercase;
        color: #fff;
        border-bottom: 2px solid var(--gq-gold);
        padding-bottom: 2px;
}

/* ==================== SHORTS (hover-to-play videos) ==================== */
    .gqv2 .gqv2-shorts {
        background: linear-gradient(180deg, #0d2c4b 0%, var(--gq-navy) 100%);
}

.gqv2 .gqv2-shorts .gqv2-script {
        color: var(--gq-gold);
        font-size: 40px;
        line-height: 1;
}

.gqv2 .gqv2-shorts .gqv2-shorts-sub {
        display: block;
        margin: 9px 0 0;
        max-width: 54ch;
        color: rgba(255, 255, 255, .75);
        font-size: 15px;
        font-weight: 600;
        line-height: 1.5;
}

.gqv2 .gqv2-shorts-head {
        margin-bottom: 26px;
}

.gqv2 .gqv2-short-ytframe {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        border: 0;
        z-index: 1;
        pointer-events: none;   /* keep card hover/click behaviour */
}

/* the card title links to the listing */
    .gqv2 .gqv2-short-info h3 a { color: inherit; text-decoration: none;
}

.gqv2 .gqv2-short-info h3 a:hover { text-decoration: underline;
}

.gqv2 .gqv2-short-grad {
        position: absolute;
        inset: 0;
        background: linear-gradient(to top, rgba(7, 20, 35, .92) 0%, rgba(7, 20, 35, .25) 34%, rgba(7, 20, 35, 0) 55%);
        pointer-events: none;
}

/* center play button — fades out while playing */
    .gqv2 .gqv2-short-play {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 52px;
        height: 52px;
        border-radius: 50%;
        border: 0;
        background: rgba(255, 255, 255, .92);
        color: var(--gq-navy);
        font-size: 16px;
        display: flex;
        align-items: center;
        justify-content: center;
        pointer-events: none;
        box-shadow: 0 12px 28px -10px rgba(0, 0, 0, .6);
        transition: opacity .25s ease, transform .25s ease;
}

.gqv2 .gqv2-short-play i {
        margin-left: 3px;
}

/* mute toggle — appears while playing */
    .gqv2 .gqv2-short-mute {
        position: absolute;
        right: 10px;
        bottom: 64px;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        border: 0;
        background: rgba(0, 0, 0, .55);
        color: #fff;
        font-size: 12px;
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        opacity: 0;
        transition: opacity .25s ease;
        z-index: 3;
}

.gqv2 .gqv2-short-info {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 3px;
        padding: 12px 10px;
        z-index: 2;
        pointer-events: none;
}

.gqv2 .gqv2-short-info .gqv2-short-loc {
        display: flex;
        align-items: center;
        gap: 5px;
        font-size: 10px;
        font-weight: 800;
        letter-spacing: .8px;
        text-transform: uppercase;
        color: #FFD98A;
        margin-bottom: 4px;
}

.gqv2 .gqv2-short-info h3 {
        font-family: var(--gq-font);
        font-size: 13px;
        font-weight: 800;
        line-height: 1.3;
        color: #fff;
        margin: 0;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
}

/* ==================== TRAVEL VIBES ==================== */
    .gqv2 .gqv2-vibes-grid {
        display: grid;
        grid-template-columns: 230px 1fr;
        gap: 30px;
        align-items: center;
}

.gqv2 .gqv2-vibes-aside .gqv2-script {
        font-size: 38px;
        line-height: 1.05;
        display: block;
        margin-bottom: 14px;
}

/* navy, not mist: this is the section's lead paragraph, not a caption, and a
   pale grey cannot carry 15px of it on a tinted band. Mist measured 3.93:1
   over sky and 4.19:1 over sand, both under the 4.5:1 WCAG AA floor for text
   this size, and slate only reached 5.03:1 — a pass on paper that still read
   as washed out. Navy is 9.47:1 and 10.1:1, clearing AAA on either band, and
   it partners the blue script heading above it rather than greying out under
   it. The token stays as it is — 89 other rules lean on mist for genuinely
   secondary text, which this is not. */
.gqv2 .gqv2-vibes-aside p {
        color: var(--gq-navy);
        font-size: 15px;
        font-weight: 500;
        line-height: 1.6;
        margin: 0 0 18px;
}

/* Reactive aside — hovering a tile turns the heading into that vibe's name (in its
       own colour) and swaps the line for its description. Both reserve height so the
       swap never nudges the "Explore all vibes" link below them: the heading holds two
       lines ("What's Your Travel Vibe?" wraps, most vibe names do not) and the line
       holds three. */
    .gqv2 .gqv2-vibes-aside .gqv2-vibe-title {
        min-height: 2.1em;
        transition: color .25s ease;
}

.gqv2 .gqv2-vibe-line {
        min-height: 4.8em;
        transition: opacity .18s ease;
}

.gqv2 .gqv2-vibe-line.is-swapping { opacity: 0;
}

.gqv2 .gqv2-vibes {
        display: grid;
        grid-template-columns: repeat(5, 1fr);
        gap: 16px;
}

.gqv2 .gqv2-vibe {
        background: #fff;
        border: 1px solid var(--gq-line);
        border-radius: var(--gq-radius);
        padding: 26px 12px;
        text-align: center;
        transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
        color: var(--gq-navy);
}

.gqv2 .gqv2-vibe:hover {
        transform: translateY(-6px);
        box-shadow: var(--gq-shadow-sm);
        border-color: var(--gq-gold);
        color: var(--gq-navy);
}

.gqv2 .gqv2-vibe i {
        font-size: 30px;
        display: block;
        margin: 0 auto 14px;
}

.gqv2 .gqv2-vibe:nth-child(1) i { color: var(--gq-blue);
}

.gqv2 .gqv2-vibe:nth-child(2) i { color: var(--gq-green);
}

.gqv2 .gqv2-vibe:nth-child(3) i { color: var(--gq-gold);
}

.gqv2 .gqv2-vibe:nth-child(4) i { color: var(--gq-navy);
}

.gqv2 .gqv2-vibe:nth-child(5) i { color: var(--gq-blue);
}

.gqv2 .gqv2-vibe:nth-child(6) i { color: var(--gq-green);
}

.gqv2 .gqv2-vibe span {
        font-size: 12.5px;
        font-weight: 800;
        letter-spacing: .6px;
        text-transform: uppercase;
        line-height: 1.4;
        display: block;
}

/* ==================== WORTH THE DRIVE — E: auto-scroll rail ====================
       A single-row rail: rAF drift (auto-scroll), grab/touch, and prev/next arrows.
       Same real-scroll-container approach as the shorts marquee. */
    .gqv2 .gqv2-wtd-shell { position: relative;
}

.gqv2 .gqv2-wtd-marquee {
        overflow-x: auto;
        overflow-y: hidden;
        padding: 6px 2px 12px;
        cursor: grab;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        -ms-overflow-style: none;
}

.gqv2 .gqv2-wtd-marquee::-webkit-scrollbar { display: none;
}

.gqv2 .gqv2-wtd-marquee.is-dragging { cursor: grabbing; user-select: none; -webkit-user-select: none;
}

.gqv2 .gqv2-wtd-marquee.is-dragging .gqv2-wtd-card { pointer-events: none;
}

.gqv2 .gqv2-wtd-track { display: flex; gap: 18px; width: max-content;
}

.gqv2 .gqv2-wtd-card {
        flex: 0 0 262px;
        display: flex;
        flex-direction: column;
        background: #fff;
        border: 1px solid var(--gq-line);
        border-radius: 16px;
        overflow: hidden;
        box-shadow: var(--gq-shadow-sm);
        color: var(--gq-navy);
        transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}

.gqv2 .gqv2-wtd-card:hover {
        transform: translateY(-4px);
        box-shadow: var(--gq-shadow);
        border-color: var(--gq-blue);
        color: var(--gq-navy);
}

/* Fixed 16:10 window. The image is taken OUT of flow (absolute + inset) so a
       portrait source can never define the box height — with height:100% alone a
       non-definite parent height falls back to auto and one tall photo stretched
       the whole stretch-aligned row. overflow:hidden clips the cover crop. */
    .gqv2 .gqv2-wtd-media {
        position: relative;
        display: block;
        aspect-ratio: 3 / 2;
        overflow: hidden;
        flex: 0 0 auto;
}

.gqv2 .gqv2-wtd-media img {
        position: absolute;
        inset: 0;
        width: 100%; height: 100%; object-fit: cover; display: block;
        -webkit-user-drag: none; user-select: none;
}

/* Left, so it clears the request toggle anchored right. Same corner the state
   badge used to occupy, at the same 10px inset. */
.gqv2 .gqv2-wtd-media .gqv2-vibe-tag {
        top: 10px;
        left: 10px;
        right: auto;
}

.gqv2 .gqv2-wtd-body { display: flex; flex-direction: column; padding: var(--gq-card-gap-top) 15px 15px; flex: 1 1 auto;
}

.gqv2 .gqv2-wtd-town { font-size: 11.5px; font-weight: 700; color: var(--gq-gold-dark);
}

.gqv2 .gqv2-wtd-town i { font-size: 10px; margin-right: 4px;
}

/* clamped so a long name can't drive the row taller than its neighbours */
    .gqv2 .gqv2-wtd-title {
        margin: 4px 0 5px; font-size: 15.5px; font-weight: 600; line-height: 1.25; color: var(--gq-navy);
        display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}

.gqv2 .gqv2-wtd-desc {
        font-size: 12.5px; line-height: 1.5; color: var(--gq-slate);
        display: -webkit-box; -webkit-line-clamp: 6; line-clamp: 6; -webkit-box-orient: vertical; overflow: hidden;
}

/* prev / next arrows, overlaying both edges */
    .gqv2 .gqv2-wtd-arrow {
        position: absolute;
        top: calc(50% - 6px);
        transform: translateY(-50%);
        z-index: 4;
        width: 44px; height: 44px;
        border-radius: 50%;
        border: 1px solid var(--gq-line);
        background: #fff;
        color: var(--gq-navy);
        font-size: 15px;
        cursor: pointer;
        display: grid; place-items: center;
        box-shadow: 0 8px 22px -8px rgba(18, 59, 99, .5);
        transition: background .18s ease, color .18s ease, transform .18s ease;
}

.gqv2 .gqv2-wtd-arrow.prev { left: -8px;
}

.gqv2 .gqv2-wtd-arrow.next { right: -8px;
}

.gqv2 .gqv2-wtd-arrow:hover { background: var(--gq-blue); color: #fff; transform: translateY(-50%) scale(1.06);
}

@media (max-width: 620px) {
    .gqv2 .gqv2-wtd-card { flex: 0 0 220px;
    }

    .gqv2 .gqv2-wtd-arrow { width: 38px; height: 38px; font-size: 13px;
    }

    .gqv2 .gqv2-wtd-arrow.prev { left: -4px;
    }

    .gqv2 .gqv2-wtd-arrow.next { right: -4px;
    }
}

/* ==================== SHORTS C: continuous marquee ====================
       A real scroll container rather than a CSS keyframe translate: that is what
       lets a finger swipe (native) and a mouse drag (JS) grab it. The drift is
       driven by rAF in JS — see the SHORTS C block. */
    .gqv2 .gqv2-shc-marquee {
        overflow-x: auto;
        overflow-y: hidden;
        padding: 6px 0 10px;
        position: relative;
        cursor: grab;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;             /* the rail is its own affordance */
        -ms-overflow-style: none;
}

.gqv2 .gqv2-shc-marquee::-webkit-scrollbar { display: none;
}

/* grabbing must not smear a text selection across the rail */
    .gqv2 .gqv2-shc-marquee.is-dragging {
        cursor: grabbing;
        user-select: none;
        -webkit-user-select: none;
}

/* ...nor start a native image drag */
    .gqv2 .gqv2-shc-item img {
        -webkit-user-drag: none;
        user-select: none;
        -webkit-user-select: none;
}

/* a drag must not trip hover-play or land as a click on a tile */
    .gqv2 .gqv2-shc-marquee.is-dragging .gqv2-shc-item { pointer-events: none;
}

/* edge fade sits on the shell — inside a scroll container it would scroll away */
    .gqv2 .gqv2-shc-shell::before,
.gqv2 .gqv2-shc-shell::after {
        content: "";
        position: absolute;
        top: 42px;
        bottom: 0;
        width: 90px;
        z-index: 2;
        pointer-events: none;
}

.gqv2 .gqv2-shc-shell::before { left: 0;  background: linear-gradient(to right, #0d2c4b, transparent);
}

.gqv2 .gqv2-shc-shell::after { right: 0; background: linear-gradient(to left,  var(--gq-navy), transparent);
}

.gqv2 .gqv2-shc-track {
        display: flex;
        gap: 14px;
        width: max-content;
}

/* --- marquee scroll controls --- */
    .gqv2 .gqv2-shc-shell { position: relative; padding-top: 42px; --gqv2-dwell: 500ms;
}

.gqv2 .gqv2-shc-controls {
        position: absolute;
        right: 24px;
        top: 0;
        display: flex;
        gap: 8px;
        z-index: 4;
}

.gqv2 .gqv2-shc-ctl {
        width: 34px;
        height: 34px;
        border-radius: 50%;
        border: 1px solid rgba(255, 255, 255, .28);
        background: rgba(255, 255, 255, .10);
        color: #EAF3FA;
        font-size: 12px;
        cursor: pointer;
        display: grid;
        place-items: center;
        transition: background .2s ease, border-color .2s ease, color .2s ease;
}

.gqv2 .gqv2-shc-ctl:hover { background: rgba(255, 255, 255, .20); border-color: rgba(255, 255, 255, .5);
}

.gqv2 .gqv2-shc-ctl.is-on { background: #EAF3FA; border-color: #EAF3FA; color: var(--gq-navy);
}

.gqv2 .gqv2-shc-item {
        position: relative;
        width: 190px;
        height: 338px;          /* fixed height so hover can widen to the clip's real ratio */
        border-radius: 14px;
        overflow: hidden;
        flex-shrink: 0;
        cursor: pointer;
        background: #0a2038;
        transition: transform .25s ease, width .32s cubic-bezier(.22, .61, .36, 1);
}

.gqv2 .gqv2-shc-item:hover { transform: translateY(-6px);
}

.gqv2 .gqv2-shc-item img,
.gqv2 .gqv2-shc-item video {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
}

.gqv2 .gqv2-shc-item video { z-index: 1;
}

.gqv2 .gqv2-shc-item .gqv2-short-grad,
.gqv2 .gqv2-shc-item .gqv2-short-info { z-index: 2;
}

.gqv2 .gqv2-shc-item .gqv2-short-play { z-index: 3;
}

.gqv2 .gqv2-shc-item.is-playing .gqv2-short-play { opacity: 0;
}

.gqv2 .gqv2-shc-item .gqv2-short-play::before {
        content: "";
        position: absolute;
        inset: -6px;
        border-radius: 50%;
        opacity: 0;
        transition: opacity .18s ease;
        background: conic-gradient(var(--gq-orange) calc(var(--gqload) * 360deg), rgba(255, 255, 255, .28) 0);
        -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
                mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 3px));
}

/* phase 1 — determinate fill over the dwell */
    .gqv2 .gqv2-shc-item.is-arming .gqv2-short-play::before {
        opacity: 1;
        animation: gqv2Arm var(--gqv2-dwell, 500ms) linear forwards;
}

@keyframes gqv2Arm { from { --gqload: 0; } to { --gqload: 1; }
}

/* phase 2 — indeterminate, only while the clip is actually fetching */
    .gqv2 .gqv2-shc-item.is-buffering .gqv2-short-play::before {
        opacity: 1;
        background: conic-gradient(var(--gq-orange) 0 90deg, rgba(255, 255, 255, .28) 90deg);
        animation: gqv2Spin .8s linear infinite;
}

@keyframes gqv2Spin { to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
    .gqv2 .gqv2-shc-item.is-buffering .gqv2-short-play::before { animation-duration: 2s;
    }
}

/* ---- playback progress along the bottom edge ---- */
    .gqv2 .gqv2-shc-bar {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        height: 3px;
        z-index: 5;
        background: rgba(255, 255, 255, .18);
        opacity: 0;
        transition: opacity .25s ease;
        pointer-events: none;
}

.gqv2 .gqv2-shc-item.is-playing .gqv2-shc-bar { opacity: 1;
}

.gqv2 .gqv2-shc-bar i {
        display: block;
        height: 100%;
        width: calc(var(--prog, 0) * 100%);
        background: var(--gq-orange);
        box-shadow: 0 0 8px rgba(217, 108, 71, .8);
}

/* YouTube tiles get a real bar too, driven by the IFrame Player API */

    /* mute toggle — only meaningful once a clip is actually playing */
    .gqv2 .gqv2-shc-item .gqv2-short-mute {
        position: absolute;
        top: 10px;
        right: 10px;
        z-index: 4;
        width: 32px;
        height: 32px;
        border-radius: 50%;
        border: 0;
        background: rgba(8, 26, 45, .62);
        backdrop-filter: blur(4px);
        color: #fff;
        font-size: 12px;
        cursor: pointer;
        display: grid;
        place-items: center;
        opacity: 0;
        transform: scale(.85);
        transition: opacity .2s ease, transform .2s ease, background .2s ease;
}

.gqv2 .gqv2-shc-item.is-playing .gqv2-short-mute { opacity: 1; transform: scale(1);
}

.gqv2 .gqv2-shc-item .gqv2-short-mute:hover { background: rgba(8, 26, 45, .85);
}

/* ring fills over the 3s fade-in so the volume ramp is visible, not a surprise */
    .gqv2 .gqv2-shc-item .gqv2-short-mute::after {
        content: "";
        position: absolute;
        inset: -3px;
        border-radius: 50%;
        pointer-events: none;
        opacity: var(--volring, 0);
        background: conic-gradient(#EAF3FA calc(var(--vol, 0) * 360deg), rgba(255, 255, 255, .18) 0);
        -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
                mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
        transition: opacity .25s ease;
}

/* ---------- shorts modal ---------- */
    .gqv2-shm {
        position: fixed;
        inset: 0;
        z-index: 9999;
        display: grid;
        place-items: center;
        padding: 24px;
}

.gqv2-shm[hidden] { display: none;
}

.gqv2-shm-backdrop {
        position: absolute;
        inset: 0;
        background: rgba(6, 18, 32, .88);
        backdrop-filter: blur(6px);
        animation: gqv2ShmFade .25s ease;
}

@keyframes gqv2ShmFade { from { opacity: 0; } to { opacity: 1; }
}

.gqv2-shm-dialog {
        position: relative;
        z-index: 1;
        display: flex;
        align-items: center;
        gap: 18px;
        animation: gqv2ShmRise .28s cubic-bezier(.22, .61, .36, 1);
}

@keyframes gqv2ShmRise {
        from { opacity: 0; transform: translateY(18px) scale(.97); }
        to   { opacity: 1; transform: none; }
}

.gqv2-shm-col {
        display: flex;
        flex-direction: column;
        gap: 13px;
        min-width: 0;
}

.gqv2-shm-stage {
        position: relative;
        height: min(66vh, 600px);      /* leaves room for the meta block beneath */
        /* the second term reserves the flanking arrows and the modal's own
           padding — without it a tablet-width window pushes the next arrow
           off-screen */
        max-width: min(86vw, calc(100vw - 180px));
        /* JS writes the clip's real ratio into --gqv2-shm-ratio. A custom
           property rather than an inline aspect-ratio, so the phone layout
           below can drop the ratio without fighting an inline style. */
        aspect-ratio: var(--gqv2-shm-ratio, 9 / 16);
        background: #000;
        border-radius: 16px;
        overflow: hidden;
        box-shadow: 0 30px 80px -20px rgba(0, 0, 0, .8);
        transition: aspect-ratio .3s ease;
}

/* hover previews are click-through; the modal player must not be */
    .gqv2-shm-stage .gqv2-short-ytframe { pointer-events: auto;
}

.gqv2-shm-stage video,
.gqv2-shm-stage iframe {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        border: 0;
        object-fit: contain;
        background: #000;
}

.gqv2-shm-nav,
.gqv2-shm-close {
        width: 48px;
        height: 48px;
        border-radius: 50%;
        border: 1px solid rgba(255, 255, 255, .25);
        background: rgba(255, 255, 255, .10);
        color: #fff;
        font-size: 16px;
        cursor: pointer;
        display: grid;
        place-items: center;
        flex-shrink: 0;
        transition: background .2s ease, border-color .2s ease, transform .2s ease;
}

.gqv2-shm-nav:hover,
.gqv2-shm-close:hover { background: rgba(255, 255, 255, .22); border-color: rgba(255, 255, 255, .55);
}

.gqv2-shm-close:hover { transform: scale(1.06);
}

/* prev · counter · next. They sit in the meta row for the phone; here the two
   buttons are lifted out of the row to flank the clip, which leaves the pager
   holding just the counter — the desktop layout it always had. */
    .gqv2-shm-pager {
        display: flex;
        align-items: center;
        gap: 10px;
        flex-shrink: 0;
        order: -1;                 /* the counter leads the row; the phone puts it back */
}

.gqv2-shm-nav {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        z-index: 2;
}

.gqv2-shm-nav:hover { transform: translateY(-50%) scale(1.06);
}

.gqv2-shm-nav.prev { left: -66px;
}

.gqv2-shm-nav.next { right: -66px;
}

.gqv2-shm-close {
        position: absolute;
        top: -6px;
        right: -6px;
        z-index: 3;
        width: 40px;
        height: 40px;
        font-size: 14px;
        transform: translate(100%, -100%);
}

.gqv2-shm-close:hover { transform: translate(100%, -100%) scale(1.06);
}

.gqv2-shm-meta {
        display: flex;
        flex-direction: column;
        gap: 11px;
        padding: 0 2px;
        /* the column is the clip's width, not the title's: without this a long
           title sets the intrinsic width and drags the flanking arrows off
           screen. Zero contributes nothing, min-width fills the column back. */
        width: 0;
        min-width: 100%;
}

/* text on the left, counter on the right of it — the phone drops this to a
   column and centres the pager underneath */
    .gqv2-shm-head {
        display: flex;
        align-items: center;
        gap: 16px;
}

.gqv2-shm-text { flex: 1; min-width: 0;
}

/* the listing link rides alongside the state, not on a row of its own */
    .gqv2-shm-topline {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 6px 14px;
}

.gqv2-shm-loc {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        font-size: 12px;
        font-weight: 600;
        color: #BFDCEC;
        letter-spacing: .3px;
}

.gqv2-shm-title {
        margin: 3px 0 0;
        font-size: 16px;
        font-weight: 700;
        color: #fff;
        line-height: 1.3;
        /* two lines, then ellipsis — a long title must not eat the clip */
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        overflow: hidden;
}

/* scoped through .gqv2 to outrank `.gqv2 a { color: inherit }` — the modal is
   moved to <body>, which carries that class, so a bare .gqv2-shm-link left the
   label sitting at the body's dark text colour on a near-black pill */
    .gqv2 .gqv2-shm-link {
        display: inline-flex;
        align-items: center;
        gap: 7px;
        font-size: 13px;
        font-weight: 600;
        color: #fff;
        text-decoration: none;
        padding: 2px 0;            /* no pill; it sits on the state's line now */
        border-bottom: 1px solid rgba(255, 255, 255, .35);
        transition: border-color .2s ease;
}

.gqv2 .gqv2-shm-link i { transition: transform .2s ease;
}

.gqv2 .gqv2-shm-link:hover { color: #fff; border-bottom-color: #fff;
}

.gqv2 .gqv2-shm-link:hover i { transform: translateX(3px);
}

/* the counter doubles as the clip's clock — see the ring below */
    .gqv2-shm-count {
        position: relative;
        display: grid;
        place-items: center;
        width: 46px;
        height: 46px;
        border-radius: 50%;
        background: rgba(255, 255, 255, .07);
        font-size: 12px;
        font-weight: 600;
        color: #BFDCEC;
        flex-shrink: 0;
}

/* time left, drawn the same way as the tile's volume ring: a conic sweep
   masked down to a hairline. JS drains --left from 1 to 0 over the clip. */
    .gqv2-shm-count::after {
        content: "";
        position: absolute;
        inset: 0;
        border-radius: 50%;
        pointer-events: none;
        background: conic-gradient(#EAF3FA calc(var(--left, 1) * 360deg), rgba(255, 255, 255, .16) 0);
        -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
                mask: radial-gradient(farthest-side, transparent calc(100% - 2px), #000 calc(100% - 2px));
}

/* --- phone: a full-screen sheet ---
   Flanking arrows and a fixed-height stage don't fit 375px: the row measured
   wider than the viewport, which pushed the next arrow off-screen, and the
   fixed height letterboxed a 16:9 clip inside a portrait box. So the dialog
   fills the screen, the stage takes whatever the meta leaves, and the arrows
   sit over the video. */
@media (max-width: 700px) {
    .gqv2-shm { padding: 0;
    }

    .gqv2-shm-dialog {
        width: 100vw;
        height: 100vh;
        height: 100dvh;            /* the browser chrome must not crop the meta */
        gap: 0;
    }

    .gqv2-shm-col {
        width: 100%;
        height: 100%;
        min-height: 0;
        gap: 0;
        justify-content: center;
    }

    /* Sized from the clip's own ratio and centred in what the meta leaves,
       rather than filling it: a stage taller than the clip strands the
       player's own chrome at the far edges of a black slab. */
    .gqv2-shm-stage {
        flex: 0 1 auto;
        width: 100%;
        height: auto;
        max-width: none;
        max-height: 100%;          /* a portrait clip letterboxes rather than overflow */
        border-radius: 0;
        box-shadow: none;
    }

    /* back into the meta row, either side of the counter — nothing covers the
       clip and the whole pager sits under the thumb */
    .gqv2-shm-nav {
        position: static;
        transform: none;
        width: 42px;
        height: 42px;
        font-size: 14px;
    }

    .gqv2-shm-nav:hover { transform: none;
    }

    /* prev · counter · next, centred on their own row under the title */
    .gqv2-shm-head { flex-direction: column; align-items: stretch; gap: 12px;
    }

    .gqv2-shm-pager { order: 0; justify-content: center; gap: 14px;
    }

    .gqv2-shm-close {
        top: max(10px, env(safe-area-inset-top));
        right: 10px;
        transform: none;
    }

    .gqv2-shm-close:hover { transform: scale(1.06);
    }

    .gqv2-shm-meta {
        flex-shrink: 0;
        gap: 9px;
        padding: 12px 14px calc(12px + env(safe-area-inset-bottom));
        background: rgba(6, 18, 32, .6);
    }

    .gqv2-shm-title { font-size: 14px;
    }

    /* a thumb has to hit it, but it shares the state's line — the extra height
       goes above the text so the underline stays tight to it */
    .gqv2 .gqv2-shm-link { font-size: 14px; padding: 9px 0 5px;
    }
}

/* ==================== CLOSE TO HOME / WORTH THE DRIVE (bento destination mosaics) ==================== */
    .gqv2 .gqv2-near-chip {
        display: inline-flex;
        align-items: center;
        gap: 7px;
        background: rgba(18, 59, 99, .08);
        border: 1px solid rgba(18, 59, 99, .16);
        color: var(--gq-navy);
        font-size: 12px;
        font-weight: 700;
        padding: 6px 14px;
        border-radius: 999px;
        margin-bottom: 10px;
}

.gqv2 .gqv2-near-chip i {
        color: var(--gq-blue);
}

.gqv2 .gqv2-ntile {
        position: relative;
        display: block;
        border-radius: 16px;
        overflow: hidden;
        background: #0a2038;
        box-shadow: var(--gq-shadow-sm);
        transition: transform .22s ease, box-shadow .22s ease;
}

.gqv2 .gqv2-ntile:hover {
        transform: translateY(-4px);
        box-shadow: var(--gq-shadow);
}

.gqv2 .gqv2-ntile.big { grid-column: span 2; grid-row: span 2;
}

.gqv2 .gqv2-ntile.wide { grid-column: span 2;
}

.gqv2 .gqv2-ntile img {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        transition: transform .5s ease;
}

.gqv2 .gqv2-ntile:hover img {
        transform: scale(1.06);
}

.gqv2 .gqv2-ntile .gqv2-short-grad { z-index: 1;
}

.gqv2 .gqv2-near-info {
        position: absolute;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 2;
        padding: 16px;
        pointer-events: none;
}

.gqv2 .gqv2-near-drive {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        font-size: 10px;
        font-weight: 800;
        letter-spacing: .8px;
        text-transform: uppercase;
        color: #FFD98A;
        margin-bottom: 5px;
}

.gqv2 .gqv2-near-info h3 {
        font-family: var(--gq-head-font);
        font-size: 20px;
        /* 600 across every listing-card title, matching the cover story headline —
           700/800 read as heavy blocks at these small card sizes */
        font-weight: 600;
        line-height: 1.2;
        color: #fff;
        margin: 0;
}

.gqv2 .gqv2-ntile.big .gqv2-near-info { padding: 20px;
}

.gqv2 .gqv2-ntile.big .gqv2-near-info h3 { font-size: 27px;
}

/* description only fits comfortably on the two larger tiles */
    .gqv2 .gqv2-near-info p { display: none;
}

.gqv2 .gqv2-ntile.big .gqv2-near-info p,
.gqv2 .gqv2-ntile.wide .gqv2-near-info p {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        font-size: 12.5px;
        line-height: 1.5;
        color: rgba(255, 255, 255, .85);
        margin: 5px 0 0;
}

@media (max-width: 900px) {
    .gqv2 .gqv2-ntile.big { grid-row: span 2;
    }
}

/* ---- NEAR/BEYOND variant B (near): spotlight + side rail ---- */
    /* .gqv2-nb / .gqv2-nb-main removed with Close to Home Option B.
       The -list / -item / -body rules below stay — Option E's rail uses them. */
    .gqv2 .gqv2-nb-list {
        display: flex;
        flex-direction: column;
        gap: 14px;
}

/* ---- the rotating column ----
   Four tiles beside it never move; this column advances through the surplus so
   a destination ranked ninth is seen at all. Present only where there IS a
   surplus — the view omits the whole apparatus at four, and then these rules
   never match. Trello card FSsAyJmW. */
.gqv2 .gqv2-nb-col {
        position: relative;
        /* the grid would otherwise stretch this to the tiles' height, and a
           scroll container cannot size itself from a stretched parent */
        align-self: start;
}

.gqv2 .gqv2-nb-col[data-nb-rotate] .gqv2-nb-view {
        overflow-y: auto;
        overflow-x: hidden;
        scroll-snap-type: y proximity;
        overscroll-behavior: contain;
        scrollbar-width: none;
}

.gqv2 .gqv2-nb-col[data-nb-rotate] .gqv2-nb-view::-webkit-scrollbar { display: none;
}

.gqv2 .gqv2-nb-col[data-nb-rotate] .gqv2-nb-item { scroll-snap-align: start;
}

/* Over the column, top and bottom, and only while the pointer is on it: two
   arrows parked there permanently read as broken pagination on a section that
   is otherwise still. Keyboard focus brings them back. */
.gqv2 .gqv2-nb-arrow {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        z-index: 3;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 38px;
        height: 38px;
        padding: 0;
        border: 1px solid var(--gq-line);
        border-radius: 50%;
        background: rgba(255, 255, 255, .94);
        color: var(--gq-navy);
        font-size: 13px;
        cursor: pointer;
        opacity: 0;
        transition: opacity .18s ease, background .18s ease, color .18s ease;
        box-shadow: 0 6px 18px -8px rgba(6, 20, 38, .55);
}

.gqv2 .gqv2-nb-arrow.up { top: -6px;
}

.gqv2 .gqv2-nb-arrow.down { bottom: -6px;
}

.gqv2 .gqv2-nb-col:hover .gqv2-nb-arrow,
.gqv2 .gqv2-nb-arrow:focus-visible { opacity: 1;
}

.gqv2 .gqv2-nb-arrow:hover { background: #fff; color: var(--gq-blue);
}

.gqv2 .gqv2-nb-item {
        flex: 1;
        display: flex;
        gap: 16px;
        background: #fff;
        border-radius: 14px;
        overflow: hidden;
        box-shadow: var(--gq-shadow-sm);
        color: var(--gq-navy);
        transition: transform .22s ease, box-shadow .22s ease;
}

.gqv2 .gqv2-nb-item:hover {
        transform: translateY(-3px);
        box-shadow: var(--gq-shadow);
        color: var(--gq-navy);
}

/* Width as a share of the rail column, height from 3:2. The share is what
       keeps this rail the same height as the mosaic beside it: both columns are
       fr fractions of the same grid, so a thumbnail sized in % of one tracks a
       tile sized in % of the other at every viewport. A fixed 200px did not —
       the rail stood 582px against the mosaic's 464.

       Width must stay the definite side and align-self must not be stretch. Set
       it the other way round (height:100% + ratio) and the item's height feeds
       back into the row that is sizing it: the thumbnail took the full 509px
       column. That is the same circularity behind the old bug where every card
       ballooned to the full 280px image. */
    .gqv2 .gqv2-nb-item img {
        width: 31%;
        aspect-ratio: 3 / 2;
        height: auto;
        align-self: flex-start;
        object-fit: cover;
        flex-shrink: 0;
}

/* Kept shorter than the 3:2 image beside it. If the body wins the flex line
   the item grows, the image cannot follow without losing its ratio, and the
   difference shows up twice: a sliver of card under the thumbnail, and a
   mosaic that opens its row gutter to stay level with the taller rail.
   Tighter than --gq-card-gap-top on purpose — that token is the space under a
   photo, and here the photo is alongside. */
.gqv2 .gqv2-nb-body {
        padding: 8px 16px 8px 0;
        display: flex;
        flex-direction: column;
        justify-content: center;
}

/* One line of title, two of blurb. Four items have to fit the height of two
   3:2 tiles, so the split is fixed rather than left to the copy — a title that
   took a second line used to push the blurb out and stretch the row. */
.gqv2 .gqv2-nb-body h3 {
        font-family: var(--gq-head-font);
        font-size: 17px;
        font-weight: 600;
        margin: 0 0 3px;
        display: -webkit-box;
        -webkit-line-clamp: 1;
        line-clamp: 1;
        -webkit-box-orient: vertical;
        overflow: hidden;
}

.gqv2 .gqv2-nb-body p {
        font-size: 12.5px;
        line-height: 1.5;
        color: var(--gq-mist);
        margin: 0;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
}

/* ---- Close to Home — Option E: 2x2 image tiles (left) + rail (right) ----
       Same 1.35 / 1 split as Option B; the right column reuses the exact
       .gqv2-nb-list / .gqv2-nb-item styling, so it stays "as is". Only the
       left changes from one spotlight to a 2x2 mosaic of four tiles. */
    .gqv2 .gqv2-ne {
        display: grid;
        grid-template-columns: 1.35fr 1fr;
        gap: 20px;
}

/* Rows size to the tiles' own 3:2 rather than splitting the column height,
   which is what let the mosaic drift to 1.22. space-between takes care of the
   remainder: the rail beside it is sized to match, but where a narrow desktop
   leaves it a little taller, the two tile rows spread to meet it instead of
   the mosaic ending early and dumping the difference at the bottom. */
.gqv2 .gqv2-ne-tiles {
        display: grid;
        grid-template-columns: 1fr 1fr;
        grid-template-rows: auto auto;
        align-content: space-between;
        gap: 16px;
}

.gqv2 .gqv2-ne-tile {
        position: relative;
        display: block;
        border-radius: 16px;
        overflow: hidden;
        background: #0a2038;
        box-shadow: var(--gq-shadow-sm);
        aspect-ratio: 3 / 2;
}

.gqv2 .gqv2-ne-tile img {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        object-fit: cover;
        transition: transform .5s ease;
}

.gqv2 .gqv2-ne-tile:hover img { transform: scale(1.06);
}

.gqv2 .gqv2-ne-tile .gqv2-near-info { padding: 16px;
}

.gqv2 .gqv2-ne-tile .gqv2-near-info h3 {
        font-size: 18px;
        line-height: 1.2;
        margin: 3px 0 0;
}

/* These tiles carry no category chip, so the vibe moves to the free corner.
   Both it and the request toggle were anchored right, and the toggle wins on
   z-index — it sat across the pill's last 38px at every width, which is why
   the label read "ADVENT…". */
.gqv2 .gqv2-ne-tile .gqv2-vibe-tag {
        left: 8px;
        right: auto;
}

/* every card that hosts an overlay toggle needs to be a positioning context */
    .gqv2 .gqv2-ntile,
.gqv2 .gqv2-nb-item,
.gqv2 .gqv2-ne-tile,
.gqv2 .gqv2-wtd-card,
.gqv2 .gqv2-wtd-media,
.gqv2 .gqv2-sp,
.gqv2 .gqv2-sp-img { position: relative;
}

@keyframes gqv2-chip-in { from { opacity: 0; transform: scale(.8); } to { opacity: 1; transform: none; }
}

@media (max-width: 900px) {
    .gqv2 .gqv2-ne { grid-template-columns: 1fr;
    }
}

/* The two-column band, where the rail column narrows faster than the text in
   it does. Left alone the body outgrows its 3:2 thumbnail, the row stretches
   past the mosaic, and the mosaic answers by opening a 50px gutter between its
   tile rows. The blurb drops to one line here — it is the only block with a
   line to spare. */
@media (min-width: 901px) and (max-width: 1100px) {
    .gqv2 .gqv2-nb-body {
            padding: 6px 12px 6px 0;
    }

    .gqv2 .gqv2-nb-body h3 {
            font-size: 15px;
    }

    .gqv2 .gqv2-nb-body p {
            -webkit-line-clamp: 1;
            line-clamp: 1;
    }
}

/* Close to Home on phones. The 2x2 mosaic and the rail both keep their shape;
   what changes is that the type is sized for the box it is actually in. */
@media (max-width: 620px) {
    .gqv2 .gqv2-ne-tiles {
            gap: 10px;
    }

    /* Phones only — desktop keeps the caption on the photo. 3:2 leaves a 159px
       tile just 106px tall, and an overlay eats nearly all of it, so here the
       tile becomes a card: photo on top, caption under it on white. The vibe
       pill is a child of the tile, so dropping out of absolute puts it in the
       column between the two on its own. */
    .gqv2 .gqv2-ne-tile {
            aspect-ratio: auto;
            display: flex;
            flex-direction: column;
            background: #fff;
    }

    .gqv2 .gqv2-ne-tile img {
            position: static;
            width: 100%;
            height: auto;
            aspect-ratio: 3 / 2;
    }

    /* The scrim only existed to make white text survive the photo. */
    .gqv2 .gqv2-ne-tile .gqv2-short-grad {
            display: none;
    }

    /* Slim tags. The desktop pill's 4px/8px padding and 9px caps read as a
       chunky capsule next to 13px card type, and the rail caption is budgeted
       to the pixel — this buys back four of them. */
    /* The caps line's own leading sat on top of the token, so the gap under
       the photo measured half again what it was set to. */
    .gqv2 .gqv2-ne-tile .gqv2-near-drive {
            line-height: 1;
    }

    /* The vibe tag stays absolute over the photo, so the caption starts at the
       standard gap rather than picking up after it. Six rather than the token:
       the state is one short word, and the space around it was reading as a
       divide between two blocks instead of a label sitting above a name. */
    .gqv2 .gqv2-ne-tile .gqv2-near-info {
            position: static;
            padding: 6px 10px 10px;
    }

    .gqv2 .gqv2-ne-tile .gqv2-near-drive {
            font-size: 9px;
            gap: 4px;
            margin-bottom: 2px;
            /* #FFD98A is picked to survive a dark photo; on white it is the
               rail's #b98c28. */
            color: #b98c28;
    }

    /* The title had no clamp at all before: "Greater Akron Gateway to Cuyahoga
       Valley National Park" ran five lines up the tile, out of the gradient
       and across both the vibe pill and the request toggle. */
    /* Three lines, not two. Destination names here run long — "Greater Akron:
       Gateway to Cuyahoga Valley National Park" — and in a 159px column two
       lines cut nearly every one of them mid-phrase. The third costs 16px of
       card and lets most of them finish. */
    .gqv2 .gqv2-ne-tile .gqv2-near-info h3 {
            font-size: 13px;
            line-height: 1.25;
            margin-top: 0;
            color: var(--gq-navy);
            display: -webkit-box;
            -webkit-line-clamp: 3;
            line-clamp: 3;
            -webkit-box-orient: vertical;
            overflow: hidden;
    }

    /* 38px of button is a quarter of a 106px photo. */
    .gqv2 .gqv2-ne-tile .gqv2-reqbtn {
            top: 8px;
            right: 8px;
            width: 30px;
            height: 30px;
    }

    .gqv2 .gqv2-ne-tile .gqv2-reqbtn i {
            font-size: 12px;
    }

    /* A fixed 200px image in a 334px row left the body 118px wide, with the
       title wrapping one word per line. It also pushed the item's min-content
       past the grid track, which is where the section's 7px of horizontal
       overhang came from. */
    .gqv2 .gqv2-nb-item {
            gap: 12px;
    }

    /* A pixel width rather than the desktop percentage: here the row height is
       set by the text, not by a neighbouring mosaic, so the thumbnail is sized
       to match what the body needs — 141 / 1.5 is the body's 94px exactly, and
       the 3:2 crop fills the row with nothing left under it. */
    .gqv2 .gqv2-nb-item img {
            width: 141px;
    }

    /* Two lines of title and one of blurb have to clear an 88px thumbnail —
       the reverse of the desktop split, and only four pixels of slack once the
       vibe row is in, so every block here is sized to the budget rather than
       to taste. */
    .gqv2 .gqv2-nb-body {
            padding: 6px 12px 6px 0;
    }

    .gqv2 .gqv2-nb-body .gqv2-card-meta {
            margin-bottom: 2px;
    }

    .gqv2 .gqv2-nb-body h3 {
            font-size: 14px;
            -webkit-line-clamp: 2;
            line-clamp: 2;
    }

    .gqv2 .gqv2-nb-body p {
            font-size: 11.5px;
            line-height: 1.4;
            -webkit-line-clamp: 1;
            line-clamp: 1;
    }
}

.gqv2 .gqv2-sp {
        display: flex;
        flex-direction: column;
        background: #fff;
        border: 1px solid var(--gq-line);
        border-radius: var(--gq-radius);
        overflow: hidden;
        text-decoration: none;
        box-shadow: var(--gq-shadow-sm);
        transition: transform .2s ease, box-shadow .2s ease;
}

.gqv2 .gqv2-sp:hover,
.gqv2 .gqv2-sp:focus-visible {
        transform: translateY(-4px);
        box-shadow: var(--gq-shadow);
}

.gqv2 .gqv2-sp-img {
        position: relative;
        aspect-ratio: 3 / 2;
        overflow: hidden;
        background: var(--gq-navy-dark);
}

.gqv2 .gqv2-sp-img img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
        transition: transform .5s cubic-bezier(.2, .7, .3, 1);
}

.gqv2 .gqv2-sp:hover .gqv2-sp-img img { transform: scale(1.05);
}

.gqv2 .gqv2-sp-cat {
        position: absolute;
        top: 10px;
        left: 10px;
        z-index: 1;
        padding: 5px 10px;
        border-radius: 999px;
        color: #fff;
        font-size: 10px;
        font-weight: 800;
        letter-spacing: .7px;
        text-transform: uppercase;
}

.gqv2 .gqv2-sp-body {
        padding: var(--gq-card-gap-top) 16px 16px;
        display: flex;
        flex-direction: column;
        gap: 5px;
        flex: 1;
}

.gqv2 .gqv2-sp-body h3 {
        margin: 0;
        font-family: var(--gq-head-font);
        font-size: 17px;
        line-height: 1.3;
        color: var(--gq-navy);
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
}

.gqv2 .gqv2-sp-loc {
        font-size: 12.5px;
        font-weight: 600;
        color: var(--gq-mist);
        display: inline-flex;
        align-items: center;
        gap: 6px;
}

.gqv2 .gqv2-sp-loc i { color: var(--gq-blue); font-size: 11px;
}

/* Every card here is a paying partner, so the disclosure belongs to the
       section, not to six repeated badges. */
    .gqv2 .gqv2-sp-note {
        display: inline-flex;
        align-items: center;
        gap: 7px;
        font-size: 12px;
        font-weight: 700;
        color: var(--gq-mist);
        white-space: nowrap;
}

.gqv2 .gqv2-sp-note i { color: var(--gq-blue);
}

/* ---------- OPTION E — stay / play toggle ---------- */
    .gqv2 .gqv2-spe-tabs {
        position: relative;
        display: inline-flex;
        gap: 6px;
        background: var(--gq-cloud);
        border: 1px solid var(--gq-line);
        border-radius: 999px;
        padding: 6px;
        margin-bottom: 20px;
}

.gqv2 .gqv2-spe-pill {
        position: absolute;
        top: 6px;
        left: 0;
        height: calc(100% - 12px);
        border-radius: 999px;
        background: var(--gq-blue);
        box-shadow: 0 8px 18px -8px rgba(36, 116, 166, .55);
        transition: transform .38s cubic-bezier(.4, 0, .2, 1), width .38s cubic-bezier(.4, 0, .2, 1);
        pointer-events: none;
        z-index: 0;
}

.gqv2 .gqv2-spe-pill.no-anim { transition: none;
}

@media (prefers-reduced-motion: reduce) {
    .gqv2 .gqv2-spe-pill { transition: none;
    }
}

.gqv2 .gqv2-spe-tab {
        position: relative;
        z-index: 1;
        border: 0;
        background: transparent;
        color: var(--gq-slate);
        font-family: var(--gq-font);
        font-weight: 800;
        font-size: 13.5px;
        padding: 10px 20px;
        border-radius: 999px;
        cursor: pointer;
        display: inline-flex;
        align-items: center;
        gap: 8px;
        transition: color .18s ease;
}

.gqv2 .gqv2-spe-tab.is-active { color: #fff;
}

/* Four across, and shorter: the filter means the row is often 4 (stay) or
       2 (play), so 4 columns lands "stay" as exactly one clean row. */
    .gqv2 .gqv2-spe-grid {
        display: grid;
        grid-template-columns: repeat(4, 1fr);
        gap: 14px;
}

.gqv2 .gqv2-spe-grid .gqv2-sp {
        transition: transform .32s cubic-bezier(.4, 0, .2, 1), opacity .28s ease, box-shadow .2s ease;
}

.gqv2 .gqv2-spe-grid .gqv2-sp.is-out {
        opacity: 0;
        transform: scale(.94);
        pointer-events: none;
}

/* shorter tile: tighter body. The photo used to flatten to 16:9 here; listing
   photos hold 3:2 everywhere now, so only the body tightens. */
.gqv2 .gqv2-spe-grid .gqv2-sp-body { padding: var(--gq-card-gap-top) 12px 12px; gap: 3px;
}

.gqv2 .gqv2-spe-grid .gqv2-sp-body h3 { font-size: 14.5px; line-height: 1.25;
}

.gqv2 .gqv2-spe-grid .gqv2-sp-loc { font-size: 11.5px;
}

.gqv2 .gqv2-spe-grid .gqv2-sp-cat {
        top: 8px;
        left: 8px;
        padding: 4px 8px;
        font-size: 9px;
}

/* The vibe pill's own styling moved to site.css: the search results wear it
   too, and a component used by more than one page belongs with the shared
   chrome. What stays below is only what the HOMEPAGE does to it. */
/* Slim tags on phones, everywhere the pill appears. The desktop capsule's
   4px/8px padding and 9px caps read as chunky next to 13px card type. It must
   sit after the base rule rather than with the Close to Home block it was
   asked for — same specificity, so source order decides. line-height is the
   part that actually slims it: Poppins' normal line box is 13px at this size
   and held the tag at 17 however little padding it had. */
@media (max-width: 620px) {
    .gqv2 .gqv2-vibe-tag {
            padding: 2px 7px;
            font-size: 8.5px;
            letter-spacing: .4px;
            gap: 4px;
            line-height: 1;
    }

    .gqv2 .gqv2-vibe-tag i {
            font-size: 8px;
    }
}

/* Same pill, in a caption instead of on a photo: no longer an overlay, and
   without the shadow it needed to lift off a picture. */
.gqv2 .gqv2-card-meta .gqv2-vibe-tag {
        position: static;
        box-shadow: none;
}

/* Vibe and location share a line. Stacked, they cost the rail 26px of height
   the 3:2 thumbnail beside them does not have to give. */
.gqv2 .gqv2-card-meta {
        display: flex;
        align-items: center;
        flex-wrap: wrap;
        gap: 4px 8px;
        margin-bottom: 2px;
}

.gqv2 .gqv2-card-meta > * {
        margin-bottom: 0;
}

@media (max-width: 1200px) {
    .gqv2 .gqv2-spe-grid { grid-template-columns: repeat(3, 1fr);
    }
}

@media (max-width: 1000px) {
    .gqv2 .gqv2-spe-grid { grid-template-columns: repeat(2, 1fr); gap: 12px;
    }
}

@media (max-width: 600px) {
    .gqv2 .gqv2-spe-grid { grid-template-columns: 1fr;
    }

    .gqv2 .gqv2-spe-tabs { display: flex; width: 100%;
    }

    .gqv2 .gqv2-spe-tab { flex: 1; justify-content: center; padding: 10px 8px; font-size: 12px;
    }
}

/* .gqv2-feat-head and its children moved to site.css — the story page uses the
   same section header. */

/* ==================== EXPLORE BY STATE ==================== */
    /* light background treatment (matches the search area): soft aurora + faint
       dots, with gently pulsing location "pings" as the animated accent. */
    .gqv2 [data-vgroup="states"] {
        position: relative;
        overflow: hidden;
        background: linear-gradient(180deg, #ffffff 0%, #f1f8fc 100%);
}

.gqv2 [data-vgroup="states"]::before {
        content: "";
        position: absolute; inset: -25%;
        background:
            radial-gradient(28% 40% at 22% 28%, rgba(36, 116, 166, .10), transparent 70%),
            radial-gradient(26% 38% at 80% 26%, rgba(0, 131, 143, .08), transparent 70%),
            radial-gradient(30% 42% at 66% 80%, rgba(255, 118, 0, .05), transparent 70%);
        animation: gqv2SearchAurora 26s ease-in-out infinite alternate;
        pointer-events: none; z-index: 0;
}

.gqv2 [data-vgroup="states"]::after {
        content: "";
        position: absolute; inset: 0;
        background-image: radial-gradient(circle, rgba(18, 59, 99, .06) 1px, transparent 1.6px);
        background-size: 26px 26px;
        -webkit-mask-image: radial-gradient(ellipse 82% 78% at 50% 46%, #000 34%, transparent 100%);
        mask-image: radial-gradient(ellipse 82% 78% at 50% 46%, #000 34%, transparent 100%);
        pointer-events: none; z-index: 0;
}

.gqv2 .gqv2-states-anim { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0;
}

.gqv2 [data-vgroup="states"] > .gqv2-wrap { position: relative; z-index: 1;
}

@media (prefers-reduced-motion: reduce) {
    .gqv2 [data-vgroup="states"]::before { animation: none;
    }

    .gqv2 .gqv2-states-anim { display: none;
    }
}

/* Vibes section: plain sand background — the drifting icon layer, the
       hover-reactive colour wash and the dot texture were all removed. */
    .gqv2 [data-vgroup="vibes"] { position: relative;
}

.gqv2 [data-vgroup="vibes"] > .gqv2-wrap { position: relative; z-index: 1;
}

/* ==================== STATES B: postcard letter tiles ==================== */
    .gqv2 .gqv2-states-post {
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
        gap: 14px;
}

/* 175 gives 7 per row at desktop width — 150 fitted 8 and stranded a single
       postcard on the last row */
    .gqv2 .gqv2-states-post > * { flex: 0 1 175px;
}

/* --- narrower screens: same postcard, scaled down ---
       At the desktop basis two cards need 364px, so a 390px phone wrapped to ONE
       per row — 17 states became 17 rows. These steps keep the design and just
       shrink it: 4-5 across on a tablet, 3 across on a phone. */
    @media (max-width: 900px) {
    .gqv2 .gqv2-states-post { gap: 12px;
    }

    .gqv2 .gqv2-states-post > * { flex: 0 1 132px;
    }

    .gqv2 .gqv2-state-post { padding: 14px 12px 12px;
    }

    .gqv2 .gqv2-state-post-abbr { font-size: 32px; margin-bottom: 7px;
    }
}

@media (max-width: 640px) {
    .gqv2 .gqv2-states-post { gap: 10px;
    }

    .gqv2 .gqv2-states-post > * { flex: 0 1 92px;
    }

    .gqv2 .gqv2-state-post {
            padding: 10px 8px 9px;
            border-radius: 11px;
    }

    .gqv2 .gqv2-state-post-abbr { font-size: 24px; margin-bottom: 4px;
    }

    .gqv2 .gqv2-state-post b { font-size: 11.5px; line-height: 1.25;
    }
}

.gqv2 .gqv2-state-post {
        display: block;
        background: #fff;
        border: 1px solid var(--gq-line);
        border-radius: 14px;
        padding: 18px 16px 16px;
        color: var(--gq-navy);
        transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}

.gqv2 .gqv2-state-post:hover {
        transform: translateY(-4px);
        border-color: var(--gq-gold);
        box-shadow: var(--gq-shadow-sm);
        color: var(--gq-navy);
}

.gqv2 .gqv2-state-post-abbr {
        font-family: var(--gq-head-font);
        font-size: 42px;
        font-weight: 800;
        line-height: 1;
        display: block;
        margin-bottom: 10px;
}

.gqv2 .gqv2-state-post:nth-child(4n+1) .gqv2-state-post-abbr { color: var(--gq-blue);
}

.gqv2 .gqv2-state-post:nth-child(4n+2) .gqv2-state-post-abbr { color: var(--gq-green);
}

.gqv2 .gqv2-state-post:nth-child(4n+3) .gqv2-state-post-abbr { color: var(--gq-gold);
}

.gqv2 .gqv2-state-post:nth-child(4n) .gqv2-state-post-abbr { color: var(--gq-navy);
}

.gqv2 .gqv2-state-post b {
        display: block;
        font-size: 13.5px;
        font-weight: 800;
        margin-bottom: 2px;
}

.gqv2 .gqv2-state-post small {
        display: block;
        font-size: 11.5px;
        font-weight: 600;
        color: var(--gq-mist);
}

/* ==================== RESPONSIVE ==================== */
    @media (max-width: 1050px) {
    /* tablet: aside on top, carousel below */
        .gqv2 .gqv2-inspired {
            grid-template-columns: minmax(0, 1fr);
    }

    .gqv2 .gqv2-inspired-aside {
            grid-column: 1 / -1;
            text-align: center;
    }

    .gqv2 .gqv2-vibes-grid {
            grid-template-columns: 1fr;
    }

    .gqv2 .gqv2-vibes-aside {
            text-align: center;
    }

    .gqv2 .gqv2-vibes {
            grid-template-columns: repeat(3, 1fr);
    }
}

@media (max-width: 620px) {
    .gqv2 .gqv2-section {
            padding: 54px 0;
    }

    /* The 48px arrow gutters cost a third of a phone's width, and spent it on
       controls no thumb reaches for on a carousel that swipes. The row takes
       the full width instead and the guides get the space. */
    .gqv2 .gqv2-guides-shell {
            padding: 0;
    }

    .gqv2 .gqv2-guides-shell .swiper-button-prev,
    .gqv2 .gqv2-guides-shell .swiper-button-next {
            display: none;
    }

    /* The old 12px/13.5px step down was compensating for a 109px-wide card.
       The card is ~200px now, so the caption goes back to full size. */
    .gqv2 .gqv2-story-body {
            padding: 14px 12px;
    }

    .gqv2 .gqv2-vibes {
            grid-template-columns: repeat(2, 1fr);
    }

    .gqv2 .gqv2-slide-actions .gqv2-btn {
            flex: 1;
            justify-content: center;
    }
}

