:root {
  --paper: #FDFBF7;
  --paper-alt: #F5F0E8;
  --paper-deep: #EDE5D8;
  --ink: #2A2320;
  --ink-soft: #5C5049;
  --line: #E2D9CC;
  --brand: #9C5B34;
  --brand-deep: #7A4527;
  --brand-wash: #F7EDE5;
  --accent: #3F6152;
  --accent-wash: #E9F0EC;
  --warn: #A8641B;
  --focus: #1F4FD8;

  --font-text: "Source Serif 4", Georgia, "Iowan Old Style", "Times New Roman", serif;
  --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  --section-y: clamp(2.25rem, 6vw, 4rem);
  --block-y: clamp(1.25rem, 3.5vw, 2rem);
  --gutter: clamp(1rem, 4vw, 2rem);
  --measure: 38rem;
  --wide: 72rem;
  --radius: 10px;
  --radius-sm: 6px;
  --tap: 44px;
  --nav-h: 58px;
}

*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* clip, not hidden: `hidden` on html makes body the scroll container and
     breaks position:sticky in Safari. This pair stops 390px pages wiggling
     sideways and is deliberate — a reading that says it is the bug needs to
     clear a higher bar than one that says a script is duplicated. */
  overflow-x: clip;
  scroll-padding-top: calc(var(--nav-h) + 8px);
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 17px/1.6 var(--font-text);
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
}
img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: var(--brand-deep); text-underline-offset: .18em; }
a:hover { color: var(--brand); }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 3px; }
h1, h2, h3 { line-height: 1.18; margin: 0 0 .5em; font-weight: 600; letter-spacing: -.01em; }
h1 { font-size: clamp(1.85rem, 6.4vw, 3rem); }
h2 { font-size: clamp(1.4rem, 4.6vw, 2rem); }
h3 { font-size: clamp(1.1rem, 3.6vw, 1.35rem); }
p { margin: 0 0 var(--block-y); }
p:last-child { margin-bottom: 0; }
small, .fine { font-size: .875rem; color: var(--ink-soft); }

.wrap { width: min(100% - (var(--gutter) * 2), var(--wide)); margin-inline: auto; }
.measure { max-width: var(--measure); }
.section { padding-block: var(--section-y); }
.section--alt { background: var(--paper-alt); }
.section--wash { background: var(--brand-wash); }
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 400;
  background: var(--ink); color: var(--paper); padding: .75rem 1rem;
}
.skip:focus { left: .5rem; top: .5rem; }

/* ---------------------------------------------------------------- nav --- */
.nav {
  position: sticky; top: 0; z-index: 200;
  background: color-mix(in srgb, var(--paper) 92%, transparent);
  backdrop-filter: saturate(1.4) blur(8px);
  border-bottom: 1px solid var(--line);
}
.nav__bar { display: flex; align-items: center; gap: .75rem; min-height: var(--nav-h); }
.nav__brand { display: block; text-decoration: none; color: var(--ink); margin-right: auto; padding: .35rem 0; }
.nav__brand-name { display: block; font-family: var(--font-ui); font-weight: 700; font-size: .98rem; letter-spacing: .01em; }
.nav__brand-sub { display: block; font-family: var(--font-ui); font-size: .72rem; color: var(--ink-soft); }
.nav__toggle {
  font: 600 .9rem/1 var(--font-ui); color: var(--ink);
  min-height: var(--tap); min-width: var(--tap);
  background: none; border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 0 .8rem; cursor: pointer;
}
.nav__menu { display: none; }
.nav__menu.is-open {
  display: block; position: absolute; left: 0; right: 0; top: 100%;
  background: var(--paper); border-bottom: 1px solid var(--line);
  padding: .5rem var(--gutter) 1rem; box-shadow: 0 12px 24px rgba(42,35,32,.10);
}
.nav__list { list-style: none; margin: 0; padding: 0; }
.nav__list a {
  display: flex; align-items: center; min-height: var(--tap);
  font-family: var(--font-ui); font-size: 1rem; text-decoration: none;
  color: var(--ink); border-bottom: 1px solid var(--line);
}
.nav__list a[aria-current="page"] { color: var(--brand-deep); font-weight: 600; }
.nav__actions { display: flex; gap: .5rem; align-items: center; margin-top: .75rem; }
.nav__lang, .nav__call {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap); padding: 0 .9rem; border-radius: var(--radius-sm);
  font: 600 .9rem/1 var(--font-ui); text-decoration: none;
}
.nav__lang { border: 1px solid var(--line); color: var(--ink); }
.nav__call { background: var(--brand); color: var(--paper); }
.nav__call:hover { background: var(--brand-deep); color: var(--paper); }

