/* ===================================================================
   Vantara Living — static runtime styles
   Added when the site was detached from Framer's React bundle.
   Framer injected these rules at runtime; they must now be real CSS.
   Safe to edit. Nothing here overrides the original design tokens.
   =================================================================== */

/* -------------------------------------------------------------------
   1. RESPONSIVE VARIANT VISIBILITY  -- deliberately NOT implemented
   -------------------------------------------------------------------
   The export wraps components in .ssr-variant divs carrying classes
   like .hidden-158n9lv, meaning "React, hide this copy at that
   breakpoint and swap in the other copy".

   That only works if every component ships one copy PER breakpoint.
   This export does not: it contains exactly ONE copy of each
   component (35 of the 41 wrappers are tagged tablet-only). Framer
   rendered the missing breakpoints from the JS bundle at runtime.

   So implementing .hidden-* here would delete real content with
   nothing to replace it -- the hero eyebrow, nav and footer all
   disappeared when it was tried. The single copy must stay visible at
   every width, and Framer's own media queries on the component
   classes handle the responsive layout.

   Do not add blanket .hidden-* rules. If you ever need a true
   per-breakpoint component, author a second copy and hide them
   against each other.

   ONE exception, below. Nine real elements (not wrappers) carry
   .hidden-qu1n34 directly - that is Framer's "hide on mobile" toggle
   on decorative pieces: the Social Proof Card, two Left Rows and five
   Leaf Dividers. Those are genuine design intent with no replacement
   needed, so they are honoured. The :not(.ssr-variant) guard is what
   keeps this from touching the variant wrappers.
   ------------------------------------------------------------------- */
@media (max-width: 809.98px) {
  .hidden-qu1n34:not(.ssr-variant) { display: none !important; }
}

/* -------------------------------------------------------------------
   1b. MOBILE NAV
   Only the tablet nav exists in the export, and its single row of
   links overflows below ~700px. Let the bar wrap into two centred
   rows instead of running off the edge.
   ------------------------------------------------------------------- */
@media (max-width: 809.98px) {
  nav [data-framer-name="Container"] {
    flex-wrap: wrap !important;
    justify-content: center !important;
    row-gap: 10px;
    height: auto !important;
  }
  nav [data-framer-name="Links"] {
    flex-wrap: wrap !important;
    justify-content: center !important;
    row-gap: 8px;
    column-gap: 14px !important;
    width: 100% !important;
    max-width: 100% !important;
  }
  nav { height: auto !important; }
}

/* -------------------------------------------------------------------
   2. TESTIMONIAL MARQUEE
   Framer's Ticker component animated these with JS. Now pure CSS.
   Speed: change --v-marquee-duration (bigger = slower).
   ------------------------------------------------------------------- */
.v-marquee-viewport {
  overflow: hidden;
  position: relative;
  width: 100%;
}
ul.v-marquee {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 16px;
  width: max-content !important;
  max-width: none !important;
  list-style: none;
  padding: 0;
  margin: 0;
  will-change: transform;
  animation: v-marquee-scroll var(--v-marquee-duration, 60s) linear infinite;
}
/* second row runs the other way, and starts half a cycle in so the two
   rows are never showing the same card at the same x position */
ul.v-marquee.is-reverse {
  animation-direction: reverse;
  animation-delay: calc(var(--v-marquee-duration, 60s) / -2);
}
ul.v-marquee > li { flex: 0 0 auto; transform: none !important; }

@keyframes v-marquee-scroll {
  from { transform: translate3d(0, 0, 0); }
  /* -50% because the item set is duplicated once for a seamless loop */
  to   { transform: translate3d(calc(-50% - (var(--v-marquee-gap, 16px) / 2)), 0, 0); }
}

.v-marquee-viewport:hover ul.v-marquee { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  ul.v-marquee { animation: none; }
}

/* -------------------------------------------------------------------
   3. FAQ ACCORDION
   Answer panels are added by site.js. Plus icon rotates to an x.
   ------------------------------------------------------------------- */
.v-faq-answer {
  overflow: hidden;
  height: 0;
  opacity: 0;
  transition: height .38s cubic-bezier(.4, 0, .2, 1),
              opacity .28s ease;
}
/* descendant, not child: the panel is appended inside [data-framer-name="Container"],
   which makes it a grandchild of .v-faq-item */
.v-faq-item.is-open .v-faq-answer { opacity: 1; }

