/* ==========================================================================
   Centered header
   Replaces the Divi header: logo centred over a centred nav, no burger.
   Ported from the shadcn NavigationMenu + RandomLetterSwap components to
   plain CSS so it runs in these static pages with no build step.
   ========================================================================== */

:root {
  --st-header-pad: 30px;
  --st-header-pad-scrolled: 14px;

  /* Fluid scale. The header is ONE ROW at every viewport - it never wraps and
     never becomes a burger - so the sizes do the adapting. Each value
     interpolates continuously with the viewport instead of stepping at
     breakpoints, which means there is no width where the row is one pixel away
     from breaking. Endpoints are tuned so the row still fits with the widest
     item set it carries at that width. */
  --st-nav-fs: clamp(11px, 1.19vw + 1.86px, 15px);
  --st-nav-track: clamp(0.06em, 0.13vw + 0.017em, 0.15em);
  --st-nav-px: clamp(6px, 0.74vw + 0.35px, 11px);
  --st-logo-h: clamp(34px, 5.45vw + 13.5px, 92px);
  --st-lang-fs: clamp(8px, 0.3vw + 5.7px, 10px);
  --st-lang-px: clamp(6px, 0.6vw + 1.4px, 10px);
  /* White at rest, because the bar is transparent and the ground behind it is
     the hero photograph. It flips to ink on scroll, further down. */
  --st-nav-fg: rgb(var(--yp-white-rgb) / 0.9);
  --st-nav-fg-hover: var(--yp-white);
  --st-pop-bg: var(--yp-ink);
  --st-pop-border: rgb(var(--yp-white-rgb) / 0.12);
  --st-ink: rgb(var(--yp-ink-rgb) / 0.86);
  --st-ease: cubic-bezier(0.22, 1, 0.36, 1);
}


/* ---- kill Divi's own header colour --------------------------------------
   Divi paints #main-header #282728 from id-scoped rules and swaps in its own
   .et-fixed-header class on scroll. Whichever of those wins for a single frame
   is the black flash between the transparent bar and the milky one. Zeroing
   the colour in every state leaves only the two gradients below in charge.
   background-color specifically, so the gradients in background-image survive. */
body #main-header,
body #main-header.et-fixed-header,
body header#main-header.st-header {
  background-color: transparent !important;
  background-image: none !important;
  /* Divi's inline scroll script still adds .et-fixed-header at 200px, and
     style-static paints a 7px slab shadow on it with !important. That shadow
     appeared on every page at 1024px and up the moment the scroll crossed
     200, on top of the hairline that is meant to do the separating. Same
     weight, same shape, stated once. */
  box-shadow: none !important;
}

/* And the scrolled bar is declared HERE, at the same weight, rather than lower
   down where Divi's rules kept reaching it. Two states, both stated once, in
   one place: transparent over the hero, milky once the page moves. Nothing
   else is allowed an opinion about the header's ground. */
/* The scrolled header must read as the page's own ground, not as a slab laid
   on top of it. It previously ran a Shell-to-Sand gradient at 0.94/0.88: over
   the Divi pages, whose sections are pure white, Sand composited to #f4eee7,
   a 24-point drop on the blue channel, and the bar showed up as a beige band
   across white content. That is the "doesn't blend in".

   One flat Shell at 0.72 instead. The blur behind it means the header borrows
   whatever it is over: on white it composites to #fcf9f7, a 1% step nobody can
   see; on our own Shell sections it is exactly Shell. A vertical gradient on a
   64px bar reads as an object either way, so there isn't one. */
body header#main-header.st-header.st-scrolled,
body #main-header.st-header.et-fixed-header {
  background-color: rgb(var(--yp-shell-rgb) / 0.72) !important;
  background-image: none !important;
}

