/* ============ Theme Variables ======================================================================
====================================================================================================*/

:root {
    --color-active: #c0392b; /* active / hover state — change here to update everywhere */
    /* On-map marker counter-scale. Default 1 (no-op on desktop). The mobile
       block in this file redefines it to `calc(1 / var(--map-scale, 1))` so
       labels / POI markers / gems / road badges shrink as the user zooms
       in, instead of inflating with the map's CSS transform. The value is
       multiplied into the marker keyframes' transform: scale(...) so the
       counter composes with the existing translate-centering. */
    --marker-counter: 1;
}


/* ============ Defaults =============================================================================
====================================================================================================*/

img {
  border-style: none;
  height: auto;
  max-width: 100%;
}
html, body {
  height: 100%;
  font-family: 'effra', 'Effra', sans-serif;
}

/* Brand: Larken (serif) for all headings, Effra (sans-serif) for body/UI. */
h1, h2, h3, h4, h5, h6 {
  font-family: 'larken', 'Larken', serif;
}


.siteWrap {
    position: relative;
    font-size: 16px;
    height: 100%;
    min-height: calc(100% - 200px);
}


/* ============ Main =============================================================================
====================================================================================================*/

.mainWrap {
    width: calc(100% - 0px);
    height: calc(100% - 30px);
    margin-top: 0px;
    margin-left: 0px;
    position: absolute;
    display: block;
    align: center;
    background-color: #fff;
    left: 0px;
    top: 0px;
    z-index: 10;
    -webkit-box-pack: center;
    overflow-x: hidden; /* clips the POI panel while it slides in from off-screen */
}

.mainWrap .outerMainWrap {
    width: 100%;
    height: 100%;
    background-color: #ffffff;
    overflow: hidden;
    position: relative;
    display: flex;
    -webkit-box-align: center;
    align-items: flex-start;
    justify-content: center;
}
.mainWrap .outerMainWrap .innerMainWrap {
    width: 100%;
    transform-origin: 0px 0px;
    position: relative;
    min-height: 100%;
    background-color: #1f3733;
    left: 0px;
    top: 0px;
    display: flex;
    transition: height 0.4s;
    align-items: start;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

/* Prevent images inside the pannable map from being dragged as a ghost
   image when the user click-drags to pan. */
.mainWrap .outerMainWrap .innerMainWrap img {
    -webkit-user-drag: none;
    user-drag: none;
}

.mainWrap .outerMainWrap .innerMainWrap figure {
    margin-bottom: 0px;
    pointer-events: none;
}

.mainWrap .outerMainWrap .innerMainWrap figure .imgMap{
    position: relative;
}

.mainWrap .outerMainWrap .innerMainWrap figure .imgRoads,
.mainWrap .outerMainWrap .innerMainWrap figure .imgOverlay{
    position: absolute;
    pointer-events: none;
    top: 0px;
    left: 0px;
    z-index: 100;
    opacity: 0;
    transition: 2.7s;
}

.mainWrap .outerMainWrap .innerMainWrap figure .imgRoads.active,
.mainWrap .outerMainWrap .innerMainWrap figure .imgOverlay.active {
    opacity: 1;
}

/* Mobile map cover. Placed AFTER the base .innerMainWrap rules above so it
   actually wins the cascade — putting it earlier resulted in the base
   width:100% / min-height:100% defaults beating the mobile overrides, which
   left the inner at viewport width and all overlays (POIs, labels, gems,
   roads, SVGs — they're sized as 100% × aspect-ratio of the inner) pegged
   to the old smaller dimensions instead of scaling with the larger
   cover-sized map.
 */
@media (max-width: 767px) {
    /* Map sits between the 76px top header and the bottom nav bar so the
       container fills exactly that slice of the viewport. The bottom nav is
       48px (matches the .mainWrap calc below). */
    .mainWrap {
        top: 76px;
        height: calc(100% - 76px - 56px);
    }
    .mainWrap .outerMainWrap {
        height: 100%;
        justify-content: flex-start;
    }
    /* Cover behaviour: inner keeps the map's 3201:2500 aspect ratio and
       fills the container height. Width follows the aspect ratio (wider
       than the viewport on portrait phones), so the sides are clipped by
       outer's overflow: hidden and the user pans horizontally to reveal
       them. min-width:0 is required to stop the flex algorithm forcing
       the inner to be at least its content's intrinsic width (the raw
       image is ~3200px wide, which would blow inner up). */
    .mainWrap .outerMainWrap .innerMainWrap {
        width: auto;
        height: 100%;
        min-width: 0;
        min-height: 0;
        aspect-ratio: 3201 / 2500;
        flex-shrink: 0;
    }
    .mainWrap .outerMainWrap .innerMainWrap figure {
        width: 100%;
        height: 100%;
    }
    .mainWrap .outerMainWrap .innerMainWrap figure .imgMap {
        width: 100%;
        height: 100%;
        max-width: none;
        object-fit: cover;
    }

    /* Counter-scale factor for on-map markers — see `--marker-counter`
       declaration at the top of the file. zoom-drag.js sets `--map-scale`
       on .innerMainWrap, so we redefine `--marker-counter` on the same
       element (custom properties don't inherit upward, so defining the
       override at :root would read --map-scale as unset). The marker
       descendants then inherit this overridden value. Outside this
       mobile block --marker-counter stays at its :root default of 1. */
    .innerMainWrap {
        --marker-counter: calc(1 / var(--map-scale, 1));
    }
}

/* ---- Cloud layer ---- */
#mapClouds {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    aspect-ratio: 3201 / 2500;
    pointer-events: none;
    z-index: 115; /* above map image/overlay, below SVG + all labels */
}
.map-cloud {
    position: absolute;
    pointer-events: none;
    /* individual position, size, opacity, and rotation set inline */
    animation: cloudDrift 20s linear infinite;
}

/* Each cloud drifts left ~20% of its own width then returns — out of sync via
   negative delays so they never all move together */
.map-cloud:nth-child(1) { animation-duration: 110s; animation-delay:  -10s; }
.map-cloud:nth-child(2) { animation-duration: 90s;  animation-delay:  -44s; }
.map-cloud:nth-child(3) { animation-duration: 130s; animation-delay:  -70s; }
.map-cloud:nth-child(4) { animation-duration: 100s; animation-delay:  -25s; }
.map-cloud:nth-child(5) { animation-duration: 120s; animation-delay:  -88s; }
.map-cloud:nth-child(6) { animation-duration: 85s;  animation-delay:  -33s; }
.map-cloud:nth-child(7) { animation-duration: 105s; animation-delay:  -58s; }
.map-cloud:nth-child(8) { animation-duration: 115s; animation-delay:  -14s; }

@keyframes cloudDrift {
    0%, 100% { translate: 0 0; }
    50%       { translate: -20% 0; }
}

#mainPageSvg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    aspect-ratio: 3201 / 2500;
    z-index: 130; /* above gems, labels and map layers */
    pointer-events: none;
}

.sectionOutline {
    fill: rgba(105, 112, 120, 0.65);
    stroke: rgba(255, 255, 255, 0.7);
    stroke-width: 1.5;
    vector-effect: non-scaling-stroke;
    transition: fill 0.35s ease, stroke 0.35s ease, stroke-width 0.3s ease, opacity 0.4s ease;
    pointer-events: all;
    /* All section outlines respond to hover + click (tooltip / modal /
       navigation), so signal that with a pointer cursor on every one. */
    cursor: pointer;
}

.sectionOutline:hover,
.sectionOutline.is-hovered {
    stroke: rgba(255, 255, 255, 1);
    stroke-width: 2;
    vector-effect: non-scaling-stroke;
}

/* Nav link hover → highlight matching polygon (thicker stroke + fill bump) */
.sectionOutline.nav-hover {
    stroke: rgba(255, 255, 255, 1);
    stroke-width: 3.5;
    vector-effect: non-scaling-stroke;
}
.sectionOutline[data-color="grey"].nav-hover         { fill: rgba(105, 112, 120, 0.82); }
.sectionOutline[data-color="blue"].nav-hover         { fill: rgba( 89, 129, 193, 0.82); }
.sectionOutline[data-color="red"].nav-hover          { fill: rgba(165,  42,  48, 0.82); }
.sectionOutline[data-color="orange"].nav-hover       { fill: rgba(243, 132,  83, 0.82); }
.sectionOutline[data-color="yellow"].nav-hover       { fill: rgba(204, 218,  51, 0.82); }
.sectionOutline[data-color="light-blue"].nav-hover   { fill: rgba(245, 198, 165, 0.78); }
.sectionOutline[data-color="green"].nav-hover        { fill: rgba( 59, 174,  73, 0.88); stroke: none; }

.sectionOutline.is-clickable { cursor: pointer; }

/* Legacy: kept so any existing code path that still adds .is-phase-dimmed
   keeps working. The new phase filter (driven by body[data-active-phase])
   below is the canonical mechanism. */
.sectionOutline.is-phase-dimmed  { opacity: 0.6 !important; }
.label.is-phase-dimmed           { opacity: 0 !important; transition: opacity 0.4s ease; }

/* Mobile: while a right-side filter (POI or Trails) is active, hide the
   on-map labels so the marker / trail layer reads cleanly. Gems are
   intentionally NOT touched here — the click handlers in custom.js skip
   `deactivateGems()` on mobile, so any gems the user has on stay on.
   `.poi-visible` is set by #btnPoi (and the POI marker click) on
   .innerMainWrap; `.trails-visible` is set by showTrails(). */
@media (max-width: 767px) {
    .innerMainWrap.poi-visible #mapLabels .label,
    .innerMainWrap.trails-visible #mapLabels .label,
    .innerMainWrap.poi-visible #mapRoadBadges .road-badge,
    .innerMainWrap.trails-visible #mapRoadBadges .road-badge,
    /* When a phase is active on mobile we hide the on-map labels and road
       badges too — the phase filter is meant to read as a clean colour-only
       view, and the partial phase-dim rule (which keeps matching labels
       visible) feels cluttered on a small screen. EXCEPTION: the main
       area labels (.label--main) stay visible through phase switches. */
    body[data-active-phase] #mapLabels .label:not(.label--main),
    body[data-active-phase] #mapRoadBadges .road-badge {
        opacity: 0 !important;
        pointer-events: none;
        transition: opacity 0.25s ease;
    }

    /* Keep main labels fully visible on mobile regardless of which phase is
       active — overrides the non-matching phase-dim (opacity 0.15) above. */
    body[data-active-phase] #mapLabels .label--main {
        opacity: 1 !important;
        pointer-events: auto;
    }
}

/* =============================================================================
   Phase filter — body[data-active-phase] is set by the left-nav Phase 1 /
   Phase 2 buttons. When active, non-matching polygons go grey + low opacity
   and non-matching labels fade right back. Matching items keep their normal
   colours and get a subtle outline bump for emphasis.

   Uses attribute selectors against data-phase (set on polygons + labels in
   front-page.php), so the entire effect is declarative — no per-element JS.
============================================================================= */
.sectionOutline, .label { transition: fill 0.45s ease, stroke 0.45s ease, opacity 0.45s ease, filter 0.45s ease; }

/* Non-matching polygons: greyed out fill, faded stroke. The !importants are
   needed to win over the per-colour fill rules above. Green Zones
   (data-color="green") are EXEMPT — they're not phase-bound, they're just
   vegetation, so they stay vivid no matter which phase is selected. */
body[data-active-phase="phase-1"] .sectionOutline:not([data-phase="phase-1"]):not([data-color="green"]),
body[data-active-phase="phase-2"] .sectionOutline:not([data-phase="phase-2"]):not([data-color="green"]),
body[data-active-phase="phase-3"] .sectionOutline:not([data-phase="phase-3"]):not([data-color="green"]) {
    fill:   rgba(150, 150, 150, 0.18) !important;
    stroke: rgba(255, 255, 255, 0.22) !important;
}

/* Non-matching labels: nearly invisible, desaturated. Green-zone labels
   (if any exist) are also exempt for the same reason. */
body[data-active-phase="phase-1"] .label:not([data-phase="phase-1"]):not([data-color="green"]),
body[data-active-phase="phase-2"] .label:not([data-phase="phase-2"]):not([data-color="green"]),
body[data-active-phase="phase-3"] .label:not([data-phase="phase-3"]):not([data-color="green"]) {
    opacity: 0.15;
    filter: saturate(0.2);
    pointer-events: none;
}

/* Matching polygons: pop the white outline up a touch so the active phase
   reads clearly against the dimmed neighbours. Green Zones don't get this
   bump even if they happen to have a phase set — they're "neutral". */
body[data-active-phase="phase-1"] .sectionOutline[data-phase="phase-1"]:not([data-color="green"]),
body[data-active-phase="phase-2"] .sectionOutline[data-phase="phase-2"]:not([data-color="green"]),
body[data-active-phase="phase-3"] .sectionOutline[data-phase="phase-3"]:not([data-color="green"]) {
    stroke: rgba(255, 255, 255, 1);
    stroke-width: 2;
}

/* Phase 1 specific tints — Le Parc and La Place get coloured fills (40%
   opacity) when Phase 1 is active so they're visually distinguishable
   within the phase rather than just keeping their default colour. Same
   green family as Green Zones for Le Parc; a soft red for La Place. */
body[data-active-phase="phase-1"] .sectionOutline[data-area-slug="le-parc"] {
    fill: rgba( 59, 174,  73, 0.40) !important;
}
body[data-active-phase="phase-1"] .sectionOutline[data-area-slug="la-place"] {
    fill: rgba(105, 112, 120, 0.65) !important;
}

