/* ═══════════════════════════════════════════════════════════════
   EGYPT MAGIC MAP DESIGN SYSTEM
   One component, three contexts: the tour journey map, the single
   destination map and the destinations archive. Same markers, same card,
   same gestures, same animation — only the card's content differs.
   Loaded only on a single tour that has something to plot, and only ever
   scoped to .em-mapframe. Nothing here can reach the destinations map,
   which is a separate, working component.
   Tokens only — no new colours are introduced.
   ═══════════════════════════════════════════════════════════════ */

/* ── Section shell ─────────────────────────────────────────────
   Moved here from tours.css with the rest of the component. */
.em-tour-map-sec { margin: 2.6rem 0 0; }
.em-tour-map__lede { color: var(--em-muted); margin: 0 0 1rem; }

.em-mapframe {
  position: relative;
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--em-hair, rgba(28,24,19,.12));
  box-shadow: 0 10px 30px -18px rgba(28,24,19,.45);
  background: var(--em-bg2);
}

/* Place names docked onto the frame, so the section reads as one component
   rather than a map with a list stranded beneath it. This list is the
   non-JS and crawler-visible content of the section — never remove it. */
.em-mapframe .em-tour-map__list {
  list-style: none;
  margin: 0;
  padding: .85rem 1.1rem;
  display: flex;
  flex-wrap: wrap;
  gap: .45rem 1.3rem;
  background: color-mix(in srgb, var(--em-bg) 92%, transparent);
  border-top: 1px solid var(--em-hair, rgba(28,24,19,.12));
}
.em-tour-map__list li {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  color: var(--em-muted);
  font-size: .92rem;
}
.em-tour-map__list svg { color: var(--em-gold); flex: none; }
.em-tour-map__list a {
  color: var(--em-ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.em-tour-map__list a:hover { border-bottom-color: var(--em-gold); }

/* Leaflet's own chrome, brought into the palette. Scoped to .em-tour-map so
   the destinations map — which scopes its own rules under its body class —
   is untouched. */
.em-tour-map .leaflet-control-zoom a,
.em-map .leaflet-control-zoom a {
  color: var(--em-ink);
  border-color: var(--em-hair, rgba(28,24,19,.12));
}
.em-tour-map .leaflet-control-attribution,
.em-map .leaflet-control-attribution {
  background: rgba(255,255,255,.78);
  font-size: 10px;
}

/* ── Map heights: four documented variants, one language ───────
   Every map reserves its height before Leaflet initialises — that is what
   holds CLS at zero — and all four use the same clamp(min, vh, max) shape so
   they read as one system rather than three unrelated rules.

     journey / tour   clamp(320px, 46vh, 460px)   a route needs vertical room
     discovery        clamp(360px, 52vh, 560px)   archive + homepage: the map
                                                   IS the section, so it leads
     single place     clamp(300px, 40vh, 420px)   supporting a page, not
                                                   leading it
   Deliberately not identical: a country-wide discovery map and a single-pin
   locator have different jobs. */
.em-mapframe .em-tour-map {
  /* The 320px floor was a zoom cliff. At 1024x768 the map computed to 46vh =
     353px, which leaves 309px inside the 22px route padding — and this
     journey needs 318px to hold zoom 7. Nine pixels short, so fitBounds fell
     to zoom 6 and framed Saudi Arabia around a tiny route. The floor now
     clears that threshold on every short viewport. Width is untouched: the
     map stays full-width. */
  height: clamp(400px, 46vh, 460px);
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: var(--em-bg2);
}

.em-tour-map .leaflet-container,
.em-map .leaflet-container { font-family: var(--em-font-body); }

/* A barely-there lift on the TILES ONLY — never the whole map, so markers,
   route, labels and controls keep their exact designed colours.
   Measured by eye against three stronger candidates: saturate(1.30) began
   yellowing the roads and saturate(1.45) looked tinted rather than sunny.
   Voyager's own palette is doing the work; this only warms the sea a little. */
/* Terrain only. The label tiles live on their own pane (see em-map.js) and
   are deliberately NOT in this selector, so the sea can be pushed to a real
   blue while every place name stays exactly as CARTO drew it — which is the
   objection that rules out filtering a normal single-layer basemap.

   Judged by eye against four stronger candidates: 1.45 was still timid, 1.9
   started tinting the roads, and 2.2 turned the Red Sea neon and the roads
   yellow — the "rainbow map" the brief forbids. 1.7 is where the water reads
   as sea and the desert as sand. */
.em-tour-map .leaflet-tile-pane,
.em-map .leaflet-tile-pane { filter: saturate(1.7) contrast(1.06) brightness(1.03); }
.em-tour-map .leaflet-pane--emLabels,
.em-map .leaflet-pane--emLabels { filter: none; }

/* ── Markers ───────────────────────────────────────────────────
   Three silhouettes, so the journey reads before anything is clicked and
   without depending on colour alone:
     origin      teal-ringed white core, gently pulsing — "you start here"
     stop        small numbered gold disc — 1, 2, 3 in journey order
     destination gold teardrop, the heaviest mark on the map
     single      the same teardrop, for a tour with one location
   ─────────────────────────────────────────────────────────────── */
/* The pin's box is the mark alone; the label hangs below it, outside the
   box and out of the hit test, so two nearby pins never block each other. */
.em-mpin {
  position: relative;
  display: block;
  pointer-events: none;
}

.em-mpin__mark {
  position: relative;
  display: grid;
  place-items: center;
  transition: transform .28s var(--em-ease), filter .28s var(--em-ease);
  transform-origin: 50% 100%;
}

/* ── Teardrop (destination / single) ── */
.em-mpin__pin {
  display: block;
  filter: drop-shadow(0 6px 10px rgba(28,24,19,.34));
}
.em-mpin__pinbody {
  fill: var(--em-gold-d);
  stroke: #fff;
  stroke-width: 2.2;
}
.em-mpin__pineye { fill: #fff; }
.em-mpin--single .em-mpin__pinbody { fill: var(--em-gold); }

/* ── Origin ring ── */
.em-mpin__ring {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: #fff;
  border: 3px solid var(--em-teal);
  box-shadow: 0 4px 10px rgba(28,24,19,.3);
}
.em-mpin__core {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: var(--em-teal);
}

/* ── Numbered stop ── */
.em-mpin__disc {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--em-gold);
  border: 2.5px solid #fff;
  box-shadow: 0 3px 9px rgba(28,24,19,.32);
  color: #fff;
  font-family: var(--em-font-head);
  font-size: .72rem;
  font-weight: 600;
  line-height: 1;
}

/* Radar ring — the two ends of the journey only, and only while the map is
   on screen. A pulse nobody can see is battery spent for nothing. */
.em-mpin__pulse {
  position: absolute;
  top: 50%; left: 50%;
  width: 26px; height: 26px;
  margin: -13px 0 0 -13px;
  border-radius: 50%;
  opacity: 0;
}
.em-mpin--origin .em-mpin__pulse { background: var(--em-teal); }
.em-mpin--destination .em-mpin__pulse,
.em-mpin--single .em-mpin__pulse { background: var(--em-gold); }
/* the teardrop's visual centre is its eye, not the middle of the box */
.em-mpin--destination .em-mpin__pulse,
.em-mpin--single .em-mpin__pulse { top: 16px; }

.is-onscreen .em-mpin--origin .em-mpin__pulse,
.is-onscreen .em-mpin--destination .em-mpin__pulse,
.is-onscreen .em-mpin--single .em-mpin__pulse {
  animation: em-mpin-pulse 3s var(--em-ease) infinite;
}
@keyframes em-mpin-pulse {
  0%   { transform: scale(.65); opacity: .34; }
  70%  { transform: scale(2.5); opacity: 0; }
  100% { transform: scale(2.5); opacity: 0; }
}

.em-mpin__label {
  position: absolute;
  top: calc(100% + 2px);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  max-width: 152px;
  padding: 2px 9px;
  border-radius: 999px;
  background: rgba(255,255,255,.95);
  border: 1px solid var(--em-hair, rgba(28,24,19,.12));
  box-shadow: 0 2px 6px rgba(28,24,19,.14);
  color: var(--em-ink);
  font-family: var(--em-font-head);
  font-size: .68rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: background .25s var(--em-ease), color .25s var(--em-ease);
}
.em-mpin__label:empty { display: none; }

/* ── Destination pin: the count is the message ─────────────────
   A destination marker answers "how much is there?" before it is clicked.
   Bigger than a journey pin because it has to hold a two-digit number at
   country zoom. */
.em-mpin--dest .em-mpin__pinbody {
  fill: var(--em-gold);
  stroke: #fff;
  stroke-width: 2.6;
}
.em-mpin--dest .em-mpin__pin {
  filter: drop-shadow(0 7px 12px rgba(28,24,19,.38));
}
/* The number is an SVG <text> inside the pin, so it is filled, not coloured. */
.em-mpin__num {
  fill: #fff;
  font-family: var(--em-font-head), sans-serif;
  font-size: 17px;
  font-weight: 600;
  letter-spacing: -.02em;
  paint-order: stroke;
}
.em-mpin--dest .em-mpin__pulse {
  top: 21px;
  background: var(--em-gold);
}
.leaflet-marker-icon.is-active .em-mpin--dest .em-mpin__pinbody { fill: var(--em-gold-d); }

/* A search hit gets a short, obvious highlight rather than a permanent one:
   it is telling you where to look, not marking a state. */
.leaflet-marker-icon.is-hit .em-mpin__mark { animation: em-hit 1.1s var(--em-ease) 2; }
@keyframes em-hit {
  0%, 100% { transform: none; }
  40%      { transform: translateY(-7px) scale(1.16); }
}

/* Filtered out: dimmed rather than deleted, so the map does not appear to
   lose places that still exist. */
.leaflet-marker-icon.is-muted { opacity: .28; filter: grayscale(.55); }
.leaflet-marker-icon.is-muted .em-mpin__pulse { animation: none !important; }

/* ── States ── */
.leaflet-marker-icon:hover .em-mpin__mark,
.leaflet-marker-icon:focus-visible .em-mpin__mark {
  transform: translateY(-3px) scale(1.09);
}
.leaflet-marker-icon.is-active .em-mpin__mark {
  transform: translateY(-4px) scale(1.16);
  filter: drop-shadow(0 10px 16px rgba(28,24,19,.4));
}
.leaflet-marker-icon.is-active .em-mpin__label {
  background: var(--em-ink);
  border-color: var(--em-ink);
  color: #fff;
}
/* halo on the selected mark, so the card and its pin read as one thing */
.leaflet-marker-icon.is-active .em-mpin__mark::after {
  content: "";
  position: absolute;
  top: 50%; left: 50%;
  width: 46px; height: 46px;
  margin: -23px 0 0 -23px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(192,136,58,.34) 0%, rgba(192,136,58,0) 70%);
  z-index: -1;
}
.leaflet-marker-icon:focus-visible {
  outline: 3px solid var(--em-gold);
  outline-offset: 4px;
  border-radius: 14px;
}

/* ── Entrance ──
   Applied ONLY under .is-sequencing, which JS sets when there is a journey
   to sequence and motion is allowed. No class = always visible, so a
   single-pin tour and a reduced-motion visitor never lose their marker. */
/* NEVER animate .leaflet-marker-icon itself: Leaflet positions every marker
   with a transform on exactly that element, so animating it moves the pin off
   its coordinate. The inner span is ours to move. */
.is-sequencing .leaflet-marker-icon:not(.is-in) .em-mpin { opacity: 0; }
.is-sequencing .leaflet-marker-icon.is-in .em-mpin {
  animation: em-mpin-in .5s var(--em-ease) both;
}
@keyframes em-mpin-in {
  from { opacity: 0; transform: translateY(-10px) scale(.8); }
  to   { opacity: 1; transform: none; }
}

/* ── Route ────────────────────────────────────────────────────
   Casing under line under travelling glow. The line is what the reveal
   draws; the glow is the part that says "travel" rather than "geometry". */
/* A WHITE casing under a #a06f28 core, on a #f4ece0 desert, is three light
   values stacked — measured as a flat tan bar on the live map, and it gave
   the travelling highlight nothing to be brighter than. Dark casing carries
   the contrast, the gold core carries the brand, and the white glow now has
   somewhere to show. */
.em-route--case { stroke: rgba(22,19,13,.86); }
.em-route--line { stroke: var(--em-gold); }
.em-route--sea  { stroke: var(--em-teal); stroke-dasharray: 1 10; stroke-linecap: round; }
.em-route--air  { stroke: var(--em-muted); stroke-dasharray: 11 9; }

.em-route--line.is-drawing {
  stroke-dasharray: var(--em-route-len);
  stroke-dashoffset: var(--em-route-len);
  animation: em-route-draw 1.4s var(--em-ease) forwards;
}
@keyframes em-route-draw { to { stroke-dashoffset: 0; } }

.em-route--line.is-drawn,
.em-route--line.is-static { stroke-dasharray: none; stroke-dashoffset: 0; }
.em-route--sea.is-drawn,
.em-route--sea.is-static { stroke-dasharray: 1 10; }
.em-route--air.is-drawn,
.em-route--air.is-static { stroke-dasharray: 11 9; }

/* One short lit dash chasing a very long gap = exactly one highlight on the
   line at a time, travelling origin -> destination. Hidden until the draw
   finishes, and paused whenever the map is off screen. */
.em-route--glow {
  stroke: #fff;
  opacity: 0;
  stroke-dasharray: var(--em-glow-dash, 40) var(--em-route-len, 4000);
}
.em-route--glow.is-travelling {
  opacity: .85;
  stroke-dashoffset: var(--em-route-len);
  animation: em-route-travel var(--em-glow-dur, 6s) linear infinite;
}
.em-mapframe:not(.is-onscreen) .em-route--glow.is-travelling {
  animation-play-state: paused;
}
@keyframes em-route-travel { to { stroke-dashoffset: 0; } }

/* ── Compact markers (<=768) ───────────────────────────────────
   The pin box is scaled in JS so the anchor stays on its coordinate; these
   rules keep the CONTENT legible at the smaller size — the count is the whole
   point of the marker and must never become a smudge. */
/* --em-pin-k is written by the engine (1, 0.8 or 0.64) so the CSS-sized parts
   shrink by exactly the same factor as the SVG artwork and the icon box. */
.em-destpin-icon.is-compact .em-mpin__count {
  font-size: calc(.86rem * var(--em-pin-k, 1));
}
.is-compact .em-mpin__ring {
  width: calc(26px * var(--em-pin-k, 1));
  height: calc(26px * var(--em-pin-k, 1));
  border-width: calc(3px * var(--em-pin-k, 1));
}
.is-compact .em-mpin__core {
  width: calc(9px * var(--em-pin-k, 1));
  height: calc(9px * var(--em-pin-k, 1));
}
.is-compact .em-mpin__disc {
  width: calc(24px * var(--em-pin-k, 1));
  height: calc(24px * var(--em-pin-k, 1));
  font-size: calc(.72rem * var(--em-pin-k, 1));
  border-width: 2px;
}
.is-compact .em-mpin__label {
  font-size: .6rem;
  max-width: 104px;
  padding: 1px 6px;
}
.is-compact .em-mpin__pin { filter: drop-shadow(0 4px 7px rgba(28,24,19,.32)); }

/* ── Direction chevrons ────────────────────────────────────────
   Decoration on the line: they say which way the journey runs. Kept out of
   the tab order and out of the accessibility tree — the same information is
   in the "Hurghada → Luxor → Aswan" lede above the map. */
/* A white disc with a gold chevron, not a bare white stroke: at 13px a plain
   chevron on a gold line was almost invisible in the screenshots. The disc
   gives it a ground to read against at any zoom. */
/* The arrowhead sits ON the route. White disc + grey chevron read as a
   decorative dot at map scale and left the direction of travel ambiguous —
   the one thing the line most needs to say. */
.em-chev {
  display: grid;
  place-items: center;
  width: 22px; height: 22px;
  color: #fff;
  filter: drop-shadow(0 1px 2px rgba(28,24,19,.55));
  pointer-events: none;
}
.em-chev svg { width: 15px; height: 15px; margin-inline-start: 1px; }

/* ── Journey badge on the route ────────────────────────────────
   States the journey's facts on the line itself instead of hiding them
   behind a hover, which on a touch screen is a fact nobody ever reads. */
.em-jbadge {
  position: absolute;
  left: 0; top: 0;
  transform: translate(-50%, -50%);
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .3rem .7rem;
  border-radius: 999px;
  background: var(--em-ink);
  color: #fff;
  font-family: var(--em-font-head);
  font-size: .68rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 3px 10px rgba(28,24,19,.35);
  pointer-events: none;
}
.em-jbadge i {
  width: 3px; height: 3px;
  border-radius: 50%;
  background: var(--em-gold);
  display: block;
  flex: none;
}

/* ── Journey facts ─────────────────────────────────────────────
   Docked on the frame, server-rendered. Only facts that exist are printed —
   there is no placeholder for a duration we do not have. */
/* One footer bar under the map: facts on one side, place names on the other.
   Flow content, so it can never overlap the map or the list — the first
   version was absolutely positioned and landed on top of the place names. */
.em-map-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: .5rem 1.2rem;
  padding: .8rem 1.1rem;
  background: color-mix(in srgb, var(--em-bg) 92%, transparent);
  border-top: 1px solid var(--em-hair, rgba(28,24,19,.12));
}
.em-map-footer .em-tour-map__list {
  padding: 0;
  background: none;
  border-top: 0;
  flex: 1 1 auto;
}

