/* ==========================================================================
   Site navigation

   Restyles the existing navbar markup rather than replacing it, so every link,
   dropdown and Bootstrap data-toggle keeps working exactly as before.

   Two states:
     .site-nav                  interior pages - solid, sticky
     .site-nav--overlay         home - transparent over the hero slider
     .site-nav.is-stuck         either one, once the page is scrolled: solid,
                                fixed to the top, with a shadow

   Everything is scoped under .site-nav so it cannot leak into the three CSS
   frameworks the site already loads.
   ========================================================================== */

.site-nav {
  --nav-purple: #7f3f98;
  --nav-ink:    #000;
  --nav-soft:   #6d6577;
  --nav-line:   #ece8f0;
  --nav-sand:   #faf7f2;

  display: flex;
  align-items: center;
  gap: 24px;
  width: 100%;
  padding: 10px 32px !important;
  /* Sand rather than white: the pages sit on #faf7f2, and a white bar reads as
     a slab laid on top of them. */
  background: var(--nav-sand);
  border-bottom: 1px solid var(--nav-line);
  transition: background-color .28s ease, box-shadow .28s ease, padding .28s ease;
}

/* Home: sits over the hero.
   Deliberately no top/left. Absolute positioning without offsets leaves the
   bar at its static position -- which is exactly where the slider starts, so
   it lands inside the hero image. Setting top:0 pulls it out to the top of
   the page instead, above the hero, which is not what this design wants. */
.site-nav--overlay {
  position: absolute;
  z-index: 1030;
  background: transparent;
  border-bottom-color: transparent;
}

/* A scrim behind the bar, so the white links have something to sit on.

   The hero photo is an aerial with a big sky, and the strip the bar covers
   averages rgb(171,198,215) -- white type on it measures 1.78:1, well under
   the 4.5:1 it needs. A text-shadow alone cannot close a gap that size, so the
   ground is darkened instead. Measured: this tint needs alpha .48 through the
   height of the bar to clear 4.5:1, which is what the first two stops hold
   before the long fade out.

   Deep blue rather than neutral grey: at the same luminance weight it reads as
   a richer sky continuing the photo, where a grey wash reads as a smudge over
   it. It costs .04 more alpha than neutral would.

   The fade runs well past the bar (bottom: -140px) so it dissolves into the
   photo instead of ending on a visible edge. */
.site-nav--overlay:not(.is-stuck)::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: -140px;
  background: linear-gradient(to bottom,
              rgba(9, 38, 66, .60) 0%,
              rgba(9, 38, 66, .48) 40%,
              rgba(9, 38, 66, .22) 70%,
              rgba(9, 38, 66, 0) 100%);
  pointer-events: none;
  z-index: -1;
}


/* Scrolled: pinned, solid, lifted.

   The bar starts translated out of view and slides in, rather than appearing
   the instant the trigger is crossed. Two classes are needed because you
   cannot transition between position values: .is-stuck does the repositioning,
   .is-shown (added by nav.js on the next frame) drives the movement.
   Removing .is-shown leaves the bar parked off-screen, which reads as the
   sticky behaviour being broken. */
.site-nav.is-stuck {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 1040;
  transform: translateY(-100%);
  /* Frosted sand: content scrolling underneath tints through rather than being
     cut off by an opaque band. */
  background: rgba(250, 247, 242, .86);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom-color: rgba(43, 37, 48, .07);
  box-shadow: 0 1px 0 rgba(43, 37, 48, .04), 0 8px 24px rgba(43, 37, 48, .07);
  padding-top: 6px !important;
  padding-bottom: 6px !important;
  transition: transform .34s cubic-bezier(.22, .61, .36, 1),
              background-color .34s ease,
              box-shadow .34s ease,
              padding .34s ease;
}
.site-nav.is-stuck.is-shown { transform: translateY(0); }

/* Without backdrop-filter the translucency would leave text over live content. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .site-nav.is-stuck { background: var(--nav-sand); }
}

/* ------------------------------------------------------------------- hero */

/* Full page rather than a 690px banner. Matched with the general sibling
   combinator (~) rather than the adjacent one (+): the search overlay is
   rendered between the bar and the hero, and + silently stops matching the
   moment anything is inserted in between. */
