/* AnCor Development Corporation
   Visual system per docs/website-agency/DESIGN-DIRECTION.md.
   Navy and ivory editorial base, one disciplined green accent, hairline
   structure instead of shadowed cards, Archivo carrying display, Work Sans
   carrying everything a buyer reads. */

:root {
  --navy: #071c2e;
  --ivory: #f3f0e8;
  --green: #2d6a43;
  --green-deep: #225033;
  --stone: #c9c5ba;
  --ink: #0c1620;
  --ivory-dim: #e7e2d6;
  --hairline: rgba(7, 28, 46, 0.14);
  --hairline-strong: rgba(7, 28, 46, 0.28);
  --on-navy: #f3f0e8;
  --on-navy-mute: rgba(243, 240, 232, 0.66);
  --on-navy-hairline: rgba(243, 240, 232, 0.2);

  --display: "Archivo", "Helvetica Neue", system-ui, sans-serif;
  --sans: "Work Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-5: 2.5rem;
  --space-8: 4rem;
  --space-12: 6rem;
  --space-16: 8rem;

  --section-y: clamp(4rem, 8vw, 8rem);
  --gutter: clamp(1.25rem, 6vw, 5rem);
  --header-h: 4.5rem;
  --ease: cubic-bezier(0.2, 0.7, 0.3, 1);
}

*,
*::before,
*::after { box-sizing: border-box; }

html {
  color: var(--ink);
  background: var(--ivory);
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

/* Body runs 16px on phones and settles at 18px on desktop. Restraint here means
   a comfortable reading size, not a small one: the display scale already carries
   the drama, so the copy only has to be easy to read. */
body {
  margin: 0;
  font-family: var(--sans);
  font-size: clamp(1rem, 0.9rem + 0.45vw, 1.125rem);
  line-height: 1.65;
  overflow-x: hidden;
}

/* height: auto matters. The width and height attributes on every img are there
   to reserve space and prevent layout shift, but as presentational hints they
   would otherwise pin a real pixel height and distort any image the CSS sizes
   by width alone. */
img,
video { max-width: 100%; height: auto; display: block; }

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 700;
  line-height: 0.98;
  letter-spacing: -0.02em;
  margin: 0;
  text-wrap: balance;
}

/* A name is the loudest thing on its card, and caps is how a grotesk shouts
   without getting bigger. Applies to names only, never to running headlines. */
.development-copy h2,
.model-card h3,
.featured-name {
  text-transform: uppercase;
  font-weight: 800;
  letter-spacing: 0.005em;
}

h1 { font-size: clamp(2.5rem, 6vw, 5.25rem); }
h2 { font-size: clamp(1.875rem, 4.4vw, 3.5rem); }
h3 { font-size: clamp(1.625rem, 2.6vw, 2.5rem); }

p { margin: 0; }

/* The serif carried emphasis in italic. A grotesk carries it in weight, so the
   accent word gets heavier rather than slanted. */
.word-accent {
  font-style: normal;
  font-weight: 800;
}

a { color: var(--green); text-underline-offset: 0.22em; }
a:hover { color: var(--green-deep); }

a:focus-visible,
button:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 3px solid var(--green);
  outline-offset: 4px;
  border-radius: 2px;
}

.on-navy a:focus-visible,
.site-header a:focus-visible,
.site-header button:focus-visible,
.site-footer a:focus-visible { outline-color: var(--on-navy); }

/* ---------- Layout ---------- */

.wrap {
  width: min(100% - (var(--gutter) * 2), 1440px);
  margin-inline: auto;
}

.wrap--reading { max-width: 66ch; }

.editorial-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 2rem);
  width: min(100% - (var(--gutter) * 2), 1440px);
  margin-inline: auto;
}

.section { padding-block: var(--section-y); }
.section--ivory-dim { background: var(--ivory-dim); }
.section--dim { background: var(--ivory-dim); }
.section--navy { background: var(--navy); color: var(--on-navy); }
.section--navy h2, .section--navy h3 { color: var(--on-navy); }

.skip-link {
  position: absolute;
  left: var(--space-2);
  top: -4rem;
  z-index: 100;
  background: var(--ivory);
  color: var(--ink);
  padding: 0.75rem 1.25rem;
  font-weight: 600;
  transition: top 0.18s var(--ease);
}
.skip-link:focus { top: var(--space-2); }

/* ---------- Editorial type devices ---------- */

/* Eyebrows and fact labels hold 13px on phones and 14px on desktop. Below 13px
   tracked caps stop being a refined label and start being unreadable. */
.eyebrow {
  font-family: var(--sans);
  font-weight: 600;
  font-size: clamp(0.8125rem, 0.78rem + 0.15vw, 0.875rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
  margin: 0;
}

.section--navy .eyebrow { color: var(--on-navy-mute); }

/* Full ivory over the film. A muted eyebrow cannot hold contrast against moving
   bright frames, and the eyebrow is the highest, least scrimmed line of copy. */
.hero .eyebrow { color: var(--on-navy); }

.index-numeral {
  font-family: var(--sans);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  color: var(--stone);
}

.section-opener { max-width: 20ch; margin-block: var(--space-2) 0; }

.lede {
  font-size: clamp(1.0625rem, 1.4vw, 1.25rem);
  max-width: 54ch;
  color: rgba(12, 22, 32, 0.78);
}

.section-opener + .lede { margin-top: var(--space-3); }

.section--navy .lede { color: var(--on-navy-mute); }

.rule-accent {
  width: 3.5rem;
  height: 2px;
  background: var(--green);
  border: 0;
  margin: 0 0 var(--space-3);
}

/* ---------- Controls ---------- */

/* Every action reads at 16px or more. A CTA is the one thing on the page that
   must never make a buyer squint. */
.button,
.button-ghost {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3rem;
  padding: 0.75rem 1.75rem;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.02em;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background 0.18s var(--ease), color 0.18s var(--ease), border-color 0.18s var(--ease);
}

.button {
  background: var(--green);
  color: var(--ivory);
}
.button:hover,
.button:focus-visible { background: var(--green-deep); color: var(--ivory); }

.button-ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--hairline-strong);
}
.button-ghost:hover { border-color: var(--green); color: var(--green-deep); }

.on-navy .button-ghost,
.hero .button-ghost {
  color: var(--on-navy);
  border-color: rgba(243, 240, 232, 0.45);
}
.on-navy .button-ghost:hover,
.hero .button-ghost:hover {
  border-color: var(--on-navy);
  background: rgba(243, 240, 232, 0.1);
  color: var(--on-navy);
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  min-height: 2.75rem;
  font-weight: 600;
  font-size: 1rem;
  color: var(--green);
  text-decoration: none;
  border-bottom: 1px solid var(--green);
  align-self: flex-start;
  transition: gap 0.18s var(--ease), border-color 0.18s var(--ease);
}
.text-link::after { content: "\2192"; transition: transform 0.18s var(--ease); }
.text-link:hover { color: var(--green-deep); }
.text-link:hover::after { transform: translateX(3px); }

.hero .text-link,
.on-navy .text-link { color: var(--on-navy); border-bottom-color: rgba(243, 240, 232, 0.5); }
.hero .text-link:hover,
.on-navy .text-link:hover { color: var(--on-navy); border-bottom-color: var(--on-navy); }

/* ---------- Header ---------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 0.75rem var(--gutter);
  background: var(--navy);
  min-height: var(--header-h);
  transition: background 0.3s var(--ease);
}

/* Home only: the header floats over the hero film until the hero scrolls away. */
.site-header--overlay {
  position: fixed;
  inset: 0 0 auto;
  background: transparent;
}

/* The upper frames of the film are bright sky and roof, so the overlay header
   carries its own shade to keep the mark and the labels legible. It runs past
   the header height and fades out, so there is no visible hard edge. */
.site-header--overlay::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 190%;
  background: linear-gradient(to bottom, rgba(7, 28, 46, 0.88) 0%, rgba(7, 28, 46, 0.72) 42%, rgba(7, 28, 46, 0.3) 72%, rgba(7, 28, 46, 0) 100%);
  pointer-events: none;
}

.site-header--overlay.is-solid {
  background: var(--navy);
}
.site-header--overlay.is-solid::before { opacity: 0; }

.brand {
  position: relative;
  display: block;
  flex-shrink: 0;
  line-height: 0;
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--on-navy);
  text-decoration: none;
}

/* The official mark reads on its own light ground. Its lettering runs deep blue
   to green, which disappears against navy, so the plate is the honest way to
   show the real mark on a dark header rather than redrawing it. */
.brand img {
  width: clamp(5.25rem, 9vw, 7.25rem);
  height: auto;
  background: var(--ivory);
  padding: 0.3rem 0.5rem;
}

.menu-toggle {
  display: none;
  min-height: 2.75rem;
  min-width: 2.75rem;
  padding: 0.5rem 0.875rem;
  background: transparent;
  color: var(--on-navy);
  border: 1px solid rgba(243, 240, 232, 0.4);
  font-family: var(--sans);
  font-weight: 600;
  font-size: 1rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
}

.site-nav {
  position: relative;
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 1.5vw, 1.5rem);
}

.site-nav a {
  position: relative;
  font-size: 1rem;
  font-weight: 500;
  color: var(--on-navy);
  text-decoration: none;
  white-space: nowrap;
  padding-block: 0.5rem;
  transition: color 0.18s var(--ease);
}

.site-nav a:hover { color: var(--ivory); }

.site-nav a[aria-current="page"] { color: var(--on-navy); }
.site-nav a[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0.15rem;
  height: 2px;
  background: var(--green);
}

/* The nav CTA is the same action as the hero card's Find a Lot, so it carries
   the same solid green fill. An outlined version read as secondary chrome next
   to a filled button doing the identical job. */
.site-nav .nav-cta {
  background: var(--green);
  border: 1px solid var(--green);
  color: var(--ivory);
  padding: 0.6rem 1.25rem;
  min-height: 2.75rem;
  display: inline-flex;
  align-items: center;
  font-weight: 600;
  font-size: 1rem;
  transition: background 0.18s var(--ease), border-color 0.18s var(--ease);
}
.site-nav .nav-cta:hover,
.site-nav .nav-cta:focus-visible {
  background: var(--green-deep);
  border-color: var(--green-deep);
  color: var(--ivory);
}
.site-nav .nav-cta[aria-current="page"]::after { display: none; }

@media (max-width: 900px) {
  /* THE CLOSE CONTROL MUST SIT ABOVE THE SHEET. .site-nav is fixed inset:0
     inside the header and comes after this button in the DOM, so without a
     stacking order the full-screen panel paints straight over it and there is
     no visible way out of the menu. */
  .menu-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    position: relative;
    z-index: 2;
  }

  .site-nav { z-index: 1; }

  /* An explicit X, because "Close" as a word alone is not what a phone user
     looks for to dismiss a full-screen menu. */
  .menu-toggle[aria-expanded='true']::before {
    content: '×';
    font-size: 1.5em;
    line-height: 1;
    font-weight: 400;
  }

  .site-nav {
    position: fixed;
    inset: 0;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: var(--space-1);
    padding: var(--space-8) var(--gutter);
    background: var(--navy);
    /* Complete resting state: the sheet is closed and inert until opened. */
    transform: translateY(-100%);
    visibility: hidden;
    transition: transform 0.32s var(--ease), visibility 0.32s var(--ease);
    overflow-y: auto;
  }

  body.menu-open .site-nav { transform: translateY(0); visibility: visible; }
  body.menu-open { overflow: hidden; }

  .site-nav a {
    font-family: var(--display);
    font-weight: 600;
    font-size: 2rem;
    line-height: 1.5;
    padding-block: 0.5rem;
    min-height: 3rem;
    display: flex;
    align-items: center;
  }

  .site-nav a[aria-current="page"]::after { bottom: 0.5rem; right: auto; width: 100%; }

  .site-nav .nav-cta {
    margin-top: var(--space-3);
    font-family: var(--sans);
    font-size: 0.9375rem;
    min-height: 3rem;
    padding: 0.75rem 1.75rem;
  }
}

/* No-JS: the lot select is only ever populated by a script fetching the
   published plan, so without JS it can never offer a real lot. Fall back to
   the same plain description field every development used before this page
   grew a picker, rather than leave a dead control nobody can act on. */
html:not(.js) .reservation-form [data-lot-select-field] { display: none; }
html:not(.js) .reservation-form [data-lot-text-field][hidden] { display: grid; }

/* No-JS: the payment preview card needs scripting to load lot data. Hide the
   live card and show the static contact fallback instead. */
html:not(.js) [data-js-only] { display: none; }
html.js [data-nojs-card] { display: none; }

/* No-JS: the sheet cannot be opened, so the links must stay reachable inline. */
html:not(.js) .menu-toggle { display: none; }
@media (max-width: 900px) {
  html:not(.js) .site-nav {
    position: static;
    transform: none;
    visibility: visible;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-2);
    padding: 0;
    background: transparent;
  }
  html:not(.js) .site-nav a { font-family: var(--sans); font-size: 1rem; }
}

/* ---------- Hero ---------- */

/* min-height, not height: the product hero carries the featured development card
   as well as the copy, so the section has to be able to grow rather than push its
   own top edge up behind the overlay header and under the clip. */
.hero {
  position: relative;
  display: flex;
  align-items: flex-end;
  min-height: 100svh;
  overflow: hidden;
  background: var(--navy);
  isolation: isolate;
}

/* The source is vertical (720x1280), so a desktop hero can only ever show a
   band of it: at 1280x800 the film scales to 1280x2276 and about 35% of the
   frame height survives. At the old 42% that band landed on the mid-level
   glazing and railings, which read as a dark corridor rather than as a home.
   26% lifts the band onto the roofline and the upper facade, which is the part
   that actually sells a finished house. Phones are unaffected: at 360x800 the
   film covers by width, so the whole frame height is already visible and this
   value does nothing. */
.hero-video,
.hero-poster {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 26%;
  z-index: -2;
}

/* Directional scrim, tuned against the actual film pixels, which are bright
   white walls and sky throughout.
   The guarantee is horizontal rather than radial-from-the-corner. The product
   hero's copy column now runs from just under the header down to the actions, so
   a scrim anchored at the lower left left the eyebrow and headline sitting on
   clear sky. A left-to-right gradient is independent of how tall the copy grows:
   the reading column is always dark enough, and the right of the frame stays
   clear, which is exactly where the house is. Measured by
   scripts/check-hero-contrast.mjs, never assumed. */
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to right,
      rgba(7, 28, 46, 0.93) 0%,
      rgba(7, 28, 46, 0.88) 30%,
      rgba(7, 28, 46, 0.72) 55%,
      rgba(7, 28, 46, 0.3) 72%,
      rgba(7, 28, 46, 0) 88%),
    linear-gradient(to top,
      rgba(7, 28, 46, 0.5) 0%,
      rgba(7, 28, 46, 0.16) 42%,
      rgba(7, 28, 46, 0) 78%);
}

/* The top padding clears the floating header, so the eyebrow can never end up
   sitting behind the brand bar however tall the copy block grows. */
.hero-content {
  position: relative;
  width: min(100% - (var(--gutter) * 2), 1440px);
  margin-inline: auto;
  padding-top: calc(var(--header-h) + var(--space-2));
  padding-bottom: clamp(2.5rem, 5vw, 4.5rem);
  color: var(--on-navy);
}

/* Sized so the hero display sets in two lines at most while the whole copy
   block stays inside the lower-left anchor, which is also the zone the scrim
   guarantees contrast for. */
.hero-inner { max-width: min(46rem, 100%); }

.hero .rule-accent { background: var(--green); }

.hero h1 {
  color: var(--on-navy);
  margin-block: var(--space-2) var(--space-3);
}

.hero-lede {
  font-size: clamp(1.0625rem, 1.3vw, 1.25rem);
  color: var(--on-navy);
  max-width: 44ch;
  margin-bottom: var(--space-5);
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

@media (max-width: 780px) {
  /* Vertical source, so the phone hero is a first-class cinematic surface.
     The product hero carries the featured development card as well as the copy,
     so the copy block now spans nearly the whole phone viewport and there is no
     longer an empty upper frame to leave clear. The scrim reads as a graded dusk field
     rather than a bottom-up fade: it is tuned to the lightest measured value
     that still clears 4.5:1 everywhere, so the house stays visible as a real
     shape instead of being buried. Verified by scripts/check-hero-contrast.mjs
     against the actual film pixels, not assumed. */
  .hero-scrim {
    background: linear-gradient(to top,
      rgba(7, 28, 46, 0.93) 0%,
      rgba(7, 28, 46, 0.87) 40%,
      rgba(7, 28, 46, 0.78) 72%,
      rgba(7, 28, 46, 0.73) 100%);
  }
  .hero-content { padding-bottom: max(1.75rem, env(safe-area-inset-bottom)); }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .button { width: 100%; }
  .hero-actions .text-link { align-self: center; }

  /* The phone hero carries the headline, the supporting line, the featured
     development card and both actions inside one 800px viewport, so the rhythm
     tightens here rather than pushing the secondary action below the fold.
     Measured by scripts/check-hero-fold.mjs, not eyeballed. */
  .hero .rule-accent { margin-bottom: var(--space-2); }
  .hero h1 { margin-block: 0.75rem var(--space-3); }
  .hero-lede { margin-bottom: var(--space-3); }
}

/* ---------- Featured development card ---------- */

/* The hero is a two-column property presentation: the offer statement on the
   left, the one development a buyer can act on today on the right. */
.hero-grid {
  display: grid;
  gap: var(--space-5);
  align-items: end;
}

@media (min-width: 900px) {
  .hero-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 22rem);
    gap: clamp(2rem, 5vw, 5rem);
  }
  /* The card is a presentation panel, not a footnote: it holds its own optical
     weight beside a 84px headline. */
  .featured { justify-self: end; width: 100%; }
}

/* A restrained editorial card, not a form. Its own ground is what makes it
   readable, so it never depends on which frame of the film is behind it: at 0.88
   over even a pure white frame the panel resolves to about rgb(37,55,71), which
   is 9.6:1 against ivory. The blur is polish, and nothing depends on it. */
