/* Plot map — three panes: filters, map, list/selected.
 *
 * Nothing here knows a status code or a category colour; both arrive from the API and are
 * written into inline styles at runtime, so re-colouring the legend is a database edit.
 *
 * The palette is One Central's: forest greens off the corporate masthead, bronze for every
 * accent and selected state, and warm neutrals rather than cold blue-greys, so the panels sit
 * quietly either side of satellite imagery.
 */
:root{
  /* brand */
  --forest:#1b2018; --forest-2:#2b3026; --forest-3:#4e503e;
  --bronze:#d4b45c; --bronze-2:#c1a454; --bronze-3:#8a7433;
  --bronze-tint:#f7f0dd; --bronze-line:#e6d6aa;

  /* neutrals */
  --ink:#232620; --ink-2:#3c4038; --muted:#6f7268;
  --paper:#fff; --paper-2:#faf9f5; --paper-3:#f2f0e9;
  --line:#e6e3da; --card-line:#e6e3da;

  /* depth + shape */
  --sh-1:0 1px 2px rgba(27,32,24,.05), 0 2px 8px rgba(27,32,24,.05);
  --sh-2:0 2px 6px rgba(27,32,24,.07), 0 10px 26px rgba(27,32,24,.10);
  --sh-3:0 12px 38px rgba(27,32,24,.24);
  --ring:0 0 0 3px rgba(212,180,92,.35);
  --r-sm:9px; --r:12px; --r-lg:16px;

  --rail:340px;
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-t: env(safe-area-inset-top, 0px);
}
*{box-sizing:border-box}
html,body{margin:0;height:100%;overscroll-behavior:none}
body{
  font:15px/1.5 "Nunito Sans",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  color:var(--ink); background:#0f120e;
  -webkit-tap-highlight-color:transparent;
  -webkit-font-smoothing:antialiased;
}
.shell{display:flex;flex-direction:column;height:100%}
@supports (height:100dvh){.shell{height:100dvh}}
.leaflet-container{font:inherit;background:#0f120e}

/* One focus treatment everywhere, so keyboard users get the bronze ring and nobody gets the
   browser default blue on a page that has no blue left in it. */
:where(button,a,input,select,textarea,[tabindex]):focus-visible{
  outline:none;box-shadow:var(--ring);
}

/* Thin, warm scrollbars — the rails scroll a lot and the default bars are loud. */
.rail-body,.checks.scroll,.legend,#plot-list{scrollbar-width:thin;scrollbar-color:#cdcabd transparent}
.rail-body::-webkit-scrollbar,.checks.scroll::-webkit-scrollbar,
.legend::-webkit-scrollbar,#plot-list::-webkit-scrollbar{width:10px;height:10px}
.rail-body::-webkit-scrollbar-thumb,.checks.scroll::-webkit-scrollbar-thumb,
.legend::-webkit-scrollbar-thumb,#plot-list::-webkit-scrollbar-thumb{
  background-color:#cdcabd;border-radius:20px;border:3px solid transparent;background-clip:content-box;
}
.rail-body::-webkit-scrollbar-thumb:hover,#plot-list::-webkit-scrollbar-thumb:hover{background-color:#b3b0a2}


/* ---------- layout ---------- */
.workspace{flex:1;display:flex;min-height:0;position:relative}
.stage{flex:1;position:relative;min-width:0}
#map{position:absolute;inset:0}

.rail{
  width:var(--rail);flex:none;background:var(--paper-2);display:flex;flex-direction:column;
  min-height:0;z-index:600;
}
.rail-left{border-right:1px solid var(--line)}
.rail-right{border-left:1px solid var(--line)}
.rail[hidden]{display:none}

.rail-head{
  display:flex;align-items:center;justify-content:space-between;gap:8px;
  padding:15px 16px;color:#fff;
  background:linear-gradient(115deg,var(--forest) 0%,var(--forest-3) 100%);
  border-bottom:1px solid rgba(212,180,92,.45);
}
.rail-head h2{
  margin:0;font-size:15px;font-weight:700;letter-spacing:.3px;
  display:flex;align-items:center;gap:9px;
}
.rail-head svg{width:18px;height:18px;fill:none;stroke:var(--bronze);stroke-width:2;stroke-linecap:round}
.rail-toggle{
  border:1px solid rgba(255,255,255,.18);background:rgba(255,255,255,.08);color:#fff;
  width:30px;height:30px;border-radius:var(--r-sm);cursor:pointer;font-size:15px;line-height:1;
  transition:background-color .18s ease,color .18s ease,border-color .18s ease;
}
.rail-toggle:hover{background:var(--bronze);border-color:var(--bronze);color:var(--forest)}
.rail-body{flex:1;overflow:auto;padding:14px;min-height:0}
.rail-foot{
  border-top:1px solid var(--line);padding:13px 14px;background:var(--paper);
  box-shadow:0 -6px 18px rgba(27,32,24,.05);
}

.rail-open{
  position:absolute;top:50%;transform:translateY(-50%);z-index:650;
  border:1px solid var(--line);background:var(--paper);color:var(--forest);
  width:26px;height:56px;cursor:pointer;font-size:15px;display:none;
  box-shadow:var(--sh-2);
}
.rail-open:hover{background:var(--bronze);border-color:var(--bronze)}
.rail-open.left{left:0;border-radius:0 var(--r) var(--r) 0}
.rail-open.right{right:0;border-radius:var(--r) 0 0 var(--r)}
.rail-open.is-on{display:block}

/* ---------- filter groups ---------- */
.fgroup{
  border:1px solid var(--line);border-radius:var(--r-lg);padding:14px;margin-bottom:12px;
  background:var(--paper);box-shadow:var(--sh-1);
}
.fgroup h3{
  margin:0 0 11px;font-size:12px;font-weight:700;letter-spacing:.7px;text-transform:uppercase;
  color:var(--ink-2);display:flex;align-items:center;gap:9px;
}
.fgroup h3::before{
  content:"";width:7px;height:7px;border-radius:50%;flex:none;
  background:var(--bronze);box-shadow:0 0 0 3px rgba(212,180,92,.22);
}
.tag{
  background:var(--bronze-tint);color:var(--bronze-3);border:1px solid var(--bronze-line);
  border-radius:20px;padding:1px 9px;font-size:11px;font-weight:700;
}
.minmax{display:flex;gap:9px}
.minmax label{flex:1;font-size:11px;font-weight:600;color:var(--muted);display:flex;flex-direction:column;gap:5px}
.minmax input{
  width:100%;padding:9px 10px;border:1px solid var(--line);border-radius:var(--r-sm);
  font:inherit;font-size:13px;font-weight:600;color:var(--ink);background:var(--paper-2);
  transition:border-color .18s ease,background-color .18s ease;
}
.minmax input:focus{border-color:var(--bronze-2);background:var(--paper);outline:none;box-shadow:var(--ring)}
/* Dual-thumb price slider: two range inputs stacked on one track. Only the thumbs take the
   pointer, so either can be dragged where they overlap the other input. */
.prange{margin-top:14px}
.prange[hidden]{display:none}
.prange-bounds,.prange-vals{display:flex;justify-content:space-between;font-size:11.5px;color:var(--muted)}
.prange-vals{font-weight:700;color:var(--ink);font-size:12.5px}
.prange-track{position:relative;height:26px;margin:2px 9px}
.prange-track::before,.prange-fill{
  content:"";position:absolute;top:50%;height:6px;margin-top:-3px;border-radius:3px;
}
.prange-track::before{left:0;right:0;background:var(--paper-3)}
.prange-fill{background:var(--bronze-2)}
.prange input[type=range]{
  position:absolute;left:-9px;width:calc(100% + 18px);top:0;height:26px;margin:0;
  background:none;pointer-events:none;-webkit-appearance:none;appearance:none;
}
.prange input[type=range]::-webkit-slider-runnable-track{background:none;border:0}
.prange input[type=range]::-moz-range-track{background:none;border:0}
.prange input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;pointer-events:auto;cursor:grab;width:18px;height:18px;border-radius:50%;
  background:var(--forest);border:2px solid var(--paper);box-shadow:0 1px 4px rgba(0,0,0,.3);
}
.prange input[type=range]::-moz-range-thumb{
  pointer-events:auto;cursor:grab;width:14px;height:14px;border-radius:50%;
  background:var(--forest);border:2px solid var(--paper);box-shadow:0 1px 4px rgba(0,0,0,.3);
}
.prange input[type=range]:focus{outline:none}
.prange input[type=range]:focus-visible::-webkit-slider-thumb{box-shadow:var(--ring)}
.prange input[type=range]:focus-visible::-moz-range-thumb{box-shadow:var(--ring)}
.checks{display:flex;flex-direction:column;gap:1px}
.checks.scroll{max-height:190px;overflow:auto}
.checks label{
  display:flex;align-items:center;gap:10px;font-size:14px;
  padding:7px 8px;border-radius:var(--r-sm);cursor:pointer;
  transition:background-color .15s ease;
}
.checks label:hover{background:var(--bronze-tint)}
.checks input{width:17px;height:17px;accent-color:var(--bronze-2);flex:none}
.swatch{width:11px;height:11px;border-radius:3px;flex:none;border:1px solid rgba(0,0,0,.18)}
.checks .n{margin-left:auto;color:var(--muted);font-size:12px;font-weight:700;font-variant-numeric:tabular-nums}
.pills{display:flex;flex-wrap:wrap;gap:7px}
.pill{
  border:1px solid var(--line);background:var(--paper);border-radius:50rem;padding:7px 14px;
  font:inherit;font-size:12.5px;font-weight:600;cursor:pointer;color:var(--ink-2);text-decoration:none;
  transition:border-color .18s ease,color .18s ease,background-color .18s ease;
}
.pill:hover{border-color:var(--bronze-2);color:var(--forest)}
.pill.is-on{
  background:linear-gradient(115deg,var(--forest),var(--forest-3));
  border-color:var(--forest);color:#fff;font-weight:700;box-shadow:var(--sh-1);
}