@media (min-width: 900px) {
  .nav__toggle { display: none; }
  .nav__menu { display: flex; align-items: center; gap: 1.25rem; }
  .nav__list { display: flex; gap: 1.1rem; }
  .nav__list a { border: 0; font-size: .95rem; }
  .nav__actions { margin: 0; }
}

/* -------------------------------------------------------------- hero --- */
.hero {
  max-height: 62svh; min-height: 46svh;
  display: flex; align-items: flex-end;
  position: relative; overflow: hidden;
  background: var(--paper-alt);
}
.hero__media { position: absolute; inset: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; }
/* The scrim is heavier than it looks like it needs to be, and that is
   deliberate: the hero photograph is a bright sky over a sunlit pasture, so
   white text sitting on the TOP of it is the worst case, not the bottom. Both
   stops were checked against the lightest pixels the image actually renders,
   not against an average. */
.hero__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(42,35,32,.46) 0%, rgba(42,35,32,.30) 34%,
                            rgba(42,35,32,.58) 74%, rgba(42,35,32,.78) 100%);
}
.hero__inner { position: relative; padding-block: clamp(1.5rem, 5vw, 3rem); color: #fff; }
.hero h1 { color: #fff; margin-bottom: .35em; text-wrap: balance; }
.hero__sub { color: #fff; max-width: 34rem; font-size: 1.05rem; }
.hero__cta { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1rem; }
@media (min-width: 900px) { .hero { max-height: 70vh; min-height: 52vh; } }

/* ------------------------------------------------------------ buttons --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap); padding: .55rem 1.15rem;
  font: 600 1rem/1.2 var(--font-ui); text-align: center; text-decoration: none;
  border-radius: var(--radius-sm); border: 1px solid transparent; cursor: pointer;
  background: var(--brand); color: var(--paper);
}
.btn:hover { background: var(--brand-deep); color: var(--paper); }
.btn--ghost { background: transparent; color: var(--ink); border-color: var(--line); }
.btn--ghost:hover { background: var(--paper-alt); color: var(--ink); }
.btn--onhero { background: #fff; color: var(--ink); }
.btn--onhero:hover { background: var(--paper-alt); color: var(--ink); }
/* Secondary action on the hero. A second solid white button reads as two
   primary actions, which is one more than a page should have. */
.btn--onhero-ghost { background: rgba(253,251,247,.10); color: #fff; border-color: rgba(255,255,255,.72); }
.btn--onhero-ghost:hover { background: rgba(253,251,247,.22); color: #fff; }
.btn--wide { width: 100%; }

/* --------------------------------------------------------- home cards ---
   Compact by default. Photo, plan, beds/baths/sq ft, price, payment with its
   rate and APR line. Everything else is behind the expand. Horizontal on
   phones so three fit: measured at 390x844, five are fully visible. */
/* THE COMPACT CARD IS SIZED BY A MEASUREMENT, NOT BY TASTE.
   At 390x844 the nav takes 58px and the filter bar 44, leaving 742 for
   results. Three cards fully visible therefore means <=247px each including
   the 10px gap. The first version of this card measured 276 and exactly ONE
   fitted — the same defect the site this forked from has had open since
   August. What got it under: one combined meta line instead of two, the
   expander moved inline beside the badges instead of a 44px full-width row,
   and a 104px photo instead of 116. Nothing was deleted from the card; the
   Reg Z disclosure in particular is untouched and still on the closed face. */
.cards { display: grid; gap: .55rem; margin: 0; padding: 0; list-style: none; }
.card {
  background: var(--paper); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
  display: grid; grid-template-columns: 104px 1fr; position: relative;
}
.card__media { background: var(--paper-alt); align-self: stretch; }
.card__media img { width: 100%; height: 100%; object-fit: cover; min-height: 100%; }
.card__body { padding: .45rem .6rem .5rem; min-width: 0; }
.card__plan {
  font: 600 .98rem/1.2 var(--font-ui); margin: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.card__plan a { color: var(--ink); text-decoration: none; }
.card__plan a::after { content: ""; position: absolute; inset: 0; }
.card__where { font: .74rem/1.35 var(--font-ui); color: var(--ink-soft); margin: .05rem 0 .15rem; }
.card__price { font: 700 1.02rem/1.15 var(--font-ui); margin: 0; }
.card__was { font: 400 .78rem/1 var(--font-ui); color: var(--ink-soft); text-decoration: line-through; margin-left: .35rem; }
.card__pay { font: .74rem/1.3 var(--font-ui); color: var(--ink-soft); margin: .1rem 0 0; }
.card__pay b { color: var(--ink); font-weight: 600; }
/* The Reg Z line that travels with the card's payment. Small, but never
   hidden, never truncated and never behind the expander: a disclosure the
   reader has to open is a disclosure they did not receive. */
.card__disc { font-size: .64rem; line-height: 1.32; color: var(--ink-soft); margin: .1rem 0 0; }
.card__foot { display: flex; align-items: center; gap: .4rem; margin-top: .25rem; }
.card__badges { display: flex; flex-wrap: wrap; gap: .22rem; margin: 0; }
.badge {
  font: 600 .68rem/1 var(--font-ui); letter-spacing: .02em; text-transform: uppercase;
  padding: .28rem .45rem; border-radius: 3px; background: var(--paper-alt); color: var(--ink-soft);
}
.badge--ready { background: var(--accent-wash); color: var(--accent); }
.badge--reduced { background: var(--brand-wash); color: var(--warn); }
.badge--age { background: var(--paper-deep); color: var(--ink); }
/* Controls inside a card sit above the stretched link. Without this the whole
   card swallows every tap on them and they look painted but dead. */
.card__acts { position: relative; z-index: 2; display: flex; gap: .4rem; margin-top: .35rem; }
/* 44px of TOUCH, not 44px of ink. The hit area is padded out to the target
   with a pseudo-element so the control obeys the tap-target floor without
   spending 44px of vertical space it does not need — which is what pushed the
   card to 276px in the first place. */
.card__more {
  position: relative; z-index: 2; margin-left: auto; flex: 0 0 auto;
  background: none; border: 1px solid var(--line); border-radius: var(--radius-sm);
  font: 600 .74rem/1 var(--font-ui); color: var(--brand-deep); cursor: pointer;
  padding: .35rem .5rem; white-space: nowrap;
}
.card__more::before { content: ""; position: absolute; left: 0; right: 0; top: 50%;
  height: var(--tap); transform: translateY(-50%); }
.card__extra { grid-column: 1 / -1; padding: 0 .6rem .6rem; display: none; }
.card__extra.is-open { display: block; }
.card__dl { display: grid; grid-template-columns: auto 1fr; gap: .15rem .6rem; margin: 0; font: .82rem/1.4 var(--font-ui); }
.card__dl dt { color: var(--ink-soft); }
.card__dl dd { margin: 0; }
@media (min-width: 700px) {
  .cards { grid-template-columns: repeat(auto-fill, minmax(255px, 1fr)); gap: 1rem; }
  .card { grid-template-columns: 1fr; }
  .card__media { aspect-ratio: 3 / 2; }
  .card__body { padding: .8rem .9rem .9rem; }
}

/* --------------------------------------------------- the Reg Z pay unit ---
   One container, four things: the payment, the note rate, the APR, and the
   estimate language. They are never separated, and nothing here is
   collapsible. */
.pay {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--paper-alt); padding: .8rem .85rem; margin-block: var(--block-y);
}
.pay__lanes { display: grid; gap: .5rem; margin: 0 0 .6rem; }
.pay__lane { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm); padding: .55rem .7rem; }
.pay__lane--dark { background: var(--paper-deep); color: var(--ink-soft); }
.pay__prog { font: 700 .75rem/1 var(--font-ui); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 .2rem; }
.pay__amt { font: 700 1.25rem/1.15 var(--font-ui); margin: 0; }
.pay__terms { font: .78rem/1.4 var(--font-ui); color: var(--ink-soft); margin: .15rem 0 0; }
.pay__terms b { color: var(--ink); font-weight: 600; }
.pay__why { font: .78rem/1.45 var(--font-ui); color: var(--ink-soft); margin: .2rem 0 0; }
.pay__regz { font: .74rem/1.5 var(--font-ui); color: var(--ink-soft); margin: 0; }
@media (min-width: 700px) { .pay__lanes { grid-template-columns: repeat(3, 1fr); } }

/* ------------------------------------------------------------ filters ---
   Collapsed by default. The bar is a compact sticky strip carrying the active
   filter count and the result count; the panel opens as an overlay sheet and
   never pushes the results down the page.

   The bar's containing block must be the tall one. `position:sticky` is bound
   by its containing block, and pinning it to a 268px mount div means it
   releases after 44px of scrolling and looks exactly like a bar that was never
   sticky. .results is the containing block on purpose. */
.results { position: relative; }
.flt {
  position: sticky; top: var(--nav-h); z-index: 120;
  display: flex; align-items: center; gap: .5rem;
  background: var(--paper); border-bottom: 1px solid var(--line);
  padding: .45rem 0;
}
.flt__btn {
  min-height: var(--tap); padding: 0 .9rem; cursor: pointer;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm);
  font: 600 .9rem/1 var(--font-ui); color: var(--ink);
  display: inline-flex; align-items: center; gap: .4rem;
}
.flt__btn[aria-expanded="true"] { background: var(--brand-wash); border-color: var(--brand); }
/* `display:inline-flex` beats the `hidden` attribute, so the empty badge
   rendered as a filled dot with no number in it — a control reporting a count
   it did not have. The attribute selector has to win. */
.flt__n[hidden] { display: none; }
.flt__n {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 1.35em; height: 1.35em; padding: 0 .3em; border-radius: 999px;
  background: var(--brand); color: var(--paper); font-size: .72rem; font-weight: 700;
}
.flt__count { margin-left: auto; font: .85rem/1 var(--font-ui); color: var(--ink-soft); }
.flt__clear { background: none; border: 0; color: var(--brand-deep); font: 600 .82rem/1 var(--font-ui); cursor: pointer; min-height: var(--tap); }

.sheet[hidden] { display: none; }
.sheet {
  position: fixed; inset: 0; z-index: 300;
  display: grid; grid-template-rows: 1fr auto;
}
.sheet__scrim { background: rgba(42,35,32,.45); border: 0; width: 100%; height: 100%; cursor: pointer; }
.sheet__panel {
  background: var(--paper); border-top-left-radius: 14px; border-top-right-radius: 14px;
  max-height: 82svh; overflow-y: auto; overscroll-behavior: contain;
  padding: .75rem var(--gutter) calc(env(safe-area-inset-bottom) + 1rem);
  box-shadow: 0 -10px 30px rgba(42,35,32,.22);
}
.sheet__head { display: flex; align-items: center; justify-content: space-between; gap: 1rem; position: sticky; top: 0; background: var(--paper); padding-block: .3rem .6rem; }
.sheet__close { min-height: var(--tap); min-width: var(--tap); border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--paper); font: 600 .9rem/1 var(--font-ui); cursor: pointer; }
.sheet__grp { border: 0; margin: 0 0 1rem; padding: 0; }
.sheet__grp legend { font: 700 .78rem/1 var(--font-ui); letter-spacing: .04em; text-transform: uppercase; color: var(--ink-soft); padding: 0 0 .45rem; }
.chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.chip { position: relative; }
.chip input { position: absolute; opacity: 0; pointer-events: none; }
.chip span {
  display: inline-flex; align-items: center; min-height: var(--tap); padding: 0 .8rem;
  border: 1px solid var(--line); border-radius: 999px; cursor: pointer;
  font: 500 .9rem/1 var(--font-ui); background: var(--paper);
}
.chip input:checked + span { background: var(--brand); color: var(--paper); border-color: var(--brand); }
.chip input:focus-visible + span { outline: 3px solid var(--focus); outline-offset: 2px; }
.sheet__apply { position: sticky; bottom: 0; background: var(--paper); padding-top: .6rem; }
@media (min-width: 900px) {
  .sheet { grid-template-rows: 1fr; place-items: center; }
  .sheet__panel { max-width: 46rem; border-radius: 14px; max-height: 80vh; }
}

/* --------------------------------------------------------------- misc --- */
.grid-2 { display: grid; gap: 1rem; }
@media (min-width: 760px) { .grid-2 { grid-template-columns: 1fr 1fr; } }
.tiles { display: grid; gap: .7rem; list-style: none; margin: 0; padding: 0; }
@media (min-width: 640px) { .tiles { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); } }
.tile { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--paper); position: relative; }
.tile img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; background: var(--paper-alt); }
.tile__body { padding: .6rem .75rem .75rem; }
.tile__h { font: 600 1.02rem/1.25 var(--font-ui); margin: 0 0 .15rem; }
.tile__h a { color: var(--ink); text-decoration: none; }
.tile__h a::after { content: ""; position: absolute; inset: 0; }
.tile__meta { font: .82rem/1.4 var(--font-ui); color: var(--ink-soft); margin: 0; }

