/* ============================================================================
   Iteration 35 — "Blue Hour" (v2, monochrome)
   The 30-essence black-&-white system, untouched, plus three additions:
     1) HOME HERO — the Hyperframe crossfade reel cycles the three generated
        blue-hour SF frames (bvlaw-hero-assets); colour comes from photography
        only, per the mono system.
     2) TESTIMONIALS — bvlawsf.com's quote-card carousel translated to sleek
        white/black: quote mark + star row + pull-quote + attribution.
     3) FOR LEASE / LEASED — stronger listing presentation: a full-width lead
        card, hairline editorial frames, a stat-styled count, loading shimmer,
        and a warmer empty state.
   No palette/typography changes — CompassSerif/Sans + ink/white/grey stand.
   ========================================================================== */

/* ============================================================================
   0) MONO CORRECTIONS — baseline warts surfaced by the walkthrough
   (The green call button stays green — Matthew's call, 2026-07-02.)
   ========================================================================== */
/* The intake form's submit was `.btn--light` on the white form card —
   a white button on a white surface. Filled ink = visible, on-system. */
form .btn--light, .form-card [type="submit"] {
  background: var(--ink); border-color: var(--ink); color: #fff;
}
form .btn--light:hover, .form-card [type="submit"]:hover {
  background: #000; border-color: #000; color: #fff;
}

/* ============================================================================
   1) TESTIMONIALS — a looping two-row ticker of real Yelp/Zillow/Google
   reviews. Each row's track holds the card group twice; translateX(-50%)
   loops seamlessly. Hover pauses. Reduced motion -> static wrapped rows.
   ========================================================================== */
.rticker {
  overflow: hidden;
  margin-top: var(--s-6);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 6%, #000 94%, transparent 100%);
}
.rticker + .rticker { margin-top: var(--s-5); }
.rticker__track {
  display: flex; width: max-content;
  animation: rticker-scroll 90s linear infinite;
}
.rticker--rev .rticker__track { animation-direction: reverse; }
.rticker:hover .rticker__track { animation-play-state: paused; }
.rticker__group {
  list-style: none; margin: 0; padding: 0 0 0 var(--s-5);
  display: flex; align-items: stretch; gap: var(--s-5);
  padding-right: var(--s-5);
}
@keyframes rticker-scroll { to { transform: translateX(-50%); } }

.tcard {
  position: relative;
  margin: 0;
  width: min(420px, 82vw);
  flex: none;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s-6) var(--s-5) var(--s-5);
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}
.tcard__stars { font-size: 0.95rem; letter-spacing: 4px; color: var(--ink); line-height: 1; }
.tcard__quote {
  margin: 0;
  font-family: var(--ff-header);
  font-size: 1.06rem;
  line-height: 1.42;
  color: var(--ink);
}
.tcard__quote::before { content: "\201C"; }
.tcard__quote::after  { content: "\201D"; }
.tcard__name {
  margin-top: auto;
  display: inline-flex; align-items: center; gap: 9px;
  padding-top: var(--s-3);
  font-size: 0.7rem; font-weight: 600;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted);
}
.tcard__brand { width: 17px; height: 17px; flex: none; display: inline-block; }

/* Clickable cards — reviews.js turns each snippet into a link to that person's
   full, real review (Yelp permalink / Google contributor page / Zillow profile).
   Stretched-link overlay keeps the figure/blockquote markup intact; a corner
   arrow appears on hover/focus. The row already pauses on hover, so the target
   holds still to be clicked. */
.tcard--link { cursor: pointer; transition: border-color .25s var(--ease), transform .25s var(--ease), box-shadow .25s var(--ease); }
.tcard--link:hover,
.tcard--link:focus-within {
  border-color: var(--ink);
  transform: translateY(-3px);
  box-shadow: 0 20px 34px -28px rgba(0, 0, 0, .40);
}
.tcard__perma {
  position: absolute; inset: 0; z-index: 4;
  border-radius: inherit;
  font-size: 0; color: transparent;          /* label lives in aria-label */
}
.tcard__perma:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; }
.tcard__go {
  position: absolute; top: 12px; right: 12px; z-index: 2;
  width: 20px; height: 20px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--muted);
  opacity: 0; transform: translateY(-2px);
  transition: opacity .25s var(--ease), transform .25s var(--ease), color .25s var(--ease);
  pointer-events: none;
}
.tcard__go svg { width: 16px; height: 16px; }
.tcard--link:hover .tcard__go,
.tcard--link:focus-within .tcard__go { opacity: 1; transform: none; color: var(--ink); }

