/* Encanto del Valle — availability map
   Dark, warm, and deliberately quiet so the aerial carries the page. */

@font-face { font-family: Lato; src: url('./assets/fonts/lato-light.woff2') format('woff2');
             font-weight: 300; font-display: swap; }
@font-face { font-family: Lato; src: url('./assets/fonts/lato-bold.woff2') format('woff2');
             font-weight: 700; font-display: swap; }
@font-face { font-family: 'Noto Serif'; src: url('./assets/fonts/notoserif-light.woff2') format('woff2');
             font-weight: 300; font-display: swap; }

:root {
  --ink:      #121109;
  --ink-2:    #1B1912;
  --surface:  #23201704;
  --panel:    #1A180F;
  --line:     #34301F;
  --cream:    #F2EBDC;
  --muted:    #9A9382;
  --gold:     #C6A96B;
  --gold-dim: #8A7644;

  --ok:   #74C08C;   /* disponible */
  --warn: #D9A441;   /* apartado   */
  --gone: #9E5B4E;   /* vendido    */
  --mute: #82827E;   /* nd: la hoja del plano no llega hasta ese lote */
  --hold: #7D8A9C;   /* nodisp: el desarrollador los retiene ("No disponible") */

  --bar: 62px;
  --pan: 380px;
  --r: 10px;
  /* named easing, so nothing rides the browser default `ease` */
  --ease-out: cubic-bezier(.16, 1, .3, 1);
  --shadow: 0 18px 50px rgba(0,0,0,.55);
  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0; background: var(--ink); color: var(--cream);
  font: 300 15px/1.55 Lato, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
button, input { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; border-radius: 6px; }

.skip {
  position: fixed; left: 8px; top: -60px; z-index: 90; background: var(--gold); color: #17150D;
  padding: .6rem 1rem; border-radius: 8px; text-decoration: none; transition: top .15s;
}
.skip:focus { top: 8px; }

/* ---------------------------------------------------------------- top bar */
.bar {
  position: fixed; inset: 0 0 auto 0; height: var(--bar); z-index: 40;
  display: grid; grid-template-columns: 1fr minmax(0, 420px) 1fr; align-items: center; gap: 1rem;
  padding: 0 1rem; background: rgba(18,17,9,.86);
  backdrop-filter: blur(14px); border-bottom: 1px solid var(--line);
}
.bar-left  { display: flex; align-items: center; gap: .9rem; min-width: 0; }
/* Four development names on the right (the Travesía Golf Club's chip) push the bar past its
   thirds below ~1170 px: the search gives up width, the logo and tally never do. Under 861 px the
   tally is hidden and the bar has its own grid. */
@media (min-width: 861px) { .bar-left { min-width: max-content; } }
.bar-right { display: flex; justify-content: flex-end; align-items: center; gap: .6rem; }

/* Which development you are looking at. Two names on one map need a way to
   read either on its own, so the other steps back instead of competing. */
.focus { display: flex; background: #1E1C13; border: 1px solid var(--line);
         border-radius: 999px; padding: 3px; }
.focus button {
  border: 0; background: none; cursor: pointer; color: var(--muted);
  font: 500 13px/1 Lato, sans-serif; letter-spacing: .02em;
  padding: .38rem .8rem; border-radius: 999px; white-space: nowrap;
  transition: color .16s, background .16s;
}
.focus button:hover { color: var(--cream); }
.focus button.on { background: var(--gold); color: #17150D; font-weight: 700; }
.mark { height: 30px; width: auto; opacity: .95; filter: brightness(0) saturate(100%) invert(89%) sepia(14%) saturate(560%) hue-rotate(2deg) brightness(94%); }

.tally { display: flex; align-items: baseline; gap: .4rem; white-space: nowrap; }
.tally strong { font: 300 23px/1 'Noto Serif', serif; color: var(--gold);
                font-variant-numeric: tabular-nums; letter-spacing: .005em; }
.tally span { font-size: 12.5px; color: var(--muted); letter-spacing: .02em; }

.bar-mid { position: relative; min-width: 0; }
.search { display: flex; align-items: center; gap: .55rem; background: #1E1C13;
          border: 1px solid var(--line); border-radius: 999px; padding: .42rem .7rem .42rem .85rem; }
.search:focus-within { border-color: var(--gold-dim); }
.search svg { width: 16px; height: 16px; flex: none; fill: none; stroke: var(--muted); stroke-width: 1.7; }
.search input { flex: 1; min-width: 0; background: none; border: 0; outline: none; }
.search input::placeholder { color: #6E6858; }
.search kbd { font: 300 11px/1 Lato, monospace; color: #6E6858; border: 1px solid var(--line);
              border-radius: 4px; padding: 2px 5px; }

.suggest {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 5;
  margin: 0; padding: .3rem; list-style: none; max-height: 46vh; overflow: auto;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r); box-shadow: var(--shadow);
}
.suggest:empty { display: none; }
.suggest li { display: flex; justify-content: space-between; gap: .8rem; padding: .5rem .65rem;
              border-radius: 7px; cursor: pointer; }
.suggest li[aria-selected="true"], .suggest li:hover { background: #262316; }
.suggest small { color: var(--muted); }

/* ---------------------------------------------------------------- buttons */
.ghost {
  display: inline-flex; align-items: center; gap: .5rem; background: #1E1C13;
  border: 1px solid var(--line); border-radius: 999px; padding: .45rem .9rem; cursor: pointer;
}
.ghost:hover { border-color: var(--gold-dim); }
.ghost svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; }
.ghost.sm { padding: .35rem .75rem; font-size: 13.5px; }
.dot { width: 7px; height: 7px; border-radius: 50%; background: var(--gold); }

.sq {
  width: 38px; height: 38px; display: grid; place-items: center; cursor: pointer;
  background: rgba(20,18,11,.72); border: 1px solid rgba(198,169,107,.16); border-radius: 10px;
  font-size: 18px; line-height: 1; backdrop-filter: blur(12px) saturate(1.1);
  box-shadow: 0 8px 26px rgba(0,0,0,.32); transition: border-color .18s, background .18s;
}
.sq:hover { border-color: var(--gold-dim); }
/* the units control says what it is instead of drawing it: two states, and the label
   is the current unit, so it reads without a legend */
.sq--txt { font: 600 12px/1 var(--ui, system-ui), sans-serif; letter-spacing: .02em; }
.sq svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }

.cta {
  display: inline-flex; align-items: center; justify-content: center; text-decoration: none;
  background: var(--gold); color: #17150D; border-radius: 999px; padding: .6rem 1.1rem; font-weight: 700;
}
.cta:hover { filter: brightness(1.06); }

/* ---------------------------------------------------------------- filters */
.filters {
  position: fixed; top: var(--bar); left: 0; right: 0; z-index: 35;
  display: grid; grid-template-columns: auto 1fr 1fr auto; gap: 1.4rem; align-items: center;
  padding: .85rem 1rem; background: rgba(22,20,13,.94); backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}
.filters[hidden] { display: none; }
.fgroup { min-width: 0; }
.fgroup-end { display: flex; align-items: center; gap: .8rem; justify-content: flex-end; }
.flabel { display: block; font-size: 11px; letter-spacing: .13em; text-transform: uppercase;
          color: var(--muted); margin-bottom: .45rem; }
.flabel output { color: var(--cream); text-transform: none; letter-spacing: 0; margin-left: .4rem; }
.chips { display: flex; gap: .4rem; flex-wrap: wrap; }
.chip { display: inline-flex; align-items: center; gap: .45rem; cursor: pointer; font-size: 13.5px;
        background: #1E1C13; border: 1px solid var(--line); border-radius: 999px; padding: .35rem .8rem;
        opacity: .45; }
.chip.on { opacity: 1; border-color: var(--gold-dim); }
.chip b { color: var(--muted); font-weight: 300; font-variant-numeric: tabular-nums; }

.sw { width: 9px; height: 9px; border-radius: 2px; display: inline-block; flex: none; }

/* second, colour-independent channel: the outline style each status uses on the map */
.ln { width: 16px; height: 0; display: inline-block; flex: none; margin: 0 .1rem 0 -.15rem;
      border-top-width: 2px; }
.ln-d { border-top: 2px solid var(--ok); }
.ln-a { border-top: 2px dashed var(--warn); }
.ln-v { border-top: 2px dotted var(--gone); }
.ln-n { border-top: 2px dotted var(--mute); }
.ln-x { border-top: 2px dashed var(--hold); }
.sw-d { background: var(--ok); }
.sw-a { background: var(--warn); }
.sw-v { background: var(--gone); }
.sw-n { background: var(--mute); }
.sw-x { background: var(--hold); }

input[type=range] { width: 100%; appearance: none; height: 3px; border-radius: 2px;
                    background: linear-gradient(90deg, var(--gold-dim), var(--line)); }
input[type=range]::-webkit-slider-thumb {
  appearance: none; width: 15px; height: 15px; border-radius: 50%;
  background: var(--gold); border: 2px solid #17150D; cursor: pointer;
}

/* ---------------------------------------------------------------- the map */
.map { position: fixed; inset: var(--bar) 0 0 0; overflow: hidden; touch-action: none; cursor: grab; }
.map.dragging { cursor: grabbing; }
.map.picking { cursor: pointer; }
body.has-filters .map { top: calc(var(--bar) + 74px); }
body.has-panel .map { right: var(--pan); }
#cv { display: block; width: 100%; height: 100%; opacity: 0; transition: opacity .9s ease; }
body.ready #cv { opacity: 1; }
@media (prefers-reduced-motion: reduce) { #cv { opacity: 1; transition: none; } }

.hud { position: absolute; z-index: 10; display: flex; gap: .4rem; }
.hud-tl { top: 1rem; left: 1rem; }
.hud-br { right: 1rem; bottom: 3.6rem; flex-direction: column; }

/* Amenity key. Sits under the status legend, screen-fixed, scrolls on its own
   if the list ever outgrows the viewport. */
.amk {
  position: absolute; z-index: 10; left: 1rem; top: 4.1rem;
  width: 12rem; max-height: calc(100% - 9rem); overflow: auto;
  background: rgba(20,18,11,.66); border: 1px solid rgba(198,169,107,.16);
  border-radius: 14px; padding: .7rem .6rem;
  backdrop-filter: blur(12px) saturate(1.1);
  box-shadow: 0 10px 30px rgba(0,0,0,.3);
}
.amk__h { display: block; width: 100%; text-align: left; background: none; border: 0;
          padding: 0; margin-bottom: .5rem; cursor: pointer;
          font: 700 10.5px Lato, sans-serif; letter-spacing: .14em;
          text-transform: uppercase; color: var(--gold); }
.amk__list { margin: 0; padding: 0; list-style: none; display: grid; gap: .4rem; }
/* Narrower card, bigger badge: the label wraps rather than the icon shrinking,
   because the icon is the part you have to recognise at a glance. */
.amk__list li { display: grid; grid-template-columns: 2.15rem 1fr; gap: .45rem;
                align-items: center; font-size: 12px; color: #D6CFBD; line-height: 1.25; }
/* Each row wears the badge it stands for. Two treatments, the same two the map
   draws: gold for the one-of-a-kind places, dark for the ones there are five of.
   The glyph inside carries its own fill and stroke, so nothing here may set
   them: a CSS rule would beat the presentation attributes and flatten every
   silhouette back to an outline. */
.amk__i { width: 2.15rem; height: 2.15rem; flex: none; justify-self: center; }
.amk__i circle { stroke-width: 1.5; }
.amk__i--u circle { fill: var(--gold); stroke: #17150D; }
.amk__i--r { width: 1.8rem; height: 1.8rem; }
.amk__i--r circle { fill: rgba(20,18,11,.9); stroke: var(--gold); }
.amk__t { min-width: 0; }
.amk__list small { color: var(--muted); font-size: 11px; }

.legend { display: flex; gap: 1rem; align-items: center; font-size: 12px; color: #D6CFBD;
          letter-spacing: .02em;
          background: rgba(20,18,11,.62); border: 1px solid rgba(198,169,107,.16);
          border-radius: 999px; padding: .5rem 1rem; backdrop-filter: blur(12px) saturate(1.1);
          box-shadow: 0 8px 26px rgba(0,0,0,.35); }
.legend span { display: inline-flex; align-items: center; gap: .4rem; }
/* An explicit `display` outranks the UA rule behind the `hidden` attribute, so both the
   legend row and the filter chip for a status with no lots kept drawing after JS set
   hidden on them. Caught by the screenshot, not by the DOM: `el.hidden` read true while
   the pixels were still there. */
.legend span[hidden], .chip[hidden] { display: none; }

.tip {
  position: absolute; z-index: 12; pointer-events: none; transform: translate(-50%, -140%);
  background: rgba(16,15,9,.92); border: 1px solid rgba(198,169,107,.3); border-radius: 9px;
  padding: .45rem .75rem; font-size: 13px; white-space: nowrap;
  box-shadow: 0 14px 34px rgba(0,0,0,.5); backdrop-filter: blur(10px);
}
.tip b { color: var(--gold); font-weight: 700; }
.tip small { color: var(--muted); display: block; }

.hint {
  position: absolute; left: 50%; bottom: 1.1rem; transform: translateX(-50%); z-index: 10;
  font-size: 12.5px; color: var(--muted); background: rgba(18,17,9,.7);
  border: 1px solid var(--line); border-radius: 999px; padding: .35rem .9rem;
  transition: opacity .4s; backdrop-filter: blur(8px);
}
.hint.gone { opacity: 0; }
/* The course on the map is a render of what is not built yet: whenever it is on screen it says so
   (NOM-247), quietly, at the top centre where nothing else sits. */
.map-ilus { position: absolute; left: 50%; top: .8rem; transform: translateX(-50%); z-index: 10;
  font-size: 11.5px; letter-spacing: .02em; color: #D6CFBD; background: rgba(18,17,9,.72);
  border: 1px solid rgba(198,169,107,.45); border-radius: 999px; padding: .26rem .75rem;
  pointer-events: none; white-space: nowrap; backdrop-filter: blur(8px); }
.map-ilus[hidden], .map-ilus--narrow { display: none; }
@media (max-width: 860px) {
  /* a phone has no free top centre: the tag goes under the status legend instead */
  .map-ilus--wide { display: none; }
  .hud-tl { flex-direction: column; align-items: flex-start; }
  .map-ilus--narrow:not([hidden]) { display: block; position: static; transform: none; }
}

/* overview inset: on a 15,268 px plan you lose your place without one */
.mini { position: absolute; left: 1rem; bottom: 1rem; z-index: 11; width: 240px; height: 140px;
        border: 1px solid var(--line); border-radius: 8px; background: rgba(18,17,9,.8);
        box-shadow: var(--shadow); cursor: pointer; }
.mini[hidden] { display: none; }
/* 2026-10-12: zoomed in, the inset opened ON the key's last rows (they scroll inside the key, but under the
   inset they could not be read or reached). While it shows, the key ends 1 rem above it. */
@media (min-width: 861px) {
  body.has-mini .amk { max-height: calc(100% - 4.1rem - 140px - 2rem); }
}

/* Where north is. Fixed to the screen like the scalebar: the plan never rotates,
   so neither does this. */
.compass { position: absolute; right: 4.2rem; bottom: 3.6rem; z-index: 11; width: 52px; height: 52px;
           pointer-events: none; filter: drop-shadow(0 2px 6px rgba(0,0,0,.6)); }
.compass[hidden] { display: none; }
.compass circle { fill: rgba(20,18,11,.72); stroke: rgba(198,169,107,.5); stroke-width: 1.2; }
.compass .n { fill: var(--gold); }
.compass .s { fill: rgba(214,207,189,.42); }
.compass text { font: 700 9px Lato, sans-serif; fill: var(--gold); }

/* real metres, derived from their own surface figures */
.scalebar { position: absolute; right: 1rem; bottom: 1rem; z-index: 11; display: flex;
            flex-direction: column; align-items: center; gap: .25rem; pointer-events: none;
            font-size: 11.5px; color: #CFC7B4; text-shadow: 0 1px 3px rgba(0,0,0,.9); }
.scalebar[hidden] { display: none; }
.scalebar i { display: block; height: 7px; width: var(--w, 90px);
              border: 1px solid rgba(242,235,220,.85); border-top: 0; }

.measurebox { position: absolute; left: 50%; top: 1rem; transform: translateX(-50%); z-index: 14;
              background: rgba(18,17,9,.94); border: 1px solid var(--gold-dim); border-radius: 9px;
              padding: .45rem .9rem; text-align: center; backdrop-filter: blur(8px); }
.measurebox[hidden] { display: none; }
.measurebox b { color: var(--gold); font-size: 16px; display: block; font-variant-numeric: tabular-nums; }
.measurebox small { color: var(--muted); font-size: 11.5px; }
.sq[aria-pressed="true"] { border-color: var(--gold); color: var(--gold); }
.map.measuring { cursor: crosshair; }

/* ---------------------------------------------------------------- panel */
.panel {
  position: fixed; top: var(--bar); right: 0; bottom: 0; width: var(--pan); z-index: 30;
  background: var(--panel); border-left: 1px solid var(--line); overflow: auto;
  padding: 1.4rem 1.3rem 2rem; display: flex; flex-direction: column; gap: 1.2rem;
}
.panel[hidden] { display: none; }
body.has-filters .panel { top: calc(var(--bar) + 74px); }
.x { position: absolute; top: .7rem; right: .8rem; width: 32px; height: 32px; border-radius: 50%;
     background: none; border: 1px solid var(--line); cursor: pointer; font-size: 19px; line-height: 1; }
.grab { display: none; }

.p-head h2 { margin: .35rem 0 .15rem; font: 300 32px/1.08 'Noto Serif', serif;
              letter-spacing: -.01em; }
.muted { color: var(--muted); font-size: 13px; margin: 0; }
.pill { display: inline-block; font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase;
        border-radius: 999px; padding: .2rem .6rem; border: 1px solid currentColor; }
.pill.disponible { color: var(--ok); }
.pill.apartado   { color: var(--warn); }
.pill.vendido    { color: var(--gone); }
.pill.nodisp     { color: var(--hold); }

.facts { margin: 0; display: grid; gap: .1rem; }
.facts > div { display: flex; justify-content: space-between; gap: 1rem; align-items: baseline;
               padding: .62rem 0; border-bottom: 1px solid var(--line); }
.facts dt { color: var(--muted); font-size: 13px; }
.facts dd { margin: 0; font-variant-numeric: tabular-nums; text-align: right; }
.facts dd.up { color: var(--warn); }
.facts dd.down { color: var(--ok); }
/* The promotion in force (2026-10-06): the list price struck through, the promotion's beside it. */
.facts > div[hidden] { display: none; }
.facts dd .was { color: var(--muted); margin-right: .2em; }
#pPrice:has(.was), #pUnit:has(.was), #pPromo { color: var(--gold); }

.p-sides h3 { margin: 0 0 .4rem; font-size: 13px; font-weight: 700; letter-spacing: .04em;
               text-transform: uppercase; color: var(--muted); }
.p-sides ul { margin: 0; padding: 0; list-style: none; display: grid; gap: .1rem; }
.p-sides li { display: flex; align-items: baseline; gap: .6rem;
              padding: .42rem 0; border-bottom: 1px solid var(--line); }
.p-sides li:last-child { border-bottom: 0; }
.sd-c { color: var(--muted); font-size: 13px; }
.sd-m { margin-left: auto; font-variant-numeric: tabular-nums; font-weight: 600; }
/* the metric figure kept beside an imperial one: present, clearly secondary. Metres are
   what the deed says; feet are the reference Miguel asked for. */
.alt-u { margin-left: .4em; font-weight: 300; font-size: .88em; color: var(--muted); }
.sd-lc { color: var(--gold); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.sd-src { margin: .5rem 0 0; font-size: 11.5px; }

.p-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.p-actions .cta { margin-left: auto; }

.p-fig { margin: 0; }
.p-fig img { width: 100%; height: auto; border-radius: var(--r); display: block; background: #241F16; }
.p-fig figcaption { margin-top: .5rem; }

/* ---------------------------------------------------------------- compare */
.tray {
  position: fixed; left: 1rem; bottom: 1rem; z-index: 32; display: flex; align-items: center; gap: .6rem;
  background: rgba(26,24,15,.95); border: 1px solid var(--line); border-radius: var(--r);
  padding: .6rem .7rem; box-shadow: var(--shadow); backdrop-filter: blur(10px);
}
body.has-panel .tray { left: 1rem; }
.tray[hidden] { display: none; }
.tray-items { display: flex; gap: .5rem; }
.tcard { min-width: 118px; border: 1px solid var(--line); border-radius: 8px; padding: .45rem .6rem; }
.tcard b { display: block; font-size: 14px; }
.tcard small { color: var(--muted); font-size: 11.5px; display: block; }
.tcard button { float: right; background: none; border: 0; color: var(--muted); cursor: pointer; }
.tnote { color: var(--gold-dim) !important; margin-top: .3rem; }

.ctable { border-collapse: collapse; font-size: 13px; }
.ctable th, .ctable td { padding: .3rem .7rem; text-align: right; white-space: nowrap;
                         border-bottom: 1px solid var(--line); }
.ctable thead th { color: var(--cream); font-weight: 700; border-bottom-color: var(--gold-dim); }
.ctable tbody th { text-align: left; color: var(--muted); font-weight: 300; }
.ctable td { font-variant-numeric: tabular-nums; }
.ctable td.best { color: var(--ok); }
.ctable thead th button { background: none; border: 0; color: var(--muted); cursor: pointer;
                          margin-left: .3rem; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }

/* ------------------------------------------------- amenity photo viewer */
.dpx { width: min(1100px, 94vw); max-height: 92vh; padding: 0; border: 1px solid var(--line);
       border-radius: 16px; background: var(--ink); color: var(--cream);
       box-shadow: 0 30px 90px rgba(0,0,0,.6); overflow: hidden; }
.dpx::backdrop { background: rgba(6,6,3,.78); backdrop-filter: blur(3px); }
.dpx-head { display: flex; align-items: center; gap: .7rem; padding: .8rem 1rem;
            border-bottom: 1px solid var(--line); }
.dpx-head strong { font-size: 15px; }
.dpx-head .x { margin-left: auto; background: none; border: 0; color: var(--muted);
               font-size: 22px; line-height: 1; cursor: pointer; padding: 0 .3rem; }
.dpx-head .x:hover { color: var(--cream); }
/* The frame keeps the photo's shape while it travels. Without it a slow connection
   showed a collapsed strip (name, arrows and caption stacked on nothing), and a failed
   photo showed the browser's broken-image icon and its alt text (office, 2026-10-07).
   The ratio is the real photos'; the taller golf renders grow the frame once they land. */
.dpx-stage { position: relative; background: #0b0a06; display: grid; place-items: center;
             /* width stated, or the 68vh cap carries through the ratio and narrows the frame */
             width: 100%; aspect-ratio: 1920 / 1072; max-height: 68vh; }
.dpx-stage img { display: block; max-width: 100%; max-height: 68vh; transition: opacity .25s; }
.dpx-stage.is-wait img, .dpx-stage.is-err img { opacity: 0; }
.dpx-note { position: absolute; inset: 0; margin: 0; display: none; place-content: center;
            justify-items: center; gap: .8rem; padding: 1rem; text-align: center;
            font-size: 13px; color: #D6CFBD; }
/* the wait note shows only if the photo is actually slow, so a cached one never flashes it */
.dpx-stage.is-wait .dpx-wait { display: grid; animation: dpx-in .2s .25s both; }
.dpx-stage.is-err .dpx-err { display: grid; }
.dpx-wait::before { content: ''; width: 28px; height: 28px; border-radius: 50%;
                    border: 2px solid rgba(198,169,107,.25); border-top-color: var(--gold);
                    animation: dpx-spin .9s linear infinite; }
.dpx-err button { font: inherit; color: var(--cream); background: none; cursor: pointer;
                  border: 1px solid var(--gold); border-radius: 999px; padding: .45rem 1.1rem; }
.dpx-err button:hover { background: rgba(198,169,107,.18); }
@keyframes dpx-spin { to { transform: rotate(360deg); } }
@keyframes dpx-in { from { opacity: 0; } to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .dpx-wait::before { animation-duration: 2.4s; } }
.dpx-nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
           width: 40px; height: 56px; border: 0; border-radius: 8px; cursor: pointer;
           background: rgba(12,11,6,.55); color: var(--cream); font-size: 26px; line-height: 1;
           transition: background .15s; }
.dpx-nav:hover { background: rgba(198,169,107,.35); }
.dpx-prev { left: .6rem; } .dpx-next { right: .6rem; }
/* renders of what is not built yet say so, beside their caption (NOM-247) */
.dpx-capline { display: flex; align-items: center; flex-wrap: wrap; gap: .4rem .7rem; padding: .7rem 1rem .2rem; }
.dpx-capline .dpx-cap { padding: 0; }
.dpx-ilus { flex: none; padding: .2rem .55rem; font-size: 11px; letter-spacing: .02em; color: #D6CFBD;
  border: 1px solid rgba(198,169,107,.45); border-radius: 999px; }
.dpx-ilus[hidden] { display: none; }
/* the Travesía Golf Club's site, on its pins (2026-10-07) */
.dpx-site { margin-left: auto; font-size: 12px; color: var(--gold); text-decoration: none; white-space: nowrap; }
.dpx-site:hover { text-decoration: underline; }
.dpx-site[hidden] { display: none; }
/* a golf lot's club name opens the club's site */
.club-link { color: inherit; text-decoration: underline; text-decoration-color: var(--gold-dim); text-underline-offset: 3px; }
.club-link:hover { color: var(--gold); }
.dpx-cap { margin: 0; padding: .7rem 1rem .2rem; font-size: 13px; color: #D6CFBD; }
.dpx-dots { display: flex; gap: .4rem; padding: .5rem 1rem 1rem; }
.dpx-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--line); cursor: pointer; }
.dpx-dots i.on { background: var(--gold); }

@media (max-width: 760px) {
  /* Full screen, but the picture centres in it. Pinned to the top it left two
     thirds of the phone empty under the dots. */
  .dpx { width: 100%; max-width: none; height: 100dvh; max-height: none; border: 0; border-radius: 0; }
  /* [open] matters: a bare `display:flex` beats the UA's `display:none` on a
     CLOSED dialog, and a full-screen invisible sheet then eats every tap on the
     map. Local phone went from 954 hover hits to zero. */
  .dpx[open] { display: flex; flex-direction: column; }
  .dpx-stage { flex: 1 1 auto; min-height: 0; aspect-ratio: auto; max-height: none; }
  .dpx-stage img { max-height: 100%; }
  .dpx-cap { padding-top: 1rem; }
  .dpx-capline { padding-top: 1rem; }
  .dpx-dots { padding-bottom: 1.6rem; }
}

/* ---------------------------------------------------------------- loading */
.loading { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center;
           background: var(--ink); transition: opacity .5s; }
.loading.done { opacity: 0; pointer-events: none; }
.loading span { width: 34px; height: 34px; border: 2px solid var(--line);
                border-top-color: var(--gold); border-radius: 50%; animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------------- mobile */
@media (max-width: 860px) {
  .bar { grid-template-columns: auto 1fr auto; gap: .6rem; padding: 0 .7rem; }
  .tally { display: none; }
  .mark { height: 24px; }
  .search kbd { display: none; }
  /* The development switch stays, the wording shrinks: at 414 px the three
     labels at desktop size push the logo out from under themselves. */
  .bar-right { gap: .4rem; }
  .focus button { padding: .34rem .5rem; font-size: 11.5px; letter-spacing: 0; }
  .filters { grid-template-columns: 1fr; gap: .9rem; }
  body.has-filters .map { top: calc(var(--bar) + 230px); }
  body.has-panel .map { right: 0; }

  .panel {
    top: auto; left: 0; right: 0; width: auto; max-height: 72vh;
    border-left: 0; border-top: 1px solid var(--line);
    border-radius: 16px 16px 0 0; padding-top: 1.6rem;
  }
    .grab { display: block; position: absolute; top: 0; left: 0; right: 0; height: 26px;
          cursor: grab; touch-action: none; }
  .grab::after { content: ''; position: absolute; top: .6rem; left: 50%; transform: translateX(-50%);
          width: 38px; height: 4px; border-radius: 2px; background: var(--line); }
  .panel { transition: max-height .18s ease; }
  .hud-br { bottom: auto; top: 1rem; }
  .mini { display: none; }
  .scalebar { right: .8rem; bottom: .8rem; }
  .hint { bottom: 3.5rem; top: auto; left: 50%; transform: translateX(-50%);
          max-width: calc(100% - 1.4rem); }
  .panel { max-height: 66vh; }
  .tray { left: .7rem; right: .7rem; bottom: .7rem; overflow-x: auto; }

  /* A 15.5 rem key over a 414 px screen IS the map. On a phone it shuts down
     to its own heading and opens on a tap, low on the left where the mini map
     used to sit. */
  .amk { top: auto; bottom: .7rem; left: .7rem; width: auto;
         max-width: calc(100% - 5.2rem); max-height: 54vh; padding: .5rem .65rem; }
  .amk__list li { grid-template-columns: 1.55rem 1fr; font-size: 11.5px; }
  .amk__i { width: 1.55rem; height: 1.55rem; }
  .amk__i--r { width: 1.3rem; height: 1.3rem; }
  .amk__h { display: flex; align-items: center; justify-content: space-between; gap: .5rem;
            margin-bottom: 0; }
  .amk__h::after { content: ''; flex: none; width: 0; height: 0;
                   border-left: 4.5px solid transparent; border-right: 4.5px solid transparent;
                   border-top: 5px solid var(--gold-dim); transition: transform .18s; }
  .amk.is-shut { overflow: hidden; }
  .amk.is-shut .amk__h::after { transform: rotate(-90deg); }
  .amk.is-shut .amk__list { display: none; }
  .amk:not(.is-shut) .amk__list { margin-top: .55rem; }
  /* the sheet owns the bottom of a phone; a key buried under it is worse
     than no key */
  body.has-panel .amk { display: none; }

  /* the legend wraps instead of running under the button column */
  .hud-tl { left: .7rem; right: 4.3rem; }
  .legend { flex-wrap: wrap; gap: .3rem .8rem; font-size: 11px;
            padding: .45rem .8rem; border-radius: 14px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* ------------------------------------------------- link across to the 360 tour
   The tour and the map are the same place seen two ways; before this they were two
   URLs that had never heard of each other. */
.see360 {
  display: flex; align-items: center; gap: .7rem; margin: 0 0 .9rem;
  padding: .6rem .8rem; border-radius: var(--r); text-decoration: none; color: var(--cream);
  background: linear-gradient(90deg, rgba(198,169,107,.15), rgba(198,169,107,.05));
  border: 1px solid rgba(198,169,107,.28);
  transition: border-color .18s var(--ease-out), background .18s var(--ease-out);
}
/* gated: on touch, a plain :hover latches after the tap and stays lit */
@media (hover: hover) {
  .see360:hover { border-color: var(--gold); background: linear-gradient(90deg, rgba(198,169,107,.26), rgba(198,169,107,.08)); }
}
.see360[hidden] { display: none; }
.see360 .s-eye {
  width: 34px; height: 34px; flex: none; display: grid; place-items: center;
  border-radius: 50%; background: rgba(198,169,107,.16); color: var(--gold);
}
.see360 svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.5; }
.see360 .s-txt { display: flex; flex-direction: column; line-height: 1.3; min-width: 0; }
.see360 strong { font-weight: 700; font-size: 14px; }
.see360 em { font-style: normal; font-size: 12.5px; color: var(--muted); }

/* the 3D entry is the same affordance as the 360 one, so it is the same object.
   It is a button rather than a link because it opens in place, not elsewhere. */
.see3d { width: 100%; font: inherit; text-align: left; cursor: pointer; }
.see3d[aria-busy="true"] { opacity: .55; cursor: progress; }
.see3d:active { transform: translateY(1px); }

/* -------------------------------------------------------------- 3D dialog */
/* Native <dialog>: it brings the top layer, the backdrop, focus containment and Escape
   with it, so none of that is reimplemented here. */
.d3d {
  width: min(1600px, 96vw); height: min(1040px, 92vh); padding: 0; border: 1px solid var(--line);
  border-radius: var(--r); background: var(--panel); color: var(--cream);
  box-shadow: var(--shadow); overflow: hidden;
  grid-template-rows: auto 1fr auto;
}
.d3d[open] { display: grid; }
.d3d::backdrop { background: rgba(8,7,4,.72); backdrop-filter: blur(3px); }

.d3d-head { display: flex; align-items: center; justify-content: space-between; gap: 1rem;
            padding: .85rem 1rem .85rem 1.2rem; border-bottom: 1px solid var(--line); }
.d3d-title { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
.d3d-title strong { font: 300 21px/1.15 'Noto Serif', serif; }
.d3d-title em { font-style: normal; font-size: 12.5px; }
.d3d .x { position: static; flex: none; }

.d3d-stage { position: relative; background: var(--ink-2); min-height: 0; }
.d3d-stage gmp-map-3d { width: 100%; height: 100%; display: block; }
.d3d-msg { position: absolute; inset: 0; margin: 0; display: grid; place-items: center;
           align-content: center; gap: .9rem; text-align: center; padding: 2rem;
           color: var(--muted); font-size: 14px; }
.d3d-msg[hidden] { display: none; }
.d3d-msg p { margin: 0; max-width: 34ch; }
/* a failed view must not read like one that is still loading */
.d3d-msg .warn { display: none; width: 26px; height: 26px; fill: none; stroke: currentColor;
                 stroke-width: 1.5; stroke-linecap: round; }
.d3d-msg.is-error { color: var(--gone); }
.d3d-msg.is-error .warn { display: block; }

.d3d-note { margin: 0; padding: .7rem 1.2rem; border-top: 1px solid var(--line);
            font-size: 12.5px; color: var(--muted); background: rgba(198,169,107,.06); }
.d3d-note[hidden] { display: none; }

@media (max-width: 760px) {
  /* 100% and not 100vw: the dialog is already inset in the top layer, and 100vw
     overshoots by the scrollbar width the moment this breakpoint is ever raised. */
  .d3d { width: 100%; height: 100dvh; max-width: none; max-height: none; border: 0; border-radius: 0; }
}

/* a lot arrived at from the tour gets found, not hunted for */
@keyframes nearPulse { 0%,100% { opacity: .25 } 50% { opacity: .75 } }

/* Narrow phones (2026-09-21). One bar row cannot hold logo + search + development
   switch + Filtros at 375 px: measured, the search box had shrunk to 27 px and the
   switch sat on top of it. Two rows: the switch takes the second, centred, and --bar
   grows with it so the map, the filters sheet and the panel keep their offsets. The
   hint used to sit across the compass; it now sits above it. */
@media (max-width: 480px) {
  :root { --bar: 100px; }
  .bar { grid-template-columns: auto 1fr auto; grid-template-rows: 54px 40px; row-gap: 0;
         align-content: start; padding-top: 2px; }
  .bar-right { display: contents; }
  .bar-left { grid-row: 1; }
  .bar-mid { grid-column: 2; grid-row: 1; }
  #filterBtn { grid-column: 3; grid-row: 1; }
  #focus { grid-column: 1 / -1; grid-row: 2; justify-self: center; align-self: start; }
  .hint { bottom: 7.6rem; }
  /* the suggestion list was as narrow as the search box (167 px) and wrapped every
     name; it now spans the bar, anchored to the fixed bar instead of .bar-mid */
  .bar-mid { position: static; }
  .suggest { top: 54px; left: .7rem; right: .7rem; }
  .suggest li { padding: .55rem .7rem; }
}

/* ---------------------------------------------------------------- the associate (2026-10-06)
   A visitor who came through a sales associate's personal link (/con/<slug>) sees that person in
   the top bar (app.js fits the chip: full, then photo + button, then the photo alone) and, with a
   lot open, a question to them pinned at the foot of the sheet. Nobody else sees either. */
.as-wa { display: block; width: 15px; height: 15px; flex: none; background: currentColor;
         -webkit-mask: url('../icons/icon_whatsapp.svg') center / contain no-repeat;
         mask: url('../icons/icon_whatsapp.svg') center / contain no-repeat; }

.as-chip { display: flex; align-items: center; gap: 7px; flex: none; height: 40px; padding: 4px;
           border-radius: 999px; background: #1E1C13; border: 1px solid var(--line); color: var(--cream);
           text-decoration: none; white-space: nowrap; transition: border-color .18s; }
.as-chip[hidden] { display: none; }
.as-chip:hover { border-color: var(--gold-dim); }
.as-chip__face { position: relative; display: block; flex: none; }
.as-chip__face img { display: block; width: 30px; height: 30px; border-radius: 50%; object-fit: cover;
                     box-shadow: 0 0 0 1.5px var(--gold); }
.as-chip__txt { display: flex; flex-direction: column; gap: 3px; padding-right: 2px; }
.as-chip__txt small { font: 700 8px/1 Lato, sans-serif; letter-spacing: .1em; text-transform: uppercase; color: var(--gold); }
.as-chip__txt b { font: 300 15px/1 'Noto Serif', serif; }
.as-chip__wa { display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%;
               background: var(--gold); color: #17150D; }
.as-badge { display: none; position: absolute; right: -5px; bottom: -3px; width: 17px; height: 17px;
            border-radius: 50%; background: #fff; box-shadow: 0 0 0 2px var(--ink); }
.as-badge::after { content: ''; position: absolute; inset: 3.5px; background: #8d702b;
                   -webkit-mask: url('../icons/icon_whatsapp.svg') center / contain no-repeat;
                   mask: url('../icons/icon_whatsapp.svg') center / contain no-repeat; }
.as-chip[data-fit="compact"] .as-chip__txt { display: none; }
.as-chip[data-fit="face"] { height: auto; padding: 0; gap: 0; border: 0; background: none; }
.as-chip[data-fit="face"] .as-chip__txt, .as-chip[data-fit="face"] .as-chip__wa { display: none; }
.as-chip[data-fit="face"] .as-chip__face img { width: 36px; height: 36px;
                                              box-shadow: 0 0 0 1.5px var(--gold), 0 4px 14px rgba(0,0,0,.45); }
.as-chip[data-fit="face"] .as-badge { display: block; }
.as-chip:focus-visible { border-radius: 999px; }
@media (max-width: 480px) {
  /* the switch's row is centred and leaves its right end free */
  #asesorChip { grid-column: 3; grid-row: 2; justify-self: end; align-self: center; }
}

/* the sheet's question: .cta sets display, so [hidden] needs saying */
#waLink[hidden] { display: none; }
.p-ask { position: sticky; bottom: -2rem; z-index: 3; margin: auto -1.3rem -2rem; padding: .85rem 1.3rem 1rem;
         display: flex; align-items: center; gap: .8rem; background: var(--panel);
         border-top: 1px solid var(--line); box-shadow: 0 -14px 24px rgba(18,17,9,.7); }
.p-ask[hidden] { display: none; }
.p-ask img { width: 44px; height: 44px; flex: none; border-radius: 50%; object-fit: cover;
             box-shadow: 0 0 0 1.5px var(--gold); }
.p-ask .cta { flex: 1; gap: .55rem; padding: .72rem 1rem; font-size: 14px; }
.p-ask .cta .as-wa { width: 16px; height: 16px; }
