/*
 * The site menu (parts/site-menu.php, assets/src/js/menu.js).
 *
 * The page recedes behind frosted glass, the destinations rise, the bubble floats between
 * them as a lens. Always dark, like the hero and the cards, whatever the page beneath.
 * Layout: two columns from 64rem on hover devices (destinations left, the lens home,
 * the pages inside the hovered destination and the panel on the right); one scrolling
 * column everywhere else, with every group listed so nothing depends on hover.
 */

html {
  scrollbar-gutter: stable;
}

html.menu-open {
  overflow: hidden;
}

.site-menu {
  --bh-white: #f7f5fb;
  --bh-muted: #b9b1c4;
  --bh-line: rgb(255 255 255 / 14%);
  --menu-base: #05030a;
  --menu-accent: #18d9ff;
  --menu-side: clamp(17rem, 26vw, 24rem);
  --menu-lens: clamp(8rem, 19vmin, 14rem);
  position: fixed;
  z-index: 39;
  inset: 0;
  color: var(--bh-white);
  visibility: hidden;
  pointer-events: none;
  /* The whole menu is a bubble: it grows from the Menu pill (menu.js sets --menu-x/y to
     the pill's centre on open) and shrinks back into it on close. */
  clip-path: circle(0% at var(--menu-x, 92%) var(--menu-y, 3rem));
  transition: visibility 0s linear 0.55s, clip-path 0.55s var(--bh-ease-glide);
}

.site-menu[data-open="true"] {
  visibility: visible;
  pointer-events: auto;
  clip-path: circle(150% at var(--menu-x, 92%) var(--menu-y, 3rem));
  transition: visibility 0s linear 0s, clip-path 0.85s var(--bh-ease-glide);
}