.tlinks { margin-top: var(--s-7); text-align: center; font-size: 0.95rem; color: var(--muted); }
.tlinks .link { white-space: nowrap; }
.tlinks__sep { margin: 0 var(--s-3); color: var(--line-2); }

@media (prefers-reduced-motion: reduce) {
  /* static rows stay one line each and scroll horizontally — with 50 cards per
     row a wrapped grid would tower thousands of pixels tall */
  .rticker { mask-image: none; -webkit-mask-image: none; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .rticker__track { animation: none; }
  .rticker__group[aria-hidden="true"] { display: none; }
  .tcard--link { transition: none; }
  .tcard--link:hover, .tcard--link:focus-within { transform: none; }
}

/* ============================================================================
   2) FOR LEASE / LEASED — listing-page upgrades (scoped to #listings-app)
   ========================================================================== */

/* Toolbar: the count reads as a stat, the cross-link as a quiet pill */
#listings-app .listings-toolbar {
  align-items: baseline;
  border-bottom: 1px solid var(--line);
  padding-bottom: var(--s-5);
  margin-bottom: var(--s-8);
}
#listings-app .listings-count {
  font-family: var(--ff-header);
  font-size: clamp(1.4rem, 1.1rem + 1.2vw, 2rem);
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--ink);
}
#listings-app .listings-toolbar .textlink { font-size: 0.82rem; letter-spacing: .1em; text-transform: uppercase; }

/* Editorial card frame: hairline at rest, ink + lift on intent */
#listings-app .listing {
  border: 1px solid var(--line);
  box-shadow: none;
  transition: transform .3s var(--ease), border-color .3s var(--ease), box-shadow .3s var(--ease);
}
#listings-app .listing:hover {
  border-color: var(--ink);
  transform: translateY(-4px);
  box-shadow: 0 28px 44px -30px rgba(0,0,0,.4);
}
#listings-app .listing__price { font-size: 1.65rem; }

/* Lead listing: the first available home gets the full row, split media/body */
@media (min-width: 901px) {
  #listings-app[data-state="lease"] .listing:first-child {
    grid-column: 1 / -1;
    flex-direction: row;
  }
  #listings-app[data-state="lease"] .listing:first-child .listing__media {
    flex: 1.35;
    aspect-ratio: auto;
    min-height: 380px;
  }
  #listings-app[data-state="lease"] .listing:first-child .listing__body {
    flex: 1;
    justify-content: center;
    padding: var(--s-7);
  }
  #listings-app[data-state="lease"] .listing:first-child .listing__title { font-size: 1.9rem; }
  #listings-app[data-state="lease"] .listing:first-child .listing__price { font-size: 2.1rem; }
}

/* Leased page: achieved rents in an inverted frame so the state reads instantly */
#listings-app[data-state="leased"] .listing__tag { background: var(--ink); color: #fff; }
#listings-app[data-state="leased"] .listing__price small { color: var(--accent); font-weight: 700; }

/* Loading shimmer while the live feed resolves (aria-busy toggled by listings.js) */
#listings-app .listings-grid[aria-busy="true"] { min-height: 320px; position: relative; }
#listings-app .listings-grid[aria-busy="true"]::before {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(100deg, var(--bg-alt) 40%, #fff 50%, var(--bg-alt) 60%);
  background-size: 200% 100%;
  animation: listingShimmer 1.4s linear infinite;
}
@keyframes listingShimmer { from { background-position: 120% 0; } to { background-position: -80% 0; } }
@media (prefers-reduced-motion: reduce) {
  #listings-app .listings-grid[aria-busy="true"]::before { animation: none; }
  #listings-app .listing { transition: none; }
  #listings-app .listing:hover { transform: none; }
}

/* Empty / error state gets real presence instead of a whisper */
#listings-app .listings-status {
  font-family: var(--ff-header);
  font-size: 1.25rem;
  color: var(--ink-soft);
  border: 1px dashed var(--line-2);
  padding: var(--s-8) var(--s-6);
}

/* ---------------------------------------------------------------------------
   FOLLOW — "aura" social buttons.
   A native-CSS take on the "aurora button": each card keeps the site's clean
   white fill + ink text, but gains a brand-coloured gradient border ring and a
   blurred brand-coloured glow that blooms on hover — Instagram's gradient,
   YouTube red, LinkedIn blue. Per-platform colour lives in custom props so the
   shared rules stay DRY: --aura (the gradient ring) and --glow-rest /
   --glow-hover (the halo). Brand colour here is the owner-sanctioned exception
   to the black-&-white system, same licence as the coloured social icons.
   No z-index/stacking tricks: the ring is a padding-box/border-box gradient and
   the halo is a layered box-shadow, both immune to the hover transform's
   stacking context.
   ------------------------------------------------------------------------- */