/* Hover/nav-hover overrides for the two named polygons — bright 80%
   colour-coded fills so they pop on mouse-over regardless of phase state.
   Higher specificity than the per-colour hover rules above so they win. */
.sectionOutline[data-area-slug="le-parc"]:hover,
.sectionOutline[data-area-slug="le-parc"].is-hovered,
.sectionOutline[data-area-slug="le-parc"].nav-hover,
body[data-active-phase="phase-1"] .sectionOutline[data-area-slug="le-parc"]:hover,
body[data-active-phase="phase-1"] .sectionOutline[data-area-slug="le-parc"].is-hovered,
body[data-active-phase="phase-1"] .sectionOutline[data-area-slug="le-parc"].nav-hover {
    fill: rgba( 59, 174,  73, 0.80) !important;
}
.sectionOutline[data-area-slug="la-place"]:hover,
.sectionOutline[data-area-slug="la-place"].is-hovered,
.sectionOutline[data-area-slug="la-place"].nav-hover,
body[data-active-phase="phase-1"] .sectionOutline[data-area-slug="la-place"]:hover,
body[data-active-phase="phase-1"] .sectionOutline[data-area-slug="la-place"].is-hovered,
body[data-active-phase="phase-1"] .sectionOutline[data-area-slug="la-place"].nav-hover {
    fill: rgba(105, 112, 120, 0.80) !important;
}
.sectionOutline.is-phase-active  { stroke-width: 3.5 !important; }

/* ---- Per-colour fills ---- */
.sectionOutline[data-color="grey"]         { fill: rgba(105, 112, 120, 0.65); }
.sectionOutline[data-color="blue"]         { fill: rgba( 89, 129, 193, 0.65); }
.sectionOutline[data-color="red"]          { fill: rgba(165,  42,  48, 0.65); }
.sectionOutline[data-color="orange"]       { fill: rgba(243, 132,  83, 0.65); }
.sectionOutline[data-color="yellow"]       { fill: rgba(204, 218,  51, 0.65); }
/* Light-blue — soft slate / bluey-grey; same blue family but desaturated
   and lifted toward white for a much paler, less saturated overlay */
.sectionOutline[data-color="light-blue"]   { fill: rgba(245, 198, 165, 0.60); }
/* Green Zone — richer, slightly darker, more luminous forest green at
   higher opacity. Stroke removed entirely so the regions read as filled
   vegetation rather than outlined zones (overrides the base 1.5px white
   stroke). The :hover / :nav-hover / .is-hovered rules below also drop
   the stroke. */
.sectionOutline[data-color="green"]        { fill: rgba( 59, 174,  73, 0.70); stroke: none; }

/* "transparent" (alias: "clear") — no fill overlay, but the white outline
   stays so the region is still visually outlined on the map. Hover / nav-
   hover stay fill-less; the stroke gets the usual brightness bump from the
   base .sectionOutline:hover rule above. */
.sectionOutline[data-color="transparent"],
.sectionOutline[data-color="clear"] {
    fill: transparent;
}
.sectionOutline[data-color="transparent"]:hover,
.sectionOutline[data-color="transparent"].is-hovered,
.sectionOutline[data-color="transparent"].nav-hover,
.sectionOutline[data-color="clear"]:hover,
.sectionOutline[data-color="clear"].is-hovered,
.sectionOutline[data-color="clear"].nav-hover {
    fill: transparent;
}

/* Hover: bump opacity to 0.82 */
.sectionOutline[data-color="grey"]:hover,         .sectionOutline[data-color="grey"].is-hovered         { fill: rgba(105, 112, 120, 0.82); }
.sectionOutline[data-color="blue"]:hover,         .sectionOutline[data-color="blue"].is-hovered         { fill: rgba( 89, 129, 193, 0.82); }
.sectionOutline[data-color="red"]:hover,          .sectionOutline[data-color="red"].is-hovered          { fill: rgba(165,  42,  48, 0.82); }
.sectionOutline[data-color="orange"]:hover,       .sectionOutline[data-color="orange"].is-hovered       { fill: rgba(243, 132,  83, 0.82); }
.sectionOutline[data-color="yellow"]:hover,       .sectionOutline[data-color="yellow"].is-hovered       { fill: rgba(204, 218,  51, 0.82); }
.sectionOutline[data-color="light-blue"]:hover,   .sectionOutline[data-color="light-blue"].is-hovered   { fill: rgba(245, 198, 165, 0.78); }
/* Greens keep no-stroke on hover too — the brighter fill is the only feedback. */
.sectionOutline[data-color="green"]:hover,        .sectionOutline[data-color="green"].is-hovered        { fill: rgba( 59, 174,  73, 0.88); stroke: none; }

/* Mobile: remove the area hover effect. Touch fires a sticky :hover after a
   tap, leaving an area stuck in its brighter hover fill + bumped stroke, so we
   pin each :hover back to its resting per-colour fill and base stroke. (The
   #mainPageSvg prefix outranks the per-colour :hover rules above; !important
   matches the le-parc / la-place hover overrides.) Tapping an area still opens
   its modal — only the visual hover feedback is gone. */
@media (max-width: 767px) {
    #mainPageSvg .sectionOutline:hover {
        stroke: rgba(255, 255, 255, 0.7);
        stroke-width: 1.5;
    }
    #mainPageSvg .sectionOutline[data-color="grey"]:hover       { fill: rgba(105, 112, 120, 0.65); }
    #mainPageSvg .sectionOutline[data-color="blue"]:hover       { fill: rgba( 89, 129, 193, 0.65); }
    #mainPageSvg .sectionOutline[data-color="red"]:hover        { fill: rgba(165,  42,  48, 0.65); }
    #mainPageSvg .sectionOutline[data-color="orange"]:hover     { fill: rgba(243, 132,  83, 0.65); }
    #mainPageSvg .sectionOutline[data-color="yellow"]:hover     { fill: rgba(204, 218,  51, 0.65); }
    #mainPageSvg .sectionOutline[data-color="light-blue"]:hover { fill: rgba(245, 198, 165, 0.60); }
    #mainPageSvg .sectionOutline[data-color="green"]:hover      { fill: rgba( 59, 174,  73, 0.70); stroke: none; }
    /* Named polygons set their hover fill with !important — match it. */
    #mainPageSvg .sectionOutline[data-area-slug="le-parc"]:hover  { fill: rgba( 59, 174,  73, 0.70) !important; }
    #mainPageSvg .sectionOutline[data-area-slug="la-place"]:hover { fill: rgba(105, 112, 120, 0.65) !important; }
}


/* ============ Labels =============================================================================
====================================================================================================*/

/*
 * #mapLabels sits inside .innerMainWrap so it inherits the CSS transform scale —
 * labels automatically stay in proportion when zooming, panning or resizing the window.
 * aspect-ratio matches the SVG viewBox (3201 × 2500) so % positions map 1-to-1
 * with the underlying map image regardless of screen size.
 */

/* `scale(var(--marker-counter, 1))` is appended after the centering
   translate on every keyframe so the entire list shares the same transform
   function signature (required for smooth interpolation). On desktop the
   counter resolves to 1 and the scale is an identity no-op. */
@keyframes labelBounceIn {
    0%   { opacity: 0; transform: translate(-50%, calc(-50% - 10px)) scale(var(--marker-counter, 1)); }
    55%  { opacity: 1; transform: translate(-50%, calc(-50% + 3px))  scale(var(--marker-counter, 1)); }
    75%  {             transform: translate(-50%, calc(-50% - 2px))  scale(var(--marker-counter, 1)); }
    90%  {             transform: translate(-50%, calc(-50% + 1px))  scale(var(--marker-counter, 1)); }
    100% { opacity: 1; transform: translate(-50%, -50%)              scale(var(--marker-counter, 1)); }
}

@keyframes labelBounceOut {
    0%   { opacity: 1; transform: translate(-50%, -50%)              scale(var(--marker-counter, 1)); }
    20%  {             transform: translate(-50%, calc(-50% + 3px))  scale(var(--marker-counter, 1)); }
    50%  {             transform: translate(-50%, calc(-50% - 2px))  scale(var(--marker-counter, 1)); }
    100% { opacity: 0; transform: translate(-50%, calc(-50% - 10px)) scale(var(--marker-counter, 1)); }
}

#mapLabels {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    aspect-ratio: 3201 / 2500;
    pointer-events: none;
    z-index: 130;
}

/* Base label — invisible until an animation class on the parent drives it.
   Positions come from inline style (set by the admin picker). */
.label {
    position: absolute;
    opacity: 0;
    background: #ffffff;
    white-space: nowrap;
    filter: drop-shadow(0 1px 6px rgba(0, 0, 0, 0.22));
    line-height: 1;
    font-family: 'effra', 'Effra', sans-serif;
}

.label::after {
    /* content: ''; */
    position: absolute;
    bottom: -9px;
    left: 50%;
    transform: translateX(-50%);
    width: 0;
    height: 0;
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    border-top: 10px solid #ffffff;
}

/* Sub-elements */
.label__icon {
    display: block;
    margin: 0 auto 4px;
    text-align: center;
}
.label__icon img {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: 2px solid rgba(255,255,255,0.7);
    object-fit: cover;
    display: block;
}
.label__text {
    display: block;
}

/* Main label tier (Le Parc, Le Place etc.) */
.label--main {
    font-size: 13px;
    font-weight: 600;
    text-align: center;
    border-radius: 20px;
    background: hsl(0deg 0% 100% / 92%);
    padding: 3px 10px;
    /* border-radius: 6px; */
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
    white-space: nowrap;
}

/* Desktop: bump the main area labels up slightly. Mobile keeps the smaller
   13px base above (where screen space is tighter and labels counter-scale). */
@media (min-width: 768px) {
    .label--main {
        font-size: 15px;
        padding: 4px 12px;
    }
}

/* The "Le Parc" overall title label has no polygon of its own (it carries
   .label--always). Render it as plain white text floating on the map — no
   white pill background, shadow, or pointer triangle. The base .label
   drop-shadow stays for legibility against the map. */
.label--always {
    background: none !important;
    box-shadow: none !important;
    color: #ffffff !important;
}
.label--always::after { display: none !important; }

/* Nav link hover → label goes red / white */
.label.nav-hover,
.label--main.nav-hover {
    background: var(--color-active);
    color: #ffffff;
    transition: background 0.3s ease, color 0.3s ease;
}
.label.nav-hover::after,
.label--main.nav-hover::after {
    border-top-color: var(--color-active);
    transition: border-top-color 0.3s ease;
}

/* Clickable labels get a pointer and subtle underline hint */
.label--clickable {
    cursor: pointer;
}
.label--clickable:hover .label__text {
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Non-main labels are hidden ONLY on the home-page map (#mapLabels) — the
   colour legend + hover tooltip cover what they used to do, and removing
   them stops the composition from getting busy. Inner pages (e.g. Le Parc's
   #lpAreaLabels) still need their small labels, so the rule is scoped to
   the home container only. Toggle this off if you want them back on home. */
#mapLabels .label.label--small {
    display: none !important;
}


.label--small {
    font-size: 11px;
    font-weight: 500;
    color: #1c2920;
    padding: 5px 11px;
    border-radius: 20px;
}

.label--large {
    font-size: 20px;
    font-weight: 700;
    color: #1c2920;
    padding: 7px 20px;
    border-radius: 30px;
}

/* ---- Positions are set via inline style by the admin iframe picker ---- */

/* ---- Bounce IN ---- */
#mapLabels.labels-visible .label {
    animation: labelBounceIn 0.55s ease both;
}
#mapLabels.labels-visible .label:nth-child(1)  { animation-delay: 0.05s; }
#mapLabels.labels-visible .label:nth-child(2)  { animation-delay: 0.17s; }
#mapLabels.labels-visible .label:nth-child(3)  { animation-delay: 0.29s; }
#mapLabels.labels-visible .label:nth-child(4)  { animation-delay: 0.41s; }
#mapLabels.labels-visible .label:nth-child(5)  { animation-delay: 0.53s; }
#mapLabels.labels-visible .label:nth-child(6)  { animation-delay: 0.65s; }
#mapLabels.labels-visible .label:nth-child(7)  { animation-delay: 0.77s; }
#mapLabels.labels-visible .label:nth-child(8)  { animation-delay: 0.89s; }

/* ---- Bounce OUT ---- */
#mapLabels.labels-hidden .label {
    animation: labelBounceOut 0.45s ease both;
}
#mapLabels.labels-hidden .label:nth-child(1)  { animation-delay: 0.00s; }
#mapLabels.labels-hidden .label:nth-child(2)  { animation-delay: 0.10s; }
#mapLabels.labels-hidden .label:nth-child(3)  { animation-delay: 0.20s; }
#mapLabels.labels-hidden .label:nth-child(4)  { animation-delay: 0.30s; }
#mapLabels.labels-hidden .label:nth-child(5)  { animation-delay: 0.40s; }
#mapLabels.labels-hidden .label:nth-child(6)  { animation-delay: 0.50s; }
#mapLabels.labels-hidden .label:nth-child(7)  { animation-delay: 0.60s; }
#mapLabels.labels-hidden .label:nth-child(8)  { animation-delay: 0.70s; }


/* ============ Action Buttons =======================================================================
====================================================================================================*/

/*
 * .actionButtons sits inside .mainWrap but OUTSIDE .innerMainWrap so it stays
 * fixed in the top-right corner regardless of zoom or pan.
 */

#actionButtons {
    position: absolute;
    top: 20px;
    right: 20px;
    display: flex;
    flex-direction: row;
    gap: 10px;
    z-index: 200;
}