.featured {
  padding: var(--space-3);
  background: rgba(7, 28, 46, 0.88);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1px solid rgba(243, 240, 232, 0.28);
  color: var(--on-navy);
}

.featured-eyebrow {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--green);
  margin: 0;
}

/* The accent green is too dark to read on the card's navy ground, so the
   eyebrow takes the lighter tint of the same hue rather than the token. */
.featured-eyebrow { color: #6fae86; }

.featured-name {
  font-size: clamp(1.5rem, 2.2vw, 1.875rem);
  color: var(--on-navy);
  margin-block: 0.625rem 0.25rem;
}

.featured-place { color: var(--on-navy-mute); }

.featured-facts {
  display: grid;
  margin: var(--space-3) 0 0;
  border-top: 1px solid var(--on-navy-hairline);
}

.featured-facts > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  padding-block: 0.7rem;
  border-bottom: 1px solid var(--on-navy-hairline);
}

.featured-facts dt {
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-navy-mute);
}

.featured-facts dd {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-size: 1rem;
  text-align: right;
}

/* 395 is a planned total. This line is the only thing stopping a buyer reading
   it as remaining stock, so it sits directly under the number and is not
   editable. See EDITABILITY-AUDIT.md. */
.featured-note {
  margin-top: 0.75rem;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--on-navy-mute);
}

.featured .button { width: 100%; margin-top: var(--space-3); }

/* ---------- Wayfinding paths ---------- */

.paths {
  display: grid;
  gap: 0;
  margin-top: var(--space-8);
  border-top: 1px solid var(--hairline);
}

.path {
  display: grid;
  gap: var(--space-1);
  grid-template-columns: auto 1fr;
  column-gap: var(--space-3);
  align-items: baseline;
  padding-block: var(--space-5);
  border-bottom: 1px solid var(--hairline);
  text-decoration: none;
  color: inherit;
  transition: background 0.2s var(--ease);
}

.path:hover { background: var(--ivory-dim); }
.path:hover .path-title { color: var(--green-deep); }

.path-title {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.625rem, 3vw, 2.5rem);
  line-height: 1.05;
  transition: color 0.18s var(--ease);
}

.path-body {
  grid-column: 2;
  color: rgba(12, 22, 32, 0.74);
  max-width: 52ch;
}

.path-cue {
  grid-column: 2;
  font-weight: 600;
  font-size: 1rem;
  color: var(--green);
  margin-top: var(--space-1);
}

@media (min-width: 900px) {
  .path { grid-template-columns: 4rem 22rem 1fr; column-gap: var(--space-5); align-items: start; }
  .path-body { grid-column: 3; margin-top: 0.35rem; }
  .path-cue { grid-column: 3; }
}

/* ---------- Development spreads ---------- */

.spreads { display: grid; gap: 0; }

.development-spread {
  display: grid;
  gap: var(--space-5);
  padding-block: var(--section-y);
  border-top: 1px solid var(--hairline);
  align-items: center;
}

.development-spread:first-child { border-top: 0; }

.development-media { margin: 0; }

.development-media img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center center;
}

/* A project logo is a mark, not a photograph, so it must never be cropped to
   the spread ratio. */
.development-media img.development-logo {
  width: clamp(11rem, 22vw, 18rem);
  aspect-ratio: auto;
  height: auto;
  object-fit: contain;
}

/* A promotional graphic carries its own title, tagline, or logo baked into
   the frame (Talon Farm Estates' "GROW L.I.F.E." card). Cropping it to the
   4:5 spread ratio cuts that text off, so it keeps its own aspect ratio at
   full card width instead of being cover-cropped. */
.development-media img.development-poster {
  aspect-ratio: auto;
  height: auto;
  object-fit: contain;
}

/* A development with no supplied photograph is a complete editorial record,
   not a hole. The name and the fact column carry it. */
.development-copy { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-2); }

.development-copy h2 { margin-block: var(--space-1) var(--space-2); }

.development-note { color: rgba(12, 22, 32, 0.74); max-width: 46ch; }

.development-logo {
  width: clamp(9rem, 16vw, 13rem);
  height: auto;
  margin-bottom: var(--space-2);
}

.facts {
  display: grid;
  width: 100%;
  max-width: 30rem;
  margin: var(--space-2) 0 var(--space-3);
  border-top: 1px solid var(--hairline);
}

.facts > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  padding-block: 0.85rem;
  border-bottom: 1px solid var(--hairline);
}

.facts dt {
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(12, 22, 32, 0.6);
}

.facts dd {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-size: 1rem;
  text-align: right;
}

/* Status is a refined typographic label, never a coloured pill badge. */
.status-open { color: var(--green); }
.status-closed { color: rgba(12, 22, 32, 0.5); }

@media (min-width: 900px) {
  .development-spread { grid-template-columns: 1fr 1fr; gap: clamp(3rem, 6vw, 6rem); }
  .development-spread--flip .development-media { order: 2; }

  /* No supplied photograph for this project, so the record itself is the
     spread: the name carries the left, the verified facts carry the right. */
  .development-spread--record { grid-template-columns: minmax(0, 26rem) 1fr; align-items: start; }
}

.development-spread--record .facts { margin-top: 0; max-width: none; }

/* Two actions per development: ask about it, or go see its layout on Find a
   Lot. They wrap rather than shrink, because both are real sentences and a
   narrow phone should stack them, not squeeze them onto one line. */
.spread-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  margin: 0;
}

/* ---------- Illustrative lot plan ---------- */

.lot-plan-section {
  grid-column: 1 / -1;
  min-width: 0;
  margin-top: var(--space-3);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline);
}

.lot-plan-section h3 {
  margin-block: var(--space-2) var(--space-3);
  font-family: var(--display);
  font-size: clamp(2rem, 5vw, 4rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
}

.lot-plan-notice,
.lot-plan-error {
  max-width: 72ch;
  margin-bottom: var(--space-3);
  padding: var(--space-3) var(--space-3);
  border-left: 3px solid var(--green);
  background: rgba(255, 255, 255, 0.64);
  color: rgba(12, 22, 32, 0.78);
}

.lot-plan {
  max-width: 100%;
  overflow-x: auto;
  border: 1px solid var(--hairline);
  background: var(--ivory-dim);
  scrollbar-gutter: stable;
}

/* 60rem, not 52rem, and the number is derived rather than chosen. Puente Acuna
   needs a 1740 unit canvas to hold 494 lots, so at 52rem its blocks scaled down
   to about 25px thick. Reaching a 44px tap target then needed 40 units of
   padding, but the roads between blocks are only 33.8 units wide, so the padded
   targets would have collided across the street. 60rem is the first width where
   the padding that buys 44px still fits inside the narrowest road, with margin.
   Recompute this if any village viewBox changes. */
.lot-plan svg {
  display: block;
  width: 100%;
  min-width: 60rem;
  height: auto;
}

.lot-plan svg:focus-visible {
  outline: 3px solid var(--green);
  outline-offset: -3px;
}

/* An empty plan host is a failed render, not a spacer. */
.lot-plan:empty { display: none; }

/* These two carry no fill attribute, and an SVG shape with no fill defaults to
   BLACK, so without these rules the whole plan paints solid black and the lots
   read as faint scratches on top. That is exactly how it shipped once.
   The ground is the land inside the village. Blocks sit on it in ivory, so the
   gaps between them read as road corridors rather than as page background. */
.plan-ground { fill: var(--stone); }

/* The generated terrain base. Land only, no roads and no lots, so the drawn
   subdivision above it can never disagree with it. */
.plan-terrain { opacity: 0.92; }

/* Tonal variation across the ground. A plan on one flat fill is the
   single-canvas tell from design-language.md, and it reads as a diagram rather
   than as land. Kept very low contrast: this should be felt, not seen. */
.plan-ground-patch {
  fill: rgba(7, 28, 46, 0.035);
  stroke: none;
}

/* The treeline outside the village edge, which is where it is in the aerials.
   It also fills the margin that made the old plan read as shapes floating on a
   page. Two tones so the canopy has depth instead of being one green mass. */
.plan-canopy {
  fill: rgba(58, 92, 62, 0.30);
  stroke: none;
}

.plan-canopy.is-deep { fill: rgba(38, 68, 45, 0.42); }

.plan-water {
  fill: rgba(28, 78, 108, 0.34);
  stroke: rgba(28, 78, 108, 0.22);
  stroke-width: 3;
}

.plan-boundary {
  fill: none;
  stroke: var(--navy);
  stroke-width: 3;
  stroke-linejoin: round;
}

/* The carriageway. Same no-fill trap as everything else here: without an
   explicit fill these paint solid black across the whole village.

   Casing is a slightly darker shape under the surface, so a road reads as a
   made-up street with a shoulder rather than a pale gap, and the blocks sit ON
   the ground instead of floating above it. Both are drawn before the blocks. */
.plan-road-casing {
  fill: rgba(7, 28, 46, 0.18);
  stroke: rgba(7, 28, 46, 0.18);
  stroke-width: 6;
  stroke-linejoin: round;
}

.plan-road {
  fill: #e2dbc9;
  stroke: none;
}

/* The spine roads are the ones carrying traffic through the village, so they
   read a touch lighter than the branches, the way a sealed road does. */
.plan-road[data-road-kind='spine'] { fill: #ece6d8; }

/* Same trap as above, and the reason the whole plan once painted black: every
   one of these ships without a fill attribute, so each defaults to black and
   paints over the lots underneath. The block is an outline around its lots,
   never a filled mass. */
.plan-block { fill: none; }

.block-shape {
  fill: none;
  stroke: var(--navy);
  stroke-width: 2.5;
  stroke-linejoin: round;
}

.block-number {
  fill: var(--navy);
  font-family: var(--display);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 0.06em;
  paint-order: stroke;
  stroke: var(--ivory);
  stroke-width: 4;
  pointer-events: none;
}

/* At village scale a lot is a few pixels across, so the BLOCK is the target and
   the lots inside it are decoration until you zoom in. */
.block-target {
  fill: transparent;
  stroke: transparent;
  stroke-width: 30;
  stroke-linejoin: round;
  cursor: pointer;
}

.block-target:hover { fill: rgba(14, 92, 59, 0.13); }

.block-target:focus-visible {
  outline: 3px solid var(--green);
  outline-offset: 2px;
}

.lot-plan-back {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding-inline: var(--space-2);
  border: 1px solid var(--hairline);
  background: transparent;
  font: inherit;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}

.lot-plan-back:hover { border-color: var(--green); color: var(--green); }

.lot {
  fill: var(--ivory);
  stroke: var(--hairline-strong);
  stroke-width: 1;
  cursor: pointer;
  transition: fill 0.18s var(--ease), stroke 0.18s var(--ease), stroke-width 0.18s var(--ease);
}

/* STATUS COLOUR IS THE FEATURE. "See all the available slots" has to be
   answerable at a glance, before anything is clicked, which a plan of uniform
   ivory rectangles cannot do.

   The palette is deliberately not a traffic light: available reads as the
   inviting one, sold is muted and recessive rather than alarming, and a lot
   whose status AnCor has not published is plainly neutral so it cannot be
   mistaken for either. */
.lot[data-lot-status='Available'] { fill: #cfe0ee; stroke: #6f93b0; }
.lot[data-lot-status='Sold'] { fill: #e6d2d4; stroke: #ac8d90; }
.lot[data-lot-status='Status not published'] { fill: #e9e5da; stroke: #b0a894; }
.lot[data-lot-status='Illustrative'] { fill: #e9e5da; stroke: #b0a894; }

/* A number on every lot. Hidden at village scale, where 395 of them at 20
   pixels each is noise, and shown once a block is zoomed into. */
.lot-number {
  display: none;
  fill: var(--navy);
  font-family: var(--sans);
  font-size: 9px;
  font-weight: 600;
  pointer-events: none;
  user-select: none;
}

[data-lot-plan-mode='block'] .lot-number { display: block; }

.lot:hover { fill: rgba(14, 92, 59, 0.13); }

.lot:focus-visible {
  outline: 3px solid var(--green);
  outline-offset: 2px;
}

/* Base .lot rule first, contextual override second. Order matters beyond the
   cascade here: a sibling test finds the lot rule with a plain ".lot {" regex,
   so a contextual rule placed above the base one gets picked up instead. */
[data-lot-plan-mode="village"] .lot {
  pointer-events: none;
}

.lot[aria-selected="true"] {
  fill: var(--green);
  stroke: var(--navy);
  stroke-width: 3;
}

.lot-detail {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-3);
  scroll-margin-top: 6.5rem;
  padding: var(--space-3);
  border: 1px solid var(--hairline);
  background: var(--ivory-dim);
}

.lot-detail[hidden] { display: none; }

.lot-detail-heading {
  margin: 0 0 var(--space-2);
  scroll-margin-top: 6.5rem;
  font-family: var(--display);
  font-size: clamp(1.75rem, 4vw, 2.75rem);
  line-height: 1;
}

.lot-detail-heading:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 0.3rem;
}

.lot-detail dl {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--space-1) var(--space-2);
  margin: var(--space-3) 0;
}

.lot-detail dt {
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(12, 22, 32, 0.72);
}

.lot-detail dd {
  margin: 0;
  font-weight: 650;
  font-variant-numeric: tabular-nums;
  text-align: right;
}

[data-lot-detail-content] {
  min-width: 0;
  /* Keep the panel's sticky containing block alive until the final monetary
     row clears the protected notice, including the taller phone notice. */
  padding-bottom: 8.5rem;
}

.lot-terms {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.lot-terms label {
  display: grid;
  flex: 1 1 12rem;
  gap: 0.4rem;
  font-size: 0.8rem;
  font-weight: 650;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.lot-terms select {
  width: 100%;
  min-height: 44px;
  padding-inline: var(--space-1);
  border: 1px solid var(--hairline-strong);
  border-radius: 0;
  background: var(--ivory);
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
}

.lot-detail-inquiry { width: fit-content; }

.lot-detail-notice {
  position: sticky;
  top: calc(var(--header-h) + var(--space-3));
  z-index: 1;
  align-self: start;
  margin: 0;
  padding: var(--space-2);
  border-left: 3px solid var(--green);
  background: var(--ivory);
  color: rgba(12, 22, 32, 0.78);
  font-size: 0.875rem;
  line-height: 1.5;
}

.lot-table-wrap {
  max-width: 100%;
  min-width: 0;
  margin-top: var(--space-3);
  border: 1px solid var(--hairline);
  background: var(--ivory-dim);
}

.lot-table-wrap > summary {
  display: flex;
  min-height: 44px;
  align-items: center;
  padding: var(--space-1) var(--space-3);
  color: var(--ink);
  font-weight: 650;
  cursor: pointer;
}

.lot-table-wrap > summary:focus-visible {
  outline: 3px solid var(--green);
  outline-offset: -3px;
}

.lot-table-scroll {
  max-width: 100%;
  overflow-x: auto;
  border-top: 1px solid var(--hairline);
  -webkit-overflow-scrolling: touch;
}

.lot-table-scroll table {
  width: 100%;
  min-width: 34rem;
  border-collapse: collapse;
  font-variant-numeric: tabular-nums;
}

.lot-table-scroll caption {
  padding: var(--space-2) var(--space-3);
  color: rgba(12, 22, 32, 0.78);
  font-size: 0.875rem;
  text-align: left;
}

.lot-table-scroll th,
.lot-table-scroll td {
  padding: 0.7rem var(--space-3);
  border-top: 1px solid var(--hairline);
  text-align: left;
  white-space: nowrap;
}

.lot-table-scroll th {
  color: var(--ink);
  font-size: 0.75rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.lot-table-scroll tbody tr:nth-child(even) { background: rgba(255, 255, 255, 0.52); }

@media (min-width: 900px) {
  .lot-detail {
    display: grid;
    grid-template-columns: minmax(0, 1.45fr) minmax(16rem, 0.75fr);
    align-items: start;
  }

  [data-lot-detail-content] {
    grid-column: 1;
    grid-row: 1;
  }

  .lot-detail-notice {
    grid-column: 2;
    grid-row: 1;
  }
}

/* ---------- Development atlas ---------- */

.atlas { display: grid; gap: var(--space-5); margin-top: var(--space-5); }

.atlas-figure { margin: 0; }

/* contain, not cover: these are maps, and cropping one would cut the very
   labels that make it useful. A shared ratio keeps the row's heights aligned. */
.atlas-figure img {
  width: 100%;
  aspect-ratio: 2 / 1;
  object-fit: contain;
  border: 1px solid var(--hairline);
  background: var(--ivory-dim);
}

.atlas-figure figcaption {
  margin-top: var(--space-1);
  font-size: 0.9375rem;
  color: rgba(12, 22, 32, 0.62);
}

.atlas-index {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-3);
  margin-top: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px solid var(--hairline);
}

.atlas-index a {
  font-weight: 600;
  font-size: 1rem;
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-block: 0.35rem;
}
.atlas-index a:hover { border-bottom-color: var(--green); }

@media (min-width: 900px) {
  .atlas { grid-template-columns: 1fr 1fr; }
}

/* ---------- Model cards and finder ---------- */

.finder {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-3);
  margin-top: var(--space-5);
  background: var(--ivory-dim);
  border: 1px solid var(--hairline);
}

.finder-controls {
  display: grid;
  gap: var(--space-2);
}

.field { display: grid; gap: 0.375rem; }

/* An explicit display BEATS the hidden attribute, so a .field marked hidden
   stays on screen. The PRC licence row shipped visible to accredited sellers
   because of exactly this. Any container with its own display needs the pair. */
.field[hidden] { display: none; }

.field label {
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(12, 22, 32, 0.66);
}

.field select,
.field textarea,
.field input {
  min-height: 2.75rem;
  padding: 0.5rem 0.75rem;
  font-family: var(--sans);
  font-size: 1rem;
  color: var(--ink);
  background: var(--ivory);
  border: 1px solid var(--hairline-strong);
  border-radius: 0;
  appearance: none;
}

.field select {
  background-image: linear-gradient(45deg, transparent 50%, var(--ink) 50%), linear-gradient(135deg, var(--ink) 50%, transparent 50%);
  background-position: calc(100% - 1.15rem) 1.2rem, calc(100% - 0.8rem) 1.2rem;
  background-size: 0.35rem 0.35rem, 0.35rem 0.35rem;
  background-repeat: no-repeat;
  padding-right: 2.25rem;
}

.field textarea { min-height: 7rem; resize: vertical; line-height: 1.6; }

.finder-footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--hairline);
}

.result-count {
  font-weight: 600;
  font-size: 1rem;
  font-variant-numeric: tabular-nums;
  color: rgba(12, 22, 32, 0.7);
}

.reset-button {
  min-height: 2.75rem;
  padding: 0.5rem 1rem;
  background: transparent;
  border: 1px solid var(--hairline-strong);
  font-family: var(--sans);
  font-weight: 600;
  font-size: 1rem;
  color: var(--ink);
  cursor: pointer;
}
.reset-button:hover { border-color: var(--green); color: var(--green-deep); }

@media (min-width: 700px) {
  .finder-controls { grid-template-columns: repeat(3, 1fr); align-items: end; }
}

.model-grid {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-5);
  list-style: none;
  padding: 0;
}

@media (min-width: 700px) { .model-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1100px) { .model-grid { grid-template-columns: repeat(3, 1fr); } }

/* Flat ivory-dim ground with a hairline. No shadow stack, no rounded pills. */
.model-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-3);
  background: var(--ivory-dim);
  border: 1px solid var(--hairline);
}