.site-menu__veil {
  position: absolute;
  inset: 0;
  width: 100%;
  border: 0;
  padding: 0;
  background:
    radial-gradient(120% 90% at 85% 10%, color-mix(in srgb, var(--menu-base) 100%, transparent), transparent 60%),
    linear-gradient(90deg, rgb(5 3 10 / 100%) 0%, rgb(5 3 10 / 97%) 50%, rgb(5 3 10 / 94%) 100%),
    linear-gradient(180deg, color-mix(in srgb, #05030a 88%, var(--menu-base)), color-mix(in srgb, #05030a 94%, var(--menu-base)));
  opacity: 0;
  cursor: default;
  /* Heavy enough that the page behind reads as a glow, not as text. */
  -webkit-backdrop-filter: blur(72px) saturate(0.6);
  backdrop-filter: blur(72px) saturate(0.6);
  transition: opacity 0.55s var(--bh-ease-glide);
}

/* Fully opaque when open: at anything under 1 the blurred page still reads through the
   lighter pools of the room light. */
.site-menu[data-open="true"] .site-menu__veil {
  opacity: 1;
}

/* Room light: pools of the hovered destination's colours (menu.js eases --menu-base and
   --menu-accent towards each item's pair) drifting slowly behind the frost, so the
   background changes with whatever is hovered. */
.site-menu__veil::after {
  position: absolute;
  inset: -25%;
  background:
    radial-gradient(38% 46% at 28% 36%, color-mix(in srgb, var(--menu-accent) 26%, transparent), transparent 72%),
    radial-gradient(46% 52% at 74% 70%, color-mix(in srgb, var(--menu-accent) 12%, transparent), transparent 72%),
    radial-gradient(60% 60% at 62% 28%, color-mix(in srgb, var(--menu-base) 88%, transparent), transparent 76%);
  opacity: 0;
  content: "";
  pointer-events: none;
  animation: menu-glow 18s ease-in-out infinite alternate;
  transition: opacity 0.9s var(--bh-ease-glide);
  will-change: transform;
}

.site-menu[data-open="true"] .site-menu__veil::after {
  opacity: 1;
}

@keyframes menu-glow {
  from {
    transform: translate3d(-4%, -3%, 0) rotate(-4deg) scale(1);
  }

  50% {
    transform: translate3d(3%, 4%, 0) rotate(2deg) scale(1.08);
  }

  to {
    transform: translate3d(5%, -4%, 0) rotate(5deg) scale(1.02);
  }
}

.site-menu__inner {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--menu-side);
  align-content: start;
  gap: clamp(2rem, 4vw, 5rem);
  width: min(100%, var(--bh-container));
  margin-inline: auto;
  padding: calc(var(--bh-header-height) + clamp(0.5rem, 2vh, 2rem)) var(--bh-gutter) clamp(1.5rem, 3vw, 3rem);
  overflow: hidden auto;
  overscroll-behavior: contain;
  outline: none;
}

/* Destinations ---------------------------------------------------------- */

/* The list sits at the vertical centre of the room, whatever the viewport's height. */
.site-menu__nav {
  align-self: center;
}

.site-menu__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-menu__link {
  position: relative;
  display: flex;
  align-items: baseline;
  gap: clamp(0.75rem, 1.4vw, 1.4rem);
  padding-block: clamp(0.5rem, 1.6vh, 1.2rem);
  color: var(--bh-white);
  font-family: var(--bh-font-display);
  font-size: clamp(2rem, 4.9vh, 4.4rem);
  font-weight: var(--bh-weight-display);
  line-height: 1.02;
  letter-spacing: var(--bh-tracking-display);
  text-decoration: none;
  opacity: 0;
  translate: 0 1.4rem;
  transition:
    opacity 0.55s var(--bh-ease-glide),
    translate 0.7s var(--bh-ease-glide),
    color 0.35s var(--bh-ease-out);
}

.site-menu[data-open="true"] .site-menu__link {
  opacity: 1;
  translate: 0;
  transition-delay: calc(var(--i, 0) * 42ms + 90ms);
}

.site-menu[data-open="false"] .site-menu__link {
  transition-duration: 0.28s, 0.28s, 0.35s;
}

.site-menu__index {
  min-width: 2.2ch;
  color: var(--bh-muted);
  font-size: var(--bh-step-label);
  letter-spacing: var(--bh-tracking-label);
  transition: color 0.35s var(--bh-ease-out);
}

.site-menu__label .roll {
  height: 1.08em;
  line-height: 1.08;
}

.site-menu__label .roll__line {
  height: 1.08em;
}

/* When one destination has the room's attention the others step back. */
.site-menu:not([data-active=""]) .site-menu__item:not(.is-active) .site-menu__link {
  color: color-mix(in srgb, var(--bh-white) 42%, transparent);
}

.site-menu__item.is-active .site-menu__index {
  color: var(--menu-accent);
}

.site-menu__link:focus-visible {
  outline: 2px solid var(--bh-focus);
  outline-offset: 0.35rem;
  border-radius: 0.25rem;
}

/* The pages inside a destination ---------------------------------------- */

.site-menu__side {
  display: flex;
  flex-direction: column;
  min-height: 100%;
  gap: clamp(1.25rem, 2.5vh, 2rem);
  opacity: 0;
  translate: 0 1rem;
  transition: opacity 0.6s var(--bh-ease-glide) 0.25s, translate 0.8s var(--bh-ease-glide) 0.25s;
}

.site-menu[data-open="true"] .site-menu__side {
  opacity: 1;
  translate: 0;
}

.site-menu[data-open="false"] .site-menu__side {
  transition-delay: 0s;
  transition-duration: 0.25s;
}

.site-menu__lens-home {
  flex: none;
  width: var(--menu-lens);
  height: var(--menu-lens);
  margin-inline-start: auto;
}

/* The groups stack in one grid cell, so the slot is as tall as the tallest of them
   and they crossfade without ever overlapping the panel below. */
.site-menu__groups {
  display: grid;
  flex: 1 0 auto;
  align-content: start;
}

.site-menu__group {
  grid-area: 1 / 1;
  margin: 0;
  opacity: 0;
  visibility: hidden;
  translate: 0 0.5rem;
  transition: opacity 0.4s var(--bh-ease-glide), translate 0.5s var(--bh-ease-glide), visibility 0s linear 0.4s;
}

.site-menu__group.is-active,
.site-menu__groups:not(:has(.is-active)) .site-menu__group--default {
  opacity: 1;
  visibility: visible;
  translate: 0;
  transition-delay: 0s;
}

.site-menu__group-title,
.site-menu__panel-title {
  margin: 0 0 0.5rem;
  color: var(--menu-accent);
  font-size: var(--bh-step-label);
  letter-spacing: var(--bh-tracking-label);
  text-transform: uppercase;
  transition: color 0.4s var(--bh-ease-out);
}

.site-menu__line {
  max-width: 24rem;
  margin: 0;
  color: var(--bh-muted);
  font-size: var(--bh-step-small);
  line-height: var(--bh-leading-snug);
}

.site-menu__sub {
  margin: 0.9rem 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.3rem;
}

.site-menu__sub a,
.site-menu__places a {
  position: relative;
  display: inline-block;
  padding-block: 0.15rem;
  color: var(--bh-white);
  font-size: var(--bh-step-body);
  font-weight: var(--bh-weight-statement);
  text-decoration: none;
  transition: color 0.3s var(--bh-ease-out), translate 0.4s var(--bh-ease-glide);
}

.site-menu__sub a::before,
.site-menu__places a::before {
  position: absolute;
  inset-inline-start: -1.1rem;
  top: 50%;
  width: 0.55rem;
  height: 1px;
  background: var(--menu-accent);
  opacity: 0;
  content: "";
  transition: opacity 0.3s var(--bh-ease-out), width 0.4s var(--bh-ease-glide);
}

.site-menu__sub a:hover,
.site-menu__sub a:focus-visible,
.site-menu__places a:hover,
.site-menu__places a:focus-visible {
  color: var(--menu-accent);
  translate: 0.9rem 0;
}

.site-menu__sub a:hover::before,
.site-menu__sub a:focus-visible::before,
.site-menu__places a:hover::before,
.site-menu__places a:focus-visible::before {
  width: 0.7rem;
  opacity: 1;
}

/* The panel: where we work, contact, socials ---------------------------- */

.site-menu__panel {
  display: grid;
  gap: clamp(1rem, 2vh, 1.5rem);
  padding-block-start: clamp(1rem, 2vh, 1.5rem);
  border-block-start: 1px solid var(--bh-line);
}

.site-menu__places ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0.15rem;
}

