/* ---------------------------------------------------------------------------
   Website design system and page chrome.

   Ported from the legacy homepage v2 mockup (guestQuest_ci
   app/Views/website/homepage_v2.php), which held its whole stylesheet inline in
   one 12,830-line view. Split here into the part every website page needs —
   tokens, typography, buttons, header, footer, section shell, request tray —
   and home.css, which holds the homepage sections themselves.

   Selectors keep the mockup's .gqv2 scope even though nothing competes with
   them here. Two reasons: it keeps this file diffable against the mockup it
   came from, and Swiper's own rules are overridden by several sections — one
   class of specificity would be lost if the prefix were stripped. .gqv2 is the
   <body> class, set in app/Views/website/layout.php.
   --------------------------------------------------------------------------- */

/* ==================== SCOPED DESIGN SYSTEM (.gqv2) ====================
   Editorial skin: Navy #123B63 + Discovery Blue #2474A6 + Playfair/Caveat,
   with TERRACOTTA #D96C47 as the warm accent (replaces the earlier gold). */
.gqv2 {
    --gq-navy: #123B63;
    --gq-navy-dark: #0d2c4b;
    --gq-blue: #2474A6;
    --gq-blue-dark: #1c5d86;
    /* terracotta accent (kept on the old --gq-gold hooks) */
    --gq-gold: #D96C47;
    --gq-gold-dark: #B85434;
    --gq-orange: #D96C47;
    --gq-orange-dark: #B85434;
    --gq-white: #ffffff;
    /* accents (sparingly) */
    --gq-green: #5F8F72;
    --gq-green-dark: #4e7a5f;
    --gq-sky: #DCECF4;
    --gq-sand: #F5F0E6;
    --gq-charcoal: #33383D;

    --gq-line: #e3e9ef;
    --gq-mist: #64748b;
    /* Both were referenced but never defined, so the search-tab track had no
       background and the resting tab labels had no colour. */
    --gq-cloud: #F2F5F8;
    --gq-slate: #55637A;
    /* Location/mode blue. The dead --gq-teal used to sit here. */
    --gq-blue-tint: #eef4f9;
    --gq-radius: 14px;
    --gq-shadow: 0 18px 50px -20px rgba(18, 59, 99, .35);
    --gq-shadow-sm: 0 8px 24px -12px rgba(18, 59, 99, .25);

    /* The sticky header's height, shortened on phones. Anything that has to
       clear it — a sticky rail, a scroll offset — reads it from here rather
       than hard-coding 76px and going stale at the next breakpoint. */
    --gq-header-h: 76px;

    /* Gap between a card's photo and the first line of its caption. Every card
       body set its own, from 10px to 20px, so the same listing sat at a
       different distance from its picture in each row it appeared in. Small on
       purpose: whatever this is set to, the uppercase location line that
       usually comes first adds about 4px of its own ascent on top. */
    --gq-card-gap-top: 8px;

    --gq-font: 'Poppins', system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
    --gq-head-font: 'Poppins', system-ui, Segoe UI, sans-serif;
    --gq-script-font: 'Vujahday Script', cursive;

    font-family: var(--gq-font);
    color: var(--gq-charcoal);
    background: var(--gq-white);
    -webkit-font-smoothing: antialiased;
    /* The UA's default 8px body margin was still in force: it framed the whole
       site in white and kept the sticky header off both edges. overflow-x was
       hiding the resulting scrollbar rather than the cause of it. */
    margin: 0;
    overflow-x: hidden;
}

.gqv2 *,
.gqv2 *::before,
.gqv2 *::after {
    box-sizing: border-box;
}

.gqv2 img {
    max-width: 100%;
    display: block;
}

.gqv2 a {
    text-decoration: none;
    color: inherit;
}

.gqv2 .gqv2-wrap {
    max-width: 1400px;
    margin: 0 auto;
    padding: 0 24px;
}

.gqv2 h1,
.gqv2 h2,
.gqv2 .gqv2-h2 {
    font-family: var(--gq-head-font);
    color: var(--gq-navy);
}

.gqv2 .gqv2-script {
    font-family: var(--gq-script-font);
    color: var(--gq-blue);
    font-weight: 700;
    letter-spacing: .5px;
}

.gqv2 .gqv2-h2 {
    font-size: clamp(28px, 3.6vw, 40px);
    line-height: 1.12;
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 10px 0 12px;
}

.gqv2 .gqv2-sub {
    font-size: 16px;
    line-height: 1.65;
    color: var(--gq-mist);
    max-width: 620px;
}

/* ---- buttons ---- */
.gqv2 .gqv2-btn {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-family: var(--gq-font);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: .8px;
    text-transform: uppercase;
    padding: 15px 28px;
    border-radius: 999px;
    border: 0;
    cursor: pointer;
    transition: transform .18s ease, box-shadow .18s ease, background .18s ease;
    line-height: 1;
}

.gqv2 .gqv2-btn i {
    font-size: 13px;
}

.gqv2 .gqv2-btn-navy {
    background: var(--gq-navy);
    color: #fff;
    box-shadow: 0 12px 26px -10px rgba(18, 59, 99, .55);
}

.gqv2 .gqv2-btn-navy:hover {
    background: var(--gq-navy-dark);
    transform: translateY(-2px);
    color: #fff;
}

.gqv2 .gqv2-btn-outline {
    background: rgba(255, 255, 255, .85);
    color: var(--gq-navy);
    border: 1.5px solid var(--gq-navy);
}

.gqv2 .gqv2-btn-outline:hover {
    background: #fff;
    transform: translateY(-2px);
    color: var(--gq-navy);
}

.gqv2 .gqv2-btn-green {
    background: var(--gq-green);
    color: #fff;
    box-shadow: 0 12px 26px -10px rgba(95, 143, 114, .6);
}

.gqv2 .gqv2-btn-green:hover {
    background: var(--gq-green-dark);
    transform: translateY(-2px);
    color: #fff;
}

.gqv2 .gqv2-btn-gold {
    background: var(--gq-gold);
    color: #fff;
    box-shadow: 0 12px 26px -10px rgba(217, 108, 71, .6);
}

