/* ===== 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: 'Inter';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/inter/inter-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: 'Inter';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/inter/inter-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;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/playfair-display/playfair-display-italic-400-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: 'Playfair Display';
  font-style: italic;
  font-weight: 400 700;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/playfair-display/playfair-display-italic-400-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;
}
@font-face {
  font-family: 'Playfair Display';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/playfair-display/playfair-display-normal-400-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: 'Playfair Display';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(https://library.c21masters.com/c21-branding/fonts/playfair-display/playfair-display-normal-400-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;
}

/* ==========================================================================
   TIMELESS — Century 21 Masters agent template
   Mirror of https://library.c21masters.com/global-css/timeless.css

   Light print-editorial / gallery catalogue. A paper-white magazine
   aesthetic: centered masthead, framed image bands, serif index numerals,
   hairline rules. Deliberately NOT a dark cinematic site.

   Fonts: Playfair Display (display) / Inter (body), from Google Fonts.

   Converted from the "Timeless Luxury" source stylesheet. Dropped with the
   markup they styled:

     .stats-band          the counter bands on Home, About and Sellers
     .team-*              the four-partner grid (every agent here is solo)
     .property-*          the invented listings, now the Ylopo widget
     .testimonial-*       reviews become a widget with its own styling
     .faq-*               no FAQ on any converted template
     .service-row*        the services page does not exist here
     .form-*              forms are injected and bring their own CSS
     .site-footer, .footer-*
                          footer.js injects the footer, and it defines a
                          .footer-bottom of its own. Keeping the source rules
                          would restyle the injected footer, which carries the
                          legal disclaimers.

   .feature-estate and .ledger survive because they carry the signature look.
   They now render communities rather than properties - see the note above
   section 10.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Design Tokens
   -------------------------------------------------------------------------- */
:root {
  --color-ink: #111827;
  --color-gold: #C9A86A;
  --color-champagne: #E9DFC8;
  --color-bg: #FFFFFF;
  --color-paper: #F9F8F6;
  --color-text: #1F2937;
  --color-muted: #6B7280;
  --color-border: #E5E7EB;

  --color-gold-deep: #A5834E;
  --color-champagne-soft: #F3EDDE;
  --color-ink-soft: #2A3340;
  --color-on-ink: #F4F2EC;
  --color-on-ink-muted: rgba(244, 242, 236, 0.60);
  --color-on-ink-line: rgba(244, 242, 236, 0.16);
  --color-success: #2F7D5D;
  --color-error: #B0413E;

  --font-display: "Playfair Display", Georgia, "Times New Roman", serif;
  --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* Editorial type scale — display runs large, body stays small & quiet */
  --t-masthead: clamp(3rem, 1.4rem + 7vw, 7rem);
  --t-h1: clamp(2.5rem, 1.5rem + 4vw, 4.5rem);
  --t-h2: clamp(2rem, 1.4rem + 2.6vw, 3.25rem);
  --t-h3: clamp(1.375rem, 1.15rem + 1.1vw, 2rem);
  --t-h4: clamp(1.125rem, 1rem + 0.5vw, 1.375rem);
  --t-lead: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
  --t-body: 1rem;
  --t-small: 0.875rem;
  --t-label: 0.6875rem;

  /* The eyebrow / masthead kicker, which is one component appearing on all
     eight pages. It is tokenised because it used to be written twice - once as
     .eyebrow and once as .masthead__kicker - and the two copies had drifted on
     every value they shared.

     Fluid, unlike --t-label: every heading it sits above scales with the
     viewport (--t-h1 doubles, --t-masthead more than doubles), so a fixed
     11px label reads as a hairline on a wide screen and heavy on a phone.
     The range is deliberately narrow - this is a label, not a heading.

     Tracking is 0.28em rather than the 0.34/0.36em it was. The absolute
     letter-space is about what it was before at the old size, so the
     editorial look is unchanged, but it now sits in the same family as the
     template's other tracked labels (0.2-0.24em) instead of outside it.

     Two sizes, not one. A hero label opens a page above a headline that runs
     to --t-masthead or --t-h1; a section label opens a band below it. At one
     size the hero label reads as an afterthought against 112px of Playfair,
     so the hero step is about 2px larger at every viewport - enough to hold
     the top of the page, not enough to stop being a label. Everything else
     about the two is identical, which is why this is a size token and not a
     second rule. */
  --t-eyebrow: clamp(0.6875rem, 0.63rem + 0.24vw, 0.8125rem);
  --t-eyebrow-hero: clamp(0.8125rem, 0.74rem + 0.30vw, 0.9375rem);
  --eyebrow-track: 0.28em;
  --eyebrow-gap: 0.7em;
  --eyebrow-below: clamp(1.25rem, 1.05rem + 0.6vw, 1.75rem);

  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-20: 5rem;
  --space-24: 6rem;

  --section-pad: clamp(4.5rem, 3rem + 6vw, 9rem);
  /* 72rem (1152px) put this below the 1200-1400px a desktop shell is expected
     to occupy, and made timeless the narrowest measure in the fleet. 80rem is
     1280px, which is also what beacon and classic-clean carry, so this lands on
     a number the set already uses rather than a new one.

     Safe to raise: .container is width:100% with this as a max-width, and the
     highest media query in this file is min-width:64em (1024px). Below the cap
     the container is fluid and computes exactly as before, so only viewports
     above 1152px change at all.

     --wrap-wide stays 84rem (1344px), still inside the range. The header row
     and the masthead use that wider measure by design; keeping it put also
     narrows their disagreement with the content from 96px to 32px. */
  --wrap: 80rem;
  --wrap-wide: 84rem;
  --pad-x: clamp(1.25rem, 4vw, 3rem);

  --rule: 1px solid var(--color-border);
  --rule-gold: 1px solid var(--color-gold);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --fast: 200ms;
  --med: 450ms;
  --slow: 900ms;

  --radius: 2px;
}

