/* ===== FONTS =====
   Self-hosted from R2 rather than fetched from Google. Three reasons, in order
   of how much they cost: a third-party font host is a second DNS lookup, a
   second TLS handshake and a dependency whose downtime is invisible to us; the
   files are served with max-age=31536000, immutable, which Google caps far
   lower; and nothing about a visitor is announced to a third party.

   These are the same subsetted WOFF2 files Google serves - same unicode-range
   splits, so a page still downloads only the latin range it needs - copied to
   c21-branding/fonts/ and served from our own domain. Regenerate them with the
   manifest rather than editing by hand: the file names encode style, weight
   and subset, and a mismatch here fails silently as a fallback face.
   ================= */
@font-face {
  font-family: 'Allura';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/allura/allura-normal-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Allura';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/allura/allura-normal-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-italic-300-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 300;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-italic-300-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-italic-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-italic-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-italic-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: italic;
  font-weight: 500;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-italic-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-normal-300-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 300;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-normal-300-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-normal-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-normal-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-normal-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Cormorant Garamond';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/cormorant-garamond/cormorant-garamond-normal-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/jost/jost-normal-300-700-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Jost';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/jost/jost-normal-300-700-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* =====================================================================
   CLASSIC LIGHT — Century 21 Masters agent template
   Mirror of https://library.c21masters.com/global-css/classic-light.css
   --------------------------------------------------------------------
   warm paper ground, Cormorant Garamond over Jost.

   Derived from "Classic Luxury Light". One design in three themes: classic-light,
   classic-clean and classic-dark share partials/classic/ and
   global-js/classic.js, and differ only in this file.

   Dropped from the source, because nothing renders them any more:
   STATS  (agent highlight), FOOTER. The .svc rules went with the services page.
   Fonts are loaded by head-meta.njk, not here.
   ===================================================================== */

/* ---- Design tokens ------------------------------------------------- */
:root {
  /* surfaces — light ground, with espresso retained for dark bands */
  --obsidian:   #0B0A08;       /* deep espresso — dark bands (footer, hero overlay) */
  --ink:        #14120E;       /* primary TEXT colour + dark contrast on gold */
  --ink-2:      #1B1813;
  --ink-3:      #221E18;
  --ivory:      #F4F0E7;       /* light text on dark bands */
  --ivory-2:    #EBE5D8;
  --paper:      #F4F0E7;       /* page background — warm paper */
  --paper-2:    #EBE4D6;       /* deeper sand — alternating "interlude" band */
  --card:       #FBF8F1;       /* raised light card */

  /* accent + text (tuned for a light ground) */
  --champagne:      #C7A763;   /* gold — large display + dark-band accents */
  --champagne-soft: #DCC495;
  --brass:          #997A3D;   /* deeper gold — small labels & lines on light */
  --stone:          #5E574B;   /* muted text on light */
  --stone-dim:      #8A8273;   /* faint text on light */
  --stone-dark:     #6A6256;   /* secondary muted text on light */

  /* lines */
  --line-gold:  rgba(153,122,61,0.34);   /* brass hairline — reads on light */
  --line-light: rgba(20,18,14,0.13);     /* default hairline on light surfaces */
  --line-dark:  rgba(20,18,14,0.16);

  /* type */
  --display: "Cormorant Garamond", Georgia, serif;
  --sans: "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* fluid scale */
  /* Was clamp(3.2rem, 1.4rem + 7.6vw, 9.5rem): 132px at 1440 and 152px at the
     ceiling, which took the headline to four and five lines and left the
     paragraph under the fold. 87px at 1440, 100px at the ceiling. */
  --fs-hero:    clamp(2.5rem, 1.3rem + 4.6vw, 6.25rem);
  --fs-display: clamp(2.6rem, 1.4rem + 4.6vw, 6rem);
  --fs-h2:      clamp(2rem, 1.3rem + 2.6vw, 3.6rem);
  --fs-h3:      clamp(1.5rem, 1.1rem + 1.4vw, 2.2rem);
  --fs-lead:    clamp(1.05rem, 0.95rem + 0.5vw, 1.3rem);
  --fs-body:    clamp(1rem, 0.96rem + 0.2vw, 1.08rem);
  --fs-label:   0.72rem;

  /* layout */
  --rail: 56px;                  /* width of the architectural margin rail */
  --pad-x: clamp(1.4rem, 5vw, 7rem);
  --maxw: 1320px;
  --nav-h: 88px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-slow: cubic-bezier(0.16, 1, 0.3, 1);
}

/* ---- Reset --------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--nav-h);
  -webkit-text-size-adjust: 100%;
}

body {
  font-family: var(--sans);
  font-size: var(--fs-body);
  font-weight: 300;
  line-height: 1.7;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; background: none; border: none; }
ul { list-style: none; }

::selection { background: var(--champagne); color: var(--ink); }

/* A focus ring is a UI indicator and needs 3:1 against what it sits on.
   --champagne is the display gold: 2.02:1 on the page and 1.81:1 on a cream
   card, so the ring was there but not reliably visible. --brass is the deeper
   gold this template already keeps for small marks on light grounds, and it
   clears 3:1 everywhere the ring appears - page 3.54:1, cream card 3.18:1,
   dark band 4.90:1. Two pixels rather than one so the ring reads as intent. */
:focus-visible {
  outline: 2px solid var(--brass);
  outline-offset: 4px;
  /* The nav sits over the agent's hero photo, so no single ring colour can be
     relied on: --brass measured 1.04:1 against one sky. This adds a light halo
     just outside the brass ring, so whichever tone the photo swallows, the
     other one shows - the same two-tone trick Chromium's default ring uses.
     The photo is different on all 582 sites, so a fixed colour cannot win. */
  box-shadow: 0 0 0 6px rgba(244, 240, 231, 0.92);
}
/* An iframe takes focus as an element but never matched the rule above, so the
   map on the contact page was a stop with no visible indicator. */
iframe:focus {
  outline: 2px solid var(--brass);
  outline-offset: 2px;
}

/* ---- Typography helpers ------------------------------------------- */
.display { font-family: var(--display); font-weight: 300; line-height: 1; letter-spacing: -0.01em; }
.display em { font-style: italic; font-weight: 400; }

.eyebrow {
  font-family: var(--sans);
  font-size: var(--fs-label);
  font-weight: 400;
  letter-spacing: 0.36em;
  text-transform: uppercase;
  color: var(--brass);
  display: inline-flex;
  align-items: center;
  gap: 0.85rem;
}
.eyebrow.is-centered { justify-content: center; }

/* ---- Dark bands ---------------------------------------------------- */
/* The hero (over a dark photo) and footer stay dark grounds: keep their
   text light and restore the muted tokens. */
.hero, .footer {
  color: var(--ivory);
  --stone:      #A39B8C;
  --stone-dim:  #756D60;
  --line-light: rgba(244,240,231,0.12);
  --line-gold:  rgba(199,167,99,0.30);
}
.hero .eyebrow, .footer .eyebrow { color: var(--champagne); }
.hero .btn { --c: var(--ivory); }

.lead {
  font-size: var(--fs-lead);
  color: var(--stone);
  font-weight: 300;
  max-width: 46ch;
}

/* ---- Layout primitives -------------------------------------------- */
.shell { padding-left: var(--rail); }       /* leaves room for the margin rail */
.wrap  { width: 100%; max-width: var(--maxw); margin: 0 auto; padding-inline: var(--pad-x); }

.block { padding-block: clamp(5rem, 10vw, 9.5rem); }
.block--tight { padding-block: clamp(3.5rem, 7vw, 6rem); }

.section-ivory { background: var(--paper-2); color: var(--ink); }
.section-ivory .lead { color: var(--stone-dark); }
.section-ivory .eyebrow { color: var(--brass); }

/* ---- Architectural margin rail (signature) ------------------------ */
.rail {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--rail);
  z-index: 80;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding-block: 1.6rem;
  border-right: 1px solid var(--line-light);
  mix-blend-mode: difference;       /* keeps it legible over any section */
  pointer-events: none;
}
.rail__mark {
  font-family: var(--display);
  font-size: 1.5rem;
  letter-spacing: 0.05em;
  color: #fff;
  pointer-events: auto;
}
.rail__meta {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 0.62rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: #fff;
  opacity: 0.8;
}
.rail__line {
  flex: 1;
  width: 1px;
  background: linear-gradient(to bottom, transparent, rgba(255,255,255,0.5), transparent);
  margin-block: 1.4rem;
}