/* ---- legibility over the hero -------------------------------------------
   Measured, not guessed. Sampling the hero video's own frames behind the nav
   band gave a background luminance between 0.19 and 0.85, so white nav type
   was running at 1.17:1 against the bright frames — the white Bentley and the
   open sky. WCAG wants 4.5:1 for text this size. The hero's own scrim is 0.55
   ink at the top, which only lifts the worst frame to about 2.2:1.

   A text shadow alone cannot fix that, which is what the note below the shell
   rule assumed it would. So the header carries its own gradient: strong at the
   very top, gone by its own bottom edge, so there is no band and no hard line
   to see — it reads as a vignette on the photograph, which is what every
   transparent header over moving footage needs.

   0.55 here composites with the hero's 0.55 to an effective 0.80, which puts
   the worst frame at roughly 3.8:1. Going further would hit 4.5 but start to
   look like the dark bar the design deliberately avoids. */
body header#main-header.st-header::before,
#main-header.st-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(to bottom,
              rgb(var(--yp-ink-rgb) / 0.55) 0%,
              rgb(var(--yp-ink-rgb) / 0.34) 45%,
              rgb(var(--yp-ink-rgb) / 0) 100%);
  transition: opacity 0.5s var(--st-ease);
}

/* Once the milky ground arrives the gradient has nothing to do, and would
   only muddy it. */
body header#main-header.st-header.st-scrolled::before,
#main-header.st-header.et-fixed-header::before,
#main-header.st-header.st-scrolled::before {
  opacity: 0;
}

/* The gradient is a ::before inside the header, so the header's own children
   have to sit above it or the nav ends up underneath the thing meant to make
   it readable. */
body header#main-header.st-header > *,
#main-header.st-header > * {
  position: relative;
  z-index: 1;
}

/* ---- shell -------------------------------------------------------------- */

/* The selector is this long on purpose. Divi's inline block carries
   `.home header#main-header { background: transparent }`, which has the same
   id and class count as a plain `#main-header.st-header` but one extra element
   selector, so it outranks it and blanked the bar on the home page only.
   Matching its shape is the fix. */
body header#main-header.st-header,
#main-header.st-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 99999;
  padding: var(--st-header-pad) 0;
  /* At rest: nothing at all. The bar blends into the hero rather than sitting
     on it, so the photograph runs unbroken to the top of the page. Both a dark
     scrim and a white wash read as a band; transparency reads as no bar.

     The type carries its own legibility instead, via the shadow below, and
     flips to ink once the milky ground arrives on scroll. */
  background: transparent;
  box-shadow: none;
  border-bottom: 1px solid transparent;
  transition: padding 0.45s var(--st-ease), background 0.5s var(--st-ease),
    border-color 0.45s var(--st-ease), backdrop-filter 0.5s var(--st-ease);
}

/* Scrolled: milky frosted glass in the brand's warm off-white, not a black
   bar. The page shows through softly instead of being cut off. Because the
   ground goes light, the mark and nav flip to near-black - see below. */
/* Divi adds its own .et-fixed-header on scroll and paints it #282728 from an
   id-scoped rule, which outranked a plain class selector and put the dark bar
   back the moment the page moved. Matching its shape, and naming Divi's class
   too, is what holds the milky ground. */
body header#main-header.st-header.st-scrolled,
#main-header.st-header.et-fixed-header,
#main-header.st-header.st-scrolled {
  padding: var(--st-header-pad-scrolled) 0;
  background: rgb(var(--yp-shell-rgb) / 0.72);
  /* saturate() is dropped: pushing the chroma of whatever scrolls under a
     header is what made white page content look tinted through it. Blur only,
     so the bar reads as frosted page rather than as a colour of its own. */
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  /* A hairline does the separating. The 24px slab shadow underneath it was
     the second half of the band: a soft beige smear on white. */
  border-bottom-color: rgb(var(--yp-ink-rgb) / 0.09);
  box-shadow: none;
}

/* Type and mark invert on the milky ground. The logo file is pure white on
   transparent, so invert(1) yields true black with the alpha untouched -
   no second asset needed. */