.site-menu__places a {
  font-size: var(--bh-step-small);
}

.site-menu__contact {
  display: grid;
  gap: 0.15rem;
  font-style: normal;
  font-size: var(--bh-step-small);
  color: var(--bh-muted);
}

.site-menu__contact a {
  width: fit-content;
  color: var(--bh-white);
  text-decoration: none;
  transition: color 0.3s var(--bh-ease-out);
}

.site-menu__contact a:hover,
.site-menu__contact a:focus-visible {
  color: var(--menu-accent);
}

.site-menu__social {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-menu__social a {
  display: inline-grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  border: 1px solid var(--bh-line);
  border-radius: 50%;
  color: var(--bh-white);
  transition: border-color 0.3s var(--bh-ease-out), color 0.3s var(--bh-ease-out), translate 0.4s var(--bh-ease-glide);
}

.site-menu__social a:hover,
.site-menu__social a:focus-visible {
  border-color: var(--menu-accent);
  color: var(--menu-accent);
  translate: 0 -0.15rem;
}

.site-menu__social svg {
  width: 1.05rem;
  height: 1.05rem;
}

/* The lens --------------------------------------------------------------- */

.site-menu__lens {
  position: fixed;
  inset-inline-start: 0;
  inset-block-start: 0;
  width: var(--menu-lens);
  height: var(--menu-lens);
  pointer-events: none;
  opacity: 0;
  transform-origin: 50% 50%;
  will-change: transform;
  transition: opacity 0.5s var(--bh-ease-glide);
}

.site-menu[data-open="true"] .site-menu__lens {
  opacity: 1;
  transition-delay: 0.2s;
}

.site-menu[data-leaving="true"] .site-menu__lens {
  transition: none;
}

.site-menu__canvas,
.site-menu__film {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
}

.site-menu__film {
  display: none;
  object-fit: contain;
}

/* No WebGL: the photograph with the destination's colour behind it. */
.site-menu.no-gl .site-menu__canvas {
  display: none;
}

.site-menu.no-gl .site-menu__film {
  display: block;
}

.site-menu.no-gl .site-menu__lens::before {
  position: absolute;
  inset: 8%;
  border-radius: 50%;
  background: radial-gradient(circle at 35% 30%, color-mix(in srgb, var(--menu-accent) 60%, var(--menu-base)), var(--menu-base) 70%);
  content: "";
  transition: background 0.5s var(--bh-ease-out);
}

/* Leaving: everything but the bubble lets go while it swells past the viewport. */
.site-menu[data-leaving="true"] .site-menu__nav,
.site-menu[data-leaving="true"] .site-menu__side {
  opacity: 0;
  transition: opacity 0.3s var(--bh-ease-out);
}

/* Header while the menu is open ------------------------------------------ */

.menu-open .primary-nav,
.menu-open .social-rail,
.menu-open .scroll-progress {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s var(--bh-ease-out);
}

.menu-open .site-header::before {
  opacity: 0;
}

.primary-nav,
.social-rail {
  transition: opacity 0.4s var(--bh-ease-out);
}

/* Arriving through the bubble: the new page is revealed from where it was. */
@view-transition {
  navigation: auto;
}

:root::view-transition-old(root),
:root::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}