/* ---- Navigation ---------------------------------------------------- */
.nav {
  position: fixed;
  top: 0; left: var(--rail); right: 0;
  height: var(--nav-h);
  z-index: 70;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-inline: var(--pad-x);
  transition: background 0.5s var(--ease), height 0.5s var(--ease),
              border-color 0.5s var(--ease), backdrop-filter 0.5s var(--ease);
  border-bottom: 1px solid transparent;
}
.nav.is-stuck {
  height: 68px;
  background: rgba(244,240,231,0.82);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-bottom: 1px solid var(--line-light);
}
.brand { display: flex; align-items: baseline; gap: 0.6rem; }
.brand__word {
  font-family: var(--display);
  font-size: 1.7rem;
  letter-spacing: 0.12em;
  line-height: 1;
}
.brand__tag {
  font-size: 0.56rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--stone);
}

/* ---- Brand logo lockup (CENTURY 21® Masters) --------------------- */
.logo {
  --ls: 1rem;
  display: inline-flex; flex-direction: column; align-items: center;
  line-height: 1; color: var(--champagne);
}
.logo__word {
  font-family: var(--sans); font-weight: 400;
  font-size: var(--ls); letter-spacing: 0.1em; text-transform: uppercase;
  white-space: nowrap;
}
.logo__masters { font-weight: 600; }
.logo__sub {
  font-family: "Allura", cursive; font-weight: 400;
  font-size: calc(var(--ls) * 2.05); line-height: 0.62;
  letter-spacing: 0; text-transform: none;
  margin-top: calc(var(--ls) * 0.16); color: var(--champagne);
}
.logo--nav { --ls: 0.74rem; }
/* Brand lockup reads as deep brass on the light nav; champagne on dark grounds */
.logo--nav, .logo--nav .logo__sub { color: var(--brass); }
.nav__cta { padding: 0.85rem 1.4rem; }
.logo--footer { display: flex; width: max-content; --ls: clamp(1.2rem, 2.6vw, 1.8rem); margin-bottom: 0.2rem; }
.logo--pre { --ls: clamp(1.3rem, 4.5vw, 2.4rem); }

.nav__menu { display: flex; align-items: center; gap: clamp(1rem, 1.9vw, 2.2rem); }
.nav__link {
  position: relative;
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--stone);
  padding-block: 0.4rem;
  transition: color 0.4s var(--ease);
}
.nav__link::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 100%; height: 1px;
  background: var(--champagne);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s var(--ease);
}
.nav__link:hover,
.nav__link[aria-current="page"] { color: var(--ink); }
.nav__link:hover::after,
.nav__link[aria-current="page"]::after { transform: scaleX(1); }

/* Homepage: the transparent nav sits over the hero photo, and the top of that
   photo is whatever the agent uploaded — a bright sky as often as a dark
   facade. The light-ground colours below (brass lockup, stone links, brass
   hairline on the CTA) disappeared into the pale ones, so everything in the bar
   goes plain white while the bar is transparent: full-opacity links, white
   brand lockup, white CTA hairline. Once stuck (light bar) the dark-on-paper
   defaults above take over again.
   :has(.hero) rather than a class on <body>: base.njk emits a bare <body> for
   all 18 templates, so the body.home this block used to be keyed on never
   matched and the whole inversion was dead. The hero is the thing that makes
   the treatment necessary and only the homepage has one, so key on it directly
   and keep the fix inside this stylesheet.
   :not(.is-nav-open) leaves the burger overlay its champagne brand, which sits
   on a dark ground and needs no help. */
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__link,
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__link:hover,
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__link[aria-current="page"] { color: #fff; }
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__link::after { background: #fff; }
/* The row's own backdrop while the bar is transparent.
   The links go #fff here (rule above) over whatever the hero photograph
   happens to be, and the hero's own scrim is at its thinnest at the top of the
   frame - 0.45 alpha - because it was built to lift the headline further down.
   A pale sky therefore left white text on near-white: measured on the demo,
   the nav row read at about 1.1:1.
   This gradient is 0.62 at the top and gone by the bottom of the bar, so the
   nav always has something to sit on and the hero is untouched below it. It is
   scoped to the transparent state; the solid bar has a real ground of its own.
   z-index: -1 keeps it behind the links and the mark: .nav is position:fixed
   with a z-index, so it is the stacking context this resolves inside. */
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open)::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: calc(100% + 2.5rem);
  background: linear-gradient(to bottom, rgba(11, 10, 8, 0.62) 0%, rgba(11, 10, 8, 0.56) 62%, rgba(11, 10, 8, 0) 100%);
  pointer-events: none;
  z-index: -1;
}

body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__toggle span { background: #fff; }
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__cta {
  --c: #fff;
  border-color: rgba(255,255,255,0.55);
}
/* .btn:hover's champagne border is only 0,2,0 and would lose to the rule above,
   leaving a white hairline around the gold fill that slides up on hover. */
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__cta:hover { border-color: var(--champagne); }
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .logo--nav,
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .logo--nav .logo__sub { color: #fff; }

/* Mobile menu open: the brand + toggle float above a dark overlay */
.nav.is-nav-open .logo--nav,
.nav.is-nav-open .logo--nav .logo__sub { color: var(--champagne); }

.nav__cta { display: inline-flex; }
.nav__toggle {
  display: none;
  /* 44px is the touch target, not the drawn size: the bars stay 26px wide and
     6px apart, and the extra is padding around them. The other Gold templates
     already sit at 42-44, so this is the set agreeing rather than this one
     growing. */
  width: 44px; height: 44px;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  align-items: flex-end;
}
.nav__toggle span {
  display: block; height: 1px; width: 26px;
  background: var(--ink);
  transition: transform 0.4s var(--ease), opacity 0.3s var(--ease), width 0.4s var(--ease);
}
.nav.is-nav-open .nav__toggle span { background: var(--ivory); }

/* ---- Buttons ------------------------------------------------------- */
.btn {
  --c: var(--ink);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  font-size: 0.74rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--c);
  padding: 1rem 1.9rem;
  border: 1px solid var(--line-gold);
  overflow: hidden;
  isolation: isolate;
  transition: color 0.5s var(--ease), border-color 0.5s var(--ease);
}
.btn::before {
  content: "";
  position: absolute; inset: 0;
  background: var(--champagne);
  transform: translateY(101%);
  transition: transform 0.55s var(--ease);
  z-index: -1;
}
.btn:hover { color: var(--ink); border-color: var(--champagne); }
.btn:hover::before { transform: translateY(0); }
.btn .btn__icon { width: 15px; height: 15px; transition: transform 0.5s var(--ease); }
.btn:hover .btn__icon { transform: translate(3px, -3px); }

.btn--solid { color: var(--ink); border-color: var(--champagne); }
.btn--solid::before { transform: translateY(0); }
.btn--solid:hover::before { transform: translateY(-101%); }
.btn--solid:hover { color: var(--champagne); }

.btn--ghost { color: var(--ink); border-color: var(--line-dark); }
.btn--ghost::before { background: var(--ink); }
.btn--ghost:hover { color: var(--ivory); border-color: var(--ink); }

/* text link with sliding underline */
.tlink {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-size: 0.74rem; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--brass);
  padding-bottom: 4px;
  position: relative;
}
.tlink::after {
  content: ""; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 1px; background: currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform 0.5s var(--ease);
}
.tlink:hover::after { transform: scaleX(1); }
.tlink svg { width: 14px; height: 14px; transition: transform 0.5s var(--ease); }
.tlink:hover svg { transform: translateX(4px); }