.follow__btn {
  border: 2px solid transparent;
  /* white centre (padding-box) framed by the brand gradient (border-box) */
  background:
    linear-gradient(#fff, #fff) padding-box,
    var(--aura, linear-gradient(135deg, var(--line-2), var(--line-2))) border-box;
  box-shadow: var(--glow-rest, 0 10px 30px -22px rgba(2, 6, 23, .45));
  transition: transform .28s var(--ease), box-shadow .32s var(--ease);
}
.follow__btn:hover,
.follow__btn:focus-visible {
  border-color: transparent;          /* keep the gradient ring, not the iter-30 ink border */
  transform: translateY(-4px);
  box-shadow: var(--glow-hover, 0 24px 44px -26px rgba(2, 6, 23, .5));
}

/* Instagram — the full IG spectrum */
.follow__btn--ig {
  --aura: linear-gradient(135deg, #FEDA75 0%, #FA7E1E 26%, #D62976 58%, #962FBF 80%, #4F5BD5 100%);
  --glow-rest:  0 8px 24px -12px rgba(214, 41, 118, .40), 0 10px 30px -14px rgba(150, 47, 191, .34), 0 8px 26px -16px rgba(250, 126, 30, .30);
  --glow-hover: 0 14px 36px -8px rgba(214, 41, 118, .58), 0 18px 46px -12px rgba(150, 47, 191, .48), 0 14px 38px -12px rgba(250, 126, 30, .40);
}
/* YouTube — red */
.follow__btn--yt {
  --aura: linear-gradient(135deg, #FF6A5F 0%, #FF0000 55%, #C4160F 100%);
  --glow-rest:  0 8px 26px -13px rgba(255, 0, 0, .42);
  --glow-hover: 0 15px 40px -10px rgba(255, 0, 0, .62);
}
/* LinkedIn — blue */
.follow__btn--li {
  --aura: linear-gradient(135deg, #4CC3FF 0%, #0A66C2 58%, #004182 100%);
  --glow-rest:  0 8px 26px -13px rgba(10, 102, 194, .42);
  --glow-hover: 0 15px 40px -10px rgba(10, 102, 194, .62);
}

/* Icons: crisp, self-contained brand marks — a hair of rounding + soft seat so
   they read as clean tiles on the white card. */
.follow__icon svg { border-radius: 7px; box-shadow: 0 2px 8px -4px rgba(2, 6, 23, .30); }
.follow__btn--ig .follow__icon svg { border-radius: 9px; }

@media (prefers-reduced-motion: reduce) {
  .follow__btn { transition: none; }
  .follow__btn:hover,
  .follow__btn:focus-visible { transform: none; }
}

/* ---------------------------------------------------------------------------
   AFFILIATIONS & PRESS — "In good company" flip-card wall.
   Two groups (verified affiliations; verified press features); every tile is
   a 3D flip card: front = the brand mark, back = the relationship or story.
   affiliations.js flips one card at a time in a slow wave — ticker energy
   with zero scrolling — and hover / keyboard focus flips any card directly.
   The 3D layout exists ONLY under .affil--flip, which the JS adds after its
   reduced-motion check: no-JS and reduced-motion users get static cards with
   mark + detail both visible. Logos are flattened to ink (grayscale; the WCR
   art ships white-on-transparent → inverted) to hold the B&W system.
   ------------------------------------------------------------------------- */
/* 2026-07-17 feedback: the "Featured in" strip now opens the press section
   (the standalone "In good company" section is gone) — trim its band margins
   there so it sits between the press intro and the article list. */
.press .affil__label { margin-top: 0; }
.press .affil__grid--press { margin-bottom: clamp(var(--s-6), 5vw, var(--s-8)); }

.affil__label {
  margin: var(--s-8) 0 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-4);
  font-family: var(--ff-normal);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--muted);
}
.affil__label::before,
.affil__label::after {
  content: "";
  height: 1px;
  width: 72px;
  background: var(--line-2);
}
.affil__grid {
  list-style: none;
  margin: var(--s-5) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-4);
}
.affil__grid--press { grid-template-columns: repeat(4, 1fr); }
.affil__card { min-width: 0; }
.affil__body {
  display: block;
  height: 100%;
  color: var(--ink);
  cursor: pointer;
}

/* --- static base (no-JS / reduced-motion): one quiet card, all info shown --- */
.affil__flipper {
  display: block;
  height: 100%;
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
}
.affil__face {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  text-align: center;
}
.affil__face--front { padding: var(--s-6) var(--s-5) var(--s-2); }
.affil__face--back  { padding: 0 var(--s-5) var(--s-6); }
.affil__face--back b,
.affil__go { display: none; }                    /* shown only in flip mode */
.affil__face b {
  font-family: var(--ff-header);
  font-weight: 500;
  font-size: 1.05rem;
  line-height: 1.2;
}
.affil__face small {
  color: var(--muted);
  font-size: .85rem;
  line-height: 1.35;
}

/* Brand marks. NOTE: .affil__mark is width:100% so percentage sizes inside
   resolve — a %-max-width against the shrink-wrapped flex item collapsed
   dimensionless SVGs (no width/height attrs, e.g. the TRD art) to 0×0. */
.affil__mark {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 52px;
}
.affil__mark img {
  height: 42px;
  width: auto;
  max-width: 86%;
  object-fit: contain;
  display: block;
  filter: grayscale(1) contrast(1.05);
}
/* ultra-wide wordmarks (SF Standard is 320:23) — trade height for width */
.affil__mark .affil__img-wide {
  height: auto;
  width: 78%;
  max-width: 250px;
}
.affil__mark .affil__img-invert { filter: invert(1) grayscale(1) contrast(1.05); }
.affil__mark--pod svg { width: 30px; height: 30px; display: block; }

/* Typographic marks — orgs with no usable logo asset */
.affil__word {
  font-family: var(--ff-normal);
  font-weight: 500;
  font-size: 1.25rem;
  letter-spacing: .28em;
  padding-left: .28em;           /* optically recentre the tracked text */
  white-space: nowrap;
}
.affil__word em {
  font-style: normal;
  font-weight: 400;
  color: var(--ink-soft);
  margin-left: .35em;
}
.affil__word--compass { letter-spacing: .34em; }
.affil__word--serif {
  font-family: var(--ff-header);
  font-size: 1.75rem;
  letter-spacing: .06em;
  padding-left: .06em;
}
.affil__word--pod {
  font-size: .82rem;
  letter-spacing: .2em;
  padding-left: .2em;
}
/* DRE — quiet official-stamp monogram */
.affil__seal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border: 1.5px solid var(--ink);
  border-radius: 50%;
  font-family: var(--ff-normal);
  font-weight: 600;
  font-size: .82rem;
  letter-spacing: .14em;
  padding-left: .14em;
}

