/* ============================================================================
   SECTION 17 · "5.4 Amenities" · Figma 2931:390 · 1280 x 891 @ page y 16509
   ----------------------------------------------------------------------------
   SPEC    ../../../figma-truth/17-amenities-54.spec.md
   PIXELS  ../../../figma-truth/sections-en/17-amenities-54.png  (2560x1782, @2x)
   LIFT    salient-truth/elements-google-map/  +  .lift.md   (live at :5010)
           Bound to this section by the founder note quoted in spec §7.1.

   ----------------------------------------------------------------------------
   §PLATE — HOW THE MAP RASTER WAS RECOVERED, AND THE PROOF IT IS EXACT
   ----------------------------------------------------------------------------
   Spec §8.1 declares the raw image bytes lossy: the MCP marks
   `styles.fills[].IMAGE -> fetch-separately`, no MCP call exports a fill by
   hash, and the @2x section PNG is the COMPOSITED plate — base + two LIGHTEN
   image fills + gradient + labels + pins — so it cannot be used as a clean
   plate. It closes with "a clean plate must be re-exported from Figma by hand,
   or the map rebuilt live."

   THIS RUN CLOSED THAT GAP without a hand export and without touching the
   Figma document. Exporting 2931:390 as SVG (read-only, save_screenshots,
   `_work/17-amenities-54/section.svg`) yields the frame as three stacked rects
   plus vector paths for the type — and Figma embeds the image fill in the SVG
   as a base64 PNG. Extracted: 2556 x 1768, RGBA, alpha uniformly 255.

     <rect width="1280" height="891" fill="#CBD6DC"/>
     <rect width="1280" height="891" fill="url(#pattern0_2931_390)"
           style="mix-blend-mode:lighten"/>
     <rect width="1280" height="891" fill="url(#paint0_linear_2931_390)"/>
     <pattern id="pattern0_2931_390" patternContentUnits="objectBoundingBox" …>
       <use xlink:href="#image0_2931_390"
            transform="matrix(0.000423316 0 0 0.000612398 -0.0819949 -0.0728764)"/>

   Inverting that matrix gives the CROP rectangle in source pixels:
       x 193.6967 .. 2555.998   =  fraction 0.075781 .. 0.999999
       y 119.0017 .. 1751.927   =  fraction 0.067309 .. 0.990909
   which is spec §3.2's reading (92.42% of width, 92.36% of height, 6.73% off
   the top) to six decimal places, independently derived. So the embedded image
   IS fills[2], hash 7db90e1c189ad56222d9187a9d595c84fa9ef6cb.

   Only ONE image is embedded. Figma's own SVG exporter dropped fills[1]
   (92481b08…), which is spec §3.3's numerically-proven finding — under LIGHTEN
   every one of its pixels is darker than the composite beneath it, so it paints
   nothing. Two independent confirmations. One raster is shipped, not two.

   The asset was then built as: crop the sub-rectangle above (float box, Lanczos),
   stretch it to 2560 x 1782 (= @2x of Figma's 1280 x 891 — CROP mode does not
   preserve aspect), and composite over #cbd6dc with per-channel max, which is
   Figma's LIGHTEN. The gradient is NOT baked in; it is §2 below, so the plate
   stays reusable if a live map ever replaces it.

   VERIFICATION, against figma-truth/sections-en/17-amenities-54.png, measured
   outside the annotation boxes over 4,378,792 pixels:
       mean |delta| per pixel   0.176 / 765
       max  |delta| per pixel   36    / 765
       pixels with |delta| > 60      0
   The residue is resampling-kernel difference (Figma's downsampler vs Lanczos)
   and is the same order as the spec's own EN-vs-ES resample test in §3.3
   (mean 0.094, max 35). The asset is 53 distinct colours, written as a 53-entry
   palette PNG that round-trips PIXEL-IDENTICAL to the 24-bit composite — 218 KB.
   Google's baked-in wordmark at x 580..660 y 866..891 is inside the crop, flush
   to the frame's own bottom edge (866..891 IS the last 25px of the 891-tall
   frame) with zero pixel rows below it in the source. R12-06 (2026-08-22)
   measured that flush edge directly and found it cuts through the glyphs
   themselves, not around them — see that item's note at §2 below, which is
   why this asset's copy of the wordmark is no longer the one Google's
   attribution requirement is satisfied by. This asset (the base plate raster)
   is otherwise unchanged by R12-06; only how §2 below uses it changed.

   ----------------------------------------------------------------------------
   §INK — measured ink boxes, why the centred label carries a 0.75px offset
   ----------------------------------------------------------------------------
   Read off the @2x reference by thresholding on the ink colours (0.5px
   granularity), per line, this run:

     hermosa   ink x 390.0..520.0  (box 389..521)   y 296.5..306.0
     airport   line 1 x 847.5..954.0  y 232.5..242.0
               line 2 x 847.5..957.5  y 250.0..265.5   (parens sit above cap)
     province  line 1 x 799.5..993.0  ink centre 896.25
               line 2 x 848.0..945.0  ink centre 896.50   box centre 896.5
     place     ink x 389.0..538.0  (box 389..539)

   Two things follow.
   1. Baseline placement needs no correction. Poppins 14px in a 21px line box
      puts the cap top at box top + 5.6px; measured 5.5 on the airport label
      (227 -> 232.5) and 5.5 on the province label (589 -> 594.5). Plain CSS
      `line-height: 21px` on a block at the Figma box top reproduces it.
   2. The CONVENTIONS §8.3 trailing-letter-space trap DOES NOT BITE HERE, and
      that was settled by measurement, not by assumption. Figma centres the ink:
      both province lines sit dead on the box centre 896.5. The prediction from
      §8.3 is that CSS centres ink PLUS the trailing 1.5px tracking and so lands
      0.75px left, and a `margin-left: 0.75px` was written to cancel it. Rendered
      and re-measured, that compensation pushed the ink to 800.5..993.5 — 0.75px
      RIGHT of Figma. Removed. Chrome does not carry the trailing letter-space
      into the centring of these lines, so the honest correction is none.
      Recorded because the trap is real elsewhere on this page; it just is not
      real on this node, and the way to know is to measure.
      "Vista Pacifico" has letter-spacing 0 and never needed one — measured ink
      389.0..538.0 is symmetric in its 389..539 box.

   ----------------------------------------------------------------------------
   §GRID — there is none, and the spec says so
   ----------------------------------------------------------------------------
   Spec §4.2 returns an explicit negative verdict: margin 0, plate full-bleed,
   and no column pitch explains the observed left edges {334, 389, 454, 485,
   799, 847, 898} — consecutive deltas 55, 65, 31, 314, 48, 51, no common
   divisor above 1. They are not layout numbers; they are where real places are
   on the raster. So: no .mk-container, no .mk-grid12, no .mk-measure-*.
   Percentage anchors of the plate (spec §4.3) are the primitive here.

   ----------------------------------------------------------------------------
   NAMING. `mk-` is ours. Everything without it — `nectar-google-map`,
   `animated-dot`, `middle-dot`, `signal`, `signal2`, `map-marker-list`,
   `map-marker`, `wpb_row`, `vc_row-fluid`, `full-width-content`,
   `row_col_wrap_12`, `vc_col-sm-12`, `wpb_column`, `vc_column-inner`,
   `wpb_wrapper`, `row-bg-wrap`, `row-bg` — is Salient's own and is NOT renamed
   (CONVENTIONS §3). Salient's JS and its vendored responsive.css query these.
   ========================================================================== */


/* ============================================================================
   §VERIFIED — the measurement this section was signed off on
   ----------------------------------------------------------------------------
   Headless Chrome @2x against figma-truth/sections-en/17-amenities-54.png,
   1280 x 891, prefers-reduced-motion forced so the pin is at REST — which is
   the state the Figma frame depicts, and the only deterministic one (the
   pulse's 180px rings tint everything within 90px of the property pin and move
   the numbers run to run).

     whole section        mean |delta| 0.498 / 765   |  pixels > 90 : 0.069 %
     plate, type excluded mean |delta| 0.271 / 765   |  max 36, i.e. the
                          resampling noise floor established in §PLATE

   Pin fills, sampled at each centre — probe vs Figma, all three identical:
     property #824267 / #824267   airport #4a5b66 / #4a5b66   coco #4a5b66 / #4a5b66

   Ink geometry, probe minus Figma (sub-pixel, darkness-weighted centroid):

     Playas del Coco        dx +0.087   dy  0.000   mass -0.08 %
     Playa HermosA          dx -0.036   dy +0.006   mass -0.06 %
     Guanacaste (line 1)    dx -0.012   dy -0.000   mass +0.15 %
     Airport (LIR) (line 2) dx -0.033   dy +0.014   mass -0.51 %
     Guanacaste Province    dx -0.073   dy +0.006   mass -0.32 %
     Costa rica             dx -0.723   dy +0.010   mass -0.30 %   <- see below
     Vista Pacifico         dx +0.344   dy -0.007   mass +1.25 %

   Pin fill boxes, probe vs Figma. The property pin is exact to the pixel at any
   threshold. The two 8px discs have identical CENTRES (904.0 and 491.0, both
   engines) but Chrome anti-aliases the outer half-pixel of a border-radius disc
   slightly softer than Figma does, so a hard threshold reads them as 7px of
   saturated fill against Figma's 8. Sub-pixel AA, not placement:
     property 456,453 -> 472,469   exact
     airport  centre 904.0 in both   coco  centre 491.0 in both

   Layout boxes read off the running page:
     1280  section 0,0,1280x891 · plate 0,1280x891 · plane 0,0,1280x891
           property dot 456,453,16x16          <- Figma's numbers exactly
     1440  section 1440x891 · plane 1440x1002.38 at y -55.69 (the cover box)
           property dot 514,454.92 — the landmark at 464x1.125 = 522 less the
           55.69 crop puts its centre at 462.9, so registration holds
     1024  plane -128,1280 wide (cover crops the sides) · dot 328,453
      640  Salient's own vendored max-height:270px clamp applies
     Horizontal overflow at 1440 / 1280 / 1024 / 640: 0 px at every width.

   THE TWO KNOWN RESIDUALS, neither of them a positioning bug:

   1. "COSTA RICA" is 0.72px left. Its rendered ink is 847.0..944.5 against
      Figma's 847.5..945.5 — 0.5px narrower, so Chrome and Figma shape that one
      line differently. Line 1 of the same node is EXACT (799.5..993.0 in both).
      A block-level shift was tried and rejected: it moves both lines together
      (+0.75 exactly, measured), so it trades an exact line for a wrong one.
      Left alone deliberately.
   2. "Vista Pacifico" carries +1.25 % more ink and is 0.34px right. Merriweather
      at opsz 18 rasterises slightly heavier in Chrome than in Figma. Vertical
      was a real half-pixel and IS corrected; horizontal weight is not
      correctable without inventing a tracking value, so it is not touched.
   ========================================================================== */