.v-faq-answer-inner {
  padding: 0 0 28px;
  max-width: 68ch;
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 15px;
  line-height: 1.7;
  color: var(--token-e66a358f-e5e2-4dbe-ae0e-2409c376d624, #5f6670);
}

[data-framer-name="Question"] { cursor: pointer; user-select: none; }
[data-framer-name="Question"]:focus-visible {
  outline: 2px solid var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  outline-offset: 4px;
  border-radius: 4px;
}

[data-framer-name="Plus Icon"] {
  transition: transform .38s cubic-bezier(.4, 0, .2, 1);
}
.v-faq-item.is-open [data-framer-name="Plus Icon"] { transform: rotate(45deg); }

/* -------------------------------------------------------------------
   4. CONTACT FORM STATES
   ------------------------------------------------------------------- */
.v-field-error {
  outline: 1.5px solid #c0392b !important;
  outline-offset: 1px;
}
.v-form-status {
  margin-top: 16px;
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 14px;
  line-height: 1.6;
  display: none;
}
.v-form-status.is-visible { display: block; }
.v-form-status.is-error   { color: #c0392b; }
.v-form-status.is-success { color: var(--token-c65558bc-654c-40a9-b4c1-c1ded2e590d8, #344832); }
.v-form-status.is-pending { color: var(--token-e66a358f-e5e2-4dbe-ae0e-2409c376d624, #5f6670); }

form[data-v-busy="true"] { opacity: .6; pointer-events: none; }

/* honeypot fields must never be visible or focusable */
input[name="website"][tabindex="-1"],
input[name="company"][tabindex="-1"],
input[name="message"][tabindex="-1"] {
  position: absolute !important;
  left: -9999px !important;
  width: 1px !important;
  height: 1px !important;
  opacity: 0 !important;
  pointer-events: none !important;
}

/* -------------------------------------------------------------------
   5. SMOOTH ANCHOR SCROLLING (replaces the Lenis library)
   ------------------------------------------------------------------- */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* -------------------------------------------------------------------
   6. HEADER CTA BUTTON
   Turns the last nav item ("Get Free Quote") into the filled gold pill
   from the reference header. Colour comes from the existing brand
   token, so it restyles automatically if the palette changes.
   ------------------------------------------------------------------- */
.v-nav-cta > div { width: auto !important; }

.v-nav-cta a {
  display: inline-flex !important;
  align-items: center;
  gap: 8px;
  padding: 14px 26px !important;
  border-radius: 100px;
  background: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .25s ease, transform .25s ease, box-shadow .25s ease;
}

/* the label sits in a RichTextContainer whose colour is set inline, so
   the override has to reach the <p> itself */
.v-nav-cta a p.framer-text {
  --framer-text-color: #fff !important;
  color: #fff !important;
  font-weight: 600 !important;
  font-size: 14px !important;
}

.v-nav-cta-arrow {
  width: 16px;
  height: 16px;
  flex: none;
  display: block;
}

.v-nav-cta a:hover {
  background: color-mix(in srgb, var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e) 88%, #000);
  box-shadow: 0 6px 18px rgba(182, 138, 94, .32);
  transform: translateY(-1px);
}
.v-nav-cta a:active { transform: translateY(0); }

.v-nav-cta a:focus-visible {
  outline: 2px solid var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, #121820);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .v-nav-cta a { transition: none; }
  .v-nav-cta a:hover { transform: none; }
}

/* on mobile the bar already wraps; keep the pill from stretching */
@media (max-width: 809.98px) {
  .v-nav-cta { flex: none !important; }
  .v-nav-cta a { padding: 12px 22px !important; }
}

/* -------------------------------------------------------------------
   7. HEADER LAYOUT - full-width space-between
   The nav Container already sets justify-content: space-between, but
   the Tablet variant rule
       .framer-MAcDI.framer-v-p4t5vm .framer-sdh57h { max-width: 810px }
   caps it at 810px and centres it inside a ~1280px bar, so the brand
   and CTA sit ~235px in from each edge instead of at the edges.
   Restoring the base 1200px cap lets space-between reach the edges.

   This changes WIDTH only - no padding, gap or margin is touched.
   ------------------------------------------------------------------- */
@media (min-width: 810px) {
  nav [data-framer-name="Container"] {
    max-width: 1200px !important;
  }
}

/* ===================================================================
   8. HERO — PAGE-LOAD ENTRANCE
   -------------------------------------------------------------------
   The export only animated 7 hero elements, and 4 of those were plain
   opacity fades with no movement, which is why the load felt flat. The
   headline and subheading had no animation at all.

   Framer's appear-animation ids were removed from the hero so its JS
   animator and this CSS are not driving the same properties at once.
   The whole entrance is now one coherent timeline you can retune here.

   Tempo: nudge --v-hero-ease / the delays below. Every element uses
   animation-fill-mode: both, so each one holds its start frame until
   its delay elapses.
   =================================================================== */
:root {
  --v-hero-ease: cubic-bezier(.22, 1, .36, 1);
  --v-hero-dur: .9s;
}

@keyframes v-rise {
  from { opacity: 0; transform: translate3d(0, 26px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes v-rise-sm {
  from { opacity: 0; transform: translate3d(0, 14px, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
@keyframes v-slide-right {
  from { opacity: 0; transform: translate3d(28px, 0, 0); }
  to   { opacity: 1; transform: translate3d(0, 0, 0); }
}
/* slow settle on the background photo - the "expensive" feel. This one
   rides on the WRAPPER, leaving the image itself free for the endless
   drift below; stacking both on one element would put two animations on
   the same transform and the last one declared would simply win. */
@keyframes v-kenburns {
  from { transform: scale(1.07); }
  to   { transform: scale(1); }
}

[data-v-hero] [data-framer-background-image-wrapper] {
  animation: v-kenburns 2.6s var(--v-hero-ease) both;
}

/* Continuous zoom on the hero photo.

   `alternate` rather than a plain loop: an animation that restarts jumps
   the photo back to its opening scale every cycle, which reads as a
   glitch on a still image. Running it out and back means the movement
   never has a seam. 22s each way, so it is felt rather than watched.

   The hero section is overflow:clip, so the oversized image is cropped
   rather than pushing the page wider. */
@keyframes v-hero-zoom {
  from { transform: scale(1); }
  to   { transform: scale(1.14); }
}

[data-v-hero] [data-framer-background-image-wrapper] > img {
  transform-origin: 55% 45%;
  animation: v-hero-zoom 22s ease-in-out infinite alternate;
  will-change: transform;
}

/* 1 — eyebrow: accent line + "CURATED FOR REFINED LIVING" */
[data-v-hero] .framer-1ajpm4g-container {
  animation: v-rise-sm var(--v-hero-dur) var(--v-hero-ease) .12s both;
}

/* 2 — headline, one word at a time (the markup is already split into
   spans for this, the export just never used them) */
[data-v-hero] .framer-njvoyl h1 > span {
  display: inline-block;
  animation: v-rise var(--v-hero-dur) var(--v-hero-ease) both;
}
[data-v-hero] .framer-njvoyl h1 > span:nth-child(1) { animation-delay: .26s; }
[data-v-hero] .framer-njvoyl h1 > span:nth-child(2) { animation-delay: .33s; }
[data-v-hero] .framer-njvoyl h1 > span:nth-child(3) { animation-delay: .40s; }
[data-v-hero] .framer-njvoyl h1 > span:nth-child(4) { animation-delay: .47s; }
[data-v-hero] .framer-njvoyl h1 > span:nth-child(5) { animation-delay: .54s; }
[data-v-hero] .framer-njvoyl h1 > span:nth-child(6) { animation-delay: .61s; }
[data-v-hero] .framer-njvoyl h1 > span:nth-child(7) { animation-delay: .68s; }

/* 3 — subheading */
[data-v-hero] .framer-szr729 {
  animation: v-rise-sm var(--v-hero-dur) var(--v-hero-ease) .74s both;
}

/* 4 — the two CTAs */
[data-v-hero] .framer-10lxvsn-container {
  animation: v-rise-sm var(--v-hero-dur) var(--v-hero-ease) .88s both;
}
[data-v-hero] .framer-1y3rrks-container {
  animation: v-rise-sm var(--v-hero-dur) var(--v-hero-ease) .97s both;
}

/* 5 — social proof card drifts in from the right */
[data-v-hero] .framer-107wji5 {
  animation: v-slide-right 1s var(--v-hero-ease) 1s both;
}

/* 6 — the three stat cards, left to right */
[data-v-hero] .framer-16cd7pe { animation: v-rise var(--v-hero-dur) var(--v-hero-ease) 1.12s both; }
[data-v-hero] .framer-1fr38wy { animation: v-rise var(--v-hero-dur) var(--v-hero-ease) 1.22s both; }
[data-v-hero] .framer-1nmu2sd { animation: v-rise var(--v-hero-dur) var(--v-hero-ease) 1.32s both; }

@media (prefers-reduced-motion: reduce) {
  [data-v-hero] .framer-1ajpm4g-container,
  [data-v-hero] .framer-njvoyl h1 > span,
  [data-v-hero] .framer-szr729,
  [data-v-hero] .framer-10lxvsn-container,
  [data-v-hero] .framer-1y3rrks-container,
  [data-v-hero] .framer-107wji5,
  [data-v-hero] .framer-16cd7pe,
  [data-v-hero] .framer-1fr38wy,
  [data-v-hero] .framer-1nmu2sd,
  [data-v-hero] [data-framer-background-image-wrapper],
  [data-v-hero] [data-framer-background-image-wrapper] > img {
    animation: none !important;
    opacity: 1;
    transform: none;
  }
}

/* ===================================================================
   9. HERO BUTTON HOVER
   Both hero CTAs share .framer-BKYom. The export shipped no hover
   state at all, so they felt dead. Lift + shadow + the arrow stepping
   out along its own diagonal.
   =================================================================== */
[data-v-hero] a.framer-BKYom {
  transition: transform .34s var(--v-hero-ease),
              box-shadow .34s var(--v-hero-ease),
              background-color .34s var(--v-hero-ease),
              border-color .34s var(--v-hero-ease);
  will-change: transform;
}
[data-v-hero] a.framer-BKYom svg[data-framer-name="Arrow"] {
  transition: transform .34s var(--v-hero-ease);
}

[data-v-hero] a.framer-BKYom:hover {
  transform: translateY(-3px);
}
/* the arrow glyph points up-right, so it travels that way */
[data-v-hero] a.framer-BKYom:hover svg[data-framer-name="Arrow"] {
  transform: translate3d(3px, -3px, 0);
}
[data-v-hero] a.framer-BKYom:active { transform: translateY(-1px); }

/* primary (dark pill) — deepen and cast a warm shadow */
[data-v-hero] a.framer-v-12nf9sg:hover {
  background-color: var(--token-5d86c2df-4408-4d62-840f-ea84742f9e49, #0f171c) !important;
  box-shadow: 0 14px 30px rgba(18, 24, 32, .30);
}

/* secondary (outlined pill) — fill softly with the brand gold */
[data-v-hero] a.framer-v-16f2ey0:hover {
  background-color: var(--token-2151477a-064a-4343-a50f-e7423ad5a59e, rgba(182, 138, 94, .30)) !important;
  border-color: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e) !important;
  box-shadow: 0 14px 30px rgba(182, 138, 94, .22);
}

[data-v-hero] a.framer-BKYom:focus-visible {
  outline: 2px solid var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  outline-offset: 4px;
}

@media (prefers-reduced-motion: reduce) {
  [data-v-hero] a.framer-BKYom,
  [data-v-hero] a.framer-BKYom svg[data-framer-name="Arrow"] { transition: none; }
  [data-v-hero] a.framer-BKYom:hover { transform: none; }
  [data-v-hero] a.framer-BKYom:hover svg[data-framer-name="Arrow"] { transform: none; }
}

/* ===================================================================
   10. SCROLL REVEAL  (paired with initReveal in site.js)
   -------------------------------------------------------------------
   site.js adds .v-rv and a --v-i stagger index to a section's blocks,
   then flips .is-in when the section scrolls into view. Because JS
   applies the class, nothing is ever hidden if JS fails to load.

   Retune: --v-rv-step is the gap between blocks, --v-rv-dur the
   travel time of each one.
   =================================================================== */
:root {
  --v-rv-step: 85ms;
  --v-rv-dur: .85s;
}

/* Hidden state carries NO transition. If it did, the block would be
   painted visible, then animate *out* to hidden, then animate back in
   on scroll - a visible flash. JS adds .is-armed on the next frame,
   which is what switches the transition on. */
.v-rv {
  opacity: 0;
  transform: translate3d(0, 26px, 0);
  transition: none;
  will-change: opacity, transform;
}
.v-rv.is-armed {
  transition: opacity var(--v-rv-dur) var(--v-hero-ease),
              transform var(--v-rv-dur) var(--v-hero-ease);
  transition-delay: calc(var(--v-i, 0) * var(--v-rv-step));
}
.v-rv.is-in {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

/* headline words travel a shorter distance so the line stays readable
   while it assembles */
.v-rv--word {
  display: inline-block;
  transform: translate3d(0, 18px, 0);
}

/* hairline rules draw themselves in from the left */
.v-rv--line {
  transform: scaleX(0);
  transform-origin: left center;
  transition-duration: .7s;
}
.v-rv--line.is-in { transform: scaleX(1); }

/* imagery scales up very slightly instead of sliding */
.v-rv--img {
  transform: scale(1.04);
  transition-duration: 1.1s;
}
.v-rv--img.is-in { transform: scale(1); }

/* once it has played, stop promising the compositor anything */
.v-rv.is-in { will-change: auto; }

@media (prefers-reduced-motion: reduce) {
  .v-rv,
  .v-rv--word,
  .v-rv--img,
  .v-rv--line {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* ===================================================================
   11. SERVICES — button-driven card slider
   -------------------------------------------------------------------
   Was a scroll-linked horizontal track (pin spacer + sticky stage,
   driven by scroll position); that scroll-hijack was removed in
   favour of an explicit .v-services__nav prev/next pair. Structure now:
     .v-services__stage    ordinary section wrapper, normal document flow.
     .v-services__viewport horizontally scrollable strip with native
                           scroll-snap; the buttons call
                           viewport.scrollBy() - see site.js section 3c.
     .v-services__rail     the row of cards inside it.

   Section padding/background/max-width mirror the Framer sections
   (60px 30px, #f7f4ed, 1200px) so the page rhythm is unbroken.
   =================================================================== */
.v-services {
  background-color: var(--token-85c9e407-2eff-4642-a975-0675c5d8c8c1, #f7f4ed);
  position: relative;
  width: 100%;
}

.v-services__stage {
  display: flex;
  padding: 60px 30px;
  box-sizing: border-box;
}
.v-services__inner {
  width: 100%;
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 26px;
}

/* ---- heading block (same shape as the other sections) ---- */
/* The head spans the full track width so the intro row can push the
   button out to the right edge. The 630px measure that used to live
   here now sits on the title, so the headline still breaks in two. */
.v-services__head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 16px;
  width: 100%;
}
.v-services__eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
}
.v-services__rule {
  display: block;
  width: 32px;
  height: 1px;
  background: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
}
.v-services__kicker {
  margin: 0;
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .05em;
  line-height: 1.15em;
  color: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
}
.v-services__title {
  margin: 0;
  /* identical to the About / Why / Amenities headings: Framer sets
     those to Cormorant Garamond 70px, weight 500, 1.05em, -1.5px */
  font-family: "Cormorant Garamond", "Cormorant Garamond Placeholder", serif;
  /* Framer steps the big headings 70 / 60 / 45 at 1200 and 810; a vw
     clamp only ever approximated that, so this matches them exactly. */
  font-size: 45px;
  font-weight: 500;
  max-width: 630px;
  line-height: 1.05em;
  letter-spacing: -1.5px;
  color: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, #121820);
}
@media (min-width: 810px)  { .v-services__title { font-size: 60px; } }
@media (min-width: 1200px) { .v-services__title { font-size: 70px; } }

.v-services__title > span { display: inline-block; }
/* heading, then the two-line paragraph, then the button underneath it -
   all stacked down the left edge */
.v-services__intro {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
  width: 100%;
}

/* deliberately identical to the About section’s "View Our Work":
   ink pill, 100px radius, 14/28 padding, 15px Inter medium */
.v-services__all {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  flex: none;
  padding: 14px 28px;
  border-radius: 100px;
  background: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, #121820);
  color: #fff;
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -.01em;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .3s ease, transform .3s cubic-bezier(.22,.61,.36,1), box-shadow .3s ease;
}
.v-services__all svg { width: 15px; height: 15px; display: block; flex: none; transition: transform .3s cubic-bezier(.22,.61,.36,1); }
.v-services__all:hover {
  background: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  transform: translateY(-2px);
  box-shadow: 0 10px 22px -8px rgba(182,138,94,.6);
}
.v-services__all:hover svg { transform: translateX(4px); }
.v-services__all:active { transform: translateY(0); }
.v-services__all:focus-visible {
  outline: 2px solid var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  outline-offset: 3px;
}
@media (prefers-reduced-motion: reduce) {
  .v-services__all, .v-services__all svg { transition: background-color .3s ease; }
  .v-services__all:hover { transform: none; box-shadow: none; }
  .v-services__all:hover svg { transform: none; }
}

.v-services__lede {
  margin: 0;
  max-width: 489px;
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 16px;
  line-height: 1.6em;
  color: var(--token-e66a358f-e5e2-4dbe-ae0e-2409c376d624, #5f6670);
}

/* ---- the scrollable track ----
   Native horizontal scroll + snap, at every width now - this used to be
   a mobile-only fallback while desktop was scroll-jacked. The prev/next
   buttons below just nudge viewport.scrollLeft; nothing here is
   JS-driven any more. */
.v-services__viewport {
  overflow-x: auto;
  overflow-y: hidden;
  width: 100%;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  /* Vertical padding is deliberate, not decorative: the card's colour
     glow (box-shadow) paints outside its own border box, and this
     viewport still clips anything outside ITS box even with overflow-x
     alone set. Zero padding puts that clip line flush against the card
     edge, so even a plain hover shadow would be invisible without it. */
  padding: 28px 0;
  /* the buttons are the control; hide the native scrollbar */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.v-services__viewport::-webkit-scrollbar { display: none; }
.v-services__rail {
  display: flex;
  align-items: center;
  gap: 24px;
  width: max-content;
}
.v-svc-card { scroll-snap-align: start; }

/* ---- prev / next slider buttons ---- */
.v-services__nav {
  display: flex;
  align-items: center;
  gap: 12px;
  align-self: flex-end;
}
.v-services__arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex: none;
  border: none;
  border-radius: 50%;
  background: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, #121820);
  color: #fff;
  cursor: pointer;
  transition: background-color .3s ease, transform .3s cubic-bezier(.22,.61,.36,1), opacity .3s ease;
}
.v-services__arrow svg { width: 18px; height: 18px; display: block; }
.v-services__arrow:hover:not(:disabled) {
  background: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  transform: translateY(-2px);
}
.v-services__arrow:active:not(:disabled) { transform: translateY(0); }
.v-services__arrow:focus-visible {
  outline: 2px solid var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  outline-offset: 3px;
}
/* site.js disables an end button once the track can't scroll further
   that way, rather than hiding it - a missing button reads as broken,
   a dim/inert one reads as "you're at the end". */
.v-services__arrow:disabled { opacity: .35; cursor: default; }

@media (max-width: 809.98px) {
  .v-services__stage { padding: 60px 20px; }
  .v-services__viewport {
    margin: 0 -20px;
    /* more top/bottom room than the 28px above: nothing here shares a
       height budget with anything else, unlike the old pinned stage */
    padding: 24px 20px 28px;
  }
  .v-svc-card { width: 78vw; max-width: 320px; }
}

@media (prefers-reduced-motion: reduce) {
  .v-svc-card { transition: none; }
  .v-svc-card:hover { transform: none; }
  .v-svc-card:hover .v-svc-card__img { transform: none; }
  .v-services__viewport { scroll-behavior: auto; }
  .v-services__arrow { transition: background-color .3s ease, opacity .3s ease; }
  .v-services__arrow:hover:not(:disabled) { transform: none; }
}

/* ===================================================================
   11c. SERVICE CARDS — full-bleed image, name overlaid, detail on hover
   -------------------------------------------------------------------
   Matches the supplied reference: a tall photo card with the service
   name set in white caps at the bottom, staggered heights across the
   row. Hovering (or keyboard-focusing) lifts the name and reveals a
   one-line description plus a Read more button.

   Section hierarchy above the cards is unchanged - eyebrow, serif
   heading, lede - so the page still reads in the same order.

   Per-card colour: each <article class="v-svc-card"> in index.html
   carries an inline style="--v-card-theme:R,G,B". All five currently
   carry the same value - the site's one real accent, gold
   (--token-a9fa4cc5, #b68a5e / 182,138,94), the only colour actually
   used repeatedly across the page (nav, buttons, focus rings). An
   earlier version gave each card a different token-derived hue (green,
   blue-slate...) but most of those tokens turn out to be unused
   anywhere else on the page, so on this page they read as off-brand
   rather than "part of the palette" - gold across all five is what
   actually matches the site. Left as a per-card variable rather than
   a flat rule only so a future redesign can vary it again on purpose.
   =================================================================== */
.v-svc-card {
  --v-card-pad: 26px;
  --v-card-radius: 12px;
  position: relative;
  flex: 0 0 auto;
  /* site.js sets --v-card-w so a whole number of complete cards fills
     the track at any width - no card is ever left part-clipped */
  width: var(--v-card-w, 340px);
  /* Fixed, not JS-computed: without the old pinned 100vh stage there is
     no height budget to protect the card from, so it's just always
     this tall now. */
  height: 400px;
  border-radius: var(--v-card-radius);
  /* Not clipped: the image and the content block each carry their own
     border-radius (see __img / __content below), so the rounded look
     doesn't depend on this. Left open so the hover reveal can grow the
     content block past the card's own box on a short card rather than
     being sliced off - it pushes the title up over the photo instead. */
  overflow: visible;
  isolation: isolate;
  background: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, #121820);
  cursor: pointer;
  outline: none;
  /* Resting glow in the card's own colour - visible against the section's
     pale background even before it's touched, on a light cream page a
     flat/neutral shadow reads as nothing, so this is what actually makes
     each card look "themed" rather than the gradient wash alone. */
  box-shadow: 0 24px 46px -24px rgba(var(--v-card-theme, 18, 24, 32), .55);
  transition: transform .5s var(--v-hero-ease), box-shadow .5s var(--v-hero-ease);
}


/* --v-card-theme is an "R,G,B" triplet set inline per card in index.html -
   currently the site's brand gold on all five cards, see section 11c
   header comment. Falls back to the card's base ink so a card with no
   theme set still gets a (neutral) glow. */
.v-svc-card:hover,
.v-svc-card:focus-visible {
  transform: translateY(-6px);
  box-shadow: 0 34px 70px -22px rgba(var(--v-card-theme, 18, 24, 32), .8);
}
.v-svc-card:focus-visible {
  box-shadow: 0 0 0 2px var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e),
              0 34px 70px -22px rgba(var(--v-card-theme, 18, 24, 32), .8);
}

.v-svc-card__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
  /* self-clip: a transformed child escapes the parent rounded clip */
  border-radius: inherit;
  transition: transform .7s var(--v-hero-ease);
}
.v-svc-card:hover .v-svc-card__img,
.v-svc-card:focus-visible .v-svc-card__img { transform: scale(1.06); }

.v-svc-card__content {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  /* the legibility wash lives here rather than on a separate layer:
     one less stacking context over the photo, and it grows with the
     content when the hover detail expands. Tinted per card by
     --v-card-theme (falls back to the old neutral ink) rather than
     plain black, so each card reads as its own service. */
  background: linear-gradient(to top,
              rgba(var(--v-card-theme, 10, 14, 18), .92) 0%,
              rgba(var(--v-card-theme, 10, 14, 18), .70) 45%,
              rgba(var(--v-card-theme, 10, 14, 18), .30) 75%,
              rgba(var(--v-card-theme, 10, 14, 18), 0)  100%);
  padding: 88px var(--v-card-pad) var(--v-card-pad);
  /* square bottom corners here would poke past the card radius */
  border-radius: 0 0 var(--v-card-radius) var(--v-card-radius);
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.v-svc-card__title {
  margin: 0;
  /* Cards are sized to fit the track, so they are narrow enough that
     longer names wrap. Reserving two lines keeps every card's text
     block the same height whether its name wraps or not - otherwise
     one-line cards sit lower than their neighbours. */
  /* Same family as the big section heading above the track, as asked.
     Cormorant is a display serif - the old uppercase Inter label read as
     a caption, this reads as a name. Sentence case, because uppercase
     throws away the letterforms that make the face worth using. */
  font-family: "Cormorant Garamond", "Cormorant Garamond Placeholder", serif;
  font-size: 28px;
  font-weight: 500;
  letter-spacing: -.3px;
  line-height: 1.12;
  text-transform: none;
  color: #fff;
}

/* The reveal is measured in max-height rather than height so the copy
   can reflow; the values are comfortably above the real content. */
.v-svc-card__reveal {
  max-height: 0;
  opacity: 0;
  transform: translateY(8px);
  overflow: hidden;
  transition: max-height .45s var(--v-hero-ease),
              opacity .35s var(--v-hero-ease),
              transform .45s var(--v-hero-ease);
}
.v-svc-card:hover .v-svc-card__reveal,
.v-svc-card:focus-visible .v-svc-card__reveal,
.v-svc-card:focus-within .v-svc-card__reveal {
  max-height: 190px;
  opacity: 1;
  transform: translateY(0);
}

.v-svc-card__desc {
  margin: 0 0 16px;
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 13.5px;
  line-height: 1.6;
  color: rgba(255, 255, 255, .82);
  /* Pin the copy to exactly two lines. Without this the teasers wrap to
     different line counts, so each card's revealed block came out a
     different height and the spacing under the button read as uneven. */
  min-height: calc(13.5px * 1.6 * 2);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.v-svc-card__more {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 9px 16px;
  border-radius: 100px;
  background: rgba(255, 255, 255, .92);
  /* faint themed rim + blur so the pill reads as glass sitting on the
     photo rather than a flat sticker - same idea as the header nav pill */
  border: 1px solid rgba(var(--v-card-theme, 255, 255, 255), .35);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, #121820);
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color .3s var(--v-hero-ease), color .3s var(--v-hero-ease), border-color .3s var(--v-hero-ease);
}
.v-svc-card__more svg { width: 13px; height: 13px; display: block; }
.v-svc-card__more:hover {
  background: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  color: #fff;
}

/* -------------------------------------------------------------------
   Touch / small screens: there is no hover, so the detail is simply
   always visible. Same content, no interaction required.
   ------------------------------------------------------------------- */
@media (hover: none), (max-width: 809.98px) {
  .v-svc-card__reveal {
    max-height: 190px;
    opacity: 1;
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .v-svc-card,
  .v-svc-card__img,
  .v-svc-card__reveal { transition: none; }
  .v-svc-card:hover { transform: none; }
  .v-svc-card:hover .v-svc-card__img { transform: none; }
}



/* ===================================================================
   12. PROJECTS SECTION  (#Projects - formerly "Floor Plan")

   Two problems were fixed here.

   (a) LAYOUT. The export only ever shipped the *Tablet* variant of
       this component (framer-v-jjt5w4), and that variant forces the
       outer row to stack - which is why the copy sat on the left with
       the image dumped underneath it instead of beside it. Framer's
       own base rules (.framer-H4vtc.framer-s65r6o etc.) already
       describe the desktop two-column layout, so the fix is simply to
       stop the tablet variant winning once there is room for it.

   (b) THE VILLA SWITCHER. Villa A / B / C were static React variants
       with no runtime behind them, so clicking did nothing. The
       active/inactive look lives entirely in inline styles, so every
       rule below needs !important to outrank it. Behaviour is in
       site.js -> initProjects().
   =================================================================== */

/* -------------------------------------------------------------------
   12a. Desktop: copy + selector on the left, project card on the right
   ------------------------------------------------------------------- */
@media (min-width: 1000px) {
  #Projects .framer-s65r6o {
    flex-direction: row !important;
    align-items: flex-start !important;
    gap: 48px;
  }

  /* back to the base rule the tablet variant overrode */
  #Projects .framer-vfbwa9 {
    flex: 1 1 0 !important;
    width: 1px !important;
    padding-top: 6px;
  }

  #Projects .framer-11nuqft { max-width: none !important; }

  #Projects .framer-1s4napv-container {
    flex: none !important;
    width: 58% !important;
  }
}

/* Below 700px the card itself stacks: image first, then the spec
   list - the same order Framer's own narrow variant uses. */
@media (max-width: 699.98px) {
  #Projects .framer-1q0tu3u { flex-direction: column !important; }
  #Projects .v-plan-media { order: 0; width: 100% !important; flex: none !important; }
  #Projects .v-plan-card__info {
    order: 1;
    max-width: none !important;
    flex: none !important;
    width: 100% !important;
    padding-top: 22px;
  }
}

/* -------------------------------------------------------------------
   12b. The villa selector

   Inline styles carry the colours, so these all have to shout. The
   custom properties are the ones Framer's own markup reads:
   --framer-text-color for copy, --1m973uw for the arrow's stroke.
   ------------------------------------------------------------------- */
#Projects .v-plan-tab {
  cursor: pointer;
  background-color: rgba(19, 25, 33, 0) !important;
  transition: background-color .35s ease, padding-left .35s ease;
}

#Projects .v-plan-tab .framer-text {
  --framer-text-color: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, rgb(18, 24, 32)) !important;
  transition: color .35s ease;
}

#Projects .v-plan-tab .framer-lxj84m {
  background-color: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, rgb(18, 24, 32)) !important;
  transition: background-color .35s ease;
}

#Projects .v-plan-tab svg {
  --1m973uw: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, rgb(18, 24, 32)) !important;
  transition: transform .35s ease;
}

/* selected */
#Projects .v-plan-tab.is-active {
  background-color: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, rgb(18, 24, 32)) !important;
}
#Projects .v-plan-tab.is-active .framer-text {
  --framer-text-color: var(--token-4c0ef0c0-5888-4f3f-a070-180b0bdeeee0, rgb(255, 255, 255)) !important;
}
#Projects .v-plan-tab.is-active .framer-lxj84m {
  background-color: var(--token-4c0ef0c0-5888-4f3f-a070-180b0bdeeee0, rgb(255, 255, 255)) !important;
}
#Projects .v-plan-tab.is-active svg {
  --1m973uw: var(--token-4c0ef0c0-5888-4f3f-a070-180b0bdeeee0, rgb(255, 255, 255)) !important;
  transform: translateX(3px);
}

/* hovering an unselected villa hints at the gold before committing */
#Projects .v-plan-tab:not(.is-active):hover {
  background-color: var(--token-2151477a-064a-4343-a50f-e7423ad5a59e, rgba(182, 138, 94, .3)) !important;
}
#Projects .v-plan-tab:not(.is-active):hover svg { transform: translateX(4px); }