/* =====================================================================
   HERO
   ===================================================================== */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  /* The copy sits on the centre of the photograph rather than on its floor.
     min-height rather than height is what makes that safe: a headline long
     enough to fill the frame grows the section instead of being centred out
     of the top of it and clipped by the overflow rule below. */
  align-items: center;
  overflow: hidden;

  /* The band at the foot of the hero that belongs to the scroll indicator.
     The indicator is taken out of flow so it can centre on the section (see
     .hero__scroll), and .hero__inner reserves the same band as bottom
     padding - which is what keeps the centred copy off it without either box
     knowing the other's height. The line is a variable for the same reason:
     .hero__scroll i draws it, and the reservation must not be able to drift
     from the thing it is reserving for. */
  --hero-scroll-line: 46px;
  --hero-scroll-gap: clamp(1.25rem, 3.5vh, 2.5rem);
  --hero-scroll-band: calc(var(--hero-scroll-line) + var(--hero-scroll-gap));
}
.hero__media { position: absolute; inset: 0; z-index: -2; overflow: hidden; }
.hero__media img {
  width: 100%; height: 116%;
  object-fit: cover;
  object-position: center;
  will-change: transform;
}
.hero__media::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(to top, rgba(11,10,8,0.93) 0%, rgba(11,10,8,0.80) 30%, rgba(11,10,8,0.26) 62%, rgba(11,10,8,0.45) 100%);
  z-index: 1;
}
.hero__inner {
  width: 100%;
  /* .hero centres this box, so these two paddings are what the centring is
     measured against: they hold the copy clear of the fixed bar above it and
     of the scroll indicator below it, and they come out within a few pixels
     of each other, which is what puts the copy on the centre line rather
     than a little under it.

     The 2rem above the bar goes fluid on a short viewport. At 480px tall the
     fixed value spent 118px of 480 on padding before the eyebrow, which put
     the last line of the paragraph 5px under the fold on classic-clean. 3vh
     reaches the 2rem cap at 667px tall, so nothing changes on a normal phone
     or above - only the short end gets the room back. */
  padding-top: calc(var(--nav-h) + clamp(0.75rem, 3vh, 2rem));
  padding-bottom: calc(var(--hero-scroll-band) + clamp(0.75rem, 3vh, 2rem));
}
.hero__title {
  font-size: var(--fs-hero);
  /* Out from 16ch with the size coming down. Holding the old measure would
     have made the column narrower in pixels and added lines rather than
     removing them; 20ch is where this title breaks in two. */
  max-width: 20ch;
  /* On .hero__title, not .display - other headings share that class. 1 was
     drawn for a single line at display size; at 87px over two or three it
     sets the lines touching. */
  line-height: 1.06;
  margin-block: 1.6rem 2.2rem;
  /* The headline is agent copy, so its longest word is not known at design
     time. A word with no break opportunity has to break rather than run out
     of the hero, which clips it. Same guard as timeless and aurelia. */
  overflow-wrap: break-word;
}
/* Paragraph, then button, down the same left edge. The two were a
   space-between row, which put the button at the far right of the hero on its
   own: it read as a third element rather than as the paragraph's action, and
   it left the empty shelf under the copy that the QA screenshot marks.

   align-items is flex-start rather than the column default - stretch would
   size the button to the width of the hero. The gap is .hero__title's bottom
   margin, so eyebrow, headline, paragraph and button keep one rhythm. The
   phone-width .btn rule still takes the button full width, as it does for
   every standalone CTA on the site. */
.hero__foot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2.2rem;
}
/* The paragraph sits on the photograph, so it cannot keep .lead's page
   treatment - and on this theme .lead's --stone is a dark brown that only
   works on paper. The hero already remaps it to #A39B8C, which still
   composites to about 2.9:1 over a bright frame at weight 300. Dimmed ivory
   holds ~6:1 and stays a step below the headline. The scrim is left alone. */
.hero__sub {
  max-width: 40ch;
  color: rgba(244, 240, 231, 0.86);
  font-weight: 400;
  line-height: 1.65;
}
/* Bottom centre of the hero, and out of flow to get there.

   In flow it was the second item of .hero's flex row: it sat at the bottom
   right beside the copy, and it took its width out of the copy's measure -
   flex:none and width:auto were there to limit that, and the phone-width rule
   in the responsive block stacked the row to undo it. Positioning it removes
   the cause, so all three of those are gone with it.

   .hero__inner reserves --hero-scroll-band under the copy, which is what
   keeps the two apart at every width - do not put this back in flow without
   taking that reservation out. */
.hero__scroll {
  position: absolute;
  left: 0; right: 0;
  bottom: var(--hero-scroll-gap);
  /* .wrap caps this box at --maxw and centres it with auto margins, which is
     under-defined for an absolutely positioned box spanning left to right and
     is resolved differently by different engines. So the cap comes off and
     the label is centred by justify-content instead; .wrap's padding-inline
     still keeps it off the edge of a phone. */
  max-width: none;
  display: flex; align-items: center; justify-content: center; gap: 0.8rem;
  font-size: 0.62rem; letter-spacing: 0.3em; text-transform: uppercase;
  color: var(--stone);
}
.hero__scroll i {
  display: block; width: 1px; height: var(--hero-scroll-line);
  background: linear-gradient(var(--champagne), transparent);
  animation: drop 2.4s var(--ease) infinite;
}
@keyframes drop {
  0% { transform: scaleY(0); transform-origin: top; }
  40% { transform: scaleY(1); transform-origin: top; }
  60% { transform: scaleY(1); transform-origin: bottom; }
  100% { transform: scaleY(0); transform-origin: bottom; }
}

/* page header (interior pages, no full-bleed hero) */
.phead { position: relative; padding-top: calc(var(--nav-h) + clamp(3rem, 9vw, 7rem)); }
.phead__index { display: none; }
.phead__title { font-size: var(--fs-display); max-width: 18ch; position: relative; z-index: 1; }

/* =====================================================================
   INTRO SPLIT
   ===================================================================== */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2.5rem, 6vw, 7rem);
  align-items: center;
}
.split--portrait { grid-template-columns: 0.85fr 1fr; }
.split__media { position: relative; overflow: hidden; }
.split__media img { width: 100%; aspect-ratio: 4/5; object-fit: cover; transition: transform 1.4s var(--ease-slow); }
.split__media:hover img { transform: scale(1.04); }
.split__media--tall img { aspect-ratio: 3/4; }
.split__title { font-size: var(--fs-h2); margin-block: 1.4rem 1.6rem; max-width: 18ch; }
.split__body p + p { margin-top: 1.2rem; }
.split__body { color: var(--stone); }
.section-ivory .split__body { color: var(--stone-dark); }
.split__cta { margin-top: 2.4rem; }

/* signature corner mark on media */
.framed { position: relative; }
.framed::before, .framed::after {
  content: ""; position: absolute; width: 26px; height: 26px; z-index: 2;
  border-color: var(--champagne); border-style: solid; border-width: 0;
}
.framed::before { top: 18px; left: 18px; border-top-width: 1px; border-left-width: 1px; }
.framed::after  { bottom: 18px; right: 18px; border-bottom-width: 1px; border-right-width: 1px; }

/* =====================================================================
   FEATURED COLLECTION  (asymmetric editorial)
   ===================================================================== */