.site-nav--overlay ~ .main-slider {
  position: relative;
  box-sizing: border-box;
  height: 100vh;
  height: 100svh;
  min-height: 560px;
  /* Equal top and bottom padding. Padding only on the top would shift the
     centred contents down by half of it, which is what made the logo sit low.
     Symmetric padding keeps it centred and still guarantees clearance from
     the floating bar on short screens. */
  padding: 96px 0;
  /* The site stylesheet points this at https://sayulita.com/... , so the local
     site was loading the old banner off the live server. Relative path now, so
     each environment uses its own copy.

     Encoded from the uploaded PNG, which was 2.5 MB -- far too heavy for the
     one image that blocks the hero from appearing. JPEG q82 is 292 KB at
     34.3 dB PSNR (no visible difference), WebP q80 is 221 KB. The plain
     declaration comes first so anything that does not understand image-set()
     still gets the JPEG. */
  background-image: url('../../images/pages/slider/hero-bg.jpg') !important;
  background-image: image-set(
      url('../../images/pages/slider/hero-bg.webp') type('image/webp'),
      url('../../images/pages/slider/hero-bg.jpg')  type('image/jpeg')) !important;
  background-size: cover !important;
  background-position: center !important;
  background-color: #0d3b52;
}

.main-slider .hero-figure {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  margin: 0;
  width: 100%;
  text-align: center;
  /* Nudged right and dropped below centre, so the logo sits over the open bay
     rather than across the headland and the village. Applied here rather than
     on .hero-logo, which runs a transform-based entrance animation that would
     overwrite it.

     The drop is worth ~11% of the hero's height, putting the logo's centre at
     about 61% down. That is the calmest water in the frame: measured across
     the logo's own width, luminance std dev falls from 10.5 at dead centre to
     7.9-8.9 through the 50-65% band, so there is less detail fighting the
     letterforms. Contrast is not the reason -- it sits between 5.3:1 and
     5.7:1 wherever it goes below the sky.

     Both offsets are clamped so they scale with the viewport but never push
     the logo into the scroll cue or off the edge on a small window. */
  transform: translate(clamp(0px, 6vw, 110px), clamp(0px, 10vh, 104px));
}



.main-slider .hero-logo {
  margin: 0;
  line-height: 0;
  font-size: 0;              /* kills the inline-image baseline gap */
  animation: heroRise 1s .18s both cubic-bezier(.22, .61, .36, 1);
}
.main-slider .hero-logo img {
  display: block;
  /* The file is 1536x1024 but the artwork inside it is 1472x476 - roughly 27%
     of the canvas is transparent padding above and below. Left alone that
     empty space is laid out too, making the logo 733px tall at this width.
     Setting the box to the artwork's own ratio and cropping to it removes the
     padding from the layout without touching the file. */
  width: min(1100px, 92vw);
  aspect-ratio: 1472 / 476;
  height: auto;
  object-fit: cover;
  /* No drop-shadow: this artwork carries its own glow. */
}



