/* Groundhopping - page-scoped styles, all .gh- namespaced.
   Design language ported from the ft.fr "Advanced search, redesigned"
   artifact: navy hero, overlapping white search card, green action color,
   light page background.

   ONE FILE, FOUR COPIES: the BO preview (?page=groundhopping) and ft.fr /
   ft.club / ft.es all load this verbatim. Everything the live theme needs and
   the BO does not is under `body.gh-body`, a class only the WordPress template
   emits, so the file is identical everywhere. Keep the four copies IDENTICAL:
   fix here, then re-upload all four. */

/* TOKENS ONLY, on both roots. .gh-prose is a SIBLING of .gh-page, not a child, so it
   inherits nothing from it: every var() in a prose rule resolved to nothing and the
   whole declaration was silently dropped at computed-value time. The ready-made search
   chips lost their border, background and colour that way.

   Tokens only is the point. The typography below stays on .gh-page, because the prose
   band deliberately takes the THEME's content styles for its headings and paragraphs,
   and a font-size here would quietly override them. */
.gh-page,.gh-prose{
  --gh-navy:#13274d; --gh-green:#0a8368; --gh-green-ink:#076f58;
  --gh-ink:#1b2733; --gh-mut:#5f6f82; --gh-line:#e4e8ef; --gh-bd:#98a4b8;
  --gh-page-bg:#eef1f5; --gh-card:#fff; --gh-tint:#f2f5fa;
  --gh-pill-bg:#e4f3ed; --gh-pill-bd:#bfe3d5; --gh-pill-ink:#1d5c46;
  --gh-t1:#0f6e56; --gh-t1bg:#e1f5ee; --gh-t2:#854f0b; --gh-t2bg:#faeeda;
  --gh-font:"Open Sans",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --gh-mono:ui-monospace,Menlo,Consolas,monospace;
}

/* The tool's own surface and typography. NOT shared with .gh-prose. */
.gh-page{
  background:var(--gh-page-bg);
  border-radius:12px;
  font-family:var(--gh-font);
  font-size:14px;
  /* Stated, not inherited. The BO's body is 1.6 and the live theme's is 2
     (css/mystyle2.css), so without this every line box on the page grows 25% on
     the port and the whole layout is measured against a baseline it was never
     designed on. 1.6 is the number the design was built at. */
  line-height:1.6;
  color:var(--gh-ink);
}