.gqv2 .gqv2-btn-gold:hover {
    background: var(--gq-gold-dark);
    transform: translateY(-2px);
    color: #fff;
}


/* ==================== SECTION SHELL ==================== */
.gqv2 .gqv2-section {
    padding: 78px 0;
}

/* The hero sits tight against the header with the search bar right below it,
   rather than carrying a full section's padding.

   In the mockup this was keyed off `#gqv2-hero-slot + section` — the drawer
   moved whichever hero you picked to just after that slot div. There is one
   hero now and no slot, so it is a class on the section itself. */
.gqv2 .gqv2-section.gqv2-hero-section {
    padding: 18px 0 22px;
    background: transparent;
}

.gqv2 .gqv2-section.sky {
    background: var(--gq-sky);
}

.gqv2 .gqv2-section.sand {
    background: var(--gq-sand);
}

/* From the mockup's RESPONSIVE block — the rest of that block is per-section
   and lives in home.css. */
@media (max-width: 620px) {
    .gqv2 .gqv2-section {
        padding: 54px 0;
    }
}

/* ---- section header ----
   Script title on the left, an optional link on the right, a supporting line
   under the title. Lived in home.css until the story page needed the same
   header; it is page chrome rather than one section's layout, so it sits here
   with the section shell it belongs to. */
.gqv2 .gqv2-feat-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 20px;
    flex-wrap: wrap;
    margin-bottom: 30px;
}

.gqv2 .gqv2-feat-head .gqv2-script {
    font-size: 40px;
    line-height: 1;
}

/* The sub used to sit inline after the script, so a 40px cursive title and a 15px
   grey line shared one baseline and read as one run-on sentence. It now drops to
   its own line, with the measure capped so it stays a supporting line rather than
   stretching the full section width. Matches .gqv2-nhead-center, which already
   stacked its sub. */
.gqv2 .gqv2-feat-head .gqv2-feat-sub {
    display: block;
    margin: 9px 0 0;
    max-width: 54ch;
    color: var(--gq-mist);
    font-size: 15px;
    font-weight: 600;
    line-height: 1.5;
}

.gqv2 .gqv2-textlink {
    font-weight: 800;
    font-size: 13px;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--gq-blue);
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

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


/* ==================== V2 HEADER ==================== */
.gqv2 .gqv2-header {
    position: sticky;
    top: 0;
    z-index: 1000;
    background: #fff;
    border-bottom: 1px solid var(--gq-line);
    box-shadow: 0 4px 20px -12px rgba(18, 59, 99, .18);
}

.gqv2 .gqv2-header-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 22px;
    height: var(--gq-header-h);
}

.gqv2 .gqv2-logo {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 3px;
    flex-shrink: 0;
}

/* brush-script wordmark (clean SVG, no "Traveler"), tinted via mask */
.gqv2 .gqv2-logo-svg {
    display: block;
    width: 136px;
    aspect-ratio: 235.44 / 97.2;
    background-color: var(--gq-navy);
    -webkit-mask: url('../images/gq-logo.svg') no-repeat center / contain;
    mask: url('../images/gq-logo.svg') no-repeat center / contain;
}

.gqv2 .gqv2-logo-tagline {
    font-size: 8.5px;
    font-weight: 800;
    letter-spacing: 2.4px;
    text-transform: uppercase;
    color: var(--gq-gold-dark);
    white-space: nowrap;
    margin-top: -4px;
}

.gqv2 .gqv2-header-nav {
    display: flex;
    align-items: center;
    gap: 28px;
}

.gqv2 .gqv2-header-nav a {
    font-size: 13px;
    font-weight: 800;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--gq-navy);
    padding: 6px 0;
    position: relative;
}

.gqv2 .gqv2-header-nav a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 100%;
    bottom: 0;
    height: 2px;
    background: var(--gq-gold);
    transition: right .22s ease;
}

.gqv2 .gqv2-header-nav a:hover {
    color: var(--gq-blue);
}

.gqv2 .gqv2-header-nav a:hover::after {
    right: 0;
}

.gqv2 .gqv2-header-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-shrink: 0;
}

.gqv2 .gqv2-header-fav {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    border: 1.5px solid var(--gq-line);
    color: var(--gq-navy);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    transition: border-color .2s ease, color .2s ease;
}

.gqv2 .gqv2-header-fav:hover {
    border-color: var(--gq-gold);
    color: var(--gq-gold-dark);
}

.gqv2 .gqv2-header-actions .gqv2-btn {
    padding: 13px 22px;
    font-size: 12.5px;
}