#main-header.st-scrolled .st-nav-link { color: var(--st-ink); }
#main-header.st-scrolled .st-nav-link:hover,
#main-header.st-scrolled .st-nav-link:focus-visible,
#main-header.st-scrolled .st-nav-item[data-open="true"] > .st-nav-link {
  color: var(--yp-ink);
  background: rgb(var(--yp-white-rgb) / 0.1);
}
#main-header.st-scrolled .st-nav-item.st-current > .st-nav-link { color: var(--yp-ink); }
#main-header.st-scrolled .st-logo img { filter: invert(1); }
/* The mark ships white on transparent, which is right at rest over the hero.
   It inverts only once the milky ground arrives, handled above. */
#main-header.st-scrolled .st-nav-link:focus-visible {
  outline-color: rgb(var(--yp-ink-rgb) / 0.55);
}

/* Dropdown follows the light ground so it does not read as a stray dark box. */
#main-header.st-scrolled .st-dropdown {
  background: rgb(var(--yp-shell-rgb) / 0.97);
  border-color: rgb(var(--yp-ink-rgb) / 0.12);
  box-shadow: 0 18px 40px -14px rgb(var(--yp-ink-rgb) / 0.28);
}
#main-header.st-scrolled .st-dropdown a { color: rgb(var(--yp-ink-rgb) / 0.72); }
#main-header.st-scrolled .st-dropdown a:hover,
#main-header.st-scrolled .st-dropdown a:focus-visible {
  color: var(--yp-ink);
  background: rgb(var(--yp-white-rgb) / 0.1);
}

/* Logo and nav share ONE row, vertically centred on each other.
   The container is wider than the page grid (1400 vs 1240) because at the
   requested sizes - logo ~203px wide, nav ~980px - the pair needs about
   1183px of run, which a 1180px content width cannot give. */
.st-header-inner {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  width: 100%;
  max-width: 1460px;
  margin: 0 auto;
  padding: 0 30px;
}

.st-logo-corner {
  flex: 0 0 auto;   /* never let the nav squeeze the logo */
}

/* ---- logo --------------------------------------------------------------- */

.st-logo {
  display: block;
  line-height: 0;
  transition: transform 0.45s var(--st-ease), opacity 0.3s ease;
}

.st-logo img {
  display: block;
  width: auto;
  height: var(--st-logo-h);
  /* filter too: the mark inverts white to black on scroll, and without this
     it snapped to black in one frame while the ground behind it was still
     fading in over 0.5s, so for a moment it sat black on the dark hero. */
  transition: height 0.45s var(--st-ease), filter 0.25s var(--st-ease);
}

#main-header.st-scrolled .st-logo img { height: calc(var(--st-logo-h) * 0.66); }
.st-logo:hover { opacity: 0.82; }

/* ---- nav ---------------------------------------------------------------- */

/* Nav flush left, sharing the logo's left edge.
   The links carry 14px of horizontal padding, so the list box starts 14px to
   the LEFT of the first letterform. Pulling the list back by that amount makes
   the "H" of HOME sit on the same vertical as the logo's left edge - optical
   alignment, not box alignment. --st-nav-pad must track the padding in
   .st-nav-link below. */
:root { --st-nav-pad: var(--st-nav-px); }

.st-nav { display: flex; justify-content: flex-end; flex: 1 1 auto; min-width: 0; }

.st-nav-list {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  justify-content: flex-end;
  gap: 5px;
  margin: 0 calc(-1 * var(--st-nav-pad)) 0 0;
  padding: 0;
  list-style: none;
}

.st-nav-item { position: relative; }

/* One shared look for links and dropdown triggers so they sit on a single
   optical baseline regardless of which element type they are. */
.st-nav-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 8px var(--st-nav-px);
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--st-nav-fg);
  font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  font-size: var(--st-nav-fs);
  font-weight: 500;
  line-height: 1;
  letter-spacing: var(--st-nav-track);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.25s ease, background-color 0.25s ease, text-shadow 0.25s ease;
  /* No scrim behind the bar any more, so the type carries its own separation
     from whatever frame of the hero video happens to be underneath it. */
  /* Two shadows: a tight one that gives every glyph its own edge against a
     bright frame, and a wide soft one that lifts the whole word off the
     photograph. A single 12px blur at 0.55 was too diffuse to define the
     letterforms, which is why the nav still washed out over the pale frames
     even with the gradient behind it. */
  text-shadow: 0 1px 2px rgb(var(--yp-ink-rgb) / 0.55),
               0 2px 18px rgb(var(--yp-ink-rgb) / 0.45);
}