/* ============================================================================
   1. LIFTED VERBATIM — element-interactive-map.q-e857062aa1.css
   ----------------------------------------------------------------------------
   SHELL GAP, PLEASE FIX AT THE SHELL LEVEL: this stylesheet is the map
   element's entire skin and it is NOT among the 57 vendored files — the vendor
   family is `salient/resort`, which ships no map element. Until the shell
   vendors it, every rule this section needs is copied here BYTE-FOR-BYTE from
   salient-truth/elements-google-map/assets/element-interactive-map.q-e857062aa1.css.
   Values are untouched, including the raw #fff, which is Salient's byte.

   Vendored and therefore NOT repeated here: responsive.q-7f4f1bd5af.css already
   carries `.nectar-google-map{max-height:425px}` at 691-999 and
   `{max-height:270px}` at <=690. Those are Salient's captured breakpoints and
   they land close to spec §6.2's independently-reasoned tablet/mobile heights
   (~640 / ~420), so this section adds no height media query of its own.

   ONE RULE DELIBERATELY NOT LIFTED:
       html:not(.js) #contact-map, html:not(.js) .nectar-google-map{display:none}
   This shell serves `<html lang="en" class="no-js">` and NOTHING in the
   vendored JS ever swaps `no-js` for `js` (grepped: zero occurrences of the
   swap in vendor/). Lifting that rule would hide this section permanently. It
   exists upstream to hide an EMPTY container until Google fills it; our plate
   is painted in CSS and is never empty, so the rule has no job here. Flagged in
   NOTES.md as a shell-level question, not silently dropped.
   ========================================================================== */

/* element-interactive-map.css — load-bearing: it locally undoes a global
   border-box, which every number in this component assumes (lift.md §1g). */
#contact-map div,
.nectar-google-map div { box-sizing:content-box; -webkit-box-sizing:content-box }

.nectar-google-map,
.wpb_wrapper>.nectar-google-map { margin-bottom:0 }

.nectar-google-map img { max-width:none!important }

.nectar-google-map .animated-dot {
  width:20px; height:20px; left:0; top:-2px; position:relative
}

.nectar-google-map .animated-dot .middle-dot {
  width:16px; height:16px; border-radius:30px; position:absolute; left:2px; top:2px;
  transform-origin:50% 50%; animation-fill-mode:forwards; animation-iteration-count:infinite
}

.nectar-google-map .animated-dot .signal {
  width:180px; pointer-events:none; height:180px; border-radius:200px;
  position:absolute; left:-80px; top:-80px; opacity:0;
  -webkit-animation:animationSignal cubic-bezier(0,.55,.55,1) 2s;
  animation:animationSignal cubic-bezier(0,.55,.55,1) 2s;
  transform-origin:50% 50%; animation-fill-mode:forwards;
  animation-delay:.78s; animation-iteration-count:infinite
}

.nectar-google-map .animated-dot .signal2 {
  width:180px; height:180px; pointer-events:none; border-radius:200px;
  position:absolute; left:-80px; top:-80px; opacity:0;
  -webkit-animation:animationSignal cubic-bezier(0,.55,.55,1) 2s;
  animation:animationSignal cubic-bezier(0,.55,.55,1) 2s;
  transform-origin:50% 50%; animation-fill-mode:forwards;
  animation-delay:1s; animation-iteration-count:infinite
}

/* ============================================================================
   D36 · FOUNDER TRACE FT-20260817 — "the pulse is a DOUBLE pulse and reads like
   an SOS beacon. Make it a single heartbeat ping."
   ----------------------------------------------------------------------------
   THE TWO RULES ABOVE ARE THE DEFECT, AND THEY ARE VERBATIM SALIENT. Read them
   together: `.signal` and `.signal2` are the SAME 180px ring on the SAME 2s
   cycle with the SAME easing, offset only by their delays — .78s and 1.0s.
   That is two rings 220ms apart followed by 1.78s of silence, repeating: a
   two-blip radar sweep. Not a heartbeat. The founders read it as an emergency
   beacon because that is literally the signal shape.

   THE DESIGN NEVER ASKED FOR TWO. Figma 2931:465 ("Ellipse 4") is a single
   16px disc with a 2px white ring and NO rings at all — spec §7.4.2 says in as
   many words that the frame is a still showing only the resting state, so the
   ring behaviour was never specified by the artboard. It came in with the
   component, unexamined, because the lift was faithful.

   ONE RING SHIPS. `.signal` alone, unchanged, keeps its .78s delay on the 2s
   cycle: one expansion every two seconds with a long rest between — a ping.
   `.signal2` is switched off here rather than deleted from the markup, so the
   lifted marker keeps the donor's exact three-div shape (the accent rule below
   still matches it through `div[class*="signal"]`) and turning the second ring
   back on is a one-line revert.
   ========================================================================== */
.mk-map54 .animated-dot .signal2 { animation: none; opacity: 0; }

/* Verbatim. CONVENTIONS §6 bans @keyframes that DUPLICATE one of the eight
   Salient entrance primitives — this is not one of them; it is the map
   marker's own skin, and it is pure CSS, so it runs without init.js. If the
   shell later vendors element-interactive-map.css the definition is identical
   and the collision is harmless. */
@-webkit-keyframes animationSignal {
  0%  { opacity:0; transform:scale(0) }
  1%  { opacity:.25 }
  20% { opacity:.25 }
  60% { transform:scale(1); opacity:0 }
}
@keyframes animationSignal {
  0%  { opacity:0; transform:scale(0) }
  1%  { opacity:.25 }
  20% { opacity:.25 }
  60% { transform:scale(1); opacity:0 }
}

/* LIFTED from the demo page's inline <style> — the ONLY accent declaration in
   the whole component (lift.md §1d.ii). Selector byte-for-byte; the single
   value is retargeted from Salient's #3452ff to the property colour, which is
   exactly the swap spec §7.4.1 asks for. Note the `div[class*="signal"]`, which
   is Salient's, and which colours both rings. */
.nectar-google-map[data-nectar-marker-color="accent-color"] .animated-dot .middle-dot,
.nectar-google-map[data-nectar-marker-color="accent-color"] .animated-dot div[class*="signal"] {
  background-color: var(--mk-accent-property);
}


/* ============================================================================
   2. THE PLATE — full-bleed band, fixed 891, raster + wash
   ----------------------------------------------------------------------------
   Spec §6.1, read from the payload with no interpretation: height is FIXED at
   891 at both 1280 and 1440; padding is 0 on all four sides; the plate spans
   0 -> frame width. Full-bleed, no container, no side margin, at every width.
   The inline `height: 891px` on the map div is Salient's own sizing mechanism
   (lift.md §1g: "height = the inline style on the map div itself") — it is not
   a stray inline style.
   ========================================================================== */

.mk-map54 {
  background-color: var(--mk-surface-stone);   /* #cbd6dc — spec §3.1 fills[0] */
}

/* CONVENTIONS §8.6 — "Salient will fight you." Measured, then overridden, and
   here is which rule forced it. style.q-98889c766d.css ships:
       .wpb_row.full-width-content { margin-left: calc(-50vw + var(--scroll-bar-w)/2);
                                     left: 50%;
                                     width: calc(100vw - var(--scroll-bar-w)); }
   (confirmed by walking document.styleSheets against this row in the running
   page — it is the only width/margin rule that matches it besides the reset).
   That is WordPress's escape hatch for a row nested inside a fixed-width content
   container. This shell has no such container: grid.css makes every .mk-section
   a full-bleed band already, so the escape does not free the row, it OVERSHOOTS
   it — measured, the plate came out 1282 wide at x -1 instead of 1280 at 0,
   which drags every percentage anchor in §3 by up to 1.2px.
   Neutralised, not deleted. The `full-width-content` class stays on the row
   because it also carries the rule that actually matters here —
   `html body .full-width-content.vc_row-fluid .wpb_column{padding:0}` in
   grid-system.css — which is what makes the plate edge-to-edge. */
.mk-map54 .wpb_row.full-width-content {
  margin-left: 0;
  left: auto;
  width: 100%;
}