#Projects .v-plan-tab:focus-visible {
  outline: 2px solid var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  outline-offset: 3px;
}

/* -------------------------------------------------------------------
   12c. Swapping a villa

   JS adds .is-swapping, waits out the fade, writes the new copy and
   image, then takes the class off again. Two halves of the card move
   independently so it reads as one considered change rather than a
   flicker.
   ------------------------------------------------------------------- */
#Projects .v-plan-card__info {
  transition: opacity .26s ease, transform .26s ease;
}
#Projects .v-plan-card.is-swapping .v-plan-card__info {
  opacity: 0;
  transform: translateY(12px);
}

#Projects .v-plan-media {
  align-self: stretch;
  min-height: 340px;
  border-radius: 12px;
  overflow: hidden;
}
#Projects .v-plan-media img {
  transition: opacity .3s ease, transform .8s cubic-bezier(.22, .61, .36, 1);
}
#Projects .v-plan-card.is-swapping .v-plan-media img {
  opacity: 0;
  transform: scale(1.04);
}

@media (max-width: 699.98px) {
  #Projects .v-plan-media { min-height: 240px; aspect-ratio: 3 / 2; align-self: auto; }
}

@media (prefers-reduced-motion: reduce) {
  #Projects .v-plan-tab,
  #Projects .v-plan-tab .framer-text,
  #Projects .v-plan-tab .framer-lxj84m,
  #Projects .v-plan-tab svg,
  #Projects .v-plan-card__info,
  #Projects .v-plan-media img { transition: none; }
  #Projects .v-plan-card.is-swapping .v-plan-card__info { transform: none; }
  #Projects .v-plan-card.is-swapping .v-plan-media img { transform: none; }
  #Projects .v-plan-tab.is-active svg,
  #Projects .v-plan-tab:not(.is-active):hover svg { transform: none; }
}


