/* Ravenor theme — small additions theme.json can't express:
   listing-status tags, blob motion, property card hover. Everything else
   (colour, type, spacing, radius, shadow) comes from theme.json globals. */

/* Sticky header. Targets the className set on the header template part's
   group (see parts/header.html), not a generic selector, so this can't
   accidentally catch some other group on the page. */
.rv-site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  border-bottom: 2px solid var(--wp--preset--color--gold);
}

/* WP core adds a block-gap margin between every top-level block under
   .wp-site-blocks (header, main, footer), which showed as a band of the
   page's own off-white background between the sticky header and the hero,
   the header has no background of its own there to cover it. The gold
   border above replaces it as a deliberate divider instead. */
.wp-site-blocks > main {
  margin-block-start: 0;
}

/* Nav dropdown submenu (e.g. Investors). Core's default submenu container
   is a white popup, but the header sets the nav's text colour to white for
   the top-level bar, so without this the submenu items render as invisible
   white-on-white text. Navy panel keeps it visually part of the header
   rather than a jarring white popup against a navy bar. */
.wp-block-navigation__submenu-container {
  background-color: var(--wp--preset--color--navy-mid) !important;
  border-radius: var(--wp--custom--radius--md);
  padding: 8px 0;
  box-shadow: var(--wp--custom--shadow--hover);
}
.wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  color: var(--wp--preset--color--white) !important;
  padding: 10px 8px 10px 20px;
}
.wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
  color: var(--wp--preset--color--gold) !important;
}

/* Mobile overlay only, scoped via .is-menu-open (JS only adds this when the
   overlay is actually open — never during a desktop hover-dropdown, unlike
   .wp-block-navigation__responsive-container-content, which wraps the menu
   in both cases since it's the same DOM node repositioned by CSS, not two
   separate markups). Everything below this point is mobile-overlay-only. */

/* The submenu-container box was only as wide as its own text needed,
   narrower than the top-level items' row, so right-aligned sub-item text
   landed short of the edge the rest of the menu aligns to. Stretching it
   to the full row width means the same right edge the dash sits against
   for a sub-item today lines up with "Contact"/"Lettings" etc. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container {
  /* !important: core's own rule for this exact state (.is-menu-open ...
     .has-child .wp-block-navigation__submenu-container) sets width:auto
     with higher specificity via a long selector chain, even though the
     :where(:not(...)) part of it doesn't count toward specificity, the
     remaining chain still out-specifies a 3-class selector like this one. */
  width: 100% !important;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  width: 100% !important;
}

/* Every link in the open mobile menu, top-level and nested, bigger text and
   a taller row so each one is a comfortable tap target, not just a line of
   text with no padding around it. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation-item__content {
  font-size: 1.25rem !important;
  padding-top: 16px !important;
  padding-bottom: 16px !important;
}

/* The dash next to each sub-item, e.g. "Investor Sales —", reads as "part of
   a set" per-item rather than one bar running down the whole submenu's
   side. Flex + align-items:center vertically centres it against the text's
   actual line box, a fixed vertical-align offset drifted depending on the
   item's font-size and line-height and kept sitting too high. */
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
.wp-block-navigation__responsive-container.is-menu-open .wp-block-navigation__submenu-container .wp-block-navigation-item__content::after {
  content: "";
  flex: 0 0 auto;
  width: 14px;
  height: 2px;
  margin-left: 10px;
  background-color: var(--wp--preset--color--gold);
}

/* "Investors" (and any future parent-only item) is a toggle, not a
   destination, it has no page of its own behind it. Dimming it and
   dropping the gold hover-highlight its sibling links get signals that
   before you click, not after. Applies in both the desktop bar and the
   mobile overlay, since it's the same markup in both. */
.wp-block-navigation-item.has-child > .wp-block-navigation-item__content {
  opacity: 0.65;
  cursor: default;
}
.wp-block-navigation-item.has-child > .wp-block-navigation-item__content:hover {
  color: inherit !important;
}