.active-label{margin:0 0 8px;font-size:10.5px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.8px}
.chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:11px;min-height:26px}
.chip{
  display:inline-flex;align-items:center;gap:7px;background:var(--bronze-tint);
  border:1px solid var(--bronze-line);color:var(--bronze-3);border-radius:50rem;
  padding:4px 11px;font-size:12px;font-weight:600;
}
.chip button{border:0;background:none;cursor:pointer;color:var(--bronze-3);font-size:13px;padding:0;line-height:1;opacity:.7}
.chip button:hover{opacity:1}
.btn-reset{
  width:100%;border:1px solid var(--forest);border-radius:var(--r);
  background:linear-gradient(115deg,var(--forest),var(--forest-3));color:#fff;
  padding:12px;font:inherit;font-weight:700;letter-spacing:.3px;cursor:pointer;
  box-shadow:var(--sh-1);transition:box-shadow .2s ease,transform .12s ease,color .18s ease;
}
.btn-reset:hover{box-shadow:var(--sh-2);color:var(--bronze)}
.btn-reset:active{transform:translateY(1px)}

/* ---------- map furniture ---------- */
.viewswitch{
  position:absolute;top:14px;left:50%;transform:translateX(-50%);z-index:620;
  display:flex;gap:8px;
}
.vs{
  display:flex;align-items:center;gap:8px;border:1px solid var(--line);
  background:rgba(255,255,255,.96);color:var(--ink-2);border-radius:var(--r);padding:10px 16px;
  font:inherit;font-size:13.5px;font-weight:700;cursor:pointer;
  backdrop-filter:saturate(140%) blur(6px);
  box-shadow:var(--sh-2);transition:color .18s ease,background-color .18s ease,border-color .18s ease;
}
.vs:hover{color:var(--forest);border-color:var(--bronze-2)}
.vs svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linejoin:round}
.vs.is-on{
  background:linear-gradient(115deg,var(--forest),var(--forest-3));
  border-color:var(--forest);color:#fff;
}
.vs.is-on svg{stroke:var(--bronze)}

.mapkit{
  position:absolute;left:12px;bottom:12px;z-index:620;display:flex;flex-direction:column;gap:8px;
  align-items:flex-start;
}
.amen{
  background:rgba(255,255,255,.96);border:1px solid var(--line);border-radius:var(--r-sm);padding:9px 13px;
  font-size:12.5px;font-weight:600;display:flex;align-items:center;gap:9px;cursor:pointer;
  backdrop-filter:saturate(140%) blur(6px);box-shadow:var(--sh-2);
}
.amen input{accent-color:var(--bronze-2)}
.mini{
  border:1px solid var(--line);background:rgba(255,255,255,.96);border-radius:var(--r-sm);padding:9px 13px;
  font:inherit;font-size:12.5px;font-weight:600;color:var(--ink-2);cursor:pointer;
  backdrop-filter:saturate(140%) blur(6px);box-shadow:var(--sh-2);
  transition:color .18s ease,border-color .18s ease;
}
.mini:hover{color:var(--forest);border-color:var(--bronze-2)}
/* Two cards over the map's bottom-right corner: amenities, then the plot legend. The stack
   caps their combined height, and each card scrolls inside that rather than growing over
   the map — on a short window it is the key that should shrink, not the map. */
.legend-stack{
  position:absolute;right:12px;bottom:12px;z-index:620;
  display:flex;flex-direction:column;align-items:stretch;gap:8px;
  width:max-content;max-width:230px;max-height:calc(100% - 24px);
}
.legend{
  background:rgba(255,255,255,.96);border:1px solid var(--line);border-radius:var(--r);padding:11px 13px;
  backdrop-filter:saturate(140%) blur(6px);box-shadow:var(--sh-2);
  max-height:min(46vh,340px);min-height:0;overflow:auto;
}
.legend h4{
  margin:0 0 8px;font-size:10.5px;font-weight:800;text-transform:uppercase;
  letter-spacing:.8px;color:var(--muted);
}
/* Every row in both keys is a button — the plot key filters, the amenity key switches its
   own pins off. Stripped back to the text it already was, so the card still reads as a key
   and not as a row of controls. */
.legend .row{
  display:flex;align-items:center;gap:9px;width:100%;margin:1px -6px;
  font:inherit;font-size:12.5px;font-weight:600;color:inherit;text-align:left;
  padding:3px 6px;background:none;border:0;border-radius:7px;cursor:pointer;
  transition:background .15s ease,color .15s ease,opacity .15s ease;
}
.legend .row-label{flex:1 1 auto;min-width:0}
.legend .row-n{font-size:11px;font-weight:700;color:var(--muted);flex:none;font-variant-numeric:tabular-nums}
.legend .row:hover{background:var(--paper-3);color:var(--forest)}
.legend .row:focus-visible{outline:none;box-shadow:var(--ring)}
/* Picked: the bronze every other chosen thing on this page wears. */
.legend .row.is-on{background:var(--bronze-tint);box-shadow:inset 0 0 0 1px var(--bronze-line);color:var(--forest)}
.legend .row.is-on .row-n{color:var(--bronze-3)}
/* Once anything is picked, the rows that are not read as out of play. */
.legend.is-filtering .row:not(.is-on){opacity:.5}
/* An amenity kind switched off keeps its word and loses its colour. */
.legend .row.is-off{opacity:.45}
.legend .row.is-off .map-pin.is-key{filter:grayscale(1)}