/* --------------------------------------------------------------------------
   2. Reset & Base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after { box-sizing: border-box; margin: 0; padding: 0; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }

body {
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: 1.75;
  color: var(--color-text);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
button { font: inherit; border: none; background: none; cursor: pointer; }

/* The list reset again, at class strength, because on the contact page the
   line above stops holding. form-inject.js copies every <link rel=stylesheet>
   off the FluentForms host into our <head> - the whole Kadence theme with it -
   and those links land after this file. Kadence ships
   `ul,ol{margin:0 0 1.5em 1.5em;padding:0}` and `ul{list-style:disc}`, which
   beat a bare element selector on order alone: the nav row slid 1.5em right,
   carried 1.5em of dead space under it, and every item that is not a
   .nav-group grew a bullet - a .nav-group is display:flex, so it has no marker
   box to fill, which is why Buyers and Sellers were the two without one.

   The nav lists are the only ul this template renders, so naming them is the
   whole fix, and a class outranks a bare element whatever the injected sheet
   does next. */
.nav-list, .nav-sub { list-style: none; margin: 0; padding: 0; }

::selection { background: var(--color-ink); color: var(--color-champagne); }
/* A focus ring needs 3:1 against what it sits on. --color-gold is the display
   gold and reads 2.25:1 on white; --color-gold-deep is 3.52:1. */
:focus-visible { outline: 2px solid var(--color-gold-deep); outline-offset: 3px; }
iframe:focus { outline: 2px solid var(--color-gold-deep); outline-offset: 2px; }

.skip-link {
  position: absolute; top: -100%; left: var(--space-4); z-index: 200;
  padding: var(--space-3) var(--space-6);
  background: var(--color-ink); color: var(--color-on-ink);
  font-size: var(--t-small);
}
.skip-link:focus { top: var(--space-4); }

/* --------------------------------------------------------------------------
   3. Typography
   -------------------------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 500;
  line-height: 1.1;
  color: var(--color-ink);
  letter-spacing: -0.005em;
}
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-h4); }

em, .i { font-style: italic; }
.text-gold { color: var(--color-gold); }
h1 em, h2 em, h3 em { font-style: italic; color: var(--color-gold); }

.lead { font-size: var(--t-lead); line-height: 1.8; color: var(--color-muted); }

/* Kicker: tracked label, the recurring editorial motif.
   .masthead__kicker is the same component in the hero, so it shares this rule
   instead of restating it. As two rules they had drifted on all four values
   they had in common - 0.34em of tracking against 0.36em, baseline alignment
   against centre, 1.5rem beneath against 2rem, and a 0.75rem gap against
   1rem - which read as the label changing size between the hero and the
   sections below it. Section 7 now overrides only the space beneath.

   The negative right margin is the trailing letter-space. Letter-spacing is
   applied after the last glyph as well as between glyphs, so the box is one
   letter-space wider than the words inside it and a centred label lands half
   a space left of true centre. That is visible here because every centred
   eyebrow sits directly above a centred headline, and pulling the box in by
   exactly one space lines the two up. It costs the left-aligned eyebrows
   nothing: the space it removes is empty.

   THE EYEBROW IS A <p>, AND THAT IS THE TRAP. Every container it appears in
   styles its own body copy with a bare descendant rule - .section-head p,
   .page-hero p, .cta-band p, .split-body p, .section--ink p. Each of those is
   (0,1,1) and this rule is (0,1,0), so each of them WINS, and the label
   quietly renders as body copy: --t-lead grey instead of --t-eyebrow gold.
   That is exactly what had happened - of the 26 eyebrows across the eight
   pages, only .masthead__kicker was still rendering as designed, because the
   masthead has no bare p rule. The section labels were 20px muted grey and
   read as sub-headings.

   The fix is on the other side: every one of those rules now says
   p:not(.eyebrow), so they style body copy only and never reach the label.
   IF YOU ADD A `<container> p` RULE, ADD :not(.eyebrow) TO IT. Raising this
   rule's specificity instead would not have worked - .section-head p is
   declared after it and would still win a (0,1,1) tie on order. */