.how { counter-reset: how; list-style: none; margin: 0 0 var(--block-y); padding: 0; }
.how li { position: relative; counter-increment: how; padding-left: 2.4rem; margin-bottom: .85rem; }
.how li::before {
  content: counter(how); position: absolute; left: 0; top: .1rem;
  width: 1.75rem; height: 1.75rem; border-radius: 999px;
  display: grid; place-items: center;
  background: var(--brand-wash); color: var(--brand-deep);
  font: 700 .85rem/1 var(--font-ui);
}

.showall { margin-top: .8rem; }
.is-hidden { display: none !important; }
.note { background: var(--accent-wash); border-left: 3px solid var(--accent); padding: .7rem .85rem; border-radius: var(--radius-sm); font-size: .92rem; }
.empty { padding: 2rem 0; color: var(--ink-soft); }
.ratelist { list-style: none; margin: 0 0 var(--block-y); padding: 0; font: .88rem/1.55 var(--font-ui); }
.ratelist li { padding: .55rem 0; border-bottom: 1px solid var(--line); }
.ratelist li:last-child { border-bottom: 0; }
.cmp__pick { display: flex; align-items: center; gap: .5rem; min-height: var(--tap); cursor: pointer; }
.cmp__pick input { width: 20px; height: 20px; flex: 0 0 auto; }
.cmp__row.is-hidden { display: none; }
.tbl { width: 100%; border-collapse: collapse; font: .9rem/1.45 var(--font-ui); }
.tbl th, .tbl td { text-align: left; padding: .5rem .6rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.tbl th { font-weight: 600; color: var(--ink-soft); }
.scrollx { overflow-x: auto; -webkit-overflow-scrolling: touch; }
/* The lead photograph on a community or plan page. Capped, and cropped rather
   than letterboxed: the source renders are 4:3, and at 1200px wide that is
   900px of image before a reader reaches a single fact about the place. */
.leadimg {
  width: 100%; aspect-ratio: 16 / 9; max-height: 46svh; object-fit: cover;
  border-radius: var(--radius); background: var(--paper-alt);
  margin-block: 0 var(--block-y);
}
.leadvid { width: 100%; aspect-ratio: 16 / 9; max-height: 46svh;
  border-radius: var(--radius); background: var(--paper-deep); margin-block: 0 var(--block-y); }

/* ---------------------------------------------------------------- form --- */
.form { display: grid; gap: .85rem; max-width: var(--measure); }
.field label { display: block; font: 600 .85rem/1.3 var(--font-ui); margin-bottom: .25rem; }
.field input, .field select, .field textarea {
  width: 100%; min-height: var(--tap); padding: .55rem .7rem;
  font: 1rem/1.4 var(--font-ui); color: var(--ink);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-sm);
}
.field textarea { min-height: 6rem; resize: vertical; }
.field__hint { font: .78rem/1.4 var(--font-ui); color: var(--ink-soft); margin: .2rem 0 0; }
.field--check { display: flex; gap: .6rem; align-items: flex-start; }
.field--check input { width: 22px; min-height: 22px; margin-top: .18rem; flex: 0 0 auto; }
.field--check label { font-weight: 400; font-size: .9rem; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form__msg { font: 600 .92rem/1.45 var(--font-ui); padding: .6rem .75rem; border-radius: var(--radius-sm); }
.form__msg--ok { background: var(--accent-wash); color: var(--accent); }
.form__msg--err { background: var(--brand-wash); color: var(--warn); }

/* -------------------------------------------------------------- footer --- */
.ft { background: var(--paper-deep); border-top: 1px solid var(--line); padding-block: var(--section-y); margin-top: var(--section-y); }
.ft__grid { display: grid; gap: 1.6rem; }
.ft__h { font: 700 .78rem/1 var(--font-ui); letter-spacing: .05em; text-transform: uppercase; color: var(--ink-soft); margin: 0 0 .7rem; }
.ft__name { font: 600 1.05rem/1.3 var(--font-ui); margin: 0 0 .5rem; }
.ft__role { font-weight: 400; font-size: .85rem; color: var(--ink-soft); }
.ft__big { font: 700 1.15rem/1.2 var(--font-ui); text-decoration: none; }
.ft__links { list-style: none; margin: 0; padding: 0; }
.ft__links a { display: flex; align-items: center; min-height: var(--tap); font-family: var(--font-ui); font-size: .95rem; }
.ft__eho { margin: 0 0 .6rem; }
.ft__eho img { width: 44px; height: auto; }
.ft__disclosure { font: 600 .8rem/1.55 var(--font-ui); margin: 0 0 .5rem; }
.ft__builder, .ft__asof { font: .78rem/1.55 var(--font-ui); color: var(--ink-soft); margin: 0 0 .5rem; }
.ft__fine { font: .78rem/1.5 var(--font-ui); margin: .4rem 0 0; }
@media (min-width: 820px) {
  .ft__grid { grid-template-columns: 1fr 1fr 1.4fr; gap: 2rem; }
}