.collection-head {
  display: flex; flex-wrap: wrap; align-items: flex-end;
  justify-content: space-between; gap: 1.5rem;
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.collection-head h2 { font-size: var(--fs-h2); max-width: 14ch; margin-top: 1.2rem; }

.estates { display: grid; gap: clamp(3rem, 6vw, 6rem); }
.estate {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.6rem, 4vw, 4rem);
  align-items: center;
}
.estate:nth-child(even) .estate__media { order: 2; }
.estate__media { position: relative; overflow: hidden; }
.estate__media img {
  width: 100%; aspect-ratio: 16/11; object-fit: cover;
  transition: transform 1.5s var(--ease-slow), filter 1.5s var(--ease-slow);
}
.estate:hover .estate__media img { transform: scale(1.05); }
.estate__no {
  position: absolute; top: 1.2rem; left: 1.2rem; z-index: 2;
  font-family: var(--display); font-size: 1.4rem; color: var(--ivory);
  mix-blend-mode: difference;
}
.estate__loc { font-size: 0.72rem; letter-spacing: 0.28em; text-transform: uppercase; color: var(--brass); }
.estate__name { font-family: var(--display); font-size: var(--fs-h3); line-height: 1.05; margin-block: 0.9rem 1.3rem; }
.estate__desc { color: var(--stone); max-width: 42ch; }
.estate__spec {
  display: flex; flex-wrap: wrap; gap: 1.8rem;
  margin-block: 1.8rem;
  padding-top: 1.6rem;
  border-top: 1px solid var(--line-light);
}
.estate__spec li { display: flex; align-items: center; gap: 0.6rem; font-size: 0.82rem; color: var(--stone); letter-spacing: 0.04em; }
.estate__spec svg { width: 17px; height: 17px; color: var(--champagne); stroke-width: 1.4; }
.estate__foot { display: flex; align-items: baseline; justify-content: space-between; gap: 1.5rem; flex-wrap: wrap; }
.estate__price { font-family: var(--display); font-size: 1.6rem; color: var(--ink); }

/* =====================================================================
   CTA banner
   ===================================================================== */
.cta-banner { text-align: center; position: relative; overflow: hidden; }
.cta-banner__big { font-size: var(--fs-display); max-width: 20ch; margin: 1.6rem auto 2.6rem; }
.cta-banner .lead { margin-inline: auto; margin-bottom: 0; }

/* =====================================================================
   TESTIMONIALS
   ===================================================================== */
.quotes { display: grid; gap: clamp(2rem, 4vw, 3rem); }
.quotes--row { grid-template-columns: repeat(3, 1fr); }
.quote {
  padding: clamp(2rem, 3vw, 2.8rem);
  border: 1px solid var(--line-light);
  display: flex; flex-direction: column; gap: 1.6rem;
  transition: border-color 0.6s var(--ease), transform 0.6s var(--ease);
}
.quote:hover { border-color: var(--line-gold); transform: translateY(-4px); }
.quote__mark { font-family: var(--display); font-size: 3.4rem; line-height: 0.4; color: var(--champagne); height: 1.4rem; }
.quote__text { font-family: var(--display); font-size: 1.35rem; line-height: 1.45; font-weight: 300; }
.quote__by { margin-top: auto; font-size: 0.68rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--stone); }

/* =====================================================================
   SERVICES
   ===================================================================== */
.services-list { border-top: 1px solid var(--line-gold); }
.service {
  position: relative;
  display: grid;
  grid-template-columns: clamp(3rem, 6vw, 6.5rem) 1fr auto;
  gap: clamp(1.6rem, 4vw, 4rem);
  align-items: start;
  padding-block: clamp(2.6rem, 4.5vw, 4rem);
  border-bottom: 1px solid var(--line-light);
  transition: padding-left 0.6s var(--ease), background 0.6s var(--ease);
}
/* gold accent that draws down the left edge on hover */
.service::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: -1px; width: 1px;
  background: var(--champagne); transform: scaleY(0); transform-origin: top;
  transition: transform 0.6s var(--ease);
}
.service:hover {
  padding-left: clamp(1rem, 2vw, 2rem);
  background: linear-gradient(90deg, rgba(199,167,99,0.05), transparent 55%);
}
.service:hover::after { transform: scaleY(1); }
.service__no {
  font-family: var(--display); font-style: italic;
  font-size: clamp(1.7rem, 2.6vw, 2.4rem); line-height: 1.15;
  color: var(--stone-dim);
  transition: color 0.6s var(--ease);
}
.service:hover .service__no { color: var(--champagne); }
.service__sub { display: block; font-family: var(--sans); font-size: 0.66rem; letter-spacing: 0.28em; text-transform: uppercase; color: var(--brass); margin-bottom: 0.8rem; }
.service__name { font-family: var(--display); font-size: var(--fs-h3); line-height: 1.04; max-width: 16ch; }
.service__desc { color: var(--stone); max-width: 58ch; margin-top: 1.2rem; }
.service__link {
  align-self: center; justify-self: end; flex: none;
  width: 54px; height: 54px; display: grid; place-items: center;
  border: 1px solid var(--line-gold); border-radius: 50%;
  color: var(--champagne);
  transition: background 0.55s var(--ease), color 0.55s var(--ease), transform 0.55s var(--ease);
}
.service:hover .service__link { background: var(--champagne); color: var(--ink); transform: translate(4px, -4px); }
.service__link svg { width: 19px; height: 19px; stroke-width: 1.4; }

/* feature cards (services secondary) */
/* Two columns, not three. Both pages that render this grid — buyers and
   sellers — carry exactly four cards, so a three-column row left the fourth
   alone with a two-cell hole beside it, and the grid's own background showed
   through as a grey slab. 2x2 holds at every width down to the single-column
   breakpoint. */
.feature-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 1px; background: var(--line-dark); border: 1px solid var(--line-dark); }
.feature {
  background: var(--card);
  padding: clamp(2rem, 3vw, 2.8rem);
  display: flex; flex-direction: column; gap: 1rem;
  transition: background 0.5s var(--ease);
}
.feature:hover { background: var(--ivory-2); }
.feature__icon svg { width: 26px; height: 26px; color: var(--brass); stroke-width: 1.2; }
.feature h4 { font-family: var(--display); font-size: 1.45rem; font-weight: 400; }
.feature p { color: var(--stone-dark); font-size: 0.96rem; }

/* =====================================================================
   TIMELINE
   ===================================================================== */
.timeline { border-top: 1px solid var(--line-gold); }
.section-ivory .timeline { border-top-color: var(--line-dark); }
.tl-item {
  --tl-dot: 11px;
  display: grid;
  grid-template-columns: clamp(4rem, 6vw, 5.5rem) 30px minmax(0, 1fr);
  column-gap: clamp(1.4rem, 2.6vw, 2.4rem);
  align-items: stretch;
  padding-block: clamp(1.7rem, 2.8vw, 2.4rem);
  border-bottom: 1px solid var(--line-light);
}
.section-ivory .tl-item { border-bottom-color: var(--line-dark); }
.tl-year {
  font-family: var(--display); font-style: italic;
  font-size: clamp(1.5rem, 2.2vw, 2rem); line-height: 1.15;
  color: var(--champagne); padding-top: 1px;
}
.section-ivory .tl-year { color: var(--brass); }
.tl-node { position: relative; }
.tl-node::before {
  content: ""; position: absolute; z-index: 1; top: 7px; left: 50%;
  transform: translateX(-50%);
  width: var(--tl-dot); height: var(--tl-dot); border-radius: 50%;
  background: var(--champagne); box-shadow: 0 0 0 4px rgba(199,167,99,0.14);
  transition: transform 0.5s var(--ease), box-shadow 0.5s var(--ease);
}
.section-ivory .tl-node::before { background: var(--brass); box-shadow: 0 0 0 4px rgba(153,122,61,0.12); }
.tl-node::after {
  content: ""; position: absolute; left: 50%; transform: translateX(-50%);
  top: 0; bottom: 0; width: 1px; background: var(--line-gold);
}
.section-ivory .tl-node::after { background: var(--line-dark); }
.tl-item:first-child .tl-node::after { top: calc(7px + var(--tl-dot) / 2); }
.tl-item:last-child .tl-node::after { bottom: auto; height: calc(7px + var(--tl-dot) / 2); }
.tl-item:hover .tl-node::before { transform: translateX(-50%) scale(1.3); box-shadow: 0 0 0 6px rgba(199,167,99,0.12); }
.tl-title { font-family: var(--display); font-size: clamp(1.35rem, 1.8vw, 1.65rem); line-height: 1.12; margin-bottom: 0.55rem; }
.tl-body { color: var(--stone); max-width: 60ch; line-height: 1.65; }
.section-ivory .tl-body { color: var(--stone-dark); }