.actionBtn {
    width: 41px;
    height: 41px;
    border-radius: 50%;
    border: 2px solid #ffffff;
    background-color: #1c2920;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 9px;
    transition: background-color 0.3s ease, transform 0.3s ease;
}

.actionBtn:hover {
    background-color: var(--color-active);
    transform: scale(1.12);
}

.actionBtn.active {
    background-color: var(--color-active);
    transform: scale(1.12);
}

/* Mobile: active filter icons use brand green instead of the desktop
   accent colour. Toggling the icon off (deselecting) already strips
   .active via the existing close* handlers, which reverts the button to
   its default #1c2920 background. The :hover overrides below stop touch
   devices from leaving the button in a "sticky red" hover state after a
   tap to deselect. */
@media (max-width: 767px) {
    /* Move the filter icons from the desktop top-right corner to a
       bottom-left position just above the collapsed sheet panels.
       Panels are 70px tall when collapsed (see #poiPanel mobile rules
       below) and sit at .mainWrap's bottom, so bottom:80px clears them
       by ~10px. When the user expands a panel it'll cover the icons,
       which is fine — the icons are the entry point for filters, not
       a control surface while a panel is open. */
    #actionButtons {
        top: auto;
        right: auto;
        bottom: 80px;
        left: 16px;
        /* Hidden on first paint. The initial reveal happens when JS adds
           `.layers-revealed` to <body> (inside activateMapLayers, right
           after openLegend()) — same trigger as the legend popup, so the
           icons land alongside it instead of floating in during the
           intro animation.

           Asymmetric timing: when fading IN (initial reveal, OR panel
           was expanded and is collapsing) we wait 0.4s — matches both
           the legend's slide-up and the panel's shrink animation below
           (`transition: transform 0.4s ... max-height 0.4s`) — so the
           icons only appear once the popup is fully in/shrunk. When
           fading OUT (panel becoming expanded) the .is-expanded rule
           below overrides this with a 0s delay so the icons disappear
           immediately. Browsers apply the destination state's transition
           on each change. */
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.25s ease 0.4s;
    }
    body.layers-revealed .mainWrap #actionButtons {
        opacity: 1;
        pointer-events: auto;
    }
    /* While any sheet panel is expanded, fade the filter icons out — they
       sit underneath the expanded panel anyway, and hiding them avoids
       any half-visible peek-through and stops accidental taps. They come
       back once the panel finishes collapsing (delay handled by the
       base #actionButtons rule's transition). */
    .mainWrap:has(#poiPanel.is-expanded, #trailsPanel.is-expanded, #roadsPanel.is-expanded, #legendPanel.is-expanded) #actionButtons {
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.2s ease 0s;
    }
    .actionBtn:hover {
        background-color: #1c2920;
        transform: none;
    }
    .actionBtn.active,
    .actionBtn.active:hover {
        background-color: #006242;
        transform: none;
    }
}

/* Gems toggle is a mobile-only filter icon — hide it on desktop. */
@media (min-width: 768px) {
    #btnGems {
        display: none;
    }
}

.actionBtn img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    /* brightness(0) flattens any source colour to pure black; invert(1)
       then turns that black into pure white. Result: every action-button
       icon renders white regardless of the SVG's intrinsic fill. The
       !important guards against any later page-specific overrides. */
    filter: brightness(0) invert(1) !important;
}

/* Inline-SVG variant (e.g. legend button) — paints with its own fills so
   no invert filter is needed. Sized to fill the button minus padding. */
.actionBtn--svg svg {
    width: 100%;
    height: 100%;
    display: block;
}


/* ============ Gems ==================================================================================
====================================================================================================*/

/* The base scale values (0.7, 1) are multiplied by --marker-counter so the
   end state shrinks proportionally on mobile zoom. .gem-wrap / .poi-marker-wrap
   center themselves with negative margins (not transforms), so plain scale
   is enough — no centering translate needed. */
@keyframes gemFadeIn {
    0%   { opacity: 0; transform: scale(calc(0.7 * var(--marker-counter, 1))); }
    100% { opacity: 1; transform: scale(var(--marker-counter, 1)); }
}

@keyframes gemFadeOut {
    0%   { opacity: 1; transform: scale(var(--marker-counter, 1)); }
    100% { opacity: 0; transform: scale(calc(0.7 * var(--marker-counter, 1))); }
}

#mapGems {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    aspect-ratio: 3201 / 2500;
    pointer-events: none;
    z-index: 135;
}

/* Mobile: pinned gems. custom.js lifts #mapGems out of the panned/scaled map
   inner and re-appends it to .mainWrap, then adds .gems-pinned. We fix it to the
   slice of the viewport the map occupies (below the 76px header, above the
   56px bottom nav) so the interest-label gems stay put and reachable while the
   user pans / zooms the map beneath them. Positions stay as % so the gems now
   resolve against the visible area and hold their spot during pan/zoom.
   pointer-events:none lets pans pass through; the .gem-wrap children keep
   pointer-events:all so taps still open the gem modal. */
@media (max-width: 767px) {
    #mapGems.gems-pinned {
        /* Inset the fixed box away from the screen edges so a gem sitting at
           ~0% / ~100% (centred via translate(-50%,-50%)) doesn't spill its
           text off the side. The gem-wraps are absolutely positioned, whose
           %s resolve against this box's padding edge — so insetting the box
           itself (not padding) is what actually moves them. The larger left
           inset pushes the left-most gems further in from the screen edge. */
        position: fixed;
        top: 84px;      /* 76px header + 8px gap */
        bottom: 64px;   /* 56px bottom nav + 8px gap */
        left: 40px;
        right: 10px;
        width: auto;
        height: auto;
        aspect-ratio: auto;
        box-sizing: border-box;
    }

    /* Smaller label chips on mobile so they read as map pins, not banners.
       Cap the width and allow wrapping (overriding the base nowrap) so long
       phrases stack onto multiple lines instead of stretching into a banner. */
    #mapGems.gems-pinned .gem-label {
        font-size: 9px;
        padding: 4px 9px;
        border-radius: 12px;
        max-width: 110px;
        white-space: normal;
    }
}

/*
 * Two-element approach: .gem-wrap owns position + load animation so
 * animation-fill-mode never touches .gem. That leaves .gem's transition
 * completely free to animate the hover scale smoothly.
 */

.gem-wrap {
    position: absolute;
    width: 85px;
    height: 85px;
    margin-left: -42px;
    margin-top: -42px;
    opacity: 0;
    cursor: pointer;
    pointer-events: all;
}

.gem {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    border: 3px solid #ffffff;
    overflow: hidden;
    box-shadow: 0 3px 12px rgba(0, 0, 0, 0.35);
    transition: transform 0.35s ease;
}

/* hover scale handled via JS to respect per-gem random base scale */

.gem img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    pointer-events: none;
}

/* ---- Fade + scale IN: image gems only (interest labels handled separately) ---- */

#mapGems.gems-visible .gem-wrap:not(.gem-wrap--label) {
    animation: gemFadeIn 0.5s ease both;
}
#mapGems.gems-visible .gem-wrap:not(.gem-wrap--label):nth-child(1) { animation-delay: 0.00s; }
#mapGems.gems-visible .gem-wrap:not(.gem-wrap--label):nth-child(2) { animation-delay: 0.15s; }
#mapGems.gems-visible .gem-wrap:not(.gem-wrap--label):nth-child(3) { animation-delay: 0.30s; }
#mapGems.gems-visible .gem-wrap:not(.gem-wrap--label):nth-child(4) { animation-delay: 0.45s; }
#mapGems.gems-visible .gem-wrap:not(.gem-wrap--label):nth-child(5) { animation-delay: 0.60s; }
#mapGems.gems-visible .gem-wrap:not(.gem-wrap--label):nth-child(6) { animation-delay: 0.75s; }

/* ---- Fade + scale OUT: image gems only ---- */

#mapGems.gems-hidden .gem-wrap:not(.gem-wrap--label) {
    animation: gemFadeOut 0.4s ease both;
    pointer-events: none;
}
#mapGems.gems-hidden .gem-wrap:not(.gem-wrap--label):nth-child(1) { animation-delay: 0.00s; }
#mapGems.gems-hidden .gem-wrap:not(.gem-wrap--label):nth-child(2) { animation-delay: 0.10s; }
#mapGems.gems-hidden .gem-wrap:not(.gem-wrap--label):nth-child(3) { animation-delay: 0.20s; }
#mapGems.gems-hidden .gem-wrap:not(.gem-wrap--label):nth-child(4) { animation-delay: 0.30s; }
#mapGems.gems-hidden .gem-wrap:not(.gem-wrap--label):nth-child(5) { animation-delay: 0.40s; }
#mapGems.gems-hidden .gem-wrap:not(.gem-wrap--label):nth-child(6) { animation-delay: 0.50s; }


/* ============ Interest-label gem variant ==========================================================
   When `is_a_interest_label` is ticked on a Gem, it renders here as a small white
   text label with a directional arrow on the side matching `arrow_direction`.
   Reuses the labels' bounce-in animation rather than the gem fade.
==================================================================================================== */
.gem-wrap--label {
    /* Override the fixed 85×85 + margin centring used by image gems. */
    width: auto;
    height: auto;
    margin: 0;
    transform: translate(-50%, -50%) scale(var(--marker-counter, 1)); /* same centring strategy as .label so the bounce keyframes work */
}

.gem-label {
    display: inline-block;
    background: #000000;
    color: #ffffff;
    font-family: 'effra';
    font-size: 11px;
    font-weight: 600;
    line-height: 1.25;
    text-transform: uppercase;
    padding: 6px 12px;
    border-radius: 16px;
    filter: drop-shadow(0 1px 6px rgba(0, 0, 0, 0.22));
    letter-spacing: 0.05em;
    text-align: center;
    /* Respect manual line breaks (<br>) but never auto-wrap mid-phrase, so the
       label keeps the same shape regardless of screen width. */
    white-space: nowrap;
}

/* Interest labels bounce in on page load via interest-labels-active.
   They are never hidden by the gems toggle — they stay visible always. */
#mapGems.interest-labels-active .gem-wrap--label {
    animation: labelBounceIn 0.55s ease both;
}
/* When disabled (gems toggle off) the labels are at opacity:0 — make sure
   they're not tappable while invisible. */
#mapGems:not(.interest-labels-active) .gem-wrap--label {
    pointer-events: none;
}

/* ---- Directional arrow ---- */
/* Default down-pointing triangle drawn with a border; rotated per data-arrow.
   The visible apex of the default triangle points DOWN (south). */
.gem-wrap--label::after {
    content: "";
    position: absolute;
    width: 0;
    height: 0;
    /* Skinnier (4px each side = 8px base) and longer (16px tall). */
    border-left: 8px solid transparent;
    border-right: 8px solid transparent;
    border-top: 20px solid #000000;
    pointer-events: none;
    filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.18));
}

/* North — top centre, apex up */
.gem-wrap--label[data-arrow="north"]::after {
    top: -17px;
    left: 50%;
    transform: translateX(-50%) rotate(180deg);
}

/* South — bottom centre, apex down (default) */
.gem-wrap--label[data-arrow="south"]::after {
    bottom: -15px; left: 50%;
    transform: translateX(-50%);
}

/* East — right middle, apex right */
.gem-wrap--label[data-arrow="east"]::after {
    top: 50%;
    right: -16px;
    transform: translateY(-50%) rotate(-90deg);
}

/* West — left middle, apex left */
.gem-wrap--label[data-arrow="west"]::after {
    top: 50%;
    left: -15px;
    transform: translateY(-50%) rotate(90deg);
}

/* North-east — top-right corner, apex up-right */
.gem-wrap--label[data-arrow="north-east"]::after {
    top: -8px; right: 0;
    transform: rotate(-135deg);
}

/* North-west — top-left corner, apex up-left */
.gem-wrap--label[data-arrow="north-west"]::after {
    top: -11px;
    left: -9px;
    transform: rotate(135deg);
}

/* South-east — bottom-right corner, apex down-right */
.gem-wrap--label[data-arrow="south-east"]::after {
    bottom: -8px; right: 0;
    transform: rotate(-45deg);
}

/* South-west — bottom-left corner, apex down-left */
.gem-wrap--label[data-arrow="south-west"]::after {
    bottom: -8px; left: 0;
    transform: rotate(45deg);
}


/* ============ Points of Interest Panel =============================================================
====================================================================================================*/

#poiPanel {
    position: absolute;
    top: 110px;   /* clears action buttons (top 20px + height 41px + ~50px gap) */
    bottom: 50px; /* breathing room from the bottom edge */
    right: 0;
    width: 310px;
    background: rgba(255, 255, 255, 0.97);
    box-shadow: -6px 0 24px rgba(0, 0, 0, 0.12);
    border-radius: 10px 0 0 10px; /* rounded on the left side, flush on the right */
    transform: translateX(100%);
    transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 150;
    display: flex;
    flex-direction: column;
}

#poiPanel.is-open {
    transform: translateX(0);
}

/* ---- Inner container ---- */

.poiPanel__inner {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden; /* views handle their own scroll */
}

/* ---- Views wrapper: clips the sliding list / detail panels ---- */

.poiPanel__views {
    flex: 1;
    position: relative;
    overflow: hidden;
}

/* Both views fill the views wrapper and scroll independently */
.poiPanel__listView,
.poiPanel__detailView {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    overflow-y: auto;
    overflow-x: hidden;
    transition: transform 0.38s cubic-bezier(0.4, 0, 0.2, 1),
                opacity  0.38s cubic-bezier(0.4, 0, 0.2, 1);
    will-change: transform, opacity;
}