.eyebrow, .masthead__kicker {
  display: inline-flex; align-items: center; gap: var(--eyebrow-gap);
  font-family: var(--font-body);
  font-size: var(--t-eyebrow); font-weight: 600; line-height: 1.4;
  letter-spacing: var(--eyebrow-track); text-transform: uppercase;
  color: var(--color-gold-deep);
  margin-right: calc(var(--eyebrow-track) * -1);
  margin-bottom: var(--eyebrow-below);
}
.eyebrow--centered { justify-content: center; }

/* The icon that opens every eyebrow, replacing the "01 -", "02 -" numerals
   the section labels used to carry.

   Sized in em so it tracks the label at every viewport, and inheriting
   currentColor so it follows the label onto a dark section without a second
   rule. Lucide draws on a 24px grid at stroke-width 2; at this size that
   reads heavier than the 600-weight text beside it, hence 1.75.

   align-items: center needs no optical nudge at line-height 1.4 - Inter's
   cap-height block is centred in that line box to within a hundredth of an
   em, so the caps and the icon share a centre line already. */
.eyebrow svg, .masthead__kicker svg {
  flex: none;
  width: 1.25em; height: 1.25em;
  stroke-width: 1.75;
}

.section-head {
  max-width: 44rem;
  margin-bottom: clamp(2.5rem, 2rem + 3vw, 4.5rem);
}
.section-head--centered { margin-inline: auto; text-align: center; }
/* :not(.eyebrow) here and on the four rules like it below — see the eyebrow
   block above. Without it this sets the section label to 20px muted grey. */
.section-head p:not(.eyebrow) { margin-top: var(--space-4); color: var(--color-muted); font-size: var(--t-lead); }

/* --------------------------------------------------------------------------
   4. Layout
   -------------------------------------------------------------------------- */
.container { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--pad-x); }
.section { padding-block: var(--section-pad); }
.section--surface { background: var(--color-paper); }
.section--ink, .section--dark { background: var(--color-ink); }
.section--ink h2, .section--ink h3, .section--ink h4,
.section--dark h2, .section--dark h3, .section--dark h4 { color: var(--color-on-ink); }
.section--ink p:not(.eyebrow), .section--dark p:not(.eyebrow) { color: var(--color-on-ink-muted); }
.section--ink .section-head p:not(.eyebrow),
.section--dark .section-head p:not(.eyebrow) { color: var(--color-on-ink-muted); }
.section--ink .eyebrow, .section--dark .eyebrow { color: var(--color-gold); }

/* --------------------------------------------------------------------------
   5. Buttons — squared, letter-spaced, print-like
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2);
  padding: 1.05rem 2.5rem;
  font-family: var(--font-body);
  font-size: var(--t-label); font-weight: 600;
  letter-spacing: 0.22em; text-transform: uppercase;
  border: 1px solid transparent; border-radius: var(--radius);
  transition: background-color var(--fast) var(--ease), color var(--fast) var(--ease),
              border-color var(--fast) var(--ease);
  position: relative;
}
.btn svg { width: 0.95rem; height: 0.95rem; }

.btn--ink { background: var(--color-ink); color: var(--color-on-ink); }
/* Hover fills with --color-gold-deep. A white label on it is 3.52:1; the ink
   label these buttons already use at rest is 5.03:1. */
.btn--ink:hover { background: var(--color-gold-deep); color: var(--color-ink); }

.btn--gold { background: var(--color-gold); color: var(--color-ink); }
.btn--gold:hover { background: var(--color-gold-deep); color: var(--color-ink); }

.btn--outline { border-color: var(--color-ink); color: var(--color-ink); }
.btn--outline:hover { background: var(--color-ink); color: var(--color-on-ink); }

.btn--outline-light { border-color: var(--color-on-ink-line); color: var(--color-on-ink); }
.btn--outline-light:hover { border-color: var(--color-gold); color: var(--color-gold); }

.btn--dark { background: var(--color-ink); color: var(--color-on-ink); }
.btn--dark:hover { background: var(--color-gold-deep); color: var(--color-ink); }

/* Editorial text link */
.link-arrow {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-size: var(--t-label); font-weight: 600; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--color-ink);
  border-bottom: 1px solid var(--color-gold); padding-bottom: 4px;
}
.link-arrow svg { width: 0.9rem; height: 0.9rem; color: var(--color-gold); transition: transform var(--med) var(--ease); }
.link-arrow:hover svg { transform: translateX(5px); }