/* Once the milky ground is there, the shadow is not only unnecessary, it is
   visible as a smudge. */
#main-header.st-scrolled .st-nav-link,
body.st-solid-header #main-header .st-nav-link { text-shadow: none; }

.st-nav-link:hover,
.st-nav-link:focus-visible,
.st-nav-item[data-open="true"] > .st-nav-link {
  color: var(--st-nav-fg-hover);
  background: rgb(var(--yp-white-rgb) / 0.1);
}

.st-nav-link:focus-visible {
  /* currentColor: White over the hero, Ink once the ground goes light. A fixed
     ink ring was invisible against the hero scrim. */
  outline: 1px solid currentColor;
  outline-offset: 2px;
}

.st-nav-item.st-current > .st-nav-link { color: var(--st-nav-fg-hover); }

.st-nav-phone { letter-spacing: 1.5px; }

.st-chevron {
  width: 11px;
  height: 11px;
  opacity: 0.6;
  transition: transform 0.3s var(--st-ease);
}

.st-nav-item[data-open="true"] .st-chevron { transform: rotate(180deg); }

/* ---- dropdown ----------------------------------------------------------- */

.st-dropdown {
  position: absolute;
  top: calc(100% + 10px);
  left: 50%;
  z-index: 50;
  min-width: 232px;
  padding: 6px;
  border: 1px solid var(--st-pop-border);
  border-radius: 10px;
  background: var(--st-pop-bg);
  box-shadow: 0 18px 40px -12px rgb(var(--yp-ink-rgb) / 0.65);
  opacity: 0;
  visibility: hidden;
  transform: translateX(-50%) translateY(-6px) scale(0.96);
  transform-origin: top center;
  transition: opacity 0.2s ease, transform 0.2s var(--st-ease), visibility 0.2s;
}

.st-nav-item[data-open="true"] > .st-dropdown {
  opacity: 1;
  visibility: visible;
  transform: translateX(-50%) translateY(0) scale(1);
}

/* Hover bridge: without it the gap between trigger and panel closes the
   dropdown as the pointer travels down to it. */
.st-dropdown::before {
  content: "";
  position: absolute;
  top: -12px;
  left: 0;
  width: 100%;
  height: 12px;
}

.st-dropdown ul { margin: 0; padding: 0; list-style: none; }

.st-dropdown a {
  display: block;
  padding: 9px 12px;
  border-radius: 6px;
  color: rgb(var(--yp-white-rgb) / 0.7);
  font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.2s ease, background-color 0.2s ease;
}

.st-dropdown a:hover,
.st-dropdown a:focus-visible {
  color: var(--yp-white);
  background: rgb(var(--yp-white-rgb) / 0.09);
}

/* ---- random letter swap ------------------------------------------------- */
/* Each character is a 2-deep stack of the same glyph in an overflow-hidden
   box. On hover the stack slides up exactly one glyph, so the letter appears
   to flip to itself. Per-letter delays are randomised in JS, which is what
   turns a uniform slide into the scattered ripple. */

.rls { display: inline-flex; }

/* The labels live in data-rls and header.js builds them, but header.js is the
   last of ~30 blocking scripts at the end of <body>, so the bar painted with
   an empty nav until all of them had run, and stays empty if the script never
   does. Until the anchor has children the label is drawn from the attribute;
   the moment buildSwap fills it, :empty stops matching and this steps aside.
   Same 1.15em box as .rls-char, so the row does not change height on handover. */
.st-nav-link:empty::before {
  content: attr(data-rls);
  line-height: 1.15em;
}

.rls-char {
  display: inline-block;
  height: 1.15em;
  overflow: hidden;
  line-height: 1.15em;
}

.rls-stack {
  display: flex;
  flex-direction: column;
  transition: transform 0.6s var(--st-ease);
  transition-delay: var(--rls-out, 0s);
}