.mk-map54__plate {
  position: relative;
  width: 100%;
  overflow: hidden;                 /* clips the annotation plane to exactly the
                                       cover crop, and contains the 180px rings */

  /* fills[0] SOLID #cbd6dc, spec §3.1. The raster is composited over it under
     LIGHTEN, which is already baked into the asset (see §PLATE), so this shows
     through only where the asset is transparent — nowhere. It is the correct
     paint-behind regardless, and the paint the top wash resolves to. */
  background-color: var(--mk-surface-stone);

  /* Layer 1 (painted on top) = fills[3], the linear gradient, spec §3.5.
     gradientTransform [[~0,1,0],[-1,~0,1]] resolves to t = y, i.e. the axis
     runs top -> bottom = CSS 180deg, NOT left -> right. Stops 3 and 4 are fully
     transparent and contribute nothing under premultiplied interpolation; they
     are kept because they are what the file contains (spec §3.5 says to keep
     them in the token record). The only visible effect is a #cbd6dc wash over
     the top 0.25 x 891 = 222.75px, verified to the byte at four sample rows.
     #a5b4bd / #224366 are one-off literals: spec §3.8 records them as
     `color.gradient.tail-a` / `-tail-b` and says do NOT promote them alone.
     There is deliberately no bottom fade — land is still #f5f5f5 at y 800.

     Layer 2 = the recovered raster. `cover` not `100% 100%`: spec §5.3 rule 2
     forbids reproducing the anamorphic stretch that the 1440 artboard shows. */
  /* D37 — FOUNDER TRACE FT-20260817: "Bottom of the map looks cropped; must be
     seamless into the next section's background colour."

     WHAT WAS ACTUALLY WRONG, measured rather than eyeballed. The plate's last
     row is already 244.7/244.7/244.8 against the next section's 245/245/245, so
     the colours were never the problem — a 0.3-of-255 step is invisible. The
     crop reads as a crop because the map's LINEWORK is guillotined: sampling the
     rendered seam, the x 600..900 band carries 46px of contiguous ink running
     straight into the bottom edge and stopping dead, and the x 200..600 band 16px.
     Roads, coastline and the Google wordmark all terminate on a straight
     horizontal line. That is what a cropped screenshot looks like.

     THE FIX is a bottom ramp to the NEXT SECTION'S GROUND COLOUR — the founders'
     own words — so every stroke dissolves instead of being cut. Layer 1 below.
     `--mk-surface-plain` is the token 18-cta-expand paints its section with; it
     is referenced rather than restated so the two cannot drift apart. If the
     closing CTA's ground ever changes, this ramp follows it automatically.

     RAMP HEIGHT = 120px, AND IT IS NOT AN INVENTED NUMBER. It is
     `--mk-page-x`, this page's gutter — the same 120 the annotation column, the
     nav icon cluster and the CTA card's inset all resolve to. It is also 2.6x
     the longest measured ink run touching the edge (46px), so no stroke is cut.
     Stated as a length rather than a percentage so it does not change with the
     plate's height at other breakpoints.

     Layer 2 = fills[3], the ORIGINAL Figma gradient, unchanged. Its stops 3 and
     4 are fully transparent and contribute nothing; kept because they are what
     the file contains (spec §3.5). Its only visible effect remains the #cbd6dc
     wash over the top 222.75px.

     Layer 3 = THE GOOGLE ATTRIBUTION was re-composited here, ON TOP of the
     ramp, from R9 through R10-07. R12-06 (2026-08-22, see the full note at §2
     below) removes it from this background-image stack entirely — the crop
     it drew from is itself cut through the letters, not around them, and no
     cleaner copy exists to re-extract. R12-06 moved the attribution to a DOM
     text element, `.mk-map54__credit`; the MOBILE ROUND (2026-08-31, lane
     map) then removed that too, at all widths — see its tombstone at §2.

     Layer 3 (was 4) = the recovered raster. `cover` not `100% 100%`: spec
     §5.3 rule 2 forbids reproducing the anamorphic stretch that the 1440
     artboard shows. */
  background-image:
    linear-gradient(to top,
      var(--mk-surface-plain) 0,
      transparent var(--mk-map54-fade)),
    linear-gradient(180deg,
      var(--mk-surface-stone)   0%,
      rgba(203, 214, 220, 0)   25%,
      rgba(165, 180, 189, 0)   75%,
      rgba( 34,  67, 102, 0)  100%),
    url("../img/17-amenities-54/map-plate-guanacaste@2x.webp");
  background-size:     100% 100%, auto,      cover;
  background-position: center,    center,    center;
  background-repeat:   no-repeat, no-repeat, no-repeat;
}

/* ----------------------------------------------------------------------------
   R10-07 (round 10, 2026-08-22) fixed WHERE this layer's attribution crop sat
   on screen — two background-position overrides, bottom-6px/left-12px below
   1000/690px, closing a viewport clip and an off-screen case. Full narrative:
   founder-trace/helix/R10-07.md. Superseded below; the two position overrides
   are removed here (not edited) because R12-06 removes the layer they moved.

   R12-06 (round 12, 2026-08-22) — her report is more specific than round 10's:
   "it's a little bit cropped, and it only sorta says Google." That describes
   the GLYPHS, not the box's position — R10-07 fixed the latter and never
   inspected the former. Measured directly on the source asset,
   map-attribution-google@2x.webp (160x50 @2x = 80x25 CSS px): row 49 of 49,
   the crop's own last pixel row, still carries full ink strength (deviation
   from #f5f5f5 = 98/255 across 128 of 160px, matching every fully-inked row
   above it — no falloff, i.e. no natural letter edge). The crop cuts straight
   through the bottom of "Google". Visual confirmation, all letters' lower
   portion sliced flat: review/r12-map-attribution/attribution-8x-lanczos.png.
   Root cause predates every round this file records: the source Figma frame
   is exactly 891px tall, the wordmark sits at y866..891 (flush to the frame's
   own bottom edge, zero rows below it in the source), so there is no cleaner
   copy to re-extract — the truncation was baked in when the original
   screenshot was captured.

   TERMS RE-VERIFIED LIVE (WebFetch, developers.google.com/maps/documentation/
   javascript/policies, 2026-08-22 — not assumed from R10-07's citation, per
   this item's own instruction). Unchanged from R10-07: attribution must never
   be removed, hidden, obscured or modified. NEW, the clause R10-07 had no
   occasion to quote: "Position attribution near the top or bottom of the
   content, and within the same visual container. For a single line of
   content, attribution can be positioned to the right or left." Attribution
   is not required to be the specific pixels overlaid on the map tile — only
   to stay visible, legible, and within the same visual container as the map.
   Text fallback is explicitly sanctioned: "In cases where space is limited,
   the text Google Maps is acceptable," unmodified in capitalisation,
   line-wrapping or language; colour white, #1F1F1F or #5E5E5E at >=4.5:1
   contrast; size 12-16sp.

   THE FIX, in the order the item asks for: (1) full visual removal from the
   map SURFACE is achievable compliantly — nothing requires the graphic to sit
   on the tile itself, only that it remain in the same container — so (2) that
   ships. The broken crop is dropped from this element's background-image
   entirely (§2 above, three layers now, not four). Required attribution
   instead lives as `.mk-map54__credit` below: real DOM text reading exactly
   "Google Maps", pinned to the plate's own bottom-right corner, sitting on
   the D37 ramp's near-opaque `--mk-surface-plain` field — the same corner
   R10-07 already measured as independently ~#f5f5f5. Live text cannot
   half-crop at any width by construction, which is the actual failure mode
   this item exists to close; no per-breakpoint position hack is needed the
   way R10-07 needed one. Per-width position/contrast verification:
   founder-trace/helix/R12-06.md.
   -------------------------------------------------------------------------- */

/* LAYER ORDER IS LOAD-BEARING. In CSS the FIRST entry of `background-image`
   paints on TOP. Order, top to bottom, R12-06 (three layers, was four):
       1  the D37 ramp       (to the next section's ground colour)
       2  Figma fills[3]     (the original top wash, untouched)
       3  the map raster     (cover)
   The Google attribution is no longer one of these layers (R12-06 above),
   and no longer anywhere: R12-06's `.mk-map54__credit` DOM element was
   itself removed at all widths — MOBILE ROUND (2026-08-31, lane map), see
   the tombstone where its rule stood below.

   `transparent` is the correct far stop for the ramp rather than a hand-written
   `rgba(245,245,245,0)`: CSS gradients interpolate premultiplied, so it does not
   drag the ramp toward black, and it keeps the ramp colour-agnostic — the near
   stop is the token and the far stop is nothing, so retinting the section
   retints the ramp with no second literal to update. The same premultiplied
   behaviour is what §3.5 relies on for the original gradient's dead stops.

   `background-origin`/`-clip` are left at their defaults: the plate has no
   border and no padding, so padding-box and border-box coincide. */
.mk-map54__plate {
  /* The ramp height IS the page gutter. Declared as its own property so the
     value has one home and a breakpoint can retune it without touching the
     three-layer background shorthand above. */
  --mk-map54-fade: var(--mk-page-x, 120px);
}

/* ----------------------------------------------------------------------------
   R12-06 — THE CREDIT LINE — REMOVED. `.mk-map54__credit` ("Google Maps",
   13px, plate bottom-right) lived here from R12-06 until the MOBILE ROUND
   (2026-08-31, lane map). Founder, verbatim: "there's no reason for that
   stamp at all. Just kill it." Killed at ALL widths: the element is gone
   from sections/17-amenities-54.html (tombstone there) and this rule with
   it — removal, not display:none, because nothing else queried the class.
   R12-06's terms research above is kept as history: it, and the credit,
   become relevant again ONLY if THE ONE GAP's seam is ever filled and a
   live Google map actually renders here.
   -------------------------------------------------------------------------- */

/* Spec §1.1: the root frame reports strokeWeight 1 / strokeAlign INSIDE with an
   EMPTY strokes array, which paints nothing — pixel (1,1) of the export is
   #cbd6dc, the plate fill, not a border colour. Stated so nobody adds one. */