/* affiliations marquee-ish row */
.affil { display: flex; flex-wrap: wrap; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.affil span {
  font-family: var(--display); font-size: clamp(1.2rem, 2.4vw, 1.9rem);
  color: var(--stone-dim); letter-spacing: 0.02em;
  transition: color 0.5s var(--ease);
}
.affil span:hover { color: var(--champagne); }

/* =====================================================================
   CONTACT
   ===================================================================== */
.contact-grid { display: grid; grid-template-columns: 1.2fr 0.8fr; gap: clamp(2.5rem, 6vw, 6rem); }
.field { position: relative; margin-bottom: 2.4rem; }
.field input, .field textarea {
  width: 100%;
  background: transparent;
  border: none;
  border-bottom: 1px solid var(--line-light);
  color: var(--ink);
  font-family: var(--sans); font-weight: 300; font-size: 1.05rem;
  padding: 0.7rem 0;
  transition: border-color 0.5s var(--ease);
}
.field textarea { resize: vertical; min-height: 120px; }
.field label {
  position: absolute; left: 0; top: 0.7rem;
  font-size: 0.78rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--stone-dim);
  pointer-events: none;
  transition: transform 0.45s var(--ease), color 0.45s var(--ease), font-size 0.45s var(--ease);
}
.field input:focus, .field textarea:focus { outline: none; border-color: var(--champagne); }
.field input:focus + label,
.field textarea:focus + label,
.field input:not(:placeholder-shown) + label,
.field textarea:not(:placeholder-shown) + label {
  transform: translateY(-2rem);
  font-size: 0.62rem;
  color: var(--brass);
}
.field input::placeholder, .field textarea::placeholder { color: transparent; }

.form-note { font-size: 0.78rem; color: var(--stone-dim); margin-top: -0.8rem; margin-bottom: 1.8rem; }
.form-status {
  margin-top: 1.4rem; font-size: 0.8rem; letter-spacing: 0.12em;
  color: var(--brass); opacity: 0; transform: translateY(6px);
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.form-status.is-shown { opacity: 1; transform: translateY(0); }

.contact-detail { display: flex; flex-direction: column; gap: 2.2rem; }
.cd-item { display: flex; flex-direction: column; gap: 0.4rem; }
.cd-item .label { font-size: 0.66rem; letter-spacing: 0.26em; text-transform: uppercase; color: var(--brass); }
.cd-item a, .cd-item p { font-family: var(--display); font-size: 1.4rem; }
.cd-item small { color: var(--stone); }

.map-frame {
  position: relative; overflow: hidden;
  border: 1px solid var(--line-light);
  margin-top: clamp(3rem, 6vw, 5rem);
}
.map-frame iframe {
  width: 100%; height: clamp(300px, 42vw, 460px);
  border: 0; display: block;
  filter: grayscale(1) contrast(1.02) brightness(1.02) sepia(0.12);
  transition: filter 0.8s var(--ease);
}
.map-frame:hover iframe { filter: grayscale(0.35) contrast(1.02) brightness(1.02) sepia(0.04); }
.map-frame__tag {
  position: absolute; left: 1.4rem; bottom: 1.4rem; z-index: 2;
  background: var(--ink); border: 1px solid var(--line-gold);
  padding: 0.7rem 1.2rem; font-size: 0.64rem; letter-spacing: 0.24em; text-transform: uppercase; color: var(--champagne);
  pointer-events: none;
}

/* =====================================================================
   BUYER / SELLER GUIDE — two columns
   ===================================================================== */
.guide { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.4rem, 3vw, 2.2rem); }
.guide__col {
  display: flex; flex-direction: column;
  padding: clamp(2rem, 4vw, 3.2rem);
  border: 1px solid var(--line-dark); border-radius: 3px;
  background: var(--card);
  transition: border-color 0.6s var(--ease), transform 0.6s var(--ease), background 0.6s var(--ease), box-shadow 0.6s var(--ease);
}
.guide__col:hover { border-color: var(--line-gold); transform: translateY(-6px); background: #fff; box-shadow: 0 24px 50px -28px rgba(20,18,14,0.35); }
.guide__no { font-size: 0.7rem; letter-spacing: 0.26em; text-transform: uppercase; color: var(--brass); }
.guide__title { font-family: var(--display); font-size: var(--fs-h3); margin-top: 0.7rem; }
.guide__lead { color: var(--stone); margin-top: 1rem; max-width: 38ch; }
.guide__list {
  counter-reset: g; margin-top: 1.8rem; padding-top: 1.8rem;
  border-top: 1px solid var(--line-light);
  display: flex; flex-direction: column; gap: 1.1rem;
}
.guide__list li { display: flex; gap: 1rem; align-items: baseline; color: var(--ink); font-size: 0.98rem; line-height: 1.5; }
.guide__list li::before {
  counter-increment: g; content: counter(g, decimal-leading-zero);
  font-family: var(--display); font-size: 1rem; color: var(--brass);
  min-width: 1.8em; flex: none;
}
.guide__cta { margin-top: auto; padding-top: 2.2rem; }

/* =====================================================================
   LISTINGS SYNDICATED TO — partner logo tiles
   --------------------------------------------------------------------
   The real SVGs from c21-branding/syndicated-logos/ in R2, each on its own
   white square tile, monochrome until pointed at: five tiles per row on a
   desktop, four on a tablet, two on a phone, and a short last row centres
   itself. Not a marquee - nothing here scrolls or animates on its own.

   Four things here are not free to change:

   - The tile is white because that is what makes the logos correct, not
     because it is a card. Five of the ten files are raster images inside an
     SVG wrapper, and three of those (Robb Report, Mansion Global, duPont
     Registry) sit on an opaque #FFF plate. The logo multiplies onto the
     tile, and multiply leaves white exactly as it finds it: on a white tile
     the plate vanishes and every brand colour renders true. Any other tile
     colour brings the plates back as pale boxes.

   - isolation on the tile is what that blend needs. mix-blend-mode reaches
     the backdrop of its nearest stacking context, so without it the logo
     blends with whatever is painted below the list - the page canvas, and
     the .reveal fade mid-animation, which is where the plates used to
     flash. Isolating makes the tile's own white the entire backdrop, so
     nothing underneath it matters any more. It is also why this list no
     longer repaints the body background the way it had to before.

   - The rest state may darken and desaturate but must never darken white.
     grayscale plus a little contrast is the whole of it, and each mark
     lands on its own luminance: eight of the ten fall between #000 and
     #6C6C6C, so the wall reads as dark grey. A brightness step would take
     them lower and take the white with them - both the plates and the
     white inside realtor.com's house and the ListHub wordmark - because to
     a filter white and ink are the same channel.

   - The two size limits work together and both are relative to the tile, so
     a tile of any width shows the same composition. max-width keeps a wide
     wordmark inside the tile. max-height is the optical cap height
     (--syn-cap, a share of the tile inner height) divided by that file's ink
     fraction (--syn-fill, set per item in the partial), which is what puts
     every mark on the same optical size - cap them all to one box instead and
     Properstar, duPont Registry and Mansion Global read at half the size of
     their neighbours. Re-measure --syn-fill when a file is replaced; the
     number belongs to the file, not to the partner.

     Equal ink boxes only mean equal cap height while a mark is one line of
     type. A lockup that stacks an icon over its wordmark spends that same box
     on two rows and the gap between them, so its wordmark comes out around
     half the size of its neighbours - CREtech, measured, was 23% of the tile
     wide against a 38-71% band. Those files carry --syn-lift, a multiplier on
     the cap. Unlike fill it is a judgement rather than a measurement, so the
     partial records how each one was arrived at.

     The widest marks (realtor.com, JamesEdition, Properstar) end up limited
     by width rather than by cap height, which is what a square tile does to a
     7:1 wordmark and is preferable to letting it run out of the tile.
   ===================================================================== */
.trust-section { text-align: center; }
.trust {
  --syn-gap: clamp(0.75rem, 1.5vw, 1.1rem);
  /* The optical cap height every mark is normalised to, as a share of the
     tile's inner height rather than of the viewport - so the composition
     inside a tile is the same on a phone as it is on a desktop. */
  --syn-cap: 19%;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: var(--syn-gap);
  max-width: 880px;
  margin: clamp(2rem, 4vw, 3rem) auto 0;
  list-style: none;
}
/* Column count. A basis of (100/n)% less one gap fits exactly n tiles per row
   and can never fit n+1, whatever width the list ends up with, so the count
   holds without measuring anything. These two overrides belong next to the
   rule they change rather than in the responsive block at the end of the
   file: the count is the layout here, not a tweak to it. max-width is a
   ceiling on the tile, not a width: without it a 4-column tablet row makes
   tiles half again as large as the 5-column desktop ones, since each track is
   a share of the row. A cap narrows a tile, so it is the one change here that
   could in principle fit an extra one on a line: at 168px it cannot, at any
   width, for any of the three counts. Re-check that if you raise it. */
.trust__item { flex: 0 0 calc(20% - var(--syn-gap)); max-width: 168px; }
@media (max-width: 880px) { .trust__item { flex-basis: calc(25% - var(--syn-gap)); } }
@media (max-width: 540px) { .trust__item { flex-basis: calc(50% - var(--syn-gap)); } }
.trust__link {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 1;
  /* Percentage padding resolves against the tile's own width, so the frame
     around the logo stays the same share of the tile at every breakpoint. */
  padding: 14%;
  /* The card idiom of this theme, at tile scale: .guide__col's border and
     radius, and the white it takes on hover. See the note above for why the
     white is not a style choice. */
  background: #fff;
  border: 1px solid var(--line-dark); border-radius: 3px;
  isolation: isolate;
  transition: border-color 0.45s var(--ease), transform 0.45s var(--ease), box-shadow 0.45s var(--ease);
}
.trust__logo {
  display: block;
  width: auto; height: auto;
  max-width: 100%;
  max-height: calc(var(--syn-cap) * var(--syn-lift, 1) / var(--syn-fill, 1));
  filter: grayscale(1) contrast(1.06);
  mix-blend-mode: multiply;
  transition: filter 0.45s var(--ease);
}
/* Brand colour on hover and on keyboard focus, so the reveal is not
   pointer-only. Both filter lists name the same functions in the same order,
   which is what lets the colour ease in rather than snap. The focus ring is
   the global :focus-visible rule - it sits 4px outside the tile with a 6px
   halo, which is why --syn-gap does not go below 0.75rem. */
.trust__link:hover,
.trust__link:focus-visible {
  border-color: var(--line-gold);
  transform: translateY(-4px);
}
/* The lift shadow is on hover alone. It is the same property the global
   :focus-visible rule uses for its light halo, and a tile is more specific
   than that rule, so naming it here as well would quietly drop the halo from
   the keyboard ring. */
.trust__link:hover { box-shadow: 0 18px 36px -26px rgba(20,18,14,0.34); }
.trust__link:hover .trust__logo,
.trust__link:focus-visible .trust__logo { filter: grayscale(0) contrast(1); }

/* Agent credential line (About bio) — name, role, and DRE together. */
.agent-id { display: flex; flex-wrap: wrap; align-items: center; gap: 0.7rem 1.1rem; margin-top: 1.5rem; }
.agent-id__name { font-family: var(--display); font-size: 1.55rem; line-height: 1; letter-spacing: 0.02em; color: var(--brass); }
.agent-id__role { font-size: 0.72rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--stone); }
.agent-id__dre {
  font-size: 0.7rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--brass);
  border: 1px solid var(--line-gold); border-radius: 2px;
  padding: 0.34rem 0.7rem;
}/* =====================================================================
   SCROLL REVEAL
   ===================================================================== */
