/* Listing site v4, 2026-09-23. Rebuilt on a fixed system after the reference capture.
   The rules, and the reason for each, are the whole point of this file:
     1. FIXED sizes on a four step scale. No clamp() anywhere. Fluid type lands on a different
        fractional pixel at every viewport width, which is where alignment drift comes from.
     2. ONE line height ratio for display, 1.2, and one for body, 1.55.
     3. ONE container width. Everything hangs off the same two edges.
     4. Display type is CENTRED. A centred heading cannot fail to line up with anything.
     5. Margins are 0, 8, 16 or 24. Section padding carries the vertical rhythm.
   Empire Team's palette and display face, read from their live site: red #C12029, Playfair.
   No inline styles or handlers: the studio ships a strict CSP. */

@font-face { font-family: "Playfair Display"; src: url("fonts/playfair-display.woff2") format("woff2");
  font-weight: 400 700; font-display: optional; }
@font-face { font-family: "Inter"; src: url("fonts/inter-var.woff2") format("woff2");
  font-weight: 100 900; font-display: optional; }

:root {
  /* Empire Team red, sampled from their own primary lockup, not guessed from the brokerage */
  --red: #c1272d;
  --red-dark: #9b1f24;
  --ink: #111111;
  --body: #4a4a4a;
  --mute: #767676;
  --line: #e4e4e4;
  --line-2: #c8c8c8;
  --paper: #ffffff;
  --paper-2: #f7f6f4;
  --black: #0a0a0a;
  --display: "Playfair Display", Georgia, "Times New Roman", serif;
  --sans: "Inter", ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  /* the scale. four display steps and two text steps, and nothing else is allowed */
  --t1: 56px;   /* page title */
  --t2: 32px;   /* section title */
  --t3: 28px;   /* subsection */
  --t4: 20px;   /* lead */
  --tb: 16px;   /* body */
  --tl: 13px;   /* label, above our 12px floor */
  --lh-display: 1.2;
  --lh-body: 1.55;
  --pad: 88px;  /* every section, top and bottom */
  --gut: 32px;
}
@media (max-width: 860px) { :root { --t1: 40px; --t2: 28px; --t3: 24px; --t4: 18px; --pad: 56px; --gut: 20px; } }
@media (max-width: 520px) { :root { --t1: 32px; --t2: 24px; --t3: 21px; --pad: 44px; } }

* { box-sizing: border-box; min-width: 0; }
body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--sans);
  font-size: var(--tb); line-height: var(--lh-body); -webkit-font-smoothing: antialiased; }
img { max-width: 100%; height: auto; display: block; }
a { color: var(--red); }
:focus-visible { outline: 2px solid var(--red); outline-offset: 3px; }
.wrap { max-width: 1200px; margin: 0 auto; padding: 0 var(--gut); }

h1, h2, h3, h4 { font-family: var(--display); font-weight: 400; line-height: var(--lh-display);
  letter-spacing: normal; margin: 0 0 8px; text-align: center; }
h1 { font-size: var(--t1); }
h2 { font-size: var(--t2); }
h3 { font-size: var(--t3); }
h4, .h4 { font-size: var(--t4); }
p { margin: 0; }
p + p { margin-top: 16px; }

/* ---------- demo label. Loud on purpose. ---------- */
.demobar { margin: 0; background: var(--red); color: #fff; text-align: center;
  padding: 10px 20px; font-size: var(--tl); font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; }

/* ---------- header: a black utility strip, then a white nav, then the photograph ----------
   The arrangement the category uses. The agent and their phone sit above everything, the
   brokerage mark and the sections sit on white, and the photograph starts underneath. */
/* The header runs wider than the page body. A 1200px container leaves the corners of a
   wide screen empty, which is what made the top look bare. */