/* ============================================================================
   3. THE ANNOTATION PLANE — percentage anchors that hold registration
   ----------------------------------------------------------------------------
   Spec §4.3 anchors every annotation as a percentage of the plate, taken from
   the EN 1280 x 891 frame (§5.3 rule 1: EN is the geometric authority — it is
   the frame in which the annotations were registered to the raster; the ES
   1440 artboard keeps the SAME absolute x while the raster stretches 1.125x,
   which mis-registers all three pins by 58-113px. That is an authoring artifact
   to be fixed in Figma, not reproduced — spec §5.2, and it is in NOTES.md).

   The subtlety §4.3 flags: percentage anchors stay correct "provided the plate
   keeps its 1.436588 aspect". Under `background-size: cover` in a box that is
   fixed at 891 tall, it does not — at 1440 the raster is drawn 1440 x 1002.6
   and vertically centre-cropped, so a percentage of the SECTION is no longer
   the same point on the map. So this plane is sized to the cover-rendered
   raster box itself and centred over the plate. Then every anchor below is a
   percentage of the raster, exactly as Figma authored it, at any width. At
   exactly 1280 the two boxes coincide and the anchors reproduce Figma's
   absolute px unchanged. The type inside does NOT scale — spec §6.2 holds it
   constant across the ladder.
   ========================================================================== */

.mk-map54__anno {
  position: absolute;
  inset: 0;
  pointer-events: none;             /* nothing here is interactive; the pin
                                       re-enables itself in §5 */
}

/* Wider than the design frame: cover scales by WIDTH and crops top+bottom. */
@media (min-width: 1280px) {
  .mk-map54__anno {
    left: 0; right: 0;
    top: 50%; bottom: auto;
    height: auto;
    aspect-ratio: 1280 / 891;       /* == the cover-rendered raster box */
    transform: translateY(-50%);
  }
}

/* Narrower: cover scales by HEIGHT and crops left+right. */
@media (max-width: 1279.98px) {
  .mk-map54__anno {
    top: 0; bottom: 0;
    left: 50%; right: auto;
    width: auto;
    aspect-ratio: 1280 / 891;
    transform: translateX(-50%);
  }
}


/* ============================================================================
   4. TYPE — two roles, spec §2.1
   ========================================================================== */

/* map-label — Poppins Medium 500, 14/21, +1.5px, UPPERCASE, #4a5b66.
   textCase is not serialised by the MCP; the 2x export renders all four in full
   caps while `characters` is mixed case, so the case lives in CSS and the
   source string stays as authored (spec §2.1, CONVENTIONS §8.2). */
/* CONVENTIONS §8.6 again, and it is not a colour this time: style.css ships
   `p{padding-bottom:var(--nectar-paragraph-bottom-spacing,28px)}` and this
   demo resolves that variable to 1.5em. Measured on the running page, every
   label box came back 21px taller than Figma's and the place name 36px taller
   (1.5 x 14 and 1.5 x 24). It does not move the ink, but it inflates the boxes
   the fidelity harness reads, so it is zeroed on both roles.

   R12-06 had `.mk-map54__credit` in this list for the same reason; the
   MOBILE ROUND (2026-08-31, lane map) removed that element entirely (§2's
   tombstone), so the selector left with it. */
.mk-map54__label,
.mk-map54__place { padding: 0; }

.mk-map54__label {
  position: absolute;
  margin: 0;
  font-family: var(--mk-font-sans);
  font-weight: var(--mk-w-medium);
  font-size: var(--mk-size-micro);            /* 14px */
  line-height: 21px;                          /* spec §2.1 — recovered by
                                                 algebra: 1-line boxes are 21,
                                                 2-line boxes exactly 42 */
  letter-spacing: var(--mk-track-map-label);  /* 1.5px */
  text-transform: uppercase;
  color: var(--mk-ink-map-label);             /* #4a5b66 */
  white-space: nowrap;                        /* the <br> is the only break */
}

/* map-place-name — Merriweather Light 300, 24/30, tracking 0, #824267.
   `.mk-serif` supplies the family and the opsz-18 pin (CONVENTIONS §8.4). */
.mk-map54__place {
  position: absolute;
  margin: 0;
  font-weight: var(--mk-w-light);
  font-size: var(--mk-size-title);            /* 24px */
  line-height: 30px;                          /* spec §2.1 */
  color: var(--mk-accent-property);           /* #824267 */
  white-space: nowrap;
}

/* --- the five boxes, spec §4.3. Left/top are % of the plate; widths are the
       Figma box widths in px, because the type does not scale. ------------- */

/* 2931:460 — box 389, 291, 132 x 21, LEFT */
.mk-map54__label--hermosa  { left: 30.390625%; top: 32.659933%; width: 132px; }

/* 2931:392 — box 334, 366, 147 x 21, LEFT */
.mk-map54__label--coco     { left: 26.093750%; top: 41.077441%; width: 147px; }

/* 2931:462 — box 847, 227, 114 x 42, LEFT, two lines */
.mk-map54__label--airport  { left: 66.171875%; top: 25.476992%; width: 114px; }

/* 2931:634 — box 799, 589, 195 x 42, CENTER, two lines, plus the halo.
   NO trailing-letter-space compensation: §INK records the measurement that
   proved one is not needed here, and that adding the predicted 0.75px made it
   worse. Verified ink after removal — see §VERIFIED at the foot of this file.
   .mk-eyebrow--centred is also not usable: it collapses the box to fit-content,
   which would break centring across two lines of unequal width. */
.mk-map54__label--province {
  left: 62.421875%; top: 66.105499%; width: 195px;
  text-align: center;

  /* THE HALO. Figma: strokes ["#f5f5f5"], strokeWeight 11, strokeAlign OUTSIDE.
     It is REAL and it does visible work — proven this run by differencing the
     recovered clean plate against the reference inside Figma's own halo mask
     box (x788 y560 217x79): the plate carries 657 #dadadc road pixels and 483
     #ffffff casing pixels there, the reference only 147 and 176. The halo
     erases roughly three quarters of the road under the label. The colour is
     EXACTLY the map's land colour, deliberately, so it reads as the label
     eating a hole in the map (spec §2.4). Confirmed in Figma's own SVG export
     as `fill="#F5F5F5" mask="url(#path-3-outside-1_2931_390)"`.

     SPEC §2.4's PROPOSED CSS DOES NOT WORK — do not put it back. It asks for
       paint-order: stroke fill;  -webkit-text-stroke: 22px #f5f5f5;
     Rendered and measured this run: at 22px on 14px glyphs tracked 1.5px,
     Chrome does not keep the whole run's stroke behind the whole run's fill —
     neighbouring glyphs' strokes land on top of already-painted fills and eat
     them. "GUANACASTE PROVINCE" came out as "GUANACAS' E PR( VINCE". That is a
     catastrophic regression, not a subtle one, so the stroke route is out.

     text-shadow is used instead: CSS paints ALL of an element's shadows beneath
     ALL of its text, so no glyph can ever be eaten. Weight is reproduced by
     dilating the glyph mass with a lattice of zero-blur copies — six concentric
     rings at r = 11 / 8.6 / 6.2 / 3.8 / 1.6 / 0.6, 24/20/16/12/8/4 directions,
     phase-alternated. 11 is Figma's OUTSIDE stroke weight; the inner rings
     exist because the sampling gap has to stay under the ~1.6px stem width of
     Poppins Medium 14 or the dilation comes out hollow.

     KNOWN LOSSINESS, and spec §8.10 called it: Figma's 11px OUTSIDE stroke
     produces long MITRE SPIKES off the sharp glyph corners. Measured on the
     reference, one spike erases road as far as y 565 — 29px above the ink top,
     far beyond an 11px offset. A shadow lattice has round joins and cannot
     produce them. The bulk knockout is reproduced; the spikes are not. §8.10
     states plainly that neither available route is pixel-exact. */
  text-shadow:
    11px 0px 0 var(--mk-surface-plain),
    10.63px 2.85px 0 var(--mk-surface-plain),
    9.53px 5.5px 0 var(--mk-surface-plain),
    7.78px 7.78px 0 var(--mk-surface-plain),
    5.5px 9.53px 0 var(--mk-surface-plain),
    2.85px 10.63px 0 var(--mk-surface-plain),
    0px 11px 0 var(--mk-surface-plain),
    -2.85px 10.63px 0 var(--mk-surface-plain),
    -5.5px 9.53px 0 var(--mk-surface-plain),
    -7.78px 7.78px 0 var(--mk-surface-plain),
    -9.53px 5.5px 0 var(--mk-surface-plain),
    -10.63px 2.85px 0 var(--mk-surface-plain),
    -11px 0px 0 var(--mk-surface-plain),
    -10.63px -2.85px 0 var(--mk-surface-plain),
    -9.53px -5.5px 0 var(--mk-surface-plain),
    -7.78px -7.78px 0 var(--mk-surface-plain),
    -5.5px -9.53px 0 var(--mk-surface-plain),
    -2.85px -10.63px 0 var(--mk-surface-plain),
    -0px -11px 0 var(--mk-surface-plain),
    2.85px -10.63px 0 var(--mk-surface-plain),
    5.5px -9.53px 0 var(--mk-surface-plain),
    7.78px -7.78px 0 var(--mk-surface-plain),
    9.53px -5.5px 0 var(--mk-surface-plain),
    10.63px -2.85px 0 var(--mk-surface-plain),
    8.49px 1.35px 0 var(--mk-surface-plain),
    7.66px 3.9px 0 var(--mk-surface-plain),
    6.08px 6.08px 0 var(--mk-surface-plain),
    3.9px 7.66px 0 var(--mk-surface-plain),
    1.35px 8.49px 0 var(--mk-surface-plain),
    -1.35px 8.49px 0 var(--mk-surface-plain),
    -3.9px 7.66px 0 var(--mk-surface-plain),
    -6.08px 6.08px 0 var(--mk-surface-plain),
    -7.66px 3.9px 0 var(--mk-surface-plain),
    -8.49px 1.35px 0 var(--mk-surface-plain),
    -8.49px -1.35px 0 var(--mk-surface-plain),
    -7.66px -3.9px 0 var(--mk-surface-plain),
    -6.08px -6.08px 0 var(--mk-surface-plain),
    -3.9px -7.66px 0 var(--mk-surface-plain),
    -1.35px -8.49px 0 var(--mk-surface-plain),
    1.35px -8.49px 0 var(--mk-surface-plain),
    3.9px -7.66px 0 var(--mk-surface-plain),
    6.08px -6.08px 0 var(--mk-surface-plain),
    7.66px -3.9px 0 var(--mk-surface-plain),
    8.49px -1.35px 0 var(--mk-surface-plain),
    6.2px 0px 0 var(--mk-surface-plain),
    5.73px 2.37px 0 var(--mk-surface-plain),
    4.38px 4.38px 0 var(--mk-surface-plain),
    2.37px 5.73px 0 var(--mk-surface-plain),
    0px 6.2px 0 var(--mk-surface-plain),
    -2.37px 5.73px 0 var(--mk-surface-plain),
    -4.38px 4.38px 0 var(--mk-surface-plain),
    -5.73px 2.37px 0 var(--mk-surface-plain),
    -6.2px 0px 0 var(--mk-surface-plain),
    -5.73px -2.37px 0 var(--mk-surface-plain),
    -4.38px -4.38px 0 var(--mk-surface-plain),
    -2.37px -5.73px 0 var(--mk-surface-plain),
    -0px -6.2px 0 var(--mk-surface-plain),
    2.37px -5.73px 0 var(--mk-surface-plain),
    4.38px -4.38px 0 var(--mk-surface-plain),
    5.73px -2.37px 0 var(--mk-surface-plain),
    3.67px 0.98px 0 var(--mk-surface-plain),
    2.69px 2.69px 0 var(--mk-surface-plain),
    0.98px 3.67px 0 var(--mk-surface-plain),
    -0.98px 3.67px 0 var(--mk-surface-plain),
    -2.69px 2.69px 0 var(--mk-surface-plain),
    -3.67px 0.98px 0 var(--mk-surface-plain),
    -3.67px -0.98px 0 var(--mk-surface-plain),
    -2.69px -2.69px 0 var(--mk-surface-plain),
    -0.98px -3.67px 0 var(--mk-surface-plain),
    0.98px -3.67px 0 var(--mk-surface-plain),
    2.69px -2.69px 0 var(--mk-surface-plain),
    3.67px -0.98px 0 var(--mk-surface-plain),
    1.6px 0px 0 var(--mk-surface-plain),
    1.13px 1.13px 0 var(--mk-surface-plain),
    0px 1.6px 0 var(--mk-surface-plain),
    -1.13px 1.13px 0 var(--mk-surface-plain),
    -1.6px 0px 0 var(--mk-surface-plain),
    -1.13px -1.13px 0 var(--mk-surface-plain),
    -0px -1.6px 0 var(--mk-surface-plain),
    1.13px -1.13px 0 var(--mk-surface-plain),
    0.42px 0.42px 0 var(--mk-surface-plain),
    -0.42px 0.42px 0 var(--mk-surface-plain),
    -0.42px -0.42px 0 var(--mk-surface-plain),
    0.42px -0.42px 0 var(--mk-surface-plain);
}