/* ===================================================================
   13. FOOTER SOCIAL LINKS - hover

   Each link is a 40px white pill with a hairline gold border; the icon
   inside it is a 14px div wearing a CSS mask, so the glyph's colour is
   that div's background-color, not a fill.

   On hover the pill fills with gold and the glyph inverts to white.
   The pill's background and --border-color are both set inline by the
   export, so those two declarations have to be !important to win.
   =================================================================== */
.framer-1a7469d a {
  transition: background-color .3s ease,
              border-color .3s ease,
              transform .3s cubic-bezier(.22, .61, .36, 1),
              box-shadow .3s ease;
}

.framer-1a7469d a .framer-12g0pai {
  transition: background-color .3s ease, transform .3s cubic-bezier(.22, .61, .36, 1);
}

.framer-1a7469d a:hover {
  background-color: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e) !important;
  --border-color: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e) !important;
  transform: translateY(-3px);
  box-shadow: 0 8px 18px -6px rgba(182, 138, 94, .55);
}

/* the mask means the glyph takes the colour of its own background */
.framer-1a7469d a:hover .framer-12g0pai {
  background-color: var(--token-4c0ef0c0-5888-4f3f-a070-180b0bdeeee0, #fff) !important;
  transform: scale(1.08);
}

.framer-1a7469d a:active {
  transform: translateY(-1px);
  box-shadow: 0 4px 10px -4px rgba(182, 138, 94, .5);
}

.framer-1a7469d a:focus-visible {
  outline: 2px solid var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  /* keep the colour change, drop the movement */
  .framer-1a7469d a,
  .framer-1a7469d a .framer-12g0pai { transition: background-color .3s ease, border-color .3s ease; }
  .framer-1a7469d a:hover,
  .framer-1a7469d a:active { transform: none; box-shadow: none; }
  .framer-1a7469d a:hover .framer-12g0pai { transform: none; }
}

/* ===================================================================
   14. OUR STUDIO — HIDDEN FOR NOW, STOOD IN FOR BY A CTA BAND
   -------------------------------------------------------------------
   Asked for on 2026-09-14, explicitly as a temporary arrangement.

   The "Our Studio" section is #Map (Framer's original name for it —
   it holds the studio copy, the three location points, the floor-plan
   graphic and the six travel times). Its markup is untouched; the one
   rule below is the only thing hiding it, so deleting that single
   line brings the whole section back exactly as it was.

   Hiding it also parks the img-22 problem: that graphic still has the
   old "VANTARA VILLAS" logo baked into the artwork, so it was the one
   place the retired brand was still visible on the page.

   In its place, a full-bleed image band carrying a Contact Us call to
   action. It is deliberately its own component rather than a reworked
   #Map, so neither one interferes with the other.
   =================================================================== */

/* TEMPORARY — delete this line to restore the Our Studio section. */
#Map { display: none !important; }

.v-studio-cta {
  position: relative;
  width: 100%;
  /* the height asked for, exactly */
  height: 567px;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  isolation: isolate;
}

/* ---- full-bleed background ---- */
.v-studio-cta__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.v-studio-cta__bg img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 62%;
}
/* A sunset photo is far too bright at the horizon for white type to
   sit on unaided. Darkest at top and bottom, lighter through the
   middle, so the picture still reads as a picture. */