/* --------------------------------------------------------------------------
   6. Header — editorial masthead bar (light, always solid)
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255, 255, 255, 0.94);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-bottom: var(--rule);
}

.site-header .container {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-8);
  height: 5rem; max-width: var(--wrap-wide);
}

.brand { display: flex; align-items: baseline; gap: var(--space-3); white-space: nowrap; }
.brand span { font-family: var(--font-display); font-size: 1.5rem; font-weight: 500; letter-spacing: 0.01em; color: var(--color-ink); }
.brand em { font-style: italic; color: var(--color-gold); }

.site-nav { display: flex; align-items: center; gap: clamp(1.5rem, 3vw, 2.75rem); }
.nav-list { display: flex; align-items: center; gap: clamp(1.25rem, 2.4vw, 2.25rem); }
.nav-list a {
  font-size: var(--t-label); font-weight: 600; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--color-text); position: relative; padding-block: var(--space-2);
}
.nav-list a::after {
  content: ""; position: absolute; left: 0; bottom: 0; width: 100%; height: 1px;
  background: var(--color-gold); transform: scaleX(0); transform-origin: left;
  transition: transform var(--med) var(--ease);
}
.nav-list a:hover::after, .nav-list a[aria-current="page"]::after { transform: scaleX(1); }

.nav-cta { display: inline-flex; padding: 0.7rem 1.5rem; }

.nav-toggle { display: none; color: var(--color-ink); width: 2.75rem; height: 2.75rem; align-items: center; justify-content: center; }
.nav-toggle svg { width: 1.5rem; height: 1.5rem; }
.nav-toggle .icon-close { display: none; }
.nav-open .nav-toggle .icon-menu { display: none; }
.nav-open .nav-toggle .icon-close { display: block; }

/* Burger panel — the overflow menu, and the phone menu, and the same thing at
   every width in between. This used to be @media (max-width: 71.99em), a
   value raised by hand each time the Gold nav grew. What replaced it is
   global-js/nav-fit.js: it keeps as many items inline as the row can hold and
   nests the rest here, so the nav no longer depends on a number that was only
   ever right for one agent's name length. */
/* A drawer from the right rather than a band dropping the full width of the
   window. Width is half the screen from 442px up and the whole screen 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. */
.nav-panel {
  position: fixed; top: 5rem; right: 0; left: auto;
  display: flex; flex-direction: column;
  justify-content: flex-start;
  gap: var(--space-8); padding: var(--space-8);
  background: var(--color-ink);
  width: 50%;
  height: calc(100svh - 5rem);
  transform: translateX(100%);
  opacity: 0;
  visibility: hidden;
  /* 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 var(--med) var(--ease),
              opacity var(--med) var(--ease),
              visibility 0s linear var(--med);
  overflow-y: auto; z-index: 90;
}
.nav-open .nav-panel {
  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-open .site-header { background: var(--color-bg); }
.nav-open .site-header .brand span { color: var(--color-ink); }
.nav-panel .nav-list { flex-direction: column; align-items: flex-start; gap: var(--space-6); width: 100%; }
.nav-panel .nav-list a { color: var(--color-on-ink); font-size: 1.25rem; letter-spacing: 0.14em; }
body.nav-open { overflow: hidden; }

/* The burger appears only when the panel 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 panel. */
.nav-toggle { display: inline-flex; }
[data-nav-overflow="false"] .nav-toggle { display: none; }

/* 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. */
.site-nav .nav-list a,
.site-nav .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 > a { 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/timeless.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.32em; height: 0.32em; flex: none;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: translateY(-0.1em) rotate(45deg);
  transition: transform var(--fast) var(--ease);
}

/* Inline: the dropdown. Square corners and a hairline, like every other
   framed thing in this template - it is a clipping, not a popover. */
[data-nav-fit-inline] .nav-sub {
  position: absolute;
  top: 100%; left: calc(var(--space-4) * -1);
  min-width: max-content;
  margin-top: var(--space-4);
  padding-block: var(--space-2);
  background: var(--color-bg);
  border: var(--rule);
  border-radius: var(--radius);
  box-shadow: 0 24px 50px -30px rgba(31, 41, 55, 0.45);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity var(--fast) var(--ease),
              transform var(--fast) var(--ease),
              visibility var(--fast) var(--ease);
  z-index: 110;
}
/* 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: calc(var(--space-4) * -1); height: var(--space-4);
}
[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 a { display: block; padding: var(--space-2) var(--space-4); }
/* The sliding gold rule is drawn at the link's bottom edge, which inside a
   padded row lands in the middle of the gap between items. */
[data-nav-fit-inline] .nav-sub a::after { display: none; }
[data-nav-fit-inline] .nav-sub a:hover { background: var(--color-paper); }

/* 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. */
[data-nav-fit-panel] .nav-group {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-4);
}
[data-nav-fit-panel] .nav-sub {
  gap: var(--space-4);
  margin-left: var(--space-2);
  padding-left: var(--space-4);
  border-left: 1px solid var(--color-on-ink-line);
}
[data-nav-fit-panel] .nav-sub a { font-size: 1rem; }
[data-nav-fit-panel] .nav-caret { display: none; }