/* 2931:393 — box 389, 469, 150 x 30, CENTER. letter-spacing is 0, so there is
   no trailing-space correction; measured ink 389.0..538.0 is symmetric. */
.mk-map54__place--property {
  left: 30.390625%;
  /* 52.637486% is Figma's y 469. The +0.5px is a MEASURED correction, not a
     nudge: Chrome and Figma agree to 0.006px on where a Poppins 14/21 baseline
     lands (all four map labels measure dy 0.000), but they disagree by exactly
     half a pixel on Merriweather 24/30 — the two engines centre the 30px line
     box on different vertical font metrics. Ink centroid before the correction:
     probe 0.508px ABOVE Figma; ink box 472.5..492.5 against Figma's 473..493.
     Re-measured after: see §VERIFIED. */
  top: calc(52.637486% + 0.5px);
  width: 150px;
  text-align: center;
}


/* ============================================================================
   5. THE PINS — Salient's nectar marker, positioned and retargeted
   ----------------------------------------------------------------------------
   Spec §7.3: `.middle-dot` is 16 x 16, which IS Figma's Ellipse 4. So the
   property pin is the marker at native size and the two secondary pins are the
   same component at half scale — one component with a size, not three shapes.

   Anchoring. Inside `.mk-map54__pin`, Salient's own numbers put the dot centre
   at (+10, +8) from the wrapper origin: `.animated-dot` is 20x20 at top:-2px,
   and `.middle-dot` is 16x16 at left/top:2px, so its centre is (10,10) inside a
   box that has been pulled up 2. The negative margins cancel that, which makes
   `left`/`top` below the TRUE pin centre — i.e. spec §4.3's centre percentages
   go in unmodified, and no font or box metric can drift them.
   ========================================================================== */

.mk-map54__pin { position: absolute; }

/* Ellipse 4 — 2931:465 — centre 464, 461. Its centre x is identical to the
   "Vista Pacifico" centre x, by design (spec §4.3), and its bottom edge is the
   label's top edge exactly, gap 0 (spec §1.3.1). */
.mk-map54__pin--property { left: 36.250000%; top: 51.739618%; margin: -8px 0 0 -10px; }

/* Ellipse 5 — 2931:497 — centre 904, 274. */
.mk-map54__pin--airport  { left: 70.625000%; top: 30.751964%; margin: -4px 0 0 -5px; }

/* Ellipse 6 — 2931:499 — centre 491, 395. A free geographic placement, NOT
   aligned to the Coco label (spec §1.3.3). */
.mk-map54__pin--coco     { left: 38.359375%; top: 44.332211%; margin: -4px 0 0 -5px; }

/* The 2px white ring. This is a MYKROBIAL ADDITION — spec §7.4.3: Salient's
   marker has no ring, Figma's three ellipses all carry one (2px, strokeAlign
   OUTSIDE, which extends the painted box by 2 on every side: 16 -> 20, 8 -> 12).
   box-shadow is the correct translation of an OUTSIDE stroke because it does
   not affect layout. Ellipse 4's payload lists the white paint TWICE; opaque
   white over opaque white is one ring (spec §3.6). --mk-ink-inverse is the
   shell's only #ffffff token; spec §3.8 names this role `color.pin.ring`. */
.mk-map54 .animated-dot .middle-dot {
  box-shadow: 0 0 0 2px var(--mk-ink-inverse);
  pointer-events: auto;                 /* .mk-map54__anno turned it off */
}

/* Secondary pins — half scale, spec §7.3/§4.3: 8px disc, same 2px ring, and
   STATIC. Spec §7.4.2 is explicit that the Figma frame is a still showing only
   the resting state, so whether these pulse is a judgement call: the
   recommendation there is static #4a5b66 discs "so the eye goes to the
   property", and that is what ships. FLAGGED FOR THE FOUNDER in NOTES.md — one
   deleted rule turns the pulse back on. Sizes override Salient's values rather
   than using transform:scale(), which would also halve the 2px ring. */
/* SPECIFICITY, and this one was caught by looking at the render, not by reading
   the cascade: the secondary discs first shipped #824267 because Salient's own
   accent rule in §1 —
     .nectar-google-map[data-nectar-marker-color="accent-color"] .animated-dot .middle-dot
   is (0,4,0) and a plain `.mk-map54__pin--airport .animated-dot .middle-dot` is
   only (0,3,0), so Salient won on specificity regardless of source order. The
   three overrides below are therefore scoped under Salient's own selector head.
   That is not decoration — drop the prefix and both pins turn magenta again. */
.nectar-google-map[data-nectar-marker-color="accent-color"] .mk-map54__pin--airport .animated-dot,
.nectar-google-map[data-nectar-marker-color="accent-color"] .mk-map54__pin--coco    .animated-dot {
  width: 10px; height: 10px; top: -1px;
}

.nectar-google-map[data-nectar-marker-color="accent-color"] .mk-map54__pin--airport .animated-dot .middle-dot,
.nectar-google-map[data-nectar-marker-color="accent-color"] .mk-map54__pin--coco    .animated-dot .middle-dot {
  width: 8px; height: 8px; left: 1px; top: 1px;
  background-color: var(--mk-ink-map-label);   /* #4a5b66 — spec §3.6 */
}

.nectar-google-map[data-nectar-marker-color="accent-color"] .mk-map54__pin--airport .animated-dot div[class*="signal"],
.nectar-google-map[data-nectar-marker-color="accent-color"] .mk-map54__pin--coco    .animated-dot div[class*="signal"] {
  display: none;
}

/* Spec §7.4.6 — suppress the two signal rings and hold the resting disc. That
   resting state is exactly what the Figma frame depicts, so this is a lossless
   fallback. Recommendation in the spec, not read from Salient, which ships no
   reduced-motion guard. */
@media (prefers-reduced-motion: reduce) {
  .mk-map54 .animated-dot .signal,
  .mk-map54 .animated-dot .signal2 { animation: none; opacity: 0; }
}