.em-journey {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
  order: 2;
}
.em-journey__item {
  display: inline-flex;
  align-items: center;
  gap: .38rem;
  padding: .34rem .7rem;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--em-hair, rgba(28,24,19,.12));
  box-shadow: 0 2px 8px rgba(28,24,19,.14);
  color: var(--em-ink);
  font-family: var(--em-font-head);
  font-size: .72rem;
  letter-spacing: .05em;
  text-transform: uppercase;
  white-space: nowrap;
}
.em-journey__item svg { color: var(--em-gold-d); flex: none; }

/* ── Legend ────────────────────────────────────────────────────── */
/* Opposite corner from Leaflet's zoom control, which sits top-left in LTR and
   is flipped to top-right in RTL by the rule further down — so a logical
   inset-inline-end keeps the two apart in both directions. Measured
   collision before this: legend x=113 vs zoom x=111. */
.em-map-legend {
  position: absolute;
  inset-block-start: 12px;
  inset-inline-end: 12px;
  /* Leaflet's own control containers are z-index 1000 and its marker pane is
     600, so anything below 1000 can be painted over by the map's chrome. */
  z-index: 1000;
  display: flex;
  gap: .8rem;
  padding: .4rem .7rem;
  border-radius: 999px;
  background: rgba(255,255,255,.92);
  border: 1px solid var(--em-hair, rgba(28,24,19,.12));
  font-size: .7rem;
  color: var(--em-muted);
  pointer-events: none;
}
.em-map-legend span { display: inline-flex; align-items: center; gap: .32rem; }
.em-map-legend i {
  width: 9px; height: 9px; border-radius: 50%; display: block;
  background: var(--em-gold);
}
.em-map-legend .em-lg--origin i { background: #fff; border: 2px solid var(--em-teal); }
.em-map-legend .em-lg--dest i   { background: var(--em-gold-d); }

/* ── Touch hint ────────────────────────────────────────────────── */
.em-map-hint {
  position: absolute;
  inset-block-end: 12px;
  inset-inline-start: 12px;
  z-index: 1000;
  padding: .38rem .7rem;
  border-radius: 999px;
  background: rgba(28,24,19,.72);
  color: #fff;
  font-size: .7rem;
  pointer-events: none;
}

/* ── Information card ──────────────────────────────────────────
   Our own DOM, not L.popup — which is also why the CTA can never inherit
   Leaflet's link blue again. */
/* The card is a part of the map, not an overlay dropped on top of it: it is
   capped to the frame and scrolls internally. Measured before this: a 488px
   card inside a 420px frame on a single-destination page, spilling over the
   facts row and colliding with the explorer trigger. */
.em-mapcard {
  position: absolute;
  max-height: calc(100% - 28px);
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Above Leaflet's control containers (z-index 1000) — at 900 the
     attribution printed straight through the bottom sheet's text. */
  z-index: 1100;
  inset-block-end: 16px;
  inset-inline-start: 16px;
  width: min(320px, calc(100% - 32px));
  background: #fff;
  border: 1px solid var(--em-hair, rgba(28,24,19,.12));
  border-radius: 14px;
  box-shadow: 0 18px 40px -22px rgba(28,24,19,.6);
  overflow: hidden;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity .22s var(--em-ease), transform .22s var(--em-ease);
}
.em-mapcard.is-open { opacity: 1; transform: none; }
.em-mapcard[hidden] { display: none; }

.em-mapcard__media { display: block; background: var(--em-bg2); }
.em-mapcard__media img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}
.em-mapcard__body { padding: .9rem 1rem 1rem; }