/* hamburger + mobile nav */
.gqv2 .gqv2-burger {
    display: none;
    width: 42px;
    height: 42px;
    border-radius: 10px;
    border: 1.5px solid var(--gq-line);
    background: #fff;
    color: var(--gq-navy);
    font-size: 17px;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.gqv2 .gqv2-mobile-nav {
    display: none;
    background: #fff;
    border-bottom: 1px solid var(--gq-line);
    box-shadow: 0 16px 30px -18px rgba(18, 59, 99, .3);
    /* The drawer lives inside the sticky header, so a nav long enough to run
       past the fold would otherwise have no way to reach its last item. */
    max-height: calc(100vh - var(--gq-header-h));
    overflow-y: auto;
}

.gqv2 .gqv2-mobile-nav a {
    display: block;
    padding: 15px 24px;
    font-size: 14px;
    font-weight: 800;
    letter-spacing: 1px;
    text-transform: uppercase;
    color: var(--gq-navy);
    border-top: 1px solid var(--gq-line);
}

.gqv2 .gqv2-mobile-nav a:hover {
    background: var(--gq-sky);
}

@media (max-width: 1000px) {
    .gqv2 .gqv2-header-nav,
    .gqv2 .gqv2-header-fav {
        display: none;
    }

    .gqv2 .gqv2-burger {
        display: flex;
    }

    /* Scoped to the breakpoint on purpose. Unscoped, a drawer opened on a
       phone stayed on screen when the window widened back past the burger,
       leaving both navs up at once. */
    .gqv2 .gqv2-mobile-nav.open {
        display: block;
    }
}

/* Phones. Above this the header still fits at its full size; below it the
   three blocks together were 446px wide on a 375px screen, which pushed the
   burger off the edge and made the nav unreachable. */
@media (max-width: 600px) {
    .gqv2 {
        --gq-header-h: 62px;
    }

    .gqv2 .gqv2-header-inner {
        gap: 12px;
        padding: 0 16px;
    }

    .gqv2 .gqv2-logo-svg {
        width: 106px;
    }

    /* 194px of nowrap text under a 106px wordmark, in a block that cannot
       shrink — the single biggest cause of the overflow. It stays in the
       footer, where there is room for it. */
    .gqv2 .gqv2-header .gqv2-logo-tagline {
        display: none;
    }

    .gqv2 .gqv2-header-actions {
        gap: 8px;
    }

    .gqv2 .gqv2-header-actions .gqv2-btn {
        padding: 11px 15px;
        font-size: 11px;
        letter-spacing: .5px;
    }

    .gqv2 .gqv2-burger {
        width: 40px;
        height: 40px;
        font-size: 16px;
    }

    .gqv2 .gqv2-mobile-nav a {
        padding: 15px 16px;
    }
}

/* ==================== V2 FOOTER ==================== */
.gqv2 .gqv2-footer {
    background: var(--gq-navy);
    color: rgba(255, 255, 255, .72);
}

.gqv2 .gqv2-footer-top {
    display: grid;
    grid-template-columns: 1.4fr 1fr 1fr 1fr;
    gap: 40px;
    padding: 64px 0 48px;
}

.gqv2 .gqv2-footer .gqv2-logo {
    align-items: flex-start;
}

.gqv2 .gqv2-footer .gqv2-logo-svg {
    width: 165px;
    background-color: #fff;
}

.gqv2 .gqv2-footer .gqv2-logo-tagline {
    color: var(--gq-gold);
}

.gqv2 .gqv2-footer-brand p {
    font-size: 14px;
    line-height: 1.7;
    margin: 18px 0 22px;
    max-width: 300px;
}

.gqv2 .gqv2-footer-social {
    display: flex;
    gap: 10px;
}

.gqv2 .gqv2-footer-social a {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    border: 1.5px solid rgba(255, 255, 255, .25);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    transition: background .2s ease, border-color .2s ease, color .2s ease;
}

.gqv2 .gqv2-footer-social a:hover {
    background: var(--gq-gold);
    border-color: var(--gq-gold);
    color: var(--gq-navy);
}

.gqv2 .gqv2-footer-col h4 {
    font-family: var(--gq-font);
    font-size: 12px;
    font-weight: 800;
    letter-spacing: 2px;
    text-transform: uppercase;
    color: var(--gq-gold);
    margin: 6px 0 18px;
}

.gqv2 .gqv2-footer-col a {
    display: block;
    font-size: 14px;
    font-weight: 600;
    color: rgba(255, 255, 255, .72);
    padding: 6px 0;
    transition: color .18s ease, transform .18s ease;
}

.gqv2 .gqv2-footer-col a:hover {
    color: var(--gq-gold);
    transform: translateX(4px);
}

.gqv2 .gqv2-footer-bottom {
    border-top: 1px solid rgba(255, 255, 255, .12);
    padding: 22px 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    font-size: 13px;
}

.gqv2 .gqv2-footer-bottom .gqv2-script {
    color: var(--gq-gold);
    font-size: 18px;
}

@media (max-width: 900px) {
    .gqv2 .gqv2-footer-top {
        grid-template-columns: 1fr 1fr;
        gap: 34px;
        padding: 48px 0 36px;
    }
}

@media (max-width: 520px) {
    .gqv2 .gqv2-footer-top {
        grid-template-columns: 1fr;
    }

    .gqv2 .gqv2-footer-bottom {
        justify-content: center;
        text-align: center;
    }
}


/* ================= Request-info toggle (all sections) ================= */
.gqv2 .gqv2-reqbtn {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 6;
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 999px;
    background: rgba(255, 255, 255, .92);
    border: 1px solid rgba(10, 32, 56, .10);
    box-shadow: 0 3px 10px rgba(10, 32, 56, .22);
    color: var(--gq-navy, #0a2038);
    cursor: pointer;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    transition: transform .2s cubic-bezier(.34, 1.56, .64, 1), background .2s ease, box-shadow .2s ease, color .2s ease;
    -webkit-tap-highlight-color: transparent;
}

.gqv2 .gqv2-reqbtn:hover {
    transform: scale(1.09);
    background: #fff;
    box-shadow: 0 5px 16px rgba(10, 32, 56, .28);
}

.gqv2 .gqv2-reqbtn:active { transform: scale(.94); }

.gqv2 .gqv2-reqbtn i {
    font-size: 15px;
    line-height: 1;
    transition: transform .25s ease, opacity .18s ease;
}

.gqv2 .gqv2-reqbtn .gqv2-reqbtn-on { position: absolute; opacity: 0; transform: scale(.4) rotate(-40deg); }
.gqv2 .gqv2-reqbtn .gqv2-reqbtn-add { opacity: 1; transform: none; }

/* selected */
.gqv2 .gqv2-reqbtn.is-on {
    background: linear-gradient(135deg, #ff8a00 0%, #ff6a00 100%);
    border-color: transparent;
    color: #fff;
    box-shadow: 0 5px 16px rgba(255, 118, 0, .5);
}

.gqv2 .gqv2-reqbtn.is-on .gqv2-reqbtn-add { opacity: 0; transform: scale(.4) rotate(40deg); }
.gqv2 .gqv2-reqbtn.is-on .gqv2-reqbtn-on  { opacity: 1; transform: none; }

/* pop when toggled on */
@keyframes gqv2-reqpop {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.28); }
    100% { transform: scale(1); }
}
.gqv2 .gqv2-reqbtn.just-added { animation: gqv2-reqpop .38s ease; }

/* hover tooltip */
.gqv2 .gqv2-reqbtn-tip {
    position: absolute;
    top: 50%;
    right: calc(100% + 8px);
    transform: translateY(-50%) translateX(6px);
    white-space: nowrap;
    background: var(--gq-navy, #0a2038);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .3px;
    padding: 5px 9px;
    border-radius: 7px;
    opacity: 0;
    pointer-events: none;
    transition: opacity .18s ease, transform .18s ease;
}
.gqv2 .gqv2-reqbtn:hover .gqv2-reqbtn-tip { opacity: 1; transform: translateY(-50%) translateX(0); }
.gqv2 .gqv2-reqbtn.is-on .gqv2-reqbtn-tip { content: none; }

/* Horizontal rail cards put the body flush to the right edge, so a top-right
   toggle lands on top of the title. Move it onto the photo (left column). */
.gqv2 .gqv2-nb-item .gqv2-reqbtn {
    left: 10px;
    right: auto;
    top: 10px;
    width: 32px;
    height: 32px;
}
.gqv2 .gqv2-nb-item .gqv2-reqbtn i { font-size: 13px; }
.gqv2 .gqv2-nb-item .gqv2-reqbtn-tip { display: none; }

/* compact toggle for the small sponsored sub-items (lane rows, hero minis) */
.gqv2 .gqv2-spb-item .gqv2-reqbtn,
.gqv2 .gqv2-spc-mini .gqv2-reqbtn,
.gqv2 .gqv2-spd-card .gqv2-reqbtn {
    width: 28px; height: 28px; top: 6px; right: 6px;
}
.gqv2 .gqv2-spb-item .gqv2-reqbtn i,
.gqv2 .gqv2-spc-mini .gqv2-reqbtn i,
.gqv2 .gqv2-spd-card .gqv2-reqbtn i { font-size: 12px; }
.gqv2 .gqv2-spb-item .gqv2-reqbtn-tip,
.gqv2 .gqv2-spc-mini .gqv2-reqbtn-tip,
.gqv2 .gqv2-spd-card .gqv2-reqbtn-tip { display: none; }

/* Lane rows are a flex row (84px thumb + text beside it), so top-right lands on
   the title — sit it on the thumb instead. 18px = the row's 12px padding + 6px. */
.gqv2 .gqv2-spb-item .gqv2-reqbtn {
    left: 18px;
    right: auto;
    top: 18px;
}

/* ---------------------------------------------------------------------------
   The vibe pill.

   Emitted by web_vibe_pill() and worn by the homepage, the search results and
   anything else showing how a place feels — so it belongs here with the shared
   chrome rather than in one page's stylesheet. It lived in home.css until the
   search page wanted it and got a plain row of icons and text instead, because
   nothing on that page consumed the --vfill it was setting.

   Solid fill and a white label: the pill IS the surface, so whatever is under it
   does not matter. The fill is pre-derived server-side to clear white text — see
   web_vibe_fill().

   Absolute by default because its first home was the corner of a photo. Anywhere
   it sits in flowing text says so, as .gqv2-card-meta and .gq-se-vibechips do.
   --------------------------------------------------------------------------- */
.gqv2 .gqv2-vibe-tag {
    position: absolute;
    top: 8px;
    right: 8px;
    z-index: 1;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 4px 8px;
    border-radius: 999px;
    background: var(--vfill, var(--gq-navy));
    color: var(--vink, #fff);
    font-size: 9px;
    font-weight: 800;
    letter-spacing: .5px;
    text-transform: uppercase;
    box-shadow: 0 4px 12px -4px rgba(0, 0, 0, .5);
}
.gqv2 .gqv2-vibe-tag i { font-size: 9px; }

/* The pill carries both names — see web_vibe_pill(). The short one is the
   default because that is what every existing use showed; anywhere with room for
   "Outdoor Adventure" rather than "Adventure" flips these two. */
.gqv2 .gqv2-vibe-tag .gqv2-vibe-full { display: none; }
.gqv2 .gqv2-vibe-tag .gqv2-vibe-short { display: inline; }

/* A feature — see web_feature_tag(). Deliberately not a pill: features come in
   twenties and outlining each one turns a list into a fence. The glyph does the
   separating instead, and the icon is fixed-width so the labels line up in a
   column whatever their icons are. Layout (columns, gaps) belongs to whoever is
   showing them; this is only how one reads. */
.gqv2 .gqv2-feature-tag {
    display: inline-flex;
    align-items: baseline;
    gap: 8px;
    font-size: 12.5px;
    line-height: 1.45;
    color: var(--gq-slate);
}
.gqv2 .gqv2-feature-tag > i {
    flex: 0 0 15px;
    text-align: center;
    font-size: 12px;
    color: var(--gq-green);
}

/* The vibe pill also lives at top-right of a sponsored photo, so it sat under the
   toggle. Category badge keeps top-left, toggle keeps top-right, vibe moves to
   bottom-left — three corners, no stacking. */
.gqv2 .gqv2-sp-img .gqv2-vibe-tag {
    top: auto;
    right: auto;
    bottom: 8px;
    left: 8px;
}

/* Accordion panels are narrow when collapsed, so a long state name ("West
   Virginia") reached across into the toggle. Drop the tag below it. */
.gqv2 .gqv2-nacc-panel .gqv2-near-tag { top: 58px; }

@media (max-width: 620px) {
    .gqv2 .gqv2-reqbtn { width: 34px; height: 34px; top: 9px; right: 9px; }
    .gqv2 .gqv2-reqbtn i { font-size: 13px; }
    .gqv2 .gqv2-reqbtn-tip { display: none; }
}

/* ================= Request-info tray (v2) ================= */
.gqv2-tray {
    position: fixed;
    left: 50%;
    bottom: 20px;
    transform: translateX(-50%) translateY(170%);
    width: min(1000px, calc(100% - 28px));
    z-index: 9999;
    opacity: 0;
    pointer-events: none;
    transition: transform .55s cubic-bezier(.22, 1, .36, 1), opacity .35s ease;
}
.gqv2-tray.is-open {
    transform: translateX(-50%) translateY(0);
    opacity: 1;
    pointer-events: auto;
}

.gqv2-tray-inner {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 12px 14px 12px 16px;
    border-radius: 20px;
    background: linear-gradient(120deg, rgba(12, 32, 56, .97), rgba(18, 44, 74, .97));
    box-shadow: 0 18px 50px rgba(6, 20, 38, .45);
    border: 1px solid rgba(255, 255, 255, .08);
    -webkit-backdrop-filter: blur(10px);
    backdrop-filter: blur(10px);
    color: #fff;
}

.gqv2-tray-lead { display: flex; align-items: center; gap: 12px; flex-shrink: 0; }

.gqv2-tray-badge {
    position: relative;
    width: 42px; height: 42px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 12px;
    background: linear-gradient(135deg, #ff8a00, #ff6a00);
    font-size: 17px; color: #fff;
    box-shadow: 0 4px 14px rgba(255, 118, 0, .45);
}
.gqv2-tray-dot {
    position: absolute; top: -7px; right: -7px;
    min-width: 20px; height: 20px; padding: 0 5px;
    border-radius: 999px; background: #fff; color: #ff6a00;
    font-size: 12px; font-weight: 800; line-height: 20px; text-align: center;
    border: 2px solid #12233f;
}
.gqv2-tray-meta { display: flex; flex-direction: column; line-height: 1.25; }
.gqv2-tray-meta b { font-size: 15px; font-weight: 800; }
.gqv2-tray-meta span { font-size: 11.5px; color: rgba(255, 255, 255, .62); }

.gqv2-tray-actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.gqv2-tray-clear {
    border: 0; background: transparent; color: rgba(255, 255, 255, .6);
    font-size: 12.5px; font-weight: 700; cursor: pointer; padding: 8px 10px; border-radius: 10px;
    transition: color .15s, background .15s;
}
.gqv2-tray-clear:hover { color: #fff; background: rgba(255, 255, 255, .08); }
.gqv2-tray-cta {
    border: 0; cursor: pointer;
    background: linear-gradient(135deg, #ff8a00 0%, #ff6a00 100%);
    color: #fff; font-size: 14px; font-weight: 800; letter-spacing: .2px;
    padding: 11px 20px; border-radius: 999px; white-space: nowrap;
    box-shadow: 0 6px 18px rgba(255, 118, 0, .45);
    transition: transform .18s ease, box-shadow .18s ease;
}
.gqv2-tray-cta:hover { transform: translateY(-2px); box-shadow: 0 9px 24px rgba(255, 118, 0, .55); }
.gqv2-tray-cta .n { font-weight: 900; }

@media (max-width: 760px) {
    .gqv2-tray { bottom: 12px; width: calc(100% - 18px); }
    .gqv2-tray-inner { gap: 10px; padding: 10px 12px; border-radius: 16px; }
    .gqv2-tray-meta span { display: none; }
    .gqv2-tray-actions { margin-left: auto; }
    .gqv2-tray-cta { padding: 10px 15px; font-size: 13px; }
    .gqv2-tray-clear { padding: 8px; }
}

/* the v2 page ships its own tray — retire the legacy grey bar here only */
.dish { display: none !important; }

/* gold drive-time line for light (white card) contexts */
.gqv2 .gqv2-ndrive-lt {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: #b98c28;
    margin-bottom: 5px;
}


/* ==================== "SEE SOMETHING YOU LIKE" BAND ==================== */
.gqv2 .gqv2-band {
    background: var(--gq-sky);
}

.gqv2 .gqv2-band .gqv2-wrap {
    display: flex;
    align-items: center;
    gap: 26px;
    padding-top: 52px;
    padding-bottom: 52px;
    flex-wrap: wrap;
}

.gqv2 .gqv2-band-icon {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: #fff;
    color: var(--gq-navy);
    font-size: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--gq-shadow-sm);
    flex-shrink: 0;
}

.gqv2 .gqv2-band-copy {
    flex: 1;
    min-width: 260px;
}

.gqv2 .gqv2-band-copy h2 {
    font-family: var(--gq-font);
    font-size: clamp(20px, 2.4vw, 26px);
    font-weight: 800;
    margin: 0 0 6px;
    color: var(--gq-navy);
}

.gqv2 .gqv2-band-copy p {
    margin: 0;
    color: var(--gq-mist);
    font-size: 15px;
    font-weight: 600;
}

/* ==================== OWNER STRIP ====================
   The partner invitation, sitting above the band. A rail rather than a band:
   half the vertical padding, sand against the band's sky, and the link is a
   link rather than a button — the band's call to action is the loud one on the
   page and this must not compete with it. */

.gqv2 .gqv2-owner-strip {
    display: block;
    background: var(--gq-sand);
    border-top: 1px solid var(--gq-line);
}

.gqv2 .gqv2-owner-strip .gqv2-wrap {
    display: flex;
    align-items: center;
    gap: 16px;
    padding-top: 22px;
    padding-bottom: 22px;
    flex-wrap: wrap;
}

.gqv2 .gqv2-owner-strip > .gqv2-wrap > i {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: #fff;
    color: var(--gq-gold);
    font-size: 15px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    box-shadow: var(--gq-shadow-sm);
}

.gqv2 .gqv2-owner-strip p {
    flex: 1;
    min-width: 240px;
    margin: 0;
    font-size: 14.5px;
    line-height: 1.55;
    color: var(--gq-mist);
}

.gqv2 .gqv2-owner-strip p b {
    color: var(--gq-navy);
    font-weight: 700;
}

.gqv2 .gqv2-owner-strip-link {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    flex-shrink: 0;
    font-size: 13px;
    font-weight: 800;
    letter-spacing: .8px;
    text-transform: uppercase;
    color: var(--gq-navy);
    border-bottom: 2px solid var(--gq-gold);
    padding-bottom: 3px;
    transition: color .18s ease, gap .18s ease;
}

.gqv2 .gqv2-owner-strip-link:hover {
    color: var(--gq-gold-dark);
    gap: 13px;
}

.gqv2 .gqv2-owner-strip-link i {
    font-size: 11px;
}

@media (max-width: 620px) {
    .gqv2 .gqv2-owner-strip > .gqv2-wrap > i {
        display: none;
    }
}


/* ---- reveal animation ---- */
.gqv2 .gqv2-reveal {
    opacity: 0;
    transform: translateY(24px);
    transition: opacity .6s ease, transform .6s ease;
}

.gqv2 .gqv2-reveal.is-in {
    opacity: 1;
    transform: none;
}


/* ---- the request tray on a desktop ----
   A panel pinned across the foot of the page is a lot of furniture for one
   number and one button, and it sits over the content the visitor is reading to
   decide whether to add anything else. Above the phone breakpoint it collapses
   to the button alone — the same gqv2-btn-navy the rest of the site uses,
   floated bottom-right, carrying the count it used to spell out.

   The tray keeps its full shape on a phone, where a thumb needs the target and
   there is no room beside the content anyway. */
@media (min-width: 761px) {
    .gqv2-tray {
        left: auto;
        right: 24px;
        transform: translateY(170%);
        width: auto;
    }

    .gqv2-tray.is-open { transform: translateY(0); }

    .gqv2-tray-inner {
        padding: 0;
        border: 0;
        border-radius: 0;
        background: none;
        box-shadow: none;
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }

    /* The count and the clear both live on the button's own page now: the
       number is in it, and removing things is what the funnel is for. */
    .gqv2-tray-lead,
    .gqv2-tray-clear { display: none; }

    .gqv2-tray-cta { box-shadow: 0 16px 38px -12px rgba(6, 20, 38, .55); }
}

/* ==================== THE REQUEST LIST ====================
   The header's Request Info button is the whole of this now — the bottom tray
   it replaced spent a strip of every page repeating one number, over the
   content a visitor was reading to decide whether to add to it. */
.gqv2 .gqv2-reqinfo { display: inline-flex; align-items: center; gap: 8px; }

.gqv2 .gqv2-reqinfo-n {
    display: inline-grid;
    place-items: center;
    min-width: 21px;
    height: 21px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--gq-gold);
    color: #fff;
    font-size: 11.5px;
    font-weight: 800;
}

/* An empty list has nothing to ask about, so its CTA is not pressable. */
.gqv2-btn:disabled {
    opacity: .45;
    cursor: not-allowed;
    box-shadow: none;
}

/* ---- what a tick looks like ------------------------------------------------
   Ticking a card used to move one number in the corner of the header, which is
   the one part of the page nobody is looking at while they read a card. Three
   things answer that now, in order: the card itself flies to the button, the
   button reacts to being hit, and a note says what has just happened. */

/* The card in flight. Sized and placed from JS off the toggle's own rect, so
   nothing here fixes where it starts; above the sticky header (1000) and below
   the modal (11000), since the header is what it is flying into. */
.gqv2-fly {
    position: fixed;
    z-index: 10500;
    pointer-events: none;
    border-radius: 14px;
    overflow: hidden;
    background: #fff;
    box-shadow: 0 18px 40px -12px rgba(6, 20, 38, .55);
}

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

/* A card with no thumb still has to send something. */
.gqv2-fly.is-plain {
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: linear-gradient(135deg, #ff8a00 0%, #ff6a00 100%);
    color: #fff;
    font-size: 24px;
}

/* The button taking the hit: the badge takes the weight of the landing, and a
   ring spreads off the button so the eye is pulled there even if it was still
   on the card. */
@keyframes gqv2-reqbump {
    0%   { transform: scale(1); }
    40%  { transform: scale(1.28); }
    100% { transform: scale(1); }
}

@keyframes gqv2-reqring {
    0%   { box-shadow: 0 0 0 0 rgba(217, 108, 71, .55); }
    100% { box-shadow: 0 0 0 16px rgba(217, 108, 71, 0); }
}

.gqv2 .gqv2-reqinfo.is-bumped { animation: gqv2-reqring .6s ease-out; }
.gqv2 .gqv2-reqinfo.is-bumped .gqv2-reqinfo-n { animation: gqv2-reqbump .45s cubic-bezier(.34, 1.56, .64, 1); }

/* The note that lands with it. Fixed and positioned from the button's rect
   rather than parented to the header, so it cannot be clipped by the header's
   own overflow and needs no change to that markup. Colours are literal: this
   is appended to the body, outside the .gqv2 scope the variables live in. */
.gqv2-reqtip {
    position: fixed;
    z-index: 10400;
    max-width: min(290px, calc(100vw - 24px));
    padding: 11px 14px;
    border-radius: 12px;
    background: #123B63;
    color: #fff;
    font-family: 'Poppins', system-ui, sans-serif;
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.45;
    box-shadow: 0 18px 40px -14px rgba(6, 20, 38, .75);
    opacity: 0;
    transform: translateY(-7px);
    transition: opacity .22s ease, transform .22s ease;
    pointer-events: none;
}

/* Points at the middle of the button, whatever the button's width — JS sets
   the offset from the bubble's right edge. */
.gqv2-reqtip::before {
    content: '';
    position: absolute;
    bottom: 100%;
    right: var(--gq-tip-arrow, 24px);
    border: 7px solid transparent;
    border-bottom-color: #123B63;
}

.gqv2-reqtip.is-in { opacity: 1; transform: none; }

/* Nothing above is load-bearing: the count, the list and the CTA all still work
   with every one of these switched off. */
@media (prefers-reduced-motion: reduce) {
    .gqv2-fly { display: none; }

    .gqv2 .gqv2-reqinfo.is-bumped,
    .gqv2 .gqv2-reqinfo.is-bumped .gqv2-reqinfo-n { animation: none; }

    .gqv2-reqtip { transition: none; }
}

/* ==================== THE REQUEST MODAL ====================
   Moved here from travel-info.css so the two places that show a request can be the
   same component rather than two that resemble each other: the funnel's
   "Everything you're requesting", and the header's Request Info list on the
   rest of the site. site.css is loaded on every page including the funnel's,
   so nothing moved out of reach. */
.gq-modal {
    position: fixed;
    inset: 0;
    z-index: 11000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    font-family: 'Poppins', system-ui, sans-serif;
}

.gq-modal[hidden] { display: none; }

.gq-modal-veil {
    position: absolute;
    inset: 0;
    background: rgba(8, 24, 42, .62);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
}

.gq-modal-box {
    position: relative;
    z-index: 1;
    width: min(620px, 100%);
    /* dvh, not vh. On a phone 100vh counts the strip behind the browser's own
       chrome, so a box sized from it is taller than what can actually be seen —
       and being centred, it overflowed off the top and the bottom at once.
       100dvh is the height that is really there, and it follows the chrome as
       it slides away. vh first as the fallback for anything that has not heard
       of dvh; the later line wins where it has. */
    max-height: min(760px, calc(100vh - 40px));
    max-height: min(760px, calc(100dvh - 40px));
    display: flex;
    flex-direction: column;
    background: #fff;
    border-radius: 22px;
    box-shadow: 0 40px 90px -30px rgba(6, 20, 38, .7);
    overflow: hidden;
    animation: gq-modal-in .26s cubic-bezier(.22, 1, .36, 1);
}

@keyframes gq-modal-in {
    from { opacity: 0; transform: translateY(16px) scale(.98); }
    to   { opacity: 1; transform: none; }
}

.gq-modal-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    padding: 22px 24px 0;
}

.gq-modal-head h3 {
    font-family: var(--gq-font);
    font-size: 19px;
    font-weight: 800;
    color: var(--gq-navy);
    margin: 0;
    display: flex;
    align-items: center;
    gap: 10px;
}

.gq-modal-x {
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    border-radius: 50%;
    border: 1.5px solid var(--gq-line);
    background: #fff;
    color: var(--gq-slate);
    font-size: 14px;
    cursor: pointer;
    transition: background .18s ease, color .18s ease, border-color .18s ease;
}

.gq-modal-x:hover { background: var(--gq-navy); border-color: var(--gq-navy); color: #fff; }

.gq-modal-note {
    margin: 8px 24px 14px;
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--gq-mist);
}

.gq-modal-body {
    flex: 1;
    /* Without this the flex item cannot shrink below its content, so
       overflow-y never engages: the list grows to full height, overflows the
       box in both directions and is clipped by it. The rows past the fold end
       up unreachable and the visible area reads as blank. */
    min-height: 0;
    overflow-y: auto;
    padding: 0 24px 4px;
    scrollbar-width: thin;
    /* Reaching the end of this list must not start scrolling the page behind
       it — the page is left unlocked so opening the modal cannot shift the
       layout, and this is what stands in for the lock. */
    overscroll-behavior: contain;
}

.gq-modal-foot {
    padding: 16px 24px 22px;
    border-top: 1px solid var(--gq-line);
    display: flex;
    justify-content: flex-end;
}

.gq-modal-foot .gqv2-btn { padding: 13px 30px; }

/* The confirm dialog: no list to scroll, so it sizes to its own words. */
.gq-modal-box.is-ask { width: min(440px, 100%); max-height: none; }
.gq-modal-box.is-ask .gq-modal-note { margin-bottom: 4px; }
.gq-modal-box.is-ask .gq-modal-foot { gap: 10px; align-items: center; }

.gq-modal-keep {
    border: 0;
    background: none;
    padding: 13px 16px;
    cursor: pointer;
    font-family: var(--gq-font);
    font-size: 13.5px;
    font-weight: 800;
    color: var(--gq-slate);
    border-radius: 999px;
    transition: background .18s ease, color .18s ease;
}

.gq-modal-keep:hover { background: var(--gq-cloud); color: var(--gq-navy); }

/* The rows read on white here, not on the sidebar's navy, and carry the full
   detail — the modal is where the visitor decides what to drop. */
/* .is-pick centres its row, and being later in this file it would win — so the
   modal's top alignment is stated against that class too, otherwise the tick's
   offset below lands 20px under a centred row. */
.gq-modal-body .gq-sum-row,
.gq-modal-body .gq-sum-row.is-pick { padding: 13px 0; align-items: flex-start; }
.gq-modal-body .gq-sum-row + .gq-sum-row { border-top: 1px solid var(--gq-line); }

/* object-fit and flex-shrink are stated here rather than inherited from the
   sidebar's rules — those are scoped to the aside now, and without these the
   thumbnails stretch and can be squashed by a long title. */
.gq-modal-body .gq-sum-row img {
    width: 84px;
    height: 68px;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
}

.gqv2 .gq-sum-detail { display: flex; flex-direction: column; gap: 3px; min-width: 0; }

.gqv2 .gq-sum-meta {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-bottom: 3px;
}

.gqv2 .gq-sum-detail b {
    font-size: 15.5px;
    font-weight: 700;
    color: var(--gq-navy);
    line-height: 1.25;
}

.gqv2 .gq-sum-detail em {
    font-style: normal;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--gq-mist);
}

.gqv2 .gq-sum-detail em i { font-size: 11px; width: 13px; }
.gqv2 .gq-sum-loc { color: var(--gq-slate); }
.gqv2 .gq-sum-sends { color: var(--gq-green-dark); }

/* Hidden for now, not deleted — the markup still renders it, so bringing the
   line back is removing this one rule.

   Matched through `em` deliberately: `.gq-sum-detail em` above sets
   display:inline-flex and is one element-selector more specific, so a plain
   `.gq-sum-sends { display: none }` loses to it and the line stays visible. */
.gqv2 .gq-sum-detail em.gq-sum-sends { display: none; }

.gqv2 .gq-sum-vibe {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: .7px;
    text-transform: uppercase;
}

/* The type badge is the outline variant, same as the card body on page one. */
.gq-modal-body .gq-type {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--type-color) 40%, transparent);
    color: var(--type-color);
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: .7px;
    text-transform: uppercase;
}

@media (max-width: 480px) {
    .gq-modal-body .gq-sum-row img { width: 64px; height: 54px; }
}

/* A row you can untick.

   position:relative is load-bearing, not decoration. The hidden checkbox below
   is absolutely positioned; without a positioned row it resolves against
   .gq-modal-box instead, landing far outside the visible list. Clicking the
   label focuses it, the browser scrolls the box to bring that phantom position
   into view, and the list appears to vanish. Every other card in this file
   (.gq-info, .gq-wtd-card, .gq-region, .gq-chip, .gq-tile, .gq-gstate,
   .gq-centry, .gq-cbanner) sets this for the same reason — this row was the
   one that missed it. */
.gq-sum-row.is-pick {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
    cursor: pointer;
    user-select: none;
}

.gq-sum-row.is-pick input { position: absolute; opacity: 0; pointer-events: none; }

.gq-sum-row.is-pick > span:not(.gq-sum-tick) { flex: 1; min-width: 0; }

.gq-sum-tick {
    flex-shrink: 0;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 1.5px solid var(--gq-line);
    background: #fff;
    color: transparent;
    font-size: 11px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background .18s ease, border-color .18s ease, color .18s ease;
}

/* The row is top-aligned in the modal, so the tick lines up with the title
   rather than floating against the middle of a three-line block. */
.gq-modal-body .gq-sum-tick { margin-top: 20px; }

.gq-sum-row.is-pick:has(input:checked) .gq-sum-tick {
    background: var(--gq-gold);
    border-color: var(--gq-gold);
    color: #fff;
}

/* Unticked reads as switched off rather than merely unmarked. */
.gq-sum-row.is-pick:has(input:not(:checked)) { opacity: .5; }

/* Sits where the fourth row would, and is built like one: the thumbnail slot
   holds the count instead of a photo, so the list continues rather than
   stopping at a button. */
/* Sits where the fourth row would, and is built like one: the thumbnail slot
   holds the count instead of a photo, so the list continues rather than
   stopping at a button. */

/* The list's own empty state — .gq-empty is the funnel's and stayed there with
   the rest of its step-two furniture. */
.gqv2 .gq-modal-body .gq-empty {
    margin: 0;
    padding: 28px 12px;
    text-align: center;
    font-size: 14px;
    color: var(--gq-mist);
}

/* The undo sits opposite the action it undoes, not beside it — in both lists.
   Not in the confirm dialogs (.is-ask): their two buttons are a pair asking one
   question, and pushing them to opposite ends would read as two questions. */
.gqv2 .gq-modal-box:not(.is-ask) .gq-modal-foot { justify-content: space-between; }

/* Every row in a modal lays out the same way. This used to arrive only with
   .is-pick — the funnel's selectable variant — so a row without it had no
   layout at all and its parts stacked wherever they fell. The interactive bits
   stay on .is-pick; the shape belongs to the row. */
.gq-modal-body .gq-sum-row {
    position: relative;
    display: flex;
    align-items: center;
    gap: 12px;
}

/* The detail takes the slack, so whatever ends the row — a tick, a remove —
   lands at its edge rather than wherever the title happened to stop. */
.gq-modal-body .gq-sum-detail { flex: 1; }


/* The head's count. Left behind when the modal moved, so the site's list wore
   its number as plain heading text while the funnel's wore a navy chip. */
.gqv2 .gq-count-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 7px;
    border-radius: 999px;
    background: var(--gq-gold);
    color: #fff;
    font-size: 12px;
    font-weight: 800;
}