.utility .wrap, .bar .wrap { max-width: 1560px; }
.utility { background: var(--black); color: #cfcfcf; }
.utility .wrap { display: flex; align-items: center; gap: 20px; min-height: 44px;
  flex-wrap: wrap; justify-content: space-between; }
.utility .who { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.utility .meta { margin: 0; font-size: var(--tl); letter-spacing: .12em; text-transform: uppercase;
  color: #8f8f8f; }
.utility .who { margin: 0; font-size: var(--tl); font-weight: 600; letter-spacing: .04em; }
.utility a { color: #fff; text-decoration: none; font-size: var(--tl); font-weight: 600;
  display: inline-flex; align-items: center; min-height: 44px; }
.utility a:hover { color: var(--red); }

.bar { position: sticky; top: 0; z-index: 60; background: var(--paper);
  border-bottom: 1px solid var(--line); }
/* Wide: one row, mark left, sections centred, button right. Narrow: the mark and the button
   keep a row of their own and the sections sit underneath. Done with flex rather than grid
   rows, because a grid row here gets sized against the bar's minimum height and collapses. */
/* No min-height here. A wrapping flex container with a fixed minimum height squeezes both
   lines into that height and draws them on top of each other. Padding sets the height instead,
   and the bar grows when the sections need a second line. */
.bar .wrap { display: flex; align-items: center; align-content: center;
  column-gap: 20px; row-gap: 2px; flex-wrap: wrap; padding-block: 14px; }
.bar .mark { margin: 0; font-family: var(--display); font-size: var(--t4);
  letter-spacing: .02em; white-space: nowrap; line-height: 1.15; }
/* the team is the brand, the brokerage is the line the state requires under it */
.bar .mark span { display: block; font-family: var(--sans); font-size: var(--tl);
  font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--mute);
  margin-top: 4px; }
.bar .mark.haslogo { line-height: 0; }
.bar .mark.haslogo img { height: 38px; width: auto; max-width: 300px; display: block; }
@media (max-width: 620px) { .bar .mark.haslogo img { height: 30px; } }
.utility .team { color: #8f8f8f; }
.utility .team::before { content: "· "; }


/* ---------- buttons ---------- */
.btn { display: inline-flex; align-items: center; justify-content: center; min-height: 48px;
  padding: 0 24px; font-size: var(--tl); font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; text-decoration: none; cursor: pointer; border: 2px solid var(--red);
  background: var(--red); color: #fff; font-family: var(--sans);
  transition: background .18s ease, color .18s ease, border-color .18s ease; }
.btn:hover { background: var(--red-dark); border-color: var(--red-dark); }
.btn.ghost { background: transparent; color: var(--ink); border-color: var(--line-2); }
.btn.ghost:hover { border-color: var(--red); color: var(--red); background: transparent; }

/* ---------- the sections, sitting in the white nav ---------- */
.tabs { display: flex; flex-wrap: wrap; justify-content: center; flex: 1 1 auto; }
.tabs a { padding: 26px 10px 23px; font-size: var(--tl); font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--mute); text-decoration: none; white-space: nowrap;
  border-bottom: 3px solid transparent; }
.tabs a:hover { color: var(--ink); }
.tabs a[aria-selected="true"] { color: var(--ink); border-bottom-color: var(--red); }
@media (max-width: 1340px) { .tabs a { padding: 12px 11px 10px; letter-spacing: .06em; } }

/* When the sections no longer fit beside the mark and the button, they take a line of their
   own underneath. `order` does it without changing the reading order in the markup, which
   still runs mark, sections, button. */
@media (max-width: 1500px) {
  .bar .wrap { padding-block: 12px 2px; justify-content: space-between; }
  .bar .mark { order: 1; }
  .bar .btn { order: 2; }
  .tabs { order: 3; flex: 1 0 100%; justify-content: flex-start; margin-left: -10px; }
}
/* On a phone the brokerage name needs two lines, so the action takes the full width under it
   rather than being squeezed into whatever is left. */
@media (max-width: 620px) {
  .bar .mark { white-space: normal; }
  .bar .btn { flex: 1 0 100%; margin-top: 10px; }
}
@media (max-width: 900px) { .bar { position: static; } .bar .wrap { padding-bottom: 6px; } }

/* ---------- hero: the photograph owns the first screen ----------
   Full viewport height, the way the category does it, with the caption centred on the image
   rather than pinned to the bottom. The scrim is measured, not eyeballed: it holds the title
   above 7:1 even against a pure white photograph, which is the worst case a hero can present.
   A text shadow carries the rest, so the photograph stays bright instead of being flattened. */
.hero { position: relative; height: 100svh; min-height: 540px; max-height: 1000px;
  background: var(--black); overflow: hidden; display: grid; }
.hero > .shot { grid-area: 1 / 1; aspect-ratio: auto; margin: 0; }
.hero img { width: 100%; height: 100%; object-fit: cover; }
.hero::after { content: ""; grid-area: 1 / 1; z-index: 2; pointer-events: none;
  background:
    radial-gradient(78% 52% at 50% 52%, rgba(10,10,10,.72) 0%, rgba(10,10,10,.34) 55%, transparent 78%),
    linear-gradient(to bottom, rgba(10,10,10,.55) 0%, transparent 22%),
    linear-gradient(to top, rgba(10,10,10,.82) 0%, transparent 26%); }
.hero-cap { grid-area: 1 / 1; z-index: 3; align-self: center; width: 100%; }
.hero h1, .hero .town, .hero .summary { text-shadow: 0 2px 28px rgba(0,0,0,.72),
  0 1px 3px rgba(0,0,0,.5); }
.hero h1 { color: #fff; margin-bottom: 14px; }
.hero .town { color: rgba(255,255,255,.92); text-align: center; font-size: var(--t4);
  margin: 0 0 22px; }
.hero .rule { width: 260px; height: 1px; background: rgba(255,255,255,.5); margin: 0 auto 22px; }
.hero .summary { color: #fff; text-align: center; font-family: var(--display);
  font-size: var(--t3); line-height: var(--lh-display); margin: 0; }
@media (max-width: 860px) { .hero { min-height: 460px; } }
@media (max-width: 620px) {
  .hero-cap .wrap { padding-left: 44px; padding-right: 44px; }
  .hero .summary { font-family: var(--sans); font-size: var(--tb); line-height: var(--lh-body);
    color: rgba(255,255,255,.92); }
  .hero .rule { width: 160px; }
}

/* ---------- section titles, centred with a rule either side ---------- */
.title { display: flex; align-items: center; justify-content: center; gap: 24px; margin-bottom: 40px; }
.title::before, .title::after { content: ""; height: 1px; background: var(--line); flex: 1 1 auto;
  max-width: 180px; }
.title h2 { margin: 0; text-transform: uppercase; letter-spacing: .04em; }

/* ---------- panels ---------- */
.panel { padding: var(--pad) 0; }
.js .panel[hidden] { display: none; }
.panel + .panel { border-top: 1px solid var(--line); }
.prose { max-width: 62ch; margin: 0 auto; color: var(--body); }
.lead { font-family: var(--display); font-size: var(--t3); line-height: var(--lh-display);
  text-align: center; max-width: 30ch; margin: 0 auto 24px; color: var(--ink); }
/* A lead that runs long is a paragraph wearing a heading's clothes. Prose gets prose width. */
.lead.long { font-size: var(--t4); max-width: 54ch; font-family: var(--sans);
  line-height: var(--lh-body); color: var(--body); }
.center { text-align: center; }
.stack { margin-top: 24px; }

/* ---------- three column lists: features, amenities, places ---------- */
.three { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 40px;
  max-width: 1000px; margin: 0 auto; }
.three li { list-style: none; padding: 11px 0; border-bottom: 1px solid var(--line);
  color: var(--body); }
.three ul { margin: 0; padding: 0; }
.tick li::before { content: "\2713"; color: var(--red); font-weight: 700; margin-right: 10px; }
.three a { color: var(--ink); text-decoration: none; display: block; }
.three a:hover { color: var(--red); }
.three a b { font-weight: 600; }
.three a span { display: block; color: var(--mute); font-size: var(--tl); margin-top: 2px; }
.three a[target] b::after { content: " \2197"; color: var(--red); font-weight: 400; }
@media (max-width: 860px) { .three { grid-template-columns: repeat(2, minmax(0,1fr)); gap: 0 24px; } }
@media (max-width: 520px) { .three { grid-template-columns: 1fr; } }

/* ---------- area tiles: prose, so they need prose measure and real gaps ---------- */
.tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 40px 48px;
  max-width: 1000px; margin: 0 auto; }
.tiles h3 { text-align: left; margin-bottom: 12px; }
.tiles p { color: var(--body); max-width: 46ch; }
@media (max-width: 720px) { .tiles { grid-template-columns: 1fr; gap: 32px; } }

/* ---------- key numbers: a centred stack, never a six cell grid ---------- */
.keys { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line); max-width: 1000px; margin: 0 auto; }
.keys div { background: var(--paper); padding: 24px 16px; text-align: center; }
.keys b { display: block; font-family: var(--display); font-size: var(--t3);
  line-height: var(--lh-display); font-variant-numeric: tabular-nums; }
.keys span { display: block; font-size: var(--tl); letter-spacing: .12em; text-transform: uppercase;
  color: var(--mute); margin-top: 8px; }
@media (max-width: 520px) { .keys { grid-template-columns: repeat(2, minmax(0,1fr)); } }
/* Below this a two column cell is too narrow for "4 full, 1 half" and the value wraps, which
   drags its label off the line its neighbour sits on. One column cannot misalign. */
@media (max-width: 400px) { .keys { grid-template-columns: 1fr; } }

/* ---------- photographs and slots ---------- */
.shots { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.shot { position: relative; aspect-ratio: 3 / 2; overflow: hidden; background: var(--paper-2);
  margin: 0; }
.shot.wide { grid-column: 1 / -1; aspect-ratio: 2 / 1; }
.shot img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 720px) { .shots { grid-template-columns: 1fr; }
  .shot, .shot.wide { aspect-ratio: 3 / 2; } }

/* An empty photograph slot, done the way the MLS does it: a real photograph behind, greyed
   right back, with a label over it saying what belongs there. It reads as a held place rather
   than as a missing file, and the layout is already the finished layout. */
.slot { position: absolute; inset: 0; display: grid; place-items: center; text-align: center;
  background: var(--paper-2); overflow: hidden; }
.slot .ghost { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: .28; }
.slot::after { content: ""; position: absolute; inset: 14px; border: 1px solid rgba(17,17,17,.16); }
.slot p { position: relative; z-index: 2; max-width: 32ch; padding: 0 16px; }
.slot span { display: block; font-size: var(--tl); letter-spacing: .16em; text-transform: uppercase;
  color: var(--red); font-weight: 700; margin-bottom: 8px; }
.slot b { display: block; font-family: var(--display); font-weight: 400; font-size: var(--t3);
  line-height: var(--lh-display); color: var(--ink); }
.hero .slot { background: var(--black); place-items: start center; padding-top: 96px; }
.hero .slot .ghost { opacity: .3; }
.hero .slot::after { inset: 26px; border-color: rgba(255,255,255,.18); }
.hero .slot b { color: rgba(255,255,255,.88); }
.hero .slot span { color: #fff; }
.agent .face .slot { border-radius: 50%; }
.agent .face .slot b { font-size: var(--t4); }

/* The MLS previews look like photographs on a phone, where two columns blow them up to
   nearly full width. So they are labelled twice: a banner above the sheet that cannot be
   scrolled past, and a tag on every single one. Nobody should mistake these for the photos. */
.banner { background: var(--red); color: #fff; text-align: center; padding: 14px 18px;
  font-size: var(--tl); font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  margin: 0 0 16px; line-height: var(--lh-body); }
.sheet { display: grid; grid-template-columns: repeat(auto-fill, minmax(133px, 1fr)); gap: 8px; }
.thumb { position: relative; margin: 0; }
.thumb img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; background: var(--paper-2);
  border: 1px solid var(--line); }
.thumb::after { content: "MLS preview"; position: absolute; left: 6px; bottom: 6px;
  background: rgba(10,10,10,.82); color: #fff; font-size: 12px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; padding: 3px 7px; line-height: 1.3; }
@media (max-width: 520px) { .sheet { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.note { font-size: var(--tl); color: var(--body); max-width: 60ch; margin: 24px auto 0;
  text-align: center; line-height: var(--lh-body); }

/* ---------- numbers table ---------- */
.rows { width: 100%; border-collapse: collapse; max-width: 760px; margin: 0 auto; }
.rows th, .rows td { text-align: left; padding: 16px 8px; border-bottom: 1px solid var(--line); }
.rows th { font-weight: 400; color: var(--mute); width: 50%; }
.rows td { font-family: var(--display); font-size: var(--t4); font-variant-numeric: tabular-nums; }

/* ---------- payment estimate ---------- */
.calc { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 32px;
  max-width: 780px; margin: 0 auto; }
.calc label { display: flex; flex-direction: column; gap: 8px; font-size: var(--tl);
  font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--mute); }
.calc input { font: inherit; font-family: var(--sans); font-size: var(--tb); min-height: 50px;
  padding: 12px 14px; border: 1px solid var(--line-2); background: var(--paper); color: var(--ink);
  letter-spacing: normal; text-transform: none; }
.calc input:focus { border-color: var(--red); }
.calc .out { grid-column: 1 / -1; border-top: 2px solid var(--red); padding-top: 24px;
  text-align: center; }
.calc .out b { display: block; font-family: var(--display); font-size: var(--t1);
  line-height: var(--lh-display); font-variant-numeric: tabular-nums; }
.calc .out span { display: block; font-size: var(--tl); letter-spacing: .12em;
  text-transform: uppercase; color: var(--mute); margin-top: 8px; }
.calc .breakdown { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 16px; text-align: center; color: var(--body); font-size: var(--tl); }
@media (max-width: 620px) { .calc { grid-template-columns: 1fr; }
  .calc .breakdown { grid-template-columns: 1fr; gap: 8px; } }

/* ---------- documents and open house ---------- */
.docs { list-style: none; padding: 0; margin: 0 auto; max-width: 620px; }
.docs li { padding: 16px 0; border-bottom: 1px solid var(--line); display: flex; gap: 16px;
  align-items: center; justify-content: space-between; flex-wrap: wrap; }
.docs b { font-family: var(--display); font-size: var(--t4); font-weight: 400; }
.openhouse { text-align: center; }
.openhouse .when { font-family: var(--display); font-size: var(--t3); line-height: var(--lh-display); }

/* ---------- agent ---------- */
.agent { text-align: center; max-width: 520px; margin: 0 auto; }
.agent .face { width: 180px; height: 180px; margin: 24px auto; position: relative;
  border-radius: 50%; overflow: hidden; }
.agent .face .slot { border-radius: 50%; }
.agent .face .slot::after { inset: 8px; border-radius: 50%; }
.agent .face img { width: 100%; height: 100%; object-fit: cover; }
.agent .role { color: var(--mute); margin: 0; }
.agent .lines { margin-top: 24px; display: flex; gap: 12px; justify-content: center;
  flex-wrap: wrap; }

/* ---------- form ---------- */
.form { display: grid; gap: 16px; max-width: 560px; margin: 0 auto; }
.form label { display: flex; flex-direction: column; gap: 8px; font-size: var(--tl);
  font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: var(--mute); }
.form input, .form textarea { font: inherit; font-family: var(--sans); font-size: var(--tb);
  min-height: 50px; padding: 12px 14px; border: 1px solid var(--line-2); background: var(--paper);
  color: var(--ink); letter-spacing: normal; text-transform: none; }
.form textarea { min-height: 120px; resize: vertical; }
.form input:focus, .form textarea:focus { border-color: var(--red); }
.form .btn { justify-self: center; }
.hp { position: absolute; left: -9999px; }

/* ---------- the mark ----------
   Two placements only. Above the agent, where it stands for who you are about to call, and
   as the sign-off at the foot of the page. A single letter used more often than that stops
   reading as a mark and starts reading as wallpaper. */
.emark { display: block; margin: 0 auto; }
.emark.sm { width: 44px; height: 44px; margin-bottom: 16px; }
.emark.lg { width: 64px; height: 64px; margin-bottom: 32px; }

/* ---------- footer ---------- */
.foot { background: var(--black); color: #a8a8a8; padding: var(--pad) 0; font-size: var(--tl); }
.foot .wrap { text-align: center; }
.foot p { max-width: 72ch; margin: 0 auto; line-height: var(--lh-body); }
.foot p + p { margin-top: 16px; }
.foot strong { color: #fff; }
.foot nav { display: flex; flex-wrap: wrap; gap: 8px 24px; justify-content: center;
  margin-bottom: 24px; }
.foot nav a { color: #d8d8d8; text-decoration: none; letter-spacing: .1em;
  text-transform: uppercase; font-weight: 600;
  /* a link on its own line is a target, not prose, so it gets a real hit area */
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 4px; }
.foot nav a:hover { color: #fff; text-decoration: underline; }
.foot .eho { display: flex; align-items: flex-start; gap: 16px; margin-top: 24px; padding-top: 24px;
  border-top: 1px solid #262626; text-align: left; }
.foot .eho svg { flex: none; color: #8a8a8a; }
.skip { position: absolute; left: -9999px; }
.skip:focus { left: 16px; top: 16px; z-index: 100; background: var(--red); color: #fff; padding: 12px 16px; }