.em-mapcard__role {
  display: inline-block;
  margin: 0 0 .3rem;
  font-family: var(--em-font-head);
  font-size: .64rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--em-gold-d);
}
.em-mapcard__role--origin { color: var(--em-teal); }

.em-mapcard__name {
  margin: 0;
  font-family: var(--em-font-head);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--em-ink);
}
.em-mapcard__desc {
  margin: .4rem 0 0;
  font-size: .88rem;
  line-height: 1.45;
  color: var(--em-muted);
}
.em-mapcard__meta {
  margin: .5rem 0 0;
  font-size: .8rem;
  color: var(--em-muted);
}
/* ── Destination card: the tours you can book here ─────────────
   A destination pin answers "what can I do here?", so its card is a short,
   clickable list of real tours. Nothing is padded out: a destination with
   one tour shows one. */
.em-mapcard__count {
  display: block;
  margin: .12rem 0 .35rem;
  font-family: var(--em-font-head);
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--em-gold-d);
}

.em-mapcard__tours {
  display: grid;
  gap: .4rem;
  margin: .6rem 0 0;
}
.em-maptour {
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .35rem;
  border-radius: 10px;
  text-decoration: none;
  color: inherit;
  transition: background .2s var(--em-ease);
}
.em-maptour:hover { background: var(--em-bg2); }
.em-maptour:focus-visible { outline: 3px solid var(--em-gold); outline-offset: 1px; }
.em-maptour__img {
  width: 46px; height: 46px;
  border-radius: 8px;
  object-fit: cover;
  flex: none;
  background: var(--em-bg2);
}
.em-maptour__body { display: grid; gap: 1px; min-width: 0; }
.em-maptour__title {
  font-family: var(--em-font-head);
  font-size: .88rem;
  font-weight: 600;
  color: var(--em-ink);
  line-height: 1.15;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.em-maptour__meta { font-size: .74rem; color: var(--em-muted); }

/* ── Card facts + booking CTA ─────────────────────────────────
   The card's job on a tour page is to turn interest in a place into a
   booking, so price and the primary CTA carry the visual weight. */
.em-mapcard__facts {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .45rem .9rem;
  margin: .65rem 0 0;
}
.em-mapcard__price {
  font-family: var(--em-font-head);
  font-size: 1.24rem;
  font-weight: 600;
  color: var(--em-ink);
  line-height: 1;
}
.em-mapcard__price--req { font-size: .96rem; color: var(--em-muted); }
.em-mapcard__from {
  font-size: .64rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--em-muted);
  margin-inline-end: .18rem;
}
.em-mapcard__fact {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  font-size: .8rem;
  color: var(--em-muted);
}
.em-mapcard__fact svg { color: var(--em-gold-d); flex: none; }

.em-mapcard__book {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  margin: .8rem 0 0;
  padding: .62rem 1rem;
  border-radius: 999px;
  background: var(--em-gold);
  color: #fff;
  font-family: var(--em-font-head);
  font-size: .8rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  transition: background .25s var(--em-ease), transform .25s var(--em-ease);
}
.em-mapcard__book:hover { background: var(--em-gold-d); transform: translateY(-1px); }
.em-mapcard__book:focus-visible { outline: 3px solid var(--em-ink); outline-offset: 2px; }
html[dir="rtl"] .em-mapcard__book svg { transform: scaleX(-1); }

.em-mapcard__cta {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  margin: .55rem 0 0;
  color: var(--em-gold-d);
  font-family: var(--em-font-head);
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid transparent;
}
.em-mapcard__cta:hover { border-bottom-color: var(--em-gold); }
.em-mapcard__cta:focus-visible { outline: 3px solid var(--em-gold); outline-offset: 3px; }

.em-mapcard__close {
  position: absolute;
  inset-block-start: 8px;
  inset-inline-end: 8px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 30px; height: 30px;
  border: 0;
  border-radius: 50%;
  background: rgba(255,255,255,.92);
  color: var(--em-ink);
  cursor: pointer;
  box-shadow: 0 2px 8px rgba(28,24,19,.25);
}
/* Hello Elementor's reset.css paints EVERY [type="button"] magenta
   (rgb(204,51,102)) on hover and focus. Ours is a close button on a photo,
   so the state is declared here rather than inherited from the parent theme. */
.em-mapcard__close:hover,
.em-mapcard__close:focus,
.em-mapcard__close:focus-visible {
  background: #fff;
  color: var(--em-ink);
  border: 0;
}
.em-mapcard__close:focus-visible { outline: 3px solid var(--em-gold); outline-offset: 2px; }

/* These strings are still English while Batch D is frozen, so in an RTL page
   the bidi algorithm reorders them: "2 experiences" rendered as
   "EXPERIENCES 2" and "€250 · 2 days" as "days 2 · €250". Forcing LTR inside
   the span keeps the words in their own order while the card as a whole
   stays right-aligned. Revisit when the Arabic translations land. */
html[dir="rtl"] .em-mapcard__count,
html[dir="rtl"] .em-maptour__meta,
html[dir="rtl"] .em-mapcard__facts,
html[dir="rtl"] .em-journey__item,
html[dir="rtl"] .em-xpanel__sub,
html[dir="rtl"] .em-xdest__count,
html[dir="rtl"] .em-xtour__meta,
html[dir="rtl"] .em-xtour__price,
html[dir="rtl"] .em-jbadge {
  direction: ltr;
  text-align: right;
}
html[dir="rtl"] .em-mapcard__facts,
html[dir="rtl"] .em-journey__item { justify-content: flex-end; }

/* RTL: logical properties place the card and legend; only the CTA arrow
   needs mirroring. Longitude is never mirrored — the map stays geographic. */