.v-studio-cta__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg,
      rgba(18, 24, 32, .72) 0%,
      rgba(18, 24, 32, .52) 38%,
      rgba(18, 24, 32, .44) 66%,
      rgba(18, 24, 32, .78) 100%);
}

/* ---- content ---- */
.v-studio-cta__inner {
  position: relative;
  z-index: 1;
  width: 100%;
  max-width: 1328px;
  padding: 0 64px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 18px;
}

/* the section eyebrow, mirrored either side because this one is centred */
.v-studio-cta__eyebrow {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .05em;
  line-height: 1.15em;
  text-transform: uppercase;
  /* A pale cast of the brand gold. The full-strength #b68a5e is meant
     for cream backgrounds; measured against the blown-out sky behind
     this line it came out at 1.6:1, effectively invisible. */
  color: #f2dcc0;
  text-shadow: 0 1px 3px rgba(18, 24, 32, .5);
}
.v-studio-cta__eyebrow::before,
.v-studio-cta__eyebrow::after {
  content: "";
  display: block;
  width: 32px;
  height: 1px;
  background: #f2dcc0;
  opacity: .8;
}

/* same Cormorant ladder as every other section heading: 45 / 60 / 70 */
.v-studio-cta__title {
  margin: 0;
  max-width: 16ch;
  font-family: "Cormorant Garamond", "Cormorant Garamond Placeholder", serif;
  font-size: 45px;
  font-weight: 500;
  line-height: 1.05em;
  letter-spacing: -1.5px;
  color: #fff;
  text-wrap: balance;
}
@media (min-width: 810px)  { .v-studio-cta__title { font-size: 60px; } }
@media (min-width: 1200px) { .v-studio-cta__title { font-size: 70px; } }
/* initReveal splits the heading into per-word spans */
.v-studio-cta__title > span { display: inline-block; }