@keyframes heroRise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* A quiet cue that there is more below, which a full-height hero needs. */
.main-slider .hero-scroll {
  position: absolute;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  width: 26px;
  height: 42px;
  padding-top: 8px;
  border: 2px solid rgba(255, 255, 255, .75);
  border-radius: 999px;
  animation: heroRise 1s .5s both ease;
}
.main-slider .hero-scroll span {
  display: block;
  width: 4px;
  height: 8px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .95);
  animation: heroScroll 1.9s ease-in-out infinite;
}
.main-slider .hero-scroll:hover { border-color: #fff; }

@keyframes heroScroll {
  0%, 100% { transform: translateY(0);    opacity: 1; }
  55%      { transform: translateY(13px); opacity: .25; }
}

@media (max-width: 991px) {
  .site-nav--overlay ~ .main-slider { padding: 76px 0; min-height: 480px; }
  /* No sideways offset on a phone -- there is no room for it -- but a much
     larger downward drop than desktop, so the wordmark clears the town and the
     jungle and sits over the surf.

     8vh puts its centre at about 60% down -- just below centre, matching the
     desktop treatment, and clear of the busy strip of boats and palapas along
     the sand. 24vh and 18vh both sat too low.

     On contrast: this is display artwork about 114px tall, so the threshold
     that applies is WCAG's large-text 3:1, not the 4.5:1 used for body copy.
     Across the 22% framing this band reads 4.39:1, and contrast improves the
     higher it goes (3.95:1 at 68%, 7.07:1 at dead centre) -- so nothing here
     is constrained by legibility. Position is a compositional choice; raise or
     lower it by changing this one value. */
  .main-slider .hero-figure { gap: 12px; transform: translateY(clamp(0px, 8vh, 80px)); }
  .main-slider .hero-logo img { width: min(680px, 90vw); }
  .main-slider .hero-scroll { bottom: 18px; }
}

/* Portrait screens crop this photo hard.
 *
 * The hero is a 1.78:1 landscape aerial, and `cover` on a tall narrow viewport
 * scales it to fill the height -- so a phone sees only the middle 26% of the
 * frame. That slice is open water: the beach, the surf line, the boats and the
 * village all fall outside it, leaving a near-empty blue rectangle.
 *
 * Moving the focal point left brings the bay back into shot. Measured across
 * candidate positions, the variation inside the visible window climbs from
 * 11.6 at centre to 16.4 here and then plateaus, so this recovers most of what
 * the crop can give back. At 28% a phone frames x 21%-47% of the photo: the
 * beach curve, the surf, and the edge of the village.
 *
 * Keyed to aspect ratio rather than width, because the problem is the shape of
 * the viewport, not its size -- a phone held sideways is already fine and is
 * deliberately left alone. The !important matches the base rule's.
 */
@media (max-aspect-ratio: 1 / 1) {
  .site-nav--overlay ~ .main-slider {
    /* Crop the sky.
     *
     * With `cover` on a tall viewport the height is the constraining axis --
     * the image is scaled until it fills vertically, so the whole frame top to
     * bottom is on screen and roughly a fifth of it is empty sky.
     * background-position-y cannot help, because there is no vertical overflow
     * to slide. Scaling to 118% of the container height creates that overflow,
     * and anchoring to the bottom spends it all on the sky.
     *
     * A phone now frames y 15%-100% instead of 0%-100%: the horizon survives
     * as a band along the top, and the beach fills the rest. This also darkens
     * the strip behind the nav -- bare white type over it goes from 1.78:1 to
     * 3.28:1, before the scrim is counted.
     */
    background-size: auto 118% !important;
    background-position: 22% 100% !important;
  }

  /* The portrait logo.
   *
   * slider.php serves a different file here through <picture>: the sun stacked
   * over the script at 900:693, rather than the wide 1472:476 wordmark, which
   * shrinks to an illegible strip on a phone.
   *
   * The desktop rule crops its image to the wordmark's ratio with object-fit:
   * cover, to strip the transparent padding baked into that file. Applying that
   * here would slice the top and bottom off this one, so both the ratio and the
   * fit are reset: contain, at the artwork's own proportions, nothing cropped.
   *
   * Sized by width so it scales with the screen and centred by the flex column
   * on .hero-figure. 66vw gives about 257x194 on a 390px phone -- present
   * without dominating -- and the 320px cap stops it ballooning on a tablet
   * held upright. */
  .main-slider .hero-logo img {
    width: min(360px, 76vw);
    height: auto;
    aspect-ratio: 900 / 693;
    object-fit: contain;
    /* The lower 40% of this artwork is the white script, and on a phone it
       lands on the wave wash: the background there averages rgb(126,153,155),
       giving white 3.01:1 -- the bare floor for large text -- and about 16% of
       that area is bright foam where it is far worse.
    
       A drop-shadow rather than a box or a scrim: it is generated from the
       alpha channel, so it hugs the letterforms and the sun instead of putting
       a visible panel on the photo. Two layers do different jobs -- a tight,
       fairly opaque one to draw the edge, and a wider soft one to lift the
       whole mark off the foam. Tinted with the same deep blue as the nav scrim
       so it reads as shade in the photo rather than as grey haze. */
    filter:
      drop-shadow(0 1px 2px rgba(9, 38, 66, .55))
      drop-shadow(0 4px 14px rgba(9, 38, 66, .45));
  }
}

@media (prefers-reduced-motion: reduce) {
  .main-slider .hero-logo,
  .main-slider .hero-scroll { animation: none; }
  .main-slider .hero-scroll span { animation: none; }
}

/* ------------------------------------------------------------------ brand */

/* A flex box that wraps the image exactly. The earlier line-height:0 collapsed
   this box around an inline image, so the bar ended up shorter than the logo
   and the logo looked cut off at the bar's edge. */
.site-nav .navbar-brand {
  display: flex;
  align-items: center;
  margin: 0;
  padding: 0;
  flex: 0 0 auto;
}
.site-nav .site-logo {
  display: block;
  max-width: none;   /* never let an inherited max-width scale it down */
  width: auto;
  /* The resting height MUST live here, not only in custom.min.css.
     It used to sit only in that file, which is minified, long-cached, and
     keeps the same filename every deploy -- so a browser holding the previous
     copy got no height rule at all. Combined with width:auto and
     max-width:none above, that renders the logo at its natural 1536x1024.
     That is exactly what went wrong on the live site after this deploy.
     nav.css is a new filename, so nothing has a stale copy of it, and at
     (0,2,0) this also outranks the bare .site-logo rule in custom.min.css. */
  height: 48px;
}
@media (max-width: 991px) { .site-nav .site-logo { height: 44px; } }
@media (max-width: 575px) { .site-nav .site-logo { height: 40px; } }

/* The hero artwork sits on a 1536x1024 canvas that is ~27% transparent padding
   top and bottom. Sized by height alone it would render the wordmark at less
   than half the bar's height. Cropping to the artwork's own ratio fixes that
   without touching the file. */
.site-nav .site-logo--light {
  aspect-ratio: 1472 / 476;
  width: auto;
  object-fit: cover;
}

/* The brand column must never be squeezed by the links or the search box.
   Without this it is a shrinkable flex item, and once the bar runs out of
   room it compresses the logo. The links wrap instead. */
.site-nav .nav-brand-col {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  min-width: 0;
  overflow: visible;
}

/* Home carries both logos and swaps them with the bar's background: the light
   version over the hero photo, the dark version once the bar is pinned on
   white. Only one is ever displayed, so it is announced once. */
.site-nav--overlay .site-logo--light { display: block; }
.site-nav--overlay .site-logo--dark  { display: none; }

.site-nav--overlay.is-stuck .site-logo--light { display: none; }
.site-nav--overlay.is-stuck .site-logo--dark  {
  display: block;
  animation: navLogoIn .28s both ease;
}

@keyframes navLogoIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}
.site-nav .site-logo { transition: height .28s ease; }
.site-nav.is-stuck .site-logo { height: 42px; }

