@charset "UTF-8";
/* ─────────────────────────────────────────────────────────────
   Lauren Rose Realty — theme
   Editorial, warm, boutique. Fraunces (display) + Inter (body).
   Palette: rose / rose-deep / ink / paper / clay / slate / hairline.
   No light green anywhere (client rule — outgoing brokerage color).
   ───────────────────────────────────────────────────────────── */
:root{
  --rose:#3879BD;--rose-deep:#2A5F96;--rose-soft:#EEC8CB;--pop:#2A5F96; /* was #F2415C */
  /* small-text rose: --rose reads 3.56:1 on paper, under the 4.5 floor for the
     12-13px uppercase eyebrows and chips. Same hue, deepened to 5.3:1. Display
     italics stay on --rose (large text only needs 3:1). */
  --rose-ink:#2A5F96;
  --ink:#1E2E44;--ink-2:#4A5A72;--paper:#FFFBF2;--cream:#FFF3D9;--blush:#FFF3D9;
  --clay:#4A5A72;--clay-deep:#4A5A72;--slate:#4A5A72;--line:#E9DFC8;
  --r-lg:20px;--r-md:14px;
  --shadow-1:0 2px 6px rgba(30,46,68,.05),0 10px 28px rgba(30,46,68,.07);
  --shadow-2:0 6px 16px rgba(30,46,68,.08),0 24px 56px rgba(30,46,68,.12);
  --wrap:1160px;
  --broke-h:0px; /* the brokerage strip above the nav: 35px only on pages that display RMLS data (body.has-brokebar), 0 elsewhere so nothing is offset */
}
*{margin:0;padding:0;box-sizing:border-box}
/* overscroll shows paper above the page, ink below — no white flash under the dark footer on iOS */
/* clip, never hidden: `overflow:hidden` on the root breaks position:fixed
   inside it on iOS Safari, and the filters drawer parks off to the right */