:root.bh-arrive::view-transition-old(root) {
  animation: bh-portal-hold 0.62s linear both;
}

:root.bh-arrive::view-transition-new(root) {
  animation: bh-portal-in 0.62s var(--bh-ease-glide) both;
}

@keyframes bh-portal-hold {
  from {
    opacity: 1;
  }

  to {
    opacity: 1;
  }
}

@keyframes bh-portal-in {
  from {
    clip-path: circle(0% at var(--bh-portal-x, 50%) var(--bh-portal-y, 50%));
  }

  to {
    clip-path: circle(160% at var(--bh-portal-x, 50%) var(--bh-portal-y, 50%));
  }
}

/* Every other link ---------------------------------------------------------

   The portal above belongs to the menu: the bubble you pressed opens into the
   page you asked for. Everywhere else, a link in the header, a card, a
   breadcrumb, the footer, there was nothing at all, and the site read as a
   stack of separate documents.

   So the rest of the site gets the quiet version of the same idea. Nothing is
   drawn over the page. The view you are leaving settles back a fraction and
   goes; the one arriving rises the last few pixels into place. The header sits
   in the same position on every page, so it simply appears not to move, which
   is the point: one document changing rather than two swapping.

   These sit at the same specificity as the reset above and are ruled out while
   the portal is running, so the two never fight. */

:root:not(.bh-arrive)::view-transition-old(root) {
  animation: bh-page-leave 0.3s var(--bh-ease-glide) both;
}

:root:not(.bh-arrive)::view-transition-new(root) {
  animation: bh-page-arrive 0.52s var(--bh-ease-out) 0.04s both;
}

@keyframes bh-page-leave {
  to {
    opacity: 0;
    transform: translate3d(0, -0.75rem, 0) scale(0.994);
  }
}

@keyframes bh-page-arrive {
  from {
    opacity: 0;
    transform: translate3d(0, 1.25rem, 0) scale(1.006);
  }
}

/* One column: phones, tablets and anything without a hover pointer --------- */

@media (max-width: 63.99rem), (hover: none) {
  .site-menu__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(1.5rem, 4vh, 2.5rem);
  }

  .site-menu__link {
    font-size: clamp(1.85rem, 7vw, 4rem);
  }

  .site-menu__side {
    min-height: 0;
  }

  .site-menu__lens-home {
    display: none;
  }

  .site-menu__groups {
    grid-auto-flow: row;
    gap: 1.25rem;
    min-height: 0;
    padding-block-start: 1.25rem;
    border-block-start: 1px solid var(--bh-line);
  }

  .site-menu__group {
    grid-area: auto;
    opacity: 1;
    visibility: visible;
    translate: 0;
  }

  .site-menu__group--default,
  .site-menu__group:not(:has(.site-menu__sub)) {
    display: none;
  }

  .site-menu__group .site-menu__line {
    display: none;
  }

  .site-menu__sub {
    margin-top: 0.4rem;
  }

  .site-menu:not([data-active=""]) .site-menu__item:not(.is-active) .site-menu__link {
    color: var(--bh-white);
  }
}

@media (max-width: 63.99rem) {
  /* The lens keeps the corner company on tablets and goes on phones. */
  .site-menu__lens {
    --menu-lens: clamp(6rem, 16vmin, 9rem);
  }
}

@media (max-width: 47.99rem) {
  .site-menu__lens {
    display: none;
  }
}

/* Reduced motion: the menu appears, nothing travels. ------------------------ */

@media (prefers-reduced-motion: reduce) {
  .site-menu,
  .site-menu,
  .site-menu[data-open="true"] {
    clip-path: none;
  }

  .site-menu__veil::after {
    animation: none;
  }

  .site-menu__veil,
  .site-menu__link,
  .site-menu__side,
  .site-menu__group,
  .site-menu__lens {
    transition-duration: 0.15s;
    transition-delay: 0s;
  }

  .site-menu[data-open="true"] .site-menu__link,
  .site-menu[data-open="true"] .site-menu__side,
  .site-menu[data-open="true"] .site-menu__lens {
    transition-delay: 0s;
  }

  .site-menu__link,
  .site-menu__side,
  .site-menu__group {
    translate: 0;
  }

  :root.bh-arrive::view-transition-old(root),
  :root.bh-arrive::view-transition-new(root),
  :root:not(.bh-arrive)::view-transition-old(root),
  :root:not(.bh-arrive)::view-transition-new(root) {
    animation: none;
  }
}