/* ------------------------------------------------------------------ links */

/* Centre the links in the bar.

   The markup carries Bootstrap's .mr-auto on the list, which sets
   margin-right:auto and so pins the links hard against the logo. Auto margins
   on BOTH sides instead makes flexbox split the leftover space evenly, which
   centres the links between the logo and the search box. Overriding rather
   than editing the markup keeps the change in one place.
   .nv-space-btw already contributes justify-content:center. */
.site-nav .navbar-collapse { flex: 1 1 auto; min-width: 0; }

.site-nav .navbar-nav {
  align-items: center;
  gap: 2px;
  flex-wrap: wrap;
  margin-left: auto !important;
  margin-right: auto !important;
}

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

.site-nav .nav-link {
  position: relative;
  padding: 11px 14px !important;
  color: var(--nav-ink);
  /* Uppercase set at 700 with tight tracking reads as a solid block; the
     letterforms run together and the row shouts. 600 with wider tracking is
     the standard fix - the labels stay the same size but separate cleanly. */
  font-family: "Open Sans", -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: .875rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-indent: .1em;          /* cancels the trailing letter-space when centred */
  text-transform: uppercase;
  white-space: nowrap;
  transition: color .18s ease;
}

/* The animated underline that replaces a plain hover colour change. */
.site-nav .nav-link::after {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 4px;
  height: 2px;
  border-radius: 2px;
  background: var(--nav-purple);
  transform: scaleX(0);
  transform-origin: center;
  transition: transform .22s ease;
}
.site-nav .nav-link:hover::after,
.site-nav .nav-item.is-current .nav-link::after { transform: scaleX(1); }

.site-nav .nav-link:hover { color: var(--nav-purple); }
.site-nav .nav-item.is-current .nav-link { color: var(--nav-purple); }

/* Home: white over the hero photo, turning black once the bar is pinned on
   white. The photo's top quarter averages 171/255 -- too bright for white on
   its own, which is what the scrim above exists to fix; the shadow below is
   only there to keep the edges crisp against the sky's detail. */
