/* ===========================================================================
   Search — the search and its results at 60%, a map at 40%, filters in a dialog.

   Same shape as the guide directory and the vibe page, and deliberately so: the
   visitor has met this layout twice before reaching search. Tokens, buttons and
   the section shell all come from site.css; only search's own pieces are here.

   The card is wide rather than a grid tile. A result has to carry a place, a
   feature list, a blurb, a rating and up to two actions, and a column of tiles
   would either crop all of that or grow tall enough to show one result per
   screen. Legacy reached the same layout for the same reason.

   Filters are behind a button rather than in a rail, as legacy had them: three
   columns left too little of any of them.
   =========================================================================== */

/* THE HIDDEN ATTRIBUTE WINS HERE. Read this before adding a `display`.

   `hidden` is only enforced by a user-agent rule, so any author-level `display`
   beats it and the element stays on screen while every script and every
   accessibility tool believes it is gone. This page toggles `hidden` on the
   autocomplete, the filter dialog, the map's status panel, the "search this
   area" button and all four Quickview panes — and it caught three of them in
   turn: an opaque "Loading the map…" panel sat on top of a working map for a
   long stretch, and every Quickview tab showed at once because the panes are
   grids.

   So it is settled once, for everything inside .gq-se, rather than paired up
   rule by rule and remembered. !important is right here: this is not styling, it
   is restoring a platform guarantee that author CSS is allowed to break. */
.gq-se [hidden] { display: none !important; }

/* ---------------- banner and the search bar ----------------
   Inside the left column rather than across the page, so the map stands beside
   the whole search and not just beside its results. */
.gq-se-top {
    background: var(--gq-sand);
    border: 1px solid var(--gq-line);
    border-radius: var(--gq-radius);
    padding: 20px;
    margin-bottom: 18px;
}
.gq-se-top-lead .gqv2-script { font-size: 24px; color: var(--gq-blue); }
.gq-se-top-lead h1 {
    margin: 0 0 14px;
    font-size: clamp(24px, 3.2vw, 34px);
    font-weight: 800;
    line-height: 1.1;
    color: var(--gq-navy);
}

/* Type switching: real links, one per listing type. */
.gq-se-types {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 16px;
}
.gq-se-type {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 16px;
    border: 1px solid var(--gq-line);
    border-radius: 999px;
    background: #fff;
    color: var(--gq-slate);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    transition: all .18s ease;
}
.gq-se-type:hover { border-color: var(--gq-blue); color: var(--gq-blue); }
.gq-se-type.is-active {
    background: var(--gq-navy);
    border-color: var(--gq-navy);
    color: #fff;
}

.gq-se-bar { display: flex; gap: 10px; align-items: stretch; }

.gq-se-box { position: relative; flex: 1 1 auto; min-width: 0; }
.gq-se-box > i.fa-magnifying-glass {
    position: absolute;
    left: 16px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--gq-mist);
    pointer-events: none;
}
.gq-se-box input {
    width: 100%;
    height: 52px;
    padding: 0 44px 0 44px;
    border: 1px solid var(--gq-line);
    border-radius: var(--gq-radius);
    background: #fff;
    font-size: 15px;
    color: var(--gq-charcoal);
}
.gq-se-box input:focus {
    outline: none;
    border-color: var(--gq-blue);
    box-shadow: 0 0 0 4px rgba(36, 116, 166, .12);
}
.gq-se-box-x {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    width: 30px;
    height: 30px;
    display: none;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: var(--gq-cloud);
    color: var(--gq-mist);
    cursor: pointer;
}
.gq-se-box.has-text .gq-se-box-x { display: grid; }

/* The disambiguation menu is assets/shared/place-picker.css — the homepage
   location card raises the same one, and it is loaded alongside this file. */

.gq-se-sort { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.gq-se-sort .lbl {
    font-size: 13px;
    font-weight: 600;
    color: var(--gq-mist);
}
.gq-se-sort select {
    height: 52px;
    padding: 0 14px;
    border: 1px solid var(--gq-line);
    border-radius: var(--gq-radius);
    background: #fff;
    font-size: 14px;
    color: var(--gq-charcoal);
    cursor: pointer;
}
.gq-se-go {
    height: 52px;
    padding: 0 22px;
    border: 0;
    border-radius: var(--gq-radius);
    background: var(--gq-navy);
    color: #fff;
    font-size: 15px;
    font-weight: 700;
    cursor: pointer;
}
/* Hidden once the script is running: a facet change swaps results in place, so
   there is nothing left for a submit button to do. */
.gq-se.is-live .gq-se-go { display: none; }

/* ---------------- layout ----------------
   Results and map, 60/40. Filters are not a column — they are behind a button,
   as legacy had them, which is what leaves both of these enough room.

   fr units rather than percentages so the gap comes out of the grid rather than
   out of the 100, and the split stays exactly 60/40 of what is left. Without a
   Maps key the second column is not rendered at all and the results take the
   whole width — .has-map is what says which. */
.gq-se-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 24px;
    align-items: start;
    padding: 20px 0 40px;
}
.gq-se-layout.has-map { grid-template-columns: minmax(0, 60fr) minmax(0, 40fr); }

/* ---------------- map pane ----------------
   Sticky and as tall as the screen allows, because its job is to stay beside the
   search while the results scroll past it. */
.gq-se-mapwrap {
    position: sticky;
    top: calc(var(--gq-header-h) + 12px);
    height: calc(100vh - var(--gq-header-h) - 32px);
    border: 1px solid var(--gq-line);
    border-radius: var(--gq-radius);
    overflow: hidden;
    background: var(--gq-cloud);
}
.gq-se-map { width: 100%; height: 100%; }

/* Until the tiles arrive, and if a key is refused, the pane says so rather than
   sitting there as an empty grey box. Toggled by `hidden`, which the rule at the
   top of this file makes stick. */
.gq-se-mapnote {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    padding: 24px;
    text-align: center;
    font-size: 13px;
    line-height: 1.6;
    color: var(--gq-mist);
    background: var(--gq-cloud);
}

.gq-se-here {
    position: absolute;
    z-index: 3;
    left: 50%;
    top: 14px;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px;
    border: 0;
    border-radius: 999px;
    background: var(--gq-navy);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    box-shadow: var(--gq-shadow-sm);
    cursor: pointer;
}
.gq-se-here:hover { background: var(--gq-navy-dark); }

/* A card and its pin light up together, from either side. */
.gq-se-card.is-hot {
    border-color: var(--gq-blue);
    box-shadow: 0 0 0 3px rgba(36, 116, 166, .14);
}

/* ---------------- the filter modal ----------------
   Legacy put filters behind a button and so does this. The facets live inside
   the dialog permanently rather than being moved in and out of a rail: two
   copies of the same checkboxes would post the same names twice and nothing
   could say which set the visitor meant.

   Centred on a wide screen, a bottom sheet on a phone. One element either way,
   because it is one dialog. */
/* Same height as the vibe modal, and for the same reason: a dialog belongs above
   the sticky header rather than under it. See the scale noted on .gq-se-lb. */
.gq-se-sheet { position: fixed; inset: 0; z-index: 1100; }
.gq-se-sheet-bg {
    position: absolute;
    inset: 0;
    background: rgba(18, 59, 99, .5);
    backdrop-filter: blur(2px);
}
.gq-se-sheet-card {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: min(760px, calc(100vw - 40px));
    max-height: min(80vh, 720px);
    display: flex;
    flex-direction: column;
    border-radius: var(--gq-radius);
    background: #fff;
    box-shadow: var(--gq-shadow);
    overflow: hidden;
}

.gq-se-sheet-head,
.gq-se-sheet-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 15px 20px;
    flex-shrink: 0;
}
.gq-se-sheet-head { border-bottom: 1px solid var(--gq-line); }
.gq-se-sheet-foot { border-top: 1px solid var(--gq-line); background: var(--gq-cloud); }
.gq-se-sheet-foot .gqv2-btn { width: 100%; justify-content: center; }
.gq-se-sheet-head h3 {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 18px;
    font-weight: 800;
    color: var(--gq-navy);
}
.gq-se-sheet-head h3 i { color: var(--gq-blue); }
.gq-se-sheet-x {
    width: 34px;
    height: 34px;
    flex-shrink: 0;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: var(--gq-cloud);
    color: var(--gq-slate);
    cursor: pointer;
}
.gq-se-sheet-x:hover { background: var(--gq-line); }
.gq-se-sheet-body { flex: 1 1 auto; overflow-y: auto; }

/* ---------------- the facets themselves ---------------- */
.gq-se-group { padding: 16px 20px; border-bottom: 1px solid var(--gq-line); }
.gq-se-group:last-of-type { border-bottom: 0; }
.gq-se-group h4 {
    margin: 0 0 10px;
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 12px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .05em;
    color: var(--gq-mist);
}
.gq-se-group h4 i { color: var(--gq-blue); }

/* Two columns in the modal, because it is wide enough for them and 24 features
   in one list is a lot of scrolling. Collapses to one on a phone. */
.gq-se-checks {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px 14px;
}