.reveal { opacity: 0; transform: translateY(34px); transition: opacity 1s var(--ease), transform 1s var(--ease); }
.reveal.is-in { opacity: 1; transform: none; }
.reveal[data-delay="1"] { transition-delay: 0.1s; }
.reveal[data-delay="2"] { transition-delay: 0.2s; }
.reveal[data-delay="3"] { transition-delay: 0.3s; }
.reveal[data-delay="4"] { transition-delay: 0.4s; }

/* hairline that draws itself in */
.draw { transform: scaleX(0); transform-origin: left; transition: transform 1.1s var(--ease-slow); }
.draw.is-in { transform: scaleX(1); }

/* clip-reveal for media */
.clip { clip-path: inset(0 0 100% 0); transition: clip-path 1.3s var(--ease-slow); }
.clip.is-in { clip-path: inset(0 0 0% 0); }

/* staggered cascade — children of a [data-stagger] container ease in one
   after another once the container scrolls into view */
[data-stagger].reveal { opacity: 1; transform: none; }
[data-stagger] > * {
  opacity: 0; transform: translateY(10px) scale(0.985);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
[data-stagger].is-in > * { opacity: 1; transform: none; }
[data-stagger].is-in > *:nth-child(1) { transition-delay: 0.05s; }
[data-stagger].is-in > *:nth-child(2) { transition-delay: 0.12s; }
[data-stagger].is-in > *:nth-child(3) { transition-delay: 0.19s; }
[data-stagger].is-in > *:nth-child(4) { transition-delay: 0.26s; }
[data-stagger].is-in > *:nth-child(5) { transition-delay: 0.33s; }
[data-stagger].is-in > *:nth-child(6) { transition-delay: 0.40s; }

/* Fail-safe: if JavaScript never runs (disabled, blocked, or a failed
   script load), the scroll-reveal classes can never resolve. Without JS
   we must never hide content, so show everything and skip the preloader. */
html:not(.js) .reveal,
html:not(.js) .draw,
html:not(.js) .clip,
html:not(.js) [data-stagger] > * { opacity: 1 !important; transform: none !important; clip-path: none !important; }
html:not(.js) .preloader { display: none !important; }

/* =====================================================================
   PRELOADER
   ===================================================================== */
.preloader {
  position: fixed; inset: 0; z-index: 200;
  background: var(--paper);
  display: grid; place-items: center;
  transition: opacity 0.8s var(--ease), visibility 0.8s var(--ease);
}
.preloader .logo, .preloader .logo .logo__sub { color: var(--brass); }
.preloader.is-done { opacity: 0; visibility: hidden; }
.preloader__mark { text-align: center; }
.preloader__mark .w { font-family: var(--display); font-size: clamp(2.5rem, 8vw, 5rem); letter-spacing: 0.18em; overflow: hidden; }
.preloader__mark .w span { display: inline-block; transform: translateY(110%); animation: rise 0.9s var(--ease) forwards; }
.preloader__mark .w span:nth-child(2){ animation-delay: 0.07s; }
.preloader__mark .w span:nth-child(3){ animation-delay: 0.14s; }
.preloader__mark .w span:nth-child(4){ animation-delay: 0.21s; }
@keyframes rise { to { transform: translateY(0); } }
.preloader__mark .logo { animation: logo-in 1s var(--ease) both; }
@keyframes logo-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: translateY(0); } }
.preloader__line { height: 1px; background: var(--brass); margin: 1.4rem auto 0; width: 0; animation: grow 1.1s 0.3s var(--ease) forwards; }
@keyframes grow { to { width: 100%; } }

/* =====================================================================
   RESPONSIVE
   ===================================================================== */
/* Burger overlay — the overflow menu, and the phone menu, and the same thing
   at every width in between. This used to be @media (max-width: 1024px) and
   was the widest miss of the Gold set: the inline row needs 1206px here, so
   everything from 1024 to 1206 laid out a nav that did not fit and said
   nothing about it. global-js/nav-fit.js keeps as many items inline as the
   row can hold and nests the rest in here. */