html{scroll-behavior:smooth;overflow-x:clip;background:linear-gradient(var(--paper) 50%,#14325C 50%)} /* ello: lower half = the footer's deep blue */
body{
  font-family:'Inter',system-ui,sans-serif;background:var(--paper);color:var(--ink);
  line-height:1.65;font-size:16.5px;-webkit-font-smoothing:antialiased;
  min-height:100svh;display:flex;flex-direction:column;
}
main{flex:1 0 auto}
h1,h2,h3{font-family:'Fraunces',Georgia,serif;font-weight:500;letter-spacing:-.01em}
a{color:var(--rose-deep);-webkit-tap-highlight-color:transparent}
img{max-width:100%;display:block}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 24px;width:100%}
.center{text-align:center}
.skip{position:absolute;left:-9999px;top:0;background:var(--ink);color:#fff;padding:10px 18px;z-index:200;border-radius:0 0 10px 0}
.skip:focus{left:0}
:focus-visible{outline:2px solid var(--rose-deep);outline-offset:2px}

/* reveal, reduced motion and the ?nofx=1 QA mode all moved to the engine's
   core/assets/motion.css. The rule that stood here was `.fade{opacity:0}` with
   no html.js guard, so the 109 .fade elements on this site depended on a
   script to become visible at all: any browser without IntersectionObserver
   showed a blank page. Only the hero's screenshot height is site-specific. */
.no-fx .hero{min-height:860px}

/* ── brokerage strip [RMLS obligation 8] ─────────────────── */
/* The firm of record, above the fold on every page. Checklist 1 asks for the
   name or logo in a readily visible colour, in type no smaller than the median
   used for the listing data. The median here is 13.5px (.lh-price span, the
   .lspecs-h headings), so this reads at 14.5px in --ink, the same size as the
   card courtesy line and above the floor either way. It is a sibling of
   .nav, never a child: the phone bar translates itself off the screen while you
   scroll down and this line must not go with it. */
.brokebar{position:relative;z-index:89;flex:none;background:var(--paper);border-bottom:1px solid var(--line)}
body.has-brokebar{--broke-h:35px}
.brokebar .wrap{display:flex;align-items:center;justify-content:center;gap:10px;height:calc(var(--broke-h) - 1px)}
.brokebar-mark{height:17px;width:auto;flex:none}
.brokebar-t{font-size:14.5px;line-height:1.2;color:var(--ink);white-space:nowrap}
.brokebar-t strong{font-weight:600}
/* ello: an admin-assigned theme banner in the strip (theme_banner()); one line, never wraps the 35px bar */
.brokebar-t.is-banner{display:flex;align-items:baseline;gap:5px;min-width:0}.brokebar-t .bb-text{min-width:0;overflow:hidden;text-overflow:ellipsis}.brokebar-t.is-banner a,.bb-sep,.bb-firm{flex:none}.bb-sep{color:var(--slate);font-size:14.5px;line-height:1.2}
.brokebar-t a{color:var(--rose-deep);font-weight:600;text-decoration:underline;text-underline-offset:2px}
/* the home page only: its nav is fixed over the hero photo, so the strip is
   fixed above it on the paper ground rather than a band that scrolls away and
   leaves a transparent gap over the bar. The nav starts below it. */
.brokebar.fixed{position:fixed;top:0;left:0;right:0;transition:transform .35s ease}
.nav.overlay{top:var(--broke-h);transition:top .35s ease,background .35s,border-color .35s}
/* Eric, 2026-09-13: once the page is scrolled the strip slides up out of the way
   and the bar takes the top edge; scrolling back to the top brings it back.
   Home page only (the fixed strip); on other pages the strip is in flow and
   scrolls away by itself. */
body.scrolled .brokebar.fixed{transform:translateY(-100%)}
body.scrolled .nav.overlay{top:0}
@media(prefers-reduced-motion:reduce){.brokebar.fixed,.nav.overlay{transition:none}}
.has-overlay-nav .hero{padding-top:calc(68px + var(--broke-h))}

/* ── nav ─────────────────────────────────────────────────── */
.nav{position:sticky;top:0;z-index:90;background:rgba(255,251,242,.88);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-bottom:1px solid var(--line);transition:background .35s,border-color .35s}
.nav .wrap{display:flex;align-items:center;gap:22px;height:68px;flex-wrap:nowrap}
.brand{display:flex;align-items:center;gap:9px;font-family:'Fraunces',serif;font-size:19.5px;font-weight:400;letter-spacing:-.02em;color:var(--ink);text-decoration:none;transition:color .35s;white-space:nowrap;flex:none} /* weight was 600, no letter-spacing */
.brand .rose-mark{width:22px;height:28px;color:var(--rose);flex:none;transition:color .35s}
/* one axis for the whole bar: the icon links are 44px tall and the text
   links are 18px, and without this the words sat above the icons */
.nav .links{display:flex;align-items:center;gap:22px;list-style:none;margin-left:auto;flex-wrap:nowrap;white-space:nowrap}
.nav .links a{font-size:14px;font-weight:500;color:var(--slate);text-decoration:none;transition:color .2s}
.nav .links a:hover{color:var(--rose-deep)}
/* desktop only (the 820px menu restyles these links into a dashed-border list):
   a hairline draws in from the left on hover, in whatever colour the link is */
@media(min-width:821px){
  .nav .links a{position:relative}
  .nav .links a::after{content:"";position:absolute;left:0;right:0;bottom:-6px;height:1.5px;background:currentColor;border-radius:2px;transform:scaleX(0);transform-origin:left center;transition:transform .3s cubic-bezier(.2,.6,.2,1)}
  .nav .links a:hover::after,.nav .links a[aria-current="page"]::after{transform:scaleX(1)}
}
/* current page: themed reddish text, never a pill */
.nav .links a[aria-current="page"]{color:var(--rose-deep)}
.nav.overlay:not(.scrolled) .links a[aria-current="page"]{color:var(--rose-soft)}
.nav .cta{display:inline-flex;align-items:center;gap:7px;flex:none;font-size:13px;font-weight:600;color:var(--ink);background:#EACF9B;padding:9px 17px;border-radius:99px;text-decoration:none;white-space:nowrap;transition:background .2s,transform .2s}
.nav .cta:hover{background:#E2C283;transform:translateY(-1px)} /* hover was #DA2E4A */
.nav .cta .cta-i{width:16px;height:16px;flex:none}
/* narrower desktops/tablets: keep every text link, just tighten spacing and
   collapse the CTA to a compact icon so the bar stays on ONE line (never wraps) */
@media(max-width:1080px){
  .nav .wrap{gap:16px}
  .nav .links{gap:15px}
  .nav .links a{font-size:13.5px}
  .nav .cta{padding:0;width:36px;height:36px;justify-content:center}
  .nav .cta .cta-t{display:none}
  .nav .cta .cta-i{width:18px;height:18px}
}
/* transparent over the home hero, solid once scrolled */
.nav.overlay{position:fixed;left:0;right:0;background:transparent;border-bottom-color:transparent}
.nav.overlay:not(.scrolled) .brand,.nav.overlay:not(.scrolled) .links a{color:#fff}
.nav.overlay:not(.scrolled) .brand .rose-mark{color:var(--rose-soft)}
.nav.overlay:not(.scrolled) .links a:hover{color:var(--rose-soft)}
.nav.overlay.scrolled{background:rgba(255,251,242,.9);backdrop-filter:blur(12px);border-bottom-color:var(--line)}
.menu-btn{display:none;width:46px;height:46px;border:0;background:none;cursor:pointer;flex-direction:column;gap:5.5px;align-items:center;justify-content:center;margin-left:auto}
.menu-btn span{width:23px;height:1.8px;background:var(--ink);border-radius:2px;transition:.28s}
.menu-btn span:nth-child(2){width:14px;margin-right:9px}
.nav.overlay:not(.scrolled) .menu-btn span{background:#fff}
.menu-btn[aria-expanded="true"] span:nth-child(1){transform:translateY(7.3px) rotate(45deg)}
.menu-btn[aria-expanded="true"] span:nth-child(2){opacity:0}
.menu-btn[aria-expanded="true"] span:nth-child(3){transform:translateY(-7.3px) rotate(-45deg)}
.m-cta,.m-meta{display:none}
@media(max-width:820px){
  .menu-btn{display:flex}
  /* align-items on the desktop bar is `center`, and in a column that centred
     every row: the words sat in a narrow stack with a divider only as wide as
     the word under each. The open menu is a full-width list, flush left with
     the brand mark. */
  .nav .links{display:none;position:fixed;top:68px;left:0;right:0;height:calc(100vh - 68px);height:calc(100dvh - 68px);background:var(--paper);flex-direction:column;align-items:stretch;gap:0;padding:6px 0 44px;margin:0;overflow-y:auto;z-index:95;
    background-image:radial-gradient(90% 50% at 50% 110%,var(--blush),transparent 70%)}
  .nav.open .links{display:flex;animation:menuin .28s cubic-bezier(.2,.6,.2,1)}
  @keyframes menuin{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
  .nav.open{background:var(--paper)!important;border-bottom-color:var(--line)!important}
  .nav.open .brand,.nav.open .links a{color:var(--ink)!important}
  /* subtle, on-brand active state: rose + the brand's signature italic (no pill) */
  .nav.open .links a[aria-current="page"]{color:var(--rose-deep)!important;font-style:italic}
  .nav.open .brand .rose-mark{color:var(--rose)!important}
  /* the close (✕) must stay dark on the light open menu — beats the overlay white rule */
  .nav.open .menu-btn span{background:var(--ink)!important}
  /* 56px rows, the word on the header's own 24px gutter, and a hairline that
     runs the whole width of the sheet rather than the width of the word */
  .nav .links a{display:flex;align-items:center;min-height:56px;padding:8px 24px;margin:0;font-size:21px;font-family:'Fraunces',serif;color:var(--ink);border-bottom:1px solid var(--line)}
  .nav .links li:nth-last-child(-n+2) a{border-bottom:none}
  .m-cta{display:block;margin:22px 24px 0}
  /* full width under the list, not a pill floating in the middle of it; the text
     keeps the same left edge as every word above it.
     .nav.open scope so the white text OUTRANKS ".nav.open .links a{color:ink!important}" (same importance, more classes) */
  .m-cta a.btn,.nav.open .m-cta a.btn{display:flex;align-items:center;width:100%;min-height:56px;text-align:left;justify-content:flex-start;font-family:'Inter',sans-serif;font-size:16px;border-bottom:none;border-radius:14px;padding:8px 22px;margin:0;color:var(--ink)!important}
  .m-meta{display:flex;gap:12px 16px;margin:22px 24px 0;flex-wrap:wrap;justify-content:flex-start}
  .m-meta a{font-family:'Inter',sans-serif!important;font-size:13.5px!important;font-weight:600;border-bottom:none!important;min-height:44px!important;padding:0!important;margin:0!important;display:inline-flex!important;align-items:center;color:var(--rose-deep)!important}
  .nav .cta{display:none}
  /* the strip reads from the left edge on phones, on the header's own gutter */
  .brokebar .wrap{justify-content:flex-start}
  /* the menu sheet is fixed at 68px, the height of the bar, which assumes the
     bar starts at 0. At the top of a page the bar starts below the strip, so an
     open menu would cover its own hamburger. The page is locked while the menu
     is open, so pinning the bar for that one state costs nothing. */
  .nav.open,.nav.overlay.open{position:fixed;top:0;left:0;right:0}
}

/* ── buttons ─────────────────────────────────────────────── */
.btn{display:inline-block;padding:14px 28px;border-radius:99px;border:0;cursor:pointer;font-family:'Inter',sans-serif;font-size:15px;font-weight:600;text-decoration:none;transition:transform .2s,box-shadow .2s,background .2s,border-color .2s,color .2s}
.btn.primary{background:#EACF9B;color:var(--ink);box-shadow:0 8px 24px rgba(20,50,92,.18)} /* shadow was rgba(242,65,92,.34) */
.btn.primary:hover{background:#E2C283;transform:translateY(-2px);box-shadow:0 12px 30px rgba(20,50,92,.24)} /* hover was #DA2E4A, shadow rgba(242,65,92,.44) */
/* hero button sits on the photo: neutral dark shadow, held through hover (Eric, 2026-07-29) */
.hero .btn.primary{box-shadow:-1px 4px 22px rgb(6 14 26 / 34%)}
.btn.ghost{background:transparent;color:var(--ink);border:1px solid var(--line)}
.btn.ghost:hover{border-color:var(--rose);color:var(--rose-deep)}
/* editorial CTA pair: both buttons on ONE row, labels on one line, at every
   width — compact padding/type on phones so they fit side by side (Eric, 8/5) */
.editorial .cta-row{flex-wrap:nowrap}
.editorial .cta-row .btn{white-space:nowrap}
@media(max-width:480px){
  .editorial .cta-row{gap:9px}
  .editorial .cta-row .btn{padding:13px 15px;font-size:13.5px}
}
.btn.ghost.light{background:rgba(255,255,255,.12);border-color:rgba(255,255,255,.5);color:#fff;backdrop-filter:blur(4px)}
.btn.ghost.light:hover{background:rgba(255,255,255,.26);border-color:#fff;color:#fff}
.btn.sm{padding:10px 20px;font-size:13.5px}
.btn.lg{padding:17px 36px;font-size:15.5px}

/* ── hero ────────────────────────────────────────────────── */
/* background-size/position pair with the inline background-image home.php sets (the hero
   poster). Ink stays as the last resort under it, for a hero configured with no poster. */
.hero{position:relative;min-height:100vh;min-height:100svh;display:flex;flex-direction:column;overflow:hidden;background:var(--ink) center/cover no-repeat;padding-top:68px}
.hero-media{position:absolute;top:-12%;right:0;bottom:-12%;left:0;will-change:transform}
.hero-video{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;object-fit:cover;transition:opacity .45s ease}
.hero-video.back{opacity:0;pointer-events:none}
/* the headline is left-aligned, so the scrim is too: a left-weighted wash carries the
   type over pale footage (the bedroom clip is nearly white behind the h1) while the
   right half of the frame stays bright. Vertical wash eased in the middle to pay for it. */
.hero-scrim{position:absolute;top:0;right:0;bottom:0;left:0;background:
  radial-gradient(120% 90% at 20% 85%,rgba(20,50,92,.42),transparent 60%),
  linear-gradient(to right,rgba(12,20,32,.52),rgba(12,20,32,.3) 48%,rgba(12,20,32,.04) 80%),
  linear-gradient(to bottom,rgba(15,24,38,.5),rgba(15,24,38,.26) 45%,rgba(15,24,38,.68))}
/* a wide, soft shadow rather than a heavier scrim: the type survives a bright frame
   (the bedroom and chandelier clips are near-white behind the italic) without
   dimming the footage a second time. Reads as depth, not as a drop shadow. */
.hero .wrap{position:relative;z-index:2;color:#fff;margin-top:auto;margin-bottom:auto;padding-top:34px;padding-bottom:34px;text-shadow:0 1px 30px rgba(12,20,32,.42)}
/* hero entrance (autoplays on load; the hero IS the fold, there is nothing to wait for).
   The block used to rise as one lump — now the parts arrive in reading order and the two
   headline lines climb out from behind their own masks. Every rule is `backwards`, so the
   resting state is the finished hero: JS off, or reduced motion (which kills animation
   globally further up), and the visitor simply sees it already arrived.
   Delays are also why the block-level lump animation is gone: it fought the scrub
   transform on .hero-in below. */
.hero h1 .hl{display:block;overflow:hidden;padding-bottom:.1em;margin-bottom:-.1em} /* padding leaves the italic descenders room inside the mask */
.hero h1 .hl-i{display:block;animation:hline 1.05s cubic-bezier(.19,.72,.2,1) backwards}
.hero h1 .hl:first-child .hl-i{animation-delay:.16s}
.hero h1 .hl:last-child .hl-i{animation-delay:.30s}
@keyframes hline{from{transform:translateY(112%)}to{transform:none}}
.hero .eyebrow{animation:hrise .85s cubic-bezier(.2,.6,.2,1) .04s backwards}
.hero .sub{animation:hrise .9s cubic-bezier(.2,.6,.2,1) .5s backwards}
.hero-ctas>*{animation:hrise .8s cubic-bezier(.2,.6,.2,1) backwards}
.hero-ctas>*:nth-child(1){animation-delay:.62s}
.hero-ctas>*:nth-child(2){animation-delay:.7s}
.scroll-cue{animation:hrise .9s ease 1.05s backwards}
@keyframes hrise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
.hero .eyebrow{color:var(--rose-soft)}
.hero h1{font-size:clamp(42px,7vw,84px);line-height:1.02;margin:16px 0 22px;font-weight:480}
.hero h1 em{font-style:italic;color:var(--rose-soft)}
.hero .sub{font-size:clamp(16px,2vw,19px);color:rgba(255,255,255,.9);max-width:640px;margin-bottom:36px}
.hero-ctas{display:flex;gap:14px;flex-wrap:wrap}
.hero-stats{position:relative;z-index:2;border-top:1px solid rgba(255,255,255,.22);background:linear-gradient(to top,rgba(15,24,38,.45),transparent)}
/* stat cards can link out: identical look, pointer cursor only (Eric, 8/5) */
.hero-stats a.stat{color:inherit;text-decoration:none;cursor:pointer}
/* padding-right reserves the bottom-right corner for the fixed "Ask Rosie" pill,
   which otherwise sits on the last stat's label at fold on 768-1280px screens */
.hero-stats .wrap{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;padding-top:26px;padding-bottom:30px;padding-right:160px}
.stat{color:#fff;min-width:0}
/* value + label each hold ONE line: a JS fitter in home.php steps the font down
   until they fit (wording is admin-editable); balance is the floor-out fallback */
.stat-v{display:block;font-family:'Fraunces',serif;font-size:clamp(24px,3vw,34px);font-weight:600;line-height:1.1;font-variant-numeric:tabular-nums;text-wrap:balance}
.stat-l{display:block;font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:rgba(255,255,255,.82);margin-top:5px;font-weight:500;line-height:1.35;text-wrap:balance} /* was .66 — unreadable over pale footage */
/* ── hero scrub ──────────────────────────────────────────────
   layout.php publishes --hp on .hero: 0 at rest, 1 once a full screen has scrolled
   past. Everything below reads it, so the motion is scroll-position-driven (scrub),
   not time-driven — flick back up and it runs backwards exactly. --hp stays 0 when
   JS is off or the visitor asked for reduced motion, which is the resting design. */
.hero-in{transform:translate3d(0,calc(var(--hp,0) * -70px),0);opacity:calc(1 - var(--hp,0) * 1.3);will-change:transform,opacity}
.hero-scrim::after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;background:linear-gradient(to bottom,rgba(12,20,32,.5),rgba(12,20,32,.72));opacity:calc(var(--hp,0) * .85)}
@media(min-width:761px){
  /* the frame pushes in as the type leaves. Phones are excluded on purpose: a scaled
     full-bleed video is the same oversized promoted layer iOS evicts mid-scroll. */
  .hero-video{scale:calc(1 + var(--hp,0) * .07)}
}
.scroll-cue{position:absolute;bottom:150px;right:38px;z-index:3;width:30px;height:52px;border:1.5px solid rgba(255,255,255,.55);border-radius:99px;display:flex;justify-content:center;padding-top:9px;opacity:calc(1 - var(--hp,0) * 4)}   /* clear of the ~120px stats band top border; gone by the first flick */
/* hero sound toggle — thin white, stacked above the scroll cue */
.vol-toggle{position:absolute;bottom:214px;right:34px;z-index:3;border:0;background:none;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:6px;opacity:.95;transition:opacity .2s,transform .2s}
.vol-toggle:hover{opacity:1;transform:scale(1.08)}
.vol-toggle svg{width:27px;height:27px;fill:none;stroke:#fff;stroke-width:1.35;stroke-linecap:round;stroke-linejoin:round;filter:drop-shadow(0 1px 5px rgba(0,0,0,.55))}
.vol-toggle .v-on{display:none}
.vol-toggle.unmuted .v-on{display:block}
.vol-toggle.unmuted .v-off{display:none}
.scroll-cue span{width:3.5px;height:9px;border-radius:99px;background:#fff;animation:cue 1.8s ease-in-out infinite}
@keyframes cue{0%,100%{transform:translateY(0);opacity:1}55%{transform:translateY(16px);opacity:.2}}
@media(min-width:761px) and (max-width:1024px){
  /* tablets: two wide columns keep 12px labels on one line (four columns squeeze
     the long award label below readable) */
  .hero-stats .wrap{grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 24px;padding-top:20px;padding-bottom:24px}
}
@media(max-width:760px){
  /* hero fills the screen with svh ONLY: dvh grows mid-scroll when the iOS address
     bar collapses, resizing the hero while scrolling — the freshly exposed strip
     painted ink+scrim before the video caught up (the "dark opaque frame"). svh is
     constant, so the hero never resizes under the user's finger. */
  .hero{min-height:100svh}
  /* NO scroll-deepening veil on phones. On desktop the hero is a band and darkening it
     as it leaves reads as depth; on a phone the hero IS the viewport, so the same layer
     reads as a dark sheet dragged over the whole screen (measured: mean luminance 114 ->
     61 within 200px of scroll). It was also a second full-size composited layer sitting
     on the video, which is the exact shape of the "dark opaque frame" iOS flashes when it
     evicts layer backing stores mid-scroll — the bug the rules below already fight. */
  .hero-scrim::after{display:none}
  /* phones: type runs the full width, so the left-weighted wash buys nothing — go back
     to one even vertical scrim, a touch deeper than desktop's */
  .hero-scrim{background:
    radial-gradient(120% 90% at 20% 85%,rgba(20,50,92,.42),transparent 60%),
    linear-gradient(to bottom,rgba(15,24,38,.56),rgba(15,24,38,.48) 45%,rgba(15,24,38,.72))}
  /* hero CTAs share one line on phones */
  .hero-ctas{gap:10px}
  .hero-ctas .btn.lg{padding:14px 21px;font-size:14px}
  /* no parallax on phones: drop the 124%-tall promoted layer (inset:-12% +
     will-change) — iOS evicts oversized layer backing stores during scroll and
     flashes the dark hero background where the video hasn't repainted */
  .hero-media{top:0;right:0;bottom:0;left:0;will-change:auto}
  /* stats: two columns of two on phones — four skinny columns forced long labels
     into 3+ tiny lines; the JS fitter keeps value + label on one line each.
     minmax(0,1fr) lets columns shrink. The 3rd/4th swap puts the long award label
     bottom-LEFT, and the padded bottom-right cell breaks before the chat bubble. */
  .hero-stats .wrap{grid-template-columns:repeat(2,minmax(0,1fr));gap:12px 16px;padding:16px 20px 19px}
  .hero-stats .stat:nth-child(3){order:1;padding-right:56px}
  .hero-stats .stat-v{font-size:19px}
  .hero-stats .stat-l{font-size:9.5px;letter-spacing:.02em;margin-top:3px;line-height:1.3}
  .scroll-cue{display:none}
  .vol-toggle{right:16px;left:auto;top:auto;bottom:150px;padding:5px}   /* right side, above the (now two-row) stats band, clear of the left-aligned CTAs */
  .vol-toggle svg{width:23px;height:23px}
}
@media(max-width:480px){
  .hero h1{font-size:37px}
  .hero .eyebrow{font-size:10.5px;letter-spacing:.16em}
  .hero .sub{font-size:15.5px}
}

/* ── sections ────────────────────────────────────────────── */
.sec{padding:clamp(64px,9vw,104px) 0}
/* two paper sections in a row stacked 208px of dead air between them at desktop.
   The first section after a band/hero keeps its full opening; stacked ones tighten. */
.sec + .sec{padding-top:clamp(52px,7vw,80px)}
.sec.alt{background:var(--cream)}
.eyebrow{font-size:12px;font-weight:600;letter-spacing:.22em;text-transform:uppercase;color:var(--rose-ink)} /* was --rose (3.56:1), tracking .24em */
.shead{margin-bottom:clamp(30px,4vw,44px)}
.shead.center{text-align:center}
.shead.split{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;flex-wrap:wrap}
.shead h2,.band h2{font-size:clamp(30px,4.6vw,46px);line-height:1.08;margin-top:10px}
.shead h2 em,.band h2 em,.areas em{font-style:italic;color:var(--rose)}
/* Every section heading was built the same way: ink phrase, rose italic tail, eight
   times down the homepage. The regularity is the template tell, not the device itself,
   so two of the eight change register. The WORDING is Lauren's and is untouched here:
   only the treatment moves. The rose accent now means the personal sections (her name,
   Portland, their words, your next chapter); the two inventory sections read straight. */
.shead.ruled{border-top:1px solid var(--line);padding-top:26px}
.shead.ruled h2 em,.shead.ruled h2 .pop{font-style:normal;color:inherit}
/* the accent survives as a mark under the word rather than a colour change; drawn as a
   background so descenders keep their tails (text-decoration cuts through them) */
.shead.underline h2 em,.shead.underline h2 .pop{color:inherit}
.shead.underline h2 em{background:linear-gradient(var(--rose-soft),var(--rose-soft)) 0 92%/100% 3px no-repeat;padding-bottom:.08em}

/* ── the reveal on a results grid ─────────────────────────────
   The shared engine (core/assets/motion.js), on a shorter beat: a dozen
   cards in a grid want a small rise and a 40ms ladder, where a page section
   wants 22px and 90ms. data-stagger on .lgrid sets the ladder; this sets the
   rise. Nothing here is a second observer. */
html.js .lgrid .fade{transform:translateY(8px)}

/* ── skeletons ───────────────────────────────────────────────
   Shown only while a request is out AND there is nothing on screen worth
   keeping. Paper and blush, one shimmer, and every one of them is
   aria-hidden: a placeholder is a drawing of an answer, not an answer. */
.sk{position:relative;overflow:hidden;background:var(--cream,#FFF3D9);border-radius:8px}
.sk::after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,rgba(255,255,255,0),var(--blush,#FFF3D9),rgba(255,255,255,0));
  animation:skshim 1.3s ease-in-out infinite}
@keyframes skshim{100%{transform:translateX(100%)}}
.sk-l,.sk-s{display:block;height:13px;border-radius:99px}
.sk-l{width:70%}
.sk-s{width:42%;height:11px;margin-top:8px}
.sk-pill{display:inline-block;width:120px;height:15px;border-radius:99px;vertical-align:middle;background:rgba(255,255,255,.45)}
/* the label a placeholder replaces still has to reach a screen reader */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.sk-pill::after{background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.75),rgba(255,255,255,0))}
/* the palette's three rows, while the first suggestions are still in flight */
.pal-sk{cursor:default}
.pal-sk .pal-th{background:var(--cream,#FFF3D9)}
.pal-sk .pal-b{padding-top:6px}
/* a card-shaped placeholder in the results grid, same box as a real card */
.lcard.sk-card{display:block;pointer-events:none}
.sk-card .lphoto{background:var(--cream,#FFF3D9)}
.sk-card .lbody{padding:17px 19px 19px}
.sk-card .sk-l{height:17px;width:52%}
.sk-card .sk-s{width:78%}
.sk-card .sk-s.two{width:46%}
@media(prefers-reduced-motion:reduce){
  .sk::after{animation:none;transform:none;opacity:.45}
}

/* ── listing cards ───────────────────────────────────────── */
.lgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(255px,1fr));gap:22px}
.lcard{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;text-decoration:none;color:var(--ink);transition:transform .25s,box-shadow .25s;display:block}
.lcard:hover{transform:translateY(-5px);box-shadow:var(--shadow-2)}
.lphoto{position:relative;aspect-ratio:4/3;background:var(--blush);background-size:cover;background-position:center;overflow:hidden;display:flex;align-items:center;justify-content:center}
/* the blur-up: the frame carries a 96px copy of its own photo as a background
   (set inline by _lcard.php), and the full image fades in over it when its
   bytes land. The hidden state is motion.css's, scoped to html.js, so a card
   can never be a blank box because a script did not run. */
/* 112% tall inside a 4:3 window: the extra 12% is the travel the scrub drifts through,
   so the frame never shows its own background at the top or bottom edge */
.lphoto img{position:absolute;top:-6%;left:0;width:100%;height:112%;object-fit:cover;transition:transform .5s cubic-bezier(.2,.6,.2,1),opacity .5s ease}

/* ── wireframe loading ───────────────────────────────────────
   A photo frame that has not arrived yet draws itself instead of sitting empty: blush
   ground, hairline graph ruling, and one slow sheen crossing it. Reads as a plan of the
   picture rather than the grey shimmer bar every app ships — the sheen is kept because a
   frame with no movement at all reads as broken rather than pending.
   The class is added by assets/imgskel.js ONLY to images that are still pending, and
   the image's opacity is only touched while it carries .img-pending — so with JS off, or
   for anything already in cache, nothing hides and nothing flashes.
   The class is doubled on purpose. Every frame it lands on (.pimg, .aphoto, .gh-img,
   .rgal-ph…) sets a background SHORTHAND, which resets background-image to none, and
   half of them are declared later in this file than this block is — so at equal
   specificity the ruling simply never drew on them. Doubling the class outranks any
   single class from anywhere, in any file, without an !important. */
.photo-loading.photo-loading{
  background-color:var(--blush);
  background-image:
    linear-gradient(rgba(30,46,68,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(30,46,68,.05) 1px,transparent 1px);
  background-size:32px 32px;background-position:center;position:relative;overflow:hidden}
.photo-loading::after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;
  background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.32) 50%,transparent 62%);
  transform:translateX(-100%);animation:skel 2.4s cubic-bezier(.4,0,.3,1) infinite}
@keyframes skel{to{transform:translateX(100%)}}
.img-pending{opacity:0}
@media(prefers-reduced-motion:reduce){.photo-loading::after{display:none}}
/* A photograph that IS its own box — the post hero, the neighborhood hero, the round
   portrait on About — cannot carry a pseudo-element, so it wears the ruling on its own
   background and goes without the sheen. Its border-radius clips the ruling for free. */
.photo-loading-self.photo-loading-self{
  background-color:var(--blush);
  background-image:
    linear-gradient(rgba(30,46,68,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(30,46,68,.05) 1px,transparent 1px);
  background-size:32px 32px;background-position:center}
/* the editorial portrait keeps its offset frame while it loads: the wireframe takes the
   photo's own radius rather than clipping the box the frame hangs outside of */
.ed-photo.photo-loading{overflow:visible;border-radius:var(--r-lg)}
.ed-photo.photo-loading::after{border-radius:var(--r-lg)}
/* the life grid sits on ink, so it rules in light rather than in ink */
.life-cell.photo-loading{background-color:var(--ink);
  background-image:
    linear-gradient(rgba(255,255,255,.07) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.07) 1px,transparent 1px)}
.life-cell.photo-loading::after{
  background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.10) 50%,transparent 62%)}
/* A file that is not there. imgskel.js swaps the source for a drawn tulip-rose, so the
   box, the caption and the alt text all survive and no browser draws its torn page. */
/* !important earns its keep here: the drawn mark is a placeholder, not a photograph,
   and every frame on the site sets object-fit:cover on its own img at a specificity
   this rule cannot reach from one place. `contain` sizes the mark off the SHORT edge,
   so it stays a watermark in a cover photo and stays legible in a 74px thumb. */
img.img-missing{background-color:var(--blush);object-fit:contain!important}
.life-cell img.img-missing{background-color:var(--cream)}
.lcard:hover .lphoto img{transform:scale(1.045)}
.lph{color:var(--rose);opacity:.55}
.lstatus{position:absolute;top:13px;left:13px;font-size:10.5px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;background:rgba(255,255,255,.94);border-radius:99px;padding:5px 13px;color:var(--slate);backdrop-filter:blur(4px)}
.lstatus.active{color:#0E6B45}
.lstatus.pending{color:#8A6D1E}
.lstatus.coming-soon{color:#3E5E80}
.lstatus.sold{color:var(--rose-deep)}
.lstatus.inline{position:static;border:1px solid var(--line);background:#fff}
.lrep,.lvideo{position:absolute;bottom:13px;right:13px;font-size:11px;font-weight:600;background:rgba(19,29,44,.72);color:#fff;border-radius:99px;padding:5px 13px;backdrop-filter:blur(4px)}
.lbody{padding:17px 19px 19px}
.lprice{font-family:'Fraunces',serif;font-size:23px;font-weight:600}
.lclosed{font-family:'Inter',sans-serif;font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--clay);margin-left:4px}
.laddr{font-size:14.5px;margin-top:3px}
.lspecs{font-size:12.5px;color:var(--slate);margin-top:5px}

/* ── sold band (horizontal scroll) ───────────────────────── */
.sold-band{background:var(--blush);padding:clamp(64px,9vw,104px) 0 clamp(48px,6vw,72px)}
.sold-carousel{max-width:var(--wrap);margin:0 auto;padding:6px 24px 10px}
.sold-carousel .splide__track{
  -webkit-mask-image:linear-gradient(to right,transparent,#000 6%,#000 94%,transparent);
  mask-image:linear-gradient(to right,transparent,#000 6%,#000 94%,transparent);
  padding:8px 0 26px}
.sold-carousel .lcard{width:292px}
.sold-carousel .splide__slide.is-active .lcard{transform:translateY(-5px);box-shadow:var(--shadow-2)}
.sold-carousel .splide__arrow{background:#fff;border:1px solid var(--line);width:44px;height:44px;opacity:1;box-shadow:var(--shadow-1);transition:border-color .2s,transform .2s}
.sold-carousel .splide__arrow:hover{border-color:var(--rose);transform:translateY(-50%) scale(1.06)}
.sold-carousel .splide__arrow svg{fill:var(--rose-deep);width:15px;height:15px}
/* the closing tile: same card footprint as an lcard, links to every sale */
.sold-alltile{width:292px;height:100%;min-height:300px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;text-align:center;padding:28px 20px}
.sold-alltile .sat-count{font-family:'Fraunces',Georgia,serif;font-size:64px;line-height:1;color:var(--rose-deep)}
.sold-alltile .sat-label{font-size:15px;color:var(--ink);opacity:.75;margin-bottom:10px}
.sold-carousel .splide__arrow--prev{left:-4px}
.sold-carousel .splide__arrow--next{right:-4px}
@media(max-width:760px){.sold-carousel .lcard{width:262px}.sold-carousel .splide__arrow{display:none}}
/* carousel cards are exempt from the per-card scroll fade: Splide's loop CLONES
   are created after the reveal observer runs, so cloned .lcard.fade neighbors
   stayed at opacity 0 forever — the band read as ONE listing on phones. The
   .sold-carousel container still fades in as a unit. */
.sold-carousel .lcard.fade{opacity:1;transform:none}
/* mobile pagination dots: second signal that there are more homes to swipe */
.sold-carousel .splide__pagination{position:static;margin-top:14px;gap:7px}
.sold-carousel .splide__pagination__page{width:7px;height:7px;background:var(--rose-soft);opacity:1;transform:none;transition:background .2s}
.sold-carousel .splide__pagination__page.is-active{background:var(--rose-deep)}
.sold-note{font-size:13.5px;color:var(--clay)}

/* ── editorial (about teaser) ────────────────────────────── */
.editorial{overflow:hidden}
.ed-grid{display:grid;grid-template-columns:5fr 6fr;gap:clamp(34px,6vw,84px);align-items:center}
.ed-photo{position:relative}
.ed-photo img{border-radius:var(--r-lg);box-shadow:var(--shadow-2);aspect-ratio:4/5;object-fit:cover;object-position:center 22%;width:100%}
.ed-photo::before{content:"";position:absolute;inset:18px -18px -18px 18px;border:1.5px solid var(--rose-soft);border-radius:var(--r-lg);z-index:-1}
.ed-badge{position:absolute;left:-14px;bottom:26px;background:#fff;border:1px solid var(--line);border-radius:var(--r-md);padding:13px 18px;box-shadow:var(--shadow-1)}
.ed-badge .stat-v{color:var(--ink);font-size:24px}
.ed-badge .stat-l{color:var(--slate);text-transform:none;letter-spacing:0;font-size:12px}
.ed-copy h2{font-size:clamp(30px,4.4vw,44px);margin:10px 0 18px}
.ed-copy h2 em{font-style:italic;color:var(--rose)}
.kw-chips{display:flex;gap:9px;flex-wrap:wrap;margin-top:22px}
.kw-chips span{font-size:12.5px;font-weight:600;color:var(--rose-ink);background:var(--blush);border:1px solid #EEC8CB;border-radius:99px;padding:7px 15px} /* was --rose-deep on blush (3.52:1) + #EBD3D6 border */
@media(max-width:860px){.ed-grid{grid-template-columns:1fr;gap:40px}.ed-photo{max-width:420px}}

/* ── feature cards — the three pillars share one box (Lauren, 07-05) ── */
.feat3{display:grid;grid-template-columns:repeat(3,1fr);gap:0;background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.fcard{padding:34px 32px;position:relative}
.fcard + .fcard{border-left:1px solid var(--line)}
@media(max-width:860px){
  .feat3{grid-template-columns:1fr}
  .fcard + .fcard{border-left:none;border-top:1px solid var(--line)}
}
.fnum{font-family:'Fraunces',serif;font-style:italic;font-size:15px;color:var(--rose);letter-spacing:.06em}
.fcard h3{font-size:22px;margin:10px 0 9px}
.fcard p{font-size:14.5px;color:var(--slate)}
.fcontact{grid-column:1/-1;border-top:1px solid var(--line);background:var(--paper);padding:18px 30px;text-align:center;font-size:14.5px;color:var(--slate)}
.fcontact a{font-weight:600;white-space:nowrap}

/* ── quotes ──────────────────────────────────────────────── */
.qgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
@media(max-width:860px){.qgrid{grid-template-columns:1fr}}
/* white-on-paper is a 1.26:1 edge — the cards read as floating text, not objects.
   Firmer hairline + the soft shadow gives them a body; the quote glyph steps up with it. */
.qcard{background:#fff;border:1px solid #E4D7BE;border-radius:var(--r-lg);padding:32px 30px 26px;position:relative;box-shadow:var(--shadow-1)} /* was 1px var(--line), no shadow */
.qcard::before{content:"\201C";position:absolute;top:2px;left:22px;font-family:'Fraunces',serif;font-size:74px;line-height:1;color:#E6B2B8} /* was --rose-soft */
.qcard blockquote{font-family:'Fraunces',serif;font-size:19.5px;line-height:1.45;font-style:italic;margin-top:26px}
.qcard figcaption{margin-top:16px;font-size:12.5px;color:var(--slate)}

/* ── areas strip ─────────────────────────────────────────── */
.areas{border-top:1px solid var(--line);border-bottom:1px solid var(--line);padding:clamp(44px,6vw,64px) 0;text-align:center;background:var(--paper)}
.areas-line{font-family:'Fraunces',serif;font-size:clamp(18px,2.6vw,25px);margin-top:14px;color:var(--ink-2);line-height:1.6}
.areas-sub{font-size:13.5px;color:var(--clay-deep);margin-top:12px;font-style:italic} /* was --clay (4.2:1) */

/* ── CTA band ────────────────────────────────────────────── */
.band{background:#14325C;color:#fff;text-align:center;padding:clamp(80px,11vw,128px) 0;position:relative;overflow:hidden}
.band .wrap{position:relative;z-index:1}
.band .sub{color:#C3CFDF;margin:14px 0 30px;font-size:16.5px}
.band-alt{margin-top:22px;font-size:14px;color:#C3CFDF}
.band-alt a{color:#fff;text-decoration:underline;text-underline-offset:3px}
/* on the dark band the deep red button had no contrast: white face, brand-red type (Eric, 2026-07-28) */
.band .btn.primary{background:#EACF9B;color:var(--ink);box-shadow:0 8px 24px rgba(0,0,0,.35)}
.band .btn.primary:hover{background:#E2C283;color:var(--ink);box-shadow:0 12px 30px rgba(0,0,0,.45)}

/* button pairs inside copy sections */
.cta-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:26px}

/* ── page headers ────────────────────────────────────────── */
.phead{padding:clamp(60px,8vw,92px) 0 clamp(36px,5vw,54px);border-bottom:1px solid var(--line)}
.phead h1{font-size:clamp(34px,5.6vw,58px);line-height:1.06;margin-top:10px}
.phead h1 em{font-style:italic;color:var(--rose)}
.psub{color:var(--slate);font-size:17px;max-width:640px;margin-top:14px}
.center .psub{margin-left:auto;margin-right:auto}
.crumbs{font-size:12.5px;color:var(--slate);margin-bottom:16px}
.crumbs a{color:var(--slate);text-decoration:none}
.crumbs a:hover{color:var(--rose-deep)}

/* ── listings index ──────────────────────────────────────── */
.lsearch{display:flex;gap:10px;margin-top:24px;flex-wrap:wrap}
.lsearch input[type=search]{flex:1;min-width:210px;padding:13px 18px;border:1px solid var(--line);border-radius:99px;font:inherit;font-size:15px;background:#fff}
/* the chevron is drawn, not native, so it can sit 18px in from the pill's curve
   with real room on both sides of it (native arrows hug the edge) */
.lsearch select{padding:13px 44px 13px 18px;border:1px solid var(--line);border-radius:99px;font:inherit;font-size:14px;color:var(--ink);cursor:pointer;
  background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none' stroke='%234A5A72' stroke-width='1.8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E") no-repeat right 18px center;
  -webkit-appearance:none;appearance:none}
.empty{color:var(--slate);font-size:16px}
/* the door from the eight recent closings to the whole record */
.allsold{margin-top:36px;padding-top:28px;border-top:1px solid var(--line);text-align:center}
.allsold p{margin-top:10px;font-size:14px;color:var(--slate)}

/* ── listing detail ──────────────────────────────────────── */
/* This header opens on a breadcrumb, not an eyebrow, so the section-header top
   padding left a band of dead space above a 12px line. It starts higher, and it
   runs straight into the gallery with no rule drawn between the two. Phones keep
   the shared .phead rhythm, which was already tight. (Eric, 2026-08-21) */
.listing-head{padding-top:clamp(30px,3.2vw,44px);border-bottom:0}
.listing-head .lh-row{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;flex-wrap:wrap}
.lh-city{color:var(--slate);margin-top:10px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.lh-price p{font-family:'Fraunces',serif;font-size:clamp(30px,4vw,42px);font-weight:600;text-align:right}
.lh-price span{color:var(--slate);font-size:13.5px}
@media(max-width:700px){.lh-price p{text-align:left}}
.ltour{padding:38px 0 0}
.vwrap{position:relative;border-radius:var(--r-lg);overflow:hidden;cursor:pointer;aspect-ratio:16/9;background:var(--ink);box-shadow:var(--shadow-2)}
.vwrap img{width:100%;height:100%;object-fit:cover;transition:transform .5s}
.vwrap:hover img{transform:scale(1.03)}
.vwrap::after{content:"";position:absolute;inset:0;background:linear-gradient(to top,rgba(19,29,44,.5),transparent 45%)}
.vplay{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:80px;height:80px;border-radius:50%;background:rgba(255,255,255,.95);display:flex;align-items:center;justify-content:center;font-size:24px;color:var(--rose-deep);z-index:2;transition:transform .2s}
.vwrap:hover .vplay{transform:translate(-50%,-50%) scale(1.08)}
.vlabel{position:absolute;bottom:20px;left:24px;color:#fff;font-weight:600;z-index:2}
.vmodal{position:fixed;inset:0;z-index:120;background:rgba(19,29,44,.94);backdrop-filter:blur(10px);display:flex;align-items:center;justify-content:center;padding:4vh 4vw;opacity:0;pointer-events:none;transition:opacity .3s}
.vmodal.open{opacity:1;pointer-events:auto}
.vmodal video{width:100%;max-width:1100px;max-height:100%;aspect-ratio:16/9;border-radius:var(--r-md);background:#000}
.vclose{position:absolute;top:18px;right:18px;width:46px;height:46px;border-radius:50%;border:1px solid rgba(255,255,255,.35);background:rgba(255,255,255,.1);color:#fff;font-size:17px;cursor:pointer}
.vclose:hover{background:rgba(255,255,255,.25)}
.gallery{display:grid;grid-template-columns:repeat(3,1fr);gap:14px}
@media(max-width:700px){.gallery{grid-template-columns:1fr 1fr}}
.gallery img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:var(--r-md);border:1px solid var(--line);transition:transform .3s,box-shadow .3s}
.gallery img:hover{transform:scale(1.02);box-shadow:var(--shadow-1)}
.gallery img:first-child{grid-column:span 2;grid-row:span 2;aspect-ratio:auto}
.cols2{display:grid;grid-template-columns:1.6fr 1fr;gap:44px;align-items:start}
/* minmax(0,1fr), not a bare 1fr: the 300px Turnstile box in the listing side card
   set the column's min-content and pushed the whole listing to 350px at 320 */
@media(max-width:820px){.cols2{grid-template-columns:minmax(0,1fr)}}
.feats{list-style:none;margin-top:22px;display:grid;grid-template-columns:1fr 1fr;gap:8px 22px}
@media(max-width:560px){.feats{grid-template-columns:1fr}}
.feats li{padding:9px 0 9px 26px;position:relative;border-bottom:1px dashed var(--line);font-size:14.5px}
.feats li::before{content:"\2713";position:absolute;left:0;color:var(--rose);font-weight:700}
.sidecard{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:24px;margin-bottom:16px}
.sidecard h3{font-size:19px;margin:6px 0 12px}
.sidecard h3 a{color:var(--ink);text-decoration:none}
.sidecard input,.sidecard textarea{width:100%;padding:11px 14px;border:1px solid var(--line);border-radius:10px;font:inherit;font-size:14px;margin-bottom:10px;background:var(--paper)}
.sidecard textarea{min-height:72px;resize:vertical}
.sidecard .btn{width:100%;text-align:center}

/* ── prose / CMS pages ───────────────────────────────────── */
.prose{font-size:16.5px;line-height:1.78}
/* editable pages: content spans the full content width to line up with the
   photos/gallery. Slightly larger leading keeps the wider measure comfortable. */
.page-prose{max-width:none;line-height:1.8}
.page-prose.faq{max-width:none}
.shortcode-btn{margin:22px 0}
.prose p{margin-bottom:16px}
.prose .lede{font-family:'Fraunces',serif;font-size:clamp(20px,2.6vw,25px);line-height:1.5;color:var(--ink-2);margin-bottom:26px}
.prose h2{font-size:clamp(23px,3vw,30px);margin:38px 0 14px}
.prose ul{margin:0 0 16px 22px}
.prose li{margin-bottom:8px}
.prose a{text-decoration-color:var(--rose-soft);text-underline-offset:3px}
/* page tab pair (Get to Know Me / Work With Me) + next-page arrow card */
.ptabs{display:flex;gap:9px;flex-wrap:wrap;margin:22px auto 0}
.ptab{display:inline-flex;align-items:center;padding:9px 20px;border-radius:99px;border:1px solid var(--line);background:#fff;color:var(--ink);font-weight:600;font-size:14.5px;text-decoration:none;transition:background .2s,border-color .2s,color .2s,box-shadow .2s}
.ptab:hover{border-color:var(--rose);color:var(--rose-deep)}
.ptab.is-active{background:var(--rose);border-color:var(--rose);color:#fff;box-shadow:0 8px 20px rgba(56,121,189,.28)}
.pnext{display:flex;align-items:center;gap:16px;max-width:520px;margin-top:46px;padding:20px 26px;border:1px solid var(--line);border-radius:16px;background:var(--cream);text-decoration:none;color:var(--ink);transition:border-color .2s,transform .2s,box-shadow .2s}
.pnext:hover{border-color:var(--rose);transform:translateY(-2px);box-shadow:0 14px 34px rgba(56,121,189,.18)}
.pnext-txt{flex:1;min-width:0}
.pnext-k{display:block;font-size:12px;letter-spacing:.07em;text-transform:uppercase;color:var(--clay)}
.pnext-l{display:block;margin-top:3px;font-family:'Fraunces',serif;font-size:22px;line-height:1.15;color:var(--rose-deep)}
.pnext-arrow{font-size:27px;color:var(--rose);margin-left:auto;transition:transform .2s}
.pnext:hover .pnext-arrow{transform:translateX(5px)}
ol.steps{list-style:none;counter-reset:step;margin:8px 0 18px}
ol.steps li{counter-increment:step;position:relative;padding:16px 0 16px 62px;border-bottom:1px dashed var(--line);font-size:15.5px}
ol.steps li::before{content:counter(step,decimal-leading-zero);position:absolute;left:0;top:16px;font-family:'Fraunces',serif;font-style:italic;font-size:21px;color:var(--rose)}

/* ── agents ──────────────────────────────────────────────── */
.agrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(230px,1fr));gap:20px}
.acard{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:28px 24px;text-align:center;text-decoration:none;color:var(--ink);transition:transform .25s,box-shadow .25s}
.acard:hover{transform:translateY(-5px);box-shadow:var(--shadow-2)}
.aphoto{width:118px;height:118px;border-radius:50%;background:var(--blush) center/cover no-repeat;margin:0 auto 16px;display:flex;align-items:center;justify-content:center;border:1px solid var(--line);color:var(--rose);overflow:hidden}
.aphoto img{width:100%;height:100%;object-fit:cover}
.aphoto.lg{width:170px;height:170px;margin:0}
.acard h3{font-size:19.5px}
.acard p{font-size:13px;color:var(--slate)}
.amini{margin-top:9px;font-size:12.5px!important}
/* "we're growing" recruitment card — invites agents, signals momentum */
.acard-soon{border:1.5px dashed var(--rose-soft);background:linear-gradient(180deg,#fff,var(--blush));display:flex;flex-direction:column;align-items:center}
.acard-soon:hover{border-color:var(--rose)}
.aphoto-soon{background:#fff;border:1.5px dashed var(--rose-soft)}
.aphoto-soon svg{width:34px;height:34px;color:var(--rose)}
.acard-soon .soon-cta{margin-top:14px;font-size:13px;font-weight:600;color:var(--rose-deep)}
.agent-hero{display:flex;gap:34px;align-items:center;flex-wrap:wrap;margin-top:12px}
.acontact{display:flex;gap:10px;margin-top:18px;flex-wrap:wrap}
.asocial{margin-top:14px;display:flex;gap:16px;flex-wrap:wrap;font-size:13.5px;font-weight:600}

/* ── intake forms ────────────────────────────────────────── */
.intake{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:clamp(24px,4vw,38px);max-width:780px;box-shadow:var(--shadow-1)}
.intake label{display:block;font-size:12.5px;font-weight:600;color:var(--slate);margin:15px 0 6px;letter-spacing:.02em}
.intake input,.intake select,.intake textarea{width:100%;padding:13px 15px;border:1px solid var(--line);border-radius:11px;font:inherit;font-size:15px;background:var(--paper)}
.intake textarea{min-height:110px;resize:vertical}
.intake input:focus,.intake select:focus,.intake textarea:focus{outline:2px solid var(--rose);outline-offset:-1px;background:#fff}
.fgrid{display:grid;grid-template-columns:1fr 1fr;gap:0 20px}
@media(max-width:620px){.fgrid{grid-template-columns:1fr}}
.intake .btn{margin-top:24px}
.fine{font-size:12.5px;color:var(--slate);margin-top:13px;font-style:italic}
.hp{position:absolute;left:-9999px;opacity:0;height:0;width:0}

/* ── FAQ ─────────────────────────────────────────────────── */
.faq details{border-bottom:1px solid var(--line);padding:16px 0}
.faq summary{font-family:'Fraunces',serif;font-size:18.5px;cursor:pointer;list-style:none;position:relative;padding-right:30px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";position:absolute;right:2px;top:-2px;color:var(--rose);font-size:22px;transition:transform .2s}
.faq details[open] summary::after{content:"\2013"}
.faq details p{margin-top:11px;color:var(--slate);font-size:15px;line-height:1.7}

/* ── about portrait header ───────────────────────────────── */
.phead-me{display:flex;align-items:center;gap:30px}
.me-circle{width:132px;height:132px;border-radius:50%;object-fit:cover;border:3px solid #fff;box-shadow:var(--shadow-2),0 0 0 1px var(--rose-soft);flex:none}
@media(max-width:640px){
  /* tighter, even page-header rhythm on phones */
  .phead{padding:26px 0 28px}
  .phead h1{font-size:clamp(29px,8.2vw,36px)}
  .crumbs{margin-bottom:12px}
  .phead-me{flex-direction:column;text-align:center;gap:14px}
  .phead-me .me-circle{width:106px;height:106px}
  /* broker · licenses · phone stays on ONE line */
  .phead-me .psub{margin:4px auto 0;white-space:nowrap;font-size:clamp(11.5px,3.55vw,14px)}
  .phead-me .psub a{white-space:nowrap}
}

/* ── google reviews modal ────────────────────────────────── */
/* Google-reviews prompt: a non-blocking bottom-corner card (z-index below the nav, so it NEVER covers navigation) */
.greview{position:fixed;right:20px;bottom:20px;z-index:70;max-width:322px;background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:0 18px 50px rgba(15,24,38,.22);padding:20px 22px 22px;opacity:0;transform:translateY(24px);transition:opacity .3s,transform .3s}
.greview.open{opacity:.9;transform:none}
.greview-x{position:absolute;top:9px;right:11px;width:30px;height:30px;border:0;background:none;color:var(--slate);font-size:15px;cursor:pointer;line-height:1;border-radius:50%;transition:color .15s,background .15s}
.greview-x:hover{color:var(--ink);background:var(--cream)}
.gstars{display:block;color:var(--rose);font-size:16px;letter-spacing:3px;margin-bottom:7px}
.greview-h{font-family:'Fraunces',serif;font-size:19px;margin-bottom:4px}
.greview-p{color:var(--slate);font-size:13.8px;margin-bottom:15px;line-height:1.5}
.greview-alt{display:block;margin-top:10px;font-size:13px;color:var(--slate);text-decoration:underline;text-underline-offset:3px}
.greview-alt:hover{color:var(--ink)}
@media(max-width:520px){.greview{left:16px;right:16px;bottom:16px;max-width:none}}

/* ── journal / blog ──────────────────────────────────────── */
.pgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
@media(max-width:900px){.pgrid{grid-template-columns:1fr 1fr}}
@media(max-width:600px){.pgrid{grid-template-columns:1fr}}
.pcard{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;text-decoration:none;color:var(--ink);transition:transform .25s,box-shadow .25s;display:flex;flex-direction:column}
.pcard:hover{transform:translateY(-5px);box-shadow:var(--shadow-2)}
.pcard.featured{grid-column:1/-1;flex-direction:row;align-items:stretch}
/* aspect-ratio:auto left this box with no height of its own, so the featured card was
   322px tall until the photo arrived and 394px after it: a 72px jump, every time, on the
   first card of the Journal. The phone rule below had already been given a ratio for
   exactly this reason. 3:2 is what the teaser crop already renders at, so the finished
   page is unchanged and only the reserved box is new; min-height still floors it at
   narrow widths, and being a floor it stays definite either way. */
.pcard.featured .pimg{flex:1.3;aspect-ratio:3/2;min-height:320px}
.pcard.featured .pbody{flex:1;display:flex;flex-direction:column;justify-content:center;padding:34px}
.pcard.featured h3,.pcard.featured .pcard-t{font-size:clamp(24px,3vw,32px)}
@media(max-width:760px){.pcard.featured{flex-direction:column}.pcard.featured .pimg{min-height:0;aspect-ratio:16/9}}
.pimg{aspect-ratio:16/9;background:var(--blush);overflow:hidden}
.pimg img{width:100%;height:100%;object-fit:cover;transition:transform .5s cubic-bezier(.2,.6,.2,1)}
.pcard:hover .pimg img{transform:scale(1.04)}
.pbody{padding:20px 22px 22px}
.pmeta{font-size:12px;letter-spacing:.04em;color:var(--clay);text-transform:uppercase;font-weight:600}
.pcard h3,.pcard .pcard-t{font-family:'Fraunces',serif;font-size:21px;line-height:1.25;margin:8px 0 8px}
.pteaser{font-size:14px;color:var(--slate);line-height:1.6}
.ptags{margin-top:14px;display:flex;gap:7px;flex-wrap:wrap}
.ptags span,.ptags a{font-size:11px;font-weight:600;color:var(--rose-deep);background:var(--blush);border-radius:99px;padding:4px 11px;text-decoration:none}
/* The tag map's pills (.ptags a) are links, not the card badges (.ptags span)
   the rest of .ptags is; the pill itself reads about 21px tall, so a::after
   grows the tap target to 44px without changing how it looks (mobile-first
   law: 44px thumb target, no hover-only affordance). */
.ptags a{position:relative;display:inline-block}
.ptags a::after{content:"";position:absolute;inset:-12px 0}
/* Tag links at the top of a post: theme red, no underline, and they now lead
   to /blog/tag/{slug} instead of being dead text. */
.ptag-row{margin:2px 0 0;display:flex;gap:14px;flex-wrap:wrap}
.ptag-link{font-size:12.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--rose);text-decoration:none}
.ptag-link:hover{color:var(--rose-deep);text-decoration:none}
.posthero{border-radius:var(--r-lg);box-shadow:var(--shadow-2);width:100%;aspect-ratio:3/2;height:auto;object-fit:cover}
/* Neighborhood guide hero. Same frame as a post hero, plus a credit line: these
   photos are her own listings, and the caption is what makes that honest rather
   than decorative. */
.nhero{margin:0}
.nhero img{border-radius:var(--r-lg);box-shadow:var(--shadow-2);width:100%;aspect-ratio:3/2;height:auto;object-fit:cover;display:block}
/* The two hero slots above carry aspect-ratio 3:2 + object-fit cover as a HARD
   guarantee (2026-08-13): the server already renders these slots at exact 3:2,
   but a stale browser cache, a hand-edited path or any future preset slip can
   put a wrong-shaped file here, and before this rule that file set the box's
   shape: a portrait upload ran the full height of the viewport and read as
   "stretched". Now the box is always 3:2 of the column width, its height can
   never exceed the image's own rendered height, and a wrong-shaped file is
   center-cropped by the browser instead of distorting the page. */
.nhero figcaption{margin-top:10px;font-size:13.5px;line-height:1.5}
.postbody{font-size:17px}
.postbody h2{font-size:clamp(23px,3vw,29px);margin:36px 0 12px}
.postbody ul{margin:0 0 16px 22px}
.postbody li{margin-bottom:9px}
.postbody .lede{font-family:'Fraunces',serif;font-size:clamp(19px,2.4vw,23px);line-height:1.55;color:var(--ink-2)}
.postcta{margin-top:46px;border:1px solid var(--line);border-radius:var(--r-lg);padding:28px;background:#fff}
.postcta h3{font-family:'Fraunces',serif;font-size:23px;margin:8px 0 16px}
.postcta h3 em{font-style:italic;color:var(--rose)}

/* ── footer (flush to page bottom, no gap) ───────────────── */
/* back-to-top: quiet paper chip, fades in once the hero (or the first screen on
   hero-less pages) is scrolled past.
   It used to sit bottom-CENTER, which put a translucent disc straight on top of
   whatever ran under it: the donation paragraph mid-page, her license numbers in the
   footer. The right gutter is the one column that is always empty, so it stacks above
   the Ask Rosie launcher instead and collides with nothing. */
.gotop{position:fixed;right:18px;bottom:calc(76px + env(safe-area-inset-bottom,0px));z-index:60;
  width:44px;height:44px;border-radius:50%;cursor:pointer;padding:0;
  display:flex;align-items:center;justify-content:center;
  background:rgba(255,251,242,.86);border:1px solid var(--line);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  opacity:0;pointer-events:none;transform:translateY(6px);
  transition:opacity .25s ease,transform .25s ease,background .2s}
.gotop.on{opacity:.92;pointer-events:auto;transform:none}
.gotop:hover{opacity:1;background:#fff}
/* Rosie hidden (rosie_public off): the chip takes her corner and rests lighter,
   solid again under a finger or a pointer */
.gotop.solo{bottom:calc(18px + env(safe-area-inset-bottom,0px))}
.gotop.solo.on{opacity:.7}
.gotop.solo.on:hover,.gotop.solo.on:focus-visible{opacity:1}
.gotop svg{width:17px;height:17px;fill:none;stroke:var(--ink);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:stroke .2s}
.gotop:hover svg{stroke:var(--rose-deep)}
@media print{.gotop{display:none!important}}
/* the review card owns the same corner while it is open, and it is the louder ask */
.greview.open ~ .gotop{opacity:0;pointer-events:none}
footer{background:#14325C;color:#fff;padding:clamp(56px,7vw,76px) 0 calc(36px + env(safe-area-inset-bottom,0px));margin-top:auto;position:relative;overflow:hidden}
footer .wrap{position:relative;z-index:1}
/* oversized tulip-rose watermark, bleeding off the bottom-right corner */
.frose{position:absolute;right:clamp(-70px,-2vw,-24px);bottom:-58px;width:auto;height:clamp(300px,33vw,420px);color:var(--rose-soft);opacity:.09;pointer-events:none;z-index:0}
@media(max-width:520px){.frose{height:240px;right:-56px;bottom:-32px;opacity:.07}}
footer .cols{display:grid;grid-template-columns:2.2fr 1fr 1fr 1fr;gap:34px;margin-bottom:44px}
@media(max-width:860px){footer .cols{grid-template-columns:1fr 1fr}}
.fbrand{font-family:'Fraunces',serif;font-size:22px}
.ftag{color:var(--rose-soft);font-style:italic;font-family:'Fraunces',serif;margin:8px 0 14px;font-size:16.5px}
.fmeta{font-size:13.5px;color:#C3CFDF}
.fmeta a{color:#EEC8CB;text-decoration:none}
.fmeta a:hover{color:#fff}
.fh{font-size:11px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:#A3B4CC;margin-bottom:12px}
footer .cols a{display:block;color:#C3CFDF;text-decoration:none;font-size:14px;padding:4.5px 0;transition:color .2s}
footer .cols a:hover{color:#fff}
.legal{border-top:1px solid rgba(255,255,255,.12);padding-top:24px;font-size:12px;color:#A3B4CC;line-height:1.7}
/* brokerage attribution — remove when Lauren leaves Works */
.fbrokerage{display:flex;align-items:center;gap:12px;margin:26px 0 18px}
.fbrokerage .bk{font-size:11px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:#A3B4CC}
.fbrokerage img{height:22px;width:auto;filter:brightness(0) invert(1);opacity:.5}
/* ello: no ello realty badge artwork yet, so the firm is set in type at the badge's 22px line */
.fbrokerage .fbroker-name{font-family:'Inter',sans-serif;font-size:16px;font-weight:600;letter-spacing:.01em;line-height:22px;color:#C3CFDF}
/* compact footer on phones: brand full-width, links in a tight 2-up grid */
@media(max-width:520px){
  footer{padding:36px 0 calc(22px + env(safe-area-inset-bottom,0px))}
  footer .cols{grid-template-columns:1fr 1fr;gap:22px 18px;margin-bottom:26px}
  .fbrandcol{grid-column:1/-1}
  .fbrand{font-size:20px}
  .ftag{margin:6px 0 10px;font-size:15px}
  .fmeta{font-size:13px}
  .fh{margin-bottom:7px}
  footer .cols a{font-size:13.5px;padding:3px 0}
  .legal{padding-top:16px;font-size:11.5px;line-height:1.6}
}
.flogin{color:#A3B4CC;text-decoration:none;border-bottom:1px dotted #A3B4CC}
.flogin:hover{color:var(--rose-soft);border-color:var(--rose-soft)}

/* ── Rosie chat slideout (AI home-value helper) ──────────── */
/* Rosie chat styles moved to chat.css (shared with the admin dashboard) */
/* the About reviews card sits above the chat launcher */
.greview{bottom:84px}

/* ── reusable media gallery (thumb grid + lightbox) ──────── */
.rgal-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:16px}
.rgal-t{margin:0;cursor:zoom-in;outline:none}
.rgal-ph{position:relative;aspect-ratio:4/3;border-radius:14px;overflow:hidden;border:1px solid var(--line);background:var(--blush);box-shadow:0 2px 8px rgba(30,46,68,.06);transition:transform .2s,box-shadow .2s}
.rgal-t:hover .rgal-ph,.rgal-t:focus-visible .rgal-ph{transform:translateY(-3px);box-shadow:var(--shadow-2)}
.rgal-ph img,.rgal-ph video{width:100%;height:100%;object-fit:cover;display:block}
.rgal-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:46px;height:46px;border-radius:50%;background:rgba(255,255,255,.92);color:var(--rose-deep);font-size:15px;display:flex;align-items:center;justify-content:center;box-shadow:0 6px 18px rgba(15,24,38,.25)}
.rgal-t figcaption{font-size:13px;color:var(--slate);margin-top:8px;text-align:center}
@media(max-width:640px){.rgal-grid{grid-template-columns:1fr 1fr;gap:10px}.rgal-t figcaption{font-size:12px;margin-top:6px}}

/* The gallery used to carry its own shimmer, painted with an animated
   background-position that never stopped: every tile on a listing page kept
   repainting for the life of the page, long after its photo had arrived. The
   wireframe above does the same job on the same box, is a compositor transform
   rather than a repaint, and comes off the moment the photo lands. */
.rgal-i{opacity:0;transition:opacity .5s ease}
.rgal-i.ld{opacity:1}

/* editorial variant — cover photo runs large, the rest arrange around it;
   captions are tiny overlays that slide up on hover (and always show in the lightbox) */
/* tight square mosaic: every cell is a square, the lead runs 2x2, dense packing
   fills the gaps (object-fit crops to fit). Capped width keeps the whole block
   a touch smaller and neat rather than full-bleed. */
.rgal.ed{max-width:none}   /* fill the wrap so gallery width matches the page text */
.rgal.ed .rgal-grid{grid-template-columns:repeat(3,1fr);grid-auto-flow:dense;gap:14px}
/* the FIGURE is the square, and the photo fills it 100% — so captions are always
   pinned to the image edge (never floating in leftover cell space) and the rows
   line up with no gaps between the right-hand photos */
.rgal.ed .rgal-t{position:relative;aspect-ratio:1}
.rgal.ed .rgal-ph{aspect-ratio:auto;height:100%}
.rgal.ed .rgal-t:first-child{grid-column:span 2;grid-row:span 2}
.rgal.ed .rgal-t:hover .rgal-ph,.rgal.ed .rgal-t:focus-visible .rgal-ph{transform:none;box-shadow:var(--shadow-2)}
.rgal.ed .rgal-t:hover .rgal-i{transform:scale(1.025)}
.rgal.ed .rgal-i{transition:opacity .5s ease,transform .45s cubic-bezier(.2,.6,.2,1)}
.rgal.ed figcaption{position:absolute;left:1px;right:1px;bottom:1px;margin:0;padding:26px 13px 9px;text-align:left;
  font-size:11px;line-height:1.45;letter-spacing:.015em;color:#fff;border-radius:0 0 13px 13px;
  background:linear-gradient(180deg,rgba(15,24,38,0),rgba(15,24,38,.66));
  transform:translateY(102%);opacity:0;pointer-events:none;
  transition:transform .38s cubic-bezier(.2,.6,.2,1),opacity .3s ease}
.rgal.ed .rgal-t:hover figcaption,.rgal.ed .rgal-t:focus-visible figcaption{transform:none;opacity:1}
@media(max-width:560px){
  .rgal.ed .rgal-grid{grid-template-columns:repeat(2,1fr);gap:8px}
  .rgal.ed .rgal-t:first-child{grid-column:span 2;grid-row:span 2}
  .rgal.ed figcaption{display:none}  /* no hover on touch: captions live in the slideshow */
}

/* showcase variant (listing pages) — the cover and ONE side block of thumbs,
   side by side, nothing underneath. The .cmp band below owns that shape at every
   photo count (Eric, 2026-08-21); these --sc-cols / --sc-lead / --sc-rows rules
   now serve the solo cover and the retired rectangle path only. The template
   solves every number (the invariant is stated in full in
   themes/rose/_gallery.php); nothing here decides shape. */
.rgal.ed.sh .rgal-grid{grid-template-columns:repeat(var(--sc-cols,6),1fr)}
.rgal.ed.sh .rgal-t{grid-column:span var(--sc-thumb,1)}
/* the cover fills the cells it spans and asks for no height of its own: its
   photo is taken OUT OF FLOW, so the square thumbs alone size the rows and the
   cover's proportions never enter into it. Exact at any gap, which an
   aspect-ratio of --sc-lead / --sc-rows is not, and it is what lets a cover run
   wider than tall (4x3, 5x3) without dragging the cells out of square. */
.rgal.ed.sh .rgal-t:first-child{grid-column:span var(--sc-lead,4);grid-row:span var(--sc-rows,4);aspect-ratio:auto;min-height:0}
.rgal.ed.sh .rgal-t:first-child .rgal-ph{position:absolute;inset:0;height:auto}
.rgal.ed.sh.solo .rgal-t:first-child{aspect-ratio:3/2;max-height:550px}   /* one photo: 3:2 until the 550px ceiling */

/* "See all N photos" — the inline grid stops at seven tiles (cover + six), so
   the sixth thumb carries a pill into the viewer. It sits inside the figure (already
   position:relative) and stays clickable: the click handler reads it and opens
   at the first photo rather than at this tile. The icon is pointer-events:none
   so the event target is always the pill itself. */
.rgal.ed.sh .rgal-more{position:absolute;left:50%;transform:translateX(-50%);bottom:8px;z-index:3;cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;gap:5px;padding:7px 12px;border-radius:99px;
  max-width:calc(100% - 12px);
  background:rgba(19,29,44,.82);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  color:#fff;font-family:'Inter',system-ui,sans-serif;font-size:11px;font-weight:600;
  line-height:1;white-space:nowrap;box-shadow:0 4px 14px rgba(15,24,38,.34);
  transition:background .25s ease,transform .25s cubic-bezier(.2,.6,.2,1)}
.rgal.ed.sh .rgal-more svg{pointer-events:none;opacity:.9}
.rgal.ed.sh .rgal-t:hover .rgal-more,.rgal.ed.sh .rgal-t:focus-visible .rgal-more{
  /* colour only: the pill is centred by a transform, so any hover transform
     here would fight the centring and shift the button */
  background:var(--rose-deep);transform:translateX(-50%)}
@media(max-width:560px){
  .rgal.ed.sh .rgal-more{padding:7px 6px;font-size:10px;gap:5px}
}

/* compact band — EVERY showcase gallery with a thumb in it. The cover runs down
   the left at 3:2 and the thumbs sit two across beside it, ending exactly level
   with its bottom edge, at most two columns of three (the inline set is capped
   at seven tiles, so the band never grows past that and nothing ever lands
   below the cover). Sized explicitly: the block gets a definite height from --sc-ar, the
   rows divide it as fr, and every cell's column and row span is solved in
   themes/rose/_gallery.php. Desktop only, so the phone rules below are
   untouched — and the placements arrive as custom properties, not inline
   grid-column, so those rules can still override them. */
@media(min-width:561px){
  .rgal.ed.sh.cmp .rgal-grid{grid-template-columns:var(--sc-tracks,3fr 2fr 2fr);
    grid-template-rows:repeat(var(--sc-rw,1),1fr);aspect-ratio:var(--sc-ar,2.532);max-height:550px}
  /* align-self is spelled out because a fork (grace-alt) sets it to start on
     every editorial tile; a compact cell must fill the rows it was given */
  .rgal.ed.sh.cmp .rgal-t,.rgal.ed.sh.cmp .rgal-t:first-child{
    grid-column:var(--gc,auto);grid-row:var(--gr,auto);aspect-ratio:auto;
    align-self:stretch;justify-self:stretch;min-width:0;min-height:0}
  .rgal.ed.sh.cmp .rgal-ph{position:absolute;inset:0;height:auto}
}
@media(max-width:560px){
  /* phone: the cover full width, then --sc-ph thumbs across (3 or 4, whichever
     leaves no straggler; 110px+ targets at 390 either way) */
  .rgal.ed.sh .rgal-grid{grid-template-columns:repeat(var(--sc-ph,3),1fr)}
  .rgal.ed.sh .rgal-t{grid-column:span 1;grid-row:auto;aspect-ratio:1}
  .rgal.ed.sh .rgal-grid{grid-template-rows:none;aspect-ratio:auto;max-height:none}
  .rgal.ed.sh .rgal-t .rgal-ph,.rgal.ed.sh .rgal-t:first-child .rgal-ph{position:relative;inset:auto;height:100%}
  .rgal.ed.sh .rgal-t.phw{grid-column:1/-1;aspect-ratio:var(--sc-ph,3)}
  .rgal.ed.sh .rgal-t:first-child{grid-column:1/-1;grid-row:auto;aspect-ratio:4/3}
}
/* lightbox */
#rgal-m{display:none;position:fixed;inset:0;z-index:150;background:rgba(19,29,44,.94);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);flex-direction:column;align-items:center;justify-content:center;padding:54px 16px calc(20px + env(safe-area-inset-bottom,0px));cursor:zoom-out}
#rgal-m.open{display:flex}
#rgal-m .rgal-stage{display:flex;align-items:center;justify-content:center;max-width:100%;flex:1;min-height:0}
#rgal-m .rgal-media{max-width:min(92vw,1100px);max-height:76vh;width:auto;height:auto;object-fit:contain;border-radius:12px;box-shadow:0 34px 90px rgba(0,0,0,.55);cursor:default}
#rgal-m .rgal-cap{margin-top:14px;color:#F0EBDF;font-size:14.5px;text-align:center;max-width:640px}
#rgal-m .rgal-count{position:fixed;top:max(18px,env(safe-area-inset-top));left:20px;color:#C3CFDF;font:600 12px 'Inter',sans-serif;letter-spacing:.08em}
#rgal-m .rgal-x{position:fixed;top:max(14px,env(safe-area-inset-top));right:14px;width:42px;height:42px;border-radius:50%;border:1px solid rgba(255,255,255,.28);background:rgba(30,46,68,.5);color:#fff;font-size:16px;cursor:pointer;z-index:2}
#rgal-m .rgal-x:hover{background:rgba(255,255,255,.18)}
#rgal-m .rgal-nav{position:fixed;top:50%;transform:translateY(-50%);width:46px;height:46px;border-radius:50%;border:1.5px solid rgba(255,255,255,.4);background:rgba(30,46,68,.45);color:#fff;font-size:22px;line-height:1;cursor:pointer;z-index:2;transition:background .15s,border-color .15s}
#rgal-m .rgal-nav:hover{background:rgba(255,255,255,.16);border-color:#fff}
#rgal-m .rgal-prev{left:14px}
#rgal-m .rgal-next{right:14px}
@media(max-width:640px){
  #rgal-m .rgal-media{max-width:96vw;max-height:70vh}
  #rgal-m .rgal-nav{top:auto;bottom:calc(16px + env(safe-area-inset-bottom,0px));transform:none;width:52px;height:44px;border-radius:99px}
  #rgal-m .rgal-prev{left:calc(50% - 62px)}
  #rgal-m .rgal-next{right:calc(50% - 62px)}
  #rgal-m .rgal-cap{margin-bottom:52px;font-size:13.5px}
}

/* ── inline editing (only present when logged in: body.rre-edit) ─────────── */
.rre-edit .rre-editable{position:relative}
.rre-edit .rre-editable:hover{outline:1.5px dashed var(--rose-soft);outline-offset:8px;border-radius:2px}
.rre-edit .rre-edit-tab{
  position:absolute;top:8px;right:8px;z-index:40;
  display:inline-flex;align-items:center;gap:5px;
  font-family:'Inter',sans-serif;font-size:11.5px;font-weight:600;line-height:1;
  color:#fff;background:var(--rose);border:0;border-radius:99px;
  padding:6px 12px;cursor:pointer;text-decoration:none;white-space:nowrap;
  box-shadow:0 4px 14px rgba(56,121,189,.4);
  opacity:0;transform:translateY(-4px);transition:opacity .16s,transform .16s,background .16s}
.rre-edit .rre-editable:hover > .rre-edit-tab,
.rre-edit .rre-edit-tab:focus-visible{opacity:1;transform:none}
.rre-edit .rre-edit-tab:hover{background:var(--rose-deep)}
@media(hover:none){.rre-edit .rre-edit-tab{opacity:.92;transform:none}}   /* touch: keep it visible */

/* fixed Save / Cancel bar */
.rre-bar{position:fixed;left:50%;bottom:22px;z-index:1000;
  display:flex;align-items:center;gap:12px;
  background:var(--ink);color:#fff;border-radius:99px;padding:10px 12px 10px 20px;
  box-shadow:0 12px 40px rgba(15,24,38,.4);transition:transform .28s cubic-bezier(.2,.6,.2,1);
  transform:translate(-50%,140%);visibility:hidden}   /* hidden when idle: keeps iOS from adding phantom scroll space below the footer */
.rre-bar.show{transform:translate(-50%,0);visibility:visible}
.rre-bar-label{font-size:13px;font-weight:500;color:#EEC8CB;margin-right:4px;white-space:nowrap}
.rre-btn{font-family:'Inter',sans-serif;font-size:13.5px;font-weight:600;border:0;border-radius:99px;
  padding:9px 20px;cursor:pointer;background:var(--rose);color:#fff;transition:background .15s,opacity .15s}
.rre-btn:hover{background:var(--rose-deep)}
.rre-btn[disabled]{opacity:.6;cursor:default}
.rre-btn.ghost{background:transparent;color:#C3CFDF;padding:9px 14px}
.rre-btn.ghost:hover{background:rgba(255,255,255,.08);color:#fff}

/* toast */
.rre-toast{position:fixed;left:50%;bottom:88px;transform:translate(-50%,16px);z-index:1001;
  background:#1E2E44;color:#fff;font-size:13.5px;font-weight:500;
  padding:11px 20px;border-radius:99px;box-shadow:0 10px 34px rgba(15,24,38,.35);
  opacity:0;pointer-events:none;transition:opacity .2s,transform .2s}
.rre-toast.show{opacity:1;transform:translate(-50%,0)}
.rre-toast.err{background:var(--rose-deep)}

/* TinyMCE inline: give the active region a soft rose frame */
.rre-edit .mce-content-body.mce-edit-focus{outline:2px solid var(--rose)!important;outline-offset:8px;border-radius:2px}
.rre-active .rre-edit-tab{display:none}   /* hide tabs while one section is being edited */

/* ── contact modal ───────────────────────────────────────── */
.cmodal{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;padding:20px}
.cmodal[hidden]{display:none}
.cmodal-back{position:absolute;inset:0;background:rgba(30,46,68,.55);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.cmodal-card{position:relative;background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);max-width:540px;width:100%;padding:38px 36px 34px;box-shadow:var(--shadow-2);max-height:calc(100dvh - 40px);overflow:auto}
.cmodal-x{position:absolute;top:14px;right:14px;width:38px;height:38px;border-radius:99px;border:1px solid var(--line);background:#fff;font-size:19px;line-height:1;cursor:pointer;color:var(--slate)}
.cmodal-x:hover{border-color:var(--rose);color:var(--rose-deep)}
.cmodal h3{font-family:'Fraunces',serif;font-size:27px;margin-top:8px}
.cmodal h3 em{font-style:italic;color:var(--rose)}
.cmodal-sub{font-size:14px;color:var(--slate);margin-top:8px}
.cmodal-sub a{font-weight:600;white-space:nowrap}
.cm-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 14px}
@media(max-width:560px){.cm-grid{grid-template-columns:1fr}}
.cm-done{margin-top:20px;font-size:15px;font-weight:600;color:var(--ink)}
.cm-err{margin-top:14px;font-size:13.5px;color:var(--rose-deep)}
/* inline form validation message */
.form-err,.cm-err{margin-top:14px;font-size:13.5px;color:var(--rose-deep);font-weight:500}
.form-err[hidden]{display:none}
.muted-note{font-weight:400;color:var(--slate);font-size:.9em}
/* Turnstile: leave the widget's native Cloudflare card as-is; just center it with spacing */
.cf-turnstile,.cm-turnstile{margin:16px auto 4px;min-height:65px;display:flex;justify-content:center}

/* staff pill: transparent quick-access to the dashboard, bottom-left, logged-in only */
.staff-pill{
  position:fixed;left:14px;bottom:calc(14px + env(safe-area-inset-bottom));z-index:150;
  display:flex;align-items:center;border-radius:99px;overflow:hidden;
  background:rgba(255,251,242,.55);border:1px solid rgba(30,46,68,.14);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
  box-shadow:0 4px 18px rgba(30,46,68,.12);
}
.staff-pill-f{display:contents}
.staff-pill button{margin:0;border:0;background:none;font-family:inherit;line-height:inherit;cursor:pointer;-webkit-appearance:none;appearance:none}
.staff-pill a,.staff-pill button{display:inline-flex;align-items:center;gap:6px;padding:9px 14px;font-size:12.5px;font-weight:600;color:var(--ink);text-decoration:none;transition:background .15s,color .15s}
.staff-pill a:hover,.staff-pill button:hover{background:rgba(255,255,255,.8);color:var(--rose-deep)}
.staff-pill svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.staff-pill span{width:1px;height:15px;background:rgba(30,46,68,.16)}
@media(max-width:560px){.staff-pill{left:10px}.staff-pill a,.staff-pill button{padding:8px 12px;font-size:12px}}
@media print{.staff-pill{display:none}}
@media(max-width:560px){
  .cm-grid{grid-template-columns:1fr}
  /* stay centered on phones (not a bottom sheet): a native-feeling card that fits */
  .cmodal{padding:14px}
  .cmodal-card{border-radius:18px;max-height:calc(100dvh - 28px);padding:30px 22px 26px}
  .cmodal h3{font-size:24px}
}

/* ── market reports (pSEO pages) ─────────────────────────── */
/* toolbar: search + sort, sticky just under the nav for a long list */
.mtools{position:sticky;top:60px;z-index:40;display:flex;gap:12px;flex-wrap:wrap;align-items:center;
  padding:12px 0;margin-bottom:2px;background:linear-gradient(180deg,var(--paper) 78%,rgba(255,251,242,0))}
.msearch{position:relative;flex:1 1 260px;min-width:220px}
.msearch svg{position:absolute;left:15px;top:50%;transform:translateY(-50%);width:17px;height:17px;fill:none;stroke:var(--slate);stroke-width:2;stroke-linecap:round}
.msearch input{width:100%;padding:12px 16px 12px 42px;border:1px solid var(--line);border-radius:99px;font:15px 'Inter',sans-serif;background:#fff;color:var(--ink)}
.msearch input:focus{outline:none;border-color:var(--rose);box-shadow:0 0 0 3px rgba(56,121,189,.16)}
.msort{display:flex;align-items:center;gap:9px;flex-shrink:0}
.msort label{font-size:13px;color:var(--slate)}
.msort select{padding:11px 38px 11px 15px;border:1px solid var(--line);border-radius:99px;font:14px 'Inter',sans-serif;
  background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none' stroke='%234A5A72' stroke-width='1.8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E") no-repeat right 15px center;
  color:var(--ink);cursor:pointer;-webkit-appearance:none;appearance:none}
.msort select:focus{outline:none;border-color:var(--rose)}
.mcount{font-size:12.5px;color:var(--slate);margin:2px 0 18px}
.mgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(178px,1fr));gap:13px}
.mcard{display:flex;flex-direction:column;gap:3px;background:#fff;border:1px solid var(--line);border-radius:var(--r-md);padding:15px 17px;text-decoration:none;color:var(--ink);transition:transform .18s,box-shadow .18s,border-color .18s}
.mcard:hover{transform:translateY(-3px);box-shadow:var(--shadow-1);border-color:var(--rose)}
.mcity-name{font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--rose);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mzip{font-family:'Fraunces',serif;font-size:20px;font-weight:600;line-height:1.1}
.mval{font-size:14px;color:var(--rose-deep);font-weight:600;margin-top:1px}
.mval-l{font-weight:500;color:var(--slate);font-size:11.5px}
.mmeta{font-size:11.5px;color:var(--slate)}
.mempty{font-size:14.5px;color:var(--slate);padding:26px 2px}
@media(max-width:560px){
  .mtools{top:56px}
  .msort{flex:1 1 100%}
  .msort select{flex:1}
  .mgrid{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
}
.mstats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
@media(max-width:900px){.mstats{grid-template-columns:repeat(2,1fr)}}
.mstat{background:#fff;border:1px solid var(--line);border-radius:var(--r-md);padding:20px 18px;text-align:center}
.ms-v{display:block;font-family:'Fraunces',serif;font-size:clamp(20px,2.6vw,28px);font-weight:600}
.ms-l{display:block;font-size:11.5px;color:var(--slate);margin-top:4px;letter-spacing:.02em}
.mverdict{margin-top:26px;background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:26px 28px}
.mv-text{font-family:'Fraunces',serif;font-size:clamp(17px,2.2vw,21px);line-height:1.55}
.mfaq{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:8px}
@media(max-width:760px){.mfaq{grid-template-columns:1fr}}
.mqa{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:22px 24px}
.mqa h3{font-size:17.5px;margin-bottom:6px}
.mqa p{font-size:14px;color:var(--slate)}
.msrc{font-size:12px;margin-top:16px}
.mnear{margin-top:12px;display:flex;flex-wrap:wrap;gap:8px 14px;justify-content:center}
.mnear a{font-size:13.5px;white-space:nowrap}

/* ── tiny bright accents (07-09): small bold color moments, kept quiet.
   Jewel tones only — the green is DEEP emerald (brand rule: no light green). ── */
::selection{background:var(--rose-deep);color:#fff}
/* a small pride ribbon tucked under the footer tagline */
.pride{display:inline-flex;width:66px;height:4px;border-radius:99px;overflow:hidden;margin:2px 0 14px}
.pride i{flex:1}
.pride i:nth-child(1){background:#C0394B}
.pride i:nth-child(2){background:#D06B2E}
.pride i:nth-child(3){background:#C9A22E}
.pride i:nth-child(4){background:#1E6B3E}
.pride i:nth-child(5){background:#3F63B0}
.pride i:nth-child(6){background:#7A4E9E}
/* pops: the admin-chosen hero word + the last word of homepage section titles,
   in the same bright pink-red as the primary buttons */
.hero h1 .pop,.shead h2 .pop{color:var(--pop)}

/* ── ZIP market pages: the five-year trend, and the guides behind the numbers ── */

/* Chart is server-drawn SVG so it needs no script and cannot fail to appear.
   preserveAspectRatio:none lets it stretch; strokes stay crisp via vector-effect. */
.mchart{margin:0;border:1px solid var(--line,#E9DFC8);border-radius:10px;background:var(--paper);overflow:hidden}
.mchart svg{display:block;width:100%;height:clamp(140px,22vw,200px)}
.mchart-fill{fill:var(--blush)}
.mchart-line{fill:none;stroke:var(--rose-deep);stroke-width:2;vector-effect:non-scaling-stroke;stroke-linejoin:round}
.mchart figcaption{display:flex;justify-content:space-between;gap:12px;padding:10px 14px;
  border-top:1px solid var(--line,#E9DFC8);font-size:13px;color:var(--ink-2);background:var(--cream)}
.mchart figcaption span:nth-child(2){font-weight:600;color:var(--ink)}

.mtrend-yoy{display:flex;align-items:baseline;gap:8px;margin:0}
.mt-n{font-family:'Newsreader',Georgia,serif;font-size:clamp(28px,4vw,40px);line-height:1;color:var(--ink)}
.mt-n.up{color:#2F6B4F}
.mt-n.down{color:#8A1428} /* ello: a falling number stays red, not brand blue */
.mt-l{font-size:13px;letter-spacing:.02em;color:var(--ink-2)}
.mtrend-say{margin:16px 0 0;max-width:62ch;font-size:clamp(16px,1.6vw,18px);line-height:1.6;color:var(--ink-2)}

/* Guide teasers + neighborhood index: the Journal card, retold. Image-top
   3:2 smart crop (wcard, same cropper the posts use); a guide with no
   relevant photo is a text card, never a placeholder slab. */
.ghints{display:grid;gap:18px;grid-template-columns:1fr}
@media (min-width:720px){.ghints{grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}}
.ghint,.nbcard{display:flex;flex-direction:column;background:#fff;border:1px solid var(--line);
  border-radius:var(--r-lg);overflow:hidden;color:var(--ink);text-decoration:none;
  transition:transform .25s,box-shadow .25s}
.ghint:hover,.nbcard:hover{transform:translateY(-5px);box-shadow:var(--shadow-2)}
@media (hover:none){.ghint:hover,.nbcard:hover{transform:none;box-shadow:none}}
.ghint:focus-visible,.nbcard:focus-visible{outline:2px solid var(--rose-deep);outline-offset:3px}
.gh-img,.nb-img{display:block;aspect-ratio:16/9;background:var(--blush);overflow:hidden}
.gh-img img,.nb-img img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .5s cubic-bezier(.2,.6,.2,1)}
.ghint:hover .gh-img img,.nbcard:hover .nb-img img{transform:scale(1.04)}
.gh-body,.nb-body{display:flex;flex-direction:column;gap:7px;padding:18px 20px 20px}
.gh-k{font-size:11.5px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:var(--rose-ink)}
.gh-t{font-family:'Fraunces',serif;font-size:21px;line-height:1.25;color:var(--ink)}
.gh-d{font-size:14px;line-height:1.6;color:var(--slate)}
.gh-go{margin-top:2px;font-size:14px;font-weight:600;color:var(--rose-ink)}
/* Guides carry no rules at the top (Eric, 2026-08-13): neither the header
   hairline nor the little dash before the eyebrow. */
.phead.plain{border-bottom:0}
.phead.plain .eyebrow::before{display:none}
.nbgrid{display:grid;gap:18px;grid-template-columns:1fr}
@media (min-width:720px){.nbgrid{grid-template-columns:repeat(2,1fr)}}
@media (min-width:1040px){.nbgrid{grid-template-columns:repeat(3,1fr)}}
.nb-t{font-family:'Fraunces',serif;font-size:21px;font-weight:600;line-height:1.25;margin:0;color:var(--ink)}
.nb-meta{font-size:13px;line-height:1.5;color:var(--slate)}
.nb-d{font-size:14px;line-height:1.6;color:var(--ink-2)}
/* body-size links on paper need the deepened rose: --rose-deep is 3.88:1 here,
   under the 4.5 floor the eyebrows already solved with --rose-ink */
.case-link{color:var(--rose-ink)}

/* Hub: ZIPs with a written guide behind them lead the grid and carry the
   author's name for the area. A stat block is worth less than her own words,
   so the card says which is which before you click. */
.mcard.guided{border-color:var(--rose-soft,#EEC8CB);background:linear-gradient(180deg,var(--blush,#FFF3D9) 0%,var(--paper,#FFFBF2) 46%)}
.mguide{display:flex;align-items:center;gap:6px;margin-top:9px;padding-top:9px;
  border-top:1px solid var(--rose-soft,#EEC8CB);font-size:12.5px;font-weight:600;
  color:var(--rose-deep,#2A5F96);line-height:1.35}
.mguide svg{width:14px;height:14px;flex:none}

/* ---- IDX compliance (RMLS) — inert until the feed is licensed ---- */
.idx-legal{max-width:none;margin:22px 0 0;padding-top:18px;border-top:1px solid rgba(255,255,255,.12)}
.idx-legal p{font-size:11.5px;line-height:1.55;color:rgba(255,255,255,.55);margin:0 0 8px}
.idx-legal img{opacity:.7;margin-bottom:8px}
/* why this card is a result (MlsCatalog::matched): the field that matched and,
   for the remarks, the sentence it matched in. Blush, never highlighter. */
mark{background:var(--blush);color:inherit;border-radius:3px;padding:0 2px;font-weight:600}
.lwhy{margin:4px 0 0;font-size:12.5px;color:var(--slate);display:flex;flex-wrap:wrap;gap:4px 8px;align-items:baseline}
.lwhy-k{font:600 11px/1.5 'Inter',sans-serif;letter-spacing:.04em;text-transform:uppercase;color:var(--rose-ink)}
.lwhy-s{flex:1 1 100%;font-size:12.5px;line-height:1.45;color:var(--slate)}
/* the listing firm on every card. 14px, not 13: the listing-data median this
   licence is measured against is 13.5px (`.lh-price span` on a detail page) and
   the attribution may never read smaller (COMPLIANCE 10; Rules 9.3; IP III
   Part.#9). The card's own data runs 23 / 14.5 / 12.5px; see row 10 for why
   that stricter reading is recorded rather than acted on. */
.lcourtesy{font-size:14.5px;color:var(--slate);margin-top:6px;display:flex;align-items:flex-start;gap:8px}
.lcourtesy img,.lcourtesy .rmls-mark{flex:0 0 auto;margin-top:3px}   /* the mark sits on the first line of the courtesy text, not centred across three */
.lcourtesy img{opacity:.85;flex:none}
/* The RMLS mark [COMPLIANCE 9], one rule for every surface that carries it:
   the card, the detail page under the gallery, and the footer disclaimer. It
   is the stand-in RMLS's own artwork replaces the moment assets/rmls-logo.png
   exists; until then it must still be on every RMLS-sourced listing. */
.rmls-mark{display:inline-block;flex:none;font:600 11px/1 'Inter',sans-serif;letter-spacing:.08em;border:1px solid currentColor;border-radius:4px;padding:3px 5px}

/* ---------------------------------------------------------------------------
   Old-browser floor (Safari 14 and older, and the Android WebViews that track
   it). Two properties this stylesheet leans on hard did not exist there, and
   both fail to nothing rather than to something smaller:
     aspect-ratio · the photo frames are empty boxes with no height, so listing
                    cards, blog cards, galleries and guide teasers rendered as
                    invisible slabs. The padding-top ratios below reserve the
                    same shape the modern property does.
     inset        · the modal backdrops and the lightbox lose their positioning
                    and stop covering the screen.
   Both blocks are inert on any browser that supports the real thing.
--------------------------------------------------------------------------- */
/* These percentages restate the aspect-ratio values above and have to move
   with them: 4/3 = 75%, 16/9 = 56.25%, 3/2 = 66.667%. The guide thumbs were
   3/2 until the teasers were made smaller. */
@supports not (aspect-ratio: 4 / 3) {
  /* position:relative belongs in here too: .pimg and the guide thumbs never
     needed it while aspect-ratio held the shape, and without it the absolute
     children below would escape to the nearest positioned ancestor */
  .lphoto, .rgal-ph, .pimg, .gh-img, .nb-img { position: relative; }
  .lphoto, .rgal-ph { height: 0; padding-top: 75%; }          /* 4:3 */
  .pimg { height: 0; padding-top: 56.25%; }                   /* 16:9 */
  .gh-img, .nb-img { height: 0; padding-top: 56.25%; }         /* 16:9 */
  .ed-photo img { height: auto; }                             /* 4:5, let it size itself */
  .lphoto > *, .rgal-ph > *, .pimg > *, .gh-img > *, .nb-img > * {
    position: absolute; top: 0; left: 0; width: 100%; height: 100%;
  }
}
@supports not (inset: 0) {
  .vmodal, #rgal-m, .cmodal, .cmodal-back, .vwrap::after {
    top: 0; right: 0; bottom: 0; left: 0;
  }
  .ed-photo::before { top: 18px; right: -18px; bottom: -18px; left: 18px; }
}

/* Listing spec sheet ("By the numbers") in the content frame: no card chrome,
   a small sans heading sized to its own rows, and the same dotted hairline the
   features list uses. Lives here, not in the template's conditional style
   block, so a listing whose ZIP has no market row still gets the styles. */
.lspecs{margin-top:38px}
.lspecs-h{font-family:'Inter',system-ui,sans-serif;font-size:13.5px;font-weight:700;letter-spacing:0;text-transform:none;margin:0 0 14px}
.lspecs-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:0 40px}
.lspec{display:flex;justify-content:space-between;align-items:baseline;gap:14px;padding:11px 0;border-bottom:1px dashed var(--line);font-size:13.5px}
.lspec span{color:var(--slate)}
.lspec b{font-weight:600}
@media(max-width:560px){.lspecs-grid{grid-template-columns:1fr}}


/* ── the viewer, while the full-size file is still on its way ──────────────
   Same language as the wireframe loading above, on a dark ground: ruled box,
   one slow sheen, and the 720px rendition blurred underneath as soon as it
   decodes. --rgal-ar is set from that rendition's real proportions, so the box
   is the size the photograph will be and nothing jumps when it arrives. The
   3/2 default is what a listing photo almost always is. */
#rgal-m .rgal-box{width:min(92vw,1100px);aspect-ratio:var(--rgal-ar,3/2);max-height:76vh;
  border-radius:12px;position:relative;overflow:hidden;
  background-color:rgba(255,255,255,.045);box-shadow:0 34px 90px rgba(0,0,0,.45)}
#rgal-m .rgal-box::before{content:"";position:absolute;top:0;right:0;bottom:0;left:0;
  background-image:linear-gradient(rgba(255,255,255,.07) 1px,transparent 1px),
                   linear-gradient(90deg,rgba(255,255,255,.07) 1px,transparent 1px);
  background-size:32px 32px;background-position:center}
/* the blurred stand-in overhangs its box so its own soft edge never shows */
#rgal-m .rgal-pre{position:absolute;top:-6%;right:-6%;bottom:-6%;left:-6%;
  background-position:center;background-size:cover;
  -webkit-filter:blur(14px) saturate(1.05);filter:blur(14px) saturate(1.05);opacity:.7}
#rgal-m .rgal-box::after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;z-index:2;
  background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.14) 50%,transparent 62%);
  transform:translateX(-100%);animation:rgalskel 2.2s cubic-bezier(.4,0,.3,1) infinite}
@keyframes rgalskel{to{transform:translateX(100%)}}
#rgal-m .rgal-media{animation:rgalfade .26s ease both}
@keyframes rgalfade{from{opacity:0}to{opacity:1}}
@media(prefers-reduced-motion:reduce){
  #rgal-m .rgal-box::after{display:none}
  #rgal-m .rgal-media{animation:none}
}
@media(max-width:640px){#rgal-m .rgal-box{width:96vw;max-height:70vh}}

/* ── the palette (assets/palette.js): one field over the page, / or Cmd-K ──
   The same language as the contact modal: a scrim, a card, the brand's
   radius. On a phone it is a sheet from the top with 44px rows. */
.pal{position:fixed;inset:0;z-index:170;display:none}
.pal.open{display:block}
/* the scrim and the card arrive together, 160ms, ease-out; the rows follow
   one at a time (--d, set in palette.js) so a result set reads as an answer
   assembling rather than a block landing. All of it is off under
   prefers-reduced-motion, at the foot of this section. */
.pal-back{position:absolute;inset:0;background:rgba(19,29,44,.55);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);opacity:0;transition:opacity .16s ease-out}
.pal.open .pal-back{opacity:1}
.pal-box{position:absolute;left:50%;top:10vh;transform:translateX(-50%) scale(.97);opacity:0;transition:opacity .16s ease-out,transform .16s ease-out;width:min(700px,calc(100vw - 24px));background:var(--paper,#FFFBF2);border-radius:var(--r-lg,20px);box-shadow:0 30px 80px rgba(0,0,0,.35);overflow:hidden;display:flex;flex-direction:column;max-height:80vh;max-height:80dvh}
.pal-form{position:relative;display:flex;align-items:center;gap:10px;padding:12px 12px 12px 16px;border-bottom:1px solid var(--rule,var(--line,#DDD4B9));flex:none}
/* a fetch is in flight: a thin line travels under the field, and the list on
   screen stays exactly where it is until the next one arrives */
.pal-form::after{content:"";position:absolute;left:0;bottom:-1px;height:2px;width:34%;background:var(--rose-deep,#2A5F96);opacity:0;transform:translateX(-40%)}
.pal.busy .pal-form::after{opacity:1;animation:palbar 1s linear infinite}
@keyframes palbar{0%{transform:translateX(-40%)}100%{transform:translateX(300%)}}
.pal-ico{color:var(--slate,#4A5A72);display:flex}
.pal-in{flex:1;min-width:0;min-height:44px;border:0;background:transparent;font:inherit;font-size:17px;outline:none;padding:0}
.pal-go{min-height:44px;padding:0 20px;font-size:14.5px;white-space:nowrap;flex:none}
.pal-x{min-height:32px;border:0;background:transparent;padding:0 2px;cursor:pointer;flex:none}
.pal-x kbd,.pal-foot kbd{display:inline-flex;align-items:center;justify-content:center;min-width:24px;min-height:24px;padding:0 6px;border:1px solid var(--rule,var(--line,#DDD4B9));border-radius:6px;background:#fff;font:600 11px/1 'Inter',sans-serif;letter-spacing:.06em;color:var(--slate,#4A5A72)}
.pal-x:hover kbd{border-color:var(--slate,#4A5A72)}
.pal-list{list-style:none;margin:0;padding:6px 0;overflow:auto;flex:1 1 auto;-webkit-overflow-scrolling:touch}
/* a row: a square on the left, then title, meta, teaser. The whole row is the
   hit target, and nothing in it is narrower than a thumb. */
.pal-list li.pal-r{display:flex;align-items:flex-start;gap:12px;padding:9px 16px;min-height:56px;cursor:pointer;font-size:15px}
.pal-list li.pal-head{display:flex;align-items:center;min-height:28px;padding:10px 16px 4px;font:600 11px/1 'Inter',sans-serif;letter-spacing:.1em;text-transform:uppercase;color:var(--slate,#4A5A72);cursor:default}
.pal-list li.on,.pal-list li.pal-r:hover{background:var(--rose-wash,#FFF3D9)}
.pal-th{width:48px;height:48px;flex:0 0 48px;border-radius:10px;overflow:hidden;background:var(--cream,#FFF3D9);color:var(--slate,#4A5A72);display:flex;align-items:center;justify-content:center;margin-top:1px}
.pal-th img{width:48px;height:48px;object-fit:cover;border-radius:10px}
.pal-b{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.pal-b b{font-weight:600;line-height:1.35;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pal-s{font-size:13px;color:var(--slate,#4A5A72)}
/* two lines of the listing's own words, then an ellipsis */
.pal-t{font-size:12.5px;line-height:1.4;color:var(--slate,#4A5A72);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.pal-l .lcourtesy{margin-top:3px;font-size:13px}
/* the cuts of a city, under its row: real links, pointer affordances. Every
   one of them is reachable from the /homes facets too, so the keyboard model
   of the list (arrows, Enter) stays a list of rows and nothing else. */
.pal-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}
.pal-chip{display:inline-flex;align-items:center;min-height:28px;padding:0 10px;border:1px solid var(--line,#DDD4B9);border-radius:99px;background:#fff;font-size:12px;color:var(--slate,#4A5A72);text-decoration:none;white-space:nowrap}
.pal-chip:hover{border-color:var(--rose-deep,#2A5F96);color:var(--rose-deep,#2A5F96);background:var(--blush,#FFF3D9)}
.pal-n{margin-left:auto;color:var(--slate,#4A5A72);font-size:13px}
.pal-list mark{background:var(--blush,#FFF3D9);color:inherit;border-radius:3px;padding:0 1px}
.pal-list li.pal-help{min-height:0;padding:10px 16px 4px;font-size:12px;line-height:1.45;color:var(--slate,#4A5A72);cursor:default;display:block}
.pal-hint{margin:0;padding:8px 16px 12px;font-size:13px;color:var(--slate,#4A5A72)}
.pal-hint:empty{display:none}
.pal-foot{flex:none;display:flex;gap:18px;align-items:center;padding:9px 16px;border-top:1px solid var(--rule,var(--line,#DDD4B9));background:var(--cream,#FFF3D9);font-size:11.5px;color:var(--slate,#4A5A72)}
.pal-foot span{display:inline-flex;align-items:center;gap:5px}
.pal.open .pal-box{opacity:1;transform:translateX(-50%) scale(1)}
.pal-list>li{opacity:0;transform:translateY(4px);animation:palrow .22s ease-out forwards;animation-delay:var(--d,0ms)}
@keyframes palrow{to{opacity:1;transform:none}}
.pal-th img{opacity:0;transition:opacity .25s ease-out}
.pal-th img.in{opacity:1}
/* a recent search is a memory, not a result: muted, with a clock beside it */
.pal-k-recent .pal-b b{font-weight:500;color:var(--slate,#4A5A72)}
@media(prefers-reduced-motion:reduce){
  .pal-back,.pal-box{transition:none}
  .pal-box{transform:translateX(-50%)}
  .pal.open .pal-box{transform:translateX(-50%)}
  .pal-list>li{opacity:1;transform:none;animation:none}
  .pal-th img{opacity:1;transition:none}
  .pal.busy .pal-form::after{animation:none;width:100%;transform:none}
}
html.pal-open{overflow:hidden}
.nav kbd{display:inline-block;font:600 11px/1 'Inter',sans-serif;border:1px solid currentColor;border-radius:4px;padding:2px 5px;margin-left:4px;opacity:.7}
@media(max-width:640px){
  /* a sheet from the top of the phone; dvh, never vh, or the footer bar sits
     under the iOS toolbar */
  .pal-box{top:0;left:0;right:0;transform:none;width:100%;max-height:100vh;max-height:100dvh;border-radius:0 0 var(--r-lg,20px) var(--r-lg,20px)}
  .pal-form{flex-wrap:wrap;gap:8px}
  .pal-go{order:3;flex:1}
  .pal-x{order:4}
  .pal-foot{gap:12px}
  .nav kbd{display:none}
}
/* the palette's desktop trigger in the main nav: an icon and a word, the same weight as its neighbours */
.pal-li a{display:inline-flex;align-items:center;gap:6px}
.pal-li svg{flex:0 0 auto}
@media(max-width:900px){.pal-li{display:none}}

/* ── accounts (modules/mls/accounts.php) ─────────────────────────────────── */
/* the heart: a sibling of the card link inside .lwrap, so the card stays an anchor */
.lwrap{position:relative}
.lwrap .lcard{height:100%}
.lwrap:hover .lcard{transform:translateY(-5px);box-shadow:var(--shadow-2)}
.lsave-f{margin:0}
.lwrap .lsave-f{position:absolute;top:8px;right:8px;z-index:2}
.lsave{display:inline-flex;align-items:center;justify-content:center;gap:7px;min-width:44px;min-height:44px;padding:0;border:0;border-radius:99px;background:rgba(255,255,255,.92);color:var(--ink);cursor:pointer;backdrop-filter:blur(4px);box-shadow:0 2px 10px rgba(0,0,0,.12);transition:transform .15s,color .15s;touch-action:manipulation}
.lsave svg{fill:none;stroke:currentColor;stroke-width:1.9;stroke-linejoin:round;transition:fill .15s}
.lsave:hover{transform:scale(1.06);color:var(--rose-deep)}
.lsave.on{color:var(--pop)}
.lsave.on svg{fill:currentColor}
.lsave:disabled{opacity:.6}
.lsave-lbl .lsave{padding:0 16px 0 12px;box-shadow:none;border:1px solid var(--line);background:#fff;font:600 13.5px/1 'Inter',sans-serif}
.listing-head .lsave-f{margin-top:10px}
/* unheart-instant (2026-10-12): a member's own list ([data-saved-list] on
   /account and /portal). Taking a heart back fades the card out, the rest
   glide into its place (assets/account.js, FLIP), and the "Removed. Undo"
   bar sits at the foot of the screen for six seconds. Reduced motion: no
   fade, no glide, the card simply goes. */
[data-saved-list]>*{transition:opacity .18s ease,transform .18s ease}
[data-saved-list]>.sv-out{opacity:0;transform:scale(.96);pointer-events:none}
.mempty[hidden],[data-saved-list][hidden]{display:none}
.sv-bar{position:fixed;left:50%;bottom:max(16px,env(safe-area-inset-bottom));z-index:1002;
  display:flex;align-items:center;gap:6px;width:max-content;max-width:calc(100vw - 32px);box-sizing:border-box;
  padding:0 6px 0 20px;min-height:52px;border-radius:26px;background:var(--ink);color:#fff;
  font:500 15px/1.35 'Inter',sans-serif;box-shadow:0 10px 34px rgba(15,24,38,.35);
  opacity:0;transform:translate(-50%,12px);transition:opacity .2s,transform .2s}
.sv-bar.show{opacity:1;transform:translate(-50%,0)}
.sv-bar[hidden]{display:none}
.sv-bar.err{background:#8A1428;padding-right:20px}
.sv-msg{padding:12px 0}
.sv-undo{min-width:44px;min-height:44px;padding:0 16px;border:0;border-radius:99px;background:transparent;
  color:#fff;font:600 15px/1 'Inter',sans-serif;text-decoration:underline;text-underline-offset:3px;cursor:pointer;touch-action:manipulation}
.sv-undo[hidden]{display:none}
.sv-undo:hover,.sv-undo:focus-visible{background:rgba(255,255,255,.14)}
.sv-undo:focus-visible{outline:2px solid #fff;outline-offset:2px}
@media(prefers-reduced-motion:reduce){[data-saved-list]>*,.sv-bar{transition:none}.sv-bar{transform:translate(-50%,0)}}
/* the nav link */
.acct-li a{display:inline-flex;align-items:center;gap:6px}
/* The account is never a word in the desktop bar. One control, one shape, on
   both platforms and in both states: a 36px circle of theme red with a white
   person in it, 44px of target around it, pointing at the account when there is
   a session and at the login when there is not. Phones carry it beside the
   hamburger, desktops at the far right edge of the header. The 821-900 band has
   neither a hamburger nor the desktop edge, so there the row keeps its word,
   and the open phone menu keeps its word too. */
.acct-dot{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;
          background:var(--pop);color:#fff;flex:none;transition:transform .15s,background .2s}
.acct-dot svg{flex:0 0 auto}
.acct-circle:active .acct-dot,.acct-edge:active .acct-dot{transform:scale(.94)}
.acct-circle{display:none}
.acct-edge{display:none}
@media(max-width:820px){
  /* 36px of theme red inside a 44px target, immediately left of the hamburger:
     the auto margin moves off the button and onto the circle so the pair sits
     together at the right end of the bar, 9px apart (the bar's gap is 16px at
     this width, so the pull-back is 7). */
  .acct-circle{display:flex;align-items:center;justify-content:center;width:44px;height:44px;flex:none;
               margin-left:auto;margin-right:-7px;text-decoration:none;-webkit-tap-highlight-color:transparent}
  .menu-btn{margin-left:0}
}
/* Search as an icon on a desktop: the magnifier carries the keyboard shortcut
   in muted type and keeps its 44px target. The phone menu is untouched:
   .pal-li is hidden there and .acct-li keeps its word. */
@media(min-width:901px){
  .pal-li a{position:relative;min-width:44px;min-height:44px;justify-content:center;gap:5px}
  /* the 44px target leaves 13px of air on each side of a 17px glyph; pull half
     of it back on the right so the magnifier reads as part of the CTA cluster
     rather than as a third nav word floating away from it */
  .pal-li{margin-right:-8px}
  /* the account has left the row entirely (see .acct-edge) */
  .acct-li{display:none}
  /* the shortcut, on hover or keyboard focus only: a permanent key cap in the
     bar is furniture, and on a touch device it names a key that is not there */
  .nav-tip{position:absolute;top:calc(100% - 2px);left:50%;z-index:5;display:flex;align-items:center;gap:6px;
           padding:6px 10px;border-radius:8px;background:var(--ink);color:#fff;font:500 12px/1 'Inter',sans-serif;
           white-space:nowrap;opacity:0;pointer-events:none;transform:translate(-50%,-4px);
           transition:opacity .18s ease-out .15s,transform .18s ease-out .15s}
  .nav-tip kbd{display:inline-flex;align-items:center;justify-content:center;min-width:18px;min-height:18px;padding:0 4px;
               border:1px solid rgba(255,255,255,.45);border-radius:4px;font:600 10px/1 'Inter',sans-serif}
  .pal-li a:hover .nav-tip,.pal-li a:focus-visible .nav-tip{opacity:1;transform:translate(-50%,0)}
  @media(hover:none){.nav-tip{display:none}}
  @media(prefers-reduced-motion:reduce){.nav-tip{transition:opacity .01s}}
  /* the far right edge of the header, not the right edge of the centred wrap:
     a direct child of the sticky/fixed .nav, on the header's own 24px gutter,
     vertically centred on the 68px bar row */
  .acct-edge{position:absolute;right:24px;bottom:0;z-index:2;height:68px;width:44px;
             display:flex;align-items:center;justify-content:center;text-decoration:none;
             -webkit-tap-highlight-color:transparent}
  .acct-edge:hover .acct-dot{background:#1F4A77;transform:translateY(-1px)}
  /* reserve the slot: below ~1224px the wrap reaches the gutter and the Home
     value button would otherwise run under the circle */
  body.has-acct .nav .wrap{padding-right:clamp(24px,calc(82px - (100vw - var(--wrap)) / 2),82px)}
}
@media(max-width:900px){.nav.open .acct-li a.on{color:var(--rose-deep)!important}}
.acct-li a.on{color:var(--rose-deep)}
/* the pages */
.acct-sec{padding-top:clamp(28px,4vw,44px)}
.acct-sec+.acct-sec{padding-top:0}
.acct-flash{margin:18px 0 0;padding:12px 16px;border-radius:12px;background:var(--blush);color:var(--ink);font-size:14.5px}
.acct-flash.err{background:#F8E8E8;color:#8A1428}
/* the same note on a page that is not an account page: saving a home sends the
   visitor back to the grid they were reading, and the reply has to land there */
.sitenote{display:flex;align-items:center;gap:12px;margin:14px 0 0;padding:12px 16px;border-radius:12px;background:var(--blush);border:1px solid var(--line);color:var(--ink);font-size:14.5px;line-height:1.5}
.sitenote.err{background:#F8E8E8;border-color:#EBD0D0;color:#8A1428}
.sitenote>span{flex:1;min-width:0}
.sitenote-x{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;margin:-11px -10px -11px 0;border:0;background:none;color:inherit;opacity:.65;cursor:pointer}
.sitenote-x:hover{opacity:1}
.sitenote-hold.under-nav{padding-top:calc(78px + var(--broke-h))}
.intake.acct h2{font-family:'Fraunces',serif;font-size:24px;font-weight:400;margin:0 0 8px}
.intake.acct .hp{position:absolute;left:-9999px;top:0;width:1px;height:1px;overflow:hidden}
.intake.acct{position:relative}
.intake.acct .btn+.btn{margin-left:10px}
.acct-check{display:flex;gap:12px;align-items:flex-start;margin-top:18px;font-size:14px;color:var(--slate);font-weight:400;letter-spacing:0}
.acct-check input{width:22px;height:22px;flex:0 0 auto;margin-top:1px;accent-color:var(--pop)}
.acct-note{font-size:17px;line-height:1.65;margin:0 0 18px}
.acct-row{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px}
.acct-row h2{font-family:'Fraunces',serif;font-size:28px;font-weight:400;margin:0}
.acct-inline{margin:0}
.acct-two{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:22px;align-items:start}
.acct-two .intake{max-width:none}
.acct-side{display:grid;gap:22px}
.acct-lead{font-size:14.5px;color:var(--slate);line-height:1.6;margin:0 0 6px}
.acct-photo{display:flex;align-items:center;gap:16px;margin:8px 0 4px}
.acct-photo img,.acct-initial{width:72px;height:72px;border-radius:50%;object-fit:cover;flex:0 0 auto}
.acct-initial{display:inline-flex;align-items:center;justify-content:center;background:var(--blush);color:var(--rose-deep);font-family:'Fraunces',serif;font-size:30px}
.acct-photo label{margin-top:0}
.acct-photo input[type=file]{padding:9px 0;border:0;background:none;font-size:13.5px}
.fgrid-half{display:grid;grid-template-columns:80px 1fr;gap:0 14px}
.acct-delete summary{cursor:pointer;font-size:14px;color:var(--slate);padding:10px 0;min-height:44px;display:flex;align-items:center}
.acct-delete .intake{margin-top:10px}
.btn.ghost.danger{color:#8A1428;border-color:#E9B9BE}
.btn.ghost.danger:hover{background:#F8E8E8;border-color:#8A1428;color:#8A1428}
@media(max-width:860px){.acct-two{grid-template-columns:1fr}}
@media(max-width:620px){.intake.acct .btn{width:100%;text-align:center}.intake.acct .btn+.btn{margin:10px 0 0}}
/* phones: the scrolled overlay nav is an opaque paper bar, never a translucent
   blur that reads as a light gradient frame over photos. It no longer slides
   away on scroll-down (layout.php's onScroll stopped setting .hidden), which
   is why the opaque rule below now covers EVERY phone nav and not just the
   home page's overlay: a bar that retreats can afford to be translucent,
   because you rarely see content pass under it. A bar that stays cannot.
   Left at 88% with a blur, a market report's paragraphs read straight through
   the site name. */
@media(max-width:900px){
  .nav.scrolled{background:var(--paper);backdrop-filter:none;-webkit-backdrop-filter:none}
}
/* phone: the palette is a full-screen sheet, never a floating box that the
   keyboard and the notch can cut off; dvh follows the keyboard, the safe
   areas keep the input and the footer hints reachable */
@media(max-width:700px){
  .pal-box{left:0;top:0;width:100%;max-width:none;height:100dvh;max-height:100dvh;border-radius:0;transform:none;display:flex;flex-direction:column;
    padding-top:env(safe-area-inset-top,0);padding-bottom:env(safe-area-inset-bottom,0);box-shadow:none}
  .pal.open .pal-box{transform:none}
  .pal-form{flex:0 0 auto}
  .pal-list{flex:1 1 auto;min-height:0;max-height:none;overflow:auto;-webkit-overflow-scrolling:touch}
  .pal-foot,.pal-hints{flex:0 0 auto}
  .pal-in{font-size:16px}   /* 16px stops iOS zooming the page on focus */
}
/* phone palette: the input gets the width; the submit is a compact arrow, the
   keyboard hints (arrows, Enter) are hidden because a thumb never uses them */
@media(max-width:700px){
  .pal-form .btn.pal-go{width:44px!important;min-width:44px!important;max-width:44px;flex:0 0 44px!important;height:44px;padding:0!important;margin:0 8px 0 4px;font-size:0;border-radius:22px;display:inline-flex;align-items:center;justify-content:center}
  .pal-form .btn.pal-go::after{content:"\2192";font-size:22px;line-height:1}   /* a bare arrow: the word does not fit beside the field */
  .pal-x kbd{display:none}
  .pal-x::after{content:"Close";font-size:13px;font-weight:600;color:var(--slate)}
  .pal-foot{display:none}
}

/* a feed card whose photo could not load: a quiet cream block, no mark, no shimmer */
.lphoto.photo-missing{background:var(--cream,#FFF3D9)}
.lphoto.photo-missing::after{display:none}

/* the price row: price left, the RMLS mark top right (feed cards) */
.lprice-row{display:flex;align-items:center;justify-content:space-between;gap:10px}
.lprice-row .lprice{margin:0}
.lmark{flex:0 0 auto;display:inline-flex;align-items:center}
.lmark img{width:44px;height:16px;display:block}

/* the map door in the phone bar, the account circle's quiet sibling */
.map-circle{display:none}
@media (max-width:820px){
  .map-circle{display:flex;align-items:center;justify-content:center;width:44px;height:44px;flex:none;margin-left:auto}
  .map-circle+ .acct-circle{margin-left:0}
  .acct-circle{margin-left:0}
  .nav .wrap:has(.map-circle) .brand{margin-right:auto}
  .map-dot{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:50%;
           background:var(--cream,#FFF3D9);border:1px solid var(--line,#E9DFC8);color:var(--pop,#2A5F96)}
  .map-circle:active .map-dot{transform:scale(.94)}
}

/* the phone bar fits its own gutter at every width down to 320 (Wren, 2026-10-12).
   The hamburger was a flex item free to shrink: it fell to 23px wide and still ran
   10px past the gutter at 390 and off the screen at 320. It is a fixed 44px target
   now, pulled 10px into the gutter so its lines (23px, centred) end on the gutter.
   Below 410 the three targets sit flush (their dots keep 8px of air), below 380 the
   name steps down a size, and below 350 the rose mark gives way to the name and the
   brokerage strip tightens. Nothing wraps, nothing leaves the screen; the desktop
   bar is untouched (every rule here is phone-only). */
@media (max-width:820px){
  .menu-btn{flex:none;width:44px;height:44px;margin-right:-10px}
}
@media (max-width:410px){
  .nav .wrap{gap:0}
  .nav .brand{margin-right:auto;padding-right:8px}
  .acct-circle,.map-circle{margin-left:0;margin-right:0}
}
@media (max-width:380px){
  .nav .brand{font-size:18px}
}
@media (max-width:350px){
  .nav .brand{font-size:16px}
  .nav .brand .rose-mark{display:none}
  .brokebar .wrap{gap:8px}
  .brokebar-mark{height:15px}
  .brokebar-t{font-size:13.5px}
}

/* ── IDX Step 11: the mortgage calculator card (themes/rose/_mortgage.php) ──
   Phone first. The total sits in a bar that sticks under the 68px nav while
   the inputs scroll, so it stays readable as a number is typed; sticky, never
   fixed (the iOS fixed-position rule), and it lets go when the card ends.
   Inputs are 16px so iOS does not zoom on focus, and every target is 44px. */
.mcalc{background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:20px 18px 18px;margin:26px 0 0}
.mcalc .lspecs-h{margin-bottom:10px}
.mc-sum{position:sticky;top:69px;z-index:5;display:flex;align-items:baseline;justify-content:space-between;gap:12px;
        margin:0 -18px;padding:12px 18px;background:var(--blush);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.mc-sum span{font-size:14px;color:var(--ink-2)}
.mc-sum b{font-family:'Fraunces',Georgia,serif;font-size:26px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.mc-break{margin:10px 0 0;padding:0}
.mc-break div{display:flex;justify-content:space-between;gap:12px;padding:7px 0;border-bottom:1px solid var(--line);font-size:14.5px}
.mc-break div:last-child{border-bottom:0}
.mc-break dt{color:var(--slate)}
.mc-break dt small{display:block;font-size:12.5px}
.mc-break dd{margin:0;font-variant-numeric:tabular-nums;color:var(--ink);font-weight:600}
.mc-in{display:grid;grid-template-columns:1fr 1fr;gap:12px 12px;margin-top:18px}
.mc-wide,.mc-term,.mc-in > .mc-f:nth-last-child(-n+4){grid-column:1 / -1}
.mc-f{display:flex;flex-direction:column;gap:5px;min-width:0;margin:0}
.mc-f > span,.mc-term legend{font-size:13.5px;font-weight:600;color:var(--ink-2)}
.mc-f input[type=text]{width:100%;min-height:44px;padding:10px 12px;border:1px solid var(--line);border-radius:10px;
        background:var(--paper);font:inherit;font-size:16px;font-variant-numeric:tabular-nums;color:var(--ink);scroll-margin-top:140px}
.mc-f input[type=text]:focus{border-color:var(--rose-deep);outline:2px solid var(--rose-soft);outline-offset:0}
.mc-f small{font-size:12.5px;color:var(--slate);line-height:1.4}
.mc-term{border:0;padding:0;display:flex;flex-direction:row;flex-wrap:wrap;gap:8px}
.mc-term legend{padding:0;margin-bottom:5px;width:100%}
.mc-term label{flex:1;position:relative}
.mc-term input{position:absolute;opacity:0;inset:0;margin:0;width:100%;height:100%;cursor:pointer}
.mc-term label span{display:flex;align-items:center;justify-content:center;min-height:44px;border:1px solid var(--line);border-radius:99px;
        font-size:14.5px;font-weight:600;color:var(--ink-2);background:var(--paper)}
.mc-term input:checked + span{background:var(--rose-deep);border-color:var(--rose-deep);color:#fff}
.mc-term input:focus-visible + span{outline:2px solid var(--rose-deep);outline-offset:2px}
.mc-src p{margin:0;font-size:13px;color:var(--slate);line-height:1.5}
.mc-src a{display:inline-flex;align-items:center;min-height:44px;margin:-12px 0}
.mc-legal{margin:16px 0 0;font-size:12.5px;color:var(--slate);line-height:1.5}
@media(min-width:700px){
  .mcalc{padding:24px}
  .mc-sum{margin:0 -24px;padding:12px 24px}
  .mc-in > .mc-f:nth-last-child(-n+4){grid-column:auto}
}

/* ── member area (member-area-refresh, 2026-10-12) ─────────────────────────
   Every account, portal and email-landing page: the pill button, the
   portrait drop zone on /account, the jump row, the empty state. Scoped to
   .member (the /account wrapper) and .acct-sec (the section every member page
   is built from), so the rest of the site keeps its own .btn.

   THE PILL. One component, three weights. The tokens below are the contract
   the member emails copy (Maren): change them here and in the mail builder.
     primary   solid ink #1E2E44, white label; at most one per page
     ghost     transparent, 1px hairline #E9DFC8, ink label
     text      no border, ink label, cream wash on press/hover
   44px minimum height at every size (48px for .lg), fully round, Inter 500,
   sentence case, no gradient, no shadow. Press: scale .98 and a deeper fill.
   Focus: 2px rose-deep ring, 2px off. Rose is only ever that ring. */
:root{
  --pill-h:44px;--pill-h-lg:48px;--pill-r:999px;
  --pill-px:22px;--pill-px-sm:18px;--pill-px-lg:28px;
  --pill-fs:15px;--pill-fs-sm:14px;--pill-fs-lg:15.5px;--pill-fw:500;
  --pill-ink:#1E2E44;--pill-ink-hover:#2A3D58;--pill-ink-press:#142033;--pill-on-ink:#FFFFFF;
  --pill-line:#E9DFC8;--pill-line-hover:#D1C1A6;--pill-wash:#FFF3D9;--pill-wash-press:#F8EACB;
  --pill-text:#1E2E44;--pill-focus:#2A5F96;--pill-danger:#8A1428;--pill-danger-line:#E9B9BE;--pill-danger-wash:#F8E8E8;
  --pill-ease:160ms cubic-bezier(.2,.7,.3,1);
}
.member .btn,.acct-sec .btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;
  min-height:var(--pill-h);padding:0 var(--pill-px);border-radius:var(--pill-r);
  border:1px solid transparent;background:transparent;color:var(--pill-text);box-shadow:none;
  font:var(--pill-fw) var(--pill-fs)/1.2 'Inter',system-ui,sans-serif;letter-spacing:-.003em;text-transform:none;
  text-decoration:none;white-space:nowrap;cursor:pointer;vertical-align:middle;
  transition:background-color var(--pill-ease),border-color var(--pill-ease),color var(--pill-ease),transform var(--pill-ease);
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.member .btn:focus-visible,.acct-sec .btn:focus-visible{outline:2px solid var(--pill-focus);outline-offset:2px}
.member .btn:active,.acct-sec .btn:active{transform:scale(.98)}
.member .btn.sm,.acct-sec .btn.sm{padding:0 var(--pill-px-sm);font-size:var(--pill-fs-sm)}
.member .btn.lg,.acct-sec .btn.lg{min-height:var(--pill-h-lg);padding:0 var(--pill-px-lg);font-size:var(--pill-fs-lg)}
.member .btn.primary,.acct-sec .btn.primary{background:var(--pill-ink);border-color:var(--pill-ink);color:var(--pill-on-ink);box-shadow:none}
.member .btn.primary:active,.acct-sec .btn.primary:active{background:var(--pill-ink-press);border-color:var(--pill-ink-press)}
.member .btn.ghost,.acct-sec .btn.ghost{background:transparent;border-color:var(--pill-line);color:var(--pill-text)}
.member .btn.ghost:active,.acct-sec .btn.ghost:active,
.member .btn.text:active,.acct-sec .btn.text:active{background:var(--pill-wash-press)}
.member .btn.text,.acct-sec .btn.text{padding:0 14px;border-color:transparent}
.member .btn.danger,.acct-sec .btn.danger{color:var(--pill-danger)}
.member .btn.ghost.danger,.acct-sec .btn.ghost.danger{border-color:var(--pill-danger-line)}
.member .btn[disabled],.acct-sec .btn[disabled]{opacity:.45;cursor:default;transform:none}
@media(hover:hover){
  .member .btn.primary:hover,.acct-sec .btn.primary:hover{background:var(--pill-ink-hover);border-color:var(--pill-ink-hover);transform:none;box-shadow:none}
  .member .btn.ghost:hover,.acct-sec .btn.ghost:hover{background:var(--pill-wash);border-color:var(--pill-line-hover);color:var(--pill-text)}
  .member .btn.text:hover,.acct-sec .btn.text:hover{background:var(--pill-wash);color:var(--pill-text)}
  .member .btn.danger:hover,.acct-sec .btn.danger:hover{background:var(--pill-danger-wash);color:var(--pill-danger)}
  .member .btn.ghost.danger:hover,.acct-sec .btn.ghost.danger:hover{border-color:var(--pill-danger)}
}
@media(prefers-reduced-motion:reduce){.member .btn,.acct-sec .btn{transition:none}.member .btn:active,.acct-sec .btn:active{transform:none}}
.member .mcount,.acct-sec .mcount{display:inline-flex;align-items:center;justify-content:center;min-width:22px;height:22px;padding:0 7px;border-radius:99px;
  background:var(--cream);color:var(--slate);font:600 12px/1 'Inter',sans-serif;letter-spacing:0;vertical-align:middle;margin:0}
.acct-row h2 .mcount{margin-left:8px;position:relative;top:-2px}
/* a hidden pill stays hidden (the pill's display:inline-flex would otherwise win over [hidden]) */
.member .btn[hidden],.acct-sec .btn[hidden]{display:none}
.intake.acct .btn+.btn{margin-left:8px}
.acct-phead h1 em{color:var(--rose)}

/* the header on /account: portrait, greeting, jump row */
.mhead{padding:clamp(26px,5vw,60px) 0 0}
.mhead .wrap{display:grid;grid-template-columns:minmax(0,1fr);grid-template-areas:"av" "txt" "tabs";gap:18px 32px;align-items:center}
.mhead .avz{grid-area:av}
.mhead-text{grid-area:txt;min-width:0}
.mhead h1{font-size:clamp(30px,5.4vw,54px);line-height:1.06;margin-top:8px}
.mhead h1 em{font-style:italic;color:var(--rose)}
/* the jump row wraps instead of scrolling (Wren, 2026-10-12); every pill stays
   whole and 44px tall, Sign out rides the right end of the last line */
.mbar{grid-area:tabs;min-width:0;padding:0 0 16px;border-bottom:1px solid var(--line)}
.mtabs{display:flex;flex-wrap:wrap;gap:8px;align-items:center;min-width:0}
.mtabs .btn{flex:0 0 auto;background:#fff}
.mtabs-out{flex:0 0 auto;margin:0 0 0 auto!important}
.mtabs-out .btn{background:transparent}
@media(min-width:760px){
  .mhead .wrap{grid-template-columns:auto minmax(0,1fr);grid-template-areas:"av txt" "tabs tabs";row-gap:30px}
  .mbar{padding:0 0 22px}
}
/* the drop zone: the whole circle is the target (96px on a phone, 132 on a desk) */
.avz{display:flex;align-items:center;gap:18px;position:relative;margin:0}
.avz-input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;opacity:0}
.avz-drop{--avz:96px;position:relative;flex:0 0 auto;display:block;width:var(--avz);height:var(--avz);border-radius:50%;cursor:pointer;
  -webkit-tap-highlight-color:transparent;transition:transform var(--pill-ease)}
.avz-face{display:flex;align-items:center;justify-content:center;width:100%;height:100%;border-radius:50%;overflow:hidden;background:var(--blush);
  box-shadow:0 0 0 1px var(--line)}
.avz-face img{width:100%;height:100%;object-fit:cover;display:block}
.avz-initial{font-family:'Fraunces',serif;font-size:calc(var(--avz) * .42);line-height:1;color:var(--rose-deep)}
.avz-badge{position:absolute;right:0;bottom:0;width:32px;height:32px;border-radius:50%;background:var(--ink);color:#fff;display:flex;align-items:center;justify-content:center;
  box-shadow:0 0 0 3px var(--paper)}
.avz-badge svg{fill:none;stroke:currentColor;stroke-width:1.8;stroke-linejoin:round}
.avz-drop:active{transform:scale(.97)}
.avz-input:focus-visible+.avz-drop{outline:2px solid var(--pill-focus);outline-offset:4px}
.avz.is-over .avz-drop{transform:scale(1.04)}
.avz.is-over .avz-face{box-shadow:0 0 0 2px var(--rose-deep);background:#fff}
.avz-spin{position:absolute;inset:0;border-radius:50%;display:none;background:rgba(255,251,242,.55)}
.avz-spin::after{content:"";position:absolute;inset:-4px;border-radius:50%;border:2px solid transparent;border-top-color:var(--ink);animation:avz-turn .8s linear infinite}
.avz.is-busy .avz-spin{display:block}
@keyframes avz-turn{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion:reduce){.avz-spin::after{animation-duration:2.4s}.avz-drop{transition:none}}
.avz-side{min-width:0;flex:1 1 auto}
.avz-hint{font-size:13.5px;line-height:1.5;color:var(--slate);margin:0 0 8px;max-width:340px}
.avz-fine{display:none}
@media(hover:hover) and (pointer:fine){.avz-fine{display:inline}.avz-touch{display:none}}
.avz-acts{display:flex;flex-wrap:wrap;gap:6px 8px;align-items:center}
.avz-acts .btn{background:#fff}
.avz-acts .btn.text{background:transparent}
.avz.js .avz-send{display:none}
.avz-msg{font-size:13.5px;line-height:1.4;color:var(--ink);margin:6px 0 0;min-height:19px}
.avz-msg:empty{display:none}
.avz-msg.bad{color:#8A1428} /* ello: error stays red */
@media(min-width:760px){
  .avz{flex-direction:column;align-items:flex-start;gap:12px;width:250px}
  .avz-drop{--avz:132px}
  .avz-badge{width:38px;height:38px;right:4px;bottom:4px}
}
/* the nav circle carries the portrait when there is one */
.acct-dot.has-photo{background:var(--blush);overflow:hidden;box-shadow:0 0 0 2px #fff,0 0 0 3px var(--rose-soft)}
.acct-dot.has-photo img{width:100%;height:100%;object-fit:cover;border-radius:50%}
.acct-edge:hover .acct-dot.has-photo{background:var(--blush)}

/* sections on /account */
.member .acct-sec{scroll-margin-top:calc(84px + var(--broke-h))}
.member .acct-row h2{font-size:clamp(24px,3.4vw,30px)}
.mempty{display:flex;gap:16px;align-items:flex-start;background:#fff;border:1px solid var(--line);border-radius:var(--r-lg);padding:22px 20px;max-width:640px}
.mempty-ico{flex:0 0 auto;width:44px;height:44px;border-radius:50%;background:var(--blush);color:var(--rose-deep);display:flex;align-items:center;justify-content:center}
.mempty-ico svg{fill:none;stroke:currentColor;stroke-width:1.9;stroke-linejoin:round}
.mempty-t{font-family:'Fraunces',serif;font-size:20px;line-height:1.3;margin:0}
.mempty-s{color:var(--slate);font-size:15px;margin:4px 0 14px}
.mempty-acts{display:flex;flex-wrap:wrap;gap:8px}

/* ── the filter bar's controls, shared ───────────────────────
   The /homes bar and the saved-search form on /account draw the same
   controls from _homes-facets.php inside a .hfbar box. Scoped to .hfbar so
   they outrank the .intake form rules on /account; on /homes these are the
   look the bar always had. */
.hfbar select{padding:13px 44px 13px 18px;border:1px solid var(--line);border-radius:99px;font:inherit;font-size:14px;color:var(--ink);cursor:pointer;
  background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' fill='none' stroke='%234A5A72' stroke-width='1.8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E") no-repeat right 18px center;
  -webkit-appearance:none;appearance:none}
.hfbar select:focus{outline:2px solid var(--rose-deep);outline-offset:1px;background-color:#fff}
.hfbar .hf-pills{display:flex;gap:6px;flex-wrap:wrap}
.hfbar .hf-pill{display:inline-flex;align-items:center;min-height:44px;margin:0;padding:0 16px;border:1px solid var(--line);border-radius:99px;background:#fff;
  font-size:14px;font-weight:400;letter-spacing:0;color:var(--slate);cursor:pointer}
.hfbar .hf-pill input{position:absolute;opacity:0;width:0;height:0;padding:0;border:0}
.hfbar .hf-pill.on,.hfbar .hf-pill:has(input:checked){border-color:var(--rose-deep);color:var(--rose-deep);background:var(--blush);font-weight:600}
.hfbar .hf-pill:focus-within{outline:2px solid var(--rose-deep);outline-offset:2px}
.hfbar .hf-sw{display:inline-flex;align-items:center;gap:10px;min-height:44px;margin:0;font-size:15px;font-weight:400;letter-spacing:0;color:var(--ink);cursor:pointer}
.hfbar .hf-sw input{position:absolute;opacity:0;width:0;height:0;padding:0;border:0}
.hf-sw-t{width:44px;height:26px;border-radius:99px;background:var(--line);position:relative;flex:none;transition:background .2s}
.hf-sw-t::after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:50%;background:#fff;transition:transform .2s}
.hf-sw input:checked + .hf-sw-t{background:var(--rose-deep)}
.hf-sw input:checked + .hf-sw-t::after{transform:translateX(18px)}
.hf-sw input:focus-visible + .hf-sw-t{outline:2px solid var(--rose-deep);outline-offset:2px}
@media(prefers-reduced-motion:reduce){.hf-sw-t,.hf-sw-t::after{transition:none}}