.gq-se-check {
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 7px 8px;
    border-radius: 9px;
    font-size: 14px;
    color: var(--gq-charcoal);
    cursor: pointer;
}
.gq-se-check:hover { background: var(--gq-cloud); }
.gq-se-check input { accent-color: var(--gq-blue); cursor: pointer; flex-shrink: 0; }
.gq-se-check > span:not(.cnt) { flex: 1 1 auto; min-width: 0; }
.gq-se-check .cnt {
    flex-shrink: 0;
    font-size: 12px;
    font-weight: 700;
    color: var(--gq-mist);
}
/* A facet with nothing behind it stays visible — "no wineries here" is
   information, and a list that shortens as you filter is disorienting. */
.gq-se-check.is-empty { opacity: .45; cursor: default; }
.gq-se-check.is-empty:hover { background: none; }

.gq-se-clear { padding: 12px 20px; border-bottom: 1px solid var(--gq-line); }
.gq-se-clear button {
    width: 100%;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 9px;
    border: 1px solid var(--gq-line);
    border-radius: 10px;
    background: #fff;
    color: var(--gq-gold-dark);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}
.gq-se-clear button:hover { border-color: var(--gq-gold); }
.gq-se-clear .n {
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--gq-gold);
    color: #fff;
    font-size: 11px;
}

.gq-se-note {
    margin: 0;
    padding: 14px 20px;
    background: var(--gq-cloud);
    font-size: 12px;
    line-height: 1.5;
    color: var(--gq-mist);
}
/* ---------------- results ---------------- */
.gq-se-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}
.gq-se-count { margin: 0; font-size: 15px; color: var(--gq-slate); }
.gq-se-count b { color: var(--gq-navy); }

.gq-se-list { display: flex; flex-direction: column; gap: 14px; }
#gqSeResults[aria-busy="true"] .gq-se-list { opacity: .45; transition: opacity .15s ease; }

/* A block, not the grid: the photo-beside-text grid is .gq-se-cardmain, so the
   Quickview panel can span the full width beneath it. */