.model-card h3 { margin-bottom: 0.25rem; }

.model-specs {
  display: grid;
  margin: 0;
  border-top: 1px solid var(--hairline);
}

.model-specs > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  padding-block: 0.6rem;
  border-bottom: 1px solid var(--hairline);
}

.model-specs dt {
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(12, 22, 32, 0.6);
}

.model-specs dd {
  margin: 0;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-size: 1rem;
}

/* The plan sheet is supporting evidence, never the primary read. */
.model-plan {
  position: relative;
  margin: 0;
  border: 1px solid var(--hairline);
  background: var(--ivory);
}

/* 4:3 matches the geometry of the real cuts taken from the client's own plan
   sheets, so no model name, dimension, or floor plan is ever cropped away. */
.model-plan img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center center;
}

.model-plan img.model-plan-name-correction {
  position: absolute;
  top: 3.2%;
  left: 3.2%;
  z-index: 1;
  width: 23.25%;
  height: auto;
  aspect-ratio: 145 / 42;
  object-fit: contain;
}

.model-plan figcaption {
  padding: 0.5rem 0.75rem;
  font-size: 0.8125rem;
  color: rgba(12, 22, 32, 0.6);
  border-top: 1px solid var(--hairline);
}

.model-media-tabs {
  display: flex;
  gap: var(--space-1);
  margin-bottom: var(--space-2);
}

.model-media-tabs[hidden] { display: none; }

.model-media-tabs button {
  min-height: 44px;
  padding-inline: var(--space-2);
  border: 1px solid var(--hairline);
  background: transparent;
  font: inherit;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}

.model-media-tabs button[aria-selected="true"] {
  border-color: var(--green);
  color: var(--green);
}

/* Model footage uses one intentional 16:9 presentation frame. Reserving that
   ratio before metadata keeps poster-first tab changes from shifting the card. */
.model-media video {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* The two actions stay on ONE ROW at every width. Wrapping put Preview on its
   own line under a full-width Ask button, which read as a separate afterthought
   rather than the pair of choices it is. They share the row and shrink instead,
   and the label ellipsises before the row ever breaks. */
.model-actions {
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  gap: var(--space-1);
  margin-top: auto;
  padding-top: var(--space-1);
}

/* The card must be allowed to shrink below its content. A grid item defaults to
   min-width:auto, so the nowrap buttons inside gave the whole card a large
   min-content width and pushed the three column grid 264px past the viewport.
   The buttons ellipsise; without this the card simply refuses to narrow. */
.model-card { min-width: 0; }

.model-actions > .button {
  flex: 1 1 0;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* A native disclosure: collapsed by default, opens and closes, and has a
   complete resting state with no scripting. */
.model-sheet { border-top: 1px solid var(--hairline); padding-top: var(--space-2); }

.model-sheet summary {
  display: flex;
  align-items: center;
  min-height: 2.75rem;
  font-weight: 600;
  font-size: 1rem;
  color: var(--green);
  cursor: pointer;
  list-style: none;
}

.model-sheet summary::-webkit-details-marker { display: none; }

.model-sheet summary::before {
  content: "+";
  margin-right: 0.5rem;
  font-size: 1.1em;
  line-height: 1;
}

.model-sheet[open] summary::before { content: "\2212"; }
.model-sheet summary:hover { color: var(--green-deep); }

.model-plan--full { margin-top: var(--space-2); }

/* The full sheet is a tall multi-model document, so it is shown whole rather
   than cropped to a card ratio. */
.model-plan--full img { aspect-ratio: auto; object-fit: contain; }

.empty-state {
  padding: var(--space-5) var(--space-3);
  margin-top: var(--space-5);
  border: 1px solid var(--hairline);
  background: var(--ivory-dim);
  text-align: left;
}

.empty-state p { max-width: 46ch; margin-bottom: var(--space-3); }

.empty-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); }

.model-detail {
  display: grid;
  gap: var(--space-5);
  padding-block: var(--section-y);
  border-top: 1px solid var(--hairline);
  scroll-margin-top: 6rem;
}

@media (min-width: 900px) {
  .model-detail { grid-template-columns: minmax(0, 24rem) 1fr; gap: clamp(2.5rem, 5vw, 5rem); align-items: start; }
}

.model-detail .model-plan img { aspect-ratio: auto; object-fit: contain; }

/* ---------- Proof band ---------- */

.proof-list {
  display: grid;
  gap: 0;
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--on-navy-hairline);
}

.proof-list li {
  display: grid;
  gap: 0.25rem;
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--on-navy-hairline);
}

.proof-value {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.4vw, 2.25rem);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.proof-label {
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-navy-mute);
}

.proof-note { font-size: 1rem; color: var(--on-navy-mute); }

@media (min-width: 800px) {
  .proof-list { grid-template-columns: repeat(3, 1fr); border-bottom: 1px solid var(--on-navy-hairline); }
  .proof-list li { border-bottom: 0; padding-inline-end: var(--space-3); }
  .proof-list li + li { border-left: 1px solid var(--on-navy-hairline); padding-inline-start: var(--space-3); }
}

/* ---------- Model preview (home) ---------- */

.model-preview { margin-top: var(--space-5); }

.preview-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--hairline);
}

/* Real links to the full model list, so they still work with scripting off. */
.preview-chips a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  padding: 0.5rem 1rem;
  font-weight: 600;
  font-size: 1rem;
  color: var(--ink);
  text-decoration: none;
  background: var(--ivory-dim);
  border: 1px solid var(--hairline);
  transition: background 0.18s var(--ease), color 0.18s var(--ease), border-color 0.18s var(--ease);
}

.preview-chips a:hover { border-color: var(--green); color: var(--green-deep); }

.preview-chips a[aria-current="true"] {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--on-navy);
}

.preview-panel {
  display: grid;
  gap: var(--space-5);
  padding-top: var(--space-5);
}

@media (min-width: 800px) {
  .preview-panel { grid-template-columns: minmax(0, 22rem) 1fr; gap: clamp(2rem, 5vw, 4rem); align-items: start; }
}

.preview-panel h3 { margin-bottom: var(--space-2); }

/* ---------- Media embeds (click to load) ---------- */

.embed { margin: var(--space-5) 0 0; width: min(100%, 56rem); }

/* A navy ground, so the resting state reads as a deliberate cinema panel
   waiting on the visitor rather than an empty box. */
.embed-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  border: 1px solid var(--navy);
  background: var(--navy);
  overflow: hidden;
}

.embed-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.embed-load {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-3);
  background: transparent;
  border: 0;
  color: var(--on-navy);
  font-family: var(--sans);
  font-size: 1rem;
  cursor: pointer;
  text-align: center;
}

.embed-load:hover .embed-cue { background: var(--green-deep); }

.embed-cue {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 3rem;
  padding: 0.75rem 1.75rem;
  background: var(--green);
  color: var(--ivory);
  font-weight: 600;
  transition: background 0.18s var(--ease);
}

.embed-note { color: var(--on-navy-mute); font-size: 1rem; max-width: 36ch; }

/* If the embed cannot load, this direct link is always present and visible. */
.embed-fallback { margin-top: var(--space-2); font-size: 1rem; }

.map-embed .embed-frame { aspect-ratio: 4 / 3; }

/* ---------- Contact ---------- */

.contact-actions {
  display: grid;
  gap: 0;
  margin: var(--space-5) 0 0;
  padding: 0;
  list-style: none;
  border-top: 1px solid var(--hairline);
}

.section--navy .contact-actions,
.on-navy .contact-actions { border-color: var(--on-navy-hairline); }

.contact-action {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--hairline);
  min-height: 3.5rem;
}

.section--navy .contact-action,
.on-navy .contact-action { border-color: var(--on-navy-hairline); }

.contact-action dt {
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(12, 22, 32, 0.6);
}

.section--navy .contact-action dt,
.on-navy .contact-action dt { color: var(--on-navy-mute); }

.contact-action dd { margin: 0; font-size: 1.0625rem; font-weight: 500; }

.contact-action a {
  display: inline-flex;
  align-items: center;
  min-height: 2.75rem;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

.section--navy .contact-action a,
.on-navy .contact-action a { color: var(--on-navy); }

.composer { display: grid; gap: var(--space-3); }

.composer-fields { display: grid; gap: var(--space-3); }

@media (min-width: 800px) { .composer-fields { grid-template-columns: 1fr 1fr; align-items: start; } }

.composer-note {
  font-size: 1rem;
  color: rgba(12, 22, 32, 0.7);
  max-width: 54ch;
}

.composer-preview {
  padding: var(--space-2);
  background: var(--ivory-dim);
  border: 1px solid var(--hairline);
  font-size: 1rem;
  line-height: 1.6;
}

.composer-preview strong {
  display: block;
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(12, 22, 32, 0.6);
  margin-bottom: 0.35rem;
}

.composer-status { min-height: 1.5em; font-weight: 700; }
.inquiry-trap { position: absolute !important; left: -10000px !important; width: 1px !important; height: 1px !important; overflow: hidden !important; }

/* ---------- FAQ ---------- */

.faq-section .lede { margin-top: var(--space-2); }

.faq-list {
  margin-top: var(--space-5);
  border-top: 1px solid var(--hairline-strong);
}

.faq-item { border-bottom: 1px solid var(--hairline-strong); }

.faq-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: 4.5rem;
  padding-block: var(--space-2);
  cursor: pointer;
  list-style: none;
  font-family: var(--display);
  font-size: clamp(1.125rem, 2vw, 1.5rem);
  font-weight: 700;
  color: var(--navy);
}

.faq-item summary::-webkit-details-marker { display: none; }

.faq-item summary::after {
  content: "+";
  flex: 0 0 auto;
  font-family: var(--sans);
  font-size: 1.5rem;
  font-weight: 500;
  color: var(--green);
}

.faq-item[open] summary::after { content: "\2212"; }

.faq-item p {
  max-width: 72ch;
  padding: 0 3rem var(--space-3) 0;
  color: rgba(12, 22, 32, 0.76);
}

/* ---------- Contact close ---------- */

.contact-close { background: var(--navy); color: var(--on-navy); padding-block: var(--section-y); }
.contact-close h2 { color: var(--on-navy); }
.contact-close .lede { color: var(--on-navy-mute); margin-top: var(--space-2); }

.close-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-5);
}

/* ---------- Footer ---------- */

.site-footer {
  background: var(--navy);
  color: var(--on-navy);
  padding: var(--section-y) 0 var(--space-5);
  border-top: 1px solid var(--on-navy-hairline);
}

.footer-grid {
  display: grid;
  gap: var(--space-5);
  width: min(100% - (var(--gutter) * 2), 1440px);
  margin-inline: auto;
}

@media (min-width: 800px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1.2fr; gap: var(--space-8); } }

.footer-identity img {
  width: clamp(6rem, 12vw, 8.5rem);
  height: auto;
  background: var(--ivory);
  padding: 0.35rem 0.55rem;
  margin-bottom: var(--space-2);
}

.footer-identity p { color: var(--on-navy-mute); font-size: 1rem; max-width: 34ch; }

.footer-heading {
  font-family: var(--sans);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--on-navy-mute);
  margin-bottom: var(--space-2);
}

.footer-links { display: grid; gap: 0.25rem; }

.site-footer nav a,
.footer-connect a {
  display: inline-flex;
  align-items: center;
  min-height: 2.5rem;
  color: var(--on-navy);
  text-decoration: none;
  font-size: 1rem;
}

.site-footer nav a:hover,
.footer-connect a:hover { color: var(--ivory); text-decoration: underline; }

.footer-connect { display: grid; gap: 0.25rem; }

.footer-bottom {
  width: min(100% - (var(--gutter) * 2), 1440px);
  margin: var(--space-8) auto 0;
  padding-top: var(--space-3);
  border-top: 1px solid var(--on-navy-hairline);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: space-between;
  color: var(--on-navy-mute);
  font-size: 0.8125rem;
}

/* ---------- Breadcrumbs ---------- */

.breadcrumbs { padding-top: var(--space-5); font-size: 0.8125rem; }

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  padding: 0;
  list-style: none;
  color: rgba(12, 22, 32, 0.6);
}

.breadcrumbs li + li::before { content: "/"; margin-right: 0.5rem; color: var(--stone); }
.breadcrumbs a { text-decoration: none; }
.breadcrumbs a:hover { text-decoration: underline; }

.page-head { padding-block: var(--space-5) 0; }
.page-head h1 { max-width: 16ch; margin-block: var(--space-2) var(--space-3); }

/* ---------- Vision and mission ---------- */

/* Not the .facts table: these are sentences, and .facts right-aligns short
   values like "215" against a label. */
.aims {
  display: grid;
  gap: var(--space-5);
  margin: var(--space-5) 0 0;
  border-top: 1px solid var(--hairline);
  padding-top: var(--space-5);
}

@media (min-width: 800px) {
  .aims { grid-template-columns: 1fr 1fr; gap: var(--space-8); }
}

.aim-label {
  font-family: var(--sans);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--green-deep);
  margin-bottom: var(--space-2);
}

.aim-text {
  margin: 0;
  font-family: var(--display);
  font-weight: 600;
  font-size: clamp(1.15rem, 2.2vw, 1.5rem);
  line-height: 1.4;
  max-width: 30ch;
}

/* ---------- Photo galleries ---------- */

/* The track is the gallery. It swipes on a phone and scrolls on a desktop with
   no scripting at all, so the resting state is the whole product rather than a
   fallback; gallery.mjs only adds arrows, dots, and a counter on top of it. */
/* min-width:0 so a gallery inside a grid or flex parent may shrink to it. A grid
   item defaults to min-width:auto, which would size this to the widest thing the
   bar can be and scroll the page sideways on a phone. */
.gallery {
  margin-top: var(--space-3);
  min-width: 0;
  /* Held to a reading-width column rather than the full wrap. At full width a
     landscape frame floats in a third of a screen of mat, which reads as a
     mistake rather than as a frame. */
  max-width: 56rem;
}

.gallery-track {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  background: var(--navy);
  border: 1px solid var(--hairline);
}

.gallery-track:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 3px;
}

.gallery-slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  margin: 0;
}

.gallery-slide figure { margin: 0; }

/* AnCor's own photography is a mix of portrait rooms and landscape streets.
   Containing each frame on the navy mat is the deliberate choice: a single
   cover-cropped ratio would cut the ceiling out of the portrait interiors and
   the street out of the landscape ones. The mat is the viewing frame, not a
   white band left by accident. */
.gallery-slide img {
  display: block;
  width: 100%;
  height: clamp(15rem, 48vw, 33rem);
  object-fit: contain;
  background: var(--navy);
}

.gallery-caption {
  margin: var(--space-1) 0 0;
  font-size: 0.85rem;
  color: rgba(12, 22, 32, 0.62);
}

/* A development's gallery spans the whole spread rather than sitting in one of
   its columns, so the photography reads at the same width as the record above
   it in both the one and two column arrangements. */
.development-gallery {
  grid-column: 1 / -1;
  margin-top: var(--space-2);
}

.development-logo--inline {
  width: min(12rem, 60%);
  height: auto;
  margin-block: var(--space-2);
}

.delivered-homes {
  display: grid;
  gap: var(--space-8);
  margin-top: var(--space-5);
}

.delivered-home { min-width: 0; }

.delivered-home h3 {
  margin: 0 0 var(--space-1);
  font-size: clamp(1.25rem, 2.4vw, 1.6rem);
}

.gallery-bar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

.gallery-arrow {
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  border: 1px solid var(--hairline-strong);
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  font-size: 1rem;
  cursor: pointer;
  transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}

.gallery-arrow:hover:not(:disabled) { border-color: var(--green); color: var(--green-deep); }
.gallery-arrow:disabled { opacity: 0.32; cursor: default; }

/* The dots are the shortcut, never the control: the arrows stay 44x44 at every
   width and reach every photograph alongside the swipe, the counter, and the
   arrow keys. So a dot only earns its place at a real 44px target. Letting them
   share the leftover width instead (the previous behaviour) put twenty dots on a
   320px phone as 3px slivers whose 8px circles overlapped into an unhittable
   chain-link smudge, which failed the 44px touch-target rule and looked broken.
   They are fixed at 44px here and gallery.mjs hides the whole row when that many
   do not fit, so the bar can never push the page into a sideways scroll. */
.gallery-dots {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
  overflow: hidden;
}

.gallery-dots[hidden] { display: none; }

.gallery-dot {
  flex: 0 0 2.75rem;
  width: 2.75rem;
  height: 2.75rem;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
}

.gallery-dot::before {
  content: "";
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  transition: background-color 0.3s var(--ease), border-color 0.3s var(--ease);
}

.gallery-dot[aria-current="true"]::before {
  background: var(--green);
  border-color: var(--green);
}

.gallery-dot:focus-visible { outline: 2px solid var(--green); outline-offset: -6px; }