/* ---------- hero ---------- */
.gh-hero{background:var(--gh-navy);border-radius:12px 12px 0 0;padding:26px clamp(16px,3vw,30px) 56px}
.gh-hero-h1{margin:0;color:#fff;font-weight:800;letter-spacing:-.01em;line-height:1.14;font-size:clamp(22px,3vw,32px);max-width:26ch}
.gh-hero-sub{margin:9px 0 0;color:#c7d3ec;font-size:13.5px;line-height:1.55;max-width:70ch}

/* ---------- search card (overlaps the hero) ---------- */
.gh-sb{background:var(--gh-card);border:1px solid var(--gh-line);border-radius:14px;
  box-shadow:0 10px 26px rgba(19,39,77,.13);margin:-34px clamp(12px,3vw,26px) 0;
  padding:14px 14px 12px;position:relative;z-index:3}
/* Field captions. Same shape as `#main_filters .big_label` on the advanced search
   page (css/ft_xx.css): 10px uppercase mono, .12em tracking, #5f6f82, which is
   --gh-mut. A caption then reads as a field NAME rather than as body copy, and the
   two search cards look like the same control on two pages. The hint beside it
   follows .sub_label there: same grey, normal case, no tracking. */
.gh-sb-label{display:flex;justify-content:space-between;align-items:baseline;gap:10px;
  font:700 10px/1 var(--gh-mono);letter-spacing:.12em;text-transform:uppercase;
  color:var(--gh-mut);margin-bottom:7px}
/* Steps back OUT of the caption's mono, so it has to NAME the page font: the `font`
   shorthand rejects `inherit` as a family (the whole declaration is then dropped and
   the hint silently inherits the mono), and font-family:inherit would inherit the
   mono from .gh-sb-label, which is the parent. */
.gh-sb-hint{font-family:var(--gh-font);font-size:11px;font-weight:700;line-height:1.2;
  letter-spacing:0;text-transform:none;color:var(--gh-mut)}
/* SPECIFICITY, THE STATE VARIANTS. Every button rule from here down is scoped under
   .gh-page, which is not decoration. The live theme styles the bare element in its
   STATES, not just at rest: style.css carries `button:hover{background-color:#185c8a}`
   and `button:active{border:none;padding:10px 24px 11px}`. A pseudo-class counts in
   the class column, so both are (0,1,1) and outrank ANY single-class rule at (0,1,0).
   Unscoped, that put a dark blue plate behind "Reinitialiser la recherche" on hover
   and made every button on the page jump to 24px of side padding while pressed, which
   on a touch device is every tap. Scoping the base rules to (0,2,0) and their hovers
   to (0,2,1) wins on the class column and hands each control its own look back.
   Reported live on ft.fr 2026-09-04. Do not un-scope these.

   The audit before the port checked that every button declares its own colour and
   padding AT REST and concluded the theme's bare-button rules were harmless. That was
   the wrong test: it is the :hover and :active variants that carry the extra
   specificity. Check state variants, not just base rules. */
/* "Reset all filters" is destructive and was a 20px target; the padding/margin pair
   grows the hit area without moving anything visually. */
.gh-page .gh-clear{background:none;border:0;font:inherit;font-size:12.5px;font-weight:700;color:var(--gh-mut);cursor:pointer;padding:6px 8px;margin:-6px -8px;border-radius:6px}
/* Red TEXT, and nothing else: no plate, no border, no shadow, no size change. Every
   one of those is restated rather than left to the base rule, because this control
   is the one the theme's state rules hit hardest and the reset is the point. */
.gh-page .gh-clear:hover,.gh-page .gh-clear:focus,.gh-page .gh-clear:active{
  color:#C62828;background:none;border:0;box-shadow:none;text-decoration:none;padding:6px 8px}
.gh-sb-divider{height:1px;background:var(--gh-line);margin:12px -14px}
.gh-sb-fields{display:flex;flex-wrap:wrap;gap:10px 14px;align-items:flex-end}
.gh-f{display:flex;flex-direction:column;gap:4px;font-size:12px;font-weight:700;color:var(--gh-mut)}
.gh-f>span{font:700 10px/1 var(--gh-mono);letter-spacing:.12em;text-transform:uppercase;color:var(--gh-mut)}
/* --gh-line against the field fill is 1.17:1, so the boundary of every control was
   effectively invisible (WCAG 1.4.11 wants 3:1 for the parts that identify a control).
   --gh-bd is the same hue, darkened until it passes. */
/* 16px on every control the visitor operates, not 13.5. Two reasons and they agree:
   these are the page's primary inputs and they were smaller than the option text
   inside their own menus, and iOS Safari ZOOMS THE WHOLE PAGE when a form control
   under 16px takes focus, which on an iPad meant tapping Dates threw the layout off
   and left the reader to pinch back out. The date fields are bumped with the select
   because they share this row; they would otherwise sit visibly smaller beside it. */
.gh-f input,.gh-f select{font:inherit;font-size:16px;font-weight:600;color:var(--gh-ink);
  padding:9px 11px;border:1px solid var(--gh-bd);background-color:#f7f9fc;border-radius:9px}
/* Safari draws its OWN control for a <select> and ignores background, border and
   border-radius until the appearance is reset, so on Safari (iPad and desktop) the
   Dates dropdown rendered as a bare native menu next to fields that were styled.
   Resetting the appearance also removes the native arrow, so the arrow is drawn
   back here as a background image: without it the control loses the only thing
   that says it opens a menu. background-COLOR, never the background shorthand,
   anywhere a select can be reached: the shorthand resets background-image and
   would wipe the arrow (that is exactly what the :focus rule below used to do). */
.gh-page select{-webkit-appearance:none;-moz-appearance:none;appearance:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1.6 1.6 6 6l4.4-4.4' fill='none' stroke='%235f6f82' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 11px center;background-size:11px 7px;
  padding-right:30px}
.gh-f select{cursor:pointer}
.gh-f input:focus,.gh-f select:focus{outline:2px solid var(--gh-green);outline-offset:1px;background-color:#fff}
.gh-f input[type=number]{width:92px}
.gh-dates-custom{display:none}
.gh-dates-custom.gh-show{display:contents}
.gh-f-check{flex-direction:row;align-items:center;gap:7px;padding-bottom:9px}
.gh-f-check input{width:auto}
.gh-f-check-txt{font-size:12.5px;font-weight:600;color:var(--gh-ink);text-transform:none;letter-spacing:0}
.gh-f-market select{background-color:#fff;border-style:dashed}
.gh-slid{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
/* Since the distance control lost its three preset buttons, this is the whole control,
   so it gets the room the buttons had. The hint carries the meaning the button labels
   used to ("environ 1 h 30"), computed by driveTime() from the engine's travel model. */
.gh-page .gh-slid{margin-top:6px}
.gh-page .gh-slid input[type=range]{width:100%;flex:1 1 160px;min-width:120px}
.gh-slid-hint{color:var(--gh-mut);font-size:11.5px;white-space:nowrap}
.gh-slid output{font-weight:700;min-width:34px;color:var(--gh-ink);font-size:13px}
.gh-slid input[type=range]{padding:0;border:0;background:none;width:130px;accent-color:var(--gh-green)}

/* country chips: site-style pills (white -> green when selected) */
.gh-country-chips{display:flex;flex-wrap:wrap;gap:7px}
.gh-page .gh-cchip{display:inline-flex;align-items:center;gap:6px;font:inherit;font-size:12.5px;font-weight:700;
  color:var(--gh-navy);background:#fff;border:1px solid var(--gh-line);border-radius:20px;
  padding:6px 12px;cursor:pointer;transition:border-color .12s,background .12s}
.gh-page .gh-cchip:hover{border-color:var(--gh-green);color:var(--gh-green-ink);background:var(--gh-pill-bg)}
/* Selected state was carried by a background 1.14:1 from the unselected one plus hue,
   which is colour alone (WCAG 1.4.1). The check mark and the heavier border are the
   non-colour cues; aria-pressed already carries it for assistive tech. */
.gh-page .gh-cchip.gh-on{background:var(--gh-pill-bg);border-color:var(--gh-pill-ink);border-width:2px;padding:5px 11px;color:var(--gh-pill-ink)}
.gh-page .gh-cchip.gh-on::before{content:"\2713";font-weight:800;margin-right:1px}
.gh-page .gh-cchip.gh-suggest{border-style:dashed;border-color:var(--gh-pill-bd);color:var(--gh-green-ink)}
.gh-page .gh-cchip.gh-morebtn{border-style:dashed;color:var(--gh-mut);background:transparent}
.gh-page .gh-cchip.gh-morebtn:hover{color:var(--gh-green-ink);background:var(--gh-pill-bg)}
.gh-cchip .gh-cc{font-weight:400;color:var(--gh-mut);font-size:11.5px}
/* opacity was the whole problem: .75 on this token blends to 3.85:1 against the chip.
   Full opacity on the same colour is 6.87:1. */
.gh-cchip.gh-on .gh-cc{color:var(--gh-pill-ink)}
.gh-chip-flag{width:15px;height:15px;border-radius:50%;object-fit:cover;border:1px solid rgba(0,0,0,.12);flex:none}
/* Group caption inside the expanded chip strip. flex-basis 100% so it takes a
   line of its own in the wrapping strip and the alphabet visibly restarts under
   a heading rather than in the middle of a row. Same caption style as the field
   labels. Only ever emitted when both tiers have chips. */
.gh-page .gh-cgroup{flex:0 0 100%;margin:8px 0 1px;font:700 10px/1 var(--gh-mono);
  letter-spacing:.12em;text-transform:uppercase;color:var(--gh-mut)}
.gh-page .gh-cgroup:first-child{margin-top:0}
/* Coverage note under the expanded country strip. Full width like a group caption, but
   prose rather than a label: it is the only thing on the page that says why France is
   not in the list. */
.gh-page .gh-cnote{flex:0 0 100%;margin:10px 0 0;padding-top:9px;border-top:1px solid var(--gh-line);
  font-size:12px;line-height:1.5;color:var(--gh-mut)}
.gh-page .gh-cnote b{color:var(--gh-ink);font-weight:700}
.gh-page .gh-cnote .gh-chip-flag{vertical-align:-3px;margin-right:6px}
body.gh-body .gh-page .gh-cnote a{color:var(--gh-navy);font-weight:700;text-decoration:underline}
body.gh-body .gh-page .gh-cnote a:hover{color:var(--gh-green-ink)}

/* ---------- results zone ---------- */
.gh-zone{padding:16px clamp(12px,3vw,26px) 24px}
/* sticky search recap: appears once the search card scrolls out of view */
/* --gh-stick, not a literal 8px: under 768px the BO paints a fixed .mobile-header 54px
   tall, and a sticky offset measured from the viewport puts this bar 46px UP inside it.
   At z-index 600 it then draws over the header instead of under the thumb. Both sticky
   elements on this page read the same variable so they cannot drift apart. */
.gh-sum-txt{font-size:12.5px;font-weight:700;color:var(--gh-navy);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gh-page .gh-sum-edit{font:inherit;font-size:12px;font-weight:700;color:var(--gh-green-ink);background:var(--gh-pill-bg);border:1px solid var(--gh-pill-bd);border-radius:20px;padding:5px 12px;cursor:pointer;flex:none}
.gh-page .gh-sum-edit:hover{background:#d3ecdf}
.gh-stats{font-size:12.5px;color:var(--gh-mut);margin-left:auto;padding-bottom:8px}
.gh-city-f{max-width:100%}
.gh-city-filter{font:inherit;font-size:16px;font-weight:600;padding:8px 10px;border:1px solid var(--gh-line);
  border-radius:9px;background-color:#fff;color:var(--gh-navy);min-width:200px;max-width:100%;cursor:pointer}

/* The map column is a range, and its ceiling is a VARIABLE, not a literal, because
   the live theme needs a narrower one (see --gh-mapcol at the bottom of this file).
   Expressing that as an override of the VALUE rather than of grid-template-columns
   is the whole point: a live-only rule that restated the template would also have to
   restate every media query that changes it, and the one that collapses this grid to
   a single column below 900px sits EARLIER in the file at the same specificity, so
   the override silently won on phones too. It did: the map column collapsed to 0px,
   the "show the map" button became a 28px sliver and the trip list sat 16px off
   centre. Live on ft.fr 2026-09-04, found by the user, fixed here. */
.gh-wrap{display:grid;grid-template-columns:minmax(0,1fr) minmax(280px,var(--gh-mapcol,420px));gap:16px;align-items:start}
/* Clears the pinned toolbar, not just the pinned site header. .gh-tools sticks at
   --gh-stick and then occupies its own height below that, so an offset of --gh-stick + 8
   parked the map's top inside the bar and its toolbar scrolled in behind it.
   --gh-tools-h is measured by toolsOffset() in the engine, because the bar wraps to two
   lines below about 1100px and a literal would be wrong at one width or the other. */
.gh-mapwrap{position:sticky;top:calc(var(--gh-stick,8px) + var(--gh-tools-h,0px) + 8px)}
/* A fixed 560px plus the toolbar is 622px, so on a 768px laptop viewport the bottom
   fifth of the pinned map (including the OSM attribution) sat below the fold for the
   whole scroll. Cap it to what is actually visible. */
/* Everything above the map inside the pinned column is subtracted by name rather than
   paid for by one 90px constant: the pinned site header, the pinned toolbar, and the
   map's own toolbar, whose height changed the day it gained a route caption. The floor
   is 260 rather than 340 because on a 1366x768 laptop with a bookmarks bar the old floor
   pushed the Leaflet attribution and the bottom zoom control past the fold. */
#gh-map{height:min(560px,calc(100vh - var(--gh-nav-h,0px) - var(--gh-tools-h,0px) - var(--gh-mapbar-h,46px) - 32px));min-height:260px;
  border:1px solid var(--gh-line);border-radius:12px;background:#dfe6f0}
/* Leaflet numbers its own panes and controls (tile pane 200, markers 600, controls
   around 800) and .leaflet-container is position:relative with z-index:auto, so it
   creates NO stacking context and those numbers escape the map to be compared against
   the rest of the page. The sticky toolbar is z-index 5, so the zoom control drew on
   top of it: scrolling a card's map behind the pinned filters put a +/- widget over
   them. isolation:isolate contains the whole lot without touching position, which
   matters because this element is static inside a card on a phone and sticky beside
   the list on desktop; z-index:0 then places the map as ONE box, under the toolbar,
   wherever it is positioned. Verified with elementFromPoint across the pinned strip. */
.gh-page .gh-mapwrap{isolation:isolate;z-index:0}
/* The caption belongs to the map's TOP edge, the way back out to its bottom. The caption
   names what the map is showing, so it reads as the map's title; "all grounds" is the
   exit and belongs under the thing it exits from. Sharing one bar above the map, the
   button pushed the caption onto a second line and the pair read as a toolbar labelling
   the LIST rather than the map.
   Two boxes rather than one, so the caption can be display:none when empty without
   stranding the button. The 8px lives on the CAP, not on .gh-map-toolbar, so an empty
   caption collapses that bar to nothing instead of leaving a gap above the map. Both
   boxes are measured into --gh-mapbar-h by mapBarOffset(): the map's height subtracts
   its own chrome by name, so a bar added above OR below has to be counted. */
.gh-map-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px}
.gh-page .gh-map-cap{flex:1 0 100%;min-width:0;margin-bottom:8px;font-size:12.5px;font-weight:700;color:var(--gh-navy);
  line-height:1.35;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.gh-page .gh-map-cap:empty{display:none}
.gh-map-foot{display:flex;justify-content:flex-end;margin-top:8px}
.gh-page .gh-map-toolbar button,.gh-page .gh-map-foot button{flex:0 0 auto;font:inherit;font-size:12.5px;font-weight:700;
  padding:8px 13px;border:1px solid var(--gh-line);border-radius:9px;background:#fff;color:var(--gh-navy);cursor:pointer}
.gh-page .gh-map-toolbar button:hover,.gh-page .gh-map-foot button:hover{border-color:var(--gh-green);
  color:var(--gh-green-ink);background:var(--gh-pill-bg)}
.gh-empty{padding:34px 20px;text-align:center;color:var(--gh-mut);background:#fff;border:1px solid var(--gh-line);border-radius:12px}

/* ---------- trip cards ---------- */
.gh-trip{background:var(--gh-card);border:1px solid var(--gh-line);border-radius:12px;padding:12px 14px;margin-bottom:12px;transition:border-color .12s}
.gh-trip:hover{border-color:var(--gh-green)}
/* An outer ring says "this one is selected". An inset bar down the left edge says it
   too and points across at the map column, which is the relationship being taught. It
   also survives on a phone, where it marks the card the inline map belongs to. */
.gh-trip.gh-active{border-color:var(--gh-green);box-shadow:inset 3px 0 0 var(--gh-green)}
.gh-trip.gh-assoc{border-left:3px solid #7f77dd}
/* The header was clickable with nothing but a cursor to say so, while the match rows
   below it visibly react to a hover. Given a row is a link that navigates away and the
   header is what drives the map, the quieter of the two was the one doing the thing a
   first-time reader wanted. The negative margin pulls the hover surface out to the card
   edges and the padding puts the content back exactly where it was, so nothing moves. */
.gh-page .gh-trip-head{position:relative;cursor:pointer;margin:-12px -14px 0;padding:12px 14px 0;
  border-radius:11px 11px 0 0;transition:background-color .12s}
.gh-page .gh-trip-head:hover{background:var(--gh-tint)}
.gh-page .gh-trip.gh-active .gh-trip-head{background:var(--gh-pill-bg)}
.gh-trip-h{display:flex;justify-content:space-between;align-items:baseline;gap:8px;flex-wrap:wrap}
.gh-trip-h .gh-name{font-size:15px;font-weight:800;color:var(--gh-navy);letter-spacing:-.01em;margin:0}
.gh-trip-dates{font-size:13px;font-weight:400;color:var(--gh-mut);margin-left:8px;white-space:nowrap}
.gh-rightbadges{display:flex;gap:6px;align-items:baseline;flex-wrap:wrap;justify-content:flex-end}
.gh-flag{width:18px;height:18px;border-radius:50%;object-fit:cover;vertical-align:-4px;margin-right:7px;border:1px solid rgba(0,0,0,.12)}
/* Two size variants, both carrying .gh-flag as well so the shape rule above still
   applies to them.

   The three-class selectors are deliberate, not habit. Two rules already claim these
   images: the live theme's .entry-content img{max-width:100%;height:auto} at (0,1,1),
   and this file's own body.gh-body .gh-flag{width:18px;height:18px}, which exists to
   beat it. That one is (0,2,1), NOT (0,2,0): `body` is a type selector and counts in the
   third column, which is easy to drop and is why a first attempt at .gh-page .gh-flag-route
   (0,2,0) lost and both variants measured 18px. (0,3,0) beats both, on both surfaces,
   wherever the rule sits, so there is no live-only twin to keep in step and no source
   order for the next person to depend on. */
.gh-page .gh-name .gh-flag-route{width:17px;height:17px;vertical-align:-3px;margin-right:6px}
/* The row title is 13.5px. An 18px circle beside it, now that EVERY row has one and not
   just the rare cross-border row, reads as a column of badges rather than as context. */
.gh-page .gh-info .gh-flag-row{width:14px;height:14px;vertical-align:-2px;margin-right:6px}
/* One leg = one flag plus the city it labels. Keeps them on the same line so a chain
   that wraps breaks at an arrow instead of orphaning a flag. */
.gh-page .gh-leg{white-space:nowrap}

.gh-teams{display:flex;flex-wrap:wrap;gap:5px;margin:8px 0 2px}
.gh-team{font-size:12.5px;padding:3px 9px;border-radius:20px;background:var(--gh-tint);border:1px solid var(--gh-line);color:var(--gh-navy);font-weight:600;white-space:nowrap}

.gh-badges{display:flex;gap:6px;flex-wrap:wrap;margin:6px 0 2px;align-items:center}
.gh-b{font-size:11px;padding:2px 8px;border-radius:5px;background:var(--gh-tint);color:#42506a;white-space:nowrap}
.gh-b.gh-t1{background:var(--gh-t1bg);color:var(--gh-t1)}
.gh-b.gh-t2{background:var(--gh-t2bg);color:var(--gh-t2)}
/* Amber is a caution colour and it was on 65% of Italian trips, warning about an unknown
   kick-off on itineraries where nothing depended on it. gh-t3 is the same fact stated
   neutrally; amber is now reserved for a same-day hop whose feasibility really is unknown. */
.gh-b.gh-t3{background:var(--gh-tint);color:#42506a}
.gh-b.gh-near{background:#efe9fb;color:#5b3da8}
.gh-b.gh-price{background:var(--gh-pill-bg);color:var(--gh-green-ink);font-weight:800;font-size:15px;padding:3px 11px;margin-left:auto}
/* .85 blended this to 4.02:1; at full opacity the same green is 5.36:1 */
.gh-b.gh-price .gh-pq{font-size:11px;font-weight:400}

/* ---------- itinerary (collapsed by default, accordion) ---------- */
.gh-tl{display:none;margin-top:8px;border-top:1px solid var(--gh-line);padding-top:8px}
.gh-trip.gh-open .gh-tl{display:block}
a.gh-m{display:flex;gap:10px;align-items:flex-start;padding:5px 6px;margin:0 -6px;border-radius:8px;text-decoration:none;color:inherit}
a.gh-m:hover{background:var(--gh-tint)}
.gh-when{flex:none;width:78px;font-size:12px;line-height:1.3;color:var(--gh-ink)}
.gh-when b{font-weight:700}
.gh-info .gh-t{font-size:13.5px;font-weight:700;color:var(--gh-ink)}
.gh-info .gh-s{font-size:12px;color:var(--gh-mut)}
.gh-tkt{display:inline-block;background:var(--gh-green);color:#fff;padding:2px 9px;border-radius:6px;font-weight:700;white-space:nowrap}
/* Every match row opens the event page in a new tab (target=_blank), which the
   reader has no way to know before clicking. The standard box-and-arrow glyph says
   so, drawn as a background image rather than an icon font: the theme's FontAwesome
   is the JS kit, which REPLACES an <i> with an <svg> and would break any selector
   hung on it, and a background image also costs no extra node in 80 rows. The <a>
   already carries rel="noopener". aria-hidden is not needed: it is not a node. */
.gh-tkt::after{content:"";display:inline-block;width:9px;height:9px;margin-left:5px;
  vertical-align:-1px;background-repeat:no-repeat;background-size:9px 9px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23ffffff' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.5 6.9v3.2a1 1 0 0 1-1 1h-7a1 1 0 0 1-1-1v-7a1 1 0 0 1 1-1h3.2'/%3E%3Cpath d='M7.6 1.5h3v3'/%3E%3Cpath d='M5.2 6.8 10.4 1.6'/%3E%3C/svg%3E")}
a.gh-m:hover .gh-tkt{background:var(--gh-green-ink)}
.gh-ttbc{display:inline-block;font-size:10.5px;background:var(--gh-t2bg);color:var(--gh-t2);padding:1px 5px;border-radius:4px}
/* the "v" between the two team names, and the country suffix on a spillover trip's
   title. Both were inline style attributes with hardcoded hex outside the token set,
   which the house rules ban and which no theme override could reach on the live port. */
.gh-vs{color:var(--gh-mut)}
/* Zone abbreviation after a venue-local kickoff ("17:00 EDT"): the clock is the
   ground's own time, not the reader's, and the abbr is what says so. */
.gh-tz{font-size:10px;font-weight:700;color:var(--gh-mut);letter-spacing:.02em;text-decoration:none;cursor:help}
.gh-conn{font-size:11px;color:var(--gh-mut);padding:1px 0 1px 88px}

/* ---------- spice badges + row tags ---------- */
.gh-b.gh-derby{background:#fdeaea;color:#a32d2d;font-weight:700}
.gh-b.gh-of{background:var(--gh-pill-bg);color:var(--gh-pill-ink);font-weight:700}
.gh-ofrow{color:var(--gh-green-ink);font-weight:700;font-size:11px}
.gh-derbyrow{color:#a32d2d;font-weight:700;font-size:11px}

/* ---------- map clusters (navy on-brand bubbles) ---------- */
.gh-cluster{background:var(--gh-navy);color:#fff;border-radius:50%;width:30px;height:30px;display:flex;align-items:center;justify-content:center;font-size:12px;font-weight:700;border:2px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,.35)}

/* ---------- empty-state jump + copy itinerary ---------- */
.gh-page .gh-jumpbtn{margin-top:12px;font:inherit;font-size:13px;font-weight:700;color:#fff;background:var(--gh-green);border:0;border-radius:9px;padding:9px 15px;cursor:pointer}
.gh-page .gh-jumpbtn:hover{background:var(--gh-green-ink)}
.gh-page .gh-copybtn{font:inherit;font-size:11.5px;font-weight:700;color:var(--gh-navy);background:#fff;border:1px solid var(--gh-line);border-radius:20px;padding:4px 11px;cursor:pointer;flex:none}
.gh-page .gh-copybtn:hover{border-color:var(--gh-green);color:var(--gh-green-ink);background:var(--gh-pill-bg)}
/* Per-card map toggle, phones only. It moved out of the card foot and up into the header
   beside the chevron: the header is what owns the map, and in the foot the control that
   summons it lived inside the collapsible panel, at the bottom of an expanded card. Now
   it is reachable whether the card is open or shut, and it sits with the other control
   that acts on the whole card. align-self keeps it off the badge row's baseline, which
   would otherwise drop a bordered pill a couple of pixels below the tier chip. */
.gh-page .gh-mapbtn{display:none;font:inherit;font-size:11.5px;font-weight:700;color:var(--gh-navy);
  background:#fff;border:1px solid var(--gh-line);border-radius:20px;padding:4px 11px;cursor:pointer;
  flex:none;align-self:center}
.gh-page .gh-mapbtn:hover{border-color:var(--gh-green);color:var(--gh-green-ink);background:var(--gh-pill-bg)}
.gh-page .gh-mapbtn:focus-visible{outline:2px solid var(--gh-green);outline-offset:2px}
@media (max-width:900px){
  .gh-page .gh-mapbtn{display:inline-block}
  .gh-page .gh-trip-foot{gap:8px}
}

/* ---------- card bottom: recap, then hotel ---------- */
.gh-trip-bottom{border-top:1px solid var(--gh-line);margin-top:8px;padding-top:8px}
.gh-trip-foot{font-size:11.5px;color:var(--gh-mut);display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap}
.gh-hotel{margin-top:10px}
.gh-hotel-h{font-size:12.5px;color:var(--gh-ink);font-weight:700;margin-bottom:7px}
.gh-hotel-btns{display:flex;flex-wrap:wrap;gap:8px}
.gh-hotel-btn{font-size:12.5px;text-decoration:none;padding:6px 13px;border-radius:20px;background:#fff;border:1px solid var(--gh-line);color:var(--gh-navy);font-weight:700}
.gh-hotel-btn:hover{border-color:var(--gh-green);color:var(--gh-green-ink);background:var(--gh-pill-bg)}

/* ---------- map pins ---------- */
.gh-pin{background:var(--gh-navy);color:#fff;border-radius:50%;width:22px;height:22px;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;border:2px solid #fff;box-shadow:0 1px 4px rgba(0,0,0,.4)}

/* ---------- narrow screens ---------- */
@media (max-width:900px){
  .gh-wrap{grid-template-columns:1fr}
  /* the map is the second grid child, so in one column it landed AFTER all 40 cards:
     tapping a card animated a map thousands of pixels below the fold, and the
     "show all grounds" button was unreachable for the same reason */
  .gh-mapwrap{position:static;order:-1}
  #gh-map{height:220px;min-height:0}
  /* The search card keeps the SAME gutter as everything else. It used to drop to a
     flat 10px here while .gh-zone stayed on clamp(12px,3vw,26px), so from 768px to
     900px the card sat up to 16px left of the toolbar and the trip list under it.
     On a phone the clamp is 12px, so this override was buying 2px and paying for it
     with a visibly crooked tablet layout. */
  .gh-f{flex:1 1 140px}
  .gh-f > input,.gh-f > select{width:100%}
  .gh-f-check input{width:auto}
  .gh-slid input[type=range]{width:100%}
}

/* ---------- Batch 5: list semantics, disclosure toggle, show more ---------- */
.gh-list{list-style:none;margin:0;padding:0}
.gh-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
/* the chevron is a real button now, not a decorative span inside one giant control */
/* Pinned to the top right of the head rather than riding in the badge row. As a badge it
   wrapped with everything else, so a card whose title ran to two lines pushed the tier
   chip and the toggle down with it: the control that opens the card moved depending on
   how long the card's own title was. Absolute against .gh-trip-head, which is already
   position:relative for this. Bigger too, because it is the card's primary control and
   was the smallest thing in the row. */
.gh-page .gh-chev{position:absolute;top:8px;right:8px;z-index:1;
  font:inherit;background:none;border:0;padding:2px 7px;margin:0;cursor:pointer;
  color:var(--gh-mut);font-size:24px;line-height:1.1;display:inline-block;border-radius:8px}
/* Room reserved so a long title or a full badge row never runs under it. */
.gh-page .gh-trip-h{padding-right:34px}
.gh-chev span[aria-hidden]{display:inline-block;transition:transform .15s}
.gh-trip.gh-open .gh-chev span[aria-hidden]{transform:rotate(90deg)}
.gh-page .gh-chev:hover{color:var(--gh-green-ink);background:var(--gh-pill-bg)}
.gh-chev:focus-visible,.gh-cchip:focus-visible,.gh-copybtn:focus-visible,.gh-more:focus-visible,
.gh-jumpbtn:focus-visible,.gh-hotel-btn:focus-visible,.gh-sum-edit:focus-visible,
.gh-clear:focus-visible{outline:2px solid var(--gh-green);outline-offset:2px}
/* line-height and the marker are STATED, not inherited: the BO's baseline is 1.6
   and the live theme's h1-h6 rule is 1.3, and the theme's `summary{display:block}`
   reset removes the disclosure triangle that is this control's only affordance. */
h3.gh-name{margin:0;font-size:15px;font-weight:800;color:var(--gh-navy);letter-spacing:-.01em;line-height:1.3}
.gh-page .gh-fine summary{display:list-item}
.gh-page .gh-more{display:block;width:100%;font:inherit;font-size:13px;font-weight:700;color:var(--gh-navy);
  background:#fff;border:1px solid var(--gh-bd);border-radius:10px;padding:11px 15px;cursor:pointer;margin:4px 0 8px}
.gh-page .gh-more:hover{border-color:var(--gh-green);color:var(--gh-green-ink);background:var(--gh-pill-bg)}
/* an expanded strip of 24 to 30 chips is ~500px on a phone, burying the rest of the
   form; the toggle stays outside the scroller so it never scrolls away */
.gh-country-chips{max-height:38vh;overflow-y:auto}
/* 18 of 477 stadium names clip inside a nowrap tooltip in an overflow:hidden pane */
.gh-page .leaflet-tooltip{white-space:normal;max-width:200px}
@media (prefers-reduced-motion:reduce){
  .gh-chev span[aria-hidden],.gh-trip{transition:none}
}

/* ==================================================================
   LAYOUT RESTRUCTURE. The form asks only WHERE and WHEN; distance, trip
   length, city and budget moved into a filters panel beside the results,
   because they are opinions you can only form once results exist. The panel
   is the 7018 advanced-search sheet (.sr-filters-sheet in
   ft_supersearch_results.css) renamed: an in-flow panel under the toolbar on
   desktop, a bottom sheet on a phone, including its position:fixed scroll
   lock and the reason that is NOT overflow:hidden.
   ================================================================== */
/* Mockup v2 layout. Reuses every token from groundhopping.css. The sheet block is a
   1:1 port of the .sr-* filters sheet in ft_supersearch_results.css. */

.gh-page .gh-hero-slim{padding:20px clamp(16px,3vw,30px) 44px}
.gh-page .gh-hero-slim .gh-hero-h1{font-size:clamp(19px,2.4vw,26px);max-width:24ch}
.gh-page .gh-hero-slim .gh-hero-sub{margin-top:6px}

/* search card: Where on the left, When on the right */
.gh-page .gh-sb-slim{padding:13px 14px 11px}
.gh-page .gh-sb-row{display:flex;gap:20px;align-items:flex-start}
.gh-page .gh-f-dest{flex:1 1 auto;min-width:0}
/* Fixed width, and the From/To pair reveals UNDERNEATH the Dates select inside this
   block. Sized auto, picking "Dates personnalisees" grew it from 183px to 505px, which
   stole the space from the country column (680 -> 358) and re-wrapped the chip strip from
   three rows to five: choosing a date option visibly rearranged the entire card. The
   country column must not move when the date control changes shape. */
.gh-page .gh-f-when{flex:0 0 292px;display:flex;flex-wrap:wrap;gap:10px;align-items:flex-end}
/* The COLUMN is pinned, the select is not stretched to fill it: it sizes to its own
   longest option and leaves the rest of the 292px empty. That empty space is doing the
   work, since it is what the From/To row occupies when it appears, so nothing outside this
   block ever moves. Dates (about 183px) plus a 141px date field exceeds 292, so the pair
   wraps to its own row on its own, with no second breakpoint to keep in step. */
.gh-page .gh-f-when > .gh-f{flex:0 0 auto;max-width:100%}
/* A native date input has a real intrinsic width: at 113px Chrome clipped the year to
   "04/09/202". 292px of column gives the pair 141px each, which fits. They stack on their
   own below 900px, where the column is full width anyway. */
.gh-page .gh-dates-custom.gh-show > .gh-f{flex:1 1 calc(50% - 5px);min-width:130px}
.gh-page .gh-dates-custom.gh-show > .gh-f input{width:100%;min-width:0}
/* The page states its own box model rather than inheriting it from a `*` rule in
   somebody else's stylesheet. The BO's style.css and the theme's mystyle2.css both
   happen to set border-box, and a width:100% input with 11px of padding overflows
   its column by 24px the day either of them stops. */
.gh-page input,.gh-page select,.gh-page button,.gh-page .gh-f{box-sizing:border-box}
/* Safari sizes input[type=date] from its OWN intrinsic content, the dd/mm/yyyy
   fields plus the calendar indicator, and will not shrink below that while the
   native appearance is on. At 16px that floor grew past the width of the search
   card, so picking "Dates personnalisees" on an iPhone or iPad pushed the card
   wider than the viewport and the whole page scrolled sideways. Chromium shrinks
   these happily, which is why the harness never showed it. Resetting the appearance
   is what makes `width` authoritative; min-width:0 lets the flex item give up the
   space it is holding. */
.gh-page input[type=date]{-webkit-appearance:none;appearance:none;min-width:0;max-width:100%}

/* WHERE disclosure: only on phones, where the strip is 3 rows of chips */
.gh-page .gh-where{display:none;width:100%;font:inherit;font-size:13.5px;font-weight:700;
  color:var(--gh-navy);background:#f7f9fc;border:1px solid var(--gh-bd);border-radius:9px;
  padding:10px 12px;cursor:pointer;text-align:left;align-items:center;justify-content:space-between}
.gh-page .gh-where-chev{color:var(--gh-mut);font-size:18px;line-height:1;transition:transform .15s}
.gh-page .gh-where[aria-expanded="true"] .gh-where-chev{transform:rotate(90deg)}

/* ONE sticky bar. Line 1 shows the count, and swaps to the recap once the card is gone. */
/* z-index 5, deliberately small. It only has to beat the search card it scrolls
   over (.gh-sb is 3) and the pinned map column beside it. Anything larger draws
   OVER the host's own top furniture: 600 put it over the BO's .mobile-header (200),
   and on the live sites it would sit over the pinned .site-header, whose desktop
   mega-menu is position:fixed inside a stacking context ft_scroll.js pins at 11.
   The bar never needs to be above either, because --gh-stick already reserves
   their height so they cannot overlap in the first place. */
.gh-page .gh-tools{position:sticky;top:var(--gh-stick,8px);z-index:5;background:#fff;border:1px solid var(--gh-line);
  border-radius:12px;box-shadow:0 4px 14px rgba(19,39,77,.08);padding:8px 13px;margin:0 0 12px}
.gh-page .gh-tools-line{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.gh-page .gh-tools-top{min-height:22px}
.gh-page .gh-tools .gh-stats{margin:0;padding:0}
.gh-page .gh-tools .gh-sum-txt,.gh-page .gh-tools .gh-sum-edit{display:none}
.gh-page .gh-tools.gh-scrolled .gh-stats{display:none}
.gh-page .gh-tools.gh-scrolled .gh-sum-txt{display:block}
.gh-page .gh-tools.gh-scrolled .gh-sum-edit{display:inline-block;margin-left:auto}
.gh-page .gh-tools-pills{margin-top:7px}

/* toolbar pills: each prints its own current value, so nothing hidden is unknowable */
.gh-page .gh-pill{display:inline-flex;align-items:center;gap:7px;font:inherit;font-size:12.5px;
  font-weight:700;color:var(--gh-navy);background:#f7f9fc;border:1px solid var(--gh-bd);
  border-radius:20px;padding:8px 14px;cursor:pointer;white-space:nowrap}
.gh-page .gh-pill:hover{border-color:var(--gh-green);color:var(--gh-green-ink);background:var(--gh-pill-bg)}
.gh-page .gh-pill.gh-on{background:var(--gh-pill-bg);border-color:var(--gh-pill-ink);color:var(--gh-pill-ink)}
.gh-page .gh-pill-count{min-width:18px;padding:1px 6px;border-radius:20px;background:#099f7d;color:#fff;
  font-size:10.5px;font-weight:700;line-height:1.5;text-align:center}
.gh-page .gh-pill-sel{padding:4px 6px 4px 14px;gap:5px;cursor:default}
.gh-page .gh-pill-sel > span{color:var(--gh-mut);font-weight:700}
.gh-page .gh-pill-sel select{font:inherit;font-size:12.5px;font-weight:700;color:var(--gh-navy);
  border:0;background:none;padding:4px 6px;cursor:pointer}
.gh-page .gh-pill:focus-visible,.gh-page .gh-where:focus-visible,.gh-page .gh-map-peek:focus-visible{outline:2px solid var(--gh-green);outline-offset:2px}
/* The theme kills focus rings wholesale: `a:focus{outline:none}` and
   `input:focus{outline:0}` in style.css, both (0,1,1). Every other control here was
   opted back in one by one and these two were missed, which left the page's PRIMARY
   click-out (one match row per match, 80 of them) and both sliders taking keyboard
   focus with nothing at all on screen. Element+class+pseudo beats (0,1,1) outright.
   Both are no-ops in the BO, which has no such reset. */
.gh-page a.gh-m:focus-visible{outline:2px solid var(--gh-green);outline-offset:-2px}
.gh-page input[type=range]:focus-visible{outline:2px solid var(--gh-green);outline-offset:2px}

/* removable chips for anything set inside the sheet */
.gh-page .gh-active-filters{display:flex;flex-wrap:wrap;gap:7px;margin:0 0 12px}
/* `display` beats the `hidden` attribute, whose own display:none comes from the UA
   sheet, so the empty chip row kept generating a box and paying its 12px bottom
   margin in the DEFAULT state (no filters set) and after "Tout effacer": a dead gap
   under the toolbar for most of the page's life. Same guard the sheet has below. */
.gh-page .gh-active-filters[hidden]{display:none}
.gh-page .gh-afchip{display:inline-flex;align-items:center;gap:7px;font:inherit;font-size:12px;font-weight:700;
  color:var(--gh-pill-ink);background:var(--gh-pill-bg);border:1px solid var(--gh-pill-bd);
  border-radius:20px;padding:5px 8px 5px 12px;cursor:pointer}
.gh-page .gh-afchip b{font-weight:800;font-size:14px;line-height:1}

/* ---------- the sheet: ported from .sr-* in ft_supersearch_results.css ---------- */
/* Desktop: an anchored panel, no scrim, no scroll lock (7018 keeps its lock inside the
   media query so the trigger is inert above the breakpoint). */
/* Desktop: NOT a floating overlay. The filters open as a panel in the page, inside the
   toolbar block, pushing the results down, which is what 7018 does on desktop too (its
   sheet is a plain wrapper there and the filters sit in the rail). */
.gh-page .gh-sheet{display:flex;flex-direction:column;background:#fff;
  border:1px solid var(--gh-line);border-radius:12px;box-shadow:0 4px 14px rgba(19,39,77,.08);
  margin:0 0 12px;padding:2px 15px 0}
.gh-page .gh-sheet[hidden]{display:none}
.gh-page .gh-sheet-scrim{display:none}
.gh-page .gh-sheet-grab{display:none}
.gh-page .gh-sheet-head{display:none}
.gh-page .gh-sheet-title{font-size:15px;font-weight:800;color:var(--gh-navy)}
.gh-page .gh-sheet-x{display:inline-flex;align-items:center;justify-content:center;width:30px;height:30px;
  padding:0;border:0;border-radius:8px;background:var(--gh-tint);color:var(--gh-navy);font-size:19px;cursor:pointer}
.gh-page .gh-sheet-x:hover{background:#e7ebf1}
.gh-page .gh-sheet-body{flex:1 1 auto;padding:2px 0 10px}
.gh-page .gh-sheet-body{display:flex;gap:26px;flex-wrap:wrap;align-items:flex-start}
.gh-page .gh-fset{flex:1 1 260px;min-width:0}
.gh-page .gh-sheet-foot{flex:none;display:flex;gap:9px;padding:10px 0 12px;border-top:1px solid var(--gh-line);width:100%}
.gh-page .gh-sheet-clear{flex:0 0 auto;font:inherit;font-size:13px;font-weight:700;color:var(--gh-mut);
  background:#fff;border:1px solid var(--gh-line);border-radius:9px;padding:11px 15px;cursor:pointer}
.gh-page .gh-sheet-go{flex:0 0 auto;min-width:190px;font:inherit;font-size:13px;font-weight:800;color:#fff;
  background:var(--gh-green);border:0;border-radius:9px;padding:12px;cursor:pointer}
.gh-page .gh-sheet-go:hover{background:var(--gh-green-ink)}

.gh-page .gh-fset{border:0;margin:14px 0 0;padding:0}
.gh-page .gh-fset legend{font-size:12.5px;font-weight:800;color:var(--gh-navy);padding:0;margin-bottom:8px}
.gh-page .gh-fset legend em{display:block;font-style:normal;font-size:11px;font-weight:400;color:var(--gh-mut);margin-top:2px}
.gh-page .gh-fset-lbl{font:700 10px/1 var(--gh-mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--gh-mut);margin:12px 0 7px}

/* the radius, stated as the engine states it: 25 km IS SAMEDAY_KM and the drive times
   are travelMin() = km x 1.3 / 80 x 60 */
.gh-page .gh-radseg{display:flex;flex-direction:column;border:1px solid var(--gh-bd);border-radius:10px;overflow:hidden}
/* A GRID, not a wrapping flex row. With four options the labels no longer fit on one
   line even in a 291px desktop column, and a wrapped flex row loses the separator
   between the two lines (the row treatment below zeroes border-bottom), so it read as
   four loose buttons rather than one control. 2x2 is deterministic at every width: each
   cell draws its right and bottom border and .gh-radseg's overflow:hidden clips the ones
   on the outer edges. */
.gh-page .gh-radseg-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
/* border-radius:0 is not redundant: the theme's `button{border-radius:2px}` (0,0,1)
   applies to any property this rule does not declare, and 2px on options that are
   meant to butt together turns a segmented control into three loose tiles with the
   1px divider curving away at each end. The segment's own 10px radius is clipped by
   .gh-radseg's overflow:hidden, so the outer corners are unaffected. */
.gh-page .gh-radopt{flex:1 1 auto;display:flex;flex-direction:column;align-items:flex-start;gap:1px;border-radius:0;
  font:inherit;font-size:12.5px;font-weight:700;color:var(--gh-navy);background:#fff;border:0;
  border-bottom:1px solid var(--gh-line);padding:9px 12px;cursor:pointer;text-align:left;line-height:1.3}
.gh-page .gh-radseg-row .gh-radopt{align-items:center;text-align:center;justify-content:center;
  border-bottom:1px solid var(--gh-line);border-right:1px solid var(--gh-line)}
.gh-page .gh-radopt:last-child{border-bottom:0;border-right:0}
.gh-page .gh-radopt small{font-size:10.5px;font-weight:600;color:var(--gh-mut)}
.gh-page .gh-radopt:hover{background:var(--gh-pill-bg)}
.gh-page .gh-radopt-on{background:var(--gh-navy);color:#fff}
.gh-page .gh-radopt-on small{color:#c7d3ec}
/* Spacing for a switch that follows a control rather than opening a column. */
.gh-page .gh-switch-sp{margin-top:16px}
.gh-page .gh-fine{margin-top:8px;font-size:11.5px;color:var(--gh-mut)}
.gh-page .gh-fine summary{cursor:pointer;font-weight:700}
.gh-page .gh-f-sheet{flex-direction:row;align-items:center;justify-content:space-between;gap:10px;margin-top:10px}
.gh-page .gh-f-sheet select,.gh-page .gh-f-sheet input{max-width:190px}

.gh-page .gh-howto{margin:18px 2px 0;font-size:12.5px;line-height:1.6;color:var(--gh-mut);max-width:70ch}
.gh-page .gh-map-peek{display:none}

@media (max-width:900px){
  /* flex, not a one-column grid. A sticky GRID ITEM is confined to its own grid
     area, so the map could only ever stick within its own 240px row, which is no
     stickiness at all. A sticky FLEX item's containing block is the flex container,
     so the map can stay pinned for the whole height of the list beside it.
     align-items has to be restated: the base rule sets `start`, and turning the axis
     vertical makes that horizontal, which would shrink both children to their
     content width. Same axis swap as .gh-sb-row above. */
  .gh-page .gh-wrap{display:flex;flex-direction:column;align-items:stretch}
  /* Turning the row into a column swaps the axes: align-items:flex-start from the base
     rule stops being vertical alignment and becomes CROSS-axis, i.e. horizontal, so both
     blocks shrank to their content width and "Partout" no longer filled the line. And
     flex:0 0 292px stops being a width and becomes a fixed HEIGHT. Both have to be undone
     explicitly here, not inherited. */
  .gh-page .gh-sb-row{flex-direction:column;gap:12px;align-items:stretch}
  .gh-page .gh-f-when{flex:0 0 auto;width:100%}
  .gh-page .gh-f-when > .gh-f{flex:1 1 100%}   /* full width on a phone: no room to spare */
  .gh-page .gh-f-dest{width:100%}
  .gh-page .gh-where{width:100%}
  /* full width each, so a native date input never has to clip its own year */
  /* min-width back to 0: the 130px floor from the desktop rule is inherited here and
     is one more thing standing between a narrow phone and a field that fits. */
  .gh-page .gh-dates-custom.gh-show > .gh-f{flex:1 1 100%;min-width:0}
  .gh-page .gh-where{display:flex}
  .gh-page .gh-country-chips{display:none;margin-top:8px}
  .gh-page .gh-country-chips.gh-where-open{display:flex}
  .gh-page .gh-tools-pills{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .gh-page .gh-tools-pills::-webkit-scrollbar{display:none}

  /* No global map toggle on a phone. Pinned at the top it took 386px of an iPhone 15's
     660px viewport, 58% of the screen, against a trip card 626px tall: a whole card
     could never be on screen with it. Each card carries its own button instead, and the
     single map moves to whichever card asks. "Voir tous les stades" travels with it, so
     the overview is still one tap away once any card's map is open. */
  .gh-page .gh-map-peek{display:none}
  .gh-page .gh-mapwrap{margin:0}
  .gh-page .gh-trip .gh-mapwrap{margin:10px 0 2px}
  /* visibility, not only height. Leaflet's container is focusable and its zoom
     controls are anchors, so a zero-height map still put a region and two links in
     the tab order after the last trip card, with no way to see where focus went. */
  .gh-page .gh-mapwrap #gh-map{height:0;min-height:0;border-width:0;visibility:hidden}
  .gh-page .gh-mapwrap .gh-map-toolbar,.gh-page .gh-mapwrap .gh-map-foot{display:none}
  .gh-page .gh-mapwrap.gh-map-open #gh-map{height:240px;border-width:1px;visibility:visible}
  /* Deliberately NOT sticky. Pinning was the previous answer to "the map scrolls away",
     and it cost more screen than it was worth. Inside a card the map is already where
     you are reading, and it scrolls away with the card it belongs to, which is correct. */
  .gh-page .gh-mapwrap.gh-map-open .gh-map-toolbar,.gh-page .gh-mapwrap.gh-map-open .gh-map-foot{display:flex}

  /* ---- bottom sheet, ported verbatim in behaviour from 7018 ---- */
  .gh-page .gh-sheet-scrim{display:block;position:fixed;top:0;right:0;bottom:0;left:0;z-index:9990;
    background:rgba(11,25,48,.5);opacity:0;visibility:hidden;transition:opacity .2s,visibility .2s}
  body.gh-sheet-open .gh-page .gh-sheet-scrim{opacity:1;visibility:visible}
  .gh-page .gh-sheet{left:0;right:0;bottom:0;width:auto;max-height:86vh;max-height:86dvh;
    border-radius:16px 16px 0 0;border:0;box-shadow:0 -8px 26px rgba(9,20,40,.24);
    transform:translateY(101%);visibility:hidden;transition:transform .26s cubic-bezier(.2,.7,.3,1),visibility .26s}
  body.gh-sheet-open .gh-page .gh-sheet{transform:none;visibility:visible}
  .gh-page .gh-sheet-grab{display:block;flex:none;width:38px;height:4px;margin:9px auto 0;border-radius:4px;background:#d3dae4}
  /* position:fixed, NOT overflow:hidden. 7018 documents why at length: this theme's body
     is one viewport tall with the content overflowing visibly, so overflow:hidden turns it
     into a clip window and iOS Safari slices the fixed sheet against it. */
  body.gh-sheet-open{position:fixed;left:0;right:0;width:100%}
}

/* market select, out of the search form entirely */
.gh-page .gh-topbar{display:flex;justify-content:flex-end;padding:8px clamp(12px,3vw,26px) 0}
.gh-page .gh-bo{display:inline-flex;align-items:center;gap:7px;font-size:11px;font-weight:700;color:var(--gh-mut)}
.gh-page .gh-bo select{font:inherit;font-size:12px;font-weight:700;color:var(--gh-navy);background-color:#fff;
  border:1px dashed var(--gh-bd);border-radius:8px;padding:5px 9px;cursor:pointer}

/* city + sort sit with the list they act on, not inside the filters */
.gh-page .gh-listbar{display:flex;flex-wrap:wrap;gap:10px 16px;align-items:center;margin:0 2px 10px}
.gh-page .gh-f-inline{flex-direction:row;align-items:center;gap:6px;font-size:11.5px}
.gh-page .gh-f-inline > span{font:700 10px/1 var(--gh-mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--gh-mut);white-space:nowrap}
/* The sort control keeps its small mono CAPTION but the control itself is 16px like
   every other dropdown: the label is chrome, the value is the thing being read. */
.gh-page .gh-f-inline select{font-size:16px;padding:6px 9px}
.gh-page .gh-f-inline .gh-city-filter{min-width:auto;max-width:200px}
.gh-page .gh-listcol{min-width:0}

/* ---- price histogram, ported from .sr-histo in ft_supersearch_results.css ---- */
.gh-page .gh-histo{display:flex;align-items:flex-end;gap:1px;height:64px;margin-top:6px;border-bottom:1px solid var(--gh-line)}
.gh-page .gh-histo-bar{flex:1;min-width:0;background:#dde3ec;border-radius:2px 2px 0 0;transition:background .15s;position:relative}
.gh-page .gh-histo-bar.gh-histo-on{background:var(--gh-green)}
.gh-page .gh-histo-bar:hover::after{content:attr(data-tip);position:absolute;bottom:calc(100% + 6px);left:50%;
  transform:translateX(-50%);background:#333;color:#fff;font-size:11px;padding:3px 7px;border-radius:4px;
  white-space:nowrap;z-index:10;pointer-events:none}
.gh-page .gh-histo-bar:nth-child(-n+4):hover::after{left:0;transform:none}
.gh-page .gh-histo-bar:nth-last-child(-n+4):hover::after{left:auto;right:0;transform:none}
.gh-page .gh-range-wrap{position:relative;height:26px;display:flex;align-items:center}
.gh-page .gh-range-wrap input[type=range]{width:100%;padding:0;border:0;background:none;accent-color:var(--gh-green)}
.gh-page .gh-range-val{margin:2px 0 0;font-size:11.5px;font-weight:700;color:var(--gh-navy)}

@media (max-width:900px){
  /* mobile keeps the bottom sheet exactly as 7018 has it */
  .gh-page .gh-sheet{position:fixed;left:0;right:0;bottom:0;width:auto;margin:0;padding:0;
    max-height:86vh;max-height:86dvh;border:0;border-radius:16px 16px 0 0;
    box-shadow:0 -8px 26px rgba(9,20,40,.24);z-index:9991;
    transform:translateY(101%);visibility:hidden;transition:transform .26s cubic-bezier(.2,.7,.3,1),visibility .26s}
  body.gh-sheet-open .gh-page .gh-sheet{transform:none;visibility:visible}
  .gh-page .gh-sheet-head{display:flex;flex:none;align-items:center;justify-content:space-between;padding:10px 14px}
  .gh-page .gh-sheet-body{display:block;overflow-y:auto;padding:4px 15px 12px}
  .gh-page .gh-sheet-foot{padding:11px 15px}
  .gh-page .gh-sheet-go{flex:1 1 auto;min-width:0}
  .gh-page .gh-topbar{padding:6px 12px 0}
  .gh-page .gh-listbar{gap:8px 12px}
}

/* Both sticky elements on this page measure from the VIEWPORT, so anything the host
   paints fixed at the top of the screen has to be reserved or they pin UP INSIDE it:
   in the BO the recap sat 46px inside the 54px .mobile-header and, at z-index 600,
   drew over it, which is what "the sticky recap does not work on mobile" looked like.
   --gh-nav-h is measured by navOffset() in groundhopping.js and covers both hosts
   (.mobile-header in the BO, .site-header on the live sites); 8px is the gap. One
   variable, read by both sticky elements, so they can never drift apart again. */
.gh-page{--gh-stick:calc(var(--gh-nav-h,0px) + 8px)}

/* Two label + select pairs do not fit one 375px row in French: both selects were clipped
   to about 60px. Stack them, each label above its control, like every other field. */
@media (max-width:560px){
  /* label left, control taking whatever is left: one row each instead of two, and no
     clipping, which is why they were stacked in the first place */
  .gh-page .gh-listbar{gap:7px}
  .gh-page .gh-listbar .gh-f-inline{flex:1 1 100%;flex-direction:row;align-items:center;gap:8px}
  .gh-page .gh-listbar .gh-f-inline > span{flex:none}
  .gh-page .gh-listbar .gh-f-inline select,
  .gh-page .gh-listbar .gh-f-inline .gh-city-filter{flex:1 1 auto;min-width:0;max-width:none;width:auto}
}

/* Desktop: the three groups are independent questions, so they read as three columns
   rather than one tall stack that pushes the results a screen down. */
/* stretch, not start: the three switches are pushed to the bottom of their own column by
   margin-top:auto below, and that only lines them up with each other if the columns are
   the same height. Each column is a flex column for the same reason. */
.gh-page .gh-sheet-body{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px 30px;align-items:stretch}
.gh-page .gh-col{min-width:0;display:flex;flex-direction:column}
/* Beats both .gh-switch's own 14px and .gh-switch-sp's 16px (0,3,0 against 0,2,0), so the
   three separators and their labels sit on one line across the panel. */
.gh-page .gh-col > .gh-switch{margin-top:auto}
.gh-page .gh-col .gh-fset-lbl{margin-top:4px}
/* 4px is right for the label that OPENS a column, and wrong for one that follows a
   control: the city label sat hard against the trip-length buttons above it with no
   gap to say a new setting had started. Targeted at the two things a label can follow
   here rather than at :not(:first-child), so inserting anything at the top of a column
   cannot silently retune the spacing of the one below it. */
.gh-page .gh-col .gh-radseg + .gh-fset-lbl,
.gh-page .gh-col .gh-sr + .gh-fset-lbl,
.gh-page .gh-col .gh-fine + .gh-fset-lbl{margin-top:20px}
.gh-page .gh-col-bud .gh-f-check{margin-top:10px}
@media (max-width:900px){
  /* one column in the bottom sheet, where vertical space is the thing you have */
  .gh-page .gh-sheet-body{display:block}
}
/* The descendant override never took effect on the scrim even though every part of the
   selector matched, so the JS now toggles a class on the element itself. One class, one
   owner, nothing to lose a specificity argument with. */
.gh-page .gh-sheet-scrim.gh-scrim-on{opacity:1;visibility:visible}

/* Toggle switch, ported from .sr-switch in ft_supersearch_results.css. Same trick: the
   checkbox stays a real focusable input, hidden with position + opacity rather than
   display:none, and the sibling track paints it. State change is pure CSS via
   input:checked + .gh-switch-track, so nothing in the engine has to know. */
.gh-page .gh-switch{display:flex;align-items:center;gap:9px;margin-top:14px;padding-top:12px;
  border-top:1px solid var(--gh-line);font-size:13px;font-weight:700;color:var(--gh-navy);cursor:pointer}
.gh-page .gh-switch input{position:absolute;width:1px;height:1px;margin:0;padding:0;border:0;opacity:0;pointer-events:none}
.gh-page .gh-switch-track{position:relative;flex:none;width:34px;height:20px;border-radius:20px;
  background:#d9e0ea;transition:background .15s}
.gh-page .gh-switch-track::after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;
  border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(0,0,0,.25);transition:transform .15s}
.gh-page .gh-switch input:checked + .gh-switch-track{background:var(--gh-green)}
.gh-page .gh-switch input:checked + .gh-switch-track::after{transform:translateX(14px)}
/* the input is invisible, so its focus ring has to move to the track or keyboard users get
   nothing. Navy, not the action green, because the track itself is green when it is on. */
.gh-page .gh-switch input:focus-visible + .gh-switch-track{outline:2px solid var(--gh-navy);outline-offset:2px}
.gh-page .gh-switch input:disabled + .gh-switch-track{opacity:.45}
@media (prefers-reduced-motion:reduce){
  .gh-page .gh-switch-track,.gh-page .gh-switch-track::after{transition:none}
}

/* ---------- fixes: hover legibility, one block, a trigger that looks like one ---------- */

/* SPECIFICITY BUG. ".gh-page .gh-radopt:hover" is (0,3,0) because a pseudo-class counts
   as a class, while ".gh-page .gh-radopt-on" is only (0,2,0). So hovering a SELECTED
   option won the background and painted it light green while the white text from the
   selected state stayed: white on light green. The selected state has to state its own
   hover rather than rely on source order. */
.gh-page .gh-radopt-on:hover,
.gh-page .gh-radopt-on:focus-visible{background:var(--gh-navy);color:#fff}
.gh-page .gh-radopt-on:hover small{color:#c7d3ec}
.gh-page .gh-pill.gh-on:hover{background:var(--gh-pill-bg);color:var(--gh-pill-ink);border-color:var(--gh-pill-ink)}
.gh-page .gh-cchip.gh-on:hover{background:#d3ecdf;color:var(--gh-pill-ink);border-color:var(--gh-pill-ink)}

/* The panel is the filters, so it must read as the SAME block as the bar that opens it,
   not as a second card floating under it. Joined: the bar loses its bottom rounding and
   border while open, and the panel picks up where it stops. */
.gh-page .gh-tools.gh-open-filters{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-color:transparent;margin-bottom:0;box-shadow:0 4px 14px rgba(19,39,77,.08)}
.gh-page .gh-sheet{margin-top:0;border-top-left-radius:0;border-top-right-radius:0;border-top:1px solid var(--gh-line)}

/* A value on its own is not a control. Label, value, chevron. */
.gh-page .gh-pill-filters{gap:6px;padding-left:12px}
.gh-page .gh-pill-ico{display:inline-flex;color:var(--gh-mut)}
.gh-page .gh-pill-lbl{font-weight:800}
.gh-page .gh-pill-val{font-weight:600;color:var(--gh-mut);padding-left:6px;border-left:1px solid var(--gh-line)}
.gh-page .gh-pill.gh-on .gh-pill-val,.gh-page .gh-pill.gh-on .gh-pill-ico{color:inherit}
.gh-page .gh-pill-chev{color:var(--gh-mut);font-size:16px;line-height:1;transition:transform .15s}
.gh-page .gh-pill[aria-expanded="true"] .gh-pill-chev{transform:rotate(90deg)}
.gh-page .gh-tools .gh-clear{margin-left:12px}
@media (prefers-reduced-motion:reduce){.gh-page .gh-pill-chev{transition:none}}
@media (max-width:900px){
  /* on a phone the panel is a bottom sheet, so there is nothing to join it to */
  .gh-page .gh-tools.gh-open-filters{border-bottom-left-radius:12px;border-bottom-right-radius:12px;border-bottom-color:var(--gh-line);margin-bottom:12px}
  /* and the other half of that join. The rule that squares the sheet's top edge and
     draws a hairline where it meets the bar sits LATER in the file at the same
     specificity, so it also reached the bottom sheet, which is not joined to
     anything: it slid up over the scrim with square corners and a stray 1px line. */
  .gh-page .gh-sheet{border-top:0;border-top-left-radius:16px;border-top-right-radius:16px}
  .gh-page .gh-pill-val{display:none}
}

/* On a phone the recap line carried "Modifier la recherche" and "Reinitialiser la
   recherche" on their own row ABOVE the filters button: two long labels and a wasted row
   for context the reader already has. The qualifier drops out under 900px and the two
   lines collapse into one wrapping row, so the buttons sit beside the filters pill. */
.gh-page .gh-lw{display:inline}
@media (max-width:900px){
  .gh-page .gh-lw{display:none}
  .gh-page .gh-tools{display:flex;flex-wrap:wrap;align-items:center;gap:8px 10px}
  .gh-page .gh-tools-top,.gh-page .gh-tools-pills{display:contents}
  .gh-page .gh-tools .gh-stats,.gh-page .gh-tools .gh-sum-txt{flex:1 1 100%;margin:0}
  .gh-page .gh-tools.gh-scrolled .gh-sum-edit{margin-left:0}
  .gh-page .gh-tools .gh-clear{margin-left:0}
}

/* City lives with the other things that shape a result set, under the trip length.
   Full width of its column, since city names run long. */
.gh-page .gh-f-stack{display:block}
.gh-page .gh-f-stack .gh-city-filter{width:100%;max-width:none;min-width:0}
.gh-page .gh-listbar{margin-bottom:10px}

/* the top bucket is an "and above" bucket when the tail overflows the p95 scale */
.gh-page .gh-histo-bar.gh-histo-over{background-image:repeating-linear-gradient(45deg,transparent,transparent 3px,rgba(255,255,255,.45) 3px,rgba(255,255,255,.45) 6px)}

/* Leaflet blocked (ad blocker, consent manager, CDN down): groundhopping.js sets
   this instead of throwing, and the trip list takes the whole width rather than
   leaving a grey rectangle where a map was meant to be. */
.gh-page.gh-nomap .gh-wrap{grid-template-columns:1fr}
.gh-page.gh-nomap .gh-mapwrap{display:none}

/* ==================================================================
   LIVE THEME ONLY.
   body.gh-body is added by ft_gh_body_class() in functions/ft_groundhopping.php,
   so nothing below can reach the BO preview and this file stays one file.
   Everything here is a cascade fix: the theme's own rules land on markup that
   was written against the BO's much smaller stylesheet.
   ================================================================== */

/* The theme puts every page in a 1080px column (.content-area in css/mystyle2.css),
   and that column is a hard clip for the grey background and for the full-bleed
   hero, so the page escapes it and sets its own measure.

   1132px, because the thing to match is the ADVANCED SEARCH CARD, not the H1.
   `#main_filters` on page 7018 is `max-width:1080px;width:100%` in a full-width
   content area, so its border sits 25px OUTSIDE the hero H1 above it, not level
   with it. .gh-page carries clamp(12px,3vw,26px) gutters, so 1080 + 2x26 = 1132
   puts .gh-sb at exactly 1080 wide with its border in exactly the same place, and
   every block below it (toolbar, filters panel, trip cards, map) lines up with the
   card rather than with the H1. An earlier pass set 1080 here to align the card's
   BORDER with the H1: that was a guess at the house rule, and the house rule is the
   card on 7018. */
body.gh-body .content-area{max-width:100%}
body.gh-body .entry-content{max-width:100%;padding:0}
/* Under 999px style.css adds `#content .entry-content{padding:0 20px}`, and an id
   beats any number of classes, so the class rule above is not enough. The page
   carries its own gutters (.gh-zone and .gh-sb both use clamp(12px,3vw,26px)), and
   20px on top of 12px takes 64px out of a 375px phone. max-width is repeated here
   too: `.sidebar .entry-content{max-width:1080px;padding:0 25px}` in mystyle2.css
   ties the class rule above at (0,2,0), so that one only wins on enqueue order.
   Matched specificity, not !important. */
body.gh-body #content .entry-content{max-width:100%;padding:0}
/* transparent, because .hentry below already paints the same grey edge to edge.
   The search card is pulled 34px UP into the hero (.gh-sb margin-top:-34px), which
   puts the top of .gh-page over the bottom of the navy band. With .gh-page painting
   its own background that 34px of navy was covered in grey on both shoulders of the
   card and the overlap read as a seam instead of a card sitting on the hero. In the
   BO there is no theme hero to overlap, so .gh-page keeps its own background there. */
/* padding-bottom, not margin: .gh-page is transparent and the grey comes from .hentry
   behind it, so padding grows the grey band and margin would not. It is the gap between
   the last thing in the tool and the edge of the grey, which the white prose band starts
   against; without it the two surfaces met with nothing between them. */
body.gh-body .gh-page{max-width:1132px;margin:0 auto;border-radius:0;background:transparent;padding-bottom:34px}
/* The search card's -34px is a deliberate overlap onto .gh-hero, which only the BO
   paints: the live theme supplies its own hero, so on these three sites the negative
   margin was not overlapping anything, it was just eating the space below the hero. That
   went unnoticed until the hero gained the trust chips, which the card then sat flush
   against with a measured 0px between them. Zero here, not a positive value: removing
   the pull already yields 34px, the same gap this file puts at the other end of the grey
   band, so the tool sits evenly between the two. Only the top is reset; the horizontal
   margins stay with the shorthand above. */
body.gh-body .gh-sb{margin-top:-20px}
/* A narrower map column than the BO's. 1132 minus two 26px gutters is 1080, and at
   the shared 420px the trip list would drop to 644px, under the ~700 the cards were
   designed and measured at. 340px still gives a 340x560 map, wider than the one a
   phone gets, and leaves the list at 724.
   Declared on BODY as a value, never as a grid-template-columns override: .gh-wrap
   is collapsed to one column by a media query earlier in this file at the same
   specificity, so an override of the template itself would win there too and take
   the phone layout with it. Inheritance carries the value into .gh-wrap; the media
   query keeps full control of the template. */
body.gh-body{--gh-mapcol:340px}
/* The page background runs edge to edge behind the centred column, as on 7018.
   Literal, not var(--gh-page-bg): that token is declared on .gh-page and .hentry
   is its ancestor, so it cannot read it. Keep the two values in step. */
/* The theme's own bottom padding here is 90px on ft.fr and 30px on ft.club / ft.es,
   so it is zeroed to stop three sites ending three different ways. The space before
   the footer is now .gh-prose-in's padding-bottom, inside the white band, so the
   grey surface cannot reappear under it. */
body.gh-body .hentry{background:#eef1f5;padding-bottom:0}
body.gh-body footer.entry-meta{margin-top:0}

/* css/mystyle2.css has .entry-content a{color:#185c8a} at (0,2,0) and style.css
   underlines EVERY anchor on hover. The two anchor kinds this page renders are a
   ticket row and a hotel button, neither of which is body copy. Element+class wins
   outright instead of depending on which stylesheet was enqueued last. */
body.gh-body a.gh-hotel-btn,body.gh-body a.gh-hotel-btn:visited{color:var(--gh-navy);text-decoration:none}
body.gh-body a.gh-hotel-btn:hover,body.gh-body a.gh-hotel-btn:focus{color:var(--gh-green-ink);text-decoration:none}
body.gh-body a.gh-m,body.gh-body a.gh-m:visited,body.gh-body a.gh-m:hover,body.gh-body a.gh-m:focus{color:inherit;text-decoration:none}

/* .entry-content img{max-width:100%;height:auto} is (0,1,1) and beats .gh-flag's
   own (0,1,0) height, which turns a 18px circular flag into a full-height sliver.
   Same numbers as the base rules, restated where they can win. */
body.gh-body .gh-flag{width:18px;height:18px}
body.gh-body .gh-chip-flag{width:15px;height:15px}

/* The market select is BO-only and the WordPress template does not render it.
   This is belt and braces for a template pasted from the BO copy by mistake. */
body.gh-body .gh-topbar{display:none}

/* style.css sets `p{text-align:justify}` at (0,0,1), which nothing here declares, so
   the closing explainer rendered justified: stretched word spacing and a hard right
   edge on a 70ch measure, which no other paragraph on this page has. */
body.gh-body .gh-page p,body.gh-body .gh-prose p{text-align:left}

/* Leaflet's zoom controls are anchors, so `.entry-content a` and its :hover paint
   them in the theme's link blue: a map control that reads as a link. The rest of the
   Leaflet chrome is untouched, including the attribution, which IS a link. */
body.gh-body .gh-page .leaflet-bar a,body.gh-body .gh-page .leaflet-bar a:visited{color:#000;text-decoration:none}
body.gh-body .gh-page .leaflet-bar a:hover,body.gh-body .gh-page .leaflet-bar a:focus{color:#000;text-decoration:none}

/* ---------------------------------------------------------------------------
   PROSE BAND (live only: the BO page emits none of this).

   Everything below .gh-page. It is a SIBLING of the tool, not a child, so it can
   paint the full width of the viewport: the grey results surface ends where the
   generated text begins, which is the whole point of the split.

   Typography is deliberately NOT set here. h2, h3 and p take the theme's own content
   styles, which is also where the space between the blocks comes from. Sizes, weights,
   colours, line heights and margins on headings belong to the theme, and the version of
   this file that set them made the section read as more UI than as content. Only layout
   lives here.

   That means the headings are whatever the theme says at the current width, not one
   fixed size: 22px/700 and 19px/700 with 25px and 22px margins on a desktop, and on
   ft.fr a bare h2{font-size:1.15em} inside @media (max-width:460px) in style.css takes
   over on a small phone. That shrink is the theme's own behaviour on every page of the
   site, so it is inherited on purpose and NOT overridden here.
   --------------------------------------------------------------------------- */
/* The white band is lifted over the grey rather than butted against it: a soft shadow
   cast UPWARDS from its top edge, so the darkening lands on the grey and the white reads
   as the nearer surface. Negative y offset with a matching negative spread, so nothing
   bleeds down the sides or under the footer. */
body.gh-body .gh-prose{background:#fff;box-shadow:0 -7px 14px -7px rgba(19,39,77,.20);position:relative;z-index:1}
body.gh-body .gh-prose-in{max-width:1132px;margin:0 auto;padding:8px clamp(12px,3vw,26px) 48px}

/* Ready-made searches: inline chips, not cards, so they do not read as a second
   destinations block three lines above the real one. */
.gh-prose .gh-seo-trips{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:8px}
.gh-prose .gh-seo-trips li{margin:0}
body.gh-body .gh-prose .gh-seo-trips a{display:inline-block;padding:7px 13px;border:1px solid var(--gh-line);
  border-radius:999px;background:var(--gh-tint);color:var(--gh-navy);font-size:13.5px;
  font-weight:600;text-decoration:none;line-height:1.3}
body.gh-body .gh-prose .gh-seo-trips a:hover,
body.gh-body .gh-prose .gh-seo-trips a:focus{background:#fff;border-color:var(--gh-bd);
  color:var(--gh-green-ink);text-decoration:none}

/* Destination cards. The markup is the theme's own .destination-card, so the card
   itself is styled by mystyle2.css and stays identical to the destinations page by
   construction. Only the grid around it is ours: .destination-grid is a fixed
   3-column, 1200px-wide, 24px-padded block built for a full-width page. */
.gh-prose .gh-seo-countries{list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(auto-fill,minmax(232px,1fr));gap:12px}
.gh-prose .gh-seo-countries li{margin:0;display:flex}
.gh-prose .gh-seo-countries .destination-card{flex:1;display:block}
/* A country with no destination page is the same card without an anchor. Kill the
   hover affordances the class carries, or it advertises a click that does nothing. */
.gh-prose .gh-seo-countries span.destination-card{cursor:default}
.gh-prose .gh-seo-countries span.destination-card:hover{box-shadow:none;background:#fff}
body.gh-body .gh-prose .gh-seo-countries a,
body.gh-body .gh-prose .gh-seo-countries a:hover,
body.gh-body .gh-prose .gh-seo-countries a:focus{text-decoration:none;font-weight:400}

/* The FAQ reuses .game-faq from the theme's ft-components.css, already enqueued on
   this page on all three sites, so there is no accordion CSS here. Its own 55px
   bottom margin goes because .gh-prose-in already ends the band. */
.gh-prose .gh-faq .game-faq{margin-bottom:0}