/* The name runs to two lines here. The funnel's rows sit in a modal the visitor
   opened to check a request they built; these are places picked one at a time
   while browsing, and a title cut at one line is the difference between two
   county bureaus nobody can tell apart. */
.gqv2 .gq-modal-body .gq-sum-row b {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ---- the request modal on a small screen ----
   The head and the foot are furniture: they should cost one line each and give
   the rest to the list. Everything here is either a smaller gutter or a rule
   keeping a line from wrapping into two. */
.gqv2 .gq-modal-head h3,
.gqv2 .gq-modal-foot .gqv2-btn,
.gqv2 .gq-modal-keep { white-space: nowrap; }

/* The title is the only part long enough to need it: ellipsis rather than a
   second line, because the count beside it must stay in view. */
.gqv2 .gq-modal-head h3 { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

@media (max-width: 620px) {
    /* 10px of gutter, not 20 — on a 375px screen the box was giving up a tenth
       of its width to the veil either side. */
    .gqv2 .gq-modal { padding: 10px; }

    .gqv2 .gq-modal-head { padding: 11px 14px 9px; }
    .gqv2 .gq-modal-head h3 { font-size: 14.5px; gap: 7px; }
    .gqv2 .gq-modal-body { padding: 0 14px 4px; }

    .gqv2 .gq-modal-foot { padding: 9px 14px 11px; gap: 10px; }
    .gqv2 .gq-modal-foot .gqv2-btn { padding: 10px 16px; font-size: 13px; }
    .gqv2 .gq-modal-keep { font-size: 12.5px; }
    .gqv2 .gq-modal-x { width: 30px; height: 30px; font-size: 14px; }
}

/* The thumbnail sits against the middle of the row, not its top edge. The
   funnel's rows are top-aligned because theirs carry a third line ("you'll
   receive…") and a picture floating beside three lines of text wants the top;
   these carry two, and centred is what looks placed rather than dropped. */
.gqv2 .gq-modal-body .gq-sum-row.is-pick { align-items: center; }
.gqv2 .gq-modal-body .gq-sum-row img { object-fit: cover; object-position: center; }

/* A page-supplied header action, in place of the travel-info button. Same
   .gqv2-btn shape, so the header keeps its proportions whichever one is
   rendered; only the optional leading word is allowed to disappear. */
.gqv2 .gqv2-header-cta {
    gap: 8px;
}

.gqv2 .gqv2-header-cta i {
    font-size: 12px;
}

/* Under the burger breakpoint the row is logo + button + burger, and the
   longer label is what pushes it over. "Partner sign in" becomes "sign in". */
@media (max-width: 620px) {
    .gqv2 .gqv2-header-cta-long {
        display: none;
    }
}