/* margin-left:auto keeps the counter and the next arrow against the right edge
   in both states. With the dots shown the growing dot row already fills the gap;
   with the row hidden this is the only thing holding the bar's shape. */
.gallery-count {
  flex: 0 0 auto;
  margin: 0 0 0 auto;
  font-family: var(--sans);
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  color: rgba(12, 22, 32, 0.62);
  font-variant-numeric: tabular-nums;
}

.on-navy .gallery-caption,
.on-navy .gallery-count { color: var(--on-navy-mute); }
.on-navy .gallery-arrow { border-color: var(--on-navy-hairline); color: var(--on-navy); }
.on-navy .gallery-dot::before { border-color: var(--on-navy-hairline); }

/* ---------- Motion ---------- */

/* Reveals apply only when scripting is on, so the no-JS resting state is
   complete and readable. */
html.js .reveal {
  opacity: 0;
  transform: translateY(1rem);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}

html.js .reveal.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* Decorative easing drops. The hero film is signature motion and is never
     gated on this query. */
  html.js .reveal,
  html.js .reveal.is-in {
    opacity: 1;
    transform: none;
    transition: none;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.prose { margin-top: var(--space-3); max-width: 66ch; }
.prose + .prose { margin-top: var(--space-2); }

.socials { margin-top: var(--space-5); }

.socials-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin: var(--space-2) 0 0;
  padding: 0;
  list-style: none;
}

.socials-list a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--space-2);
  border: 1px solid var(--hairline);
  font-weight: 600;
  text-decoration: none;
}

.socials-list a:hover { border-color: var(--green); }

.broker-list {
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
  max-width: 44rem;
}

.broker-list li {
  padding-block: var(--space-2);
  border-top: 1px solid var(--hairline);
}

.broker-list li:last-child { border-bottom: 1px solid var(--hairline); }
.broker-list + .note { max-width: 44rem; margin-top: var(--space-2); }

/* ---------------------------------------------------------------------------
   Illustrated site plan with live lot hotspots.
   The picture is the map; the polygons over it are the product.
   --------------------------------------------------------------------------- */
/* Capped by HEIGHT, expressed as a width, because the panel is 1.487:1 and a
   plan taller than the viewport makes the reader scroll to see one map. Capping
   the width is what actually controls the height, since the svg keeps its
   aspect. */
.plan-map-figure {
  position: relative;
  width: 100%;
  max-width: 100%;
  margin-inline: auto;
  background: var(--ivory);
  border: 1px solid var(--hairline);
}

.plan-map-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem;
  border-bottom: 1px solid var(--hairline);
  background: var(--ivory);
}

.plan-map-zoom {
  min-width: 44px;
  min-height: 44px;
  padding: 0.4rem 0.75rem;
  border: 1px solid var(--navy);
  background: #fff;
  color: var(--navy);
  font: inherit;
  font-size: 0.84rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.12s ease, color 0.12s ease;
}

.plan-map-zoom:hover {
  background: var(--navy);
  color: #fff;
}

.plan-map-zoom:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

.plan-map-zoom-readout {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding-inline: 0.5rem;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--ink);
  opacity: 0.75;
}

.plan-map-viewport {
  overflow: auto;
  height: min(70vh, calc(100vh - 14rem));
  min-height: 16rem;
  width: 100%;
  background: var(--ivory);
}

.plan-map-viewport.is-panning-active {
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
}

.plan-map-viewport.is-dragging {
  cursor: grabbing;
}

.plan-map-hint {
  margin: 0;
  padding: 0.45rem 0.75rem;
  font-size: 0.76rem;
  line-height: 1.35;
  color: var(--ink);
  opacity: 0.72;
  background: var(--ivory);
  border-top: 1px solid var(--hairline);
}

.plan-map-figure.is-fullscreen {
  position: fixed;
  inset: 0;
  z-index: 1000;
  width: 100vw;
  height: 100vh;
  max-width: none;
  max-height: none;
  margin: 0;
  border: none;
  background: #091724;
  display: flex;
  flex-direction: column;
}

.plan-map-figure.is-fullscreen .plan-map-toolbar {
  background: #071c2e;
  border-bottom-color: rgba(255, 255, 255, 0.12);
}

.plan-map-figure.is-fullscreen .plan-map-zoom {
  background: #0d283f;
  border-color: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.plan-map-figure.is-fullscreen .plan-map-zoom:hover {
  background: var(--green);
  border-color: var(--green);
}

.plan-map-figure.is-fullscreen .plan-map-zoom-readout {
  color: rgba(255, 255, 255, 0.85);
}

.plan-map-figure.is-fullscreen .plan-map-viewport {
  flex: 1;
  height: auto;
  min-height: 0;
  background: #0d1f2d;
}

.plan-map-figure.is-fullscreen .plan-map-hint {
  background: #071c2e;
  color: rgba(255, 255, 255, 0.75);
  border-top-color: rgba(255, 255, 255, 0.1);
}

.plan-map-stage {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
}

.plan-map-stage.is-zoomed {
  display: block;
  height: auto;
  place-items: unset;
}

.plan-map-fallback {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: min(70vh, calc(100vh - 14rem));
  margin-inline: auto;
  object-fit: contain;
}

.plan-categories {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0;
}

.find-lot {
  padding-top: var(--space-3);
}

.plan-finder-head {
  margin-bottom: var(--space-3);
}

.plan-finder-head .section-opener {
  margin: 0.25rem 0 var(--space-2);
  max-width: none;
}

.plan-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-2) var(--space-3);
  margin-bottom: var(--space-3);
}

.plan-picker {
  flex: 1 1 16rem;
  min-width: min(100%, 16rem);
}

.plan-picker-label {
  display: block;
  margin: 0 0 0.35rem;
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.72;
}

.plan-picker select {
  min-height: 44px;
  width: 100%;
  max-width: 32rem;
  padding: 0.45rem 0.7rem;
  border: 1px solid var(--hairline-strong);
  background: var(--ivory);
  font: inherit;
  color: var(--ink);
}

.plan-picker select:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 1px;
}

@media (max-width: 700px) {
  .find-lot { padding-top: var(--space-2); }
  .plan-finder-head { margin-bottom: var(--space-2); }
  .plan-finder-head .section-opener {
    font-size: clamp(1.45rem, 7vw, 2rem);
    margin-bottom: 0.45rem;
  }
  .official-map-notice { margin-bottom: 0; }
  .plan-toolbar { margin-bottom: var(--space-2); }
  .plan-facts { margin-bottom: 0.6rem; }
  .plan-map-viewport {
    height: min(58vh, calc(100vh - 16rem));
    min-height: 14rem;
  }
}

.plan-category {
  min-height: 44px;
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--hairline);
  background: #fff;
  font: inherit;
  cursor: pointer;
}

.plan-category[aria-selected='true'] {
  border-color: var(--navy);
  background: var(--navy);
  color: #fff;
}

.plan-panel-title {
  margin: 0 0 0.5rem;
  font-size: 1.15rem;
}

.plan-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: 0.75rem 1.25rem;
  margin: 0 0 var(--space-2);
}

.plan-facts div { margin: 0; }
.plan-facts dt { font-size: 0.75rem; letter-spacing: 0.04em; text-transform: uppercase; opacity: 0.72; }
.plan-facts dd { margin: 0.15rem 0 0; font-weight: 600; }

.official-map-notice { max-width: 46rem; }

.plan-map-svg {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
}

.plan-map-stage.is-zoomed .plan-map-svg {
  max-height: none;
}

/* Available and Sold stay visible without hovering. A buyer has to see what
   is open and what is gone before they go looking. Disabled lots stay hidden. */
.plan-map-lot {
  fill: transparent;
  stroke: transparent;
  stroke-width: 2;
  cursor: pointer;
  transition: fill 0.14s ease, stroke 0.14s ease;
}

.plan-map-lot[data-lot-status='Available'] {
  fill: rgba(31, 122, 74, 0.42);
  stroke: rgba(18, 82, 49, 0.7);
}

.plan-map-lot[data-lot-status='Sold'] {
  fill: rgba(178, 58, 58, 0.42);
  stroke: rgba(140, 38, 38, 0.6);
}

.plan-map-lot[data-lot-status='Available']:hover,
.plan-map-lot[data-lot-status='Available']:focus-visible {
  fill: rgba(31, 122, 74, 0.58);
  stroke: rgba(18, 82, 49, 0.9);
}

.plan-map-lot[data-lot-status='Sold']:hover,
.plan-map-lot[data-lot-status='Sold']:focus-visible {
  fill: rgba(178, 58, 58, 0.62);
  stroke: rgba(120, 30, 30, 0.9);
}

.plan-map-lot[data-lot-status='Blocked'] {
  fill: rgba(217, 119, 6, 0.38);
  stroke: rgba(180, 83, 9, 0.7);
}

.plan-map-lot[data-lot-status='Blocked']:hover,
.plan-map-lot[data-lot-status='Blocked']:focus-visible {
  fill: rgba(217, 119, 6, 0.58);
  stroke: rgba(146, 64, 14, 0.9);
}

.plan-map-lot[data-lot-status='Not offered'] {
  fill: rgba(100, 116, 139, 0.32);
  stroke: rgba(71, 85, 105, 0.5);
}

.plan-map-lot[data-lot-status='Not offered']:hover,
.plan-map-lot[data-lot-status='Not offered']:focus-visible {
  fill: rgba(100, 116, 139, 0.5);
  stroke: rgba(51, 65, 85, 0.8);
}

.plan-map-lot[data-lot-status='Disabled'] {
  display: none;
}

.plan-map-lot:focus-visible { outline: none; }

.plan-map-popup {
  position: absolute;
  transform: translate(-50%, calc(-100% - 12px));
  min-width: 11rem;
  padding: var(--space-1) var(--space-2);
  background: var(--navy);
  color: var(--ivory);
  border-radius: 3px;
  font-size: 0.82rem;
  line-height: 1.35;
  pointer-events: none;
  z-index: 2;
  box-shadow: 0 6px 18px rgba(7, 28, 46, 0.28);
}

.plan-map-popup[hidden] { display: none; }
.plan-map-popup strong { display: block; margin-bottom: 0.25rem; }

.plan-map-popup dl {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.1rem 0.6rem;
  margin: 0;
}

.plan-map-popup dt { opacity: 0.72; }
.plan-map-popup dd { margin: 0; text-align: right; font-weight: 600; }

/* The development switcher on /find-a-lot/. One plan on screen at a time, which
   is the entire reason that page exists. */
.plan-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin-block: var(--space-3) var(--space-2);
}

.plan-tab {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-height: 44px;
  padding: 0.6rem 1rem;
  border: 1px solid var(--hairline);
  background: transparent;
  font: inherit;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
}

.plan-tab-name { font-weight: 600; }

.plan-tab-state {
  font-size: 0.76rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  opacity: 0.62;
}

.plan-tab:hover { border-color: var(--navy); }

.plan-tab[aria-selected='true'] {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--ivory);
}

.plan-tab[aria-selected='true'] .plan-tab-state { opacity: 0.78; }
.plan-panel[hidden] { display: none; }

.plan-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* Only a PINNED popup takes the pointer. While hovering it must stay
   transparent, or it sits between the cursor and the lots and blocks the next
   hover. Pinned, it has to be clickable so the reserve action works. */
.plan-map-popup.is-pinned { pointer-events: auto; }

.plan-map-models {
  margin: 0.35rem 0 0;
  font-size: 0.74rem;
  line-height: 1.3;
  opacity: 0.8;
}

.plan-map-reserve {
  display: block;
  margin-top: 0.5rem;
  padding: 0.35rem 0.6rem;
  background: var(--ivory);
  color: var(--navy);
  border-radius: 2px;
  font-size: 0.78rem;
  font-weight: 700;
  text-align: center;
  text-decoration: none;
}

.plan-map-reserve:hover { background: #fff; }

/* Flipped below its lot when the lot sits near the top of the plan, so the
   heading and the price are never clipped by the figure edge. */
.plan-map-popup.is-below { transform: translate(-50%, 12px); }

@media (max-width: 640px) {
  .plan-map-popup {
    left: 0.5rem !important;
    right: 0.5rem;
    min-width: 0;
    z-index: 60;
    transform: translateY(calc(-100% - 12px));
  }

  .plan-map-popup.is-below { transform: translateY(12px); }
}

.plan-guide {
  margin-top: var(--space-3);
  padding: var(--space-3);
  background: #fff;
  border: 1px solid var(--hairline);
  border-radius: 4px;
}

.plan-guide-title {
  margin: 0 0 var(--space-2);
  font-size: 1.15rem;
  color: var(--navy);
}

.plan-guide-steps {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.plan-guide-step {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.plan-guide-num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--navy);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 700;
}

.plan-guide-heading {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--ink);
}

.plan-guide-body {
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.4;
  opacity: 0.8;
}

/* ---------------------------------------------------------------------------
   Reservation form.
   --------------------------------------------------------------------------- */
.wrap-narrow { max-width: 46rem; }

.privacy-copy h2 {
  margin-top: var(--space-5);
  line-height: 1.08;
}

.privacy-copy h2 + p { margin-top: var(--space-2); }

.privacy-copy .note { margin-top: var(--space-3); }

.reservation-form { margin-top: var(--space-3); }

.reservation-form fieldset {
  margin: 0 0 var(--space-3);
  padding: 0;
  border: 0;
  border-top: 1px solid var(--hairline);
  padding-top: var(--space-2);
}

.reservation-form legend {
  padding: 0 0.6rem 0 0;
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.05rem;
}

.field { margin-bottom: var(--space-2); }

.field-required {
  font-weight: 500;
  font-size: 0.74rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.55;
}

.field-hint,
.field-note {
  margin: 0 0 0.35rem;
  font-size: 0.84rem;
  opacity: 0.72;
}

.field input[type='text'],
.field input[type='email'],
.field input[type='tel'] {
  width: 100%;
  min-height: 44px;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--hairline-strong);
  background: var(--ivory);
  font: inherit;
  color: var(--ink);
}

.field input:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 1px;
}

/* Empty until something is actually wrong, so it never reserves blank space or
   announces itself to a screen reader before there is a problem. */
.field-error {
  margin: 0.3rem 0 0;
  font-size: 0.84rem;
  font-weight: 600;
  color: #9b2226;
}

.field-error:empty { display: none; }

/* A radio label is a CHOICE, not a field label. Without this it inherits the
   uppercase, letter-spaced treatment .field label carries and reads as another
   heading rather than as something you pick. */
.field label.choice {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
  font-size: 1rem;
  font-weight: 500;
  letter-spacing: normal;
  text-transform: none;
  color: var(--ink);
  cursor: pointer;
}

/* The site styles .field inputs with a border and padding, which turns a radio
   into a large empty box. Radios opt back out. */
.field .choice input[type='radio'] {
  /* appearance MUST be restored explicitly. The site's field styling strips the
     native control, and border:0 alone leaves an invisible radio: the label
     still works but there is nothing on screen to show which one is chosen. */
  appearance: auto;
  -webkit-appearance: radio;
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  accent-color: var(--green);
}

/* ---------------------------------------------------------------------------
   Build your home here: the dialog behind a lot.

   Laid out as a fixed HEADER / scrolling BODY / fixed FOOTER, because the
   content is tall and the primary action must never be the thing that falls off
   the bottom of the screen. First version scrolled the whole panel and the
   Reserve button was unreachable.
   --------------------------------------------------------------------------- */
.lot-builder {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-2) var(--gutter);
  background: rgba(7, 28, 46, 0.66);
}

body.builder-open { overflow: hidden; }

.lot-builder-panel {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 58rem;
  max-height: min(88vh, 54rem);
  background: var(--ivory);
  border: 1px solid var(--hairline-strong);
  box-shadow: 0 24px 60px rgba(7, 28, 46, 0.35);
}

.lot-builder-header {
  flex: none;
  position: relative;
  padding: var(--space-3) var(--space-3) var(--space-2);
  padding-right: 6.5rem;
  border-bottom: 1px solid var(--hairline-strong);
}

.lot-builder-header h2 {
  margin: 0.25rem 0 0.5rem;
  font-family: var(--display);
  font-size: clamp(1.5rem, 3.4vw, 2rem);
  line-height: 1.15;
}

/* The lot facts read as a row of separated values rather than one run-on
   sentence, so area, price and status can each be found at a glance. */
.lot-builder-facts {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  margin: 0;
  font-size: 0.92rem;
}

.lot-builder-facts span { font-weight: 700; }

.lot-builder-facts span + span {
  padding-left: 1.25rem;
  border-left: 1px solid var(--hairline-strong);
}

.lot-builder-close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
  min-height: 44px;
  min-width: 44px;
  padding: 0.4rem 1rem;
  border: 1px solid var(--hairline-strong);
  background: transparent;
  font: inherit;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}

.lot-builder-close:hover { border-color: var(--navy); color: var(--navy); }

.lot-builder-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Extra room at the foot so the last line never sits flush against the
     fixed footer and read as clipped. */
  padding: var(--space-3) var(--space-3) var(--space-5);
}

.lot-builder-lede { margin: 0 0 var(--space-2); }

.lot-builder-picker {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(14rem, 1fr));
  gap: var(--space-2);
  margin: 0;
}

.lot-builder-card {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--hairline-strong);
  background: #fff;
  font: inherit;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.16s var(--ease), box-shadow 0.16s var(--ease);
}

/* contain, not cover: these are floor PLANS. Cropping them hides the very
   information the card exists to show. */
.lot-builder-card img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  background: #fff;
  border-bottom: 1px solid var(--hairline);
}

.lot-builder-card-name {
  padding: 0 0.75rem;
  font-weight: 700;
  font-size: 1rem;
}

.lot-builder-card-facts {
  padding: 0 0.75rem 0.75rem;
  font-size: 0.8rem;
  line-height: 1.35;
  opacity: 0.72;
}

.lot-builder-card:hover { border-color: var(--navy); }

.lot-builder-card[aria-pressed='true'] {
  border-color: var(--green);
  box-shadow: inset 0 0 0 2px var(--green);
}

/* The chosen package. Its own block below the grid, never beside it. */
.lot-builder-detail {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 2px solid var(--navy);
}

.lot-builder-detail[hidden] { display: none; }