.rls-stack > span { display: block; height: 1.15em; line-height: 1.15em; }

.st-nav-link:hover .rls-stack,
.st-nav-link:focus-visible .rls-stack {
  transform: translateY(-50%);
  transition-delay: var(--rls-in, 0s);
}

@media (prefers-reduced-motion: reduce) {
  .rls-stack,
  .st-dropdown,
  .st-chevron,
  #main-header.st-header,
  #main-header.st-header::before,
  .st-logo,
  .st-logo img,
  .st-nav-link,
  .st-lang,
  .st-lang-btn {
    transition-duration: 0.01ms !important;
    transition-delay: 0s !important;
  }
}

/* ---- responsive: one row, always -----------------------------------------
   The header never wraps and never becomes a burger, so at every width the row
   has to genuinely fit. The fluid tokens carry the full six-item set from 1920
   down to about 1200. Below that the least load-bearing items leave, rather
   than the row breaking: the phone first (it repeats in the footer and on the
   contact page), then the deepest dropdown sections on phones.

   :has() is doing the selecting so the shedding schedule lives entirely in CSS
   and the 24 pages of markup stay untouched. */

@media (max-width: 820px) {
  :root { --st-header-pad: 20px; --st-header-pad-scrolled: 12px; }
}


@media (max-width: 580px) {
  .st-header-inner { padding: 0 16px; gap: 12px; }
  .st-dropdown { min-width: 200px; }
}

/* Five items, and "Buy" and "Sell" are the shortest labels the row has ever
   carried at roughly 40px each. That buys back enough room that only the two
   long items need to shed at all: the phone, which repeats in the footer, and
   Our Listings. Buy and Sell stay at every width, which is the point of them.
   Re-check these if NAV changes again: the row is required to stay on one
   line at every viewport. */
@media (max-width: 760px) {
  .st-nav-item:has(> .st-nav-phone) { display: none; }
}

/* 520, not 470: measured, five labels touch the mark from 471 up to about
   510. The sweep sampled 540 then 430 and never saw the band between. */
@media (max-width: 520px) {
  .st-nav-item:has([data-rls="Our Listings"]) { display: none; }
}

/* 320 to 350: the oldest phones still in use. Four labels plus the toggle
   need about 36px more row than there is, and the row overflows LEFT, under
   the logo, with no scrollbar to give it away. Home goes: the logo beside it
   is already the home link. */
/* Phones. Before Montserrat lands the fallback sans sets about 10px wider,
   and for that moment the row touched the mark at 390, the commonest phone
   width there is. Tighter link padding and list gap buy back 25px, so the
   row clears the logo in both font states without shedding another label. */
@media (max-width: 400px) {
  :root { --st-nav-px: 4px; }
  .st-nav-list { gap: 2px; }
}

@media (max-width: 385px) {
  .st-nav-item:has([data-rls="Home"]) { display: none; }
}

/* 320: three labels still touch the mark by a few px. About goes (it is in
   the footer on every page) and the row gives back its spare gutter. Both
   languages: the Spanish row is down to Comprar and Vender here and was 7px
   short for the same reason. */
@media (max-width: 335px) {
  .st-nav-item:has([data-rls="About"]) { display: none; }
  .st-header-inner { padding: 0 12px; gap: 8px; }
}

/* Spanish. The rule above is keyed on the English label, and build-es.py
   translates data-rls, so on es/ pages nothing shed at all and the row ran
   left, underneath the logo. It overflowed without wrapping and without a
   scrollbar, which is why the sweep never flagged it. The Spanish labels are
   also about 70% longer, so the same row needs its own schedule, starting
   with the phone going a little earlier than it does in English. Comprar and
   Vender stay at every width, same as Buy and Sell. */
@media (max-width: 860px) {
  :lang(es) .st-nav-item:has(> .st-nav-phone) { display: none; }
}

@media (max-width: 760px) {
  :lang(es) .st-nav-item:has([data-rls="Propiedades"]) { display: none; }
}