html[dir="rtl"] .em-mapcard__cta svg { transform: scaleX(-1); }
[dir="rtl"] .em-tour-map .leaflet-left,
[dir="rtl"] .em-map .leaflet-left  { left: auto; right: 0; }
[dir="rtl"] .em-tour-map .leaflet-right,
[dir="rtl"] .em-map .leaflet-right { right: auto; left: 0; }

/* ── Mobile: the card becomes a bottom sheet ───────────────────── */
@media (max-width: 768px) {
  .em-mapframe .em-tour-map { height: clamp(300px, 52vh, 420px); }

  .em-mapcard {
    inset-inline: 0;
    inset-block-end: 0;
    width: 100%;
    border-radius: 16px 16px 0 0;
    border-inline: 0;
    border-block-end: 0;
    transform: translateY(100%);
    max-height: 62%;
    overflow-y: auto;
    overscroll-behavior: contain;   /* the sheet scrolls, the page does not */
  }
  .em-mapcard.is-open { transform: translateY(0); }

  /* grab handle */
  .em-mapcard::before {
    content: "";
    display: block;
    width: 38px; height: 4px;
    margin: 8px auto 0;
    border-radius: 99px;
    background: rgba(28,24,19,.18);
  }
  /* A ratio-sized photo grows with the sheet's width: at 768 a 21/9 image is
     302px tall, which pushed the sheet to 368 of the map's 420 and left the
     map barely visible behind it. A capped height keeps the sheet compact at
     every width — the point of a sheet is that the map stays in view. */
  .em-mapcard__media img {
    aspect-ratio: auto;
    height: clamp(104px, 19vh, 150px);
  }
  /* A destination sheet carries a photo AND a tour list. With the full-height
     photo the first tour sat below the fold and had to be scrolled to, which
     defeats the point of putting tours on the map. The photo gives way. */
  .em-mapcard:has(.em-maptour) .em-mapcard__media img { height: clamp(84px, 13vh, 104px); }
  .em-mapcard:has(.em-maptour) { max-height: 74%; }
  .em-map-legend { font-size: .64rem; gap: .55rem; padding: .34rem .6rem; }
  .em-map-footer { flex-direction: column; align-items: flex-start; gap: .55rem; }
  .em-journey { order: 0; }
  .em-journey__item { font-size: .66rem; padding: .3rem .6rem; }
}

@media (max-width: 380px) {
  .em-map-legend .em-lg--stop { display: none; }
  .em-mpin__label { max-width: 108px; font-size: .62rem; }
}

/* ── Reduced motion ────────────────────────────────────────────
   No draw, no pulse, no pan easing. The route still renders. */
@media (prefers-reduced-motion: reduce) {
  .em-mpin__pulse { animation: none !important; opacity: 0 !important; }
  .em-mpin__mark,
  .em-mpin__label,
  .em-mapcard { transition: none; }
  .em-mpin { animation: none !important; opacity: 1 !important; }
  .em-route--line.is-drawing { animation: none; stroke-dasharray: none; stroke-dashoffset: 0; }
  /* the travelling highlight is motion for its own sake — remove it entirely
     rather than leaving a static white dash sitting on the route */
  .em-route--glow { display: none !important; }
  .em-mapcard { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════
   FULLSCREEN TOUR EXPLORER
   An application-level overlay, not the browser Fullscreen API: the API
   fights iOS Safari, cannot be styled and loses the URL-bar contract, and a
   100dvh overlay gives everything it would have.
   ═══════════════════════════════════════════════════════════════ */

/* The trigger belongs TO the map, not to the layout around it: it is
   anchored to the shell that wraps the map frame, centred on its bottom
   edge and overlapping it, so at every width it reads as a control on the
   map rather than a button that happens to sit nearby. Percentage-based, so
   there is no viewport-specific pixel position to break. */
.em-map-shell { position: relative; }

/* The anchor wraps the frame ONLY, so "bottom: 0" is the map's own bottom
   edge rather than the section's padding box. The frame itself cannot host
   the button: it has overflow:hidden and would clip the half that overhangs. */
.em-map-anchor { position: relative; }

.em-map-anchor .em-xopen {
  position: absolute;
  inset-block-end: 0;
  inset-inline-start: 50%;
  transform: translate(-50%, 50%);
  z-index: 500;              /* over the map, under Leaflet's controls */
  margin: 0;
  max-width: calc(100% - 24px);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
html[dir="rtl"] .em-map-anchor .em-xopen { transform: translate(50%, 50%); }
.em-map-anchor .em-xopen:hover { transform: translate(-50%, calc(50% - 2px)); }
html[dir="rtl"] .em-map-anchor .em-xopen:hover { transform: translate(50%, calc(50% - 2px)); }

/* The shell needs room for the half that hangs below the frame. */
.em-map-shell { padding-bottom: 26px; }

/* The tour page has no .em-map-shell — its trigger used to be nested INSIDE
   .em-mapframe, which is overflow:hidden for its 16px radius, and 22 of the
   button's 46px were cut off. The trigger is now a child of .em-map-anchor
   in every context; this is the reserve that .em-map-shell provides for the
   other three.

   The reserve goes on the SECTION, not on .em-map-anchor. Absolute
   `inset-block-end: 0` resolves against the anchor's PADDING box, so padding
   there just moves the anchor's bottom edge down and the button rides with
   it — landing fully below the card instead of straddling its edge, which is
   not how the destination and homepage triggers look. */
.em-tour-map-sec { padding-bottom: 26px; }

/* The trigger straddles the bottom edge, and at narrow widths its 256px pill
   reaches across a 294px frame — straight over Leaflet's attribution, which
   must stay legible. Measured overlaps at 390 and 320 on every page, and at
   768 on the homepage. Lifting the attribution above the pill clears it and
   costs nothing: the credit stays fully visible, just higher. */
.em-map-anchor .leaflet-bottom { bottom: 26px; }

.em-xopen {
  display: inline-flex;
  align-items: center;
  gap: .55rem;
  margin: 1.4rem auto 0;
  padding: .8rem 1.5rem;
  border: 0;
  border-radius: 999px;
  background: var(--em-ink);
  color: var(--em-bg);
  font-family: var(--em-font-head);
  font-size: .84rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .25s var(--em-ease), transform .25s var(--em-ease);
}
.em-xopen:hover { background: var(--em-gold-d); transform: translateY(-2px); }
.em-xopen:focus-visible { outline: 3px solid var(--em-gold); outline-offset: 3px; }
.em-xopen svg { color: var(--em-gold); flex: none; }

body.em-x-open { overflow: hidden; }

.em-explorer {
  position: fixed;
  inset: 0;
  z-index: 10000;          /* above the WhatsApp float, which sits at 9000+ */
  /* Flex, not a three-row grid: with the filters row hidden the body dropped
     into the second (auto) track and sized to its own content — 689px of a
     900px viewport, with the page showing underneath. */
  display: flex;
  flex-direction: column;
  background: var(--em-bg);
  opacity: 0;
  transition: opacity .22s var(--em-ease);
}
.em-explorer.is-open { opacity: 1; }
.em-explorer[hidden] { display: none; }

/* Giving an element a display value defeats the hidden attribute, which is
   how an empty search showed a clear button and a filter count of zero showed
   a gold dot. Every hidden element in here stays hidden. */
.em-explorer [hidden] { display: none !important; }

/* ── Top bar ─────────────────────────────────────────────────── */
.em-explorer__bar {
  display: flex;
  align-items: center;
  gap: .8rem;
  padding: .7rem clamp(.8rem, 2vw, 1.4rem);
  padding-top: max(.7rem, env(safe-area-inset-top));
  background: var(--em-ink);
  color: var(--em-bg);
}
.em-explorer__brand {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-family: var(--em-font-head);
  font-size: .82rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
}
.em-explorer__brand svg { color: var(--em-gold); }

.em-explorer__search {
  position: relative;
  display: flex;
  align-items: center;
  gap: .5rem;
  flex: 1 1 auto;
  max-width: 460px;
  padding: .42rem .8rem;
  border-radius: 999px;
  background: rgba(255,255,255,.1);
  border: 1px solid rgba(255,255,255,.16);
}
.em-explorer__search svg { color: rgba(255,255,255,.6); flex: none; }
.em-explorer__search input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: none;
  color: var(--em-bg);
  font-family: var(--em-font-body);
  font-size: .92rem;
}
.em-explorer__search input::placeholder { color: rgba(255,255,255,.5); }
.em-explorer__search input:focus { outline: none; }
.em-explorer__search:focus-within { border-color: var(--em-gold); }
.em-explorer__clear {
  border: 0; background: none; cursor: pointer;
  color: rgba(255,255,255,.7); font-size: 1.2rem; line-height: 1; padding: 0 .2rem;
}

.em-explorer__filtoggle,
.em-explorer__close {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  padding: .5rem .85rem;
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 999px;
  background: none;
  color: var(--em-bg);
  font-family: var(--em-font-head);
  font-size: .78rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background .2s var(--em-ease), border-color .2s var(--em-ease);
}
.em-explorer__filtoggle:hover,
.em-explorer__close:hover { background: rgba(255,255,255,.12); border-color: var(--em-gold); }
.em-explorer__filtoggle:focus-visible,
.em-explorer__close:focus-visible { outline: 3px solid var(--em-gold); outline-offset: 2px; }
.em-explorer .em-explorer__close,
.em-explorer .em-explorer__filtoggle,
.em-explorer .em-xreset,
.em-explorer .em-explorer__clear {
  background-color: transparent;
  border-color: rgba(255,255,255,.18);
}
.em-explorer .em-explorer__close:hover,
.em-explorer .em-explorer__filtoggle:hover {
  background-color: rgba(255,255,255,.12);
  border-color: var(--em-gold);
  color: var(--em-bg);
}
.em-explorer .em-xreset,
.em-explorer .em-xreset:hover { border-color: transparent; color: var(--em-gold-d); }
.em-explorer__close { padding: .5rem; }
.em-explorer__filcount {
  display: grid; place-items: center;
  min-width: 18px; height: 18px; padding: 0 4px;
  border-radius: 999px;
  background: var(--em-gold);
  color: #fff; font-size: .68rem;
}

/* ── Filters ─────────────────────────────────────────────────── */
.em-explorer__filters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 1rem 2rem;
  padding: .9rem clamp(.8rem, 2vw, 1.4rem);
  background: var(--em-bg2);
  border-bottom: 1px solid var(--em-hair, rgba(28,24,19,.12));
}
.em-explorer__filters[hidden] { display: none; }
.em-xfilter__k {
  display: block;
  margin: 0 0 .35rem;
  font-family: var(--em-font-head);
  font-size: .68rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--em-muted);
}
.em-xfilter__opts { display: flex; flex-wrap: wrap; gap: .4rem; }
.em-xchip { position: relative; display: inline-flex; cursor: pointer; }
.em-xchip input {
  position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer;
}
.em-xchip span {
  padding: .35rem .8rem;
  border-radius: 999px;
  border: 1px solid var(--em-hair, rgba(28,24,19,.16));
  background: #fff;
  font-size: .82rem;
  color: var(--em-ink);
  transition: background .18s var(--em-ease), border-color .18s var(--em-ease), color .18s var(--em-ease);
}
.em-xchip input:checked + span {
  background: var(--em-gold);
  border-color: var(--em-gold);
  color: #fff;
}
.em-xchip input:focus-visible + span { outline: 3px solid var(--em-gold); outline-offset: 2px; }
.em-xreset {
  align-self: center;
  margin-inline-start: auto;
  border: 0; background: none; cursor: pointer;
  color: var(--em-gold-d);
  font-family: var(--em-font-head);
  font-size: .76rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}