.lot-builder-detail-title {
  margin: 0 0 var(--space-1);
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.15rem;
}

/* Ruled rows, label left, figure right. The first version right-aligned a long
   description into a narrow column and it wrapped into a mess. */
.lot-builder-pricing { margin: 0; }

.lot-builder-pricing div {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.5rem 1.5rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--hairline);
}

.lot-builder-pricing dt {
  font-weight: 600;
  opacity: 0.72;
}

.lot-builder-pricing dd {
  margin: 0;
  font-weight: 700;
  text-align: right;
}

.lot-builder-pricing .is-total {
  border-bottom: 0;
  border-top: 2px solid var(--navy);
  margin-top: 0.25rem;
  padding-top: 0.7rem;
  font-size: 1.1rem;
}

.lot-builder-detail .note { margin-top: var(--space-2); }

/* Pinned, and it carries the PRICE as well as the action. Comparing two models
   should change the number in front of you, not move the page. */
.lot-builder-footer {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-1) var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-top: 2px solid var(--navy);
  background: var(--stone);
}

/* A column, so the summary keeps its natural width and space-between can push
   the actions to the right instead of dropping them onto their own line. */
.lot-builder-summary {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
}

.lot-builder-summary-name {
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.62;
}

.lot-builder-summary-price {
  font-family: var(--display);
  font-weight: 700;
  font-size: clamp(1.15rem, 3.4vw, 1.5rem);
  line-height: 1.1;
}

.lot-builder-summary-note {
  font-size: 0.78rem;
  opacity: 0.66;
}

.lot-builder-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

@media (max-width: 700px) {
  .lot-builder { padding: 0; }
  .lot-builder-panel { max-height: 100vh; border: 0; }
  .lot-builder-header { padding: var(--space-3) var(--space-2) var(--space-2); padding-right: 6rem; }
  .lot-builder-close { right: var(--space-2); }
  .lot-builder-body,
  .lot-builder-footer { padding-inline: var(--space-2); }

  /* TWO COLUMNS AND SHORTER CARDS ON A PHONE. At the desktop card size only one
     fits the visible area, so comparing two models meant scrolling the whole
     list. The plan thumbnail shrinks because at phone width it is an
     identifying glance, not a readable drawing; the viewer is where you read
     it. */
  .lot-builder-picker {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-1);
  }

  .lot-builder-card img { aspect-ratio: 16 / 10; }
  .lot-builder-card-name { padding-inline: 0.5rem; font-size: 0.92rem; }

  .lot-builder-card-facts {
    padding: 0 0.5rem 0.5rem;
    font-size: 0.72rem;
  }
  /* ONE COMPACT ROW ON A PHONE. Stacked, the footer ate roughly a quarter of an
     844px screen and squeezed the model list it exists to serve. Price left,
     action right, and the indicative note drops because the body breakdown
     already says it. */
  .lot-builder-footer {
    flex-wrap: nowrap;
    align-items: center;
    gap: var(--space-2);
    padding: 0.6rem var(--space-2);
  }

  .lot-builder-summary { flex: 1 1 auto; min-width: 0; }
  .lot-builder-summary-note { display: none; }

  /* The price must never break across two lines. Split as "PHP" then the
     number it reads as broken rather than as a figure. Sized to fit the row
     beside the button at 390px. */
  .lot-builder-summary-price {
    font-size: 1.02rem;
    white-space: nowrap;
  }

  .lot-builder-summary-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
  }

  .lot-builder-actions { flex: none; }
  .lot-builder-actions .button { white-space: nowrap; }

  /* The plan link now lives in the body, so it needs room of its own there. */
  .lot-builder-plan-link { margin-top: var(--space-1); }
}

/* ---------------------------------------------------------------------------
   Floor plan viewer. Stacks above the build dialog (z-index 200), so closing it
   returns the reader to the model they were considering.
   --------------------------------------------------------------------------- */
.plan-viewer {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-2);
  background: rgba(7, 28, 46, 0.86);
}

.plan-viewer-panel {
  display: flex;
  flex-direction: column;
  width: min(100%, 58rem);
  max-height: 94vh;
  background: #fff;
  border: 1px solid var(--hairline-strong);
}

.plan-viewer-bar {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: 0.6rem var(--space-2);
  border-bottom: 1px solid var(--hairline-strong);
  background: var(--ivory);
}

.plan-viewer-title {
  margin: 0;
  font-weight: 700;
}

.plan-viewer-close {
  min-height: 44px;
  min-width: 44px;
  padding: 0.4rem 1rem;
  border: 1px solid var(--hairline-strong);
  background: transparent;
  font: inherit;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
}

.plan-viewer-close:hover { border-color: var(--navy); color: var(--navy); }

/* THE SOURCE PLANS ARE ONLY 624x468, so shown at their natural size they are a
   small card on a desktop screen and the room labels are barely readable. They
   are allowed to scale up to fill the viewer: line art takes a moderate upscale
   far better than an unreadable plan serves anyone. Ask AnCor for higher
   resolution drawings and this simply gets sharper with no change here.

   min-height 0 lets the image shrink inside the flex column instead of pushing
   the close bar off the top on a short viewport. */
.plan-viewer-image {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  height: auto;
  max-height: calc(94vh - 7rem);
  object-fit: contain;
}

/* A portrait clip in a landscape panel WILL letterbox. Against black it reads
   as a video player; against the panel's ivory it read as broken empty space. */
video.plan-viewer-image {
  background: #000;
  max-height: calc(94vh - 7rem);
}

/* The button that opens it is a button, not a link, so it needs the link's look
   without the link's default control styling. */
.lot-builder-plan-link {
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
}

.lot-builder-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

/* Says plainly that the footage is a stand-in. It sits under the media rather
   than over it, so it cannot be mistaken for part of the video. */
.plan-viewer-note {
  flex: none;
  margin: 0;
  padding: 0.55rem var(--space-2);
  border-top: 1px solid var(--hairline);
  background: var(--ivory);
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ink);
}

.button-secondary {
  background: transparent;
  border: 1px solid var(--navy);
  color: var(--navy);
}

.button-secondary:hover { background: var(--navy); color: var(--ivory); }

.plan-viewer-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.plan-viewer-action {
  min-height: 44px;
  padding: 0.4rem 1rem;
  border: 1px solid var(--navy);
  background: var(--navy);
  font: inherit;
  font-weight: 600;
  color: var(--ivory);
  cursor: pointer;
}

.plan-viewer-action:hover { background: var(--green); border-color: var(--green); }

@media (max-width: 700px) {
  /* Three things in the footer at 390px, so the plan link keeps its own row
     above the price and the action rather than squeezing them. */
  .lot-builder-footer { flex-wrap: wrap; }
  .lot-builder-actions { gap: var(--space-1); }
  .lot-builder-actions .lot-builder-plan-link { font-size: 0.86rem; }
  .plan-viewer-action,
  .plan-viewer-close { padding-inline: 0.7rem; }
}

/* ===========================================================================
   The AnCor Desk. An internal reporting surface, so it is denser and darker
   than the sales site: this is a tool to read, not a page to be sold by.
   =========================================================================== */
.desk-body {
  background: #0d1b26;
  color: #e8e4da;
  min-height: 100vh;
}

.desk-header {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--gutter);
  background: #071c2e;
  border-bottom: 1px solid rgba(232, 228, 218, 0.16);
}

.desk-brand { display: flex; align-items: center; gap: var(--space-2); }
.desk-brand img { width: 96px; height: auto; }

.desk-title {
  font-family: var(--display);
  font-weight: 800;
  font-size: 1.1rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #e8e4da;
}

.desk-meta { display: flex; align-items: center; gap: var(--space-2); font-size: 0.86rem; }
.desk-period { opacity: 0.66; }

.desk-exit {
  color: #7fd4a2;
  text-decoration: none;
  font-weight: 600;
  border-bottom: 1px solid rgba(127, 212, 162, 0.5);
}

.desk-logout {
  padding: 0;
  border-width: 0 0 1px;
  background: transparent;
  font: inherit;
  cursor: pointer;
}

.desk-main {
  max-width: 84rem;
  margin: 0 auto;
  padding: var(--space-3) var(--gutter) var(--space-8);
}

.desk-notice {
  margin: 0 0 var(--space-3);
  padding: 0.75rem 1rem;
  border-left: 3px solid #d9a441;
  background: rgba(217, 164, 65, 0.1);
  font-size: 0.9rem;
  line-height: 1.5;
}

/* Headline numbers. */
.desk-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.stat {
  padding: var(--space-2);
  background: #12283a;
  border: 1px solid rgba(232, 228, 218, 0.12);
}

.stat-label {
  margin: 0 0 0.4rem;
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.6;
}

.stat-value {
  margin: 0;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(1.6rem, 3.4vw, 2.1rem);
  line-height: 1.05;
}