.rv-tag {
  display: inline-block;
  margin: 0;
  font-family: var(--wp--preset--font-family--body);
  font-size: var(--wp--preset--font-size--caption);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 6px 14px;
  border-radius: var(--wp--custom--radius--pill);
}
.rv-tag-available   { background: rgba(111, 129, 88, 0.14); color: #4C5A3D; }
.rv-tag-under-offer { background: rgba(219, 190, 100, 0.16); color: #8A6D1F; }
.rv-tag-let-sold    { background: rgba(11, 16, 48, 0.08); color: var(--wp--preset--color--navy); }

/* The query loop's grid already stretches each card's own grid cell to
   match the tallest card in its row (CSS Grid's default align-items:stretch),
   but the CARD itself never used that extra height, it just sized to fit
   its own content, cards with a longer address wrapping onto a second line
   ended up visibly taller than their row-mates. height:100% + flex lets the
   text block (the only part with variable-length content, the photo is a
   fixed aspect-ratio) grow to fill whatever height the grid cell gives it. */
.rv-property-card {
  height: 100%;
  display: flex;
  flex-direction: column;
  background: var(--wp--preset--color--white);
  border-radius: var(--wp--custom--radius--2xl);
  overflow: hidden;
  box-shadow: var(--wp--custom--shadow--sm);
  transition: box-shadow 0.3s ease, transform 0.3s ease;
}
.rv-property-card:hover {
  box-shadow: var(--wp--custom--shadow--hover);
  transform: translateY(-2px);
}
.rv-property-card .rv-property-photo {
  flex-shrink: 0;
}
.rv-property-card > .wp-block-group {
  flex: 1;
}
.rv-property-photo {
  aspect-ratio: 4 / 3;
  background: linear-gradient(135deg, #cfc9b8 0%, #e8e3d5 100%);
  position: relative;
  /* .rv-property-card became a flex column so the card's own height could
     be made consistent (see above). Side effect: as a flex item, this box
     gets an automatic content-based minimum height unless overflow is
     anything other than visible — a portrait-oriented source photo (taller
     than wide, e.g. one shot in portrait) was letting the box grow past
     its intended aspect-ratio height to fit that image's natural minimum
     size. overflow:hidden both fixes that and is the right guard anyway,
     the object-fit:cover'd image should never visually spill outside this
     box regardless of its source proportions. */
  overflow: hidden;
}
.rv-property-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.rv-property-tag-wrap { position: absolute; top: 12px; left: 12px; margin: 0; }

/* === PROPERTY PHOTO CAROUSEL + LIGHTBOX (single-property.html) ===
   Same 4:3 crop as .rv-property-photo above, a photo on the Lettings/Sales
   card and that same photo leading the carousel on its own listing page
   read as the same shape rather than two different crops of one source
   image. Markup is built server-side in functions.php
   (ravenor_property_carousel_html), interaction is property-gallery.js. */
.rv-property-carousel {
  position: relative;
  border-radius: var(--wp--custom--radius--xl);
  overflow: hidden;
  background: linear-gradient(135deg, #cfc9b8 0%, #e8e3d5 100%);
}
.rv-property-carousel-empty {
  aspect-ratio: 4 / 3;
}
.rv-carousel-track {
  display: flex;
  aspect-ratio: 4 / 3;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  /* Hide the native scrollbar, the prev/next buttons + counter are the
     intended way to navigate, a visible scrollbar under a 4:3 photo reads
     as a layout glitch rather than a control. */
  scrollbar-width: none;
}
.rv-carousel-track::-webkit-scrollbar { display: none; }
.rv-carousel-slide {
  flex: 0 0 100%;
  scroll-snap-align: start;
  cursor: zoom-in;
}
.rv-carousel-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.rv-carousel-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: none;
  background: rgba(11, 16, 48, 0.55);
  color: var(--wp--preset--color--white);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease;
}
.rv-carousel-arrow:hover { background: rgba(11, 16, 48, 0.8); }
.rv-carousel-prev { left: 16px; }
.rv-carousel-next { right: 16px; }
.rv-carousel-counter {
  position: absolute;
  bottom: 16px;
  right: 16px;
  background: rgba(11, 16, 48, 0.55);
  color: var(--wp--preset--color--white);
  font-family: var(--wp--preset--font-family--body);
  font-size: var(--wp--preset--font-size--caption);
  padding: 4px 12px;
  border-radius: var(--wp--custom--radius--pill);
}

.rv-lightbox {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 100001;
  background: rgba(6, 9, 38, 0.92);
  align-items: center;
  justify-content: center;
}
.rv-lightbox.is-open { display: flex; }
.rv-lightbox-stage {
  width: 90vw;
  height: 85vh;
  display: flex;
  align-items: center;
  justify-content: center;
}
.rv-lightbox-img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: var(--wp--custom--radius--md);
}
.rv-lightbox-close {
  position: absolute;
  top: 20px;
  right: 24px;
  background: transparent;
  border: none;
  color: var(--wp--preset--color--white);
  font-size: 2rem;
  line-height: 1;
  cursor: pointer;
}
.rv-lightbox-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.12);
  color: var(--wp--preset--color--white);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease;
}
.rv-lightbox-arrow:hover { background: rgba(255, 255, 255, 0.22); }
.rv-lightbox-prev { left: 24px; }
.rv-lightbox-next { right: 24px; }
.rv-lightbox-counter {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  color: var(--wp--preset--color--white);
  font-family: var(--wp--preset--font-family--body);
  font-size: var(--wp--preset--font-size--caption);
  opacity: 0.8;
}