/* ============================================================================
   R7-09 · REQ-ZEBRA-5 — THE MAP FILLS ITS OWN BAND. SEAM `17 -> 18` GOES TO 0.
   ----------------------------------------------------------------------------
   THE RULE (founder-trace/FT-20260821-jehnean-round7 R7-09, derived by lane
   `r7:zebra`, full derivation in sections/01-who-why.css §8):

     ONE BREATH. The empty space between any two neighbouring things on this
     page is one breath, and a breath is always the same fraction of the screen
     you are looking at: one fifth of its SHORTER side, never under 96px and
     never over 208px. A section whose photograph runs to its own edge spends
     no breath there and its neighbour supplies the whole one.

       --mk-breath: clamp(96px, 20vmin, 208px)
         1280x900 -> 180   1440x900 -> 180   1750x980 -> 196
          834x1112 -> 166.8   390x844 -> 96 (floor)

   THIS SEAM IS THE OTHER ANSWER THE RULE GIVES: **ZERO.** The map plate runs to
   its own bottom edge and 18-cta-expand's photograph runs to its own top edge.
   Two grounds that both reach the boundary spend no breath at all, which is
   what the whole `09 -> 13` tile run already does correctly.

   MEASURED BEFORE (this lane, review/r7/r7-seams/seam-before-*.json, five fresh
   headless viewports, served bytes SHA-verified against disk):

       17 -> 18      9 / 9 / **89** / 0 / 0      at 1280 / 1440 / 1750 / 834 / 390

   The 89 exists ONLY in her band and that is the R7-10 shape exactly: a value
   that verifies clean at 1280 and misbehaves at the width she actually reviews
   at. It is also not a spacing decision anybody made — it is a MISSED LINK.
   css/rhythm.css §2 raises the SECTION to `max(891px, 100svh)` for B01 ("it is
   a map, not a reading surface, so it wants to fill the viewport"), but the
   plate inside it keeps the authored `style="height: 891px"` from the HTML. So
   at a 980-tall viewport the section is 980 and the map is 891, and the 89px
   difference paints as `--mk-surface-stone` under the map. B01's own intent is
   the fix: the map fills the band.

   `min-height`, NOT `height: … !important`. The inline 891 is Salient's own
   sizing mechanism and it is the Figma number (lift.md §1g, §2 above); it stays
   readable in the markup. `min-height` wins over `height` in the used-size
   calculation without an `!important` and without touching the HTML.

   SCOPED TO >= 1000px, deliberately, matching rhythm.css's own scope. Below it
   Salient's vendored `.nectar-google-map{max-height:425px}` (691-999) and
   `{max-height:270px}` (<=690) own the plate height — §2 above records that
   this section adds no height media query of its own there — and `min-height`
   BEATS `max-height`, so an unscoped rule would blow the tablet and phone
   plates from 425/270 to a full viewport. Both already measure a seam of 0.
   ========================================================================== */

@media (min-width: 1000px) {
  .mk-map54__plate {
    min-height: max(891px, 100svh);   /* == css/rhythm.css §2's section band */
  }
}

/* ----------------------------------------------------------------------------
   AND THE CONSEQUENCE, WHICH IS NOT OPTIONAL — §3's COVER AXIS.

   §3 sizes the annotation plane to the COVER-RENDERED RASTER BOX rather than to
   the plate, because `background-size: cover` crops. It picks the axis with a
   plain `min-width: 1280px`, and that was exactly right for as long as the
   plate was FIXED at 891: with a fixed height, plate aspect >= 1280/891 is the
   same statement as plate width >= 1280.

   The plate is no longer fixed, so the two statements have come apart. Cover
   scales by WIDTH only while

       plateW / plateH  >=  1280 / 891 = 1.436588,    plateH = max(891px, 100svh)

   At 1280x900 the plate is now 1280 x 900 = 1.4222, which is BELOW the
   threshold, so cover scales by HEIGHT there and the §3 width branch would
   register every anchor against the wrong box — up to 6.5px at the extremes.
   Small, and precisely the class of drift §3 exists to prevent.

   The third branch below restores the correct axis. `min-aspect-ratio` reads
   the VIEWPORT aspect, which is the plate's aspect whenever the plate is
   viewport-driven (svh > 891) — the only case in which this can go wrong. When
   svh <= 891 the plate is back to a fixed 891 and any viewport at >= 1280px
   wide is already above the threshold, so the branch cannot fire spuriously.
   At exactly 1280/891 both branches resolve to the same box, so the boundary is
   inclusive and harmless.

   Source order, not specificity: all three branches are (0,1,0) and this one is
   last in the file, which is CONVENTIONS §8.6's preferred way to win. Every
   property the width branch sets is restated here, so nothing leaks across.
   -------------------------------------------------------------------------- */

@media (min-width: 1280px) and (max-aspect-ratio: 1280 / 891) {
  .mk-map54__anno {
    top: 0; bottom: 0;
    left: 50%; right: auto;
    width: auto; height: auto;
    aspect-ratio: 1280 / 891;
    transform: translateX(-50%);
  }
}


/* ============================================================================
   6. R8-15 · ENTRANCE REVEAL — the five annotations, staggered, plus the
      property marker's distinct later beat
   ----------------------------------------------------------------------------
   founder-trace/FT-20260821-jehnean-round8.md, verbatim: "if you could
   actually animate in the labels, like, Playa Hermosa, Playas del Coco,
   Guanacaste Airport, Guanacaste Providence [Province], and then animate in
   the Vista Pacifico text and dot, like, animating those little text and
   dots, and [it] would be a really nice touch on that section." No right-to-
   left is named for this item, so the round's GENERAL DIRECTION applies by
   default: fade in and move UP on load (the Omai grammar), not ecology's own
   right-to-left overline+title gesture (R7-11/R7-13) — that pattern is named
   for R8-04 (sections/07-building.*) specifically, not here.

   THE MECHANISM — zero new JavaScript, zero edits to a shared file.
   js/myk-motion.js's own `start()` observes every `[data-mv]:not(.mv-in)`
   element on the page with one shared IntersectionObserver — not only the
   ones its own selector-based `adopt()` finds. That is precisely how
   sections/04-ecology.html's `data-mv-skip` and index.html's `.mk-eyebrow`
   items already opt individual elements OUT of or the page already opts
   elements INTO the vocabulary from inside a section's own markup without
   touching js/myk-motion.js. This file does the same thing in the other
   direction: the six elements below manually carry `data-mv` in
   sections/17-amenities-54.html because none of them qualify for automatic
   adoption — the four labels and "Vista Pacifico" are `<p>` tags under
   myk-motion.js's own 24-character MIN_TEXT floor (its documented reason:
   "a paragraph is a label, a unit, a separator... giving it an entrance of
   its own reads as noise", which is exactly the class these strings are in
   ON THEIR OWN — they read as noise from js/myk-motion.js's perspective
   precisely because it cannot see that R8-15 asks for this specific set as a
   deliberate, hand-picked group), and the property pin is a `<div>` that
   matches no LEAD/BODY selector at all. Manually setting `data-mv` is the
   file's own documented escape hatch working as designed, and everything
   below is scoped under `#s17-amenities-54`, which OUTRANKS
   css/myk-motion.css's (0,2,1)/(0,3,1) rules on ID alone (CONVENTIONS §8.6:
   win by specificity, never !important) — so this section owns its own
   timing without raising a fight against the shared file, the same posture
   03-unique.css takes at its own B11 (media gated on the copy's arrival).

   FAIL-OPEN IS INHERITED, NOT REBUILT. `data-mv` only becomes `opacity:0` at
   all under `html.mv`, and `html.mv` is added by js/myk-motion.js SOLELY
   when IntersectionObserver exists and prefers-reduced-motion is off (that
   file's own §0). No script here re-implements that guard — riding the
   existing gate is what makes riding it safe: no-JS, JS-error, JS-blocked and
   reduced-motion all fall through to today's fully-opaque, unanimated render,
   exactly as every other adopted element on the page already does.

   THE STAGGER STEP IS NOT INVENTED. 90ms is "the value Salient's own
   `data-animation-stagger` [carries]... two sections later. One stagger
   constant on this page" — sections/14-amenities.css:449-451, quoted rather
   than re-derived. Reusing it here keeps this section's cadence in the same
   family as the rest of the page instead of adding a second stagger number.

   ORDER: the founder named the labels Hermosa, Coco, Airport, Province — and
   that is already this file's DOM order (spec §4.3's box list), so the
   stagger below needs no re-sequencing to match her sentence.

       Hermosa   0ms
       Coco      90ms   (1 step)
       Airport   180ms  (2 steps)
       Province  270ms  (3 steps)

   THE PROPERTY MARKER IS A PAUSE, NOT A FIFTH STEP. Her words: "the Vista
   Pacifico text and dot" as its own beat, "distinct, slightly later" — not a
   continuation of the same 90ms cadence. sections/01-who-why.css:364 draws
   exactly this distinction elsewhere on the page ("not a stagger, it is a
   pause"). The gap from Province's own delay to the marker group's start is
   TWO stagger steps (180ms) rather than one, which is what makes it read as
   a pause: 270 + 180 = 450ms. Inside that one beat the dot leads and the
   name follows it by one further step (90ms) — a marker drops, then names
   itself, the ordinary reading of a map pin — landing the whole group at:

       Vista Pacifico dot     450ms  (5 steps)
       "Vista Pacifico" text  540ms  (6 steps)

   TRAVEL IS DELIBERATELY SHORTER THAN THE PAGE DEFAULT. Her own words bound
   this: "keep it light and quick, this is a map label reveal, not a hero
   moment." --myk-mv-travel is a flat 40px used page-wide (myk-motion.css's
   own §0 explains why it is flat and not em-scaled) but that number was
   measured for headlines and paragraph copy, not a 14px caption sitting
   14-30px from its neighbour on a dense annotation plane — Province's own
   box top is only 66.1% down the plate with Hermosa's at 32.7%, i.e. two
   labels can sit within a few tens of px of each other at the narrow
   viewports. A 40px rise risks a label transiently sliding through or past a
   neighbour mid-transition. 16px is under half that, keeps the motion
   perceptible without inviting the overlap, and is scoped to this section
   only — the rest of the page's `--myk-mv-travel` is untouched.

   THE PIN GETS A SCALE, NOT A TRAVEL. `data-mv="media"` supplies opacity
   only (css/myk-motion.css: "MEDIA role — opacity ONLY, no travel. Omai never
   translates an image"), which is right for a photograph but a pin is a
   glyph with no "up" that reads as natural — Google Maps' own convention is a
   marker that grows into place, not one that falls from above. `transform`
   is free on `.mk-map54__pin--property`: spec §5 above lists everything the
   selector owns — `position: absolute; left; top; margin` — no transform
   anywhere in this file or any media query touches it. The scale is applied
   to the WRAPPER, not `.animated-dot`/`.middle-dot` inside it, so it grows
   the ring, the disc and the pulse-signal container as one unit around a
   single centre, matching how the marker already reads as one glyph.

   THE PULSE IS UNTOUCHED, VERIFIED BY ELEMENT, NOT BY EYE. D36 above (this
   file) already runs `animationSignal` on `.signal`, two DOM levels below
   `.mk-map54__pin--property` (pin > .animated-dot > .signal). This block's
   opacity/transform transition targets the PIN wrapper only; nothing here
   sets a property on `.animated-dot`, `.middle-dot` or `.signal` themselves,
   so the pulse's own keyframe timeline is not paused, restarted or
   overridden — it simply pulses inside a wrapper that is, for the first
   ~450-670ms of the page's life, transitioning from half-size/transparent to
   full-size/opaque around it. `animation-fill-mode: forwards` plus
   `animation-iteration-count: infinite` on `.signal` (spec above) means it is
   already mid-loop the instant the wrapper becomes visible, which is correct
   — the ping should not wait for the entrance to notice it exists.

   COMPOSITOR-SAFE PROPERTIES ONLY. opacity and translate for the labels,
   opacity and transform for the pin — the same two categories
   css/myk-motion.css itself restricts to (that file's own §5 note on why
   Chrome can promote these for the transition's duration). Nothing here
   animates width, height, margin or a layout-triggering property.
   ========================================================================== */