.stat.is-money .stat-value { color: #7fd4a2; }
.stat-note { margin: 0.3rem 0 0; font-size: 0.78rem; opacity: 0.6; }

.desk-panel {
  margin-bottom: var(--space-3);
  padding: var(--space-3);
  background: #12283a;
  border: 1px solid rgba(232, 228, 218, 0.12);
}

.desk-panel-head { margin-bottom: var(--space-2); }

.desk-panel-head h2 {
  margin: 0;
  font-family: var(--display);
  font-size: 1.25rem;
}

/* A panel heading that is not wrapped in .desk-panel-head used to inherit the
   page-level h2 clamp and tower over its siblings. */
.desk-panel > h2 {
  margin: 0 0 var(--space-2);
  font-family: var(--display);
  font-size: 1.25rem;
}

.desk-panel-note { margin: 0.3rem 0 0; font-size: 0.82rem; opacity: 0.6; }

.desk-login-panel {
  width: min(100%, 32rem);
  margin: clamp(2rem, 10vh, 7rem) auto 0;
}

.desk-login-panel h1 {
  margin: 0;
  font-family: var(--display);
  font-size: clamp(1.8rem, 4vw, 2.75rem);
  line-height: 1.05;
}

.desk-login-form {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.desk-login-form .field { margin: 0; }
.desk-login-form .field label { color: var(--on-navy); }
.desk-login-form .field input {
  width: 100%;
  border-color: var(--on-navy-hairline);
  background: rgba(243, 240, 232, 0.06);
  color: var(--on-navy);
}
.desk-login-form .button { justify-self: start; }
.desk-login-status {
  min-height: 1.25rem;
  margin: 0;
  color: var(--on-navy-mute);
  font-size: 0.82rem;
}

/* Reservation pipeline. */
.desk-pipeline {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: 1px;
  margin-bottom: var(--space-2);
  background: rgba(232, 228, 218, 0.12);
  border: 1px solid rgba(232, 228, 218, 0.12);
}

.pipeline-step {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: 0.7rem 0.9rem;
  background: #0d1b26;
}

.pipeline-count { font-family: var(--display); font-weight: 800; font-size: 1.5rem; line-height: 1; }
.pipeline-name { font-size: 0.76rem; letter-spacing: 0.08em; text-transform: uppercase; opacity: 0.6; }

/* Tables. Wide content scrolls in its own box, never the page. */
.desk-table-scroll { overflow-x: auto; }

.desk-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.86rem;
  white-space: nowrap;
}

.desk-table th {
  padding: 0.5rem 0.75rem;
  text-align: left;
  font-size: 0.72rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  opacity: 0.6;
  border-bottom: 1px solid rgba(232, 228, 218, 0.2);
}

.desk-table td {
  padding: 0.55rem 0.75rem;
  border-bottom: 1px solid rgba(232, 228, 218, 0.08);
}

.desk-table tbody tr:hover { background: rgba(232, 228, 218, 0.05); }

.pill {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 2px;
  font-size: 0.74rem;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.pill-new { background: rgba(127, 178, 212, 0.22); color: #9ecbe8; }
.pill-contacted,
.pill-screening { background: rgba(217, 164, 65, 0.22); color: #e8c07d; }
.pill-reserved,
.pill-accredited { background: rgba(127, 212, 162, 0.2); color: #7fd4a2; }
.pill-closed { background: rgba(232, 228, 218, 0.14); color: #cfcabd; }
.pill-declined { background: rgba(212, 127, 127, 0.2); color: #e59b9b; }

/* Availability bars. */
.stock-row {
  display: grid;
  grid-template-columns: minmax(9rem, 1fr) 2fr auto;
  align-items: center;
  gap: var(--space-2);
  padding: 0.6rem 0;
  border-bottom: 1px solid rgba(232, 228, 218, 0.08);
}

.stock-label { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.stock-name { font-weight: 600; }
.stock-figures { font-size: 0.76rem; opacity: 0.6; }

.stock-bar {
  height: 10px;
  background: rgba(232, 228, 218, 0.12);
  overflow: hidden;
}

.stock-fill { display: block; height: 100%; background: #7fd4a2; }

/* No claim either way, so the bar is striped rather than empty. An empty bar
   reads as nothing sold, which is itself a claim. */
.stock-bar.is-unknown {
  background: repeating-linear-gradient(135deg,
    rgba(232, 228, 218, 0.16) 0 6px, rgba(232, 228, 218, 0.06) 6px 12px);
}
.stock-share { font-family: var(--display); font-weight: 700; }

/* Interest. */
.desk-chart { margin-bottom: var(--space-2); }
.desk-spark { width: 100%; height: 72px; }

.desk-spark-line {
  fill: none;
  vector-effect: non-scaling-stroke;
  stroke: #7fd4a2;
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.desk-lists {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--space-3);
}

.desk-list h3 {
  margin: 0 0 0.5rem;
  font-size: 0.76rem;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  opacity: 0.6;
}

.desk-list-row {
  display: grid;
  grid-template-columns: minmax(7rem, 1fr) 3fr auto;
  align-items: center;
  gap: 0.75rem;
  padding: 0.3rem 0;
  font-size: 0.86rem;
}

.desk-list-bar { height: 8px; background: rgba(127, 178, 212, 0.5); }
.desk-list-value { font-weight: 700; opacity: 0.8; }

@media (max-width: 700px) {
  .stock-row,
  .desk-list-row { grid-template-columns: 1fr auto; }
  .stock-bar,
  .desk-list-bar { grid-column: 1 / -1; }
  .desk-panel { padding: var(--space-2); }
}

/* Desk shell: fixed left rail, scrolling content. */
.desk-shell {
  display: grid;
  grid-template-columns: 14rem 1fr;
  gap: var(--space-3);
  align-items: start;
}

.desk-nav {
  position: sticky;
  top: 6rem;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.desk-nav-item {
  padding: 0.65rem 0.9rem;
  border: 0;
  border-left: 3px solid transparent;
  background: transparent;
  font: inherit;
  font-weight: 600;
  text-align: left;
  color: rgba(232, 228, 218, 0.62);
  cursor: pointer;
}

.desk-nav-item:hover { color: #e8e4da; background: rgba(232, 228, 218, 0.05); }

.desk-nav-item[aria-current='page'] {
  color: #e8e4da;
  background: rgba(127, 212, 162, 0.1);
  border-left-color: #7fd4a2;
}

.desk-view[hidden] { display: none; }
.desk-views { min-width: 0; }

.desk-panel-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
}

.desk-panel-heading { min-width: 0; }

.desk-export {
  flex: none;
  min-height: 40px;
  padding: 0.4rem 0.9rem;
  border: 1px solid rgba(127, 212, 162, 0.55);
  background: transparent;
  font: inherit;
  font-weight: 600;
  color: #7fd4a2;
  cursor: pointer;
}

.desk-export:hover { background: rgba(127, 212, 162, 0.14); }

/* A row you can open. Without the affordance nobody discovers the record. */
.desk-table tbody tr.is-openable { cursor: pointer; }
.desk-table tbody tr.is-openable:hover { background: rgba(127, 212, 162, 0.09); }

.desk-table tbody tr.is-openable:focus-visible {
  outline: 2px solid #7fd4a2;
  outline-offset: -2px;
}

/* One record, in full. */
.desk-record {
  position: fixed;
  inset: 0;
  z-index: 300;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-2);
  background: rgba(4, 12, 20, 0.72);
}

.desk-record-sheet {
  width: min(100%, 34rem);
  max-height: 90vh;
  overflow-y: auto;
  background: #12283a;
  border: 1px solid rgba(232, 228, 218, 0.2);
}

.desk-record-bar {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2);
  background: #0d1b26;
  border-bottom: 1px solid rgba(232, 228, 218, 0.2);
}

.desk-record-bar h2 { margin: 0; font-family: var(--display); font-size: 1.1rem; }

.desk-record-close {
  flex: none;
  min-height: 44px;
  padding: 0.4rem 1rem;
  border: 1px solid rgba(232, 228, 218, 0.4);
  background: transparent;
  font: inherit;
  font-weight: 600;
  color: #e8e4da;
  cursor: pointer;
}

.desk-record-close:hover { border-color: #7fd4a2; color: #7fd4a2; }

.desk-record-fields { margin: 0; padding: var(--space-2); }

.desk-record-fields > div {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.4rem 1.5rem;
  padding: 0.55rem 0;
  border-bottom: 1px solid rgba(232, 228, 218, 0.1);
}

.desk-record-fields > div:last-child { border-bottom: 0; }
.desk-record-fields dt { opacity: 0.62; }
.desk-record-fields dd { margin: 0; font-weight: 700; text-align: right; }

@media (max-width: 900px) {
  /* The rail becomes a scrolling tab strip. A sidebar at phone width costs more
     than it navigates. */
  .desk-shell { grid-template-columns: 1fr; gap: var(--space-2); }

  .desk-nav {
    position: static;
    flex-direction: row;
    gap: 0;
    overflow-x: auto;
    border-bottom: 1px solid rgba(232, 228, 218, 0.16);
  }

  .desk-nav-item {
    flex: none;
    border-left: 0;
    border-bottom: 3px solid transparent;
    white-space: nowrap;
  }

  .desk-nav-item[aria-current='page'] {
    background: transparent;
    border-bottom-color: #7fd4a2;
  }
}

/* A LIVE legend, replacing the one baked into the artwork. That one said "hover
   to see price", which was wrong twice: the interaction is a click, and only one
   development publishes a price. Pixels cannot be corrected; this can. */
/* The written-out lot lists, below the plans and outside the tab panels. */
.lot-lists {
  margin-top: var(--space-8);
  padding-top: var(--space-5);
  border-top: 1px solid var(--hairline);
}

.lot-lists-title {
  margin-block: 0 var(--space-2);
  font-family: var(--display);
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  line-height: 1.05;
  letter-spacing: -0.03em;
}

.lot-lists .lot-table-wrap { margin-top: var(--space-2); }

.plan-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem var(--space-2);
  margin-top: var(--space-2);
  padding: 0.65rem var(--space-2);
  border: 1px solid var(--hairline);
  background: var(--ivory);
  font-size: 0.86rem;
}

.plan-legend-title {
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-size: 0.74rem;
}

.plan-legend-item { display: inline-flex; align-items: center; gap: 0.4rem; }

.plan-legend-swatch {
  width: 0.9rem;
  height: 0.9rem;
  border: 1px solid var(--hairline-strong);
}

/* Same fills the lots use, so the key and the map cannot drift apart. */
.plan-legend-swatch.is-available { background: rgba(31, 122, 74, 0.45); border-color: rgba(18, 82, 49, 0.85); }
.plan-legend-swatch.is-sold { background: rgba(178, 58, 58, 0.42); border-color: rgba(140, 38, 38, 0.6); }
.plan-legend-swatch.is-unknown { background: transparent; }

.plan-legend-note { margin-left: auto; opacity: 0.7; }

@media (max-width: 700px) {
  .plan-legend-note { margin-left: 0; width: 100%; }
}

/* Covers the legend baked into the plan artwork. Percentages, so it tracks the
   image at every width. Matched to the artwork's own near-white background
   rather than the page, since it sits on the picture. */
/* MEASURED, not guessed. The legend box occupies x 0.045 to 0.281 and y 0.867
   to 0.987 of the artwork; the river label's descenders stop at about 0.86, so
   the cover starts just below them at 13.5 per cent from the bottom and reaches
   30 per cent across.

   Automatic detection was tried and abandoned: the legend's white is too close
   to the artwork's own background, so it either missed the box entirely or
   sliced a block through the map. Editing the source pixels was tried too and
   destroyed the river label. Covering in the DOM takes nothing with it. */
.plan-map-legend-cover {
  fill: #fff;
  pointer-events: none;
}

/* ---------------------------------------------------------------------------
   Payment preview page. The primary action is now the hero, not a button after
   the reference tables. Buyers can choose a lot and reach the Maya preview in
   the first viewport, while schedule details sit lower as optional context.
   --------------------------------------------------------------------------- */
.pay-hero {
  position: relative;
  padding: clamp(7rem, 13vw, 9.5rem) 0 clamp(3rem, 7vw, 5rem);
  background:
    radial-gradient(circle at 12% 18%, rgba(214, 177, 86, 0.22), transparent 24rem),
    linear-gradient(135deg, var(--navy) 0%, #102f36 100%);
  color: var(--on-navy);
  overflow: hidden;
}

.pay-hero::after {
  content: "";
  position: absolute;
  inset: auto -8rem -12rem auto;
  width: min(42vw, 28rem);
  aspect-ratio: 1;
  background: rgba(214, 177, 86, 0.18);
  transform: rotate(18deg);
  pointer-events: none;
}

.pay-hero-grid {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(22rem, 27rem);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.pay-hero-copy {
  max-width: 42rem;
}

.pay-hero .eyebrow { color: #d6b156; }
.pay-hero h1 { color: var(--on-navy); }
.pay-hero .lede { color: rgba(255, 255, 255, 0.86); }
.pay-hero .note {
  max-width: 36rem;
  color: rgba(255, 255, 255, 0.74);
  border-color: rgba(255, 255, 255, 0.18);
}

.pay-hero-alt {
  margin: var(--space-2) 0 0;
  color: rgba(255, 255, 255, 0.78);
}

.pay-hero-alt a { color: #f7dc90; }

.pay-card {
  position: relative;
  overflow: hidden;
  background: var(--ivory);
  color: var(--ink);
  border: 1px solid rgba(7, 28, 46, 0.12);
  border-radius: 8px;
  box-shadow: 0 1.4rem 3rem rgba(4, 20, 26, 0.22);
}

.pay-card-head {
  padding: 1rem var(--space-3);
  background: #061d22;
  color: var(--on-navy);
}

.pay-card-brand {
  display: block;
  margin-bottom: 0.65rem;
  font-family: var(--sans);
  font-weight: 800;
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #82e0a9;
}

.pay-progress {
  display: flex;
  gap: 0.35rem;
}

.pay-progress-seg {
  flex: 1;
  height: 4px;
  background: rgba(255, 255, 255, 0.22);
  transition: background-color 0.2s var(--ease);
}

.pay-progress-seg.is-done { background: #82e0a9; }
.pay-progress-seg.is-current { background: #d6b156; }

.pay-card-body {
  min-height: 28rem;
  padding: var(--space-3);
}

.pay-card-title {
  margin: 0 0 0.45rem;
  font-size: clamp(1.45rem, 4vw, 2rem);
  line-height: 1.05;
}

.pay-card-note {
  margin: 0 0 var(--space-2);
  font-size: 0.9375rem;
  line-height: 1.5;
  color: rgba(12, 22, 32, 0.7);
}

.pay-card [data-pay-status].pay-receipt-note {
  margin: 0.9rem 0 0;
  padding: 0.9rem 1rem;
  border: 1px solid var(--green);
  background: #e7f3ec;
  color: var(--navy);
  font-size: 0.95rem;
  font-weight: 600;
  line-height: 1.45;
  opacity: 1;
}

.pay-field-pair {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}

.pay-card-action {
  width: 100%;
  justify-content: center;
  margin-top: var(--space-2);
}

.pay-card-actions {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-2);
  align-items: center;
  margin-top: var(--space-2);
}

.pay-card-actions .pay-card-action { margin-top: 0; }

.pay-card-back {
  min-height: 2.75rem;
  padding: 0.6rem 0.25rem;
  border: 0;
  background: transparent;
  color: var(--green);
  font: inherit;
  font-weight: 700;
  cursor: pointer;
}

.pay-card-back:hover,
.pay-card-back:focus-visible { color: var(--navy); }

.pay-amount {
  margin: var(--space-2) 0;
  padding: 1rem;
  background: #f3eddc;
  border: 1px solid rgba(7, 28, 46, 0.12);
  border-radius: 8px;
  font-family: var(--display);
  font-weight: 800;
  font-size: clamp(2rem, 7vw, 3rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.pay-facts {
  margin: 0 0 var(--space-2);
  border-top: 1px solid var(--hairline);
}

.pay-facts > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-2);
  padding-block: 0.7rem;
  border-bottom: 1px solid var(--hairline);
}

.pay-facts dt {
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(12, 22, 32, 0.58);
}

.pay-facts dd {
  margin: 0;
  text-align: right;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.pay-loading {
  min-height: 18rem;
  display: grid;
  align-content: center;
  justify-items: start;
}

.pay-spinner {
  width: 2.5rem;
  height: 2.5rem;
  margin-bottom: var(--space-2);
  border: 3px solid var(--hairline);
  border-top-color: #00c56d;
  border-radius: 999px;
  animation: pay-spin 0.8s linear infinite;
}

.pay-done-mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.25rem;
  height: 3.25rem;
  margin-bottom: var(--space-2);
  border-radius: 999px;
  background: #dff4e9;
  color: #0c6d3f;
}

.pay-card-flag {
  display: inline-flex;
  margin: 0 0 var(--space-2);
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  background: #f3eddc;
  color: #5a4314;
  font-weight: 700;
  font-size: 0.8125rem;
}

@keyframes pay-spin {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .pay-progress-seg { transition-duration: 0.01ms; }
  .pay-spinner { animation-duration: 0.01ms; }
}

.pay-steps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2);
  margin: var(--space-3) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: payment-step;
}

.pay-steps li {
  position: relative;
  min-height: 8rem;
  padding: 3.35rem var(--space-2) var(--space-2);
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--ivory);
  line-height: 1.45;
}

.pay-steps li::before {
  counter-increment: payment-step;
  content: counter(payment-step);
  position: absolute;
  left: var(--space-2);
  top: var(--space-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  background: var(--green);
  color: var(--ivory);
  font-family: var(--display);
  font-weight: 800;
  font-size: 0.9375rem;
}

.payment-summary {
  max-width: none;
  margin-top: var(--space-3);
}

@media (max-width: 980px) {
  .pay-hero {
    background:
      radial-gradient(circle at 15% 0%, rgba(214, 177, 86, 0.22), transparent 18rem),
      var(--navy);
  }

  .pay-hero-grid {
    grid-template-columns: 1fr;
  }

  .pay-card {
    order: -1;
    max-width: 32rem;
  }
}

@media (max-width: 700px) {
  .pay-hero {
    padding-top: 6.5rem;
  }

  .pay-card-body {
    min-height: 0;
    padding: var(--space-2);
  }

  .pay-field-pair,
  .pay-card-actions,
  .pay-steps {
    grid-template-columns: 1fr;
  }

  .pay-steps li {
    min-height: 0;
  }

  .pay-facts > div {
    display: grid;
    gap: 0.25rem;
  }

  .pay-facts dd {
    text-align: left;
  }
}

/* ---------------------------------------------------------------------------
   Page banner. Real AnCor photography, full bleed, at the top of every
   secondary page. Home keeps its own video hero; the desk is internal.

   No text sits on the image: the eyebrow / h1 / lede immediately below already
   carry the heading, so an overlay would either duplicate it or force a
   contrast treatment the photo was never shot for. The banner's job is mood
   and craft, not another headline.
   --------------------------------------------------------------------------- */
.page-banner {
  position: relative;
  margin: 0 0 var(--space-3);
  border-bottom: 3px solid var(--navy);
  background: var(--stone);
  overflow: hidden;
}

/* Taller than a plain decorative strip needs to be, because the title now
   lives ON it. Short enough on a phone that it never eats the whole first
   screen; tall enough on desktop to read as a real hero rather than a sliver. */
.page-banner img {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  max-width: 1400px;
  margin-inline: auto;
  height: clamp(14rem, 34vw, 24rem);
  object-fit: cover;
}

/* The six source photos are real client photography capped around 1000 to
   1200px wide, AnCor has never supplied anything bigger. Below 1400px viewport
   width (the vast majority of visits, phones included) the sharp image above
   already reads as full bleed, since width:100% never exceeds its own
   max-width there. Only past that does the sharp photo become a centred panel;
   this blurred, scaled up copy of the SAME photo fills the rest so a very wide
   desktop still reads as one continuous banner rather than a paint job that
   stops partway with the site background showing through. */
.page-banner-fill {
  position: absolute;
  z-index: 0;
  inset: 0;
  background-size: cover;
  background-position: center;
  filter: blur(32px) saturate(1.05) brightness(0.85);
  transform: scale(1.15);
}

/* A fixed gradient, not tuned per photo. The six source photos range from a
   bright pool to a shaded pavilion, and picking a different scrim strength for
   each would be fragile against the next photo swapped in. One gradient strong
   enough for the brightest of the six (the pool) holds AA contrast on all of
   them, confirmed by measuring the rendered white against navy at its weakest
   point over each image. */
.page-banner-scrim {
  position: absolute;
  z-index: 2;
  inset: 0;
  background: linear-gradient(
    to top,
    rgba(7, 28, 46, 0.86) 0%,
    rgba(7, 28, 46, 0.55) 40%,
    rgba(7, 28, 46, 0) 72%
  );
  pointer-events: none;
}

.page-banner-copy {
  position: absolute;
  z-index: 3;
  inset: auto 0 0 0;
  padding: var(--space-2) var(--gutter) var(--space-3);
}

/* Reuses the site's existing on-navy tokens, the same ones the header already
   sits on, so the banner text is not a one-off palette. */
.page-banner-copy .breadcrumbs { padding-top: 0; margin: 0 0 var(--space-1); }
.page-banner-copy .breadcrumbs a { color: var(--on-navy-mute); }
.page-banner-copy .breadcrumbs a:hover { color: var(--on-navy); }
.page-banner-copy .breadcrumbs li[aria-current] { color: var(--on-navy); }
.page-banner-copy .breadcrumbs li + li::before { color: var(--on-navy-hairline); }

.page-banner-copy .eyebrow { color: var(--on-navy); opacity: 0.78; }
.page-banner-copy h1 { color: var(--on-navy); margin: 0.3rem 0 0; max-width: 20ch; }

/* Per-image focal point. object-fit: cover defaults to centring the frame,
   which is wrong wherever the subject is not already centred; picked by eye
   against each source photo rather than assumed. */
.page-banner img[src*="delivered-d-01"] { object-position: 50% 22%; }
.page-banner img[src*="built-houses-11"] { object-position: 50% 40%; }
.page-banner img[src*="st-ignatius-heights-03"] { object-position: 50% 60%; }

/* --page-head and --section-y's top spacing was tuned for a page that opened
   with a plain eyebrow and h1. Now that the eyebrow and h1 sit ON the banner
   instead, that spacing is left over: measured at 64 to 88px of dead air
   before the first real line of body copy on every one of these six pages.
   The banner itself already reads as a strong break, so only the element
   immediately after it needs a smaller gap; sections further down the page
   keep their normal breathing room. */
.page-banner + .wrap .page-head { padding-block: var(--space-3) 0; }
.page-banner + .section { padding-top: var(--space-3); }

/* ---------------------------------------------------------------------------
   SARVI 4 Commercial: the one interactive map on /find-a-lot/.

   The artwork already carries AnCor's own rate colours, yellow and magenta, so
   the hotspots stay TRANSPARENT while a lot is open. Painting them would hide
   the very legend the panel is reading. Status is the only thing this layer
   draws, and only when status is something other than available.
   --------------------------------------------------------------------------- */
.plan-panel-lede {
  max-width: 52rem;
  margin: 0 0 var(--space-3);
  color: rgba(12, 22, 32, 0.82);
}

.commercial-shell {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 22rem;
  gap: var(--space-3);
  align-items: start;
}

.commercial-map-column { min-width: 0; }

/* Transparent, with NO outline of its own, until it is pointed at. The drawing
   already has boundary lines; a second set traced over them at a slightly
   different place reads as a printing fault, which is exactly how it looked
   before this was removed. */
.commercial-lot {
  fill: transparent;
  stroke: transparent;
  stroke-width: 3;
  cursor: pointer;
  transition: fill 0.14s ease, stroke 0.14s ease;
}

.commercial-lot:hover,
.commercial-lot:focus-visible {
  fill: rgba(45, 106, 67, 0.34);
  stroke: rgba(7, 28, 46, 0.92);
  stroke-width: 6;
}

.commercial-lot:focus-visible { outline: none; }

.commercial-lot.is-selected {
  fill: rgba(45, 106, 67, 0.3);
  stroke: var(--navy);
  stroke-width: 9;
}

/* Read before hovering, because a buyer has to see what is gone without
   pointing at every parcel first. */
.commercial-lot[data-lot-status='Blocked'] { fill: url(#commercial-hatch-hold); }
.commercial-lot[data-lot-status='Sold'] { fill: url(#commercial-hatch-sold); }

/* AN INTERIOR POLYGON IS NEVER OUTLINED, in any state. LOT1-A and LOT1-B are
   bounded on the east by two survey curves this scan does not separate, so the
   shape held for them is a click area well inside the parcel, not a boundary.
   Stroking it would draw a line on an official survey map that the survey does
   not agree with, and filling it solid would bury a third of the drawing under
   a grey slab. It gets a soft wash when it is pointed at, and nothing else. */
.commercial-lot[data-polygon='interior'] {
  fill: transparent;
  stroke: transparent;
}

.commercial-lot[data-polygon='interior']:hover,
.commercial-lot[data-polygon='interior']:focus-visible,
.commercial-lot[data-polygon='interior'].is-selected {
  fill: rgba(7, 28, 46, 0.16);
  stroke: transparent;
}

.commercial-key {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
  margin-top: var(--space-2);
  padding: var(--space-2);
  border: 1px solid var(--hairline);
  background: var(--ivory);
}

.commercial-key-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 1rem;
}

.commercial-key-title {
  width: 100%;
  margin: 0;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.7;
}

.commercial-key-item {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.84rem;
}

.commercial-key-swatch {
  width: 1rem;
  height: 1rem;
  border: 1px solid var(--hairline-strong);
  background: transparent;
}

.commercial-key-swatch[data-status='Available'] { background: rgba(45, 106, 67, 0.34); }

/* The same hatch the map draws, restated in CSS because the key is HTML and
   cannot point at an SVG pattern. Angle, width and colours must match the
   patterns built in commercial-panel.mjs. */
.commercial-key-swatch[data-status='Blocked'] {
  background: repeating-linear-gradient(45deg,
    rgba(150, 100, 6, 0.95) 0 2px,
    rgba(214, 158, 26, 0.34) 2px 9px);
}

.commercial-key-swatch[data-status='Sold'] {
  background: repeating-linear-gradient(45deg,
    rgba(150, 26, 26, 0.95) 0 2px,
    rgba(178, 58, 58, 0.34) 2px 9px);
}
.commercial-key-swatch[data-status='Not offered'] { background: rgba(7, 28, 46, 0.16); }
.commercial-key-swatch[data-status='Disabled'] { background: rgba(7, 28, 46, 0.16); }

.commercial-detail {
  position: sticky;
  /* Selecting a lot on a phone scrolls this into view, and the site header is
     sticky, so without the margin the heading and the status badge land
     underneath it and the reader sees the card with its title cut off. */
  scroll-margin-top: calc(var(--header-h) + 0.75rem);
  top: calc(var(--header-h) + 1rem);
  padding: var(--space-3);
  background: var(--navy);
  color: var(--on-navy);
  border: 1px solid var(--navy);
}

.commercial-detail-empty {
  margin: 0;
  font-size: 0.9rem;
  color: var(--on-navy-mute);
}

.commercial-detail-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: var(--space-2);
}

.commercial-detail-title {
  margin: 0;
  font-family: var(--display);
  font-size: 1.6rem;
  letter-spacing: 0.01em;
}

.commercial-status {
  padding: 0.2rem 0.6rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid var(--on-navy-hairline);
}

.commercial-status[data-status='Available'] { background: #39c07a; color: var(--navy); border-color: #39c07a; }
.commercial-status[data-status='Blocked'] { background: #e0a52a; color: var(--navy); border-color: #e0a52a; }
.commercial-status[data-status='Sold'] { background: #c4574f; color: #fff; border-color: #c4574f; }
.commercial-status[data-status='Disabled'] { background: #68747a; color: #fff; border-color: #68747a; }

.commercial-detail-rows {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 0.4rem 1rem;
  margin: 0 0 var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--on-navy-hairline);
  font-size: 0.88rem;
}

.commercial-detail-rows dt { color: var(--on-navy-mute); }
.commercial-detail-rows dd { margin: 0; text-align: right; font-weight: 600; }

.commercial-detail-note {
  margin: 0 0 var(--space-2);
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--on-navy-mute);
}

.commercial-message-label {
  margin: 0 0 0.35rem;
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-navy-mute);
}

.commercial-message {
  width: 100%;
  padding: 0.6rem;
  border: 1px solid var(--on-navy-hairline);
  background: rgba(243, 240, 232, 0.06);
  color: var(--on-navy);
  font: inherit;
  font-size: 0.8rem;
  line-height: 1.45;
  resize: vertical;
}

.commercial-actions {
  display: grid;
  gap: 0.5rem;
  margin-top: var(--space-2);
}

.commercial-actions .button {
  width: 100%;
  min-height: 44px;
  text-align: center;
}

.commercial-ask {
  background: var(--ivory);
  color: var(--navy);
  border-color: var(--ivory);
}

.commercial-download {
  background: transparent;
  color: var(--on-navy);
  border: 1px solid var(--on-navy-hairline);
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  padding: 0.7rem 1rem;
}

.commercial-download:hover { background: rgba(243, 240, 232, 0.1); }

.commercial-action-status {
  margin: 0.6rem 0 0;
  min-height: 1.1rem;
  font-size: 0.76rem;
  color: var(--on-navy-mute);
}

.commercial-list { margin-top: var(--space-3); }

.commercial-list-title {
  margin: 0 0 0.6rem;
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.7;
}

.commercial-chip {
  display: inline-flex;
  flex-direction: column;
  gap: 0.1rem;
  min-height: 44px;
  margin: 0 0.4rem 0.4rem 0;
  padding: 0.4rem 0.8rem;
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--stone);
  background: #fff;
  font: inherit;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
}

.commercial-chip:hover { border-color: var(--navy); }

.commercial-chip[aria-pressed='true'] {
  background: var(--navy);
  color: var(--ivory);
  border-color: var(--navy);
}

.commercial-chip[data-lot-status='Available'] { border-left-color: #2d6a43; }
.commercial-chip[data-lot-status='Blocked'] { border-left-color: #c48a16; }
.commercial-chip[data-lot-status='Sold'] { border-left-color: #b23a3a; }
.commercial-chip[data-lot-status='Not offered'] { border-left-color: var(--stone); }
.commercial-chip[data-lot-status='Disabled'] { border-left-color: var(--stone); }

.commercial-chip-name { font-weight: 700; font-size: 0.88rem; }
.commercial-chip-area { font-size: 0.74rem; opacity: 0.74; }
.commercial-chip[aria-pressed='true'] .commercial-chip-area { opacity: 0.82; }

@media (max-width: 900px) {
  .commercial-shell { grid-template-columns: minmax(0, 1fr); }
  .commercial-detail { position: static; }
  /* An EXPLICIT height, not a cap. The zoom is a transform, which does not
     change layout, so the window would otherwise stay the height of the
     unscaled map and show a narrow slot of a drawing that is twice as tall. */
  .commercial-figure .plan-map-viewport {
    height: 58vh;
    max-height: 58vh;
  }
}

@media (prefers-reduced-motion: reduce) {
  .commercial-lot { transition: none; }
}

/* ---------------------------------------------------------------------------
   The commercial lot status desk. Internal, never linked from the public site.
   --------------------------------------------------------------------------- */
.lot-desk-heading {
  margin: 0 0 var(--space-2);
  font-family: var(--display);
  font-size: clamp(1.5rem, 3vw, 2rem);
}

.lot-desk-table {
  width: 100%;
  margin: var(--space-3) 0;
  border-collapse: collapse;
  font-size: 0.88rem;
}

.lot-desk-table th,
.lot-desk-table td {
  padding: 0.55rem 0.7rem;
  text-align: left;
  border-bottom: 1px solid var(--on-navy-hairline);
  vertical-align: middle;
}

.lot-desk-table thead th {
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--on-navy-mute);
  border-bottom-color: var(--on-navy-hairline);
}

.lot-desk-name {
  font-family: var(--display);
  font-weight: 700;
  white-space: nowrap;
}

.lot-desk-published { color: var(--on-navy-mute); }

/* A row the desk has moved but not published is marked, because the difference
   between "changed here" and "changed for everybody" is the whole point. */
.lot-desk-table tr[data-changed='true'] {
  background: rgba(224, 165, 42, 0.16);
}

.lot-desk-table tr[data-changed='true'] .lot-desk-name::after {
  content: ' (local)';
  font-family: var(--sans);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #e0a52a;
}

.lot-desk-select {
  min-height: 40px;
  min-width: 9.5rem;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--on-navy-hairline);
  background: rgba(243, 240, 232, 0.06);
  color: var(--on-navy);
  font: inherit;
  font-size: 0.85rem;
}

.lot-desk-select option { color: #0c1620; }

.lot-desk-shown { font-weight: 600; }

.lot-desk-table tr[data-lot-status='Available'] .lot-desk-shown { color: #6fd6a2; }
.lot-desk-table tr[data-lot-status='Blocked'] .lot-desk-shown { color: #f0c261; }
.lot-desk-table tr[data-lot-status='Sold'] .lot-desk-shown { color: #f0938c; }
.lot-desk-table tr[data-lot-status='Not offered'] .lot-desk-shown { color: var(--on-navy-mute); }
.lot-desk-table tr[data-lot-status='Disabled'] .lot-desk-shown { color: var(--on-navy-mute); }

.lot-desk-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: var(--space-3);
}

.lot-desk-actions .button { min-height: 44px; }

.lot-desk-actions .button-quiet {
  background: transparent;
  color: var(--on-navy);
  border: 1px solid var(--on-navy-hairline);
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  padding: 0.7rem 1.1rem;
}

.lot-desk-feedback {
  margin: var(--space-2) 0 0;
  min-height: 1.2rem;
  font-size: 0.82rem;
  color: var(--on-navy-mute);
}

.lot-desk-map-grid {
  display: grid;
  grid-template-columns: minmax(0, 2fr) minmax(17rem, 1fr);
  align-items: start;
  gap: 1rem;
  margin: 1rem 0 1.5rem;
}

.lot-desk-map-host {
  min-width: 0;
  overflow: hidden;
  border: 1px solid rgba(7, 28, 46, 0.12);
  border-radius: 0.85rem;
  background: #eef0eb;
}

.lot-desk-map-figure { margin: 0; }
.lot-desk-map-figure .plan-map-viewport {
  height: min(62vh, 42rem);
  min-height: 24rem;
}

.lot-desk-map-lot {
  fill: rgba(98, 112, 121, 0.22);
  stroke: rgba(255, 255, 255, 0.92);
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  cursor: pointer;
  transition: fill 0.16s ease, stroke 0.16s ease;
}

.lot-desk-map-lot[data-lot-status='Available'] { fill: rgba(31, 122, 74, 0.48); }
.lot-desk-map-lot[data-lot-status='Sold'] { fill: rgba(178, 58, 58, 0.48); }
.lot-desk-map-lot:hover,
.lot-desk-map-lot:focus,
.lot-desk-map-lot.is-selected {
  fill: rgba(196, 138, 22, 0.64);
  stroke: #071c2e;
  outline: none;
}

.lot-desk-editor {
  position: sticky;
  top: 1rem;
  display: grid;
  gap: 0.85rem;
  padding: 1.1rem;
  border: 1px solid rgba(7, 28, 46, 0.12);
  border-radius: 0.85rem;
  background: #fff;
  box-shadow: 0 0.7rem 1.8rem rgba(23, 50, 69, 0.08);
}

.lot-desk-editor[hidden] { display: none; }
.lot-desk-editor h3 { margin: 0; color: #071c2e; }
.lot-desk-field { display: grid; gap: 0.35rem; color: #3f4e56; font-size: 0.82rem; font-weight: 650; }
.lot-desk-field input,
.lot-desk-field select {
  width: 100%;
  min-height: 44px;
  padding: 0.65rem 0.7rem;
  border: 1px solid rgba(7, 28, 46, 0.2);
  border-radius: 0.45rem;
  background: #fff;
  color: #14232c;
  font: inherit;
}

.desk-table-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.desk-search-input {
  flex: 1 1 18rem;
  min-height: 44px;
  padding: 0.65rem 0.75rem;
  border: 1px solid rgba(7, 28, 46, 0.16);
  border-radius: 0.5rem;
  background: #fff;
  color: #14232c;
  font: inherit;
}

@media (max-width: 900px) {
  .lot-desk-map-grid { grid-template-columns: 1fr; }
  .lot-desk-editor { position: static; }
  .lot-desk-map-figure .plan-map-viewport { min-height: 20rem; height: 55vh; }
}

.blast-desk-main { max-width: 72rem; }

.blast-form {
  display: grid;
  gap: 1.15rem;
}

.blast-form .field { margin: 0; }
.blast-form .field label { color: var(--on-navy); }
.blast-form .field input,
.blast-form .field select,
.blast-form .field textarea {
  width: 100%;
  border-color: var(--on-navy-hairline);
  background: rgba(243, 240, 232, 0.06);
  color: var(--on-navy);
}

.blast-form .field select option { color: #0c1620; }
.blast-message-field textarea { min-height: 8rem; }
.blast-form .field-note { color: var(--on-navy-mute); }

.blast-channel {
  margin: 0;
  padding: 0;
  border: 0;
}
.blast-channel legend {
  margin-bottom: 0.55rem;
  color: #173245;
  font-size: 0.82rem;
  font-weight: 700;
}
.blast-channel-picks {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.65rem;
}
.blast-channel-pick {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0.7rem 0.85rem;
  border: 1px solid rgba(7, 28, 46, 0.16);
  border-radius: 0.7rem;
  background: #fff;
  color: #173245;
  font-weight: 650;
  text-align: center;
  cursor: pointer;
}
.blast-channel-pick input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.blast-channel-pick:has(input:checked) {
  border-color: #2d6a43;
  background: #e6f2ea;
  color: #1f5b39;
}
.blast-channel-pick:has(input:focus-visible) {
  outline: 2px solid #2d6a43;
  outline-offset: 2px;
}

.blast-people-block { display: grid; gap: 0.75rem; }
.blast-people-head h3 {
  margin: 0;
  color: #071c2e;
  font-size: 1.05rem;
}
.blast-people-head p {
  margin: 0.25rem 0 0;
  color: #68747a;
  font-size: 0.88rem;
}
.blast-people { display: grid; gap: 0.75rem; }
.blast-person {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  align-items: end;
  padding: 0.9rem;
  border: 1px solid rgba(7, 28, 46, 0.1);
  border-radius: 0.8rem;
  background: #fff;
}
.blast-person .field { flex: 1 1 11rem; margin: 0; }
.blast-person label {
  display: grid;
  gap: 0.35rem;
  font-size: 0.8rem;
  font-weight: 650;
}
.blast-person-remove,
.blast-add-person {
  min-height: 44px;
  padding: 0.55rem 0.85rem;
  border: 1px solid rgba(7, 28, 46, 0.16);
  border-radius: 0.55rem;
  background: #fff;
  color: #173245;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 650;
  cursor: pointer;
}
.blast-person-remove { flex: 0 0 auto; }
.blast-add-person { justify-self: start; }
.blast-person-remove:hover,
.blast-add-person:hover,
.blast-person-remove:focus-visible,
.blast-add-person:focus-visible {
  border-color: #2d6a43;
  background: #edf5ee;
  color: #225033;
}
.blast-live-approval {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0.75rem;
}
.blast-live-approval[hidden] { display: none; }
.blast-preflight {
  margin: 0;
  color: #173245;
  font-size: 0.9rem;
  font-weight: 650;
}
.blast-history-people {
  margin: 0;
  color: #071c2e;
  font-size: 1.05rem;
  font-weight: 700;
}
.blast-history-card[data-blast-status='practice'] { border-left-color: #c48a16; }
.blast-history-card[data-blast-status='practice'] .app-status-pill { background: #fbf0d8; color: #7a5209; }
.blast-history-card[data-blast-status='failed'] { border-left-color: #b23a3a; }
.blast-history-card[data-blast-status='failed'] .app-status-pill { background: #fbe9e7; color: #93302f; }
.blast-history-card[data-blast-status='submitted'],
.blast-history-card[data-blast-status='sent'] { border-left-color: #2d6a43; }
.blast-history-card[data-blast-status='submitted'] .app-status-pill,
.blast-history-card[data-blast-status='sent'] .app-status-pill { background: #e6f2ea; color: #1f5b39; }

@media (max-width: 720px) {
  .lot-desk-table { font-size: 0.8rem; }
  .lot-desk-table th,
  .lot-desk-table td { padding: 0.45rem 0.4rem; }
  .lot-desk-select { min-width: 7.5rem; }
  .blast-channel-picks,
  .blast-live-approval { grid-template-columns: 1fr; }
}

/* ---------------------------------------------------------------------------
   AnCor Operations Desk. The public site stays editorial and warm, while the
   working surface uses a crisp property-operations shell with its own rail.
   --------------------------------------------------------------------------- */
.desk-body {
  min-height: 100vh;
  background: #f2f0e9;
  color: #14232c;
  font-size: 1rem;
}

.desk-app-shell {
  display: grid;
  grid-template-columns: 17.5rem minmax(0, 1fr);
  min-height: 100vh;
}

.desk-sidebar {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  height: 100vh;
  padding: 1.5rem 1.25rem;
  overflow-y: auto;
  background:
    radial-gradient(circle at 8% 2%, rgba(214, 177, 86, 0.16), transparent 13rem),
    #061b2b;
  color: #f7f3e8;
  border-right: 1px solid rgba(255, 255, 255, 0.08);
}

.desk-side-brand {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  min-height: 4.5rem;
  color: #f7f3e8;
  text-decoration: none;
}

.desk-side-brand:hover { color: #fff; }
.desk-side-brand img { width: 4.25rem; height: auto; border-radius: 0.35rem; }
.desk-side-brand span { display: grid; gap: 0.08rem; }
.desk-side-brand strong {
  font-family: var(--display);
  font-size: 1.05rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.desk-side-brand small { color: rgba(247, 243, 232, 0.58); font-size: 0.73rem; }

.desk-side-nav {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
  margin-top: 2.5rem;
}

.desk-side-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.8rem;
  min-height: 48px;
  padding: 0.72rem 0.85rem;
  border-radius: 0.7rem;
  color: rgba(247, 243, 232, 0.68);
  text-decoration: none;
  font-weight: 600;
  transition: color 0.2s var(--ease), background 0.2s var(--ease), transform 0.2s var(--ease);
}

.desk-side-link svg {
  flex: none;
  width: 1.25rem;
  height: 1.25rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.desk-side-link:hover {
  color: #fff;
  background: rgba(255, 255, 255, 0.07);
  transform: translateX(2px);
}

.desk-side-link:focus-visible {
  outline: 3px solid #d6b156;
  outline-offset: 2px;
}

.desk-side-link[aria-current='page'] {
  color: #071c2e;
  background: #d6b156;
  box-shadow: 0 0.45rem 1rem rgba(0, 0, 0, 0.2);
}

.desk-side-foot {
  display: grid;
  gap: 1rem;
  margin-top: auto;
  padding-top: 2rem;
}

.desk-demo-state {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.05rem 0.6rem;
  align-items: center;
  padding: 0.9rem;
  border: 1px solid rgba(214, 177, 86, 0.24);
  border-radius: 0.7rem;
  background: rgba(214, 177, 86, 0.08);
}

.desk-demo-state > span {
  grid-row: 1 / 3;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: #d6b156;
  box-shadow: 0 0 0 0.25rem rgba(214, 177, 86, 0.12);
}
.desk-demo-state strong { font-size: 0.82rem; }
.desk-demo-state small { color: rgba(247, 243, 232, 0.58); font-size: 0.68rem; }

.desk-public-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: rgba(247, 243, 232, 0.68);
  font-size: 0.82rem;
  font-weight: 600;
  text-decoration: none;
}
.desk-public-link::after { content: '\2197'; margin-left: 0.45rem; color: #d6b156; }
.desk-public-link:hover { color: #fff; }

.desk-workspace { min-width: 0; }

.desk-topbar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  min-height: 6.25rem;
  padding: 1rem clamp(1.25rem, 4vw, 3.5rem);
  background: #f2f0e9;
  border-bottom: 1px solid rgba(7, 28, 46, 0.1);
  backdrop-filter: blur(14px);
}

.desk-topbar h1 {
  margin-top: 0.1rem;
  font-size: clamp(1.5rem, 2.4vw, 2rem);
  color: #071c2e;
}

.desk-kicker {
  margin: 0;
  color: #68747a;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.desk-topbar-actions { display: flex; align-items: center; gap: 1rem; }
.desk-map-link,
.desk-logout {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0.55rem 0.9rem;
  border: 1px solid rgba(7, 28, 46, 0.16);
  border-radius: 0.55rem;
  background: #fff;
  color: #173245;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 650;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), background 0.2s var(--ease), color 0.2s var(--ease);
}
.desk-map-link:hover,
.desk-logout:hover { border-color: #2d6a43; background: #edf5ee; color: #225033; }
.desk-logout[hidden] { display: none !important; }

.desk-main {
  width: min(100%, 78rem);
  max-width: none;
  margin: 0;
  padding: clamp(1.5rem, 4vw, 3.5rem);
}

.desk-page-intro { margin-bottom: 1.5rem; }
.desk-page-intro .lot-desk-heading {
  margin: 0.35rem 0 0;
  max-width: 22ch;
  color: #071c2e;
  font-size: clamp(1.8rem, 4vw, 3rem);
  line-height: 1.04;
}

.desk-notice {
  margin-bottom: 1.25rem;
  padding: 0.9rem 1rem;
  border: 1px solid rgba(196, 138, 22, 0.28);
  border-left: 4px solid #c48a16;
  border-radius: 0.65rem;
  background: #fff8e8;
  color: #554112;
}

.desk-panel {
  margin-bottom: 1.25rem;
  padding: clamp(1.15rem, 2.5vw, 2rem);
  border: 1px solid rgba(7, 28, 46, 0.09);
  border-radius: 1rem;
  background: #fff;
  color: #14232c;
  box-shadow: 0 0.8rem 2.2rem rgba(23, 50, 69, 0.07);
}

.desk-panel-head h2,
.desk-panel h2 { color: #071c2e; }
.desk-panel-note { color: #68747a; opacity: 1; }

.desk-login-form .field label { color: #14232c; }
.desk-login-form .field input {
  border-color: rgba(7, 28, 46, 0.18);
  background: #fff;
  color: #14232c;
}
.desk-login-status { color: #68747a; }
.desk-stats { gap: 1rem; }
.stat { border: 1px solid rgba(7, 28, 46, 0.09); border-radius: 0.8rem; background: #fff; }
.stat-label,
.stat-note { color: #68747a; opacity: 1; }
.stat-value { color: #071c2e; }
.stat.is-money .stat-value { color: #2d6a43; }

.lot-desk-table th,
.lot-desk-table td { border-bottom-color: rgba(7, 28, 46, 0.1); }
.lot-desk-table thead th { color: #68747a; border-bottom-color: rgba(7, 28, 46, 0.14); }
.lot-desk-published { color: #68747a; }
.lot-desk-table tr[data-lot-status='Available'] .lot-desk-shown { color: #1f7a4a; }
.lot-desk-table tr[data-lot-status='Blocked'] .lot-desk-shown { color: #95630a; }
.lot-desk-table tr[data-lot-status='Sold'] .lot-desk-shown { color: #b23a3a; }
.lot-desk-table tr[data-lot-status='Not offered'] .lot-desk-shown { color: #68747a; }
.lot-desk-table tr[data-lot-status='Disabled'] .lot-desk-shown { color: #68747a; }
/* Recruitment queue. The owner reviews applicants one person at a time, so this
   is a card list, not an eight-column table that only fitted by scrolling. */
.app-filter-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1.25rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid rgba(7, 28, 46, 0.1);
}
.app-filter {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 40px;
  padding: 0.4rem 0.75rem;
  border: 1px solid rgba(7, 28, 46, 0.16);
  border-radius: 999px;
  background: #fff;
  color: #173245;
  font: inherit;
  font-size: 0.82rem;
  font-weight: 650;
  cursor: pointer;
  transition: border-color 0.2s var(--ease), background 0.2s var(--ease), color 0.2s var(--ease);
}
.app-filter-count {
  min-width: 1.5rem;
  padding: 0.05rem 0.4rem;
  border-radius: 999px;
  background: rgba(7, 28, 46, 0.07);
  color: #68747a;
  font-size: 0.74rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
}
.app-filter:hover { border-color: rgba(7, 28, 46, 0.32); background: #f7f6f1; }
.app-filter[aria-pressed='true'] { border-color: #c48a16; background: #d6b156; color: #071c2e; }
.app-filter[aria-pressed='true'] .app-filter-count { background: rgba(7, 28, 46, 0.14); color: #071c2e; }

.app-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(21rem, 1fr));
  gap: 1rem;
}
.app-card {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 1.1rem 1.15rem 1.15rem;
  border: 1px solid rgba(7, 28, 46, 0.1);
  border-left: 4px solid rgba(7, 28, 46, 0.22);
  border-radius: 0.85rem;
  background: #fff;
  box-shadow: 0 0.4rem 1.2rem rgba(23, 50, 69, 0.05);
}
.app-card-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}
.app-card-name {
  margin: 0;
  color: #071c2e;
  font-size: 1.1rem;
  line-height: 1.2;
}
.app-card-role { margin: 0.2rem 0 0; color: #68747a; font-size: 0.85rem; }
.app-status-pill {
  flex: none;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: rgba(7, 28, 46, 0.08);
  color: #173245;
  font-size: 0.68rem;
  font-weight: 750;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  white-space: nowrap;
}
.app-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.75rem;
  margin: 0;
  color: #68747a;
  font-size: 0.75rem;
}
.app-card-ref { color: #173245; font-weight: 700; letter-spacing: 0.02em; }
.app-card-facts {
  display: grid;
  gap: 0.5rem;
  margin: 0;
  padding-top: 0.75rem;
  border-top: 1px solid rgba(7, 28, 46, 0.08);
}
.app-fact { display: grid; grid-template-columns: 6.25rem minmax(0, 1fr); gap: 0.5rem; align-items: baseline; }
.app-fact dt { color: #68747a; font-size: 0.76rem; }
.app-fact dd { margin: 0; color: #14232c; font-size: 0.86rem; overflow-wrap: anywhere; }
.app-fact a { color: #225033; text-decoration: none; border-bottom: 1px solid rgba(34, 80, 51, 0.32); }
.app-fact a:hover { border-bottom-color: #225033; }

.app-card-actions {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 0.6rem;
  margin-top: auto;
  padding-top: 0.85rem;
  border-top: 1px solid rgba(7, 28, 46, 0.08);
}
.app-field { display: grid; gap: 0.3rem; min-width: 0; }
.app-field-note { grid-column: 1 / -1; }
.app-field label {
  color: #68747a;
  font-size: 0.68rem;
  font-weight: 750;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.app-card-actions .application-save { align-self: end; }

/* The status list is the one control the owner uses on every card, and the
   native Windows popup drew it in the OS serif with a blue highlight, ignoring
   every font and colour on the page. Browsers without the customizable select
   API skip this block and keep their own list. */
@supports (appearance: base-select) {
  .desk-body select,
  .desk-body select::picker(select) { appearance: base-select; }

  .desk-body select {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.5rem 0.7rem;
    text-align: left;
  }
  .desk-body select::picker-icon {
    color: #68747a;
    transition: transform 0.18s var(--ease);
  }
  .desk-body select:open::picker-icon { transform: rotate(180deg); }

  .desk-body select::picker(select) {
    padding: 0.3rem;
    border: 1px solid rgba(7, 28, 46, 0.16);
    border-radius: 0.55rem;
    background: #fff;
    box-shadow: 0 0.8rem 2rem rgba(23, 50, 69, 0.16);
  }
  .desk-body select option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    min-height: 40px;
    padding: 0.45rem 0.6rem;
    border-radius: 0.4rem;
    background: #fff;
    color: #14232c;
    font: inherit;
    font-size: 0.92rem;
  }
  .desk-body select option:hover { background: #f4f2ea; }
  .desk-body select option:checked { background: #f7efd9; color: #071c2e; font-weight: 650; }
  .desk-body select option::checkmark { color: #c48a16; }
}

.app-card[data-application-status='New'] { border-left-color: #1f5f9e; }
.app-card[data-application-status='Screening'] { border-left-color: #c48a16; }
.app-card[data-application-status='Accepted'] { border-left-color: #2d6a43; }
.app-card[data-application-status='Declined'] { border-left-color: #b23a3a; }
.app-card[data-application-status='New'] .app-status-pill { background: #e7f0f8; color: #1a4f83; }
.app-card[data-application-status='Screening'] .app-status-pill { background: #fbf0d8; color: #7a5209; }
.app-card[data-application-status='Accepted'] .app-status-pill { background: #e6f2ea; color: #1f5b39; }
.app-card[data-application-status='Declined'] .app-status-pill { background: #fbe9e7; color: #93302f; }

/* Payment queue. The money figure is the thing staff came for, so it is the
   loudest element on the card, and a Maya preview row is flagged in amber
   because nothing was charged on it. */
.pay-desk-totals {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.35rem 0.85rem;
  margin: 0 0 1.1rem;
  padding: 0.85rem 1.05rem;
  border: 1px solid rgba(7, 28, 46, 0.1);
  border-radius: 0.85rem;
  background: #fff;
  box-shadow: 0 0.4rem 1.2rem rgba(23, 50, 69, 0.05);
  color: #68747a;
  font-size: 0.85rem;
}
.pay-desk-totals strong {
  color: #1f5b39;
  font-family: 'Archivo', system-ui, sans-serif;
  font-size: 1.45rem;
  letter-spacing: -0.01em;
}
.pay-desk-awaiting {
  margin-left: auto;
  padding: 0.25rem 0.6rem;
  border-radius: 999px;
  background: #fbf0d8;
  color: #7a5209;
  font-size: 0.75rem;
  font-weight: 650;
}
.pay-desk-amount {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.45rem;
  margin: 0;
  color: #68747a;
  font-size: 0.85rem;
}
.pay-desk-amount strong {
  color: #071c2e;
  font-family: 'Archivo', system-ui, sans-serif;
  font-size: 1.3rem;
  letter-spacing: -0.01em;
}
.pay-desk-flag {
  margin: 0;
  padding: 0.3rem 0.6rem;
  border-radius: 0.5rem;
  background: #fbf0d8;
  color: #7a5209;
  font-size: 0.76rem;
  font-weight: 650;
}
.app-card[data-payment-status='Declared'] { border-left-color: #1f5f9e; }
.app-card[data-payment-status='Received'] { border-left-color: #2d6a43; }
.app-card[data-payment-status='Not found'] { border-left-color: #c48a16; }
.app-card[data-payment-status='Declined'] { border-left-color: #b23a3a; }
.app-card[data-payment-status='Declared'] .app-status-pill { background: #e7f0f8; color: #1a4f83; }
.app-card[data-payment-status='Received'] .app-status-pill { background: #e6f2ea; color: #1f5b39; }
.app-card[data-payment-status='Not found'] .app-status-pill { background: #fbf0d8; color: #7a5209; }
.app-card[data-payment-status='Declined'] .app-status-pill { background: #fbe9e7; color: #93302f; }

@media (max-width: 560px) {
  .pay-desk-awaiting { margin-left: 0; }
}

.recruitment-audit-list {
  display: grid;
  gap: 0.55rem;
  margin: 0;
  padding: 0;
  list-style: none;
}
.recruitment-audit-list li {
  display: grid;
  gap: 0.15rem;
  padding: 0.7rem 0.85rem;
  border: 1px solid rgba(7, 28, 46, 0.09);
  border-radius: 0.6rem;
  background: #faf9f5;
}
.recruitment-audit-list strong { color: #071c2e; font-size: 0.88rem; }
.recruitment-audit-list span { color: #68747a; font-size: 0.78rem; }
.recruitment-audit-list .desk-audit-note { color: #173245; }
.lot-desk-select {
  min-height: 44px;
  border-color: rgba(7, 28, 46, 0.18);
  border-radius: 0.45rem;
  background: #f8f7f2;
  color: #14232c;
}
.application-status-select,
.application-note {
  width: 100%;
  min-width: 0;
  min-height: 44px;
  border: 1px solid rgba(7, 28, 46, 0.18);
  border-radius: 0.45rem;
  background: #f8f7f2;
  color: #14232c;
  font: inherit;
}
.application-note {
  min-height: 3.4rem;
  padding: 0.55rem 0.65rem;
  line-height: 1.45;
  resize: vertical;
}
.application-save {
  min-height: 44px;
  padding: 0.55rem 0.85rem;
  border: 1px solid rgba(7, 28, 46, 0.16);
  border-radius: 0.55rem;
  background: #fff;
  color: #173245;
  font: inherit;
  font-size: 0.8rem;
  font-weight: 650;
  cursor: pointer;
}
.application-save:hover,
.application-save:focus-visible { border-color: #2d6a43; background: #edf5ee; color: #225033; }

.blast-form .field label { color: #173245; }
.blast-form .field input,
.blast-form .field select,
.blast-form .field textarea {
  min-height: 48px;
  border-color: rgba(7, 28, 46, 0.16);
  border-radius: 0.55rem;
  background: #faf9f5;
  color: #14232c;
}
.blast-form .field input:focus,
.blast-form .field select:focus,
.blast-form .field textarea:focus { border-color: #2d6a43; background: #fff; }
.blast-form .field-note,
.lot-desk-feedback { color: #68747a; }
.desk-notice[data-blast-mode][data-mode='dry-run'] {
  border-color: rgba(196, 138, 22, 0.28);
  background: #fbf0d8;
  color: #7a5209;
}
.desk-notice[data-blast-mode][data-mode='live'] {
  border-color: rgba(45, 106, 67, 0.28);
  background: #e6f2ea;
  color: #1f5b39;
}

@media (max-width: 760px) {
  .desk-app-shell { grid-template-columns: minmax(0, 1fr); }
  .desk-sidebar {
    position: static;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    gap: 0.75rem;
    align-items: center;
    min-height: auto;
    height: auto;
    padding: 0.75rem 1rem;
    overflow: visible;
  }
  .desk-side-brand { min-height: 44px; }
  .desk-side-brand img { width: 3.35rem; }
  .desk-side-brand span { display: none; }
  .desk-side-nav { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 0.25rem; margin: 0; min-width: 0; }
  .desk-side-link { min-height: 44px; padding: 0.55rem 0.55rem; font-size: 0.8rem; }
  .desk-side-link:hover { transform: none; }
  .desk-side-link svg { width: 1.05rem; height: 1.05rem; }
  .desk-side-foot { display: block; margin: 0; padding: 0; }
  .desk-demo-state { display: flex; min-height: 44px; padding: 0.55rem 0.7rem; }
  .desk-demo-state > span { width: 0.5rem; height: 0.5rem; }
  .desk-demo-state strong,
  .desk-demo-state small,
  .desk-public-link { display: none; }
  .desk-topbar { position: static; min-height: 5.25rem; padding: 0.9rem 1.25rem; }
  .desk-topbar h1 { font-size: 1.45rem; }
  .desk-map-link { padding-inline: 0.7rem; }
  .desk-main { padding: 1.5rem 1rem 3rem; }
  .desk-panel { border-radius: 0.8rem; }
  .app-card-grid { grid-template-columns: minmax(0, 1fr); }
  .app-card { padding: 1rem; }
  .app-card-actions { grid-template-columns: minmax(0, 1fr); }
  .app-card-actions .application-save { justify-self: start; }
  .app-fact { grid-template-columns: 5.5rem minmax(0, 1fr); }
}

@media (max-width: 430px) {
  .desk-sidebar { grid-template-columns: auto minmax(0, 1fr); }
  .desk-side-foot { display: none; }
  .desk-side-link { gap: 0.45rem; }
  .desk-topbar-actions { gap: 0.4rem; }
  .desk-map-link { font-size: 0.74rem; }
}

@media (prefers-reduced-motion: reduce) {
  .desk-side-link,
  .desk-map-link,
  .desk-logout { transition-duration: 0.01ms; }
}

.desk-subdivision-filter {
  margin-bottom: 1.5rem;
}

.desk-subdivision-label {
  font-weight: 600;
  display: block;
  margin-bottom: 0.5rem;
}

.desk-filter-select {
  padding: 0.6rem 1rem;
  border-radius: 4px;
  border: 1px solid var(--desk-border, #d1d5db);
  background: var(--desk-bg, #fff);
  font-size: 1rem;
  min-width: 320px;
  max-width: 100%;
}

.desk-table-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.desk-search-input {
  padding: 0.5rem 0.8rem;
  border: 1px solid var(--desk-border, #d1d5db);
  border-radius: 4px;
  font-size: 0.95rem;
  min-width: 260px;
  max-width: 100%;
}

.desk-pagination {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 1rem;
  margin-bottom: 1rem;
}

.desk-page-info {
  font-size: 0.9rem;
  color: var(--muted, #64748b);
}

.plan-map-picker-wrap {
  margin-bottom: 0.75rem;
  width: 100%;
}

.plan-map-lot-picker {
  width: 100%;
  min-height: 44px;
  padding: 0.6rem 0.8rem;
  font-size: 0.95rem;
  border: 1px solid var(--border-subtle, #cbd5e1);
  border-radius: 4px;
  background: var(--surface, #ffffff);
  color: var(--text, #0f172a);
}

/* Drawing a lot the official plan never traced. */
.lot-desk-draw-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin: 0 0 1rem;
}

.lot-desk-draw-bar .desk-panel-note { margin: 0; }

.lot-desk-draw-bar [aria-pressed='true'] {
  background: #c48a16;
  border-color: #c48a16;
  color: #071c2e;
}

.lot-desk-map-svg.is-drawing { cursor: crosshair; }

.lot-desk-map-svg.is-drawing .lot-desk-map-lot { cursor: crosshair; }

.lot-desk-placing-shape {
  fill: rgba(196, 138, 22, 0.22);
  stroke: #c48a16;
  stroke-width: 3;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

.lot-desk-placing-corner {
  fill: #c48a16;
  stroke: #071c2e;
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  pointer-events: none;
}

.lot-desk-corner {
  fill: #ffffff;
  stroke: #071c2e;
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
  cursor: grab;
  touch-action: none;
}

.lot-desk-corner:hover,
.lot-desk-corner:active {
  fill: #c48a16;
  cursor: grabbing;
}

.lot-desk-delete {
  color: #b23a3a;
  border-color: rgba(178, 58, 58, 0.5);
}

.lot-desk-delete:hover:not(:disabled) {
  background: rgba(178, 58, 58, 0.1);
  border-color: #b23a3a;
}
.pay-confirmation-dialog {
  width: min(92vw, 34rem);
  max-height: 85vh;
  overflow: auto;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  border: 1px solid var(--line, #c9c9c9);
  border-radius: 1rem;
  background: #fff;
  color: #17221b;
  box-shadow: 0 1.5rem 4rem #0004;
}
.pay-confirmation-dialog::backdrop { background: #101b17b3; }
.pay-confirmation-dialog h2 { margin-top: 0; }
.pay-confirmation-dialog form { margin-top: 1.5rem; }