/* --------------------------------------------------------------------------
   7. MASTHEAD HERO — signature: centered editorial opener + framed band
   -------------------------------------------------------------------------- */
.masthead { background: var(--color-bg); padding-top: clamp(3rem, 2rem + 4vw, 6rem); overflow: hidden; }
.masthead .container { max-width: var(--wrap-wide); text-align: center; }

/* Shares .eyebrow's rule in section 3 - it is the same label doing the same
   job - so all this needs is the hero size and the extra air the hero asks
   for. It sits above --t-masthead, the largest headline in the template. */
.masthead__kicker {
  font-size: var(--t-eyebrow-hero);
  margin-bottom: clamp(1.75rem, 1.35rem + 1.2vw, 2.5rem);
}
.masthead__title {
  font-size: var(--t-masthead); line-height: 1.02; letter-spacing: -0.015em;
  max-width: 18ch; margin-inline: auto;
  /* The headline is agent copy, so its length is not known at design time.
     Long words have to break rather than push the page sideways. */
  overflow-wrap: break-word;
}
.masthead__lead {
  max-width: 46ch; margin: var(--space-8) auto 0; font-size: var(--t-lead);
  line-height: 1.85; color: var(--color-muted);
}
.masthead__actions {
  display: flex; flex-wrap: wrap; gap: var(--space-4); justify-content: center;
  margin-top: var(--space-10);
}
.masthead__frame { margin-top: clamp(3rem, 2rem + 4vw, 5.5rem); position: relative; }
.masthead__frame img { width: 100%; aspect-ratio: 21 / 9; object-fit: cover; }
@media (max-width: 47.99em) { .masthead__frame img { aspect-ratio: 4 / 3; } }
.masthead__frame::after {
  content: ""; position: absolute; inset: var(--space-4);
  border: 1px solid rgba(244, 242, 236, 0.45); pointer-events: none;
}
.masthead__meta {
  display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-4) clamp(2rem, 5vw, 4rem);
  padding-block: var(--space-8); border-bottom: var(--rule);
}
.masthead__meta div { text-align: center; }
.masthead__meta dt { font-size: var(--t-label); font-weight: 600; letter-spacing: 0.24em; text-transform: uppercase; color: var(--color-muted); margin-bottom: 4px; }
.masthead__meta dd { font-family: var(--font-display); font-size: 1.5rem; color: var(--color-ink); }
.masthead__meta dd em { font-style: italic; color: var(--color-gold); }

/* --------------------------------------------------------------------------
   8. Interior page header — light editorial
   -------------------------------------------------------------------------- */
.page-hero { background: var(--color-paper); border-bottom: var(--rule); }
.page-hero .container {
  padding-block: clamp(4.5rem, 3rem + 6vw, 8rem) clamp(3rem, 2rem + 3vw, 5rem);
  text-align: center; max-width: 54rem;
}
.page-hero h1 { color: var(--color-ink); font-size: var(--t-h1); }
/* The interior-page counterpart of .masthead__kicker, so it takes the hero
   size. These two are the only eyebrows that open a page rather than a band. */
.page-hero .eyebrow { font-size: var(--t-eyebrow-hero); justify-content: center; }
.page-hero p:not(.eyebrow) { color: var(--color-muted); font-size: var(--t-lead); margin-top: var(--space-4); max-width: 48ch; margin-inline: auto; }

/* --------------------------------------------------------------------------
   9. Editorial split
   -------------------------------------------------------------------------- */
.split { display: grid; gap: clamp(2.5rem, 2rem + 4vw, 6rem); align-items: center; }
@media (min-width: 64em) {
  .split { grid-template-columns: repeat(12, 1fr); }
  .split-media { grid-column: 1 / 7; }
  .split-body { grid-column: 8 / 13; }
  .split--reverse .split-media { grid-column: 7 / 13; order: 2; }
  .split--reverse .split-body { grid-column: 1 / 6; order: 1; }
}
.frame { position: relative; }
.frame img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.frame--landscape img { aspect-ratio: 4 / 3; }
.frame::after { content: ""; position: absolute; inset: 0; margin: var(--space-3); border: 1px solid rgba(255, 255, 255, 0.5); pointer-events: none; }
.frame-caption { position: absolute; left: 0; bottom: 0; background: var(--color-bg); padding: var(--space-4) var(--space-6); display: flex; flex-direction: column; gap: 2px; border-top: var(--rule-gold); }
.frame-caption strong { font-family: var(--font-display); font-size: 1.125rem; color: var(--color-ink); font-weight: 500; }
.frame-caption span { font-size: var(--t-label); letter-spacing: 0.2em; text-transform: uppercase; color: var(--color-gold-deep); }
.split-body h2 { margin-bottom: var(--space-6); }
.split-body p:not(.eyebrow) { color: var(--color-muted); margin-bottom: var(--space-4); }
.split-body .link-arrow, .split-body .btn { margin-top: var(--space-4); }