/* The amenity card carries its own switch, so its title shares a row with the controls. */
.legend-head{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.legend-head h4{margin:0;flex:1 1 auto}
.legend-check{accent-color:var(--bronze-2);width:15px;height:15px;margin:0;flex:none;cursor:pointer}
.legend-collapse{
  border:0;background:none;padding:0;margin:0;width:16px;height:16px;flex:none;
  color:var(--muted);font:inherit;font-size:11px;line-height:1;cursor:pointer;
}
.legend-collapse:hover{color:var(--forest)}
#amenity-panel.is-collapsed .legend-head{margin-bottom:0}
#amenity-panel.is-collapsed #amenity-rows{display:none}
/* Layer off: the key stays legible so you can see what you switched off. */
#amenity-panel.is-off #amenity-rows{opacity:.42}
.legend .dot{width:12px;height:12px;border-radius:3px;border:1px solid rgba(0,0,0,.22);flex:none}
.loading{
  position:absolute;inset:auto 0 50% 0;text-align:center;color:#d9d6c8;z-index:610;margin:0;
}

/* ---------- pins ----------
   One circular badge serves plots, clusters, amenities and the legend key; only the size,
   the fill and the glyph change. The white ring is what keeps it readable over satellite
   imagery, which is dark, busy and never the colour you expected. */
.map-pin{
  width:34px;height:34px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  border:2.5px solid #fff;box-shadow:0 2px 6px rgba(0,0,0,.5);
  color:#fff;font:800 12px/1 "Nunito Sans",system-ui;
}
.map-pin svg{
  width:19px;height:19px;fill:none;stroke:#fff;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;
}
.map-pin.is-cluster{background:var(--forest)}
.map-pin.is-amenity{width:30px;height:30px;border-width:2px}
.map-pin.is-amenity svg{width:17px;height:17px}
.map-pin.is-sel{box-shadow:0 0 0 4px rgba(212,180,92,.65),0 2px 6px rgba(0,0,0,.5)}
.map-pin.is-key{
  width:18px;height:18px;border-width:1.5px;box-shadow:none;flex:none;
}
.map-pin.is-key svg{width:11px;height:11px;stroke-width:2.4}

.plot-label{font:700 11px/16px "Nunito Sans",system-ui;text-align:center;white-space:nowrap;pointer-events:none}
.plot-label.is-small{font-size:10px;line-height:14px}
.plot-label.on-plan{color:#2a3340;text-shadow:0 0 3px #fff,0 0 3px #fff,0 0 3px #fff}
.plot-label.on-sat{color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.95),0 0 4px rgba(0,0,0,.85)}

/* ---------- right rail ---------- */
.tabs{display:flex;align-items:center;border-bottom:1px solid var(--line);background:var(--paper-3)}
.tab{
  flex:1;border:0;background:none;padding:15px 8px;font:inherit;font-size:13px;font-weight:700;
  letter-spacing:.3px;cursor:pointer;color:var(--muted);border-bottom:2px solid transparent;
  transition:color .18s ease,background-color .18s ease;
}
.tab:hover{color:var(--ink)}
.tab.is-on{color:var(--forest);border-bottom-color:var(--bronze);background:var(--paper)}
/* The list's hide button. .rail-toggle is drawn for the dark filters header - white on a
   white wash - which all but vanishes on this light tab bar, so here it is the dark chip with
   the bronze chevron instead: the filters header, shrunk to a button. */
.tabs .rail-toggle{
  flex:none;margin:0 10px;width:32px;height:32px;display:grid;place-items:center;
  background:linear-gradient(115deg,var(--forest),var(--forest-3));border-color:var(--forest);
  color:var(--bronze);font-size:19px;font-weight:700;box-shadow:var(--sh-1);
}
.tabs .rail-toggle:hover{background:var(--bronze);border-color:var(--bronze);color:var(--forest)}
.search input{
  width:100%;padding:11px 13px;border:1px solid var(--line);border-radius:var(--r);
  font:inherit;font-size:13.5px;margin-bottom:11px;background:var(--paper-2);
  transition:border-color .18s ease,background-color .18s ease;
}
.search input:focus{border-color:var(--bronze-2);background:var(--paper);outline:none;box-shadow:var(--ring)}
.cards{display:flex;flex-direction:column;gap:10px}
.pcard{
  border:1px solid var(--line);border-left:4px solid var(--bronze);border-radius:var(--r);
  padding:12px 13px;cursor:pointer;background:var(--paper);box-shadow:var(--sh-1);
  transition:box-shadow .2s ease,transform .16s ease,border-color .18s ease;
}
.pcard:hover{transform:translateY(-2px);box-shadow:var(--sh-2)}
.pcard.is-locked{cursor:default;opacity:.7}
.pcard.is-locked:hover{transform:none;box-shadow:var(--sh-1)}
.pcard.is-sel{border-color:var(--bronze-2);box-shadow:0 0 0 2px rgba(212,180,92,.45),var(--sh-2)}
.pcard .top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.pcard b{font-size:15px;font-weight:800;letter-spacing:-.1px}
.state{border-radius:20px;padding:3px 10px;font-size:10.5px;font-weight:800;letter-spacing:.3px;color:#fff}
.facts{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.fact{
  background:var(--paper-3);border:1px solid var(--line);border-radius:50rem;
  padding:3px 10px;font-size:11.5px;font-weight:600;color:var(--ink-2);
}

/* ---------- selected pane ---------- */
.sel-head{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:14px}
.sel-head h3{margin:0;font-size:22px;font-weight:800;letter-spacing:-.4px;color:var(--forest)}
.kv{display:grid;grid-template-columns:1fr auto;gap:9px 12px;font-size:13.5px;margin:0 0 16px}
.kv dt{color:var(--muted)}
.kv dd{margin:0;text-align:right;font-weight:700}
.money{font-size:21px;font-weight:800;letter-spacing:-.5px;color:var(--forest)}
/* Label and figure on one line -- the two-line "Plot price / PKR 53 M" stack cost a full
   row for nothing a baseline-aligned row doesn't say just as clearly. */
.price-row{display:flex;align-items:baseline;justify-content:space-between;gap:10px;margin:0 0 14px}
.price-row .hint{margin:0}
.price-row .money{margin:0}
.sec-title{margin:0 0 8px;font-size:13px;font-weight:800;color:var(--ink-2)}
.note{
  background:var(--bronze-tint);border:1px solid var(--bronze-line);border-radius:var(--r);
  padding:11px 13px;font-size:12.5px;color:var(--bronze-3);margin:0 0 13px;
}
.plan{
  display:flex;align-items:center;gap:12px;border:1px solid var(--line);background:var(--paper);
  border-radius:var(--r);padding:12px 13px;margin-bottom:9px;cursor:pointer;
  transition:border-color .18s ease,background-color .18s ease,box-shadow .2s ease;
}
.plan:hover{border-color:var(--bronze-2)}
.plan.is-on{border-color:var(--bronze-2);background:var(--bronze-tint);box-shadow:0 0 0 1px var(--bronze-2) inset}
.plan input{accent-color:var(--bronze-2);width:17px;height:17px;flex:none}
.plan .pname{font-weight:800;font-size:13.5px}
.plan .psub{font-size:11.5px;color:var(--muted)}
/* The half of the card that gives way when the panel is narrow. A flex item floors at its own
   min-content unless told otherwise, so without this the plan name and the discount label hold
   the card open and the price is what gets pushed out of it. */
.plan .pmeta{min-width:0}
/* A discounted plan prints two figures here, the gross struck through above the net. Side by
   side on one nowrap line they cannot shrink below their combined width -- so the price ran
   off the edge of the panel and the two numbers ran into each other. Stacked, the column only
   has to fit the longer of the two, and each stays on its own line. */
.plan .ptotal{
    margin-left:auto;flex:none;
    display:flex;flex-direction:column;align-items:flex-end;
    text-align:right;font-weight:800;font-size:14px;white-space:nowrap;color:var(--forest);
}
.plan .pnow{display:block}
/* The one call to action on the page, so it gets the dark card and the bronze button. */
.secure{
  border:1px solid var(--forest);border-radius:var(--r-lg);padding:15px;margin-top:16px;
  background:linear-gradient(140deg,var(--forest),var(--forest-3));box-shadow:var(--sh-2);
}
.secure h4{margin:0 0 7px;font-size:14.5px;font-weight:800;color:var(--bronze);display:flex;align-items:center;gap:8px}
.secure p{margin:0 0 12px;font-size:12.5px;color:rgba(255,255,255,.78)}
/* The token-amount row is a .kv like the ones on white, so it needs its colours flipped. */
.secure .kv{margin-bottom:13px}
.secure .kv dt{color:rgba(255,255,255,.7)}
.secure .kv dd{color:#fff}
.btn-primary{
  width:100%;border:0;border-radius:var(--r);
  background:linear-gradient(115deg,var(--bronze),var(--bronze-2));color:var(--forest);
  padding:13px;font:inherit;font-weight:800;letter-spacing:.3px;cursor:pointer;
  transition:filter .18s ease,transform .12s ease;
}
.btn-primary:hover{filter:brightness(1.06)}
.btn-primary:active{transform:translateY(1px)}
.btn-primary:disabled{background:#b5ab8c;color:rgba(27,32,24,.55);cursor:not-allowed;filter:none}
.btn-ghost{
  width:100%;border:1px solid var(--line);border-radius:var(--r);background:var(--paper);
  padding:12px;font:inherit;font-weight:600;color:var(--ink-2);cursor:pointer;margin-top:9px;
  transition:border-color .18s ease,color .18s ease;
}
.btn-ghost:hover{border-color:var(--bronze-2);color:var(--forest)}
.ok{background:#eef5ec;border:1px solid #c3d9bd;border-radius:var(--r);padding:13px;font-size:13px;color:#2f5b2a}
.err{background:#fbeee9;border:1px solid #e9c4b6;border-radius:var(--r);padding:12px;font-size:12.5px;color:#8a3a22;margin-top:11px}
.empty{color:var(--muted);font-size:13.5px;text-align:center;padding:28px 12px}
.hint{color:var(--muted);font-size:11.5px;margin:7px 0 0}

/* ---------- phone furniture ----------
   Three controls that exist only where the rails stop fitting beside the map. They are laid
   out in the narrow block below; here they are simply switched off, so nothing about the
   desktop layout has to know they are in the markup. */
.sheet-head{display:none}
.vs-filter{display:none}
.sheet-grip{display:none}
.rail-scrim{display:none}
.kit-key{display:none}

/* ---------- narrow screens ---------- */
@media (max-width:1100px){
  :root{--rail:300px}
}

/* Below this the three panes cannot sit side by side. The map keeps the full width and the
   rails become bottom sheets over it — one at a time, because two 90vw drawers on a 390px
   screen is the pile the edge tabs used to produce. */
@media (max-width:860px){
  .workspace{overflow:hidden}

  /* Both rails are bottom sheets, one up at a time. Filters waits wholly below the edge and
     comes up from its button at the top of the map; its grip sends it back down. The plots
     sheet peeks its head and tabs, and is dragged or tapped up and down by that head. Open, a
     sheet stops short of the top, so the map's own top row stays in sight above it. */
  .rail{
    position:absolute;inset:58px 0 0 0;width:auto;height:auto;border:0;overflow:hidden;
    border-radius:18px 18px 0 0;box-shadow:0 -10px 30px -6px rgba(15,18,14,.32);
    transform:translateY(100%);visibility:hidden;
    transition:transform .3s cubic-bezier(.2,.8,.2,1),visibility 0s linear .3s;
    will-change:transform;
  }
  /* The plots sheet never fully leaves: shut, its head and tabs peek above the bottom edge --
     a count, a handle and the two tabs, always in reach. */
  .rail-right{
    transform:translateY(calc(100% - var(--peek,104px) - var(--safe-b)));visibility:visible;
    transition:transform .3s cubic-bezier(.2,.8,.2,1);
  }
  .rail.is-open,.rail.is-dragging{
    transform:none;visibility:visible;
    transition:transform .3s cubic-bezier(.2,.8,.2,1),visibility 0s;
  }
  /* Mid-drag the sheet follows the finger, not the easing. */
  .rail.is-dragging{transition:none}

  .sheet-grip{
    display:grid;place-items:center;flex:none;width:100%;height:22px;padding:0;border:0;
    background:var(--paper-3);cursor:grab;touch-action:none;user-select:none;
  }
  .sheet-grip::before{content:"";width:40px;height:5px;border-radius:5px;background:#bdb8a6}
  .rail-left .sheet-grip{background:var(--paper-2);height:26px}

  /* ---- the plots sheet's head: count, handle, hint, chevron ---- */
  .sheet-head{
    display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:8px;flex:none;
    padding:9px 14px 7px;background:var(--paper);
    cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none;
  }
  .sheet-head:focus-visible{outline:2px solid var(--bronze);outline-offset:-2px}
  .sh-count{
    justify-self:start;background:linear-gradient(115deg,var(--forest),var(--forest-3));color:#fff;
    border-radius:999px;padding:5px 12px;font-size:12.5px;font-weight:800;white-space:nowrap;
    font-variant-numeric:tabular-nums;
  }
  .sh-mid{display:flex;flex-direction:column;align-items:center;gap:5px}
  .sh-grip{width:46px;height:5px;border-radius:5px;background:var(--bronze)}
  .sh-hint{font-size:11.5px;font-weight:700;color:var(--muted);letter-spacing:.2px;white-space:nowrap}
  .sh-chev{
    justify-self:end;width:34px;height:34px;display:grid;place-items:center;border-radius:50%;
    border:1px solid var(--line);background:var(--paper-2);
  }
  .sh-chev svg{
    width:18px;height:18px;fill:none;stroke:var(--forest);stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;
    transition:transform .3s cubic-bezier(.2,.8,.2,1);
  }
  .sheet-head:not(.is-open) .sh-chev svg{animation:hint-bob 1.8s ease-in-out infinite}
  .sheet-head.is-open .sh-chev svg{transform:rotate(180deg)}
  /* A chosen plot waits on the Selected tab, so while there is one the tab lights up in the
     brand's dark green and carries the plot's number on a gold badge that pulses gently. */
  .tab.has-sel{
    display:flex;align-items:center;justify-content:center;gap:7px;
    background:linear-gradient(115deg,var(--forest),var(--forest-3));color:#fff;
    border-bottom-color:var(--bronze);font-weight:800;
  }
  .tab.has-sel::after{
    content:attr(data-plot);flex:none;padding:3px 9px;border-radius:999px;
    background:var(--bronze);color:var(--forest);font-size:11.5px;font-weight:800;line-height:1.2;
    white-space:nowrap;animation:sel-pulse 2s ease-out infinite;
  }
  .rail-left .rail-head{display:none}
  #close-list{display:none}
  .rail-body{padding:12px 12px calc(12px + var(--safe-b))}
  .rail-foot{padding:11px 12px calc(11px + var(--safe-b))}

  /* ---- filters: denser on phones ----
     Five cards of 14px padding and 12px gaps is most of a phone screen before Status is even
     in view. Tighter cards, closer together, so more sections are visible at once. */
  .fgroup{padding:11px 12px;margin-bottom:9px}
  .fgroup h3{margin-bottom:8px}
  .fgroup h3::before{width:6px;height:6px}
  .minmax{gap:8px}
  .minmax input{padding:8px 10px}
  .prange{margin-top:11px}
  .checks label{padding:9px 8px}
  .checks.scroll{max-height:168px}
  .active-label{margin-bottom:6px}
  .chips{margin-bottom:8px}
  .btn-reset{padding:11px}

  /* 26px of edge tab is a mouse target sitting where a thumb pans. The top Filters button
     and the plots sheet's head replace it. */
  .rail-open{display:none!important}

  .rail-scrim{
    display:block;position:absolute;inset:0;
    background:rgba(15,18,14,.42);opacity:0;pointer-events:none;
    transition:opacity .22s ease;
  }
  .rail-scrim.is-on{opacity:1;pointer-events:auto}

  /* ---- Filters, at the top of the map ----
     Top right, with a count of what is narrowing the
     list, so the bottom of the screen belongs to the plots sheet alone. */
  .vs-filter{
    display:flex;position:absolute;top:10px;right:10px;z-index:620;
    padding:10px 14px;gap:7px;
  }
  .vs-filter svg{stroke-width:2}
  .mb-badge{
    background:var(--bronze);color:var(--forest);border-radius:20px;padding:0 7px;min-width:20px;
    text-align:center;font-size:11px;font-weight:800;line-height:20px;flex:none;
    font-variant-numeric:tabular-nums;
  }
  .vs-filter.is-on .mb-badge{background:var(--bronze);color:var(--forest)}

  /* ---- stacking ----
     One context for everything the map owns, Leaflet's own controls included, so a drawer
     covers all of it in a single step instead of outbidding each layer in turn. */
  .stage{z-index:0}
  .rail-scrim{z-index:1}
  .rail{z-index:2}
  .rail-left{z-index:3}

  /* ---- map furniture ----
     Top row: the two view buttons as icons in the centre, Filters on the right. Leaflet's zoom
     drops below Filters, and everything at the bottom sits above the peeking plots sheet. */
  .viewswitch{top:10px;left:50%;transform:translateX(-50%);gap:6px}
  .vs{padding:10px 11px;font-size:12.5px;white-space:nowrap}
  .viewswitch .vs-txt{
    position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;
  }
  .leaflet-top.leaflet-right{top:56px}
  .leaflet-bottom{bottom:calc(var(--peek,104px) + var(--safe-b))}

  /* Leaflet parks its attribution flush in the bottom-right corner. It stays, because it is a
     licence condition, but as one clipped line. */
  .leaflet-container .leaflet-control-attribution{
    max-width:80vw;padding:2px 7px;border-radius:7px 0 0 0;
    font-size:9.5px;line-height:1.5;
    white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }

  /* The map's switches, moved into the filters sheet: rows like the other filter boxes rather
     than floating chips, and Zoom to site as a full-width button under them. */
  #kit-slot .mapkit{
    position:static;display:flex;flex-direction:column;align-items:stretch;gap:0;
  }
  #kit-slot .amen{
    background:none;border:0;box-shadow:none;backdrop-filter:none;border-radius:var(--r-sm);
    padding:10px 8px;font-size:13.5px;font-weight:600;color:var(--ink);
  }
  #kit-slot .amen input{width:19px;height:19px;margin:0}
  #kit-slot .kit-key{display:flex}
  #kit-slot .mini{
    margin-top:8px;padding:11px;box-shadow:none;backdrop-filter:none;
    font-size:13px;font-weight:700;text-align:center;
  }

  .legend-stack{
    right:10px;bottom:calc(var(--peek,104px) + var(--safe-b) + 28px);max-width:min(64vw,220px);
    max-height:calc(100% - var(--peek,104px) - var(--safe-b) - 100px);
  }
  .legend-stack.is-off{display:none}
  .legend{font-size:11px;padding:9px 11px;max-height:min(32vh,240px)}
  .legend .row{font-size:11.5px;gap:8px;padding:5px 6px;margin:0 -6px}
  .legend .dot,.map-pin.is-key{flex:none}

  /* ---- targets ----
     A 32px checkbox row is a pointer row. Everything the buyer taps gets thumb-sized, and the
     two text inputs go to 16px because iOS zooms the whole page into anything smaller. */
  .checks label{padding:10px 8px}
  .checks input{width:19px;height:19px}
  .pill{padding:9px 15px}
  .tab{padding:14px 6px;font-size:12.5px}
  .minmax input,.search input{font-size:16px}
  .dp-step{padding:8px 13px}

  /* ---- selected pane: denser on phones ----
     The drawer is fighting the mobile bar for height, so this pane gets its own pass: a
     ruled fact table in place of the loose list, and less air between every block below it --
     the same figures, the same tap targets, in noticeably less scroll. */
  .sel-head{margin-bottom:10px}
  .sel-head h3{font-size:18px}
  #pane-sel > .kv{
    background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-sm);
    column-gap:10px;row-gap:0;padding:0 11px;font-size:12.5px;margin:0 0 12px;
  }
  #pane-sel > .kv dt,#pane-sel > .kv dd{padding:7px 0;border-bottom:1px solid var(--line)}
  #pane-sel > .kv dt:last-of-type,#pane-sel > .kv dd:last-of-type{border-bottom:0}
  .price-row{margin-bottom:11px}
  .price-row .money{font-size:19px}
  .sec-title{margin-bottom:6px;font-size:12.5px}
  .pay-tabs{margin-bottom:8px}
  .dp-pick{margin-bottom:8px}
  .plan{padding:10px 12px;margin-bottom:7px}
  .plan .pname{font-size:13px}
  .plan .psub{font-size:11px}
  .pdetail{padding:9px 11px 10px;margin-bottom:7px}
  .pdetail dl{gap:5px 10px;font-size:12px}
  .secure{padding:12px;margin-top:12px}
  .secure h4{margin-bottom:5px;font-size:13.5px}
  .secure p{margin-bottom:9px;font-size:12px}
  .secure .kv{margin-bottom:10px}
  .btn-primary{padding:12px}
  .btn-ghost{padding:10px;margin-top:7px}
  .ok{padding:10px 12px;font-size:12px}
}


@keyframes sel-pulse{
  0%{box-shadow:0 0 0 0 rgba(212,180,92,.75)}
  70%{box-shadow:0 0 0 7px rgba(212,180,92,0)}
  100%{box-shadow:0 0 0 0 rgba(212,180,92,0)}
}
/* The swipe tab's chevron nudges the way the bar swipes. */
@keyframes hint-bob{0%,100%{translate:0 0}50%{translate:0 -2px}}
@keyframes hint-bob-down{0%,100%{translate:0 0}50%{translate:0 2px}}

/* Small phones: the view switch and the keys give up width before the map does. */
@media (max-width:420px){
  .vs{padding:8px 10px;font-size:12px;gap:6px}
  .vs svg{width:15px;height:15px}
  .legend-stack{max-width:min(58vw,190px)}
  .pp{width:min(200px,64vw)}
  .sel-head h3{font-size:17px}
  .price-row .money{font-size:18px}
}

/* A pointer-driven lift feels wrong on touch, where it only lags the tap. */
@media (hover:none){
  .pcard:hover{transform:none;box-shadow:var(--sh-1)}
}
@media (prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
}

/* ---------- plot popup ----------
   The card that opens on the plot you clicked. Leaflet supplies the frame, the tail and the
   close button; everything below replaces its default chrome so the popup reads as part of
   this map rather than as a browser tooltip that landed on it. */
.plot-popup .leaflet-popup-content-wrapper{
  background:var(--paper);border-radius:var(--r);box-shadow:var(--sh-2);
  padding:0;color:var(--ink);
}
.plot-popup .leaflet-popup-content{margin:0;line-height:1.35}
.plot-popup .leaflet-popup-tip{background:var(--paper);box-shadow:var(--sh-1)}
/* The same round button the terms sheet closes with, so the cards share one close control. */
.leaflet-container .plot-popup a.leaflet-popup-close-button{
  top:10px;right:10px;width:30px;height:30px;display:grid;place-items:center;
  font:400 20px/1 system-ui;color:var(--ink);background:var(--paper);
  border:1px solid var(--line);border-radius:50%;box-shadow:var(--sh-1);
  transition:background-color .15s ease,border-color .15s ease;
}
.leaflet-container .plot-popup a.leaflet-popup-close-button span{line-height:1}
.leaflet-container .plot-popup a.leaflet-popup-close-button:hover{background:var(--paper-3);border-color:var(--bronze-2);color:var(--forest)}
.plot-popup .pp-title{margin-right:40px}

.pp{width:290px;padding:13px 15px 15px;font:400 12.5px/1.35 "Nunito Sans",system-ui}

/* ---------- modal sheet ----------
   A sheet over everything on a dimmed backdrop, used by the terms and conditions. Capped at the
   screen height, with its body scrolling inside, so its buttons never run off the bottom. */
.pp-modal{
  position:fixed;inset:0;z-index:3000;display:flex;align-items:center;justify-content:center;
  padding:16px;background:rgba(23,27,20,.55);animation:pp-fade .18s ease-out;
}
.pp-modal[hidden]{display:none}
.pp-sheet{
  position:relative;width:min(100%,400px);max-height:calc(100vh - 32px);
  display:flex;flex-direction:column;background:var(--paper);border-radius:var(--r-lg,16px);
  box-shadow:var(--sh-3);overflow:hidden;animation:pp-rise .22s ease-out;
}
@supports (height:100dvh){ .pp-sheet{max-height:calc(100dvh - 32px)} }
.pp-scroll{overflow-y:auto;overscroll-behavior:contain;-webkit-overflow-scrolling:touch}
.pp-x{
  position:absolute;top:10px;right:10px;z-index:1;width:34px;height:34px;
  display:grid;place-items:center;border:1px solid var(--line);border-radius:50%;
  background:var(--paper);color:var(--ink);font:400 22px/1 system-ui;cursor:pointer;
  box-shadow:var(--sh-1);
}
.pp-x:hover{background:var(--paper-3)}
/* The page behind stays put while the card is up. */
body.pp-modal-open{overflow:hidden}
@keyframes pp-fade{from{opacity:0}to{opacity:1}}

/* ---------- terms and conditions sheet ----------
   Built on the modal sheet above, wider for reading. Head and foot stay put and
   only the clauses scroll, so the agree box and button are always in reach. */
.tc-modal{z-index:3100}
.pp-sheet.tc-sheet{width:min(100%,640px)}
.tc-head{position:relative;padding:20px 24px 14px;border-bottom:1px solid var(--line)}
/* Only the text needs to clear the close button; the fact boxes run the full width, even on both sides. */
.tc-eyebrow,.tc-title,.tc-meta{padding-right:36px}
.tc-eyebrow{margin:0 0 4px;font:700 11px/1.3 "Nunito Sans",system-ui;letter-spacing:.1em;text-transform:uppercase;color:var(--bronze-3)}
.tc-title{margin:0;font:800 19px/1.25 "Nunito Sans",system-ui;color:var(--ink)}
.tc-meta{margin:4px 0 0;font:400 12.5px/1.4 "Nunito Sans",system-ui;color:var(--muted)}
/* What is being agreed to, in the plan card's own figures. */
.tc-sum{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:1px;margin:14px 0 0;
  background:var(--bronze-line);border:1px solid var(--bronze-line);border-radius:var(--r-sm);overflow:hidden;
}
.tc-sum:empty{display:none}
/* Who is agreeing and when sits directly above the deal figures, as one block. */
.tc-sum.tc-deal{margin-top:6px}
/* Name over two columns, date and time one each, so the boxes line up with the deal row below. */
.tc-sum.tc-who{grid-template-columns:repeat(4,minmax(0,1fr))}
.tc-sum.tc-who div:first-child{grid-column:span 2}
.tc-sum div{padding:8px 12px;background:var(--bronze-tint);min-width:0}
.tc-sum dt{font:700 10.5px/1.3 "Nunito Sans",system-ui;letter-spacing:.08em;text-transform:uppercase;color:var(--bronze-3)}
.tc-sum dd{margin:2px 0 0;font:800 14px/1.3 "Nunito Sans",system-ui;color:var(--forest);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tc-progress{position:absolute;left:0;right:0;bottom:-1px;height:2px;background:transparent}
.tc-progress span{display:block;height:100%;background:var(--bronze-2);transform-origin:left;transform:scaleX(0);transition:transform .12s linear}

.tc-body{position:relative;flex:1 1 auto;min-height:0;padding:8px 24px 4px;outline:none}
.tc-body:focus-visible{box-shadow:inset var(--ring)}
.tc-list{margin:0;padding:0;list-style:none;counter-reset:tc;font:400 14px/1.6 "Nunito Sans",system-ui;color:var(--ink-2)}
.tc-list li{
  counter-increment:tc;position:relative;padding:11px 0 11px 40px;border-bottom:1px dashed var(--line);
}
.tc-list li:last-child{border-bottom:0}
.tc-list li::before{
  content:counter(tc);position:absolute;left:0;top:11px;width:26px;height:26px;border-radius:50%;
  display:grid;place-items:center;background:var(--bronze-tint);border:1px solid var(--bronze-line);
  font:800 12px/1 "Nunito Sans",system-ui;color:var(--bronze-3);
}
.tc-list b{font-weight:800;color:var(--ink)}
.tc-list b.tc-warn{color:#a3402f}
.tc-end{
  margin:6px 0 14px;text-align:center;font:700 11px/1 "Nunito Sans",system-ui;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted);
}
.tc-end::before,.tc-end::after{content:"";display:inline-block;width:28px;height:1px;background:var(--line);vertical-align:middle;margin:0 10px}
/* A fade over the cut-off edge while there is more to read below. */
.tc-body::after{
  content:"";position:sticky;display:block;bottom:-4px;height:36px;margin-top:-36px;pointer-events:none;
  background:linear-gradient(rgba(255,255,255,0),var(--paper));opacity:0;transition:opacity .2s ease;
}
.tc-body.is-more::after{opacity:1}

/* The foot is kept to two short lines: the tick, then print and the two choices. */
.tc-foot{padding:12px 24px 14px;border-top:1px solid var(--line);background:var(--paper-2)}
.tc-agree{
  display:flex;align-items:center;gap:10px;padding:2px 0;
  font:600 13.5px/1.4 "Nunito Sans",system-ui;color:var(--ink);cursor:pointer;
}
.tc-agree.is-on{color:var(--forest)}
.tc-agree:has(input:focus-visible) input{box-shadow:var(--ring)}
.tc-agree input{width:17px;height:17px;margin:0;flex:none;accent-color:var(--bronze-3);cursor:pointer;border-radius:4px}
.tc-actions{display:flex;align-items:center;gap:8px;margin-top:10px}
/* Both buttons get the same box: the shared ghost style's 7px top margin and 1px border would
   otherwise drop Cancel below Agree. Agree carries a clear border so the heights match. */
.tc-actions .pp-btn{margin-top:0;flex:0 0 auto;width:auto;padding:9px 18px;font-size:13.5px;
  font-weight:800;border:1px solid transparent}
.tc-actions .pp-btn.is-ghost{margin-top:0;background:var(--paper);border-color:var(--line)}
.tc-actions .pp-btn:not(:disabled){box-shadow:0 2px 8px rgba(193,164,84,.3)}
.tc-actions .pp-btn:focus-visible{outline:none;box-shadow:var(--ring)}
.tc-hint{display:none}
.tc-print{
  display:inline-flex;align-items:center;gap:6px;margin-right:auto;
  padding:7px 8px;border:0;border-radius:var(--r-sm);background:none;cursor:pointer;
  font:700 12.5px/1.3 "Nunito Sans",system-ui;color:var(--bronze-3);
}
.tc-print:hover{color:var(--forest);background:var(--bronze-tint)}
.tc-print:focus-visible{outline:none;box-shadow:var(--ring)}

/* On a phone the sheet rises from the bottom edge, where the thumb already is. */
@media (max-width:480px){
  .tc-modal{align-items:flex-end;padding:0}
  .pp-sheet.tc-sheet{width:100%;max-height:92vh;border-radius:var(--r-lg) var(--r-lg) 0 0}
  @supports (height:100dvh){ .pp-sheet.tc-sheet{max-height:92dvh} }
  /* A grab bar, so it reads as a sheet that came up rather than a box that landed. */
  .pp-sheet.tc-sheet::before{
    content:"";position:absolute;top:6px;left:50%;width:36px;height:4px;margin-left:-18px;
    border-radius:4px;background:var(--line);
  }
  .tc-sheet .pp-x{top:12px;right:12px;width:30px;height:30px;font-size:19px;box-shadow:none}

  /* Head and foot are pressed flat so the clauses — the thing being agreed to — get the room. */
  .tc-head{padding:18px 16px 10px}
  .tc-eyebrow{margin-bottom:2px;font-size:10px;padding-right:40px}
  .tc-title{font-size:16px;line-height:1.3;padding-right:40px}
  .tc-meta{font-size:11.5px;margin-top:2px}
  /* The four figures on one line, label over value, each as wide as its own text needs —
     a two-digit plot number should not take the room an amount in Mn needs. */
  .tc-sum{display:flex;margin-top:10px}
  .tc-sum div{flex:1 1 auto;padding:6px 8px}
  .tc-sum dt{font-size:9px;letter-spacing:.06em}
  .tc-sum dd{
    font-size:12.5px;line-height:1.25;white-space:normal;
    display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  }

  .tc-body{padding:2px 16px 0}
  .tc-list{font-size:13.5px;line-height:1.55}
  .tc-list li{padding:9px 0 9px 32px}
  .tc-list li::before{top:10px;width:22px;height:22px;font-size:11px}
  .tc-end{margin:4px 0 10px;font-size:10px}

  .tc-foot{padding:10px 16px calc(12px + var(--safe-b))}
  .tc-agree{font-size:13px;line-height:1.35}
  .tc-actions{gap:6px}
  /* Agree takes what is left of the row; print drops to its icon. */
  .tc-actions #tc-go{flex:1 1 auto;padding:10px 12px}
  .tc-actions .pp-btn.is-ghost{padding:10px 14px}
  .tc-print{margin-right:0;padding:8px}
  .tc-print span{display:none}
}
/* Short phones (landscape, or a small screen with the browser bar up): the figures go, but
   the name and time the buyer agrees under stay. */
@media (max-width:480px) and (max-height:620px), (max-height:480px){
  .tc-meta,.tc-sum.tc-deal{display:none}
}
@keyframes pp-rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.pp-title{margin:0 24px 8px 0;font:800 16px/1.2 "Nunito Sans",system-ui;color:var(--ink)}
.pp-tags{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:9px}
.pp-tag{
  border-radius:999px;padding:3px 9px;font:800 10.5px/1.4 "Nunito Sans",system-ui;
  letter-spacing:.02em;white-space:nowrap;
}
.pp-tag.is-cat{background:var(--paper-3);color:var(--ink-2)}
.pp-tag.is-state{color:#fff}

/* The one line a buyer is most likely to be caught out by, so it is tinted rather than
   dropped into the list of facts where it would read as another fact. */
.pp .pp-note{
  display:flex;gap:7px;align-items:flex-start;
  margin:0 0 12px;padding:7px 10px;border-radius:var(--r-sm);
  background:var(--bronze-tint);border:1px solid var(--bronze-line);
  color:var(--bronze-3);font:700 11px/1.4 "Nunito Sans",system-ui;
}
/* An "i" in a ring, drawn rather than fetched: it marks the note as an aside to read. */
.pp .pp-note::before{
  content:"i";flex:none;width:15px;height:15px;margin-top:1px;border-radius:50%;
  display:grid;place-items:center;border:1.5px solid currentColor;
  font:800 9.5px/1 Georgia,serif;font-style:italic;
}
/* Hidden for now: the markup and the styling above stay, so it comes back by deleting this. */
.pp .pp-note{display:none}

/* The facts as a ruled table in a soft box, so each label is plainly paired with its value
   instead of the two columns drifting apart across the card. */
.pp-kv{
  display:grid;grid-template-columns:auto 1fr;column-gap:12px;margin:0 0 12px;
  padding:2px 11px;background:var(--paper-2);border:1px solid var(--line);border-radius:var(--r-sm);
}
.pp-kv dt,.pp-kv dd{padding:6px 0;border-bottom:1px solid var(--line)}
.pp-kv dt:last-of-type,.pp-kv dd:last-of-type{border-bottom:0}
.pp-kv dt{color:var(--muted);font-weight:600}
.pp-kv dd{margin:0;color:var(--ink);font-weight:700;text-align:right;overflow-wrap:anywhere}

/* The plan the hold will be taken on: a fact like the rest, with Change plan under the name,
   kept to the right edge the values line up on. A quiet text link — no fill on hover. */
.pp-kv dd.pp-plan{color:var(--forest)}
.pp-link.pp-change{
  display:block;margin:2px 0 0 auto;
  font-size:11.5px;font-weight:700;color:var(--bronze-3);
  text-decoration:underline;text-decoration-color:transparent;text-underline-offset:2px;
  transition:color .15s ease,text-decoration-color .15s ease;
}
.pp-link.pp-change:hover{color:var(--forest);text-decoration-color:currentColor}

/* The price gets a panel of its own: it is the figure the whole card is about. */
.pp-price{
  padding:10px 12px;border-radius:var(--r-sm);
  background:linear-gradient(115deg,var(--forest),var(--forest-3));color:#fff;
}
.pp .pp-k{margin:0;color:var(--muted);font-weight:600}
.pp-price .pp-k{
  color:var(--bronze);font-size:10.5px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;
}
.pp .pp-money{margin:1px 0 0;font:800 17px/1.2 "Nunito Sans",system-ui;color:var(--forest)}
.pp .pp-price .pp-money{margin-top:3px;color:#fff}
.pp .pp-wait{margin:0;color:var(--muted);font-style:italic}

/* The action row. The panel's dark call-to-action card folded down to a strip, because the
   buyer is already looking at the plot they want and the way to hold it belongs there. The
   button carries the bronze so it reads as the same offer, not a second one. The price panel
   above already closes off the facts, so no rule is drawn between them. */
.pp-act{margin-top:12px}
.pp-btn{
  display:block;width:100%;border:0;border-radius:var(--r-sm);
  background:linear-gradient(115deg,var(--bronze),var(--bronze-2));color:var(--forest);
  padding:10px 11px;font:800 12.5px/1.3 "Nunito Sans",system-ui;letter-spacing:.2px;
  text-align:center;text-decoration:none;cursor:pointer;
  transition:filter .18s ease,transform .12s ease;
}
/* Leaflet colours every link on the map blue (.leaflet-container a), and that outranks a plain
   class. The card's links are put back to the card's own colours. */
.leaflet-container a.pp-btn{color:var(--forest)}
.leaflet-container a.pp-btn.is-ghost{color:var(--ink-2)}
.leaflet-container a.pp-btn.is-ghost:hover{color:var(--forest)}
.leaflet-container a.pp-link{color:var(--bronze-3)}
.leaflet-container a.pp-link:hover{color:var(--forest)}
.pp-btn:hover{filter:brightness(1.06)}
.pp-btn:active{transform:translateY(1px)}
.pp-btn:disabled{
  background:var(--paper-3);color:var(--muted);font-weight:700;cursor:not-allowed;filter:none;
}
.pp-btn.is-ghost{background:none;border:1px solid var(--line);color:var(--ink-2);margin-top:7px}
.pp-btn.is-ghost:hover{border-color:var(--bronze-2);color:var(--forest);filter:none}
.pp .pp-sub{margin:9px 0 0;color:var(--muted);font-size:12.5px;line-height:1.4;text-align:center}

/* Sits inside a sentence, so it is a link in everything but the element it is built from. */
.pp-link{
  border:0;background:none;padding:0;font:inherit;font-weight:700;color:var(--bronze-3);
  text-decoration:underline;cursor:pointer;
}
.pp .pp-held{
  margin:0 0 4px;padding:8px 10px;border-radius:var(--r-sm);
  background:#eef5ec;border:1px solid #c3d9bd;color:#2f5b2a;font-size:11.5px;line-height:1.4;
}
.pp .pp-err{
  margin:8px 0 0;padding:8px 10px;border-radius:var(--r-sm);
  background:#fbeee9;border:1px solid #e9c4b6;color:#8a3a22;font-size:11.5px;line-height:1.4;
}

/* A pin off OpenStreetMap rather than off the developer's drawing. Same colour and glyph —
   it means the same thing on the ground — but a size down, so the development's own
   amenities stay the ones your eye lands on first. */
.map-pin.is-amenity.is-nearby{width:26px;height:26px;border-width:2px;opacity:.93}
.map-pin.is-amenity.is-nearby svg{width:15px;height:15px}

/* ---------- down payment selector (BR-15 / BR-16) ---------- */
/* Shown only where there is an instalment plan to apply it to. Picking a step re-fetches the
   quote, because the rebate that comes with it is worked out from rules in the database and a
   figure computed here could disagree with the one the server will book. */

.pay-tabs{display:flex;gap:4px;margin:0 0 10px;padding:3px;border:1px solid var(--line);border-radius:999px;background:var(--panel)}
.pay-tab{
    flex:1;font:inherit;font-size:12.5px;font-weight:700;cursor:pointer;
    padding:7px 10px;border:0;border-radius:999px;background:transparent;color:var(--muted)
}
.pay-tab:hover{color:var(--ink)}
.pay-tab.is-on{background:var(--bronze-tint);color:var(--ink);box-shadow:0 0 0 1px var(--bronze-2) inset}

.dp-pick{margin:0 0 10px}
.dp-label{margin:0 0 6px;font-size:11.5px;color:var(--muted)}
.dp-steps{display:flex;flex-wrap:wrap;gap:6px}

.dp-step{
    font:inherit;font-size:12px;font-weight:700;cursor:pointer;
    padding:5px 10px;border-radius:999px;
    border:1px solid var(--line);background:var(--panel);color:var(--ink);
}
.dp-step:hover{border-color:var(--bronze-2)}
.dp-step.is-on{
    border-color:var(--bronze-2);background:var(--bronze-tint);
    box-shadow:0 0 0 1px var(--bronze-2) inset
}

/* The chosen plan's working, opened under its card. Tucked up against it and sharing the
   bronze edge, so it reads as the inside of that card rather than a fifth plan on offer. */
.plan.is-on{margin-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}
.pdetail{
    border:1px solid var(--bronze-2);border-top:0;
    border-radius:0 0 var(--r) var(--r);background:var(--paper-2);
    padding:11px 13px 12px;margin:0 0 9px;
}
.pdetail dl{display:grid;grid-template-columns:1fr auto;gap:7px 12px;margin:0;font-size:12.5px}
.pdetail dt{color:var(--muted)}
.pdetail dd{margin:0;text-align:right;font-weight:700;color:var(--ink)}
.pdetail .is-cut{color:#2f6b3f}
/* The two figures a buyer actually leaves with: what to transfer now, and what it comes to. */
.pdetail .is-key{border-top:1px solid var(--line);padding-top:7px;color:var(--forest)}
.pdetail dt.is-key{font-weight:700;color:var(--ink-2)}
.pdetail dd.is-key{font-weight:800}

/* The rebate is the thing BR-16 promises to show moving, so it gets its own line rather than
   being folded into the summary sentence. */
.plan .prebate{
    display:block;margin-top:3px;font-size:11.5px;font-weight:700;color:#2f6b3f
}
/* A discount off the price, said on the card as well as in the breakdown: the same green as
   the rebate, because to a buyer scanning the plans both read as "this one costs less". */
.plan .psave{
    display:block;margin-top:3px;font-size:11.5px;font-weight:700;color:#2f6b3f
}
/* The price it came off, kept beside the net so the saving is visible without doing the
   subtraction. Muted and smaller -- the figure that is paid stays the loudest one. */
.plan .pwas{
    display:block;font-size:11.5px;font-weight:600;color:var(--muted);text-decoration:line-through
}

/* A plot a customer cannot buy is drawn but does not open; see canOpen() in portal-map.js. */
.leaflet-interactive.plot-locked{cursor:default}

/* ---------- selected pane: premium pass ----------
   The same facts, the same plans, the same breakdown -- arranged so it stops reading as one
   long list. A summary pinned to the top of the panel (plot, state, price, chosen plan) that
   stays in view while the working scrolls under it; the plot's facts as small tiles; each
   payment plan in its own colour, carried from its card into the breakdown under it and up
   into the pinned summary; the breakdown grouped, with the two figures a buyer leaves with
   as bands; and the call to action tightened into one card. See renderSelected(). */
#pane-sel{--pad:14px}

.sel-top{
  position:sticky;top:calc(-1 * var(--pad));z-index:5;
  margin:calc(-1 * var(--pad)) calc(-1 * var(--pad)) 14px;
  padding:16px var(--pad) 14px;
  background:linear-gradient(180deg,#fff 0%,#fcfaf4 100%);
  border-bottom:1px solid var(--line);
  transition:box-shadow .2s ease,padding .2s ease;
}
.sel-top.is-stuck{padding-top:11px;padding-bottom:10px;box-shadow:0 10px 20px -14px rgba(27,32,24,.45)}
.sel-row{display:flex;align-items:center;justify-content:space-between;gap:10px}
.sel-top h3{
  margin:0;min-width:0;font-size:22px;font-weight:800;letter-spacing:-.4px;line-height:1.15;
  color:var(--forest);overflow-wrap:anywhere;transition:font-size .2s ease;
}
.sel-top.is-stuck h3{font-size:17px}
.sel-top .state{flex:none;box-shadow:0 2px 6px -2px rgba(0,0,0,.25)}
.sel-row-2{margin-top:6px;align-items:baseline}
.sel-cat{min-width:0;font-size:12.5px;font-weight:600;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sel-price{
  flex:none;font-size:20px;font-weight:800;letter-spacing:-.4px;color:var(--forest);
  font-variant-numeric:tabular-nums;transition:font-size .2s ease;
}
.sel-top.is-stuck .sel-price{font-size:16px}
.sel-plan{
  display:flex;align-items:center;gap:8px;margin-top:10px;padding:7px 10px;border-radius:10px;
  font-size:12px;background:color-mix(in srgb,var(--acc) 8%,#fff);
  border:1px solid color-mix(in srgb,var(--acc) 26%,#fff);
}
.sel-plan-dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--acc);box-shadow:0 0 0 3px color-mix(in srgb,var(--acc) 18%,transparent)}
.sel-plan-name{min-width:0;font-weight:800;color:var(--acc);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sel-plan-due{margin-left:auto;flex:none;font-weight:700;color:var(--ink-2);white-space:nowrap}

/* Facts: two tiles to a row; a long value (a street name) takes the whole row. */
.sel-facts{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0 0 20px}
.sel-fact{min-width:0;padding:9px 11px;border-radius:10px;background:var(--paper-2);border:1px solid var(--line)}
.sel-fact.is-wide{grid-column:1 / -1}
.sel-fact span{display:block;font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);font-weight:800}
.sel-fact b{display:block;margin-top:3px;font-size:13px;font-weight:700;line-height:1.35;color:var(--ink);overflow-wrap:anywhere}

.sel-sec .sec-title{margin:0 0 10px;font-size:10.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}

/* Lump Sum and Installment each in their own colour, and the steps follow the open tab. */
.pay{--mode:#2f7a55}
.pay.mode-inst{--mode:#3b62a0}
.pay .pay-tabs{padding:4px;margin-bottom:12px;background:var(--paper-3);border-color:var(--line)}
.pay .pay-tab{display:flex;align-items:center;justify-content:center;gap:7px;padding:9px 10px;font-size:13px;transition:background-color .18s ease,color .18s ease,box-shadow .18s ease}
.pay-tab.is-lump{--c:#2f7a55}
.pay-tab.is-inst{--c:#3b62a0}
.pay-tab::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--c);opacity:.55}
.pay .pay-tab:hover{color:var(--c)}
.pay .pay-tab.is-on{background:var(--c);color:#fff;box-shadow:0 4px 12px -4px color-mix(in srgb,var(--c) 70%,transparent)}
.pay .pay-tab.is-on::before{background:#fff;opacity:1}

.pay .dp-label{font-size:12px;line-height:1.45;margin-bottom:8px}
.pay .dp-pick{margin-bottom:12px}
.pay .dp-step{padding:6px 13px;transition:all .15s ease}
.pay .dp-step:hover{border-color:var(--mode);color:var(--mode)}
.pay .dp-step.is-on{
  border-color:var(--mode);color:var(--mode);background:color-mix(in srgb,var(--mode) 10%,#fff);
  box-shadow:0 0 0 1px var(--mode) inset;
}

/* Plan cards: an even colour border, a radio in the same colour, and the chosen one tinted with it. */
.pay .plan{
  position:relative;overflow:hidden;align-items:flex-start;gap:11px;
  padding:13px 14px;margin-bottom:10px;box-shadow:var(--sh-1);
  border:1px solid color-mix(in srgb,var(--acc) 35%,#fff);
}
.pay .plan:hover{border-color:color-mix(in srgb,var(--acc) 55%,#fff)}
.pay .plan.is-on{
  background:color-mix(in srgb,var(--acc) 7%,#fff);border-color:var(--acc);margin-bottom:0;
  box-shadow:var(--sh-1);
}
.pay .plan:focus-within{box-shadow:var(--ring)}
.pay .plan input{position:absolute;opacity:0;pointer-events:none}
.pradio{
  flex:none;width:18px;height:18px;margin-top:1px;border-radius:50%;display:grid;place-items:center;
  border:2px solid color-mix(in srgb,var(--acc) 45%,#fff);background:#fff;transition:border-color .15s ease;
}
.plan.is-on .pradio{border-color:var(--acc)}
.plan.is-on .pradio::after{content:"";width:8px;height:8px;border-radius:50%;background:var(--acc)}
.pay .plan .pmeta{display:flex;flex-direction:column;gap:3px;flex:1}
.pay .plan .pname{font-size:14px;color:var(--ink)}
.pay .plan.is-on .pname{color:var(--acc)}
.pay .plan .psub{line-height:1.45}
.pay .plan .pnow{font-size:15px}
.pay .plan.is-on .pnow{color:var(--acc)}

/* The breakdown under the chosen plan, grouped, with its two key figures as bands. */
.pay .pdetail{background:#fff;border:1px solid var(--acc);padding:2px 14px 14px;margin:0 0 12px}
.pd-rows{display:flex;flex-direction:column}
.pd-head{margin:12px 0 3px;font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);font-weight:800}
.pd-row{
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  padding:7px 0;font-size:12.5px;border-bottom:1px dashed var(--line);
}
.pd-row .k{flex:1 1 55%;min-width:0;color:var(--muted);line-height:1.4}
.pd-row .v{flex:0 1 auto;max-width:48%;text-align:right;font-weight:700;color:var(--ink);line-height:1.4;font-variant-numeric:tabular-nums}
.pd-row.is-cut .k,.pd-row.is-cut .v{color:#2f6b3f}
.pd-row:has(+ .pd-row.is-key),.pd-row:has(+ .pd-head){border-bottom:0}
.pd-row.is-key{
  margin:8px -8px 0;padding:9px 8px;border:0;border-radius:9px;
  background:color-mix(in srgb,var(--acc) 9%,#fff);
}
.pd-row.is-key .k{color:var(--ink);font-weight:800}
.pd-row.is-key .v{color:var(--acc);font-weight:800;font-size:14px}
/* The last band is the total: solid, the plan's own colour. */
.pd-rows > .pd-row.is-key:last-child{background:var(--acc);margin-top:12px}
.pd-rows > .pd-row.is-key:last-child .k,.pd-rows > .pd-row.is-key:last-child .v{color:#fff}

/* The call to action: text and token side by side, then the buttons. */
.secure{
  position:relative;overflow:hidden;margin-top:20px;padding:16px;border-radius:16px;
  background:
    radial-gradient(120% 90% at 100% 0%,rgba(212,180,92,.20),transparent 55%),
    linear-gradient(150deg,var(--forest) 0%,var(--forest-2) 60%,#3a4030 100%);
  box-shadow:0 14px 30px -16px rgba(27,32,24,.6);
}
.secure-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;margin-bottom:14px}
.secure h4{margin:0 0 5px}
.secure p{margin:0;font-size:12px;line-height:1.5}
.secure-token{
  flex:none;text-align:right;padding:8px 11px;border-radius:10px;
  background:rgba(255,255,255,.06);border:1px solid rgba(212,180,92,.32);
}
.secure-token span{display:block;font-size:9px;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.6);font-weight:800}
.secure-token b{display:block;margin-top:2px;font-size:16px;font-weight:800;color:var(--bronze);white-space:nowrap}
.secure-btns{display:flex;flex-direction:column;gap:8px}
.secure .btn-primary{display:block;text-align:center;text-decoration:none;box-shadow:0 6px 16px -8px rgba(212,180,92,.8)}
.btn-ghost.is-dark{
  display:block;margin-top:0;text-align:center;text-decoration:none;
  background:transparent;border-color:rgba(255,255,255,.24);color:#fff;
}
.btn-ghost.is-dark:hover{border-color:var(--bronze);color:var(--bronze)}

.sel-tools{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:12px}
.sel-tools .btn-ghost{margin-top:0;padding:10px 8px;font-size:12.5px}

@media (max-width:860px){
  #pane-sel{--pad:12px}
  .sel-top h3{font-size:19px}
  .sel-price{font-size:18px}
  .sel-facts{margin-bottom:16px}
}

/* ---------- plot popup on phones ----------
   The same card pinned to the plot, as on a wide screen, folded down to fit beside it: narrower,
   tighter rows and type a step smaller, so the plot it describes and its neighbours stay in
   view. Everything else about the plot is a tap away on the sheet's Selected tab. */
@media (max-width:860px){
  .pp{width:236px;padding:10px 12px 12px;font-size:12px}
  .pp-title{font-size:15px;margin-bottom:6px}
  .plot-popup .pp-title{margin-right:34px}
  .pp-tags{gap:5px;margin-bottom:8px}
  .pp-tag{padding:2px 8px;font-size:10px}
  .pp-kv{margin-bottom:9px;padding:0 9px;column-gap:10px}
  .pp-kv dt,.pp-kv dd{padding:4px 0}
  .pp-link.pp-change{font-size:11px;margin-top:1px}
  .pp-price{padding:7px 10px}
  .pp-price .pp-k{font-size:9.5px}
  .pp .pp-price .pp-money{font-size:15px;margin-top:1px}
  .pp-act{margin-top:9px}
  .pp-btn{padding:9px;font-size:12.5px}
  .pp .pp-sub{margin-top:7px;font-size:12px}
  .leaflet-container .plot-popup a.leaflet-popup-close-button{top:8px;right:8px;width:26px;height:26px;font-size:18px}
  .plot-popup .leaflet-popup-content-wrapper{box-shadow:0 8px 24px -6px rgba(15,18,14,.45)}
}