/* List: default visible */
.poiPanel__listView {
    transform: translateX(0);
    opacity: 1;
    pointer-events: all;
    padding: 0 0 16px;
}

/* Detail: default hidden to the right */
.poiPanel__detailView {
    transform: translateX(100%);
    opacity: 0;
    pointer-events: none;
    padding: 0 0 24px;
}

/* When detail is active: list exits right, detail enters from right */
.poiPanel__inner.detail-active .poiPanel__listView {
    transform: translateX(-30%);
    opacity: 0;
    pointer-events: none;
}
.poiPanel__inner.detail-active .poiPanel__detailView {
    transform: translateX(0);
    opacity: 1;
    pointer-events: all;
}

/* During a detail→detail switch: slide detail out right before swapping content */
.poiPanel__inner.detail-active.detail-switching .poiPanel__detailView {
    transform: translateX(100%);
    opacity: 0;
}

/* ---- Close X button (top-right of header) ---- */

.poiPanel__close {
    position: absolute;
    top: 11px;
    right: 11px;
    width: 26px;
    height: 26px;
    background: none;
    border: none;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    font-weight: 300;
    line-height: 1;
    color: #666;
    cursor: pointer;
    transition: color 0.2s ease;
    padding: 0;
}

.poiPanel__close:hover {
    color: var(--color-active);
}

/* ---- Header ---- */

.poiPanel__header {
    position: relative;
    padding: 24px 24px 18px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.07);
    flex-shrink: 0;
}

.poiPanel__title {
    font-size: 22px;
    font-weight: 600;
    color: #1c2920;
    margin: 0 0 6px;
    line-height: 1.2;
    font-family: 'larken', 'Larken', serif;
}

/* Meta row: subtitle and back button occupy the same space and cross-fade */
.poiPanel__meta {
    position: relative;
    min-height: 18px;
}

.poiPanel__subtitle {
    font-size: 12px;
    color: #888;
    margin: 0;
    letter-spacing: 0.06em;
    line-height: 1.4;
    transition: opacity 0.2s ease;
}

.poiPanel__inner.detail-active .poiPanel__subtitle {
    opacity: 0;
    pointer-events: none;
}

/* ---- List ---- */

.poiPanel__list {
    list-style: none;
    padding: 0 0 5px;
    margin: 0;
    flex-grow: 1;
}

.poiPanel__item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 9px 20px;
    cursor: pointer;
    transition: background-color 0.2s ease;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}

.poiPanel__item:last-child {
    border-bottom: none;
}

.poiPanel__item:hover {
    background-color: rgba(0, 98, 66, 0.05);
}

.poiPanel__icon {
    width: 36px;
    height: 36px;
    min-width: 36px;
    border-radius: 50%;
    background-color: #006242;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.2s ease;
}

.poiPanel__item:hover .poiPanel__icon {
    background-color: var(--color-active);
}

.poiPanel__icon img {
    width: 17px;
    height: 17px;
    filter: brightness(0) invert(1);
    pointer-events: none;
}

.poiPanel__name {
    font-size: 13px;
    font-weight: 500;
    color: #1c2920;
    line-height: 1.3;
}


/* ---- Active list item ---- */

.poiPanel__item.is-active {
    background-color: rgba(0, 98, 66, 0.07);
}
.poiPanel__item.is-active .poiPanel__icon {
    background-color: var(--color-active);
}

/* ---- Back button: sits in header meta area, hidden until detail-active ---- */

.poiPanel__back {
    position: absolute;
    top: 0;
    left: 0;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: none;
    border: none;
    padding: 0;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.04em;
    color: #006242;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s ease, color 0.2s ease;
    white-space: nowrap;
}

.poiPanel__back:hover {
    color: var(--color-active);
}

.poiPanel__inner.detail-active .poiPanel__back {
    opacity: 1;
    pointer-events: all;
}

/* ---- Detail view content ---- */

.poiPanel__detailHeader {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 9px 20px;
}

.poiPanel__detailIcon {
    width: 36px;
    height: 36px;
    min-width: 36px;
    border-radius: 50%;
    background-color: #006242;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.poiPanel__detailIcon img {
    width: 18px;
    height: 18px;
    filter: brightness(0) invert(1);
    pointer-events: none;
}

.poiPanel__detailTitle {
    font-size: 16px;
    font-weight: 700;
    color: #1c2920;
    margin: 0;
    line-height: 1.2;
}

.poiPanel__detailContent {
    padding: 20px 20px 0;
}

/* Tabs */
.poi-tabs {
    display: flex;
    gap: 6px;
    margin-bottom: 14px;
}
.poi-tab {
    flex: 1;
    padding: 8px 10px;
    border: 1.5px solid rgba(0, 98, 66, 0.3);
    border-radius: 4px;
    background: #fff;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #1c2920;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.poi-tab.is-active {
    background-color: var(--color-active);
    border-color: var(--color-active);
    color: #fff;
}
.poi-tab:hover:not(.is-active) {
    border-color: #006242;
    color: #006242;
}
/* Mobile: active video/gallery tabs use brand green instead of the red
   --color-active, to match the rest of the mobile palette in the Local
   Highlights popup. */
@media (max-width: 767px) {
    .poi-tab.is-active {
        background-color: #006242;
        border-color: #006242;
    }
}

/* Tab panels */
.poi-tab-panel {
    display: none;
}
.poi-tab-panel.is-active {
    display: block;
}

/* Video */
.poi-video-wrap {
    position: relative;
    aspect-ratio: 16 / 9;
    border-radius: 6px;
    overflow: hidden;
    margin-bottom: 12px;
}
.poi-video-wrap video {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
    border-radius: 6px;
}

/* Gallery carousel in panel — same aspect ratio as video so height never changes */
.poi-gallery-wrap {
    position: relative;
    aspect-ratio: 16 / 9;
    margin-bottom: 12px;
    border-radius: 6px;
    overflow: hidden;
}
.poi-gallery-wrap .carousel,
.poi-gallery-wrap .carousel-inner,
.poi-gallery-wrap .carousel-item {
    height: 100%;
}
.poi-gallery-wrap .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.poi-gallery-wrap .carousel-control-prev,
.poi-gallery-wrap .carousel-control-next {
    width: 30px;
    height: 30px;
    background-color: rgba(0, 0, 0, 0.45);
    border-radius: 50%;
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    opacity: 1;
}
.poi-gallery-wrap .carousel-control-prev { left: 8px; }
.poi-gallery-wrap .carousel-control-next { right: 8px; }
.poi-gallery-wrap .carousel-control-prev-icon,
.poi-gallery-wrap .carousel-control-next-icon {
    width: 12px;
    height: 12px;
}

/* Expand button (magnify) */
.poi-expand-btn {
    position: absolute;
    bottom: 8px;
    right: 8px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.5);
    border: none;
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background-color 0.2s ease;
    z-index: 5;
}
.poi-expand-btn:hover {
    background: rgba(0, 0, 0, 0.8);
}

/* POI text content */
.poi-text {
    font-size: 12px;
    color: #4a5568;
    line-height: 1.8;
    margin-top: 14px;
    white-space: pre-line;
}


/* ============ POI Map Markers =======================================================================
====================================================================================================*/

.poi-markers {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    aspect-ratio: 3201 / 2500;
    pointer-events: none;
    /* Sits ABOVE the road badges (145) so the hover thumbnail crossfade
       on a POI never disappears behind a road name, and ABOVE labels (130)
       too. Kept below the POI panel (150) so the panel still covers it. */
    z-index: 148;
}

/* Outer wrap: handles position + animation (same two-element pattern as gems) */
.poi-marker-wrap {
    position: absolute;
    width: 46px;
    height: 46px;
    margin-left: -23px;
    margin-top: -23px;
    opacity: 0;
    cursor: pointer;
    pointer-events: none;
}

/* Inner marker: visual + hover scale */
.poi-marker {
    position: relative;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background-color: #006242;
    border: 2px solid #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    transition: transform 0.35s ease, border-width 0.35s ease, box-shadow 0.35s ease;
}
.poi-marker__icon {
    position: relative;
    z-index: 1;
    width: 20px;
    height: 20px;
    filter: brightness(0) invert(1);
    pointer-events: none;
    display: block;
    transition: opacity 0.25s ease;
}
.poi-marker__thumb {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 0.25s ease;
    pointer-events: none;
}
.poi-marker-wrap:hover .poi-marker {
    transform: scale(1.1);
}
/* Expand to gem size and show gallery image on hover */
.poi-marker-wrap.has-thumb:hover {
    z-index: 20;
}
.poi-marker-wrap.has-thumb:hover .poi-marker {
    transform: scale(2.55);
    border-width: 1.5px;
    box-shadow: 0 3px 12px rgba(0, 0, 0, 0.35);
}
.poi-marker-wrap.has-thumb:hover .poi-marker__icon {
    opacity: 0;
}
.poi-marker-wrap.has-thumb:hover .poi-marker__thumb {
    opacity: 1;
}

/* Mobile sticky-hover state: tapping a POI keeps it in the expanded
   thumb appearance until another POI is tapped (is-active is moved
   between markers by setActiveMarkerAndItem in custom.js). Touch
   devices don't keep :hover, so we mirror those hover styles onto
   .is-active. */
@media (max-width: 767px) {
    /* Neutralize the desktop :hover rules on touch. Without this,
       interacting with the popup (e.g. tapping the header to shrink)
       can re-trigger the touch-sticky :hover on the previously-tapped
       POI and stack the larger scale(2.55) hover state on top of
       .is-active. These rules must come BEFORE the .is-active block
       below so .is-active wins on source order for the active marker. */
    .poi-marker-wrap:hover .poi-marker {
        transform: none;
    }
    .poi-marker-wrap.has-thumb:hover {
        z-index: auto;
    }
    .poi-marker-wrap.has-thumb:hover .poi-marker {
        transform: none;
        border-width: 2px;
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    }
    .poi-marker-wrap.has-thumb:hover .poi-marker__icon {
        opacity: 1;
    }
    .poi-marker-wrap.has-thumb:hover .poi-marker__thumb {
        opacity: 0;
    }

    .poi-marker-wrap.has-thumb.is-active {
        z-index: 20;
    }
    .poi-marker-wrap.has-thumb.is-active .poi-marker {
        transform: scale(1.4);
        border-width: 1.5px;
        box-shadow: 0 3px 12px rgba(0, 0, 0, 0.35);
    }
    .poi-marker-wrap.has-thumb.is-active .poi-marker__icon {
        opacity: 0;
    }
    .poi-marker-wrap.has-thumb.is-active .poi-marker__thumb {
        opacity: 1;
    }

    /* Smaller marker overall on mobile — desktop's 46px circle reads
       too chunky on a phone. Margins are kept at -half-the-size so the
       inline left/top % continues to anchor on the marker's centre. */
    .poi-marker-wrap {
        width: 38px;
        height: 38px;
        margin-left: -19px;
        margin-top: -19px;
    }
    /* Icon shrinks alongside the wrap so the gap around it stays tight
       (~6px each side). */
    .poi-marker__icon {
        width: 22px;
        height: 22px;
    }
}

/* Active state: red + slightly bigger + raised above siblings */
.poi-marker-wrap.is-active {
    z-index: 10;
}
.poi-marker-wrap.is-active .poi-marker {
    background-color: var(--color-active);
    transform: scale(1.15);
}
.poi-marker-wrap.is-active:hover .poi-marker {
    transform: scale(1.2);
}