#s17-amenities-54 {
  /* Local overrides of the shared vocabulary's constants — scoped here only,
     the page-wide tokens in css/myk-motion.css are untouched. */
  --mk-map54-travel: 16px;   /* half the page default; see rationale above */
  --mk-map54-step:   90ms;   /* Salient's own stagger constant, cited above */
  --mk-map54-dur:    400ms;  /* R9-15: 2x the inherited BODY role's 200ms —
                                see the duration-override rule below for why. */
}

/* --- THE FOUR LABELS + "Vista Pacifico" — shorter travel than the shared
       40px default. `[data-mv]` in the selector keeps this scoped to exactly
       the elements this file put the attribute on (not every `<p>` the page
       might ever adopt here in future), and `#s17-amenities-54` alone already
       out-specifies css/myk-motion.css's html.mv rule, so no !important.

       SPLIT IN TWO, same reason css/myk-motion.css's own §1 gives for doing
       this: a REST-state rule alone, with no `.mv-in` requirement, would
       KEEP matching after reveal (an ID-scoped selector beats the shared
       file's `:not([data-mv-t]).mv-in` reset at (0,4,1) on specificity a=1
       alone) and would pin every label at a permanent 16px vertical offset
       forever — caught by re-deriving the cascade math before measuring,
       not after. The second rule below restores `translate: 0 0` once
       `.mv-in` lands, at higher specificity again (adds the `.mv-in` class
       to an already ID-scoped selector), so it wins the SAME way the shared
       file's own reset rule was designed to. --- */
html.mv #s17-amenities-54 .mk-map54__label[data-mv],
html.mv #s17-amenities-54 .mk-map54__place--property[data-mv] {
  translate: 0 var(--mk-map54-travel);
}
html.mv #s17-amenities-54 .mk-map54__label[data-mv].mv-in,
html.mv #s17-amenities-54 .mk-map54__place--property[data-mv].mv-in {
  translate: 0 0;
}

/* --- R9-15: DURATION OVERRIDE, "poppy" -> softer. Her words: "fade those a
       little bit so they're a little less poppy... a little more smooth,
       like all of our other animations on the page." Live-measured BEFORE
       this change (review/r9-map54/before-computed.json, all 5 required
       widths, byte-identical): every label computed `transition-duration:
       0.2s, 0.2s` — the inherited BODY role's 200ms
       (css/myk-motion.css:93), untouched by this section's existing travel
       override, which only ever touched `translate`'s VALUE, never its
       timing. 200ms is right for a full paragraph (the role's design
       intent — see myk-motion.css's own "3.5x faster than lead" note) but
       reads as a snap on a two-word label already travelling a short,
       locally-halved 16px: the eye barely registers motion before
       `--myk-ease-entrance`'s heavy deceleration has already stopped it.

       This is a LOCAL override, not a retune of the shared BODY role —
       every other paragraph, caption and meta string on the page still
       gets 200ms; only these 5 elements read `--mk-map54-dur` instead.
       Same selector list as the translate-value rule two rules up (same
       reasoning: `#s17-amenities-54` ID-scoping already out-specifies the
       shared file's `html.mv [data-mv="body"]` rule, so no !important
       needed), setting ONLY `transition-duration` — `transition-property`
       (opacity, translate) and `transition-timing-function`
       (--myk-ease-entrance) still fall through from the inherited BODY
       rule since nothing here re-declares them, exactly the same
       longhand-only technique the stagger rules below already use for
       `transition-delay`. A single value broadcasts to both properties in
       the inherited 2-item `transition-property` list, so opacity and
       translate stay in lockstep — still simultaneous, not sequential,
       matching the page's one entrance grammar.

       400ms, not the shared LEAD role's 700ms: this is still a small,
       secondary label, not a heading — doubling the inherited BODY
       duration moves it decisively out of sub-250ms "instant" territory
       (the common threshold past which motion reads as deliberate rather
       than a pop) without slowing it toward the hero's own 1500ms
       fade-in-from-bottom (00-hero.css) or the LEAD role's 700ms, both
       tuned for large single-shot title text, not a compact map pin
       label. The stagger step (90ms) is untouched — it stays well under
       the new 400ms duration, so labels still visibly overlap in flight,
       the same cascading-wave feel the praised hero sequence has at its
       own (much larger) scale, not five isolated pops in a row. */
html.mv #s17-amenities-54 .mk-map54__label[data-mv],
html.mv #s17-amenities-54 .mk-map54__place--property[data-mv] {
  transition-duration: var(--mk-map54-dur);
}

/* --- THE STAGGER, in the order she named them / this file's DOM order --- */
html.mv #s17-amenities-54 .mk-map54__label--hermosa[data-mv]  { transition-delay: 0ms; }
html.mv #s17-amenities-54 .mk-map54__label--coco[data-mv]     { transition-delay: var(--mk-map54-step); }                 /* 90ms */
html.mv #s17-amenities-54 .mk-map54__label--airport[data-mv]  { transition-delay: calc(var(--mk-map54-step) * 2); }       /* 180ms */
html.mv #s17-amenities-54 .mk-map54__label--province[data-mv] { transition-delay: calc(var(--mk-map54-step) * 3); }       /* 270ms */

/* --- THE PAUSE, then the property beat: dot leads, name follows by one more
       step. See rationale above for why this is +2 steps past Province's own
       delay rather than +1 (a pause, not a fifth item in the same stagger). */
html.mv #s17-amenities-54 .mk-map54__place--property[data-mv] {
  transition-delay: calc(var(--mk-map54-step) * 6);   /* 540ms */
}

/* --- THE PIN — opacity (inherited from `data-mv="media"`) plus a scale-in
       this file adds on top. Full `transition` shorthand here intentionally
       replaces css/myk-motion.css's 1000ms media-role timing (too slow for
       "light and quick") rather than only overriding `transition-delay`, so
       the duration and curve are also this section's own call. The curve
       stays `--myk-ease-entrance` — the page's one entrance curve — because
       nothing about a faster, smaller motion needs a different feel, only a
       different amount of it. --- */
html.mv #s17-amenities-54 .mk-map54__pin--property[data-mv] {
  transform: scale(0.5);
  transform-origin: 50% 50%;
  transition:
    opacity   240ms var(--myk-ease-entrance) calc(var(--mk-map54-step) * 5),   /* 450ms */
    transform 240ms var(--myk-ease-entrance) calc(var(--mk-map54-step) * 5);
}
html.mv #s17-amenities-54 .mk-map54__pin--property[data-mv].mv-in {
  transform: scale(1);
}