/* === MOTION (ported from brand-guidelines/tokens/effects.css) === */
@keyframes rv-blob-1 {
  0%, 100% { transform: translate(0,0) scale(1); }
  33%       { transform: translate(8%,-6%) scale(1.15); }
  66%       { transform: translate(-6%,8%) scale(0.92); }
}
@keyframes rv-blob-2 {
  0%, 100% { transform: translate(0,0) scale(1); }
  33%       { transform: translate(-9%,7%) scale(0.9); }
  66%       { transform: translate(7%,-8%) scale(1.18); }
}
.rv-blob {
  position: absolute;
  border-radius: 9999px;
  filter: blur(80px);
  pointer-events: none;
  will-change: transform;
}
.rv-blob-1 { animation: rv-blob-1 22s ease-in-out infinite; }
.rv-blob-2 { animation: rv-blob-2 28s ease-in-out infinite; }

@media (prefers-reduced-motion: reduce) {
  .rv-blob-1, .rv-blob-2 { animation: none; }
}

/* === PHOTO COLLAGE (hero) ===
   Real photography (theme/assets/photos/), a bottom scrim gradient is
   layered over every tile so the location caption stays readable regardless
   of how bright or busy the photo underneath is. Shape, overlap, shadow and
   float motion are unchanged from the placeholder version, swapping the
   background-image is the only thing that changed.
*/
.rv-photo-collage {
  position: relative;
  width: 100%;
  aspect-ratio: 1 / 0.95;
  min-height: 340px;
}
/* Below 782px (WP core's own columns-stacking breakpoint) the hero's two
   columns stack, putting the collage directly under the CTA buttons with
   nothing but the row's own blockGap between them, not enough room to
   read as a separate element rather than something crowding the buttons.
   !important: some other rule (never fully identified — matched selector,
   matched media condition, equal specificity, still lost the cascade)
   was overriding a plain, unqualified version of this same rule, forcing
   margin-top back to 0. */
@media (max-width: 781px) {
  .rv-photo-collage {
    margin-top: var(--wp--preset--spacing--12) !important;
  }
}
.rv-photo-tile {
  position: absolute;
  border-radius: 1.5rem;
  box-shadow: var(--wp--custom--shadow--hover);
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  padding: var(--wp--preset--spacing--4);
  background-size: cover;
  background-position: center;
  animation-name: rv-photo-float;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}
.rv-photo-tile-label {
  font-family: var(--wp--preset--font-family--body);
  font-size: var(--wp--preset--font-size--label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.92);
  text-shadow: 0 1px 4px rgba(0, 0, 0, 0.35);
}
@keyframes rv-photo-float {
  0%, 100%  { transform: translateY(0) rotate(var(--rot, 0deg)); }
  50%       { transform: translateY(-12px) rotate(var(--rot, 0deg)); }
}
@media (prefers-reduced-motion: reduce) {
  .rv-photo-tile { animation: none; }
}

.rv-photo-tile-1 {
  width: 58%; height: 62%;
  top: 0; left: 4%;
  /* Its bottom edge is overlapped by tiles 2 and 4, a bottom-anchored
     label would sit hidden underneath them, so this one tile anchors its
     label to the top instead, the only part of it that's never covered. */
  align-items: flex-start;
  background-image: linear-gradient(to bottom, rgba(11, 16, 48, 0.55) 0%, rgba(11, 16, 48, 0.05) 40%), url('photos/london-riverside-living-room.jpg');
  --rot: -4deg;
  z-index: 2;
  animation-duration: 11s;
}
.rv-photo-tile-2 {
  width: 46%; height: 48%;
  bottom: 0; right: 0;
  background-image: linear-gradient(to top, rgba(11, 16, 48, 0.65) 0%, rgba(11, 16, 48, 0.05) 45%), url('photos/chelsea-mansion-block.jpg');
  --rot: 5deg;
  z-index: 3;
  animation-duration: 13s;
  animation-delay: -4s;
}
.rv-photo-tile-3 {
  width: 38%; height: 36%;
  top: 6%; right: 8%;
  background-image: linear-gradient(to top, rgba(11, 16, 48, 0.65) 0%, rgba(11, 16, 48, 0.05) 45%), url('photos/manchester-apartments.jpg');
  --rot: 3deg;
  z-index: 1;
  animation-duration: 9s;
  animation-delay: -6s;
}
.rv-photo-tile-4 {
  width: 32%; height: 30%;
  bottom: 16%; left: 0;
  background-image: linear-gradient(to top, rgba(11, 16, 48, 0.65) 0%, rgba(11, 16, 48, 0.05) 45%), url('photos/bristol-cottage-door.jpg');
  --rot: -6deg;
  z-index: 2;
  animation-duration: 12s;
  animation-delay: -2s;
}