/* ── Body: map + panel ───────────────────────────────────────── */
.em-explorer__body {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: 1fr 380px;
  min-height: 0;
}
.em-explorer__map {
  position: relative;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  min-height: 0;
}
.em-explorer__map .em-map { height: 100%; }

.em-explorer__panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: #fff;
  border-inline-start: 1px solid var(--em-hair, rgba(28,24,19,.12));
}
.em-xpanel__grip { display: none; }
.em-xpanel__head {
  padding: 1.1rem 1.2rem .7rem;
  border-bottom: 1px solid var(--em-hair, rgba(28,24,19,.1));
}
.em-xpanel__title {
  margin: 0;
  font-family: var(--em-font-head);
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--em-ink);
}
.em-xpanel__sub {
  margin: .15rem 0 0;
  font-family: var(--em-font-head);
  font-size: .74rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--em-gold-d);
}
.em-xpanel__back {
  display: inline-flex;
  align-items: center;
  gap: .3rem;
  margin: .6rem 0 0;
  border: 0; background: none; cursor: pointer; padding: 0;
  color: var(--em-muted);
  font-family: var(--em-font-head);
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.em-xpanel__back:hover { color: var(--em-ink); }
html[dir="rtl"] .em-xpanel__back svg,
html[dir="rtl"] .em-xdest__arrow svg { transform: scaleX(-1); }

.em-xpanel__list {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: .6rem;
}

/* ── Destination row ─────────────────────────────────────────── */
.em-xdest {
  display: flex;
  align-items: center;
  gap: .75rem;
  width: 100%;
  padding: .5rem;
  border: 0;
  border-radius: 12px;
  background: none;
  text-align: start;
  cursor: pointer;
  transition: background .18s var(--em-ease);
}
.em-xdest:hover { background: var(--em-bg2); }
.em-xdest:focus-visible { outline: 3px solid var(--em-gold); outline-offset: -2px; }
.em-xdest.is-empty { opacity: .42; }
.em-xdest__img {
  width: 54px; height: 54px;
  border-radius: 10px;
  object-fit: cover;
  flex: none;
  background: var(--em-bg2);
}
.em-xdest__body { display: grid; gap: 2px; flex: 1; min-width: 0; }
.em-xdest__name {
  font-family: var(--em-font-head);
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--em-ink);
}
.em-xdest__count {
  font-family: var(--em-font-head);
  font-size: .72rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--em-gold-d);
}
.em-xdest__arrow { color: var(--em-muted); flex: none; }