/* Staggered fade+scale IN */
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap {
    animation: gemFadeIn 0.5s ease both;
    pointer-events: all;
}
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(1)  { animation-delay: 0.00s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(2)  { animation-delay: 0.12s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(3)  { animation-delay: 0.24s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(4)  { animation-delay: 0.36s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(5)  { animation-delay: 0.48s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(6)  { animation-delay: 0.60s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(7)  { animation-delay: 0.72s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(8)  { animation-delay: 0.84s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(9)  { animation-delay: 0.96s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(10) { animation-delay: 1.08s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(11) { animation-delay: 1.20s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(12) { animation-delay: 1.32s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(13) { animation-delay: 1.44s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(14) { animation-delay: 1.56s; }
#mapPoiMarkers.poi-markers-visible .poi-marker-wrap:nth-child(15) { animation-delay: 1.68s; }

/* Staggered fade+scale OUT */
#mapPoiMarkers.poi-markers-hidden .poi-marker-wrap {
    animation: gemFadeOut 0.4s ease both;
}
#mapPoiMarkers.poi-markers-hidden .poi-marker-wrap:nth-child(1) { animation-delay: 0.00s; }
#mapPoiMarkers.poi-markers-hidden .poi-marker-wrap:nth-child(2) { animation-delay: 0.08s; }
#mapPoiMarkers.poi-markers-hidden .poi-marker-wrap:nth-child(3) { animation-delay: 0.16s; }
#mapPoiMarkers.poi-markers-hidden .poi-marker-wrap:nth-child(4) { animation-delay: 0.24s; }
#mapPoiMarkers.poi-markers-hidden .poi-marker-wrap:nth-child(5) { animation-delay: 0.32s; }
#mapPoiMarkers.poi-markers-hidden .poi-marker-wrap:nth-child(6) { animation-delay: 0.40s; }


/* ============ POI Media Modal =======================================================================
====================================================================================================*/

.poi-media-modal-content {
    border: none;
    border-radius: 12px;
    overflow: hidden;
    background: #ffffff;
    position: relative;
    padding: 5px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.45);
}

.poi-media-modal-close {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background-color: #006242;
    border: none;
    cursor: pointer;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background-color 0.25s ease;
}
.poi-media-modal-close:hover {
    background-color: var(--color-active);
}

.poi-media-modal-body {
    border-radius: 8px;
    overflow: hidden;
    line-height: 0; /* removes gap below inline elements */
}

/* Video: fill width, no black bars */
.poi-media-modal-body video {
    width: 100%;
    display: block;
    border-radius: 8px;
}

/* Full-size gallery carousel in modal */
.poi-media-modal-body .carousel {
    width: 100%;
}
.poi-media-modal-body .carousel-inner {
    border-radius: 8px;
    overflow: hidden;
}
.poi-media-modal-body .carousel-item {
    height: 78vh;
}
.poi-media-modal-body .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.poi-media-modal-body .carousel-control-prev,
.poi-media-modal-body .carousel-control-next {
    width: 40px;
    height: 40px;
    background-color: rgba(0, 0, 0, 0.35);
    border-radius: 50%;
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    opacity: 1;
}
.poi-media-modal-body .carousel-control-prev { left: 14px; }
.poi-media-modal-body .carousel-control-next { right: 14px; }


/* ============ Gem Modals ===========================================================================
====================================================================================================*/

.gemModal .modal-dialog {
    /* Width only. Leave Bootstrap's centered-flex defaults so the inner
       .modal-content sits vertically centered. Actual popup height is
       set on .gemModal .modal-content below. */
    width: 80vw;
    max-width: none;
    min-width: 0;
}

@media (max-width: 1199.98px) {
    .gemModal .modal-dialog {
        width: min(95vw, 1100px);
    }
}

@media (max-width: 600px) {
    .gemModal .modal-dialog {
        width: 95vw;
    }
}

.gemModal .modal-content {
    border: 3px solid #ffffff;
    border-radius: 14px;
    overflow: hidden;
    position: relative;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
    display: flex;
    flex-direction: column;
    /* The full-height dialog flex-centers this card vertically. */
    height: 80vh;
    max-height: calc(100vh - 40px);
    width: 100%;
}

/* ---- Custom close button ---- */
.gem-modal-close {
    position: absolute;
    top: 14px;
    right: 14px;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background-color: #006242;
    border: none;
    cursor: pointer;
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    transition: background-color 0.25s ease;
    flex-shrink: 0;
}

.gem-modal-close:hover {
    background-color: var(--color-active);
}

/* ---- Split body ---- */
.gem-modal-body {
    display: flex;
    align-items: stretch;
    flex: 1 1 auto;
    min-height: 0; /* allow the carousel/image to stretch in the flex column */
}

/* ---- Left column (40%) ---- */
.gem-modal-left {
    width: 40%;
    padding: 50px 35px 40px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    background: #ffffff;
}

.gem-modal-title {
    font-size: 26px;
    font-weight: 700;
    color: #1c2920;
    margin-bottom: 20px;
    line-height: 1.2;
}

.gem-modal-text {
    font-size: 13px;
    color: #4a5568;
    line-height: 1.9;
    margin-bottom: 32px;
    flex-grow: 1;
}

.gem-modal-enquiry {
    display: inline-block;
    background-color: #006242;
    color: #ffffff;
    text-decoration: none;
    border: none;
    cursor: pointer;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 12px 28px;
    border-radius: 4px;
    align-self: flex-start;
    transition: background-color 0.25s ease;
}

.gem-modal-enquiry:hover {
    background-color: var(--color-active);
    color: #ffffff;
}

/* CTA button rendered at the bottom of the area popup (controlled by the
   ACF `area_cta_text` + `area_cta_target` fields). Matches the gem
   enquiry button styling for visual consistency. */
.area-modal-cta {
    display: inline-block;
    margin-top: 18px;
    background-color: #006242;
    color: #ffffff;
    text-decoration: none;
    border: none;
    cursor: pointer;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    padding: 12px 28px;
    border-radius: 4px;
    align-self: flex-start;
    transition: background-color 0.25s ease;
}
.area-modal-cta:hover {
    background-color: var(--color-active);
    color: #ffffff;
}

/* ---- Right column: carousel (60%) ---- */
.gem-modal-right {
    width: 60%;
    position: relative;
    overflow: hidden;
}

.gem-modal-right .carousel,
.gem-modal-right .carousel-inner,
.gem-modal-right .carousel-item {
    height: 100%;
}

.gem-modal-right .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* ---- Carousel controls ---- */
.gem-modal-right .carousel-control-prev,
.gem-modal-right .carousel-control-next {
    width: 36px;
    height: 36px;
    background-color: rgba(0, 0, 0, 0.45);
    border-radius: 50%;
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    opacity: 1;
    transition: background-color 0.2s ease;
}

.gem-modal-right .carousel-control-prev { left: 12px; }
.gem-modal-right .carousel-control-next { right: 12px; }

.gem-modal-right .carousel-control-prev:hover,
.gem-modal-right .carousel-control-next:hover {
    background-color: rgba(0, 0, 0, 0.7);
}

.gem-modal-right .carousel-control-prev-icon,
.gem-modal-right .carousel-control-next-icon {
    width: 14px;
    height: 14px;
}

/* ---- Mobile gem popup: mirror the area popup layout ----
   Lift above the map layers, drop the white outline, and restack the body
   into a single column: green title header → image (carousel) → scrollable
   text → CTA pinned to the bottom like a footer. The four-zone layout keeps
   the header, image and CTA fixed while only the text scrolls. */
@media (max-width: 767px) {
    #gemModal {
        z-index: 5000;
    }
    .gemModal .modal-dialog {
        width: 92vw;
        max-width: none;
        height: auto;
        max-height: 85vh;
        margin-left: auto;
        margin-right: auto;
    }
    .gemModal .modal-content {
        height: auto;
        max-height: 85vh;
        border: 0;
    }
    /* gem-modal-left becomes a pass-through so its children (title, text,
       enquiry) reorder alongside the carousel inside the body flex column. */
    .gem-modal-left {
        display: contents;
    }
    .gem-modal-body {
        flex-direction: column;
        align-items: stretch;
    }
    /* Title → green header strip across the top, white text. */
    .gem-modal-title {
        order: 0;
        margin: 0;
        padding: 14px 52px 14px 18px; /* right pad clears the close × */
        background: #006242;
        color: #ffffff;
        font-size: 16px;
        font-weight: 700;
        flex-shrink: 0;
    }
    /* Close × on the green header. */
    .gem-modal-close {
        top: 10px;
        right: 10px;
        background-color: rgba(0, 0, 0, 0.25);
    }
    /* Carousel fills the full width below the header. */
    .gem-modal-right {
        order: 1;
        width: 100%;
        height: 220px;
        flex-shrink: 0;
    }
    /* No gallery → JS leaves #gemModalCarousel empty; collapse the image
       block so there's no empty 220px gap between header and text. */
    .gem-modal-right:empty {
        display: none;
    }
    /* Text is the only scroll region — flex-grows into the leftover space
       between the fixed image and the fixed CTA footer. */
    .gem-modal-text {
        order: 2;
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        margin-bottom: 0;
        padding: 16px 20px 22px;
        font-size: 13px;
    }
    /* CTA pinned to the bottom like a footer — full-width green bar that
       stays put while the text scrolls above it. */
    .gem-modal-enquiry {
        order: 3;
        flex-shrink: 0;
        align-self: stretch;
        width: 100%;
        border-radius: 0;
        padding: 15px;
        text-align: center;
        font-size: 13px;
    }
}


/* ============ Area Popup Modal ===============================================================
====================================================================================================*/

.area-modal-dialog {
    /* Width = 80vw. Leave the dialog at its Bootstrap default
       (.modal-dialog-centered: display:flex, min-height ≈ 100vh) so the
       inner .area-modal-content can sit vertically centered. The actual
       popup height is set on .area-modal-content below. */
    width: 80vw;
    max-width: none;
}

/* Below 1200px viewport width, cap the modal at 1100px (95vw on small screens
   so it still fits with breathing room). */
@media (max-width: 1199.98px) {
    .area-modal-dialog {
        width: min(95vw, 1100px);
    }
}

@media (max-width: 600px) {
    .area-modal-dialog {
        width: 95vw;
    }
}

/* Mobile area-modal layout: smaller-than-fullscreen sheet with a green
   title header, full-width gallery at the top, and text content below.
   Selectors prefixed with #areaModal to beat the base rules further
   down in source order. */
@media (max-width: 767px) {
    /* Lift the modal above the label/marker layers (which sit inside
       .mainWrap and can otherwise outrank a default-stacked Bootstrap
       modal in some contexts). 5000 comfortably beats the in-map z-index
       budget (POI panel = 150) and the default Bootstrap modal layers. */
    #areaModal {
        z-index: 5000;
    }
    #areaModal .area-modal-dialog {
        width: 92vw;
        max-width: none;
        height: auto;
        max-height: 80vh;
        margin-left: auto;
        margin-right: auto;
    }
    /* Remove the 3px white outline that the desktop content uses. */
    #areaModal .area-modal-content {
        height: auto;
        max-height: 80vh;
        border: 0;
    }
    /* Optional hero image isn't needed on mobile — the gallery panel
       takes that visual role. */
    #areaModal .area-modal-hero {
        display: none !important;
    }
    /* Promote .area-modal-left's children up into the body flex so they
       can be reordered alongside .area-modal-right (gallery). Eliminates
       the gap between the title and the gallery that the previous
       absolute-positioned title approach caused. */
    #areaModal .area-modal-left {
        display: contents;
    }
    /* Title → green header strip across the top, white text. */
    #areaModal .area-modal-title {
        order: 0;
        margin: 0;
        padding: 14px 52px 14px 18px; /* right pad clears the close × */
        background: #006242;
        color: #ffffff;
        font-size: 16px;
        font-weight: 700;
        flex-shrink: 0;
    }
    /* Close × on the green header. */
    #areaModal .area-modal-close {
        top: 10px;
        right: 10px;
        background: rgba(0, 0, 0, 0.25);
    }
    /* Body stacks vertically: title, gallery, text. */
    #areaModal .area-modal-body {
        flex-direction: column;
        align-items: stretch;
    }
    /* Gallery panel fills the full modal width with no side border. */
    #areaModal .area-modal-right {
        order: 1;
        width: 100%;
        height: 220px;
        flex-shrink: 0;
        border-left: none;
        display: flex;
        padding: 0;
    }
    #areaModal .area-modal-tab-content {
        width: 100%;
    }
    /* Text is the only scroll region — grows into the space between the
       fixed image and the fixed CTA footer. */
    #areaModal .area-modal-text {
        order: 2;
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        padding: 16px 20px 22px;
        font-size: 13px;
    }
    /* CTA pinned to the bottom like a footer — full-width green bar that
       stays put while the text scrolls above it. (Hidden until JS populates
       it, same as desktop.) */
    #areaModal .area-modal-cta {
        order: 3;
        flex-shrink: 0;
        align-self: stretch;
        width: 100%;
        margin-top: 0;
        border-radius: 0;
        padding: 15px;
        text-align: center;
        font-size: 13px;
    }
}

.area-modal-content {
    border-radius: 10px;
    overflow: hidden;
    border: 3px solid #ffffff;
    background: #fff;
    position: relative;
    display: flex;
    flex-direction: column;
    /* The full-height dialog (from .modal-dialog-centered) flex-centers
       this card vertically. Setting height + max-height here is what
       actually controls the popup's visible size. */
    height: 80vh;
    max-height: calc(100vh - 40px);
    width: 100%;
}

/* Close button */
.area-modal-close {
    position: absolute;
    top: 14px;
    right: 14px;
    z-index: 10;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    border: none;
    background: rgba(0,0,0,0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background 0.2s;
}
.area-modal-close:hover { background-color: var(--color-active); }

/* Optional hero image */
.area-modal-hero {
    width: 100%;
    height: 200px;
    overflow: hidden;
}
.area-modal-hero img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Body: two columns when right panel is shown */
.area-modal-body {
    display: flex;
    align-items: stretch;
    flex: 1 1 auto;
    min-height: 0; /* allow children with overflow:auto to size correctly */
}

.area-modal-left {
    flex: 1;
    padding: 40px 35px;
    overflow-y: auto;
    min-height: 0;
}

.area-modal-title {
    font-size: 24px;
    font-weight: 700;
    color: #1c2920;
    margin: 0 0 16px;
}

.area-modal-text {
    font-size: 13px;
    color: #4a5568;
    line-height: 1.7;
}

.area-modal-text p { margin: 0 0 12px; }

/* Right panel: tabs + content */
.area-modal-right {
    width: 55%;
    border-left: 1px solid #eee;
    display: flex;
    flex-direction: column;
    min-height: 0;
}

/* Single-pane variant: only one of video / gallery is present, so the tab bar
   is hidden and the media fills the entire right column. */
.area-modal-right.single-pane .area-modal-tabs {
    display: none;
}

.area-modal-tabs {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 14px;
    border-bottom: 1px solid #eee;
    background: #f9f9f9;
}

.area-tab-btn {
    flex: 0 0 auto;
    padding: 7px 16px;
    border: 1px solid transparent;
    background: transparent;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    color: #888;
    cursor: pointer;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    transition: color 0.2s, background 0.2s, border-color 0.2s;
}
.area-tab-btn:hover {
    color: #1c2920;
}
.area-tab-btn.is-active {
    color: #ffffff;
    background: #006242;
    border-color: #006242;
}

.area-modal-tab-content {
    flex: 1;
    overflow: hidden;
    position: relative;
    min-height: 0;
}

/* Make tab panes themselves fill the content area so the carousel/video
   inside can stretch the full height of the right column. */
.area-modal-tab-content .area-tab-pane {
    height: 100%;
    width: 100%;
}

/* Gallery carousel fills the right panel */
.area-modal-tab-content .carousel,
.area-modal-tab-content .carousel-inner,
.area-modal-tab-content .carousel-item {
    height: 100%;
}
.area-modal-tab-content .carousel-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Video panel */
.area-tab-video-wrap {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #000;
}
.area-tab-video-wrap video {
    max-width: 100%;
    max-height: 100%;
    display: block;
}


/* ============ Enquiry Modal =================================================================
====================================================================================================*/

.enquiry-modal-content {
    border: 0;
    border-radius: 10px;
    overflow: hidden;
}

.enquiry-modal-header {
    background: #006242;
    padding: 18px 24px;
    border-bottom: 0;
}

.enquiry-modal-title {
    color: #ffffff;
    font-family: 'effra', 'Effra', sans-serif;
    font-weight: 600;
    font-size: 18px;
    margin: 0;
}

.enquiry-modal-body {
    padding: 28px 24px;
    background: #ffffff;
}

.enquiry-modal-intro {
    font-family: 'effra', 'Effra', sans-serif;
    font-size: 13px;
    font-weight: 300;
    line-height: 1.5;
    color: #555;
    margin: 0 0 18px;
}

/* Mobile: cap the enquiry modal at 80vh and let the form body scroll inside
   it (the .modal-content is a flex column, so the header stays fixed and the
   body takes the remaining space). */
@media (max-width: 767px) {
    #enquiryModal .enquiry-modal-content {
        max-height: 80vh;
    }
    #enquiryModal .enquiry-modal-header {
        flex-shrink: 0;
    }
    #enquiryModal .enquiry-modal-body {
        overflow-y: auto;
    }
}