/* --------------------------------------------------------------------------
   10. COMMUNITIES — lead feature + index ledger
   --------------------------------------------------------------------------
   The source rendered invented listings here: a "No. 01" cover estate over a
   numbered index of three more, with prices and bed/bath counts. That is the
   signature of the design, and it is also the one section that cannot survive
   the conversion intact - we do not hold listing data, and the IDX widget
   brings its own card design.

   So the frame stays and the contents change: the agent's first community is
   the cover, the rest are the index, and every row links into the IDX scoped
   to that city. The numbering stays with the frame - it indexes the plates of
   a catalogue, which is what this section is. Dropped with the listings:
   __specs and __price.
   -------------------------------------------------------------------------- */
.feature-estate { display: grid; gap: clamp(2rem, 1.5rem + 3vw, 4rem); align-items: center; }
@media (min-width: 64em) { .feature-estate { grid-template-columns: 1.2fr 1fr; } }
.feature-estate__media { position: relative; overflow: hidden; }
.feature-estate__media img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; transition: transform 1.3s var(--ease); }
.feature-estate:hover .feature-estate__media img { transform: scale(1.04); }
.feature-estate__tag { position: absolute; top: var(--space-4); left: var(--space-4); background: var(--color-bg); color: var(--color-gold-deep); font-size: var(--t-label); font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; padding: var(--space-2) var(--space-4); }
/* The index numeral over the cover community. It had been swapped for the
   .service-icon square; the numerals are the signature of this design - it is
   a catalogue, and a catalogue numbers its plates - so the section reads as
   "No. 01" over an index of 02, 03, 04 again. .ledger__no below is the same
   mark at index size, and the two have to stay in step: the cover is 01 and
   the ledger opens at 02 because the ledger skips it. */
/* Sized just under __name at every width, which is the relationship the
   source had (48 under 52 on a desktop). Its own clamp bottomed out at 2rem
   while __name now scales below that on a phone, so at 390px the numeral came
   out larger than the place it numbers; this range tracks the name down. */
.feature-estate__no { font-family: var(--font-display); font-style: italic; font-size: clamp(1.5rem, 1.2rem + 1.3vw, 2.25rem); color: var(--color-gold); line-height: 1; display: block; margin-bottom: var(--space-4); }
/* Was --t-h2 - the same 52px as the section's own <h2> directly above it, so
   an h3 and the h2 it sits under rendered identically and the hierarchy read
   flat. Sized between --t-h2 and .ledger__name instead: 52 / 40 / 22. */
.feature-estate__name { font-size: clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem); margin-bottom: var(--space-2); }
.feature-estate__loc { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--t-small); color: var(--color-muted); margin-bottom: var(--space-6); }
.feature-estate__loc svg { width: 0.9rem; height: 0.9rem; color: var(--color-gold); }
.feature-estate__desc { color: var(--color-muted); margin-bottom: var(--space-6); }
.feature-estate__foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-6); padding-top: var(--space-6); border-top: var(--rule); flex-wrap: wrap; }

.ledger { margin-top: clamp(3rem, 2rem + 3vw, 5rem); border-top: 1px solid var(--color-ink); }
.ledger__row { display: grid; gap: var(--space-4) var(--space-8); align-items: center; padding-block: var(--space-8); border-bottom: var(--rule); transition: background-color var(--fast) var(--ease); }
.ledger__row:hover { background: var(--color-paper); }
/* 3.5rem is the width of two italic serif digits at 1.5rem, which is what
   this column holds. It had narrowed to 2rem for a pin icon. */
@media (min-width: 48em) { .ledger__row { grid-template-columns: 3.5rem 8rem 1fr auto; } }
.ledger__no { font-family: var(--font-display); font-style: italic; font-size: 1.5rem; color: var(--color-gold); }
.ledger__thumb { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }
.ledger__name { font-family: var(--font-display); font-size: 1.375rem; color: var(--color-ink); }
.ledger__loc { font-size: var(--t-small); color: var(--color-muted); }
.ledger__cta { color: var(--color-gold-deep); display: inline-flex; }
.ledger__cta svg { width: 1.1rem; height: 1.1rem; transition: transform var(--med) var(--ease); }
.ledger__row:hover .ledger__cta svg { transform: translate(3px, -3px); }

.section-foot { margin-top: clamp(2.5rem, 2rem + 3vw, 4rem); text-align: center; }

/* --------------------------------------------------------------------------
   11. Editorial cards — buyer/seller guidance
   -------------------------------------------------------------------------- */