.nav-panel {
  position: fixed;
  top: 0; left: 0; width: 100%;
  /* Height follows the contents rather than filling the viewport. It holds
     nine items on a phone and sometimes one on a desktop, and a full-screen
     overlay containing a single word reads as a broken page. */
  height: auto;
  max-height: 100svh;
  /* A drawer from the right rather than a full-screen overlay dropping from
     the top. Width is half the window from 442px up and the whole window at
     441 and below; height fills, which it can now do because the panel holds
     either the entire nav or nothing rather than a single leftover link. */
  top: 0; right: 0; left: auto;
  width: 50%;
  height: 100svh;
  /* The top also clears the close button. The bar keeps its X above this drawer
     (z-index 70 against 65), and on a 480px-tall screen the 4rem floor of the
     figure below put the mark level with it - measured, 1px of overlap at
     320x480 and 3px of clearance at 320x568, which is not a margin.
     max() leaves the drawer's own rhythm alone wherever it is already generous
     enough and lifts only the short end, so nothing changes above ~550px tall. */
  padding-top: max(clamp(4rem, 12vh, 8rem), calc(var(--nav-h) + 0.5rem));
  padding-bottom: clamp(4rem, 12vh, 8rem);
  padding-inline: clamp(1.5rem, 4vw, 2.5rem);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 2.2rem;
  background: var(--obsidian);
  transform: translateX(100%);
  opacity: 0;
  /* visibility carries a delay so it flips instantly on open and only once
     the slide has finished on close; without it the panel disappears on the
     first frame of closing and the animation is never seen. */
  transition: transform 0.45s var(--ease),
              opacity 0.45s var(--ease),
              visibility 0s linear 0.45s;
  z-index: 65;
  /* The overlay sits off-screen rather than hidden, so without this its links
     stay in the tab order while it is closed. */
  visibility: hidden;
}
/* No auto margins here, and that is the point.
   The panel used to centre its contents with justify-content, which put the
   overflow at both ends and made the top half unreachable. Auto margins fixed
   the reachability but kept the drift: the mark landed 32px from the panel top
   on a short screen and 180px on a tall one, and on a tall drawer it left a
   168px void between the mark and the first link - the logo read as stranded
   rather than as the head of the menu.
   So the stack is simply top-aligned: the mark sits at the panel's top padding,
   the links follow one gap below it, and both are the same on every screen. It
   costs nothing in emptiness, because the panels that could look sparse
   (classic, california, timeless) are height:auto and shrink to their content;
   the two side drawers are full-height by design, where a menu that starts at
   the top is the ordinary thing. justify-content: flex-start above is what
   keeps the top scrollable when the content is taller than the screen. */
.nav-panel.is-open {
  transform: translateX(0);
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

/* Phones take the whole window: half of 400px is a column of menu beside a
   column of page nobody can read. */
@media (max-width: 441px) {
  .nav-panel { width: 100%; }
}
.nav-panel .nav__menu { flex-direction: column; justify-content: center; gap: 2.2rem; }
/* Overlay is a dark panel — links/CTA stay light inside it on every page */
.nav-panel .nav__link { font-size: 1rem; color: rgba(244,240,231,0.82); }
.nav-panel .nav__link:hover,
.nav-panel .nav__link[aria-current="page"] { color: var(--ivory); }
.nav-panel .btn { margin-top: 1rem; --c: var(--ivory); }

/* The burger appears only when the overlay has something in it. nav-fit.js
   sets this to "false" when every item fits inline; it is absent until the
   script runs, and absent has to mean visible - that is the state a phone
   loads in, with every item still in the overlay. */
.nav__toggle { display: flex; z-index: 70; }
[data-nav-overflow="false"] .nav__toggle { display: none; }
.nav.is-nav-open .nav__toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav.is-nav-open .nav__toggle span:nth-child(2) { opacity: 0; width: 0; }
.nav.is-nav-open .nav__toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* An inline nav link that wraps to a second line is the thing overflow is
   there to prevent, so it must not be an option the row can take instead. */
[data-nav-fit-inline] .nav__link, [data-nav-fit-inline] .nav__cta { white-space: nowrap; }

/* ---- Nav submenus --------------------------------------------------- */
/* Buyers carries Calculator; Sellers carries Home Valuation and Sold. A group
   is ONE element, so nav-fit.js moves it whole and knows nothing about the
   nesting - all that is left is how it reads in each of the two places it can
   land.

   Inline it is an absolutely positioned dropdown, and that is not a styling
   preference: a submenu in flow would make the group as wide as its widest
   child, nav-fit would measure that width, and the group would nest at every
   screen size - so the dropdown would never once be seen.

   It opens on :hover and on :focus-within, and no script owns either. Focus
   reaches the parent link, which is always visible, before it can reach into
   the submenu, so :focus-within is already true by the time the next Tab
   lands inside. That is what lets the closed state use visibility:hidden and
   keep the submenu out of the tab order until it is on screen. */
.nav__group { position: relative; display: flex; align-items: center; }
.nav__group > .nav__link { display: inline-flex; align-items: center; gap: 0.5em; }
.nav__sub { display: flex; flex-direction: column; }

/* Drawn from borders rather than an icon: Lucide is inlined in
   global-js/classic.js and runs after first paint, so an <i data-lucide> here
   would be an empty box in the bar until that script landed. */
.nav__caret {
  width: 0.34em; height: 0.34em; flex: none;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: translateY(-0.1em) rotate(45deg);
  transition: transform 0.4s var(--ease);
}

/* Inline: the dropdown */
[data-nav-fit-inline] .nav__sub {
  position: absolute;
  top: 100%; left: -1.1rem;
  min-width: max-content;
  margin-top: 0.6rem;
  padding-block: 0.5rem;
  background: var(--paper);
  border: 1px solid var(--line-light);
  box-shadow: 0 24px 52px -30px rgba(20,18,14,0.55);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease), visibility 0.35s var(--ease);
  z-index: 75;
}
/* The gap between the label and the card is dead ground the pointer has to
   cross, and crossing it would close the menu. This bridges it. */
[data-nav-fit-inline] .nav__sub::before {
  content: ""; position: absolute; left: 0; right: 0; top: -0.6rem; height: 0.6rem;
}
[data-nav-fit-inline] .nav__group:hover .nav__sub,
[data-nav-fit-inline] .nav__group:focus-within .nav__sub {
  opacity: 1; visibility: visible; transform: translateY(0);
}
[data-nav-fit-inline] .nav__group:hover .nav__caret,
[data-nav-fit-inline] .nav__group:focus-within .nav__caret { transform: translateY(0.08em) rotate(-135deg); }
[data-nav-fit-inline] .nav__sub .nav__link { padding: 0.5rem 1.1rem; }
/* The sliding champagne rule belongs to the bar. Inside a card it reads as a
   border on the wrong edge. */
[data-nav-fit-inline] .nav__sub .nav__link::after { display: none; }
[data-nav-fit-inline] .nav__sub .nav__link:hover { background: var(--paper-2); }

/* The homepage inversion above turns EVERY .nav__link in the bar white so it
   reads over the hero photo. The dropdown is inside that bar but stands on a
   paper card of its own, so white there is white on cream: a menu that opens
   into nothing. Specificity has to beat that rule's (0,5,1) - these are
   (0,6,1) and (0,7,1). */
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__sub .nav__link { color: var(--stone); }
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__sub .nav__link:hover,
body:has(.hero) .nav:not(.is-stuck):not(.is-nav-open) .nav__sub .nav__link[aria-current="page"] { color: var(--ink); }

/* Panel: an indented block, always open. There is no disclosure to tap - the
   panel exists to show what did not fit, so hiding half of it behind a second
   interaction would defeat it. The overlay centres its links, so the submenu
   is centred under a hairline rather than indented behind a left border. */
[data-nav-fit-panel] .nav__group { flex-direction: column; align-items: center; gap: 1.3rem; }
[data-nav-fit-panel] .nav__sub {
  position: relative;
  align-items: center;
  gap: 1.1rem;
  padding-top: 1.3rem;
}
[data-nav-fit-panel] .nav__sub::before {
  content: "";
  position: absolute; top: 0; left: 50%;
  width: 28px; height: 1px;
  transform: translateX(-50%);
  background: var(--line-gold);
}
[data-nav-fit-panel] .nav__sub .nav__link { font-size: 0.85rem; }
[data-nav-fit-panel] .nav__caret { display: none; }