.site-nav--overlay:not(.is-stuck) .nav-link {
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, .45);
}
.site-nav--overlay:not(.is-stuck) .nav-link:hover,
.site-nav--overlay:not(.is-stuck) .nav-item.is-current .nav-link { color: #fff; }
.site-nav--overlay:not(.is-stuck) .nav-link::after { background: #fff; }

/* Pinned: black, from --nav-ink on the base rule. */
.site-nav--overlay.is-stuck .nav-link { color: #000; }
.site-nav--overlay.is-stuck .nav-link::after { background: #000; }

/* ------------------------------------------------------------- dropdowns */

/* The caret is its own element next to the link, so the label stays a plain
   link and only the arrow opens the menu. Drawn in CSS instead of relying on
   Bootstrap's triangle. */
.site-nav .carret {
  display: inline-block;
  width: 18px;
  height: 18px;
  margin-left: -8px;
  cursor: pointer;
  vertical-align: middle;
}
.site-nav .carret::before,
.site-nav .dropdown-toggle::after { display: none !important; }
.site-nav .carret::after {
  content: "";
  display: block;
  width: 6px;
  height: 6px;
  margin: 4px auto 0;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  transition: transform .2s ease;
  color: var(--nav-soft);
}
.site-nav--overlay:not(.is-stuck) .carret::after { color: rgba(255, 255, 255, .95); }
.site-nav--overlay.is-stuck .carret::after { color: #000; }
.site-nav .carret:hover::after { color: var(--nav-purple); }
.site-nav .show > .carret::after,
.site-nav .carret[aria-expanded="true"]::after { transform: rotate(-135deg); margin-top: 7px; }

.site-nav .dropdown-menu {
  margin-top: 10px;
  padding: 8px;
  min-width: 232px;
  border: 1px solid var(--nav-line);
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 4px 10px rgba(43, 37, 48, .07), 0 20px 44px rgba(43, 37, 48, .14);
}

.site-nav .dropdown-item {
  padding: 10px 14px;
  border-radius: 9px;
  color: var(--nav-ink) !important;
  font-size: .9375rem;
  font-weight: 500;
  letter-spacing: .005em;
  transition: background-color .15s ease, color .15s ease;
}
.site-nav .dropdown-item:hover,
.site-nav .dropdown-item:focus {
  background: #f4eef7;
  color: var(--nav-purple) !important;
}

.site-nav .dropdown-divider { margin: 6px 8px; border-top-color: var(--nav-line); }

/* --------------------------------------------------------- right cluster */

.site-nav .nav-utility {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 0 0 auto;
  /* No auto margin here: the list's auto margins already push this to the
     right edge, and a third auto would split the space three ways and pull
     the links off-centre again. */
}

/* Search ---------------------------------------------------------------

   An icon in the bar that opens a panel underneath, rather than a text field
   wedged between the links and the edge. Deliberately avoids the old
   .search-btn class, which the site stylesheet positions with top:-0.1em and
   height:55px and which pushed the icon below centre.                      */

.site-nav .nav-search-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid var(--nav-line);
  border-radius: 999px;
  background: #f5f4f7;
  color: var(--nav-ink);
  cursor: pointer;
  transition: background-color .18s ease, color .18s ease,
              border-color .18s ease, transform .18s ease;
}
.site-nav .nav-search-toggle svg {
  width: 18px; height: 18px;
  display: block;                 /* no inline baseline gap, so it sits centred */
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}
.site-nav .nav-search-toggle:hover {
  background: var(--nav-purple);
  border-color: var(--nav-purple);
  color: #fff;
  transform: scale(1.05);
}
.site-nav .nav-search-toggle[aria-expanded="true"] {
  background: var(--nav-purple);
  border-color: var(--nav-purple);
  color: #fff;
}

/* Over the hero the bar is transparent, so the button is frosted glass. */
.site-nav--overlay:not(.is-stuck) .nav-search-toggle {
  background: rgba(255, 255, 255, .18);
  border-color: rgba(255, 255, 255, .5);
  color: #fff;
  backdrop-filter: blur(6px);
}

/* ---- the search overlay ----

   A centred card over a dimmed page, in the spirit of a command palette:
   one field, nothing competing with it. Lives outside .site-nav, so its
   selectors are not scoped under it.                                       */

.site-search {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 12vh 20px 20px;
}
.site-search[hidden] { display: none; }

.site-search-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(24, 17, 30, .55);
  backdrop-filter: blur(6px);
  animation: searchFade .22s ease both;
}

.site-search-card {
  position: relative;
  width: min(640px, 100%);
  padding: 10px 10px 0;
  border-radius: 20px;
  background: #fff;
  box-shadow: 0 24px 70px rgba(16, 10, 22, .38), 0 2px 8px rgba(16, 10, 22, .16);
  animation: searchPop .26s cubic-bezier(.22, .61, .36, 1) both;
}

@keyframes searchFade { from { opacity: 0; } to { opacity: 1; } }
@keyframes searchPop {
  from { opacity: 0; transform: translateY(-14px) scale(.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.site-search-card form {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 6px 8px 6px 16px;
}

.site-search-icon {
  width: 21px; height: 21px;
  flex: 0 0 auto;
  fill: none;
  stroke: #9a93a4;
  stroke-width: 2;
  stroke-linecap: round;
}

/* Borderless: the card is the input, which is what keeps it feeling clean. */
.site-search-card input[type="search"] {
  flex: 1 1 auto;
  min-width: 0;
  height: 56px;
  padding: 0;
  border: 0;
  background: transparent;
  color: #1d1a22;
  font-family: "Open Sans", sans-serif;
  font-size: 1.125rem;
  -webkit-appearance: none;
  appearance: none;
}
.site-search-card input[type="search"]:focus { outline: none; }
.site-search-card input[type="search"]::placeholder { color: #a7a0b0; }
.site-search-card input[type="search"]::-webkit-search-cancel-button { -webkit-appearance: none; }

.site-search-go {
  flex: 0 0 auto;
  height: 40px;
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  background: #7f3f98;
  color: #fff;
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color .18s ease;
}
.site-search-go:hover { background: #683180; }

.site-search-close {
  flex: 0 0 auto;
  width: 36px; height: 36px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #8b8394;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  transition: background-color .15s ease, color .15s ease;
}
.site-search-close:hover { background: #f2eff5; color: #1d1a22; }

/* A quiet row of starting points, so the empty state isn't a blank box. */
.site-search-hints {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 16px 14px;
  border-top: 1px solid #ece8f0;
}
.site-search-hints span {
  color: #a7a0b0;
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.site-search-hints a {
  padding: 6px 12px;
  border-radius: 999px;
  background: #f6f4f8;
  color: #4a4351;
  font-size: .8125rem;
  text-decoration: none;
  transition: background-color .15s ease, color .15s ease;
}
.site-search-hints a:hover { background: #f0e8f5; color: #7f3f98; }

@media (max-width: 560px) {
  .site-search { padding: 8vh 12px 12px; }
  .site-search-card form { gap: 8px; padding-left: 12px; }
  .site-search-go { display: none; }   /* Enter submits; the row stays uncluttered */
  .site-search-card input[type="search"] { font-size: 1rem; height: 50px; }
}

@media (prefers-reduced-motion: reduce) {
  .site-search-backdrop, .site-search-card { animation: none; }
}

#google_translate_element { line-height: 1; }

/* ------------------------------------------------------------ hamburger */

.site-nav .navbar-toggler {
  order: -1;
  /* 48px square: the bars read at a glance, and the button meets the minimum
     touch target rather than being a small tap on a phone.

     Deliberately NO display here. Bootstrap hides this button above 992px with
     .navbar-expand-lg .navbar-toggler{display:none} -- specificity (0,2,0),
     exactly the same as .site-nav .navbar-toggler. nav.css loads after
     Bootstrap, so declaring display:flex at this level won the tie and left a
     hamburger sitting on the desktop bar. The flex display is set inside the
     991px block instead, where it belongs. */
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 1px solid var(--nav-line);
  border-radius: 12px;
  background: #fff;
}

/* Belt and braces: state it outright, so the button stays hidden on desktop
   even if Bootstrap's own rule is ever reordered or dropped. */
@media (min-width: 992px) {
  .site-nav .navbar-toggler { display: none !important; }
}
.site-nav--overlay:not(.is-stuck) .navbar-toggler {
  background: rgba(255, 255, 255, .16);
  border-color: rgba(255, 255, 255, .4);
}

/* The three bars, drawn here rather than with an icon font.
 *
 * The markup puts <i class="fas fa-bars"> inside the button, but the site
 * loads Font Awesome from kit.fontawesome.com/a076d05399.js, and that legacy
 * kit now answers 403. The <i> therefore renders nothing at all, leaving a
 * button with no icon in it -- which is what made the menu unrecognisable on
 * a phone. Painting the bars in CSS removes the dependency on a third party
 * for a control the site cannot work without.
 *
 * Two bars are the pseudo-elements, the middle one is a background gradient on
 * the span itself. currentColor makes all three follow the button's colour, so
 * they turn white over the hero and dark once the bar is pinned. */
.site-nav .navbar-toggler-icon > i { display: none; }

.site-nav .navbar-toggler-icon {
  position: relative;
  display: block;
  width: 28px;
  height: 22px;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 28px 3px;
  background-position: center;
  background-repeat: no-repeat;
}
.site-nav .navbar-toggler-icon::before,
.site-nav .navbar-toggler-icon::after {
  content: "";
  position: absolute;
  left: 0;
  width: 28px;
  height: 3px;
  border-radius: 3px;
  background: currentColor;
}
.site-nav .navbar-toggler-icon::before { top: 0; }
.site-nav .navbar-toggler-icon::after  { bottom: 0; }

/* Colour the bars via the button, so both states are set in one place. */
.site-nav .navbar-toggler { color: var(--nav-ink); }
.site-nav--overlay:not(.is-stuck) .navbar-toggler { color: #fff; }

/* ------------------------------------------------------------- responsive */

@media (max-width: 1199px) {
  .site-nav { padding: 10px 20px !important; gap: 14px; }
  .site-nav .nav-link { padding: 10px 10px !important; font-size: .8125rem; letter-spacing: .07em; }
  .site-nav .nav-search input[type="search"] { width: 150px; }
  .site-nav .nav-search input[type="search"]:focus { width: 200px; }
}

@media (max-width: 991px) {
  .site-nav { flex-wrap: wrap; padding: 10px 16px !important; }

  /* The brand row spans the bar, so the hamburger can sit hard against the
     right edge instead of being packed next to the logo on the left. */
  .site-nav .nav-brand-col {
    width: 100%;
    justify-content: flex-end;
  }
  /* The toggler's desktop order:-1 put it left of the logo. This is also where
     the button is switched on -- see the note on the base rule. */
  .site-nav .navbar-toggler { display: flex; order: 2; }
  /* margin-right:auto does the separating, so the row still reads correctly
     when the logo is hidden -- the hamburger simply stays right. */
  .site-nav .navbar-brand { order: 1; margin-right: auto; }

  /* Over the hero, at rest: no logo in the bar at all. The hero already carries
     the wordmark directly below it, so repeating it in the bar is duplication,
     and on a narrow screen the two collide badly. Just the hamburger. */
  .site-nav--overlay:not(.is-stuck) .navbar-brand { display: none; }

  /* Once pinned, the hero is off-screen and the bar needs to identify the site
     again, so the logo returns on the left. 44px rather than the 34px tried
     first, which read as an afterthought next to a 48px hamburger. */
  .site-nav.is-stuck .site-logo { height: 44px; }

  /* The collapsed panel becomes a card under the bar. */
  .site-nav .navbar-collapse {
    width: 100%;
    margin-top: 10px;
    padding: 8px;
    border-radius: 16px;
    background: #fff;
    box-shadow: 0 12px 30px rgba(43, 37, 48, .16);
  }

  .site-nav .navbar-nav { align-items: stretch; gap: 0; width: 100%; }
  .site-nav .nav-item { border-bottom: 1px solid var(--nav-line); }
  .site-nav .nav-item:last-child { border-bottom: 0; }

  /* Bigger tap targets, and the label always reads dark inside the panel. */
  .site-nav .nav-link,
  .site-nav--overlay:not(.is-stuck) .nav-link,
  .site-nav--overlay.is-stuck .nav-link {
    display: inline-block;
    padding: 14px 12px !important;
    font-size: .9375rem;
    letter-spacing: .08em;
    color: var(--nav-ink);
    text-shadow: none;
  }
  .site-nav .nav-link::after { display: none; }

  .site-nav .carret { float: right; margin: 12px 8px 0 0; }
  .site-nav--overlay:not(.is-stuck) .carret::after { color: var(--nav-soft); }

  .site-nav .dropdown-menu {
    margin: 0 0 8px;
    border: 0;
    border-radius: 10px;
    background: #faf9fb;
    box-shadow: none;
  }

  .site-nav .nav-utility { width: 100%; margin: 8px 0 4px; padding: 0 12px; }
  .site-nav .nav-utility form { flex: 1; }
  .site-nav .nav-search,
  .site-nav .nav-search input[type="search"],
  .site-nav .nav-search input[type="search"]:focus { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .site-nav, .site-nav *, .site-nav .site-logo { transition: none !important; animation: none !important; }
}