@media (max-width: 560px) {
  :lang(es) .st-nav-item:has([data-rls="Inicio"]) { display: none; }
}

@media (max-width: 460px) {
  :lang(es) .st-nav-item:has([data-rls^="Sobre"]) { display: none; }
}

/* On hero pages the bar floats over the artwork, so the hero must start at
   the very top. Divi's script reserves a header-height gap on every page,
   which on these pages shows as a white band behind the logo. Zero it out and
   let the hero run full-bleed; .st-solid-header pages keep their reservation
   and have it re-measured in header.js. */

body:not(.st-solid-header) #page-container { padding-top: 0 !important; }

/* ---- solid variant ------------------------------------------------------
   Pages whose first section is plain content, not a hero, have nothing dark
   behind the header - white nav on a white page is invisible. Those pages
   carry .st-solid-header on <body> and get an opaque bar from the start. */

/* Inner pages have no hero behind the bar, so they wear the milky treatment
   from the start rather than a black slab. */
body.st-solid-header #main-header.st-header {
  /* Identical to the scrolled ground above, on purpose: one milky recipe, so a
     solid page at rest and a hero page once scrolled are the same bar. */
  background: rgb(var(--yp-shell-rgb) / 0.72);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  border-bottom-color: rgb(var(--yp-ink-rgb) / 0.09);
}

body.st-solid-header #main-header .st-nav-link { color: var(--st-ink); }
body.st-solid-header #main-header .st-nav-link:hover,
body.st-solid-header #main-header .st-nav-link:focus-visible,
body.st-solid-header #main-header .st-nav-item[data-open="true"] > .st-nav-link {
  color: var(--yp-ink);
  background: rgb(var(--yp-white-rgb) / 0.1);
}
body.st-solid-header #main-header .st-nav-item.st-current > .st-nav-link { color: var(--yp-ink); }
body.st-solid-header #main-header .st-logo img { filter: invert(1); }
body.st-solid-header #main-header .st-dropdown {
  background: rgb(var(--yp-shell-rgb) / 0.97);
  border-color: rgb(var(--yp-ink-rgb) / 0.12);
  box-shadow: 0 18px 40px -14px rgb(var(--yp-ink-rgb) / 0.28);
}
body.st-solid-header #main-header .st-dropdown a { color: rgb(var(--yp-ink-rgb) / 0.72); }
body.st-solid-header #main-header .st-dropdown a:hover { color: var(--yp-ink); background: rgb(var(--yp-white-rgb) / 0.1); }

/* ---- suppress the Divi header we replaced -------------------------------- */


#main-header .mobile-side-menu1,
#main-header #et_mobile_nav_menu,
#main-header .mobile-social-box,
#main-header #mySidenav,
#main-header .et_search_outer,
#main-header #et-top-navigation,
#main-header .logo_container { display: none !important; }

/* ---- language toggle -----------------------------------------------------
   Sits at the far right of the header row, past the nav.

   Colours run off four variables rather than three repeated rule blocks. The
   bar has three grounds - dark scrim over the hero, milky once scrolled, and
   milky from the start on .st-solid-header pages - and every element above
   that ignored this ended up with its states restated three times. Each light
   ground here only re-points the variables.

   Both sides are live links: tools/build-es.py wires each one to the same
   page in the other language and marks the current one aria-current. */

:root {
  --st-lang-fg: rgb(var(--yp-white-rgb) / 0.62);
  --st-lang-fg-active: var(--yp-ink);
  --st-lang-bg-active: rgb(var(--yp-white-rgb) / 0.92);
  --st-lang-border: rgb(var(--yp-white-rgb) / 0.3);
}

#main-header.st-scrolled,
body.st-solid-header #main-header {
  --st-lang-fg: rgb(var(--yp-ink-rgb) / 0.66);
  --st-lang-fg-active: var(--yp-shell);
  --st-lang-bg-active: rgb(var(--yp-ink-rgb) / 0.88);
  --st-lang-border: rgb(var(--yp-ink-rgb) / 0.20);
}

.st-lang {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  margin-left: 4px;
  padding: 3px;
  border: 1px solid var(--st-lang-border);
  border-radius: 999px;
  transition: border-color 0.45s var(--st-ease);
}