/* The architectural rail stays on a width breakpoint. It is a page-layout
   element, not part of the nav row, so it has no reason to follow the nav
   into the burger — and .nav's offset is the rail's, so it moves with it. */
@media (max-width: 1024px) {
  :root { --rail: 0px; }
  .rail { display: none; }
  .nav { left: 0; }

  .stats { grid-template-columns: repeat(2, 1fr); }
  .stat:nth-child(3) { border-left: none; }
}

@media (max-width: 880px) {
  .split, .split--portrait { grid-template-columns: 1fr; gap: 2.5rem; }
  .split__media { order: -1; }
  .estate, .estate:nth-child(even) .estate__media { grid-template-columns: 1fr; }
  .estate:nth-child(even) .estate__media { order: -1; }
  .estate__media { order: -1; }

  .quotes--row { grid-template-columns: 1fr; }
  .feature-grid { grid-template-columns: 1fr; }
  .guide { grid-template-columns: 1fr; }
  .footer__top { grid-template-columns: 1fr; gap: 2.5rem; }
  .contact-grid { grid-template-columns: 1fr; }

  .service { grid-template-columns: auto 1fr; column-gap: 1.2rem; row-gap: 1.3rem; align-items: center; }
  .service:hover { padding-left: 0; }
  .service__no { grid-column: 1; grid-row: 1; font-size: 1.5rem; }
  .service__link { grid-column: 2; grid-row: 1; justify-self: end; width: 46px; height: 46px; }
  .service__body { grid-column: 1 / -1; grid-row: 2; }
}

@media (max-width: 540px) {
  .stats { grid-template-columns: 1fr; }
  .stat, .stat:nth-child(3) { border-left: none; }
  .tl-item { grid-template-columns: 1fr; row-gap: 0.5rem; padding-block: 1.8rem; }
  .tl-node { display: none; }
  .tl-year { font-size: 1.5rem; }
}

/* ---- Reduced motion ----------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveal, .clip, .draw,
  [data-stagger] > * { opacity: 1 !important; transform: none !important; clip-path: none !important; }
  .hero__media img { height: 100%; }
}


/* =====================================================================
   ADDED IN CONVERSION — markup the source template did not have
   classic-light
   ===================================================================== */

/* Ylopo IDX widget. It renders its own cards; this only reserves the space
   and shimmers until it hydrates, so the page does not jump. */
.ylopo-easy-widget { min-height: 420px; position: relative; }
.ylopo-easy-widget.ylopo-loading::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--paper-2) 25%, var(--card) 37%, var(--paper-2) 63%);
  background-size: 400% 100%;
  animation: classic-shimmer 1.4s ease infinite;
}
.ylopo-easy-widget.ylopo-ready::before { display: none; }
@keyframes classic-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* The source styled .feature h4; the converted markup uses h3, which is the
   correct level under the section's h2. */
.feature h3 {
  font-family: var(--display);
  font-size: 1.45rem;
  font-weight: 400;
}

/* QA build notices. Deliberately visible while the reviews, sold-properties
   and contact-form widgets are being built - an empty band reads as broken
   where a labelled one reads as pending. Remove once all three ship. */
.qa-note {
  display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap;
  max-width: 60ch;
  padding: 1.4rem 1.6rem;
  border: 1px dashed var(--brass);
  border-radius: 2px;
  background: color-mix(in srgb, var(--champagne) 8%, transparent);
}
.qa-note__tag {
  flex: none;
  font-size: 0.62rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--ink);
  background: var(--champagne);
  border-radius: 2px;
  padding: 0.35rem 0.8rem;
}
.qa-note p { font-size: 0.94rem; color: var(--stone); flex: 1 1 22ch; margin: 0; }

@media (max-width: 640px) { .qa-note { flex-direction: column; gap: 0.8rem; } }

/* Mobile CTA width ----------------------------------------------------
   At phone widths a standalone CTA goes full width with its label centred.
   Sized to its own text it leaves a ragged edge against the copy above it,
   and of two stacked buttons the shorter reads as the lesser one purely
   because it is narrower.

   Card actions and widget-injected markup are excluded. Written as a
   max-width override rather than a mobile-first base rule so the desktop
   layout cannot be affected by construction. */
@media (max-width: 640px) {
  .btn { width: 100%; justify-content: center; text-align: center; }
  .community .btn,
  .ylopo-easy-widget .btn { width: auto; }

  /* "Open the full search" is a text link, not a CTA, so it is centred
     without being stretched. fit-content keeps the hover underline tight to
     the label - .tlink::after spans the element, so a full-width link would
     drag a rule across the column. */
  .tlink { display: flex; width: fit-content; margin-inline: auto; }

  /* The hero wants nothing here any more. This block used to stack .hero's
     flex row so the copy got its full measure back from the scroll indicator;
     the indicator is out of flow at every width now, .hero__inner is the only
     item in that row, and there is nothing left to stack. Re-adding a
     flex-direction here would only move the centred copy back to the floor of
     the hero on a phone. */
}

/* Sold page with nothing to show.
   The visitor-facing counterpart to .qa-note: an agent whose Ylopo agent ids
   are not on file yet gets this instead of an empty band. Which of the two
   renders is decided in Nunjucks - the widget has to be absent from the page,
   not hidden here. */
.sold-empty {
  max-width: 46ch; margin-inline: auto;
  padding: 2rem 1rem;
  text-align: center;
  border-top: 1px solid var(--line-light, rgba(20,18,14,0.13));
  border-bottom: 1px solid var(--line-light, rgba(20,18,14,0.13));
}
.sold-empty .sold-empty__title {
  font-family: var(--display, Georgia, serif);
  font-size: var(--fs-h3, 1.6rem); font-weight: 400;
  margin: 0 0 0.75rem;
  color: var(--ink, #14120E);
}
.sold-empty p { margin: 0; font-size: var(--fs-body, 1rem); color: var(--stone, #5E574B); }
.sold-empty a { color: var(--brass, #997A3D); text-decoration: underline; text-underline-offset: 0.2em; }
.sold-empty a:hover { color: var(--champagne, #C7A763); }

/* Sale date on sold cards - OFF unless SHOW_SOLD_DATE is on in
   scripts/feature-flags.mjs, which is what emits data-sold-date on the widget.

   The Ylopo widget puts the date in .gallery-card-b-generate-sort-block, which
   this template's card CSS in the ylopo-grid project hides outright. Overriding
   that !important needs both the flag attribute and this specificity, so the
   rule lives here rather than there - and so the per-template design of the bar,
   when it happens, sits with the rest of this template's tokens.

   :has(.sold-date) is load-bearing, not decoration. For-sale cards reuse the
   same container for "Listed 4 Months Ago", so revealing it unscoped would put
   that strip on every listing card on every home and search page. Only a sold
   card has .sold-date inside.

   Two selectors, not one: the card redesign takes .property-details-wrap out of
   layout with display:none, and on these templates that wrapper holds the sort
   block and nothing else - so the block alone computes to a 0x0 box inside a
   hidden parent. Revealing the wrapper duplicates no content precisely because
   it is otherwise empty; check that still holds before copying this to a new
   template.

   Still wearing the widget's own grey bar styling: designing it per template is
   the work that has to happen before the flag is turned on. */
.ylopo-easy-widget[data-sold-date="true"] .property-details-wrap:has(.sold-date),
.ylopo-easy-widget[data-sold-date="true"] .gallery-card-b-generate-sort-block:has(.sold-date) {
  display: flex !important;
}

/* Backdrop for the nav drawer. Created by the template's script, not by the
   layout, so no markup changes. It exists as much to swallow the click as to
   dim the page: tapping beside an open drawer should dismiss it and nothing
   else, and a dim painted with a shadow on the panel would let that tap fall
   through to a link underneath. Sits one below the drawer. */
.nav-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.45);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.45s var(--ease), visibility 0s linear 0.45s;
  z-index: 64;
}
.nav-backdrop.is-open {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}