/* Show only the form matching the current language (default EN). */
.enquiry-form--fr { display: none; }
body[data-lang="fr"] .enquiry-form--en { display: none; }
body[data-lang="fr"] .enquiry-form--fr { display: block; }

/* ---- Gravity Forms overrides inside enquiry modal ---- */

/* Tighten vertical gaps between fields */
#enquiryModal .gform_wrapper .gfield {
    margin-bottom: 6px !important;
    margin-top: 0 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
}

#enquiryModal .gform_wrapper .gform_fields {
    row-gap: 6px !important;
    gap: 6px !important;
}

#enquiryModal .gform_wrapper .ginput_container {
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}

/* Remove the extra space Gravity Forms reserves for validation messages when empty */
#enquiryModal .gform_wrapper .gfield .validation_message {
    padding: 2px 0 0 !important;
    margin: 0 !important;
    font-size: 11px;
}

/* Inputs & textarea */
#enquiryModal .gform_wrapper input[type="text"],
#enquiryModal .gform_wrapper input[type="email"],
#enquiryModal .gform_wrapper input[type="tel"],
#enquiryModal .gform_wrapper input[type="number"],
#enquiryModal .gform_wrapper select,
#enquiryModal .gform_wrapper textarea {
    font-family: 'effra', 'Effra', sans-serif;
    font-weight: 400;
    font-size: 13px;
    border: 1px solid #ddd;
    border-radius: 5px;
    padding: 9px 12px;
    width: 100%;
    transition: border-color 0.2s;
}

#enquiryModal .gform_wrapper input[type="text"]:focus,
#enquiryModal .gform_wrapper input[type="email"]:focus,
#enquiryModal .gform_wrapper input[type="tel"]:focus,
#enquiryModal .gform_wrapper input[type="number"]:focus,
#enquiryModal .gform_wrapper textarea:focus {
    outline: none;
    border-color: #006242;
    box-shadow: 0 0 0 3px rgba(0, 98, 66, 0.1);
}

/* Lighter placeholder text */
#enquiryModal .gform_wrapper input::placeholder,
#enquiryModal .gform_wrapper textarea::placeholder {
    font-weight: 300;
    color: #aaa;
}

/* Labels */
#enquiryModal .gform_wrapper .gfield_label {
    font-family: 'effra', 'Effra', sans-serif;
    font-weight: 400;
    font-size: 12px;
    color: #555;
    margin-bottom: 3px;
}

/* Submit button — red, tighter top/bottom, wider left/right */
#enquiryModal .gform_wrapper .gform_footer,
#enquiryModal .gform_wrapper .gform_page_footer {
    margin-top: 12px;
    padding: 0 !important;
}

#enquiryModal .gform_wrapper input[type="submit"],
#enquiryModal .gform_wrapper button[type="submit"] {
    background-color: #006242 !important;
    border: none !important;
    border-radius: 5px !important;
    color: #ffffff !important;
    font-family: 'effra', 'Effra', sans-serif !important;
    font-size: 13px !important;
    font-weight: 500 !important;
    letter-spacing: 0.8px !important;
    padding: 8px 30px !important;
    cursor: pointer !important;
    transition: background-color 0.25s ease !important;
}

#enquiryModal .gform_wrapper input[type="submit"]:hover,
#enquiryModal .gform_wrapper button[type="submit"]:hover {
    background-color: #004d33 !important;
}


/* ============ Site Footer ==================================================================
====================================================================================================*/

.siteFooter {
    position: fixed;
    bottom: 0;
    left: 230px; /* clear the left nav */
    right: 0;
    z-index: 50;
    background: #006242;
    display: flex;
    align-items: center;
    justify-content: center;
    border-top: 4px solid #006242;
    gap: 6px;
    padding: 14px 20px;
    font-family: 'effra', 'Effra', sans-serif;
    font-size: 11px;
    font-weight: 400;
    color: #ffffff;
    white-space: nowrap;
    box-shadow: 0px -6px 8px 0px #0000008a;
}

/* Right-anchored group: language switcher + Maison logo, sitting outside the
   centred footer text flow so the copyright line stays centred. */
.siteFooter__right {
    position: absolute;
    right: 20px;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    gap: 16px;
}

.siteFooter__brand {
    height: 36px;
    width: auto;
}

/* ---- Desktop language switcher (sliding pill) ----
   Horizontal curved-corner rectangle: thin white border, dark-green fill.
   A white "thumb" sits behind the labels and slides to the active language;
   active label = green-on-white, inactive = white-on-green. */
.langSwitch--footer {
    position: relative;
    display: inline-flex;
    align-items: stretch;
    border: 1px solid #ffffff;
    border-radius: 14px;
    background: #006242;
    overflow: hidden;
    flex-shrink: 0;
}
.langSwitch--footer .langSwitch__thumb {
    position: absolute;
    top: 0;
    left: 0;
    width: 50%;
    height: 100%;
    background: #ffffff;
    border-radius: 14px;
    transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 0;
}
body[data-lang="fr"] .langSwitch--footer .langSwitch__thumb {
    transform: translateX(100%);
}
.langSwitch--footer .langSwitch__btn {
    position: relative;
    z-index: 1;
    flex: 1 1 0;
    min-width: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 0;
    color: #ffffff;
    font-family: 'effra', 'Effra', sans-serif;
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.08em;
    line-height: 1;
    padding: 8px 14px;
    cursor: pointer;
    transition: color 0.3s ease;
}
.langSwitch--footer .langSwitch__btn.is-active {
    color: #006242;
    cursor: default;
}

.siteFooter__sep {
    opacity: 0.5;
    color: #ffffff;
}

.siteFooter__copy,
.siteFooter__powered {
    color: #ffffff;
}

.siteFooter a,
.siteFooter__link {
    color: #ffffff;
    text-decoration: none;
    transition: opacity 0.2s;
}

.siteFooter a:hover,
.siteFooter__link:hover {
    opacity: 0.75;
    text-decoration: none;
    color: #ffffff;
}

@media (max-width: 767px) {
    .siteFooter {
        display: none;
    }
}

/* ============ Policy Modals (Cookie Policy / Privacy Policy) ===============================
   Opened from the footer "Cookie Policy" and "Privacy Policy" links. Brand-green
   header, readable scrollable body. Shared styling via .policyModal / .policyDoc.
====================================================================================================*/

.policyModal .modal-content {
    border: 0;
    border-radius: 12px;
    overflow: hidden;
    font-family: 'effra', 'Effra', sans-serif;
}

.policyModal .modal-header {
    background: #006242; /* Pantone 3425 C — brand primary */
    color: #ffffff;
    border-bottom: 0;
    padding: 18px 24px;
}

.policyModal .modal-title {
    font-size: 20px;
    font-weight: 600;
    margin: 0;
    color: #ffffff;
}

.policyModal .btn-close {
    filter: invert(1) grayscale(1) brightness(2);
    opacity: 0.85;
}

.policyModal .btn-close:hover {
    opacity: 1;
}

.policyDoc {
    padding: 24px 28px;
    color: #2b2b2b;
    font-size: 14px;
    line-height: 1.6;
    /* Scroll the body when the policy is taller than the viewport allows.
       Backstops Bootstrap's .modal-dialog-scrollable in case a theme style
       interferes with it. */
    max-height: 70vh;
    overflow-y: auto;
}

.policyDoc h3 {
    font-size: 15px;
    font-weight: 600;
    color: #006242;
    margin: 22px 0 8px;
}

.policyDoc h3:first-child {
    margin-top: 0;
}

/* Sub-section heading (e.g. "1.1 Contact Information") */
.policyDoc h4 {
    font-size: 14px;
    font-weight: 600;
    color: #2b2b2b;
    margin: 14px 0 4px;
}

.policyDoc p {
    margin: 0 0 12px;
}

.policyDoc ul,
.policyDoc ol {
    margin: 0 0 12px;
    padding-left: 22px;
}

.policyDoc li {
    margin-bottom: 6px;
}

.policyDoc a {
    color: #006242;
    text-decoration: underline;
}

.policyDoc a:hover {
    color: #004d34;
}


/* ============ Roads Panel ==================================================================
====================================================================================================*/

#roadsPanel {
    position: absolute;
    top: 110px;
    right: 0;
    width: 280px;
    max-height: calc(100vh - 160px);
    background: rgba(255, 255, 255, 0.97);
    box-shadow: -6px 0 24px rgba(0, 0, 0, 0.12);
    border-radius: 10px 0 0 10px;
    transform: translateX(100%);
    transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 150;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

#roadsPanel.is-open {
    transform: translateX(0);
}

.roadsPanel__inner {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
}

.roadsPanel__header {
    position: relative;
    padding: 24px 24px 18px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.07);
    flex-shrink: 0;
}

.roadsPanel__close {
    position: absolute;
    top: 11px;
    right: 11px;
    width: 26px;
    height: 26px;
    background: none;
    border: none;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    font-weight: 300;
    line-height: 1;
    color: #666;
    cursor: pointer;
    transition: color 0.2s ease;
    padding: 0;
}

.roadsPanel__close:hover {
    color: var(--color-active);
}

.roadsPanel__title {
    font-size: 22px;
    font-weight: 600;
    color: #1c2920;
    margin: 0;
    line-height: 1.2;
    font-family: 'larken', 'Larken', serif;
}

.roadsPanel__list {
    list-style: none;
    padding: 0 0 13px; /* 13px + 11px item padding = 24px, matching header top */
    margin: 0;
    overflow-y: auto;
    overflow-x: hidden;
}

.roadsPanel__item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 11px 20px;
    cursor: pointer;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    transition: background-color 0.2s ease;
}

.roadsPanel__item:last-child {
    border-bottom: none;
}

.roadsPanel__item:hover,
.roadsPanel__item.is-active {
    background-color: rgba(0, 98, 66, 0.05);
}

/* Coloured dash indicator */
.roadsPanel__dash {
    flex-shrink: 0;
    width: 22px;
    height: 3px;
    border-radius: 2px;
    background: #ccc;
}