/* An anchor now, not a button: each side navigates to the same page in the
   other language, so it is a link and has to say so to assistive tech. The
   reset below is what an <a> needs and a <button> did not. */
.st-lang-btn {
  display: inline-block;
  text-decoration: none;
  -webkit-appearance: none;
  appearance: none;
  padding: 5px var(--st-lang-px);
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--st-lang-fg);
  font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  font-size: var(--st-lang-fs);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  cursor: pointer;
  transition: color 0.25s ease, background-color 0.25s ease;
}

/* aria-current is the correct state for "this is the page you are on"; the
   older aria-pressed selector is kept so the toggle still renders on any page
   that has not been regenerated yet. */
.st-lang-btn[aria-current="true"],
.st-lang-btn.is-active,
.st-lang-btn[aria-pressed="true"] {
  background: var(--st-lang-bg-active);
  color: var(--st-lang-fg-active);
}

/* An inactive side has no fill, so its hover colour has to resolve against the
   bar, not against the active pill: --st-lang-fg-active is Ink over the hero
   scrim and Shell on the milky bar, and both vanish there. Fifth variable,
   re-pointed per ground like the other four. */
:root { --st-lang-fg-hover: var(--yp-white); }
#main-header.st-scrolled,
body.st-solid-header #main-header { --st-lang-fg-hover: var(--yp-ink); }

.st-lang-btn:hover:not([aria-disabled="true"]),
.st-lang-btn:focus-visible { color: var(--st-lang-fg-hover); }

/* The active side sits on its own pill and keeps the on-pill colour. */
.st-lang-btn.is-active:hover,
.st-lang-btn.is-active:focus-visible,
.st-lang-btn[aria-current="true"]:hover,
.st-lang-btn[aria-current="true"]:focus-visible,
.st-lang-btn[aria-pressed="true"]:hover,
.st-lang-btn[aria-pressed="true"]:focus-visible { color: var(--st-lang-fg-active); }

/* The ring is drawn outside the pill, on the bar, so it takes the bar colour. */
.st-lang .st-lang-btn:focus-visible { outline-color: var(--st-lang-fg-hover); }

/* Both languages are live. The disabled styling is kept only because it is
   the correct rendering if a language is ever taken offline; nothing on the
   site carries aria-disabled now. */
.st-lang-btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }
.st-lang-btn[aria-disabled="true"]:hover { color: var(--st-lang-fg); }

.st-lang-btn:focus-visible { outline: 1px solid currentColor; outline-offset: 2px; }

/* ---- touch targets --------------------------------------------------------
   The row is drawn small on purpose (11px type, a 26px pill) but a finger
   needs 44. The hit area grows on a pseudo-element, not on the control, so
   the type, the hover pill and the focus ring stay exactly where they are.
   The bar is 53px at its shortest, so 44 always fits inside it. Coarse
   pointers only: a mouse should hover the pill it can see. */
@media (pointer: coarse) {
  .st-nav-link,
  .st-lang-btn { position: relative; }

  .st-nav-link::after,
  .st-lang-btn::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 0;
    right: 0;
    height: 44px;
    transform: translateY(-50%);
  }
}

/* ---- skip link ------------------------------------------------------------
   First focusable element on every page. Off-screen until it takes keyboard
   focus, then it sits above the fixed bar (99999). Divi resets
   `:focus { outline: 0 }` site-wide, so the ring is stated here. */
.yp-skip {
  position: fixed;
  top: 8px;
  left: 8px;
  z-index: 100000;
  padding: 12px 18px;
  background: var(--yp-ink);
  color: var(--yp-white);
  font-family: "Montserrat", "Inter", "Helvetica Neue", Arial, sans-serif;
  font-size: 12px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  transform: translateY(-300%);
}
.yp-skip:focus {
  transform: translateY(0);
  color: var(--yp-white);
  outline: 2px solid var(--yp-white);
  outline-offset: 2px;
}
#main-content { scroll-margin-top: 96px; }