.service-grid { display: grid; gap: 0; grid-template-columns: 1fr; }
@media (min-width: 48em) { .service-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64em) { .service-grid { grid-template-columns: repeat(3, 1fr); } }
.service-card { padding: var(--space-8) var(--space-8) var(--space-10); border-top: 1px solid var(--color-ink); background: transparent; transition: background-color var(--med) var(--ease); }
.service-card:hover { background: var(--color-paper); }
/* .service-num is gone with the "No. 01 / No. 02 / No. 03" it held. Each card
   already opened with its own icon directly underneath, so the numeral was a
   second mark saying less: nothing on the page refers to a card by number,
   and the grid reflows to one column on a phone where the count is the only
   thing the numbering could have been describing. */

/* The template's icon mark. Used for the card icons, the values list on About,
   the contact details and the featured community, so a mark is the same
   object wherever it appears. */
.service-icon { display: inline-grid; place-items: center; width: 3rem; height: 3rem; border: var(--rule-gold); color: var(--color-gold-deep); margin-bottom: var(--space-6); }
.service-icon svg { width: 1.3rem; height: 1.3rem; }
.service-card h3 { font-size: 1.5rem; margin-bottom: var(--space-3); }
.service-card p { color: var(--color-muted); font-size: var(--t-small); line-height: 1.8; }
.service-card .link-arrow { margin-top: var(--space-6); }

/* --------------------------------------------------------------------------
   12. Process steps
   -------------------------------------------------------------------------- */
.step-grid { display: grid; gap: var(--space-8); grid-template-columns: 1fr; }
@media (min-width: 48em) { .step-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64em) { .step-grid--4 { grid-template-columns: repeat(4, 1fr); } }
.step { padding-top: var(--space-6); border-top: 1px solid var(--color-border); }
.section--ink .step, .section--dark .step { border-color: var(--color-on-ink-line); }
/* Was ::before with counter(step, decimal-leading-zero) - 01 to 04 - and the
   counter-reset/increment pair that fed it. The mark is an icon per step now,
   so it says what the step is rather than where it sits. The order is not lost
   with the digits: these grids run left to right in reading order, and each
   heading names its stage.

   Unbordered, unlike .service-icon. A step is a stage in a sequence and sits
   under a hairline rule already; boxing it as well gives the row two frames. */
.step__mark { display: block; color: var(--color-gold-deep); margin-bottom: var(--space-4); }
.step__mark svg { width: 1.85rem; height: 1.85rem; stroke-width: 1.5; }
.section--ink .step__mark, .section--dark .step__mark { color: var(--color-gold); }
.step h3 { font-size: 1.25rem; margin-bottom: var(--space-3); }
.step p { font-size: var(--t-small); color: var(--color-muted); line-height: 1.75; }
.section--ink .step p, .section--dark .step p { color: var(--color-on-ink-muted); }

/* --------------------------------------------------------------------------
   13. CTA band — solid charcoal, centered
   -------------------------------------------------------------------------- */
.cta-band { background: var(--color-ink); color: var(--color-on-ink); text-align: center; position: relative; overflow: hidden; }
.cta-band .container { max-width: 48rem; position: relative; }
.cta-band .eyebrow { color: var(--color-gold); justify-content: center; }
.cta-band h2 { color: var(--color-on-ink); margin-bottom: var(--space-4); }
.cta-band p:not(.eyebrow) { color: var(--color-on-ink-muted); font-size: var(--t-lead); margin-bottom: var(--space-8); }
.cta-band .hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-4); justify-content: center; }

/* --------------------------------------------------------------------------
   14. Values / checklist
   -------------------------------------------------------------------------- */
.value-list { display: flex; flex-direction: column; gap: var(--space-6); margin-top: var(--space-8); }
.value-item { display: flex; gap: var(--space-4); align-items: flex-start; }
.value-item .service-icon { margin-bottom: 0; flex-shrink: 0; width: 2.75rem; height: 2.75rem; }
.value-item .service-icon svg { width: 1.1rem; height: 1.1rem; }
.value-item h4 { font-family: var(--font-body); font-weight: 600; font-size: 1rem; margin-bottom: var(--space-1); }
.value-item p { font-size: var(--t-small); color: var(--color-muted); }

.checklist { display: flex; flex-direction: column; gap: var(--space-3); margin-block: var(--space-6); }
.checklist li { display: flex; align-items: flex-start; gap: var(--space-3); color: var(--color-text); font-size: var(--t-small); }
.checklist svg { width: 1.1rem; height: 1.1rem; color: var(--color-gold); flex-shrink: 0; margin-top: 3px; }

/* Pill row — the credentials strip on About. */
.pill-row { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-top: var(--space-8); }
.pill { font-size: var(--t-label); font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: var(--color-gold-deep); border: var(--rule-gold); padding: var(--space-2) var(--space-4); }

/* --------------------------------------------------------------------------
   15. Contact page
   -------------------------------------------------------------------------- */