.roadsPanel__dash[data-color="white"]  { background: #bbb; }
.roadsPanel__dash[data-color="green"]  { background: #27ae60; }
.roadsPanel__dash[data-color="blue"]   { background: #2980b9; }
.roadsPanel__dash[data-color="red"]    { background: #c0392b; }
.roadsPanel__dash[data-color="yellow"] { background: #d4a017; }

.roadsPanel__name {
    font-size: 13px;
    font-weight: 500;
    color: #1c2920;
    line-height: 1.3;
}

/* ---- Road polylines on the map SVG ---- */

.roadLine {
    opacity: 0; /* JS sets opacity:1 directly — CSS keeps it hidden by default */
    stroke: #ffffff;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
    /* Fixed dashed pattern — shorter dash + bigger gap. The roadLine itself
       is NEVER animated; the road-reveal-<id> SVG mask wipes it on/off.
       6/5 reads as small dashes with airy gaps — feels more like road
       markings than a continuous dotted run. */
    stroke-dasharray: 6 5;
    /* Smooth stroke-colour transition so the yellow (Roads legend hover)
       eases back to white rather than snapping. */
    transition: stroke 0.5s ease;
}

/* Mask reveal stroke — black mask + white stroke along the path. JS sets
   stroke-dasharray + dashoffset = pixel length at animation time, then eases
   dashoffset to 0 to wipe the reveal across the path. Until then this stays
   opacity:0 / pre-wiped so the road appears hidden under a fully black mask. */
.roadMaskLine {
    /* Stroke colour is inlined as white on the polyline; nothing to do here. */
}

/* Road type → thickness (each ~2px thinner than the previous values) */
.roadLine[data-type="thin"]   { stroke-width: 0.6; }
.roadLine[data-type="medium"] { stroke-width: 1; }
.roadLine[data-type="thick"]  { stroke-width: 1.8; }

/* Road base — solid dark stroke that sits under every roadLine. Present
   from page load (no opacity/animation gating), giving the illusion of
   real tarmac with the animated white dashes drawn on top of it. Stroke
   widths are roadLine_width + 3px so the dashes always sit fully inside
   the base. */
.roadBase {
    stroke: #444444;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
    fill: none;
}

/* Invisible wide hit-target sitting on top of each road. Same path as the
   roadBase/roadLine (drawn after both so it sits on top for hit-testing),
   transparent stroke, but `pointer-events: stroke` means the stroke region
   still captures hover events — giving the user a much more forgiving
   target without changing the visible road thickness. */
.roadHit {
    stroke: transparent;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
    fill: none;
    pointer-events: stroke;
    cursor: pointer;
}
.roadHit[data-type="thin"]   { stroke-width: 12; }
.roadHit[data-type="medium"] { stroke-width: 14; }
.roadHit[data-type="thick"]  { stroke-width: 16; }
.roadBase[data-type="thin"]   { stroke-width: 4.6; }
.roadBase[data-type="medium"] { stroke-width: 5;   }
.roadBase[data-type="thick"]  { stroke-width: 5.8; }

/* Hover the Roads row in the legend → every existing roadLine smoothly
   shifts to bright yellow (the stroke transition on .roadLine handles the
   ease). Mouseout returns them to the default off-white. No flash, no
   clone overlay, no animation — pure colour swap. */
body[data-legend-hover="road"] .roadLine {
    stroke: #ffd60a !important;
}

/* Active road highlight is handled by a JS-created overlay polyline appended
   to #mainPageSvg — the original white roadLine is never modified */

/* Roads visible state — opacity is controlled entirely by JS (animateRoadDraw)
   so no CSS rule sets roadLine opacity:1 (that caused a flash before the animation) */

/* ============ Trails Legend Panel + dotted polylines =================================
   The Trails panel mirrors the Roads panel structurally but is a static legend:
   exactly two rows (yellow / orange), not clickable. Trails are rendered as
   dotted SVG polylines with spacing varying per `trail_color` and dot diameter
   per `trail_type`.
====================================================================================*/

#trailsPanel {
    position: absolute;
    top: 110px;
    right: 0;
    width: 280px;
    max-height: calc(100vh - 160px);
    background: rgba(255, 255, 255, 0.97);
    box-shadow: -6px 0 24px rgba(0, 0, 0, 0.12);
    border-radius: 10px 0 0 10px;
    transform: translateX(100%);
    transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 150;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

#trailsPanel.is-open {
    transform: translateX(0);
}

.trailsPanel__inner {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
}

.trailsPanel__header {
    position: relative;
    padding: 24px 24px 18px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.07);
    flex-shrink: 0;
}

.trailsPanel__close {
    position: absolute;
    top: 11px;
    right: 11px;
    width: 26px;
    height: 26px;
    background: none;
    border: none;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    font-weight: 300;
    line-height: 1;
    color: #666;
    cursor: pointer;
    transition: color 0.2s ease;
    padding: 0;
}

.trailsPanel__close:hover {
    color: var(--color-active);
}

.trailsPanel__title {
    font-size: 22px;
    font-weight: 600;
    color: #1c2920;
    margin: 0;
    line-height: 1.2;
    font-family: 'larken', 'Larken', serif;
}

.trailsPanel__list {
    list-style: none;
    padding: 0 0 13px; /* 13px + 11px item padding = 24px, matching header top */
    margin: 0;
    overflow-y: auto;
    overflow-x: hidden;
}

.trailsPanel__item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 11px 20px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    /* Static legend — not interactive */
    cursor: default;
}

.trailsPanel__item:last-child {
    border-bottom: none;
}

/* Dotted dash indicator — matches the on-map dot pattern per colour.
   Width 36px is chosen so 12px-spaced orange dots fit exactly 3 across,
   while 6px-spaced yellow shows 6. */
.trailsPanel__dash {
    flex-shrink: 0;
    width: 36px;
    height: 4px;
    background-image: radial-gradient(circle, currentColor 50%, transparent 52%);
    background-repeat: repeat-x;
    background-position: left center;
    background-size: 6px 4px;
    color: #f5c800;
}

.trailsPanel__dash[data-color="yellow"] {
    color: #f5c800;
    height: 5px;
    /* Square dashes to match the on-map stroke style */
    background-image: repeating-linear-gradient(
        90deg,
        currentColor 0,
        currentColor 6px,
        transparent 6px,
        transparent 10px
    );
    background-size: auto;
}

.trailsPanel__dash[data-color="orange"] {
    color: #e67e22;
    height: 7px;               /* match the heavier on-map dot */
    background-size: 12px 7px; /* a touch more spread — walking + cycling */
}

.trailsPanel__name {
    font-size: 13px;
    font-weight: 500;
    color: #1c2920;
    line-height: 1.3;
}

/* =============================================================================
   Legend Panel — colour-key sidebar shown when the Legend action button is on.
   Visually identical to the Trails panel; the only difference is that the
   indicators are solid circles instead of dotted dashes, since we're showing
   region fills rather than trail line styles. Colours map 1:1 to the polygon
   data-color values in style.css so the legend stays in sync with the map.
============================================================================= */
#legendPanel {
    position: absolute;
    top: 110px;
    right: 0;
    /* Narrower than the trails / POI panels — the legend rows are short
       labels so the previous 280px left a lot of dead space on the right. */
    width: 200px;
    max-height: calc(100vh - 160px);
    background: rgba(255, 255, 255, 0.97);
    box-shadow: -6px 0 24px rgba(0, 0, 0, 0.12);
    border-radius: 10px 0 0 10px;
    transform: translateX(100%);
    transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
    z-index: 150;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
#legendPanel.is-open { transform: translateX(0); }

.legendPanel__inner {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
}
.legendPanel__header {
    position: relative;
    padding: 24px 24px 18px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.07);
    flex-shrink: 0;
}
.legendPanel__close {
    position: absolute;
    top: 11px;
    right: 11px;
    width: 26px;
    height: 26px;
    background: none;
    border: none;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    font-weight: 300;
    line-height: 1;
    color: #666;
    cursor: pointer;
    transition: color 0.2s ease;
    padding: 0;
}
.legendPanel__close:hover { color: var(--color-active); }

.legendPanel__title {
    font-size: 22px;
    font-weight: 600;
    color: #1c2920;
    margin: 0;
    line-height: 1.2;
    font-family: 'larken', 'Larken', serif;
}

.legendPanel__list {
    list-style: none;
    padding: 0 0 13px;
    margin: 0;
    overflow-y: auto;
    overflow-x: hidden;
}
.legendPanel__item {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 11px 20px;
    border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    cursor: pointer; /* hover bumps matching polygons + dims the rest */
    transition: background 0.2s ease;
}
.legendPanel__item:hover {
    background: rgba(0, 0, 0, 0.04);
}
.legendPanel__item:last-child { border-bottom: none; }

/* Colour swatch — solid circle, ~18px so it reads clearly against the white
   panel without being chunky. Border keeps lighter colours (yellow,
   light-blue) visible against the white background. */
.legendPanel__dot {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    border: 1px solid rgba(0, 0, 0, 0.12);
}
/* Match the polygon data-color fills, but use solid (no-alpha) values so the
   swatch reads strongly on white. The hex values are the rgba() colours from
   .sectionOutline[data-color="..."] with the alpha removed. */
.legendPanel__dot[data-color="grey"]       { background: #697078; }
.legendPanel__dot[data-color="blue"]       { background: #5981C1; }
.legendPanel__dot[data-color="orange"]     { background: #F38453; }
.legendPanel__dot[data-color="yellow"]     { background: #CCDA33; }
.legendPanel__dot[data-color="light-blue"] { background: #F5C6A5; }
.legendPanel__dot[data-color="red"]        { background: #a52a30; }
.legendPanel__dot[data-color="green"]      { background: #3BAE49; }

/* Roads row — dashed line indicator (mirrors the on-map dashed road
   stroke). Same medium grey as the road's CSS stroke colour. */
.legendPanel__line {
    flex-shrink: 0;
    width: 22px;
    height: 0;
    border: 0;
    border-top: 2px dashed #777777;
}

.legendPanel__name {
    font-size: 13px;
    font-weight: 500;
    color: #1c2920;
    line-height: 1.3;
}

/* =============================================================================
   Legend hover-highlight — hovering a legend row temporarily fades every
   non-matching polygon down to 20% opacity while matching polygons keep
   their natural colour and stroke unchanged. JS sets body[data-legend-hover]
   on enter and clears it on leave; CSS does the rest declaratively.
============================================================================= */
body[data-legend-hover] .sectionOutline,
body[data-legend-hover] .label { transition: opacity 0.25s ease; }

/* Non-matching polygons + labels: drop to 20% opacity. We deliberately do
   NOT recolour them grey or touch the stroke — they keep their natural
   look, just faded. */
body[data-legend-hover="blue"]       .sectionOutline:not([data-color="blue"]),
body[data-legend-hover="orange"]     .sectionOutline:not([data-color="orange"]),
body[data-legend-hover="yellow"]     .sectionOutline:not([data-color="yellow"]),
body[data-legend-hover="light-blue"] .sectionOutline:not([data-color="light-blue"]),
body[data-legend-hover="green"]      .sectionOutline:not([data-color="green"]),
body[data-legend-hover="blue"]       .label:not([data-color="blue"]),
body[data-legend-hover="orange"]     .label:not([data-color="orange"]),
body[data-legend-hover="yellow"]     .label:not([data-color="yellow"]),
body[data-legend-hover="light-blue"] .label:not([data-color="light-blue"]),
body[data-legend-hover="green"]      .label:not([data-color="green"]) {
    opacity: 0.35;
}

/* Green Zone specifically — default has no stroke (so it reads as filled
   vegetation), but when the Green Zone legend row is hovered the matching
   greens pick up a white outline so they pop against the rest of the map. */
body[data-legend-hover="green"] .sectionOutline[data-color="green"] {
    stroke: #ffffff !important;
    stroke-width: 1.5;
}

/* ---- Trail polylines on the map SVG ---- */

.trailLine {
    opacity: 0; /* JS toggles via animateTrailDraw, mirroring roads */
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}

/* Stroke colour per trail_color */
.trailLine[data-color="yellow"] { stroke: #f5c800; }
.trailLine[data-color="orange"] { stroke: #e67e22; }

/* Stroke widths per trail_type (screen-pixel values via non-scaling-stroke). */
.trailLine[data-type="thin"]   { stroke-width: 2; }
.trailLine[data-type="medium"] { stroke-width: 3.5; }
.trailLine[data-type="thick"]  { stroke-width: 5.5; }

/* Yellow (walking only): square dashes — butt linecap gives flat rectangular
   ends; dasharray 6 4 = 6px dash / 4px gap. Slightly thicker than the base
   type values so the dashes read clearly at map scale. */
.trailLine[data-color="yellow"] {
    stroke-dasharray: 6 4;
    stroke-linecap: butt;
}
.trailLine[data-color="yellow"][data-type="thin"]   { stroke-width: 3; }
.trailLine[data-color="yellow"][data-type="medium"] { stroke-width: 5; }
.trailLine[data-color="yellow"][data-type="thick"]  { stroke-width: 7; }

/* Orange (walking + cycling): keep the original dot style, heavier weight. */
.trailLine[data-color="orange"] { stroke-dasharray: 0 10; }
.trailLine[data-color="orange"][data-type="thin"]   { stroke-width: 5; }
.trailLine[data-color="orange"][data-type="medium"] { stroke-width: 7; }
.trailLine[data-color="orange"][data-type="thick"]  { stroke-width: 10; }


/* ---- Road badge container — same coordinate space as #mapLabels / #mapPoiMarkers ---- */

#mapRoadBadges {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    aspect-ratio: 3201 / 2500;
    pointer-events: none;
    z-index: 145;
}

/* ---- Road badges ---- */

.road-badge {
    position: absolute;
    /* Badge sits above the pinned point; the ::after arrow tip lands exactly on it.
       Y offset uses `calc(-50% - (50% + 8px) * counter)` (same formula as the
       100% keyframe of roadBadgeBounceIn) so the arrow tip stays glued to the
       pin when the counter shrinks the badge on mobile zoom. At counter=1 this
       reduces to `-100% - 8px`. */
    transform: translate(-50%, calc(-50% - (50% + 8px) * var(--marker-counter, 1))) scale(var(--marker-counter, 1));
    padding: 1px 8px 0px;
    border-radius: 10px;
    background: #ffffff;
    border: 1.5px solid #ffffff;
    font-size: 10px;
    font-weight: 600;
    color: #006242;
    box-shadow: 0px 3px 5px 1px rgba(0,0,0,0.58);
    white-space: nowrap;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.4s ease;
    font-family: 'effra', 'Effra', sans-serif;
    /* drop-shadow covers both badge and ::after arrow as one unified shape */
    filter: drop-shadow(0 1px 5px rgba(0,0,0,0.28));
}

/* Downward-pointing arrow below the badge */
.road-badge::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 0px; /* slight overlap so no gap at badge border */
    width: 0;
    height: 0;
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;
    border-top: 8px solid #ffffff;
}

/* All road badges use the default white styling regardless of road colour */

/* Road badges bounce in after road draw animation completes.
   Triggered by JS adding .road-badges-visible to #mapRoadBadges.
   fill:both keeps them at opacity:1 after the animation so they stay visible. */

/* Road badges anchor by their ARROW TIP (bottom-center of the badge + 8px
   arrow border), not by their box center like the labels do. When we scale
   the badge by c the box shrinks around its center, so the bottom moves
   up by (1-c)·boxH/2 — the arrow tip drifts off the road. To compensate,
   the translate-Y also scales with c: the form `-50% - (50% + Npx) * c`
   keeps the scaled arrow tip pinned to the original anchor point. At c=1
   it reduces to the original `-100% - Npx`, so desktop is unchanged. The
   bounce overshoots (Npx values other than 8) scale with c too, so the
   bounce looks proportionally smaller when the badge is shrunk. */
@keyframes roadBadgeBounceIn {
    0%   { opacity: 0; transform: translate(-50%, calc(-50% - (50% + 20px) * var(--marker-counter, 1))) scale(var(--marker-counter, 1)); }
    55%  { opacity: 1; transform: translate(-50%, calc(-50% - (50% + 5px)  * var(--marker-counter, 1))) scale(var(--marker-counter, 1)); }
    75%  {             transform: translate(-50%, calc(-50% - (50% + 11px) * var(--marker-counter, 1))) scale(var(--marker-counter, 1)); }
    90%  {             transform: translate(-50%, calc(-50% - (50% + 6px)  * var(--marker-counter, 1))) scale(var(--marker-counter, 1)); }
    100% { opacity: 1; transform: translate(-50%, calc(-50% - (50% + 8px)  * var(--marker-counter, 1))) scale(var(--marker-counter, 1)); }
}

/* Road badges are hidden by default. They appear only when their matching
   .roadLine is hovered — the JS handler in custom.js adds .road-badge--hover
   to the badge whose data-road-id matches the hovered line. */
.road-badge.road-badge--hover {
    opacity: 1;
}








/* Intro Overlay + Brand Loader styles moved to assets/css/intro.css */

/* =====================================================================
   Polygon hover tooltip
===================================================================== */
.poly-tooltip {
    position: fixed;
    z-index: 99998;
    background: rgba(255, 255, 255, 0.93);
    color: #1a1a1a;
    font-family: 'effra', 'Effra', sans-serif;
    font-size: 9px;
    font-weight: 600;
    line-height: 1;
    letter-spacing: 0.04em;
    text-transform: capitalize;
    padding: 5px 9px 3px;
    border-radius: 4px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.22);
    pointer-events: none;
    white-space: nowrap;
    opacity: 0;
    transition: opacity 0.12s ease;
}

.poly-tooltip.is-visible {
    opacity: 1;
}

/* Mobile: never show the area hover tooltip. Touch fires the mouseenter that
   reveals it, so on a tap it pops up and overlays the area modal. Hiding the
   element keeps it out of the way regardless of the JS .is-visible toggle. */
@media (max-width: 767px) {
    .poly-tooltip {
        display: none !important;
    }
}

/* =====================================================================
   Le Parc Area Polygons
===================================================================== */
.lpSectionOutline {
    fill: rgba(0, 98, 66, 0.45);
    stroke: none;
    transition: fill 0.3s ease, opacity 0.3s ease;
}

.lpSectionOutline[data-color="blue"]       { fill: rgba(120, 160, 220, 0.30); }
.lpSectionOutline[data-color="green"]      {fill: rgba( 59, 174,  73, 0.35);}
.lpSectionOutline[data-color="dark-green"] { fill: rgba( 25, 135,  90, 0.30); }

.lpSectionOutline.is-hovered,
.lpSectionOutline:hover                             { fill: rgba( 25, 135,  90, 0.58); cursor: pointer; }
.lpSectionOutline[data-color="blue"].is-hovered,
.lpSectionOutline[data-color="blue"]:hover          { fill: rgba(120, 160, 220, 0.70); }
.lpSectionOutline[data-color="green"].is-hovered,
.lpSectionOutline[data-color="green"]:hover         { fill: rgba( 59, 174,  73, 0.70); }
.lpSectionOutline[data-color="dark-green"].is-hovered,
.lpSectionOutline[data-color="dark-green"]:hover    { fill: rgba( 25, 135,  90, 0.76); }

/* =====================================================================
   Le Parc Area Labels
===================================================================== */
#lpAreaLabels {
    position: absolute;
    top: 0; left: 0; width: 100%; height: 100%;
    pointer-events: none;
    z-index: 125;
}

#lpAreaLabels .label {
    opacity: 0;
    pointer-events: none;
    /* Hidden by default — JS adds .is-hovered when the matching polygon is
       hovered, which bounces the label in. Default white background + brand
       green text (the user's request). */
    background: #ffffff;
    color: #006242;
}

/* `.label--always` (added in page-le-parc.php for any Le Parc area that has
   no polygon shapes) stays permanently visible — used for the overarching
   "Le Parc" title label which has no polygon to hover. Sized larger than
   the hover-only area labels so it reads as a primary heading on the map. */
#lpAreaLabels .label.label--always {
    opacity: 1;
    /* Fades in (via inline opacity set in JS) the moment the boundary outline
       draw animation starts — see the outline script in page-le-parc.php. */
    transition: opacity 0.6s ease;
    font-size: 32px;
    font-weight: 700;
    padding: 14px 28px;
    border-radius: 30px;
    letter-spacing: 0.02em;
}
/* Clickable always-visible labels need pointer-events restored (the base
   #lpAreaLabels .label rule sets pointer-events: none for hover-only
   labels). Without this the always-visible label can't receive clicks. */
#lpAreaLabels .label.label--clickable {
    pointer-events: auto;
    cursor: pointer;
}
#lpAreaLabels .label::after {
    /* Speech-bubble tail — white to match the label background. */
    border-top-color: #ffffff;
}

/* Hover: bounce in, stay opaque. The animation provides both the visual
   pop AND the opacity transition, so no separate opacity rule is needed.
   pointer-events stays at the parent's `none` so the cursor passes through
   the label and continues to hit the polygon underneath — otherwise the
   moment the label tracks under the cursor we'd lose the polygon hover
   and the label would flicker on/off. Clickable labels (.label--clickable)
   re-enable pointer-events via the rule above, which has the same
   specificity but comes earlier in source — so we leave their behaviour
   alone with an explicit guard. */
#lpAreaLabels .label.is-hovered:not(.label--clickable) {
    animation: labelBounceIn 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both;
    pointer-events: none;
    background: #ffffff;
    color: #006242;
}
#lpAreaLabels .label.is-hovered.label--clickable {
    animation: labelBounceIn 0.45s cubic-bezier(0.34, 1.56, 0.64, 1) both;
    background: #ffffff;
    color: #006242;
}
#lpAreaLabels .label.is-hovered::after {
    border-top-color: #ffffff;
}