.gq-se-card {
    position: relative;
    border: 1px solid var(--gq-line);
    border-radius: var(--gq-radius);
    background: #fff;
    overflow: hidden;
    transition: box-shadow .2s ease, border-color .2s ease;
}
.gq-se-card:hover { border-color: #cfdae6; box-shadow: var(--gq-shadow-sm); }

/* ---- an unclaimed place ----
   Padding from the Google cache, filling out a thin area. Quieter than a member's
   card on purpose: it earns its place by being useful to the visitor, not by being
   sold, and a directory entry that looked identical to a paid listing would cheapen
   both. A dashed edge and a tinted ground, no more — it is still a real answer to
   the search and must not read as an error. */
.gq-se-card.is-place {
    border-style: dashed;
    background: color-mix(in srgb, var(--gq-cloud) 55%, #fff);
}
.gq-se-card.is-place:hover { border-color: #c2cedb; }

.gq-se-unclaimed {
    margin-left: 8px;
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--gq-cloud);
    color: var(--gq-mist);
    font-size: 9.5px;
    font-weight: 800;
    letter-spacing: .5px;
    text-transform: uppercase;
    vertical-align: middle;
    white-space: nowrap;
}

/* Google has no photograph for plenty of small tourism offices. In the flow with
   the same ratio as the image it replaces — absolutely positioned it would give the
   media column no height at all and collapse the card. */
.gq-se-nophoto {
    display: grid;
    place-items: center;
    width: 100%;
    aspect-ratio: 3 / 2;
    background: var(--gq-cloud);
    color: #c6d2df;
    font-size: 30px;
}

/* Its own website and its own phone, in place of the Quickview it has not got. */
.gq-se-plink {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 10px;
    border: 1px solid var(--gq-line);
    border-radius: 999px;
    background: #fff;
    color: var(--gq-slate);
    font-size: 11.5px;
    font-weight: 700;
    text-decoration: none;
}
.gq-se-plink:hover { border-color: var(--gq-green); color: var(--gq-green); }

/* The plan ribbon. Only paid tiers get one — see the note in _results.php on
   why Basic does not. */
.gq-se-ribbon {
    position: absolute;
    z-index: 3;
    top: 12px;
    left: 0;
    padding: 4px 12px 4px 10px;
    border-radius: 0 999px 999px 0;
    background: var(--gq-gold);
    color: #fff;
    font-size: 11px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .05em;
}

.gq-se-media { position: relative; background: var(--gq-cloud); }
.gq-se-media > img {
    display: block;
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
}
/* The strip exists only where the plan pays for more than one photo, so it is
   laid out for however many arrive rather than a fixed four. */
.gq-se-thumbs {
    display: flex;
    gap: 3px;
    padding: 3px;
}
.gq-se-thumbs img {
    flex: 1 1 0;
    min-width: 0;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: 4px;
}
.gq-se-media .gqv2-reqbtn { position: absolute; top: 10px; right: 10px; z-index: 3; }

.gq-se-body { padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; }
.gq-se-body h3 {
    margin: 0;
    font-size: 18px;
    font-weight: 800;
    line-height: 1.25;
    color: var(--gq-navy);
}
.gq-se-place {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    color: var(--gq-mist);
}
.gq-se-place > i { color: var(--gq-gold); }
.gq-se-dist {
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--gq-cloud);
    font-size: 11px;
    font-weight: 700;
}

/* Vibes lead the card where the listing has them; features are the fallback —
   see the note in _results.php. Both occupy the same slot, so they are sized to
   sit interchangeably.

   NOT capsules here. The pill from site.css is a solid fill made to sit on a
   photo, and three of them in a row inside a card read as three buttons with
   gaps punched between them — chrome competing with the title right above it.
   So the colour moves to the ink and the capsule goes: --vfill was derived to
   clear white text, which makes it dark enough to read on white as well.

   Set to run on as one line of labels rather than separate objects. The icon is
   what separates one from the next, so they need no boxes to be told apart. */
.gq-se-vibechips { display: flex; flex-wrap: wrap; gap: 4px 36px; }
.gq-se-vibechips .gqv2-vibe-tag {
    position: static;
    padding: 0;
    background: none;
    box-shadow: none;
    color: var(--vfill, var(--gq-navy));
    font-size: 12px;
    letter-spacing: .3px;
}
.gq-se-vibechips .gqv2-vibe-tag i { font-size: 12px; }

/* Room for the real name here — "Outdoor Adventure", not "Adventure". The card
   is the width of the results column, and a vibe is the reason someone reads the
   card, so it is worth the characters. Phones get the short form and one fewer,
   further down. */
.gq-se-vibechips .gqv2-vibe-tag .gqv2-vibe-full { display: inline; }
.gq-se-vibechips .gqv2-vibe-tag .gqv2-vibe-short { display: none; }

/* Six features on the card, in as many columns as fit — the same wide column gap
   the vibe row uses, so whichever of the two a card shows the body reads alike. */
.gq-se-features {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 6px 28px;
}
.gq-se-features .gqv2-feature-tag { font-size: 12px; }

/* One line each, since a card is not the place to discover that a feature has a
   long name. The full list is a Quickview tab away, where it can wrap. */
.gq-se-features .gqv2-feature-tag > span {
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* --lines is the PLAN's clamp, set per card — see s_desc_lines. */
.gq-se-desc {
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: var(--lines, 2);
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 13.5px;
    line-height: 1.55;
    color: var(--gq-slate);
}

.gq-se-foot {
    margin-top: auto;
    padding-top: 4px;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
}
.gq-se-rating {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 13px;
    color: var(--gq-charcoal);
}
.gq-se-rating i { color: #f2b01e; }
.gq-se-rating small { color: var(--gq-mist); }
.gq-se-vibes { display: inline-flex; gap: 5px; flex-wrap: wrap; }
.gq-se-actions { margin-left: auto; display: inline-flex; gap: 8px; }
.gq-se-actions a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 13px;
    border: 1px solid var(--gq-line);
    border-radius: 999px;
    font-size: 12.5px;
    font-weight: 700;
    text-decoration: none;
    color: var(--gq-blue);
    transition: all .18s ease;
}
.gq-se-actions a:hover { border-color: var(--gq-blue); background: var(--gq-blue-tint); }
.gq-se-events { color: var(--gq-green) !important; }
.gq-se-events:hover { border-color: var(--gq-green) !important; background: #eef5f0 !important; }

/* ---------------- paging and empty ---------------- */
.gq-se-pager {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 16px;
    padding: 26px 0 0;
}
.gq-se-pager a {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 18px;
    border: 1px solid var(--gq-line);
    border-radius: 999px;
    background: #fff;
    color: var(--gq-navy);
    font-size: 14px;
    font-weight: 700;
    text-decoration: none;
}
.gq-se-pager a:hover { border-color: var(--gq-blue); color: var(--gq-blue); }
.gq-se-pager-at { font-size: 13px; color: var(--gq-mist); }

.gq-se-empty {
    padding: 54px 20px;
    text-align: center;
    border: 1px dashed var(--gq-line);
    border-radius: var(--gq-radius);
    background: #fff;
}
.gq-se-empty > i { font-size: 40px; color: var(--gq-sky); }
.gq-se-empty h2 {
    margin: 14px 0 6px;
    font-size: 20px;
    font-weight: 800;
    color: var(--gq-navy);
}
.gq-se-empty p { margin: 0; font-size: 14px; color: var(--gq-mist); }

/* ---------------- the filters and map buttons ----------------
   Both sit in the search bar. Filters is there at every width now; Map only
   appears where the pane cannot, on a narrow screen. */
.gq-se-filterbtn,
.gq-se-mapbtn {
    height: 52px;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    padding: 0 18px;
    border: 1px solid var(--gq-line);
    border-radius: var(--gq-radius);
    background: #fff;
    color: var(--gq-navy);
    font-size: 14px;
    font-weight: 700;
    cursor: pointer;
    transition: all .18s ease;
}
.gq-se-filterbtn:hover,
.gq-se-mapbtn:hover { border-color: var(--gq-blue); color: var(--gq-blue); }
.gq-se-filterbtn .n {
    padding: 1px 8px;
    border-radius: 999px;
    background: var(--gq-gold);
    color: #fff;
    font-size: 11px;
}
/* The pane is beside the results above the breakpoint, so there is nothing to
   toggle — see the media queries below. */
.gq-se-mapbtn { display: none; }
.gq-se-mapbtn[aria-pressed="true"] {
    background: var(--gq-navy);
    border-color: var(--gq-navy);
    color: #fff;
}

/* ---------------- narrower screens ---------------- */
@media (max-width: 1100px) {
    /* The map cannot usefully share the width with a list at this size, so it
       goes behind the toggle and the list takes the room. */
    .gq-se-layout,
    .gq-se-layout.has-map { grid-template-columns: minmax(0, 1fr); }
    .gq-se-mapwrap { display: none; }
    .gq-se-mapbtn { display: inline-flex; }

    /* Toggled on: the map takes the screen and the list steps aside. */
    .gq-se-layout.map-open .gq-se-mapwrap {
        display: block;
        height: calc(100vh - var(--gq-header-h) - 120px);
    }
    .gq-se-layout.map-open #gqSeResults { display: none; }
}

@media (max-width: 760px) {
    /* The bar stacks, so the two buttons share a row of their own. */
    .gq-se-bar { flex-wrap: wrap; }
    .gq-se-box { flex: 1 1 100%; }
    .gq-se-sort { flex: 1 1 100%; }
    .gq-se-sort select { flex: 1 1 auto; }
    .gq-se-filterbtn,
    .gq-se-mapbtn { flex: 1 1 0; padding: 0 12px; }

    /* A dialog centred on a phone leaves slivers of page around it; a sheet
       rising from the bottom is reachable with a thumb. */
    .gq-se-sheet-card {
        left: 0;
        right: 0;
        bottom: 0;
        top: auto;
        transform: none;
        width: auto;
        max-height: 86vh;
        border-radius: 18px 18px 0 0;
    }
    .gq-se-checks { grid-template-columns: minmax(0, 1fr); }

    /* Stacked, because 248px of photo beside text is unreadable at this width. */
    /* .gq-se-cardmain carries the grid now — see the rule near the Quickview. */
    .gq-se-type span { display: none; }
    .gq-se-type { padding: 9px 14px; }
    .gq-se-type.is-active span { display: inline; }

    /* Two vibes, short names. Three full ones wrap to two lines on a phone and
       the card starts reading as a list of labels rather than a place. The third
       is dropped in CSS rather than by rendering fewer, so the same markup
       serves both and nothing has to know the breakpoint twice. */
    .gq-se-vibechips .gqv2-vibe-tag:nth-child(n+3) { display: none; }
    .gq-se-vibechips .gqv2-vibe-tag .gqv2-vibe-full { display: none; }
    .gq-se-vibechips .gqv2-vibe-tag .gqv2-vibe-short { display: inline; }
    .gq-se-vibechips { gap: 4px 20px; }
}

/* ---------------- the visitor guides strip ----------------
   Above the results, as legacy's was. Covers rather than titles, because a
   guide is a physical-looking thing and its cover is what makes it read as one
   worth opening. */
.gq-se-guides {
    margin-bottom: 18px;
    padding: 14px 16px 16px;
    border: 1px solid var(--gq-line);
    border-radius: var(--gq-radius);
    background: #fff;
}
.gq-se-guides-head {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 12px;
}
.gq-se-guides-head h2 {
    margin: 0;
    display: flex;
    align-items: center;
    gap: 9px;
    font-size: 15px;
    font-weight: 800;
    color: var(--gq-navy);
}
.gq-se-guides-head h2 i { color: var(--gq-gold); }
.gq-se-guides-head span {
    padding: 1px 9px;
    border-radius: 999px;
    background: var(--gq-cloud);
    color: var(--gq-mist);
    font-size: 11px;
    font-weight: 700;
}

.gq-se-guides-rail { position: relative; }
.gq-se-guide-card {
    display: flex;
    flex-direction: column;
    gap: 6px;
    text-decoration: none;
}
.gq-se-guide-card img {
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    border-radius: 8px;
    border: 1px solid var(--gq-line);
    box-shadow: var(--gq-shadow-sm);
    transition: transform .2s ease;
}
.gq-se-guide-card:hover img { transform: translateY(-3px); }
.gq-se-guide-name {
    font-size: 12px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--gq-navy);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.gq-se-guide-read { font-size: 11px; font-weight: 700; color: var(--gq-blue); }

.gq-se-guides-prev,
.gq-se-guides-next {
    position: absolute;
    z-index: 3;
    top: 38%;
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    border: 1px solid var(--gq-line);
    border-radius: 50%;
    background: #fff;
    color: var(--gq-navy);
    box-shadow: var(--gq-shadow-sm);
    cursor: pointer;
}
.gq-se-guides-prev { left: -8px; }
.gq-se-guides-next { right: -8px; }
.gq-se-guides-prev:disabled,
.gq-se-guides-next:disabled { opacity: 0; pointer-events: none; }

/* ---------------- the Quickview panel ----------------
   The card's photo-beside-text grid moved into its own element so this can span
   the whole width beneath it. */
.gq-se-cardmain { display: grid; grid-template-columns: 248px minmax(0, 1fr); }

/* Beside Quickview, and it carries the auto margin that pushes the rest of the
   row right — the two are always rendered together, so whichever comes last owns
   the gap. Dashed and grey to read as the try-me twin rather than a second offer
   of equal weight. Both this and .gq-se-mvbtn go when one of the two designs is
   settled on, and the auto margin goes back on .gq-se-qvbtn. */
.gq-se-mvbtn {
    margin-right: auto;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    border: 1px dashed var(--gq-line);
    border-radius: 999px;
    background: #fff;
    color: var(--gq-mist);
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
}
.gq-se-mvbtn:hover { border-color: var(--gq-blue); color: var(--gq-blue); }

.gq-se-qvbtn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    border: 1px solid var(--gq-line);
    border-radius: 999px;
    background: #fff;
    color: var(--gq-slate);
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
}
.gq-se-qvbtn:hover { border-color: var(--gq-blue); color: var(--gq-blue); }
.gq-se-qvbtn i { transition: transform .2s ease; }
.gq-se-qvbtn[aria-expanded="true"] i { transform: rotate(180deg); }

.gq-se-qv { border-top: 1px solid var(--gq-line); background: var(--gq-cloud); }

.gq-se-qvtabs {
    display: flex;
    gap: 4px;
    padding: 8px 12px 0;
    overflow-x: auto;
}
.gq-se-qvtabs button {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 8px 13px;
    border: 0;
    border-radius: 8px 8px 0 0;
    background: none;
    color: var(--gq-slate);
    font-size: 12.5px;
    font-weight: 700;
    white-space: nowrap;
    cursor: pointer;
}
.gq-se-qvtabs button:hover { background: rgba(255, 255, 255, .6); }
.gq-se-qvtabs button.is-on { background: #fff; color: var(--gq-navy); }
.gq-se-qvtabs .n {
    padding: 0 6px;
    border-radius: 999px;
    background: var(--gq-line);
    font-size: 10px;
}

/* A height rather than a truncated description: cutting HTML at a character
   count leaves tags open, and everything is still reachable by scrolling. */
.gq-se-qvpane {
    padding: 14px 16px;
    background: #fff;
    max-height: 320px;
    overflow-y: auto;
}

.gq-se-qvphotos { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 6px; }
.gq-se-qvphotos img {
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    border-radius: 6px;
    display: block;
}

.gq-se-qvvideos { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 8px; }
.gq-se-qvvideo {
    position: relative;
    padding: 0;
    border: 0;
    border-radius: 8px;
    overflow: hidden;
    background: #000;
    cursor: pointer;
    aspect-ratio: 16 / 9;
}
.gq-se-qvvideo img { width: 100%; height: 100%; object-fit: cover; display: block; opacity: .85; }
.gq-se-qvvideo .play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: #fff;
    font-size: 26px;
    text-shadow: 0 2px 12px rgba(0, 0, 0, .6);
}
.gq-se-qvvideo iframe { width: 100%; height: 100%; border: 0; display: block; }

/* Room to breathe: 10px between rows and 32px between columns, so the eye reads
   down a column rather than across two names that happen to be adjacent. */
.gq-se-qvfeatures {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 10px 32px;
    padding: 2px 0;
}
.gq-se-qvfeatures .gqv2-feature-tag { font-size: 13px; color: var(--gq-charcoal); }

/* ---- the Details pane -------------------------------------------------------
   Legacy's shape: the name across the top, then About on the left and how to get
   in touch on the right. Two columns because they are read for different reasons
   — one to decide, the other to act. */
.gq-se-qvdetails {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 4px 30px;
}
.gq-se-qvname {
    grid-column: 1 / -1;
    margin: 0 0 2px;
    font-size: 16px;
    font-weight: 800;
    color: var(--gq-navy);
}
.gq-se-qvcol { min-width: 0; }
/* A listing with no description has only the contact column, which reads badly
   squeezed into half the pane with nothing beside it. */
.gq-se-qvcol:only-of-type { grid-column: 1 / -1; }
.gq-se-qvcol h5 {
    margin: 0 0 8px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .4px;
    text-transform: uppercase;
    color: var(--gq-mist);
}

.gq-se-qvtext { font-size: 13.5px; line-height: 1.65; color: var(--gq-slate); }
.gq-se-qvtext p { margin: 0 0 10px; }
.gq-se-qvtext :last-child { margin-bottom: 0; }

/* Four lines, then Read more. The pane is a preview, and a full description runs
   to two thousand characters — unclamped it decides how tall every open card is. */
.gq-se-qvtext.is-clamped {
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.gq-se-qvmore {
    margin-top: 6px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--gq-green);
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
}
.gq-se-qvmore:hover { text-decoration: underline; }

.gq-se-qvcontact {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 7px;
    font-size: 13px;
    color: var(--gq-charcoal);
}
.gq-se-qvcontact li { display: flex; align-items: baseline; gap: 9px; }
/* Fixed width, so the address and the phone number start at the same place
   whatever their icons happen to measure. */
.gq-se-qvcontact i { flex: 0 0 15px; text-align: center; color: var(--gq-green); font-size: 12px; }
.gq-se-qvcontact a { color: inherit; text-decoration: none; }
.gq-se-qvcontact a:hover { text-decoration: underline; }

/* Legacy ruled a line above its buttons and stretched them across the column;
   same here, and they wrap rather than shrink past readable. */
.gq-se-qvlinks {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--gq-line);
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.gq-se-qvlinks a,
.gq-se-qvlinks span {
    flex: 1 1 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    padding: 7px 12px;
    border: 1px solid var(--gq-line);
    border-radius: 8px;
    background: #fff;
    color: var(--gq-navy);
    font-size: 12.5px;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.gq-se-qvlinks a:hover {
    border-color: var(--gq-green);
    background: color-mix(in srgb, var(--gq-green) 8%, #fff);
    color: var(--gq-green);
}

/* View Full Details is the way further in, so it takes the whole width under the
   others rather than competing with them for a third of a row. */
.gq-se-qvlinks .is-primary {
    flex: 1 1 100%;
    border-color: var(--gq-navy);
    background: var(--gq-navy);
    color: #fff;
}
.gq-se-qvlinks a.is-primary:hover {
    border-color: var(--gq-green);
    background: var(--gq-green);
    color: #fff;
}
/* Not yet a link — see web_listing_url(). Reads as a button that is not ready,
   which is honest, rather than one that leads to a 404. */
.gq-se-qvlinks .is-soon {
    border-color: var(--gq-line);
    background: color-mix(in srgb, var(--gq-navy) 6%, #fff);
    color: var(--gq-mist);
    cursor: default;
}

/* One column below the split — two columns of forty characters each is not a
   layout, and the contact block reads better under the description than beside a
   sliver of it. */
@media (max-width: 900px) {
    .gq-se-qvdetails { grid-template-columns: minmax(0, 1fr); gap: 16px; }
    .gq-se-qvname { margin-bottom: 0; }
}

.gq-se-qvvibes { display: grid; gap: 10px; }  /* its own pane, styled further down */

@media (max-width: 760px) {
    .gq-se-cardmain { grid-template-columns: minmax(0, 1fr); }
}

/* ---------------- the lightbox ----------------
   One overlay for every Quickview photo and video on the page — see the note in
   the markup. Above the filter dialog, because it can be opened from a card while
   that is closed and nothing else stacks with it.

   A framed box rather than a picture pinned to the glass. The first attempt let
   the image fill the viewport, and it read as a page that had gone wrong rather
   than a gallery: the counter collided with the bottom edge of the photo, the
   arrows were stranded at the edges of the screen, and with nothing else on show
   there was no saying which listing any of it belonged to. */
/* Above the header, which is sticky at 1000, and above the guide reader at 2000
   — this is the topmost thing on the page while it is open. 200 put it UNDER the
   header, so the site chrome sat across the top of the photo.

   The scale this joins, so the next overlay does not have to guess: header 1000,
   bell 1050, vibe modal 1100, guide reader 2000, request tray 9999. */
.gq-se-lb { position: fixed; inset: 0; z-index: 2200; }
.gq-se-lb-bg {
    position: absolute;
    inset: 0;
    background: rgba(9, 22, 37, .9);
    backdrop-filter: blur(3px);
}

/* The request-info tray is fixed at 9999 so it survives every other overlay on
   the site — but it is a basket, and it has no business floating over a photo
   somebody is looking at. Out-bidding it would start a numbers race; the tray is
   simply put away while the viewer is open, and comes straight back after. */
body.gq-se-lb-open .gqv2-tray { display: none; }

/* ---- quickview as a modal ---------------------------------------------------
   Under the lightbox at 2200, since photos in here still open over it, and above
   the header at 1000 and the filter sheet at 1100. */
.gq-se-mv { position: fixed; inset: 0; z-index: 1500; }

/* Same reasoning as the lightbox: the tray is fixed at 9999 and would float over
   the dialog. Put away while it is open, back straight after. */
body.gq-se-mv-open .gqv2-tray { display: none; }
.gq-se-mv-bg {
    position: absolute;
    inset: 0;
    background: rgba(9, 22, 37, .62);
    backdrop-filter: blur(2px);
}
.gq-se-mv-box {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: clamp(12px, 4vh, 48px) clamp(12px, 4vw, 48px);
}
/* The frame. Wider than the 60% results column the inline panel is stuck inside —
   which is the whole point of trying this — but not the full screen: a description
   measured across 1400px is unreadable. 920 was the first try and it was no wider
   than a card on a 1440 display, so the comparison said nothing.

   Tall as well as wide: the panel is a listing read top to bottom, so it takes the
   height it can get and scrolls the rest. */
.gq-se-mv-bar,
.gq-se-mv-body {
    width: min(1120px, 100%);
    background: #fff;
}
/* A ceiling, not a height: the panes differ wildly — a folded About is a paragraph,
   twelve photos are a page — and a fixed height left most of the frame empty behind
   the short ones. A floor keeps the smallest from looking like a mistake. */
.gq-se-mv-body { max-height: min(88vh, 1000px); min-height: 300px; }
.gq-se-mv-bar {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 14px 16px;
    border-radius: var(--gq-radius) var(--gq-radius) 0 0;
    border-bottom: 1px solid var(--gq-line);
}
.gq-se-mv-bar h3 {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 16px;
    font-weight: 800;
    color: var(--gq-navy);
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* With a hero below it the bar would be saying the name a second time, so it holds
   back until the hero has scrolled off and the name needs carrying — see mvFill().
   Faded rather than removed, or the close button would jump across the bar. */
.gq-se-mv.has-hero .gq-se-mv-bar h3 {
    opacity: 0;
    transition: opacity .2s ease;
}
.gq-se-mv.has-hero.is-scrolled .gq-se-mv-bar h3 { opacity: 1; }
.gq-se-mv-x {
    flex-shrink: 0;
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: var(--gq-cloud);
    color: var(--gq-slate);
    font-size: 14px;
    cursor: pointer;
}
.gq-se-mv-x:hover { background: var(--gq-line); }

/* Scrolls itself, so a long panel never grows the frame past the screen. */
.gq-se-mv-body {
    flex: 0 1 auto;
    min-height: 0;
    overflow-y: auto;
    border-radius: 0 0 var(--gq-radius) var(--gq-radius);
}

.gq-se-pv-wait {
    display: grid;
    place-items: center;
    min-height: 320px;
    color: var(--gq-mist);
    font-size: 22px;
}

/* ================= the preview panel =========================================
   One listing read top to bottom, rather than four fifths of it behind tabs. See
   app/Views/website/search/_preview.php. */

/* ---- hero ----
   A picture at a size worth looking at, with the name over it. The scrim is what
   makes white text safe on a photograph nobody vetted for contrast. */
/* Height directly, not an aspect-ratio with a max-height on top: the ratio derives
   whichever dimension is not given, so a capped height capped the WIDTH too and the
   hero came out 890px inside a 1120px frame. */
.gq-se-pv-hero {
    position: relative;
    height: clamp(190px, 24vw, 330px);
    overflow: hidden;
    background: var(--gq-navy);
}
.gq-se-pv-hero > img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Dark enough at the foot to carry white text over a photograph nobody vetted for
   contrast — which includes posters with their own bright lettering. */
.gq-se-pv-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(9, 22, 37, .96) 0%, rgba(9, 22, 37, .82) 34%, rgba(9, 22, 37, .3) 68%, rgba(9, 22, 37, 0) 100%);
}
.gq-se-pv-hero-text {
    position: absolute;
    inset: auto 0 0;
    z-index: 1;
    padding: 20px clamp(18px, 3vw, 32px);
    color: #fff;
}
/* The colour is stated rather than inherited: site.css sets a navy on every h2,
   and that rule is more specific than the white on this element's parent — so the
   name rendered navy-on-photograph and was all but unreadable. */
.gq-se-pv-hero-text h2 {
    margin: 0;
    color: #fff;
    font-size: clamp(20px, 2.6vw, 30px);
    font-weight: 800;
    line-height: 1.2;
    text-shadow: 0 2px 14px rgba(0, 0, 0, .5);
}

/* The vibe pills are absolutely placed for the corner of a card — over the hero
   they belong in the flow, above the name. */
.gq-se-pv-vibes {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
}
.gq-se-pv-vibes .gqv2-vibe-tag { position: static; top: auto; right: auto; }
.gq-se-pv-vibes .gqv2-vibe-tag .gqv2-vibe-full { display: inline; }
.gq-se-pv-vibes .gqv2-vibe-tag .gqv2-vibe-short { display: none; }

.gq-se-pv-meta {
    margin: 8px 0 0;
    display: flex;
    flex-wrap: wrap;
    gap: 6px 20px;
    font-size: 13px;
    font-weight: 600;
    color: rgba(255, 255, 255, .88);
}
.gq-se-pv-meta i { margin-right: 6px; opacity: .8; }
.gq-se-pv-meta small { font-weight: 500; opacity: .75; }

/* ---- body ----
   Reading column and rail. 300px is enough for an address and a phone number and
   little enough that the text beside it still gets the room. */
.gq-se-pv-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: clamp(20px, 3vw, 36px);
    align-items: start;
    padding: clamp(20px, 3vw, 32px);
}
.gq-se-pv-main { min-width: 0; display: grid; gap: 20px; align-content: start; }

.gq-se-pv-sec { min-width: 0; }

/* ---- tabs ----
   Underlined rather than boxed: the panel is already a frame inside a frame, and a
   third border around the tabs would be one too many. */
.gq-se-pv-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px 4px;
    border-bottom: 1px solid var(--gq-line);
}
.gq-se-pv-tabs button {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    margin-bottom: -1px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--gq-mist);
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
}
.gq-se-pv-tabs button:hover { color: var(--gq-slate); }
.gq-se-pv-tabs button.is-on { border-bottom-color: var(--gq-green); color: var(--gq-navy); }
.gq-se-pv-tabs i { font-size: 12px; }
/* The tally. Grey until its tab is the one open. */
.gq-se-pv-tabs b {
    padding: 1px 7px;
    border-radius: 999px;
    background: var(--gq-cloud);
    color: var(--gq-slate);
    font-size: 10.5px;
    font-weight: 800;
}
.gq-se-pv-tabs button.is-on b { background: var(--gq-green); color: #fff; }

/* The short description, opening the About tab. A size up from the body so the two
   do not read as one undifferentiated block. */
.gq-se-pv-lede {
    margin: 0 0 12px;
    font-size: 15.5px;
    font-weight: 600;
    line-height: 1.55;
    color: var(--gq-navy);
}
/* The disclosure under the short description. A button, but it reads as a link —
   it reveals text rather than doing anything. */
.gq-se-pv-more {
    padding: 0;
    border: 0;
    background: none;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    color: var(--gq-green);
    font-size: 12.5px;
    font-weight: 800;
    cursor: pointer;
}
.gq-se-pv-more:hover span { text-decoration: underline; }
.gq-se-pv-more i { font-size: 10px; transition: transform .2s ease; }
.gq-se-pv-more[aria-expanded="true"] i { transform: rotate(180deg); }
/* Only when it is open, so the button sits tight under the paragraph while shut. */
.gq-se-pv-more[aria-expanded="true"] { margin-bottom: 12px; }

.gq-se-pv-rich { font-size: 14px; line-height: 1.72; color: var(--gq-slate); }
.gq-se-pv-rich p { margin: 0 0 12px; }
.gq-se-pv-rich :last-child { margin-bottom: 0; }
.gq-se-pv-rich ul,
.gq-se-pv-rich ol { margin: 0 0 12px; padding-left: 20px; }
.gq-se-pv-rich a { color: var(--gq-blue); }

/* ---- vibes ----
   A picture and the writing beside it, in the vibe's own colour. Two up where
   there is room, since the notes are short. */
.gq-se-pv-vibecards { display: grid; gap: 12px; }
.gq-se-pv-vibecard {
    display: grid;
    grid-template-columns: 160px minmax(0, 1fr);
    align-items: stretch;
    border: 1px solid color-mix(in srgb, var(--vc) 24%, var(--gq-line));
    border-left: 3px solid var(--vc);
    border-radius: 10px;
    background: color-mix(in srgb, var(--vc) 4%, #fff);
    overflow: hidden;
}

/* ---- vibe art ----
   Every vibe carries a picture, so the column never collapses and the cards stay
   the same shape down the list. */
/* min-height on the box, not only on the photo: a vibe with no picture of its
   own fills this with .gq-vibe-blank, which is absolutely positioned and would
   leave the column with nothing to give it height. */
.gq-se-pv-vibeart {
    position: relative;
    overflow: hidden;
    min-height: 132px;
    background: var(--vc);
}
.gq-se-pv-vibeart img { width: 100%; height: 100%; min-height: 132px; object-fit: cover; display: block; }

/* The blurred-backdrop-plus-emblem treatment that used to live here, under
   .is-emblem, is now .gq-vibe-blank in public/assets/shared/vibe-blank.css —
   one component for every surface that has to stand in for a vibe's picture,
   drawn by listing_vibe_placeholder(). It blurs the VIBE's artwork rather than the
   listing's hero, which is what stopped this column repeating one photograph
   under three different vibe names. */

/* The vibe's mark. A small badge in the corner of a real photograph; the whole
   point of the tile when the picture behind it is only a backdrop. */
.gq-se-pv-vibeicon {
    position: absolute;
    z-index: 1;
    left: 8px;
    bottom: 8px;
    width: 26px;
    height: 26px;
    display: grid;
    place-items: center;
    border-radius: 50%;
    background: var(--vc);
    color: #fff;
    font-size: 12px;
    box-shadow: 0 3px 10px -3px rgba(0, 0, 0, .6);
}
/* The large centred variant of this badge is gone with .is-emblem: the emblem
   carries its own disc now, inside .gq-vibe-blank. This badge is only ever the
   small corner mark over a real photograph. */
.gq-se-pv-vibecard-text { padding: 13px 15px; }
.gq-se-pv-vibecard h4 {
    margin: 0 0 5px;
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 13.5px;
    font-weight: 800;
    color: color-mix(in srgb, var(--vc) 76%, #000 14%);
}
.gq-se-pv-vibecard p { margin: 0; font-size: 13px; line-height: 1.6; color: var(--gq-slate); }
.gq-se-pv-vibecard ul {
    margin: 8px 0 0;
    padding-left: 17px;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--gq-mist);
}

.gq-se-pv-features {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 11px 30px;
}

/* ---- photos and videos ---- */
.gq-se-pv-shots {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px;
}
.gq-se-pv-shots a,
.gq-se-pv-shots button {
    position: relative;
    padding: 0;
    border: 0;
    border-radius: 10px;
    overflow: hidden;
    background: var(--gq-cloud);
    cursor: zoom-in;
    display: block;
}
.gq-se-pv-shots button { cursor: pointer; }
.gq-se-pv-shots img {
    width: 100%;
    aspect-ratio: 3 / 2;
    object-fit: cover;
    display: block;
    transition: transform .35s ease;
}
.gq-se-pv-shots a:hover img,
.gq-se-pv-shots button:hover img { transform: scale(1.04); }

/* ---- rail ----
   Sticky against the panel's own scroll, so the phone number is wherever the
   reading stops. */
.gq-se-pv-rail {
    position: sticky;
    top: 0;
    display: grid;
    gap: 12px;
    min-width: 0;
}
.gq-se-pv-card {
    padding: 16px;
    border: 1px solid var(--gq-line);
    border-radius: 12px;
    background: var(--gq-cloud);
}
.gq-se-pv-card > h3 {
    margin: 0 0 12px;
    font-size: 12px;
    font-weight: 800;
    letter-spacing: .6px;
    text-transform: uppercase;
    color: var(--gq-mist);
}
.gq-se-pv-contact {
    margin: 0 0 14px;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 9px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--gq-charcoal);
}
.gq-se-pv-contact li { display: flex; align-items: baseline; gap: 9px; }
.gq-se-pv-contact i { flex: 0 0 15px; text-align: center; color: var(--gq-green); font-size: 12px; }
.gq-se-pv-contact a { color: inherit; text-decoration: none; }
.gq-se-pv-contact a:hover { text-decoration: underline; }

.gq-se-pv-links { display: grid; gap: 7px; }
.gq-se-pv-links a {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 9px 12px;
    border: 1px solid var(--gq-line);
    border-radius: 9px;
    background: #fff;
    color: var(--gq-navy);
    font-size: 12.5px;
    font-weight: 700;
    text-decoration: none;
    transition: border-color .15s ease, color .15s ease;
}
.gq-se-pv-links a:hover { border-color: var(--gq-green); color: var(--gq-green); }

/* The way further in, so it carries the weight the others do not. */
.gq-se-pv-go {
    margin-top: 10px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    padding: 11px 14px;
    border-radius: 9px;
    background: var(--gq-navy);
    color: #fff;
    font-size: 13px;
    font-weight: 800;
    text-decoration: none;
    transition: background .15s ease;
}
a.gq-se-pv-go:hover { background: var(--gq-green); }
/* Not yet a link — see web_listing_url(). */
.gq-se-pv-go.is-soon { background: color-mix(in srgb, var(--gq-navy) 10%, #fff); color: var(--gq-mist); cursor: default; }

/* The guide is an offer, not a link: a real book, posted, for nothing. It gets a
   panel with the cover in it rather than a fourth button.

   Against the right of the hero on a wide screen — see the note in _preview.php.
   The panel is one element and CSS decides where it lands, so there is no second
   copy of it to keep in step. */
.gq-se-pv { position: relative; }
.gq-se-pv-guide {
    display: grid;
    grid-template-columns: 62px minmax(0, 1fr);
    gap: 12px;
    align-items: center;
    padding: 12px;
    border: 1px solid var(--gq-line);
    border-radius: 12px;
    background: #fff;
    text-decoration: none;
    transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.gq-se-pv-guide:hover {
    border-color: var(--gq-gold, #C9A227);
    box-shadow: 0 8px 22px -12px rgba(9, 22, 37, .35);
}
.gq-se-pv-guide img {
    width: 100%;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    border-radius: 4px;
    display: block;
    box-shadow: 2px 2px 8px -2px rgba(0, 0, 0, .4);
}
.gq-se-pv-guide-text { min-width: 0; display: grid; gap: 3px; }
.gq-se-pv-guide-text b { font-size: 13px; font-weight: 800; color: var(--gq-navy); }
.gq-se-pv-guide-text small { font-size: 11.5px; line-height: 1.45; color: var(--gq-mist); }

@media (min-width: 981px) {
    /* Over the hero, clear of the name at bottom-left. Glass rather than white, or
       an opaque card dropped on a photograph looks like a mistake. */
    .gq-se-pv-guide {
        position: absolute;
        z-index: 2;
        top: clamp(70px, 12vw, 150px);
        right: clamp(16px, 2.4vw, 28px);
        width: 272px;
        border-color: rgba(255, 255, 255, .32);
        background: rgba(255, 255, 255, .14);
        backdrop-filter: blur(10px) saturate(1.2);
        box-shadow: 0 18px 40px -18px rgba(0, 0, 0, .7);
    }
    .gq-se-pv-guide:hover { transform: translateY(-2px); background: rgba(255, 255, 255, .22); }
    .gq-se-pv-guide-text b { color: #fff; }
    .gq-se-pv-guide-text small { color: rgba(255, 255, 255, .8); }

    /* Room for it. A long name — "Greater Akron: Gateway to Cuyahoga Valley
       National Park" — otherwise ran straight under the panel and the last words
       were lost behind it. */
    .gq-se-pv.has-guide .gq-se-pv-hero-text { padding-right: 316px; }
}

@media (max-width: 980px) {
    /* In the flow, above the reading. */
    .gq-se-pv-guide { margin: clamp(20px, 3vw, 32px) clamp(20px, 3vw, 32px) 0; }

    /* The rail under the reading rather than beside a sliver of it, and no longer
       sticky — there is nothing left to stick to once it is in the flow. */
    .gq-se-pv-body { grid-template-columns: minmax(0, 1fr); }
    .gq-se-pv-rail { position: static; }
}

@media (max-width: 760px) {
    /* A sheet from the bottom, which is what a phone wants — and the thing worth
       comparing against the inline panel on a small screen. */
    .gq-se-mv-box { padding: 0; justify-content: flex-end; }
    .gq-se-mv-bar { border-radius: 0; }
    .gq-se-mv-bar,
    .gq-se-mv-body { width: 100%; }
    .gq-se-mv-body { border-radius: 0; max-height: 86vh; }

    .gq-se-pv-hero { aspect-ratio: 16 / 9; max-height: 220px; }
    /* Was .gq-se-pv-vibecard.has-image, a class this card never carried — only
       .gq-se-qvvibe did — so these cards stayed two-column at every width and
       squeezed the note into 160px less than the screen. */
    .gq-se-pv-vibecard { grid-template-columns: minmax(0, 1fr); }
    .gq-se-pv-vibeart,
    .gq-se-pv-vibeart img { aspect-ratio: 16 / 9; height: auto; min-height: 0; }
}

.gq-se-lb-box {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
    /* Air around it, so it reads as a layer over the page and not a new one. */
    padding: 18px clamp(16px, 4vw, 56px) 20px;
    /* Shown by removing `hidden` rather than kept in the DOM visible, so an
       animation runs on every open with no class juggling. */
    animation: gqSeLbIn .18s ease-out both;
}
@keyframes gqSeLbIn {
    from { opacity: 0; transform: scale(.985); }
    to   { opacity: 1; transform: none; }
}

.gq-se-lb-bar {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 14px;
    color: #fff;
}
.gq-se-lb-bar h3 {
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: 16px;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.gq-se-lb-count {
    flex-shrink: 0;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .06em;
    color: rgba(255, 255, 255, .6);
}

.gq-se-lb-x {
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .12);
    color: #fff;
    font-size: 16px;
    cursor: pointer;
    transition: background .15s ease;
}
.gq-se-lb-x:hover { background: rgba(255, 255, 255, .26); }

/* Picture and arrows on one row, so the arrows sit beside what they move rather
   than pinned to the glass at either edge.

   min-height:0 is what keeps the media off the thumbnail strip. A flex item
   defaults to min-height:auto, which refuses to shrink below its content — so a
   tall photo pushed this row past its share and the strip went under it. With the
   floor removed the row takes exactly what the bar and the strip leave, and the
   media is capped to that. */
.gq-se-lb-stagewrap {
    flex: 1 1 auto;
    min-height: 0;
    display: flex;
    align-items: center;
    gap: clamp(8px, 2vw, 20px);
}
.gq-se-lb-stage {
    flex: 1 1 auto;
    min-width: 0;
    min-height: 0;
    margin: 0;
    /* The frame the media is fitted into. Sized by flex, and the media is laid
       out against it absolutely rather than with percentages. */
    position: relative;
    align-self: stretch;
    overflow: hidden;
}

/* object-fit rather than max-height. A percentage max-height has to resolve
   against the containing block, and this one gets its height from flex — which
   engines treat as indefinite for that purpose, so the rule was ignored and a
   tall photo rendered at 697px inside a 556px frame and was cropped. Fitting to
   an absolutely-positioned box needs no percentage to resolve, and `contain`
   shows the whole picture whatever shape it is. */
.gq-se-lb-stage img,
.gq-se-lb-stage iframe {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border: 0;
    border-radius: 10px;
}
/* No border-radius on a fitted photo: `contain` letterboxes it inside the frame,
   so the corners would be rounded off the empty box rather than the picture.
   YouTube letterboxes its own player, so the iframe can fill the frame. */
.gq-se-lb-stage img { object-fit: contain; border-radius: 0; }

.gq-se-lb-nav {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .14);
    color: #fff;
    font-size: 18px;
    cursor: pointer;
    transition: background .15s ease;
}
.gq-se-lb-nav:hover { background: rgba(255, 255, 255, .3); }

/* ---- the thumbnail strip ----
   Twelve photos is more than anyone will arrow through blind. */
.gq-se-lb-strip {
    flex-shrink: 0;
    display: flex;
    justify-content: center;
    gap: 6px;
    overflow-x: auto;
    /* Room for the selected thumbnail's ring. A scroll container clips whatever
       paints outside its padding box, so with less than the ring's offset plus its
       width the top and bottom edges were cut off and it read as two brackets. */
    padding: 5px;
    scrollbar-width: thin;
}
.gq-se-lb-strip button {
    flex: 0 0 auto;
    width: 74px;
    height: 50px;
    padding: 0;
    border: 0;
    border-radius: 6px;
    overflow: hidden;
    background: none;
    cursor: pointer;
    opacity: .45;
    outline: 2px solid transparent;
    outline-offset: 2px;
    transition: opacity .15s ease, outline-color .15s ease;
}
.gq-se-lb-strip button:hover { opacity: .8; }
.gq-se-lb-strip button.is-on { opacity: 1; outline-color: #fff; }
.gq-se-lb-strip img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* A play badge over a video thumbnail, so the strip says which is which. The icon
   is a real element built in search.js, so it uses whichever Font Awesome release
   the page loads rather than a codepoint and family name pinned here. */
.gq-se-lb-strip button.is-video { position: relative; }
.gq-se-lb-play {
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    font-size: 13px;
    color: #fff;
    background: rgba(0, 0, 0, .35);
}

@media (max-width: 760px) {
    .gq-se-lb-box { padding: 12px 10px 14px; gap: 10px; }
    .gq-se-lb-bar h3 { font-size: 14px; }
    .gq-se-lb-nav { width: 38px; height: 38px; font-size: 15px; }
    /* Thumbnails cost height a phone has not got; swiping covers the same job. */
    .gq-se-lb-strip { display: none; }
}

.gq-se-qvphotos a { display: block; cursor: zoom-in; }

/* ---------------- vibe notes ----------------
   Tinted with the vibe's own colour, and a picture beside the writing where the
   partner chose one. */
/* Always the two-column grid now. It used to depend on .has-image, which the
   markup only set when the partner had chosen a picture — so a listing's vibes
   rendered as a ragged mix of picture rows and text-only ones. Every vibe has
   art of its own to show, so every row is the same shape. */
.gq-se-qvvibe {
    display: grid;
    grid-template-columns: 108px minmax(0, 1fr);
    gap: 12px;
    align-items: start;
    padding: 10px 12px;
    border-left: 3px solid var(--vc, var(--gq-blue));
    background: color-mix(in srgb, var(--vc, var(--gq-blue)) 7%, #fff);
    border-radius: 0 8px 8px 0;
}

/* The slot, sized by the wrapper rather than by the photo, because the emblem
   that stands in for a missing photo is absolutely positioned and gives the
   row no height of its own. */
.gq-se-qvvibe-art {
    position: relative;
    display: block;
    aspect-ratio: 4 / 3;
    border-radius: 6px;
    overflow: hidden;
}

.gq-se-qvvibe img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.gq-se-qvvibe h4 {
    margin: 0 0 4px;
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 13px;
    font-weight: 800;
    color: color-mix(in srgb, var(--vc, var(--gq-navy)) 78%, #000 12%);
}
.gq-se-qvvibe p { margin: 0; font-size: 12.5px; line-height: 1.55; color: var(--gq-slate); }
.gq-se-qvvibe ul { margin: 6px 0 0; padding-left: 18px; font-size: 12px; color: var(--gq-mist); }

@media (max-width: 760px) {
    /* Was .gq-se-qvvibe.has-image — the class is gone, and every row is the
       grid now, so the stacking applies to all of them. */
    .gq-se-qvvibe { grid-template-columns: minmax(0, 1fr); }
    .gq-se-qvvibe-art { aspect-ratio: 16 / 9; }
}


/* ==========================================================================
   CANDIDATE — Vibes 2: poster tiles, and the reader they open
   ==========================================================================
   An alternative to the .gq-se-qvvibe list above, running beside it as its own
   Quickview tab so the two can be judged on real listings. One of the two goes
   when that is settled; this whole block leaves with the tab, along with the
   markup in _results.php / search/index.php and the vread functions in
   search.js.

   The idea: a listing's vibes are a SET, and the question a visitor is asking
   is "what is this place like?". Five pictures answer that in one glance where
   five paragraphs have to be read one after another. The writing is not thrown
   away, it moves one click back.
   ------------------------------------------------------------------------- */

.gq-se-qvtiles {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: 10px;
}

/* A button, so it is focusable and the keyboard works without help. All the
   inherited button chrome has to come off for it to read as a tile. */
.gq-se-vt {
    position: relative;
    display: block;
    padding: 0;
    border: 0;
    border-radius: 10px;
    overflow: hidden;
    background: var(--vc, var(--gq-blue));
    cursor: pointer;
    text-align: left;
    font: inherit;
    color: #fff;
    transition: transform .18s ease, box-shadow .18s ease;
}

.gq-se-vt:hover { transform: translateY(-3px); box-shadow: 0 18px 30px -18px rgba(10, 32, 56, .75); }
.gq-se-vt:focus-visible { outline: 3px solid var(--vc, var(--gq-blue)); outline-offset: 2px; }

/* The tile is mostly this. .gq-vibe-blank pins itself to the box, so the box
   is what carries the shape. */
.gq-se-vt-art { position: relative; display: block; aspect-ratio: 4 / 3; }
.gq-se-vt-art img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Name over the picture rather than under it: the tile stays all image, and the
   scrim is what keeps white legible over whatever the photograph happens to be
   — a caption bar sized to the text would eat a third of the tile. */
.gq-se-vt-cap {
    position: absolute;
    inset: auto 0 0 0;
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 26px 11px 9px;
    background: linear-gradient(to top,
        color-mix(in srgb, var(--vc, #123B63) 88%, #000 22%) 12%,
        transparent);
}

.gq-se-vt-name {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    font-size: 13px;
    font-weight: 800;
    text-shadow: 0 1px 6px rgba(0, 0, 0, .5);
}

.gq-se-vt-name i { flex-shrink: 0; opacity: .92; }

.gq-se-vt-n {
    margin-left: auto;
    flex-shrink: 0;
    font-size: 10.5px;
    font-weight: 700;
    opacity: .86;
    white-space: nowrap;
}

/* The affordance. Hidden until wanted, because the point of the tile is the
   picture — but a tile that opens something has to say so before it is pressed,
   and on touch there is no hover to say it, so it is always there below 760px. */
.gq-se-vt-read {
    position: absolute;
    top: 9px;
    right: 9px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 9px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .94);
    color: var(--vc, var(--gq-navy));
    font-size: 10.5px;
    font-weight: 800;
    opacity: 0;
    transform: translateY(-4px);
    transition: opacity .18s ease, transform .18s ease;
}

.gq-se-vt:hover .gq-se-vt-read,
.gq-se-vt:focus-visible .gq-se-vt-read { opacity: 1; transform: none; }

/* ---- the reader ---- */
.gq-se-vread { position: fixed; inset: 0; z-index: 1200; display: grid; place-items: center; }
.gq-se-vread[hidden] { display: none; }
.gq-se-vread-bg { position: absolute; inset: 0; background: rgba(8, 22, 38, .72); }

.gq-se-vread-box {
    position: relative;
    width: min(560px, calc(100vw - 32px));
    max-height: calc(100vh - 48px);
    overflow: auto;
    border-radius: 14px;
    background: #fff;
    box-shadow: 0 40px 80px -30px rgba(6, 20, 36, .7);
}

.gq-se-vread-x {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 2;
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .92);
    color: var(--gq-navy);
    cursor: pointer;
    box-shadow: 0 3px 10px -2px rgba(0, 0, 0, .4);
}

/* Sized here rather than by the picture, for the same reason as everywhere else
   this component appears: the emblem is absolutely positioned. */
.gq-se-vread-art { position: relative; aspect-ratio: 16 / 9; background: var(--vc, var(--gq-blue)); }
.gq-se-vread-art img { width: 100%; height: 100%; object-fit: cover; display: block; }

.gq-se-vread-body { padding: 16px 18px 20px; }

.gq-se-vread-body h3 {
    margin: 0 0 8px;
    font-size: 17px;
    font-weight: 800;
    color: color-mix(in srgb, var(--vc, var(--gq-navy)) 72%, #000 16%);
}

.gq-se-vread-body p { margin: 0; font-size: 13.5px; line-height: 1.65; color: var(--gq-slate); }

.gq-se-vread-body h4 {
    margin: 16px 0 6px;
    font-size: 11px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .06em;
    color: var(--gq-mist);
}

.gq-se-vread-body ul { margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.6; color: var(--gq-slate); }

@media (max-width: 760px) {
    .gq-se-qvtiles { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
    /* No hover on touch, so the affordance cannot be hidden behind one. */
    .gq-se-vt-read { opacity: 1; transform: none; }
}


/* ==========================================================================
   CANDIDATE — Quickview 2: the same panel under a redesigned skin
   ==========================================================================
   Not a second panel — the ONE panel with .is-v2 on it, so there is a single
   set of markup however it is dressed. The Quickview 2 button beside the old
   one is what puts the class on; see _results.php and search.js. This whole
   block, that button and the .gq-se-qv2x close go when one skin is settled on.

   What changes: the boxed grey tab strip becomes a row of pill chips on white,
   the photos lead with a featured shot, the play buttons get a proper badge,
   features read as chips, and the contact column becomes a card with rounded
   actions — with its own narrow-screen rules at the bottom, because the v2
   selectors outweigh the v1 media queries above.
   ------------------------------------------------------------------------- */

/* The button — dashed, the try-me twin, same standing as .gq-se-mvbtn. */
.gq-se-qv2btn {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 6px 12px;
    border: 1px dashed var(--gq-line);
    border-radius: 999px;
    background: #fff;
    color: var(--gq-mist);
    font-size: 12.5px;
    font-weight: 700;
    cursor: pointer;
}
.gq-se-qv2btn:hover,
.gq-se-qv2btn[aria-expanded="true"] { border-color: var(--gq-blue); color: var(--gq-blue); }
.gq-se-qv2btn[aria-expanded="true"] { border-style: solid; }

/* The panel's own close exists in the markup always, but only this skin has a
   use for it — v1 keeps its single toggle button. */
.gq-se-qv2x { display: none; }

/* White throughout rather than grey-behind-white, and a brand accent where the
   grey rule was — the panel reads as part of the card, not a drawer under it. */
.gq-se-qv.is-v2 {
    position: relative;
    border-top: 0;
    background: #fff;
    animation: gqSeQv2In .22s ease-out both;
}
.gq-se-qv.is-v2::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 3px;
    background: linear-gradient(90deg, var(--gq-navy), var(--gq-blue) 55%, var(--gq-green));
}
@keyframes gqSeQv2In {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .gq-se-qv.is-v2 { animation: none; }
}

.gq-se-qv.is-v2 .gq-se-qv2x {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 2;
    width: 30px;
    height: 30px;
    display: grid;
    place-items: center;
    border: 1px solid var(--gq-line);
    border-radius: 50%;
    background: #fff;
    color: var(--gq-mist);
    font-size: 13px;
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease, transform .15s ease;
}
.gq-se-qv.is-v2 .gq-se-qv2x:hover {
    color: var(--gq-navy);
    border-color: var(--gq-navy);
    transform: rotate(90deg);
}

/* ---- chips where the tab strip was ----
   Right padding keeps the row clear of the close button; the scrollbar goes
   because a chip row that scrolls on a phone should read as one, not as a
   framed widget. */
.gq-se-qv.is-v2 .gq-se-qvtabs {
    gap: 6px;
    padding: 14px 52px 12px 16px;
    scrollbar-width: none;
}
.gq-se-qv.is-v2 .gq-se-qvtabs::-webkit-scrollbar { display: none; }
.gq-se-qv.is-v2 .gq-se-qvtabs button {
    padding: 8px 14px;
    border: 1px solid var(--gq-line);
    border-radius: 999px;
    background: #fff;
    transition: background .18s ease, color .18s ease, border-color .18s ease, box-shadow .18s ease;
}
.gq-se-qv.is-v2 .gq-se-qvtabs button:hover {
    border-color: var(--gq-blue);
    background: #fff;
    color: var(--gq-blue);
}
.gq-se-qv.is-v2 .gq-se-qvtabs button.is-on {
    border-color: var(--gq-navy);
    background: var(--gq-navy);
    color: #fff;
    box-shadow: 0 6px 16px -8px rgba(18, 59, 99, .55);
}
.gq-se-qv.is-v2 .gq-se-qvtabs .n { background: var(--gq-cloud); color: var(--gq-slate); }
.gq-se-qv.is-v2 .gq-se-qvtabs button.is-on .n { background: rgba(255, 255, 255, .22); color: #fff; }

/* A hairline under the chips, so the pane has an edge to scroll against. */
.gq-se-qv.is-v2 .gq-se-qvpane {
    border-top: 1px solid var(--gq-line);
    padding: 14px 16px 18px;
    max-height: 400px;
    scrollbar-width: thin;
}

/* ---- photos: a collage that leads with one ----
   The first shot goes 2×2 — but only in a gallery of five or more, where the
   grid has enough around it to wrap; promoted out of a gallery of three it
   just left holes. */
.gq-se-qv.is-v2 .gq-se-qvphotos {
    grid-template-columns: repeat(auto-fill, minmax(118px, 1fr));
    gap: 8px;
}
.gq-se-qv.is-v2 .gq-se-qvphotos a {
    border-radius: 10px;
    overflow: hidden;
}
.gq-se-qv.is-v2 .gq-se-qvphotos img {
    border-radius: 0;
    transition: transform .25s ease;
}
.gq-se-qv.is-v2 .gq-se-qvphotos a:hover img { transform: scale(1.05); }
.gq-se-qv.is-v2 .gq-se-qvphotos a:first-child:nth-last-child(n+5) {
    grid-column: span 2;
    grid-row: span 2;
}
/* The featured cell's height comes from the rows it spans, not its own ratio. */
.gq-se-qv.is-v2 .gq-se-qvphotos a:first-child:nth-last-child(n+5) img {
    height: 100%;
    aspect-ratio: auto;
}

/* ---- videos: a badge, not a floating glyph ---- */
.gq-se-qv.is-v2 .gq-se-qvvideos { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); }
.gq-se-qv.is-v2 .gq-se-qvvideo { border-radius: 12px; }
.gq-se-qv.is-v2 .gq-se-qvvideo .play { font-size: 15px; text-shadow: none; }
.gq-se-qv.is-v2 .gq-se-qvvideo .play i {
    width: 46px;
    height: 46px;
    display: grid;
    place-items: center;
    padding-left: 3px;
    border: 1px solid rgba(255, 255, 255, .45);
    border-radius: 50%;
    background: rgba(255, 255, 255, .22);
    backdrop-filter: blur(4px);
    transition: transform .18s ease, background .18s ease;
}
.gq-se-qv.is-v2 .gq-se-qvvideo:hover .play i {
    transform: scale(1.1);
    background: rgba(255, 255, 255, .34);
}

/* ---- features as chips ----
   The bare two-column list read as a settings page; chips read as amenities. */
.gq-se-qv.is-v2 .gq-se-qvfeatures {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.gq-se-qv.is-v2 .gq-se-qvfeatures .gqv2-feature-tag {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 13px;
    border: 1px solid var(--gq-line);
    border-radius: 999px;
    background: var(--gq-cloud);
    font-size: 12.5px;
    font-weight: 600;
}
.gq-se-qv.is-v2 .gq-se-qvfeatures .gqv2-feature-tag i { color: var(--gq-green); }

/* ---- vibe notes: rounded cards instead of edge-ruled rows ---- */
.gq-se-qv.is-v2 .gq-se-qvvibe {
    padding: 12px;
    gap: 14px;
    border: 1px solid color-mix(in srgb, var(--vc, var(--gq-blue)) 24%, #fff);
    border-radius: 12px;
    background: color-mix(in srgb, var(--vc, var(--gq-blue)) 6%, #fff);
}
.gq-se-qv.is-v2 .gq-se-qvvibe-art { border-radius: 9px; }

/* ---- details: the contact column becomes a card ---- */
.gq-se-qv.is-v2 .gq-se-qvdetails { grid-template-columns: 1.15fr .85fr; gap: 8px 26px; }
.gq-se-qv.is-v2 .gq-se-qvname { font-size: 17px; }
.gq-se-qv.is-v2 .gq-se-qvcol:last-of-type {
    align-self: start;
    padding: 14px 16px 16px;
    border: 1px solid var(--gq-line);
    border-radius: 12px;
    background: var(--gq-cloud);
}
.gq-se-qv.is-v2 .gq-se-qvlinks { border-top-color: color-mix(in srgb, var(--gq-navy) 12%, #fff); }
.gq-se-qv.is-v2 .gq-se-qvlinks a,
.gq-se-qv.is-v2 .gq-se-qvlinks span { border-radius: 999px; }
.gq-se-qv.is-v2 .gq-se-qvlinks .is-primary {
    padding: 9px 12px;
    border: 0;
    background: linear-gradient(105deg, var(--gq-navy), var(--gq-blue));
}
.gq-se-qv.is-v2 .gq-se-qvlinks a.is-primary:hover {
    background: linear-gradient(105deg, var(--gq-blue), var(--gq-green));
}
.gq-se-qv.is-v2 .gq-se-qvlinks .is-soon {
    background: color-mix(in srgb, var(--gq-navy) 8%, #fff);
    color: var(--gq-mist);
}

/* ---- narrow screens ----
   Repeated here because these selectors outweigh the v1 media queries above —
   without them the two-column details would survive onto a phone. */
@media (max-width: 900px) {
    .gq-se-qv.is-v2 .gq-se-qvdetails { grid-template-columns: minmax(0, 1fr); gap: 16px; }
}
@media (max-width: 760px) {
    .gq-se-qv.is-v2 .gq-se-qvtabs { padding: 12px 48px 10px 12px; }
    .gq-se-qv.is-v2 .gq-se-qvpane { padding: 12px 12px 14px; max-height: 340px; }
    .gq-se-qv.is-v2 .gq-se-qv2x { top: 10px; right: 10px; }
    .gq-se-qv.is-v2 .gq-se-qvphotos { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
    /* One thing to a row: thumb-sized targets, and no half-width buttons. */
    .gq-se-qv.is-v2 .gq-se-qvlinks a,
    .gq-se-qv.is-v2 .gq-se-qvlinks span { flex: 1 1 100%; }
}