/* ============================================================================
   7. MOBILE ROUND (2026-08-31, lane map / map2) — THE TALL MOBILE MAP
   ----------------------------------------------------------------------------
   ROUND 1 of this lane sized the raster BAND independently of cover — shrunk
   until the full fixed-size annotation cluster fit inside the viewport
   (fitW = (100vw - 187px) / 0.382031, a 588px band at 412) — then centred it
   in the tall 78svh plate and washed the exposed top/bottom edges. Every
   glyph fit, and the FOUNDER REJECTED IT on a real Pixel 7 (round-2 trace):
   "you didn't actually make the map bigger" — the SECTION got taller but the
   PLATE stayed near strip scale, leaving ~145-150px of fully-uniform blank
   band above and below the raster at 412x780 (measured on the shipped
   render, review probes before-412x780: uniform top 144px / bottom 151px;
   at 412x915: 196px / 205px). "I don't need this much extra blank space...
   there's a lot of blank space below the map. That's gotta go." And the way
   in: "you could move your text up and left so that you can crop off more
   of that right side", plus "GUANACASTE PROVINCE / COSTA RICA... doesn't
   have to be on that exact spot" — it names the whole region, not a point.

   ROUND 2 THEREFORE INVERTS ROUND 1'S TRADE. The band is the COVER box
   again — the raster fills the ENTIRE tall plate, edge to edge, no blank
   bands by construction — and instead of shrinking the map to fit the
   cluster, the two right-side annotations move to it:

     - The crop WINDOW slides right-of-centre over the raster: the viewport
       centre sits at band fraction 0.44 (not 0.50), i.e. the visible window
       at 412x780 is raster x 20.4%..67.5% — the Pacific dead-space on the
       far left and the inland far right are what gets cropped, exactly the
       right-side crop she sanctioned. 0.44 is DERIVED, not tuned: the Coco
       label's left edge (band frac 0.38359 minus its 110px fixed offset)
       must clear the 8px viewport margin on the narrowest supported band —
       at 320x~660 (bandW 740) that binds at c <= 0.4403; every wider phone
       is slacker (412x780 binds at 0.484). 0.44 is the floor value, so the
       whole phone range holds with one constant.
     - PROVINCE re-anchors from band centre 70.039% to 50% — a 256px leap
       left at raster scale. It is the region's name; at 50% it floats over
       inland Guanacaste, right-of-viewport-centre, clear of the Vista
       cluster (they are ~50px apart vertically at the minimum bandH) and
       its 97.5px half-width clears the right margin on the worst case
       (412x915, bandW 1025: right edge = (0.50-0.44)*1025 + 206 + 97.5
       = 365 <= 404).
     - AIRPORT (label + pin together, coherence per the founder's own
       parenthetical) re-anchors from (70.625%, 30.75%) to (52%, 21%) — up
       and left. The pin MUST move with the label: its true geographic spot
       is off-viewport under this crop (band frac 0.706 > visible edge
       ~0.64), and an on-screen label pointing at an off-screen dot is the
       incoherence she flagged. Label right edge, worst case 412x915:
       (0.52-0.44)*1025 + 206 + 57 = 345 <= 404. The label keeps its fixed
       47px stack offset above the pin (desktop: box top 227 vs pin centre
       274) as a px term, because the type does not scale (spec §6.2) —
       a %-only top would let the pin ride up into line 2 at small bandH,
       which is exactly what round 1 shipped (pin at 0.3075 vs label bottom
       at 0.2548*410+42: 6px overlap at 412x780, never flagged only because
       the ink there is sparse).

   WHY NO BLANK SPACE CAN EXIST NOW: bandW = max(100vw, plateH*1280/891).
   On every portrait phone/tablet cover wins the max() (78svh*1.4366 > vw
   whenever svh > 0.7*vw), so bandH == plateH exactly — the raster IS the
   plate, top row to bottom row, and the section's height (= the plate, the
   section holds nothing else) hugs the map treatment. The top stone wash
   and the round-1 bottom fade-to-plain stay, but as ~8px-anchored edge
   treatments over live raster, not as caps on empty bands: their stops are
   now constants (the round-1 --mk-map54-gap term is identically 0px in the
   cover regime and is retired with the fit math). The 100vw floor only
   binds in short-landscape shapes (svh < 0.7*vw), where the band overflows
   the plate vertically and background-position/`--mk-map54-bandtop` centre
   the crop — same behaviour round 1 had there.

   THE OTHER THREE ANCHORS ARE ROUND 1'S, UNCHANGED AND STILL LOAD-BEARING:
   centre-first re-anchors (ink-centre % minus half the fixed width, exact
   at bandW=1280 by the same algebra), and the Coco two-line right-aligned
   treatment. Left-side fits under the new window, worst cases: Coco label
   left 38px at 412x915, 47px at 412x780, 8.3px at 320; Hermosa 53px;
   Vista Pacifico 52px. All >= the 8px margin.

   SPECIFICITY/ORDER — unchanged mechanism: `.mk-map54 .nectar-google-map`
   (0,2,0) beats the vendored responsive.css 425/270 clamps (0,1,0); the
   anno + label + pin overrides tie their §3/§4/§5 base rules at (0,1,0)
   and win by being last in the file. Nothing here touches >=1000px:
   desktop stays pixel-identical. Motion (§6) is untouched: labels travel
   on the `translate` longhand and the pin scales on `transform`, neither
   of which any rule below declares.
   ========================================================================== */

@media (max-width: 999px) {

  .mk-map54 {
    /* The whole geometry, one derivation chain — constants documented above.
       bandleft is capped at 0 so the raster's own left edge can never slide
       into view when the 100vw floor wins the max() (short-landscape). */
    --mk-map54-plateh:  min(891px, 78svh);
    --mk-map54-bandw:   max(100vw, calc(var(--mk-map54-plateh) * 1280 / 891));
    --mk-map54-bandh:   calc(var(--mk-map54-bandw) * 891 / 1280);
    --mk-map54-bandtop: calc((var(--mk-map54-plateh) - var(--mk-map54-bandh)) / 2);
    --mk-map54-bandleft: min(0px, calc(50vw - var(--mk-map54-bandw) * 0.44));
  }

  /* Replaces the vendored 425/270 clamps' job at this section only: the tall
     plate. min() against the inline 891 keeps the Figma height the ceiling. */
  .mk-map54 .nectar-google-map {
    max-height: var(--mk-map54-plateh);
  }

  /* Same three layers as §2, mobile stops. The raster is the band = cover
     box; x is the capped bandleft as a plain length (a px value positions
     the image's LEFT edge, so the same var drives this and the anno box);
     y centres, which is a no-op in the cover regime (bandH == plateH) and
     centres the crop under the landscape floor. */
  .mk-map54__plate {
    /* Plain, not §2's stone, at this tier only — and the reason is a MEASURED
       sub-pixel artifact, not taste. A 78svh plate is fractional-height
       (713.66px at 412x915); Chrome rasterises the stretched gradient tile a
       fraction short of the box, and the uncovered last row shows this
       background-color through as a 1px stone-tinted seam line against
       18-cta-expand's plain ground (probed: row reads 239/240/241 with stone
       behind, exactly 245/245/245 with plain behind — the A/B is the only
       thing that changed). The bottom ramp already lands on plain, so plain
       IS this tier's correct paint-behind. Desktop keeps §2's stone. */
    background-color: var(--mk-surface-plain);
    background-image:
      linear-gradient(to top,
        var(--mk-surface-plain) 8px,
        transparent 168px),
      linear-gradient(180deg,
        var(--mk-surface-stone) 8px,
        rgba(203, 214, 220, 0) 208px),
      url("../img/17-amenities-54/map-plate-guanacaste@2x.webp");
    background-size:     100% 100%, 100% 100%, var(--mk-map54-bandw) var(--mk-map54-bandh);
    background-position: center, center, var(--mk-map54-bandleft) center;
    background-repeat:   no-repeat, no-repeat, no-repeat;
  }

  /* The annotation plane IS the band box — explicit width+height (the
     aspect-ratio the §3 branches lean on is inert once both are set). */
  .mk-map54__anno {
    top: var(--mk-map54-bandtop); bottom: auto;
    left: var(--mk-map54-bandleft); right: auto;
    width: var(--mk-map54-bandw);
    height: var(--mk-map54-bandh);
    transform: none;
  }

  /* Centre-first anchors — ink-centre % minus half the fixed width. Each
     collapses to its §4 left at bandW = 1280 (derivation in the header). */
  .mk-map54__label--hermosa  { left: calc(35.546875% - 66px); }    /* centre 455   */
  /* coco: RIGHT-edge anchored to its pin, not centre-anchored. The centre
     anchor (31.835938% - 73.5px) kept desktop's 83.5px centre spacing as a
     PERCENT of the band, but the 147px label is fixed — on the narrow band
     the label's right end overran the pin and the dot sat on the second "O"
     ("PLAYAS DEL C•CO", founder-visible at 412). There is not 147px of room
     left of the pin at phone widths at all (pin centre ~121px from the edge
     at 412), so the label narrows to 100px, right-aligns against the dot
     (right edge = pin centre - 10px), and wraps to two lines
     ("PLAYAS DEL / COCO"). The left clamp keeps it on-canvas on the
     narrowest bands. */
  .mk-map54__label--coco     {
    left: max(8px, calc(38.359375% - 110px));
    width: 100px;
    text-align: right;
    white-space: normal;   /* the inherited nowrap made the 100px box overflow
                              right, putting the glyphs back under the dot —
                              wrapping is the point of the narrow box */
  }
  /* AIRPORT — round 2, "(and its pin if needed for coherence) UP and LEFT".
     Label + pin move as one stack to band (52%, 21%); the true geographic
     spot (70.625%, 30.75%) is off-viewport under the 0.44 crop window, so
     coherence requires the pin to travel — founder-sanctioned, header above.
     The label's top keeps the desktop stack as a FIXED px offset (box top
     227 = pin centre 274 - 47) because the type does not scale; the pin
     rule itself is below with §5's other pin overrides. */
  .mk-map54__label--airport  {
    left: calc(52% - 57px);                                        /* centre = its pin */
    top:  calc(21% - 47px);
  }
  .mk-map54__pin--airport    { left: 52%; top: 21%; }              /* ties §5's base, wins by order */
  .mk-map54__place--property { left: calc(36.25% - 75px); }        /* centre 464 = its pin */

  /* PROVINCE — round 2, "that doesn't have to be on that exact spot": the
     region label leaves its Figma point (centre 70.039%) for band centre
     50%, notably left, floating over inland Guanacaste right-of-viewport-
     centre. ID-scoped, unlike its four siblings, because _band-mobile.css
     re-hung this one label from the plane's right edge at <=690 (`.mk-page
     .mk-map54__label--province`, (0,2,0) — its own header: "a strict no-op
     wherever the authored anchor still fits") to stop the very clip the
     cover-window fit above now prevents by construction. Its arm-2 math
     also assumes a CENTRED plane, which the 0.44-window band is not.
     (1,1,0) retires it inside this section without touching that file;
     `right: auto` unwinds its `left: auto; right: max(...)` pair. */
  #s17-amenities-54 .mk-map54__label--province {
    left: calc(50% - 97.5px);                                      /* centre = band 50% */
    right: auto;
  }
}