.contact-layout { display: grid; gap: clamp(2.5rem, 2rem + 4vw, 5rem); }
@media (min-width: 64em) { .contact-layout { grid-template-columns: 7fr 5fr; align-items: start; } }
.contact-info { display: flex; flex-direction: column; gap: var(--space-8); }
.contact-item { display: flex; gap: var(--space-4); align-items: flex-start; }
.contact-item .service-icon { margin-bottom: 0; flex-shrink: 0; }
.contact-item h3 { font-family: var(--font-body); font-size: var(--t-label); font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase; color: var(--color-muted); margin-bottom: var(--space-1); }
.contact-item p, .contact-item a { font-size: var(--t-lead); color: var(--color-ink); line-height: 1.5; }
.contact-item a:hover { color: var(--color-gold-deep); }
.contact-map { margin-top: var(--section-pad); }
.contact-map img { width: 100%; aspect-ratio: 21 / 9; object-fit: cover; }

/* --------------------------------------------------------------------------
   16. Reveal animations
   -------------------------------------------------------------------------- */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity var(--slow) var(--ease), transform var(--slow) var(--ease); transition-delay: var(--reveal-delay, 0ms); }
.reveal.is-visible { opacity: 1; transform: translateY(0); }

.masthead__kicker, .masthead__title, .masthead__lead, .masthead__actions, .masthead__frame { animation: rise 1s var(--ease) both; }
.masthead__title { animation-delay: 0.08s; }
.masthead__lead { animation-delay: 0.18s; }
.masthead__actions { animation-delay: 0.28s; }
.masthead__frame { animation-delay: 0.38s; }
@keyframes rise { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: translateY(0); } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
  .reveal { opacity: 1; transform: none; }
}


/* =====================================================================
   ADDED IN CONVERSION — markup the source template did not have
   ===================================================================== */

/* The IDX. The widget renders into this container asynchronously, so it
   reserves its height and shows a paper-toned shimmer until it does. */
.ylopo-easy-widget { min-height: 420px; position: relative; }
.ylopo-easy-widget.ylopo-loading::before {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, var(--color-paper) 25%, #fff 37%, var(--color-paper) 63%);
  background-size: 400% 100%;
  animation: timeless-shimmer 1.4s ease infinite;
}
.ylopo-easy-widget.ylopo-ready::before { display: none; }
@keyframes timeless-shimmer { 0% { background-position: 100% 0; } 100% { background-position: 0 0; } }

/* QA build notices, visible while the reviews, sold-properties and contact
   widgets are being built. Remove once all three ship. */
.qa-note {
  display: flex; align-items: flex-start; gap: var(--space-4); flex-wrap: wrap;
  max-width: 60ch; margin-inline: auto;
  padding: var(--space-6) var(--space-8);
  border: 1px dashed var(--color-gold);
  background: var(--color-champagne-soft);
  text-align: left;
}
.qa-note__tag {
  flex: none;
  font-size: var(--t-label); font-weight: 700; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--color-ink); background: var(--color-gold);
  padding: var(--space-1) var(--space-3);
}
.qa-note p { font-size: var(--t-small); flex: 1 1 22ch; margin: 0; color: var(--color-text); }
.section--ink .qa-note, .section--dark .qa-note { background: rgba(201, 168, 106, 0.10); }
.section--ink .qa-note p, .section--dark .qa-note p { color: var(--color-on-ink); }

@media (max-width: 40em) { .qa-note { flex-direction: column; gap: var(--space-3); } }

/* 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.

   40em to match this file's own phone breakpoint. 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: 40em) {
  .btn { width: 100%; justify-content: center; text-align: center; }
  .community .btn,
  .ylopo-easy-widget .btn { width: auto; }

  .cta-band .hero-actions { flex-direction: column; align-items: stretch; }

  /* .link-arrow is a text CTA rather than a button, so it is centred without
     being stretched. fit-content keeps its underline and arrow tight to the
     label instead of dragging them across the column. */
  .link-arrow { display: flex; width: fit-content; margin-inline: auto; }
}

/* 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: var(--space-8, 2rem) var(--space-4, 1rem);
  text-align: center;
  border-top: 1px solid var(--color-border, #E5E7EB);
  border-bottom: 1px solid var(--color-border, #E5E7EB);
}
.sold-empty .sold-empty__title {
  font-family: var(--font-display, Georgia, serif);
  font-size: var(--t-h4, 1.375rem); font-weight: 400;
  margin: 0 0 var(--space-3, 0.75rem);
  color: var(--color-ink, #111827);
}
.sold-empty p { margin: 0; font-size: var(--t-body, 1rem); color: var(--color-muted, #6B7280); }
.sold-empty a { color: var(--color-gold, #C9A86A); text-decoration: underline; text-underline-offset: 0.2em; }
.sold-empty a:hover { color: var(--color-gold-deep, #A5834E); }

/* 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 var(--med) var(--ease), visibility 0s linear var(--med);
  z-index: 89;
}
.nav-backdrop.is-open {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}