.v-studio-cta__lede {
  margin: 0;
  max-width: 520px;
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 16px;
  line-height: 1.6em;
  color: rgba(255, 255, 255, .82);
}

/* ---- the call to action ---- */
.v-studio-cta__btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
  padding: 16px 34px;
  border-radius: 100px;
  background: var(--token-a9fa4cc5-9241-41d0-a20d-26d373462458, #b68a5e);
  color: #fff;
  font-family: "Inter", "Inter Placeholder", sans-serif;
  font-size: 15px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -.01em;
  text-decoration: none;
  white-space: nowrap;
  box-shadow: 0 14px 30px -12px rgba(18, 24, 32, .65);
  transition: background-color .3s ease, color .3s ease,
              transform .3s cubic-bezier(.22,.61,.36,1), box-shadow .3s ease;
}
.v-studio-cta__btn svg {
  width: 15px;
  height: 15px;
  display: block;
  flex: none;
  transition: transform .3s cubic-bezier(.22,.61,.36,1);
}
/* inverting to cream reads as a deliberate CTA against the photograph,
   where another gold-on-gold shift would barely register */
.v-studio-cta__btn:hover {
  background: var(--token-85c9e407-2eff-4642-a975-0675c5d8c8c1, #f7f4ed);
  color: var(--token-c67f0217-9d8b-4835-bc1f-620297d28714, #121820);
  transform: translateY(-2px);
  box-shadow: 0 18px 34px -12px rgba(18, 24, 32, .75);
}
.v-studio-cta__btn:hover svg { transform: translateX(4px); }
.v-studio-cta__btn:active { transform: translateY(0); }
.v-studio-cta__btn:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

/* ---- narrow screens ----
   The 567px is honoured as a floor rather than a fixed height here, so
   a heading that wraps to four lines on a phone can never be clipped. */
@media (max-width: 809.98px) {
  .v-studio-cta {
    height: auto;
    min-height: 567px;
    padding: 72px 0;
  }
  .v-studio-cta__inner { padding: 0 24px; gap: 16px; }
  .v-studio-cta__title { max-width: 100%; }
  .v-studio-cta__lede  { font-size: 15px; }
}

@media (prefers-reduced-motion: reduce) {
  .v-studio-cta__btn,
  .v-studio-cta__btn svg { transition: background-color .3s ease, color .3s ease; }
  .v-studio-cta__btn:hover { transform: none; }
  .v-studio-cta__btn:hover svg { transform: none; }
}