/* ============ Mobile bottom-sheet panels =========================================================
   On phones the POI / Trails / Roads / Legend popups sit above the bottom
   nav (which is 48px) as full-width sheets with curved top corners. They
   slide in from the bottom and start collapsed — only the header is
   visible. Tapping the header toggles .is-expanded which raises the sheet
   to nearly fill the area below the 76px top header. The close × button
   removes both .is-open and .is-expanded via the JS handlers in custom.js.
====================================================================================================*/

@media (max-width: 767px) {
    /* Clip closed/translated panels so they don't leak into the body's
       scrollable area (was causing scroll-down to reveal hidden panel
       headers below the nav). The map's own scroll lives on .outerMainWrap
       so this doesn't affect panning. */
    .mainWrap {
        overflow: hidden;
    }

    #poiPanel,
    #trailsPanel,
    #roadsPanel,
    #legendPanel {
        top: auto;
        /* bottom:0 inside .mainWrap, which already ends 48px above the
           viewport bottom (calc(100% - 76px - 48px)) — so the sheet sits
           directly above the bottom nav with no extra offset needed. */
        bottom: 0;
        left: 0;
        right: 0;
        width: 100%;
        max-width: none;
        height: auto;
        /* Collapsed cap: just the header is visible. The body below is
           still in flow (so max-height can smoothly animate it open and
           closed), but clipped by max-height + overflow: hidden.
           Sized to fit the Trails/Legend headers exactly; POI's subtitle
           gets clipped slightly — acceptable per design call. */
        max-height: 70px;
        border-radius: 16px 16px 0 0;
        box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.18);
        transform: translateY(100%);
        transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1),
                    max-height 0.4s cubic-bezier(0.4, 0, 0.2, 1),
                    height 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        overflow: hidden;
    }
    #poiPanel.is-open,
    #trailsPanel.is-open,
    #roadsPanel.is-open,
    #legendPanel.is-open {
        transform: translateY(0);
    }

    /* Expanded — short panels size to their content, capped at 60vh.
       Animate by raising max-height; height stays auto so the panel still
       fits its (short) content list. */
    #trailsPanel.is-expanded,
    #roadsPanel.is-expanded,
    #legendPanel.is-expanded {
        max-height: 60vh;
    }
    /* POI needs a definite height (not auto) — its list↔detail slide
       relies on a fixed-height container, and content-driven sizing made
       the panel resize when toggling detail/back. Setting both height and
       max-height to 60vh gives a smooth animation since the collapsed
       state is height: auto + max-height: 90px and we transition both. */
    #poiPanel {
        /* Definite collapsed height so the height transition has two
           explicit endpoints (auto → 60vh wouldn't animate). */
        height: 70px;
    }
    #poiPanel.is-expanded {
        height: 60vh;
        max-height: 60vh;
    }

    /* Body sections stay rendered + visible so the content gets clipped
       progressively by the panel's shrinking max-height/height instead of
       vanishing instantly at the start of the collapse. pointer-events
       are guarded so the hidden-clipped portion can't be tapped while
       collapsed, but visibility stays `visible` throughout. */
    #poiPanel:not(.is-expanded) .poiPanel__views,
    #trailsPanel:not(.is-expanded) .trailsPanel__list,
    #roadsPanel:not(.is-expanded) .roadsPanel__list,
    #legendPanel:not(.is-expanded) .legendPanel__list {
        pointer-events: none;
    }

    /* Header is the tap target for expand/collapse on mobile. */
    .poiPanel__header,
    .trailsPanel__header,
    .roadsPanel__header,
    .legendPanel__header {
        cursor: pointer;
    }

    /* Slightly smaller panel titles on mobile to save vertical space. */
    .poiPanel__title,
    .trailsPanel__title,
    .roadsPanel__title,
    .legendPanel__title {
        font-size: 20px;
    }

    /* Tiny "Tap to expand / shrink" hint at the top-center of each panel
       header. Swaps copy via the parent panel's .is-expanded state. */
    .poiPanel__header::before,
    .trailsPanel__header::before,
    .roadsPanel__header::before,
    .legendPanel__header::before {
        content: "Tap to expand";
        position: absolute;
        top: 6px;
        left: 50%;
        transform: translateX(-50%);
        font-size: 10px;
        font-weight: 400;
        letter-spacing: 0.5px;
        color: rgba(0, 0, 0, 0.35);
        pointer-events: none;
        /* Double caret (two ^ stacked) flanking the text on each side */
        padding: 0 16px;
        background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='10'%20height='12'%20viewBox='0%200%2010%2012'%3E%3Cg%20fill='none'%20stroke='%23a6a6a6'%20stroke-width='1.3'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M1.5%205%20L5%201.5%20L8.5%205'/%3E%3Cpath%20d='M1.5%209.5%20L5%206%20L8.5%209.5'/%3E%3C/g%3E%3C/svg%3E"),
                          url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='10'%20height='12'%20viewBox='0%200%2010%2012'%3E%3Cg%20fill='none'%20stroke='%23a6a6a6'%20stroke-width='1.3'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M1.5%205%20L5%201.5%20L8.5%205'/%3E%3Cpath%20d='M1.5%209.5%20L5%206%20L8.5%209.5'/%3E%3C/g%3E%3C/svg%3E");
        background-repeat: no-repeat, no-repeat;
        background-position: left center, right center;
        background-size: 9px 11px;
    }
    #poiPanel.is-expanded .poiPanel__header::before,
    #trailsPanel.is-expanded .trailsPanel__header::before,
    #roadsPanel.is-expanded .roadsPanel__header::before,
    #legendPanel.is-expanded .legendPanel__header::before {
        content: "Tap to shrink";
        /* Flip the carets to point down when expanded */
        background-image: url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='10'%20height='12'%20viewBox='0%200%2010%2012'%3E%3Cg%20fill='none'%20stroke='%23a6a6a6'%20stroke-width='1.3'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M1.5%203%20L5%206.5%20L8.5%203'/%3E%3Cpath%20d='M1.5%207.5%20L5%2011%20L8.5%207.5'/%3E%3C/g%3E%3C/svg%3E"),
                          url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='10'%20height='12'%20viewBox='0%200%2010%2012'%3E%3Cg%20fill='none'%20stroke='%23a6a6a6'%20stroke-width='1.3'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M1.5%203%20L5%206.5%20L8.5%203'/%3E%3Cpath%20d='M1.5%207.5%20L5%2011%20L8.5%207.5'/%3E%3C/g%3E%3C/svg%3E");
    }

    /* Larger close × hit target on mobile — easier to tap than the
       26px desktop default. Top is set so the 40px button's vertical
       centre lines up with the 22px title text inside the header (the
       title sits ~37px down from the top of the header given its 24px
       padding-top and ~26px line-height: 1.2; placing the button at
       top:17px puts its centre at 17 + 20 = 37px, in line with the
       title). */
    .poiPanel__close,
    .trailsPanel__close,
    .roadsPanel__close,
    .legendPanel__close {
        width: 40px;
        height: 40px;
        top: 17px;
        right: 8px;
        font-size: 32px;
    }

    /* Legend has no close × on mobile — the only way to dismiss it is to
       tap its header to collapse (or to pick another filter). */
    .legendPanel__close {
        display: none;
    }
}