/* --- flip mode (JS adds .affil--flip to #affiliations) --- */
.affil--flip .affil__body { perspective: 1000px; }
.affil--flip .affil__flipper {
  position: relative;
  height: 158px;
  background: transparent;
  border: 0;
  transform-style: preserve-3d;
  transition: transform .75s cubic-bezier(.3, .7, .2, 1);
}
.affil--flip .affil__face {
  position: absolute;
  inset: 0;
  padding: var(--s-4) var(--s-5);
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: var(--radius);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  transition: border-color .4s var(--ease), box-shadow .4s var(--ease);
}
.affil--flip .affil__face--back { transform: rotateY(180deg); }
.affil--flip .affil__face--back b,
.affil--flip .affil__go { display: block; }
.affil--flip .affil__card.is-flipped .affil__flipper,
.affil--flip .affil__body:hover .affil__flipper,
.affil--flip .affil__body:focus-visible .affil__flipper { transform: rotateY(180deg); }
.affil--flip .affil__card.is-flipped .affil__face,
.affil--flip .affil__body:hover .affil__face,
.affil--flip .affil__body:focus-visible .affil__face {
  border-color: var(--ink);
  box-shadow: 0 24px 40px -30px rgba(0, 0, 0, .35);
}

.affil__go {
  margin-top: 2px;
  font-family: var(--ff-normal);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--ink);
}

@media (max-width: 900px) {
  .affil__grid,
  .affil__grid--press { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .affil__grid,
  .affil__grid--press { grid-template-columns: 1fr; }
  .affil--flip .affil__flipper { height: 150px; }
}
@media (prefers-reduced-motion: reduce) {
  .affil__flipper, .affil__face { transition: none; }
}

/* ===== Page-hero Hyperframe reel (for-lease / leased) =====================
   Live listing photos crossfade inside the parallaxed [data-hero-bg] div;
   the inline background-image underneath stays as the no-data/JS-off
   fallback. Cadence matches the homepage reel (5200 dwell + 1500 fade). */
.page-hero__layer {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity 2.6s linear;
  will-change: opacity, transform;
}
.page-hero__layer.is-active { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  /* Incoming frame arrives a touch zoomed and settles — constant, linear drift. */
  .page-hero__layer.is-kb { animation: page-hero-kb 8s linear both; }
}
@keyframes page-hero-kb { from { transform: scale(1.07); } to { transform: scale(1.01); } }