/* ── Tour card in the panel ──────────────────────────────────── */
.em-xtour {
  display: flex;
  gap: .75rem;
  padding: .5rem;
  border-radius: 12px;
  text-decoration: none;
  color: inherit;
  transition: background .18s var(--em-ease), transform .18s var(--em-ease);
}
.em-xtour:hover { background: var(--em-bg2); transform: translateY(-1px); }
.em-xtour:focus-visible { outline: 3px solid var(--em-gold); outline-offset: -2px; }
.em-xtour__img {
  width: 78px; height: 66px;
  border-radius: 10px;
  object-fit: cover;
  flex: none;
  background: var(--em-bg2);
  transition: transform .3s var(--em-ease);
}
.em-xtour:hover .em-xtour__img { transform: scale(1.04); }
.em-xtour__img--none { display: block; }
.em-xtour__body { display: grid; gap: 2px; min-width: 0; align-content: center; }
.em-xtour__badge {
  font-family: var(--em-font-head);
  font-size: .62rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--em-teal);
}
.em-xtour__title {
  font-family: var(--em-font-head);
  font-size: .96rem;
  font-weight: 600;
  line-height: 1.15;
  color: var(--em-ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.em-xtour__meta { font-size: .76rem; color: var(--em-muted); }
.em-xtour__price {
  font-family: var(--em-font-head);
  font-size: .92rem;
  font-weight: 600;
  color: var(--em-ink);
}
.em-xtour__price.is-request { font-size: .78rem; font-weight: 400; color: var(--em-muted); }

/* ── Mobile: map on top, discovery sheet below ───────────────── */
@media (max-width: 768px) {
  .em-explorer__bar { flex-wrap: wrap; gap: .5rem; }
  .em-explorer__brand { display: none; }
  .em-explorer__search { order: 1; flex: 1 1 100%; }
  .em-explorer__filtoggle { order: 2; }
  .em-explorer__close { order: 0; margin-inline-start: auto; }

  .em-explorer__body { grid-template-columns: 1fr; grid-template-rows: 1fr auto; }

  /* The map must stay the LARGER half: at 46vh the sheet measured 396px
     against a 298px map, which is a sheet with a map above it rather than a
     map you are exploring. The top bar wraps to two rows on mobile and eats
     ~112px, so the sheet's share has to allow for that. */
  .em-explorer__panel {
    border-inline-start: 0;
    border-top: 1px solid var(--em-hair, rgba(28,24,19,.12));
    border-radius: 16px 16px 0 0;
    max-height: min(38vh, 330px);
    padding-bottom: env(safe-area-inset-bottom);
    box-shadow: 0 -8px 24px -16px rgba(28,24,19,.5);
  }
  .em-xpanel__grip {
    display: block;
    width: 38px; height: 4px;
    margin: 8px auto 0;
    border-radius: 99px;
    background: rgba(28,24,19,.18);
  }
  .em-xpanel__head { padding: .7rem 1rem .55rem; }
  .em-xpanel__title { font-size: 1.24rem; }
}

@media (max-width: 520px) {
  /* The full label does not fit beside a 320px map; a tighter pill keeps it
     tappable without overflowing. */
  .em-map-anchor .em-xopen { padding: .7rem 1rem; font-size: .74rem; letter-spacing: .06em; }
}

@media (max-width: 380px) {
  .em-explorer__filtoggle span { display: none; }
  .em-xtour__img { width: 62px; height: 56px; }
}

@media (prefers-reduced-motion: reduce) {
  .em-explorer,
  .em-xtour,
  .em-xtour__img,
  .em-xopen { transition: none; }
}


/* ── Journey badge: compact variant (Phase 5K) ─────────────────
   On a narrow map no leg is long enough to carry a pill beside it, and the
   badge used to simply not render — measured jbadge:0 at 390 while desktop
   showed it. It now docks at the route's midpoint in a tighter form, because
   the duration and stop count are the whole point of a journey map. */
/* Anchored to the route: a short connector plus a heavier pill so the facts
   read as a label ON the journey rather than a chip floating in the desert. */
.em-jbadge {
  box-shadow: 0 6px 18px -6px rgba(28,24,19,.55);
  border: 1px solid rgba(255,255,255,.14);
}

.em-jbadge--compact {
  font-size: .64rem;
  padding: .28rem .6rem;
  gap: .3rem;
  max-width: 82vw;
}
.em-jbadge--compact b { white-space: nowrap; }

/* The direction chevrons carry the journey's direction, so they earn a little
   more presence than a decorative dot. */
/* size is set once above; kept here only to override the earlier 5J block */
.em-chev { width: 22px; height: 22px; }
.em-chev svg { width: 20px; height: 20px; }


/* ── Waypoint chip with role (Phase 5K Stage A) ────────────────
   The chip is now a two-line stack: the place, and what it IS in the
   journey. Before this the only key to direction was a legend in the map's
   corner, so a customer had to infer which end was the start. */
.em-mpin__label { display: grid; justify-items: center; gap: 1px; line-height: 1.1; }
.em-mpin__label b { font-weight: 600; }
.em-mpin__role {
  display: block;
  font-style: normal;
  font-size: .52rem;
  letter-spacing: .14em;
  color: var(--em-gold-d);
}
.em-mpin--origin .em-mpin__role { color: var(--em-teal); }
.leaflet-marker-icon.is-active .em-mpin__role { color: var(--em-gold); }

/* Arrowheads were white on a gold line — the direction was there and easy to
   miss. Ink fill with a white edge reads against both the route and the sand. */
/* An arrowhead spans BOTH the gold core and the dark casing either side of
   it, so no single fill works against one background alone: ink vanished on
   the casing, plain white washed out on the gold. It is drawn white with a
   heavy ink outline, which reads as a solid arrow on the gold, a bright
   arrow on the casing, and stays defined when the white comet passes under
   it. Same idea as a road marking with a painted border. */
.em-chev { color: #fff; }
.em-chev svg path {
  stroke: var(--em-dark);
  stroke-width: 2.6;
  stroke-linejoin: round;
  paint-order: stroke fill;
}

/* The travelling highlight was white on gold: almost invisible in motion.
   A brighter, warmer segment actually reads as movement. */
/* Stage A set this to #ffe9bd. Cream over a white casing over a tan map is
   invisible — the animation was running the whole time and could not be
   seen. Back to pure white, now over a DARK casing. */
.em-route--glow { stroke: #fff; }
.em-route--glow.is-travelling { opacity: 1; }
/* A hairline of white either side of the gold, so the ribbon separates from
   the dark casing at every zoom. */
.em-route--line { paint-order: stroke; }

/* The end of the journey should be the heaviest mark on the map. */
.em-mpin--destination .em-mpin__pin { filter: drop-shadow(0 8px 14px rgba(28,24,19,.45)); }
.em-mpin--origin .em-mpin__pin { filter: drop-shadow(0 8px 14px rgba(28,24,19,.45)); }

/* START and DESTINATION are now the same SHAPE in different colours, so the
   two ends of the journey read as a matched pair and the numbered discs
   between them read as stops. Before this the origin was a 26px ring beside
   a 44px teardrop: the start of the journey was the least prominent thing
   on it. Teal is already the origin's colour in the legend and the pulse. */
.em-mpin--origin .em-mpin__pinbody { fill: var(--em-teal); }

/* The legend collides with the START pin at 430 and below. Measured on the
   Nile route at 390: Hurghada frames at the top-right, which is exactly where
   the legend sits, so the legend's white box covered the origin's chip — the
   one marker whose job is to say where the journey begins.

   It is hidden rather than moved, because at this size it is pure repetition:
   the chips already read "HURGHADA / START" and "ASWAN / DESTINATION" and the
   stops are numbered discs. The element is aria-hidden decoration, so nothing
   is lost to assistive technology either. It stays on >=431, where it has its
   own corner and overlaps nothing. */
@media (max-width: 430px) {
  .em-map-legend { display: none; }
}


/* ═══════════════════════════════════════════════════════════════
   PHASE 5L — the Journey Bridge as the map's strongest accent
   ═══════════════════════════════════════════════════════════════ */

/* Arrowheads repeat along the route (see drawChevrons) and light in sequence
   from origin to destination. One static arrow says "there is a line"; a wave
   of them travelling one way says "the excursion goes THIS way", which is the
   whole job of this element.

   The rotation stays on .em-chev as an inline transform — animating the same
   property here would spin every arrowhead back to 0deg — so the chase
   animates the SVG inside it instead. */
.em-chev { width: 24px; height: 24px; }
.em-chev svg {
  width: 22px;
  height: 22px;
  margin-inline-start: 0;
  /* .85 at rest, NOT .32. A chase that fades the arrows down between pulses
     looks alive in motion and reads as a row of ghosts in a still frame —
     and a still frame is exactly how this gets judged. Every arrowhead is
     legible at all times; the wave BRIGHTENS and enlarges one at a time on
     top of that. */
  opacity: .85;
  transform-origin: 50% 50%;
  animation: em-chev-chase 1.7s var(--em-ease) infinite;
  animation-delay: calc(var(--em-chev-i, 0) * .15s);
}
@keyframes em-chev-chase {
  0%, 62%, 100% { opacity: .8; transform: scale(.96); }
  22%           { opacity: 1;  transform: scale(1.16); }
}

/* Off screen, or the visitor asked for less motion: every arrowhead stays
   fully legible, it just stops chasing. The route is never hidden. */
.em-mapframe:not(.is-onscreen) .em-chev svg { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .em-chev svg { animation: none; opacity: 1; transform: none; }
}

/* Warmth. The brief asks for a tourism map, not neutral cartography, and the
   desert was rendering as flat white. A little sepia under the existing
   saturation pushes sand back towards sand while leaving the sea blue and the
   roads un-yellowed — the failure mode of the 2.2 saturation rejected
   earlier. Terrain only; the label pane stays untouched. */
.em-tour-map .leaflet-tile-pane,
.em-map .leaflet-tile-pane {
  filter: saturate(1.72) contrast(1.07) brightness(1.02) sepia(.12);
}


/* ═══════════════════════════════════════════════════════════════
   JOURNEY BRIDGE MOTION — the restrained version
   ═══════════════════════════════════════════════════════════════
   What was wrong with the first pass:

   1. The comet was a hard-edged white dash with blunt ends looping on a
      linear timing function. A rectangle of paint sliding round and round
      reads as a stripe on the road, not as something travelling along it.
   2. The arrowheads SCALED up and down (1.28x). Scaling icons is the single
      most toy-like move available; it drew the eye to the animation instead
      of to the journey.
   3. Both ran continuously and competed with each other.

   The replacement: one light, with soft ends and a real glow, that eases
   away from the origin, arrives at the destination, fades, and rests before
   going again — the way a departure board or a premium travel site would do
   it. The arrows do nothing but brighten in sequence underneath it. */

.em-route--glow {
  /* round ends and an actual glow: light, not paint */
  stroke-linecap: round;
  filter: drop-shadow(0 0 5px rgba(255, 255, 255, .9));
}

.em-route--glow.is-travelling {
  /* Slower than the old 3s, and eased rather than linear, so the light
     accelerates away from the origin and settles into the destination. */
  animation: em-route-travel 4.6s cubic-bezier(.42, 0, .22, 1) infinite;
}

/* Redefining the keyframes rather than editing the original: this file is
   read top-to-bottom and the last definition of a name wins, so the engine's
   JS (which only toggles the class) is untouched. */
@keyframes em-route-travel {
  0%   { stroke-dashoffset: var(--em-route-len); opacity: 0; }
  10%  { opacity: 1; }
  60%  { opacity: 1; }
  74%  { stroke-dashoffset: 0; opacity: 0; }
  100% { stroke-dashoffset: 0; opacity: 0; }   /* rest before the next pass */
}

/* Opacity only. No scale, no bounce — the wave should be felt rather than
   watched, and a still screenshot still shows every arrow clearly. */
.em-chev svg {
  animation: em-chev-chase 4.6s ease-in-out infinite;
  animation-delay: calc(var(--em-chev-i, 0) * .12s);
  transform: none;
}
@keyframes em-chev-chase {
  0%, 46%, 100% { opacity: .62; }
  16%           { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .em-chev svg { animation: none; opacity: 1; }
  .em-route--glow { display: none !important; }
}


/* ═══════════════════════════════════════════════════════════════
   PHASE 5O — the Journey Bridge as a LUXURY TRAVEL PATH
   ═══════════════════════════════════════════════════════════════

   The 5L/5N bridge was unmistakably visible, which was the problem it had
   been built to solve. Judged as design rather than as a bug fix it read as
   a HIGHWAY: a 12px gold carriageway inside a 22px near-black casing, with a
   queue of filled arrowheads every 88px and a 72px white stripe sliding along
   it. Visible, and the least premium mark on the page.

   Everything below was judged on the real frame — 828px at 1440, 707 at 768,
   359 at 390 — because the composition is the point. A weight that looks
   restrained in the abstract is a different mark inside an 828x414 map.

   Four decisions, in order of how much they changed the result:

     1. The gold dominates and the ink is a contour, not a slab.
     2. Direction marks are INK ON GOLD, so they cannot fail at their edges.
     3. The travelling light is a head plus a trail, not one lit dash.
     4. The badge and the legend are the same object as the fact chips that
        already sit in the map footer — one material, two weights.

   Geometry lives in em-map.js; everything about how it READS is here. */


/* ── 1. the ribbon ─────────────────────────────────────────────
   At 13/6 the casing showed 3.5px of near-black either side of the gold, so
   the ink was as heavy as the core and the ribbon read as a black line with
   a gold fill. The weights are inverted in em-map.js (7 core, +2px contour);
   this drops the casing alpha to match, and moves the job of separating the
   route from the sand off the black and onto a soft shadow. A drop-shadow is
   what a printed map uses to lift a route off its ground — a heavier outline
   is what a road atlas uses. */
/* The casing is a CREAM HALO, not an ink outline — see the weight note in
   em-map.js. A printed travel map separates a drawn route from its terrain
   with a light surround, which costs no visual weight and leaves the accent
   colour as the only saturated thing in the frame. An ink outline costs the
   most weight available and makes the eye read the black first.

   The heavy offset shadows are gone with it: they were compensating for a
   line that needed lifting off flat pale ground, and on textured sand they
   only added a grey smear under the route. What is left is a single soft,
   symmetric shadow for a hint of depth. */
.em-route--case {
  stroke: rgba(255,251,240,.75);
  filter: drop-shadow(0 1px 2px rgba(60,44,20,.18));
}

/* ── 2. direction ──────────────────────────────────────────────
   Ink on gold. See the long note in mkChev for why white-on-anything failed
   twice: a mark large enough to read always overhangs the ribbon, and what
   happens at the OVERHANG decides whether it reads as a bearing or as a
   fragment. Ink stays legible on the gold core, on the casing and on the
   sand alike, so the mark degrades gracefully at every size. */
.em-chev svg {
  width: 13px;
  height: 13px;
  overflow: visible;
}
/* Selector deliberately at (0,2,2), not the (0,1,0) `.em-chev__core` this
   started as. Phases 5J, 5K and 5N each left a `.em-chev svg path` block in
   this file at (0,1,2) — the last of them still setting `stroke-width: 2.6`
   and `paint-order: stroke fill` for the old white-with-an-ink-outline
   arrowhead. They beat a single class, so the weight below was silently
   ignored until it was measured in the browser rather than read in the file.
   Everything the old treatment set is restated here, so this rule is the
   whole description of the mark and does not depend on what precedes it. */
/* Warm dark brown, not near-black. At #16130d on a 4.5px gold line the
   chevron was the highest-contrast mark on the whole map — a hard black notch
   that read as a kink in the route rather than a bearing on it. A deep umber
   sits IN the route's own colour family, so it reads as part of the material
   and not as something dropped on top of it. */
.em-chev svg path.em-chev__core {
  fill: none;
  stroke: #5c3d14;
  stroke-width: 3.1;
  stroke-linecap: round;
  stroke-linejoin: round;
  paint-order: normal;
}

/* Sized to sit INSIDE the ribbon, which pinScale() shrinks at the same two
   thresholds. The mark spans (14 + stroke) of a 24-unit box across the line,
   so 13px renders ~9.4px across an 11px ribbon, 11px renders ~8px across a
   9px ribbon at 768, and 9px renders ~6.5px across a 7px ribbon at 390.

   The first attempt used 17px, and magnified 4x that was the whole problem:
   the arms reached past the gold onto bare sand, where a dark stroke reads as
   an angular scratch beside the route rather than a bearing on it, and the
   mark looked like a kink in the line. Contained inside the gold it reads as
   engraved — which is what a chart does. */
@media (max-width: 768px) { .em-chev svg { width: 11px; height: 11px; } }
@media (max-width: 430px) { .em-chev svg { width: 10px; height: 10px; } }

/* The chevrons no longer animate on a timer. 5N gave them a staggered
   opacity chase and 5O slowed it down, and both read as decoration for the
   same reason: a mark that pulses on a clock is a mark with nothing to say.
   They now sit completely still at a low, even opacity, and brighten ONLY
   while the travelling light is passing over them — `--em-chev-lit` is
   written by the frame loop from the light's real distance along the path.
   The sequence a visitor sees running down the route is therefore the light
   arriving, not an animation playing. */
.em-chev {
  /* .62 was measured on screen as a grey tick that could not be read at
     map scale — the direction was effectively gone. The mark has to hold
     its own as INFORMATION when nothing is moving. */
  opacity: calc(.8 + .2 * var(--em-chev-lit, 0));
  filter: none;
  transition: opacity .18s linear;
}
/* `animation: none` is load-bearing. Phases 5J and 5N each left a
   `.em-chev svg { animation: em-chev-chase ... }` block earlier in this file,
   and both keyframes animate opacity. Without this reset the chevrons keep
   pulsing on a timer underneath the new treatment — the exact mechanical
   blink the light was built to replace — while the CSS above reads as though
   they are still. Found by looking at the rendered frames, not the file. */
.em-chev svg {
  margin-inline-start: 0;
  animation: none;
  opacity: 1;
}

/* ── 3. the travelling light ───────────────────────────────────
   PHASE 5O.1. Everything that came before was a `stroke-dasharray` segment
   sliding along the route, and every version of it was rejected on sight.
   The reason is structural, not a matter of tuning: a dash is a piece of
   stroke with two geometrically perfect ends and a constant opacity along
   its whole length. Light has a bright core, a falloff in every direction,
   and no edges at all. No quantity of drop-shadow closes that gap.

   So the lit section of route is revealed by an SVG MASK made of radial
   gradients — soft on every side, no edge anywhere — and the mask is moved
   along the real path geometry by requestAnimationFrame. The mask, the head
   and the timeline are all built in em-map.js (startLume); what is here is
   only how the result is painted.

   The route beneath stays completely static. Exactly one thing on this map
   moves, which is the whole of the restraint. */
.em-route--lume {
  /* ADDITIVE, not opaque.

     Attempt 5 painted #fffdf4 at full opacity over the #c0883a core. That
     REPLACES the gold with near-white, and on the real frame the lit section
     read as a grey bleached streak — the ribbon losing its colour rather than
     receiving light. Light does not remove colour; it adds to it.

     `mix-blend-mode: screen` is that addition, and it is why the stroke below
     is a mid amber rather than a white: screened onto the gold core it lifts
     it to a bright warm gold, and where it spills past the ribbon onto sand
     it becomes a soft warm bloom. One colour, two correct behaviours, because
     the maths is the maths of light. Browsers without the blend mode fall
     back to painting the amber normally, which is still warm and still
     readable — it simply stops being additive. */
  /* Deeper amber than the first pass. Screened onto the gold this lifts
     it to a bright warm gold; any lighter and it climbs to white the moment
     it touches the cream halo at the edges of the stroke. */
  stroke: #8a6528;
  mix-blend-mode: screen;
  opacity: 1;
  pointer-events: none;
}

.em-lume {
  pointer-events: none;
  mix-blend-mode: screen;
}
/* Both circles are radial gradients with a fully transparent rim, so there is
   no edge anywhere in the light — see the note in startLume(). The core was a
   flat white disc and looked exactly like one. */
.em-lume__halo { opacity: .8; }
.em-lume__core { opacity: 1; }

/* The stop and the destination acknowledge the light as it reaches them:
   a brief lift in the pin's own glow, and nothing else. No scale, no bounce,
   no ring expanding outwards — those are the gestures that make a map look
   like a game. The pin does not move at all; it is simply lit for a moment
   and then it is not. */
/* A warm glow around a GOLD pin sitting on SAND has almost no contrast, and
   measured at full frame the arrival at Luxor and at Aswan simply did not
   register — the one moment the whole animation is building towards. The
   inner ring is now near-white so it separates from the sand, and the pin
   itself brightens: the mark is not merely surrounded by light, it is lit.
   Still no scale, no bounce, no expanding ring — the pin does not move. */
.leaflet-marker-icon.is-lit .em-mpin__pinbody,
.leaflet-marker-icon.is-lit .em-mpin__disc {
  filter: brightness(1.14)
          drop-shadow(0 0 4px rgba(255,253,244,1))
          drop-shadow(0 0 11px rgba(255,231,172,.92))
          drop-shadow(0 0 24px rgba(224,176,96,.5));
}
.leaflet-marker-icon.is-lit .em-mpin__pulse { opacity: .7; }

/* A MATERIAL response, not an animation.

   Gold-on-sand gives a warm glow almost nothing to work against, so the
   arrival was carried entirely by the light's own bloom and the marker barely
   read as responding. Rather than turning the glow up — which is where this
   starts looking like a game — the marker's own surface briefly lightens, as
   a gold object does when a light reaches it. Nothing moves, nothing scales,
   nothing expands: the place is simply lit, and then it is not. */
.leaflet-marker-icon.is-lit .em-mpin__disc {
  background: #e5b063;
  border-color: #fffdf6;
}
.leaflet-marker-icon.is-lit .em-mpin__pinbody { fill: #d9a250; }

.leaflet-marker-icon .em-mpin__pinbody,
.leaflet-marker-icon .em-mpin__disc {
  transition: filter .34s ease-out, background-color .34s ease-out,
              border-color .34s ease-out, fill .34s ease-out;
}

/* ── 4. badge and legend: ONE material ─────────────────────────
   The badge was an opaque near-black pill and the legend a white one: two
   floating labels on one map, in two unrelated visual languages, and the
   black pill was the highest-contrast object in the frame — heavier than the
   route it was describing.

   Both are now the same warm paper chip that the map FOOTER already uses for
   "1 stop en route" and "5 days / 4 nights" a few pixels below. That is the
   coherence win: the label on the map and the facts under it stop being two
   designs and become one component at two weights — the badge carrying ink
   type and a gold lead, the legend muted and smaller. */
.em-jbadge {
  padding: .34rem .74rem;
  gap: .45rem;
  font-size: .6rem;
  letter-spacing: .13em;
  background: rgba(255,250,242,.93);
  color: var(--em-ink);
  border: 1px solid rgba(192,136,58,.4);
  -webkit-backdrop-filter: blur(9px) saturate(1.12);
  backdrop-filter: blur(9px) saturate(1.12);
  box-shadow: 0 1px 3px rgba(28,24,19,.14),
              0 12px 26px -14px rgba(28,24,19,.55);
}
/* A lead in gold and the rest in ink. "ROUND TRIP" and "1 STOP" are what the
   journey IS; the duration is a detail of it, and printing both at one weight
   made the pill a row of equal shouts. */
.em-jbadge b:first-of-type { color: var(--em-gold-d); }
.em-jbadge i { width: 3px; height: 3px; background: var(--em-gold); opacity: .85; }

.em-map-legend {
  padding: .34rem .68rem;
  gap: .7rem;
  font-size: .58rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  background: rgba(255,250,242,.9);
  color: var(--em-muted);
  border: 1px solid rgba(28,24,19,.1);
  -webkit-backdrop-filter: blur(9px);
  backdrop-filter: blur(9px);
  box-shadow: 0 1px 3px rgba(28,24,19,.1),
              0 10px 22px -14px rgba(28,24,19,.45);
}
.em-map-legend i { width: 7px; height: 7px; }

/* ── waypoint chips ────────────────────────────────────────────
   The chips were never the problem — the basemap was printing the same place
   name underneath them (see the label-pane note in em-map.js). With that gone
   they only needed to stop shouting. */
.em-mpin__label { letter-spacing: .04em; }
.em-mpin__role { font-size: .5rem; letter-spacing: .15em; }

@media (prefers-reduced-motion: reduce) {
  /* The complete route stays visible and the chevrons keep their presence —
     they ARE the direction, and direction is information, not decoration.
     The travelling light is removed outright: startLume() returns early, and
     this makes sure nothing is painted even if it is ever reached. */
  .em-chev { opacity: .8; transition: none; }
  .em-route--lume,
  .em-lume { display: none !important; }
  .leaflet-marker-icon .em-mpin__pinbody,
  .leaflet-marker-icon .em-mpin__disc { transition: none; }
}


/* ═══════════════════════════════════════════════════════════════
   PHASE 5O.1 — BASEMAP AFTER CARTO
   ═══════════════════════════════════════════════════════════════

   The warmth filter above was tuned against CARTO Voyager, whose land was
   already sand-coloured. The replacement basemap is paler and cooler, so the
   same numbers leave Egypt looking like a printed atlas rather than a desert.

   These rules do NOT hide anything. The "API KEY REQUIRED" stamp is gone
   because the site stopped requesting tiles it had no key for — see
   inc/map-tiles.php. What is below is colour grading, and it is applied to
   the TERRAIN pane only, exactly as before: the label pane is never filtered,
   because a filter over type is how you get smeared place names. */
.em-tour-map .leaflet-tile-pane,
.em-map .leaflet-tile-pane {
  filter: saturate(1.28) contrast(1.05) sepia(.24);
}
.em-tour-map .leaflet-pane--emLabels,
.em-map .leaflet-pane--emLabels { filter: none; }

/* A provider whose place names are drawn INTO the terrain tile cannot have
   them lifted onto their own pane, so on the JOURNEY map — where our own
   chips name every waypoint — the basemap is damped instead. Its type
   recedes, our chips and the gold ribbon do not, because neither of those is
   in the tile pane. This is the same judgement the two-layer trick has always
   made: exactly one of the two ever names a place. */
.em-tour-map.em-map--bakedlabels .leaflet-tile-pane {
  /* Attempt 1 damped with contrast(.9) brightness(1.07) and the result was
     a bleached photocopy — Egypt went to near-white and the Nile disappeared.
     Damping the basemap is right; taking the CONTRAST out of it is not. This
     desaturates and warms instead, so the basemap recedes in COLOUR while
     keeping its structure — the coastline and the river still read, and the
     gold ribbon is the only saturated thing in the frame. */
  filter: saturate(1.02) contrast(1.02) sepia(.28);
}


/* ── attribution ───────────────────────────────────────────────
   PHASE 5P.1. Two Esri layers meant two "Tiles (c) Esri" credits on one line,
   and at 1440 the result ran the full width of the map and straight across
   the ASWAN chip; at 320 it wrapped to THREE lines and took about a sixth of
   the map surface — comfortably the loudest, least premium object on screen.

   The duplicate prefix is gone (inc/map-tiles.php merges the two credits and
   keeps every named source). What is left is a genuinely long string, because
   Esri's own source list is long, and it is NOT this file's business to
   shorten it.

   So the remaining fix is presentational, and deliberately conservative:
   NOTHING is hidden, cropped, collapsed or truncated. The type is smaller,
   the background is a warm translucent tint rather than a solid white band,
   and the leading is tightened so a wrap costs less height. The credit stays
   fully legible and fully present at every width. */
.em-tour-map .leaflet-control-attribution,
.em-map .leaflet-control-attribution {
  background: rgba(255,250,242,.82);
  color: rgba(28,24,19,.72);
  font-size: 9px;
  line-height: 1.35;
  padding: 1px 6px;
  border-start-start-radius: 6px;
}
.em-tour-map .leaflet-control-attribution a,
.em-map .leaflet-control-attribution a { color: rgba(28,24,19,.72); }

@media (max-width: 430px) {
  .em-tour-map .leaflet-control-attribution,
  .em-map .leaflet-control-attribution {
    font-size: 8px;
    line-height: 1.3;
    /* Never wider than the frame, so a long credit stacks rather than
       forcing the map to scroll sideways. */
    max-width: 100%;
  }
}


/* ═══════════════════════════════════════════════════════════════
   THE DOCKED CREDIT
   ═══════════════════════════════════════════════════════════════

   em-map.js moves .leaflet-control-attribution out of the tile canvas and
   into .em-map-footer on the inline maps. See the long note there for why
   moving beat shrinking, padding and (never an option) hiding.

   Everything here is layout. Nothing reduces the credit's legibility below
   the surrounding UI: it sits at the frame's own small-print size, at full
   contrast for body text, selectable, wrapping rather than clipping. */
.leaflet-control-attribution.em-attrib--docked {
  position: static;
  display: block;
  width: 100%;
  margin: .55rem 0 0;
  padding: 0;
  background: none;
  box-shadow: none;
  border-radius: 0;
  font-size: .625rem;
  line-height: 1.45;
  letter-spacing: .01em;
  color: rgba(28, 24, 19, .58);
  /* The frame is a flex row; the credit is a full-width line under it. */
  flex: 0 0 100%;
  order: 99;
  white-space: normal;
  text-align: start;
}
.leaflet-control-attribution.em-attrib--docked a {
  color: rgba(28, 24, 19, .72);
  text-decoration: underline;
  text-underline-offset: .15em;
}
/* Leaflet's own separator and flag are noise once the credit is prose in a
   footer rather than a tag on a map. The FLAG is decorative chrome the
   library injects, not a licence requirement; every named source stays. */
.leaflet-control-attribution.em-attrib--docked .leaflet-attribution-flag { display: none; }

@media (max-width: 430px) {
  .leaflet-control-attribution.em-attrib--docked {
    font-size: .5625rem;
    line-height: 1.4;
    margin-top: .45rem;
  }
}

/* ── baked basemap, retuned for a DETAILED journey base ────────
   The journey map used to stack a label-free Physical layer, which removed
   the double-naming and the geography with it. It now runs a fully detailed
   base, so the damping has a different job: hold the basemap's own type and
   colour BEHIND our chips and the gold ribbon without washing the terrain
   out. Desaturate slightly, keep contrast (the coastline and the Nile are
   carried by contrast, not colour), warm it to the brand's ground. */
.em-tour-map.em-map--bakedlabels .leaflet-tile-pane {
  filter: saturate(.86) contrast(1.06) sepia(.2) brightness(1.015);
}