/* === BUTTONS ===
   One system, used everywhere instead of mixing the core button block
   (em-based padding from theme.json) with hand-styled links (px-based
   padding). Mixing the two was exactly why buttons sitting next to each
   other were different heights, this is the fix: every button on the site
   is one of these four classes, nothing else. All four share the same
   box-sizing, padding and border-width (transparent where there's no
   visible border) so they're pixel-identical in height and only differ in
   colour.
*/
.rv-btn {
  box-sizing: border-box;
  display: inline-block;
  font-family: var(--wp--preset--font-family--body);
  font-weight: 600;
  font-size: var(--wp--preset--font-size--body);
  line-height: 1.2;
  padding: 14px 28px;
  border-width: 2px;
  border-style: solid;
  border-radius: var(--wp--custom--radius--xl);
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
/* Three stops, not two, a flat two-stop khaki-to-gold gradient reads flat
   and a little muddy. The lighter middle stop gives it a soft metallic
   sheen instead. Shadow is deliberately soft and gold-tinted (large blur,
   low opacity), not the hard dark offset a default box-shadow gives you,
   that's what reads as dated rather than a bit of lift reading as premium.
*/
.rv-btn-primary {
  background: linear-gradient(135deg, #F1E3AE 0%, #DBBE64 45%, #C9A94A 100%);
  border-color: transparent;
  color: var(--wp--preset--color--navy) !important;
  box-shadow: 0 6px 20px -8px rgba(219, 190, 100, 0.55);
}
.rv-btn-primary:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 28px -8px rgba(219, 190, 100, 0.65);
  filter: brightness(1.03);
}
.rv-btn-primary:active {
  transform: translateY(0);
  box-shadow: 0 4px 14px -8px rgba(219, 190, 100, 0.5);
}

/* Fluent Forms submit buttons (.ff-btn-submit): the plugin's own gold
   background/text colour is set per-form in Send message/Register interest
   forms, matches the brand, but its shape (padding, radius, flat fill,
   no shadow) doesn't match .rv-btn-primary elsewhere on the site.
   !important because Fluent Forms injects its own <style> block with the
   colour rule, this needs to win regardless of where that lands in the
   cascade. */
.ff-btn-submit {
  background: linear-gradient(135deg, #F1E3AE 0%, #DBBE64 45%, #C9A94A 100%) !important;
  color: var(--wp--preset--color--navy) !important;
  border: none !important;
  border-radius: var(--wp--custom--radius--xl) !important;
  padding: 14px 28px !important;
  font-weight: 600 !important;
  box-shadow: 0 6px 20px -8px rgba(219, 190, 100, 0.55);
  transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
}
.ff-btn-submit:hover {
  transform: translateY(-1px);
  box-shadow: 0 10px 28px -8px rgba(219, 190, 100, 0.65);
  filter: brightness(1.03);
}

.rv-btn-ghost {
  background: transparent;
  border-color: rgba(219, 190, 100, 0.45);
  color: var(--wp--preset--color--white) !important;
}
.rv-btn-ghost:hover {
  border-color: rgba(219, 190, 100, 0.85);
  background: rgba(219, 190, 100, 0.08);
}
.rv-btn-navy {
  background: var(--wp--preset--color--navy);
  border-color: transparent;
  color: var(--wp--preset--color--white) !important;
}
.rv-btn-navy:hover {
  background: var(--wp--preset--color--navy-mid);
}
.rv-btn-outline {
  background: transparent;
  border-color: var(--wp--preset--color--navy);
  color: var(--wp--preset--color--navy) !important;
}
.rv-btn-outline:hover {
  background: var(--wp--preset--color--navy);
  color: var(--wp--preset--color--white) !important;
}

/* === AUDIENCE CARDS (homepage) ===
   Cards in the same row need matching heights regardless of how much their
   body copy wraps, and their CTA link needs to land on the same baseline
   across the row rather than tucking right under whatever length of text
   that card happens to have. flex column + margin-top:auto on the CTA does
   both: the group already stretches to the row's tallest sibling (WP core
   columns default to stretch), this makes the visible card fill that full
   height instead of shrinking to its own content, and pins the CTA down.
*/
.rv-audience-card {
  height: 100%;
  display: flex;
  flex-direction: column;
}
.rv-audience-card > :last-child {
  margin-top: auto;
  padding-top: var(--wp--preset--spacing--4);
}

/* === FOUNDER CARD (homepage About section) ===
   Text on the left, headshot on the right (a transparent-background
   cutout, no crop box needed). The photo is positioned relative to the
   card itself: right + bottom: 0 anchors it flush to the card's
   bottom-right corner with no gap underneath, and since its natural
   height exceeds the card's at that point, the top of the photo rises
   above the card's own top edge automatically, no separate offset needed
   for the overlap. */
.rv-founder-wrap {
  /* No custom max-width here on purpose — the parent wp:group already uses
     the theme's standard "constrained" content width, same as every other
     section on the page. This just fills whatever that gives it. */
}
.rv-founder-card {
  position: relative;
  background: var(--wp--preset--color--white);
  border: 1px solid #eae7de;
  border-radius: var(--wp--custom--radius--2xl);
  box-shadow: var(--wp--custom--shadow--sm);
  /* overflow stays visible (the default) on purpose — the photo needs to
     rise above the card's own top edge, overflow:hidden here would clip
     exactly the part that's meant to show. */
  display: flex;
  align-items: flex-start;
}
.rv-founder-text {
  flex: 1;
  min-width: 0;
  max-width: 600px;
  padding: var(--wp--preset--spacing--8);
  padding-right: 380px;
}
.rv-founder-photo {
  position: absolute;
  right: 32px;
  bottom: 0;
  width: 340px;
  z-index: 1;
}
.rv-founder-photo img {
  width: 100%;
  height: auto;
  display: block;
  /* Mirrored on desktop so he faces into the text column on his left
     rather than out toward the edge of the card. Mobile stacks the photo
     above the text instead of beside it, so there's no "facing into the
     text" to preserve there, cancelled back out in that breakpoint below. */
  transform: scaleX(-1);
}
/* Below 782px the desktop layout (text reserving 420px on its right for a
   380px photo) leaves no room for text at all. Text drops back to flowing
   the full width of the card (just normal padding, no reserved gap), the
   photo shrinks and moves to sit centered above it instead of pinned to
   the corner, keeping the same "rises above the card" treatment at a
   scale that fits. */
@media (max-width: 781px) {
  .rv-founder-card {
    flex-direction: column;
    align-items: stretch;
    padding-top: 100px;
  }
  .rv-founder-text {
    max-width: none;
    padding: 0 var(--wp--preset--spacing--6) var(--wp--preset--spacing--6);
  }
  .rv-founder-photo {
    /* bottom:0 from the desktop rule anchored this to the card's bottom
       edge, fine when the card is a short, wide flex row, but once the
       card stacks to full-height column here the "bottom" is now way
       down past all the text, dragging the photo down to overlap the
       text instead of the top. top + a negative offset replaces that
       anchor entirely for this breakpoint. */
    width: 160px;
    height: 160px;
    right: 50%;
    bottom: auto;
    top: -80px;
    transform: translateX(50%);
    /* The transparent-cutout treatment that works as a tall portrait on
       desktop read as too loose/undefined at this small centered size.
       A circular crop gives it a contained edge instead, closer to a
       standard avatar treatment. Source photo has a transparent
       background, so the empty area around him inside the circle needs
       an explicit fill — #f8f6f0 (this section's own background, not the
       white card) rather than left transparent, which would otherwise
       show white where the circle overlaps the card and off-white where
       it doesn't, a visible mismatch down the middle of the circle. */
    background-color: #f8f6f0;
    border-radius: 50%;
    overflow: hidden;
    border: 1px solid #eae7de;
    box-shadow: var(--wp--custom--shadow--hover);
  }
  .rv-founder-photo img {
    height: 100%;
    object-fit: cover;
    object-position: top center;
    transform: none;
  }
}
