/* wp-content/plugins/notts-osteo-elements/assets/css/site-nav.css
 *
 * Site navigation: utility bar, logo, ajax search, mega menu, mobile drawer.
 * No raw colours — everything resolves against tokens.css or the custom properties the
 * Elementor controls write onto .nosteo-nav.
 *
 * Author: Sean Burn
 */

.nosteo-nav {
  /* The utility bar reads as a pale band above the white one, not a dark strip. Both are
     tokens, so a rebrand of the tint or the green carries through here untouched. */
  --nosteo-nav-top-bg:     var(--nosteo-tint);
  --nosteo-nav-top-fg:     var(--nosteo-resolve-ink);
  --nosteo-nav-bar-bg:     var(--nosteo-white);
  --nosteo-nav-link:       var(--nosteo-ink);
  --nosteo-nav-link-hover: var(--nosteo-accent);
  --nosteo-nav-max:        var(--nosteo-site-max);

  --nosteo-mega-bg:        var(--nosteo-white);
  --nosteo-mega-left-bg:   var(--nosteo-tint);
  --nosteo-mega-active-bg: var(--nosteo-ink);
  --nosteo-mega-active-fg: var(--nosteo-white);
  --nosteo-mega-left-w:    378px;

  --nosteo-cta-bg:         var(--nosteo-accent);
  --nosteo-cta-fg:         var(--nosteo-white);
  --nosteo-cta-radius:     999px;

  font-family: var(--nosteo-font);
  color: var(--nosteo-nav-link);
  position: relative;
  z-index: 200;
}

/* The bars themselves are full width so their backgrounds run edge to edge; only the
   content inside them sits on the site grid. */
.nosteo-nav__inner {
  max-width: var(--nosteo-nav-max);
  margin: 0 auto;
  padding: 0 var(--nosteo-site-pad);
  display: flex;
  align-items: center;
  gap: clamp(12px, 2vw, 28px);
}

/* ---------- utility bar ---------- */

.nosteo-nav__top {
  background: var(--nosteo-nav-top-bg);
  color: var(--nosteo-nav-top-fg);
  font-size: 14px;
  /* Collapses rather than vanishing. `display: none` cannot be transitioned, so the bar
     used to disappear between two frames and the whole header snapped upward. Max-height
     is generous on purpose — it only has to exceed the bar, and the opacity carries most
     of what the eye reads as the movement. */
  overflow: hidden;
  max-height: 120px;
  transition: max-height 300ms var(--nosteo-ease), opacity 220ms var(--nosteo-ease);
}
/* The clip is only wanted while the bar is collapsing. It also clipped the search results,
   which drop out of the bar's box — the panel was being built and populated correctly and
   then cut off at the bar's edge, which looks exactly like AJAX that never returned.
   Releasing it on focus-within costs the collapse nothing: the bar only condenses on scroll,
   and nobody scrolls the page with the search field focused. */
.nosteo-nav__top:focus-within { overflow: visible; }
/* …but focus is the wrong thing to hang it on. The results panel is a child of this bar, so the
   clip has to be open for as long as there are RESULTS, not for as long as the field happens to
   hold focus — and focus leaves the field readily (tapping a result, a mobile keyboard dismissing,
   any re-render). When it did, the clip snapped back and cut the dropdown off mid-interaction,
   which looks exactly like a dropdown stuck behind the page.
   Keyed to the panel's own state instead. :focus-within stays above as the fallback for browsers
   without :has(). */
.nosteo-nav__top:has(.nosteo-search__results:not([hidden])) { overflow: visible; }
/* The mobile overlay is a state the script already holds, and it outlives focus too. */
.nosteo-nav.is-searching .nosteo-nav__top { overflow: visible; }
/* Three columns: address left, search dead centre, phone and links right. Grid rather than
   flexbox so the search sits at the true centre of the bar regardless of how long the
   address or phone number happen to be. */
.nosteo-nav__top-inner {
  min-height: 54px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(12px, 2vw, 28px);
  padding-top: 8px;
  padding-bottom: 8px;
}

.nosteo-nav__address,
.nosteo-nav__tel {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: inherit;
  text-decoration: none;
  opacity: 0.92;
  line-height: 1.3;
}
/* Colour stated, not just opacity. These are (0,1,0) rules, so Hello Elementor's reset —
   `a:active, a:hover { color: #336 }` at (0,1,1) — outranked them and turned the address
   navy on hover. Naming the colour here makes each of these (0,2,0) and settles it. */
.nosteo-nav__address:hover,
.nosteo-nav__address:focus,
.nosteo-nav__tel:hover,
.nosteo-nav__tel:focus {
  opacity: 1;
  color: var(--nosteo-nav-link-hover);
  text-decoration: underline;
}
.nosteo-nav__address svg,
.nosteo-nav__tel svg { width: 16px; height: 16px; flex: none; }

.nosteo-nav__top-right {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: clamp(14px, 2vw, 26px);
}

.nosteo-nav__top-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  gap: clamp(14px, 2vw, 24px);
}
.nosteo-nav__top-list a {
  color: inherit;
  text-decoration: none;
  opacity: 0.92;
}
.nosteo-nav__top-list > li > a:hover,
.nosteo-nav__top-list > li > a:focus {
  opacity: 1;
  color: var(--nosteo-nav-link-hover);
  text-decoration: underline;
}
/* The booking link is pushed right and given emphasis wherever it sits in the menu. */
.nosteo-nav__top-list .nosteo-book { margin-left: auto; font-weight: var(--nosteo-weight-strong); }

/* A utility-bar item can still carry children — About keeps the practitioner pages. Small
   hover panel rather than a second mega menu: this bar is for getting somewhere quickly. */
.nosteo-nav__top-list > li { position: relative; }
.nosteo-nav__top-list > li > a { display: inline-flex; align-items: center; gap: 6px; }
.nosteo-nav__top-list .nosteo-nav__chev { width: 9px; height: 6px; opacity: 0.8; }

.nosteo-nav__top-sub {
  position: absolute;
  top: 100%;
  left: -12px;
  min-width: 190px;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--nosteo-white);
  border-radius: 6px;
  box-shadow: 0 14px 32px rgba(50, 62, 72, 0.18);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 160ms var(--nosteo-ease), transform 160ms var(--nosteo-ease), visibility 160ms;
  z-index: 20;
}
.nosteo-nav__top-list > li:hover > .nosteo-nav__top-sub,
.nosteo-nav__top-list > li:focus-within > .nosteo-nav__top-sub {
  opacity: 1;
  visibility: visible;
  transform: none;
}
.nosteo-nav__top-sub a {
  display: block;
  padding: 8px 12px;
  border-radius: 4px;
  color: var(--nosteo-ink);
  opacity: 1;
  white-space: nowrap;
}
.nosteo-nav__top-sub a:hover { background: var(--nosteo-tint); text-decoration: none; }

/* ---------- main bar ---------- */

.nosteo-nav__bar {
  background: var(--nosteo-nav-bar-bg);
  border-bottom: 1px solid var(--nosteo-hair-soft);
  transition: box-shadow 220ms var(--nosteo-ease), padding 220ms var(--nosteo-ease);
}
/* Transitioned so the bar shrinks with the utility bar above it rather than snapping to its
   condensed height a beat later. */
.nosteo-nav__bar .nosteo-nav__inner {
  min-height: 74px;
  transition: min-height 300ms var(--nosteo-ease);
}

/* Fixed, not sticky. A sticky element can only stick within its own parent's box, and in
   a Theme Builder header that parent is only as tall as the header itself — so it unsticks
   and scrolls away the moment the page moves. Fixed is relative to the viewport and does
   not care what Elementor wrapped it in. */
.nosteo-nav.is-stuck {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 400;
}

/* Fallback for the logged-in admin bar before script runs. Script then measures it, which
   also covers the narrow-screen case where WordPress makes that bar absolute and it
   scrolls away. */
body.admin-bar .nosteo-nav.is-stuck { top: 32px; }
@media screen and (max-width: 782px) {
  body.admin-bar .nosteo-nav.is-stuck { top: 46px; }
}

/* Holds the space the fixed bar no longer occupies, so page content does not start
   underneath it. The BAR's own height, not its distance from the top of the screen —
   WordPress already reserves the admin bar's space with its own html margin. */
.nosteo-nav-spacer { display: none; }
.nosteo-nav.is-stuck + .nosteo-nav-spacer {
  display: block;
  /* Floored from the two bars' OWN declared min-heights (54px + 74px + the 1px border) rather
     than a number picked to look right, so it tracks them if either changes.
     The fallback used to be 0px, which is the one way the first container can end up sitting
     BEHIND the fixed header instead of below it: the script skips publishing --nosteo-nav-h while
     the bar is condensed, so any path that reaches that state before the first measurement left
     nothing reserved at all. A floor cannot be worse than the header's real height. */
  height: var(--nosteo-nav-h, calc(54px + 74px + 1px));
}
.nosteo-nav.is-condensed .nosteo-nav__bar { box-shadow: 0 6px 24px rgba(50, 62, 72, 0.10); }
.nosteo-nav.is-condensed .nosteo-nav__bar .nosteo-nav__inner { min-height: 60px; }
/* The utility bar is the first thing to go when space gets tight on scroll — it slides up
   into itself rather than being switched off. */
.nosteo-nav.is-condensed .nosteo-nav__top {
  max-height: 0;
  opacity: 0;
}

/* The bar is 74px (60px condensed) and the mark is 4:1, so at the 150px default it sits
   ~37px tall with room either side. The block padding is a floor on that breathing room:
   it only does work at the top of the width slider, where the logo would otherwise reach
   the bar edges. Vertical only — the left edge stays on the site gutter, in line with the
   nav above it. */
.nosteo-nav__logo {
  display: inline-flex;
  align-items: center;
  padding: 8px 0;
  text-decoration: none;
}
.nosteo-nav__logo img { display: block; height: auto; }

/* ---------- main menu ---------- */

.nosteo-nav__main { margin-left: auto; }
.nosteo-nav__main > ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: center;
  gap: clamp(10px, 1.6vw, 26px);
}
.nosteo-nav__main > ul > li { position: static; }
.nosteo-nav__main > ul > li > a,
.nosteo-nav__main > ul > li > button {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 10px 2px;
  background: none;
  border: 0;
  font: inherit;
  font-weight: var(--nosteo-weight-medium);
  color: var(--nosteo-nav-link);
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
.nosteo-nav__main > ul > li > a:hover { color: var(--nosteo-nav-link-hover); }

/* Every button we render carries type="button", and Hello Elementor's reset styles it with
   `[type=button]:hover, [type=button]:focus { background-color: #c36; color: #fff }`.
   That selector is (0,2,0) — an attribute and a pseudo-class BOTH count in the class
   column — so it outranks `.nosteo-nav__main > ul > li > button:hover` (0,1,3) no matter
   how deep the structural chain gets. Depth loses to a single attribute selector.
   Hence the `.nosteo-nav` prefix: it buys the class-column point needed to win, and both
   background and colour must be restated or the reset supplies them. */
.nosteo-nav .nosteo-nav__main > ul > li > button:hover,
.nosteo-nav .nosteo-nav__main > ul > li > button:focus,
.nosteo-nav .nosteo-nav__main > ul > li > button[aria-expanded="true"] {
  background: none;
  color: var(--nosteo-nav-link-hover);
}

.nosteo-nav__chev { width: 11px; height: 7px; transition: transform 200ms var(--nosteo-ease); }
.nosteo-nav__main > ul > li > button[aria-expanded="true"] .nosteo-nav__chev { transform: rotate(180deg); }

/* Orange, inverting to orange-on-white on hover. The white arrives as a wipe across the
   pill rather than a cross-fade: a background-size transition on a flat gradient, so there
   is no pseudo-element to stack against the button's own background and the label needs no
   wrapper to stay above it.
   The outline is an inset shadow, not a border — a real border would add 2px to the button
   the moment it appeared and nudge the bar's layout on hover. Invisible while the fill is
   orange, since it is the same colour. */
.nosteo-nav__cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 22px;
  border-radius: var(--nosteo-cta-radius);
  background-color: var(--nosteo-cta-bg);
  background-image: linear-gradient(var(--nosteo-cta-fg), var(--nosteo-cta-fg));
  background-repeat: no-repeat;
  background-position: left center;
  background-size: 0% 100%;
  box-shadow: inset 0 0 0 1px var(--nosteo-cta-bg);
  color: var(--nosteo-cta-fg);
  font-weight: var(--nosteo-weight-strong);
  text-decoration: none;
  white-space: nowrap;
  transition: background-size 320ms var(--nosteo-ease), color 200ms var(--nosteo-ease);
}
/* The colour is restated deliberately. Hello Elementor's reset.css ships
   `a:active, a:hover { color: #336 }` at (0,1,1), which outranks the (0,1,0) base rule
   above — without this the Book Now label turned navy on hover and on click. */
.nosteo-nav__cta:hover,
.nosteo-nav__cta:focus-visible,
.nosteo-nav__cta:active {
  background-size: 100% 100%;
  color: var(--nosteo-cta-bg);
}

.nosteo-nav__cta:focus-visible,
.nosteo-nav a:focus-visible,
.nosteo-nav button:focus-visible {
  outline: 2px solid var(--nosteo-accent);
  outline-offset: 2px;
}

/* ---------- icon button states ----------
   Same root cause as the CTA above, worse effect. Hello Elementor's reset paints EVERY
   button `background-color: #c36; color: #fff` on :hover AND :focus, at (0,1,1) — so
   these icon buttons, whose base rules are (0,1,0), flashed raspberry with white icons,
   including on a plain mouse click. Restating background/colour here reclaims them, and
   since that leaves them with no feedback at all they get a real hover state: the same
   accent shift the nav links use, so the whole bar behaves as one thing.
   Keyboard focus is handled by :focus-visible above — this is only undoing the reset. */
.nosteo-nav .nosteo-nav__burger:hover,
.nosteo-nav .nosteo-nav__burger:focus,
.nosteo-nav .nosteo-nav__burger:hover span { background: var(--nosteo-nav-link-hover); }

.nosteo-drawer .nosteo-drawer__back:hover,
.nosteo-drawer .nosteo-drawer__back:focus {
  background: var(--nosteo-tint);
  color: var(--nosteo-nav-link-hover);
}

/* ---------- mega menu ---------- */

.nosteo-mega {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  background: var(--nosteo-mega-bg);
  box-shadow: 0 18px 44px rgba(50, 62, 72, 0.14);
  border-top: 1px solid var(--nosteo-hair-soft);
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
  transition: opacity 200ms var(--nosteo-ease), transform 200ms var(--nosteo-ease);
}
.nosteo-mega[hidden] { display: none; }
.nosteo-mega.is-open { opacity: 1; transform: none; pointer-events: auto; }

/* The panel background is full width; this puts its content on the same 1440 grid as the
   bars above. No horizontal padding here on purpose — the tinted column runs to the
   container edge as in the wireframe, and it is the TEXT inside it that is indented by the
   site gutter, so the first character lines up with the logo. */
.nosteo-mega__inner {
  max-width: var(--nosteo-nav-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: var(--nosteo-mega-left-w) 1fr;
  min-height: 340px;
}

/* Left column: the parents, per the wireframe. No vertical padding — the first item sits
   flush against the bar above, so the active row reads as a continuation of the nav rather
   than a block floating inside a tinted panel. Removed at both ends, not just the top: the
   active row is full-bleed, and 18px left at the bottom would strand the last item the
   same way the top one was stranded. */
.nosteo-mega__parents {
  list-style: none;
  margin: 0;
  padding: 0;
  background: var(--nosteo-mega-left-bg);
}
.nosteo-mega__parents a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* Left inset matches the site gutter so these line up with the logo above. */
  padding: 15px var(--nosteo-site-pad) 15px var(--nosteo-site-pad);
  color: var(--nosteo-ink);
  text-decoration: none;
  font-weight: var(--nosteo-weight-medium);
  transition: background 160ms var(--nosteo-ease), color 160ms var(--nosteo-ease);
}
.nosteo-mega__parents a svg { width: 7px; height: 11px; opacity: 0.5; flex: none; }
.nosteo-mega__parents a:hover { background: rgba(50, 62, 72, 0.06); }
.nosteo-mega__parents a.is-active {
  background: var(--nosteo-mega-active-bg);
  color: var(--nosteo-mega-active-fg);
}
.nosteo-mega__parents a.is-active svg { opacity: 1; }

/* Right: one panel per left item, only the active one shown. */
/* The media block carries its own height now, so the panel needs no floor of its own — it just has
   to be the positioning context for the conditions scene, which IS absolutely positioned. */
.nosteo-mega__panels { position: relative; padding: 34px 48px 34px 50px; }
.nosteo-mega__panel { display: none; }
.nosteo-mega__panel.is-active { display: block; animation: nosteo-mega-in 220ms var(--nosteo-ease) both; }

@keyframes nosteo-mega-in {
  from { opacity: 0; transform: translateX(8px); }
  to   { opacity: 1; transform: none; }
}

.nosteo-mega__links {
  list-style: none;
  margin: 0;
  padding: 0;
  columns: 2;
  column-gap: 40px;
}
.nosteo-mega__links li { break-inside: avoid; }
.nosteo-mega__links a {
  display: block;
  padding: 9px 0;
  color: var(--nosteo-ink);
  text-decoration: none;
}
.nosteo-mega__links a:hover { color: var(--nosteo-nav-link-hover); }

/* Feature panel — the "map boxes, images and icons" slot. */
/* ---------- live anatomy preview ----------
   Fills the panel edge to edge rather than sitting in it: the figure is the right-hand half of the
   menu, not a thumbnail placed on it. The panels box has padding for the link lists, so this pulls
   back out through it. */
.nosteo-mega__scene {
  position: absolute;
  inset: 0;
  overflow: hidden;
  /* A ground for the figure to stand on instead of flat white. Two layers: a soft warm pool behind
     where the body sits, and a tint that lifts off the floor — the same light-on-pale relationship
     the page heroes use, so the menu looks like the pages it opens. */
  background:
    radial-gradient(58% 68% at 62% 42%, var(--nosteo-white) 0%, transparent 68%),
    linear-gradient(180deg, var(--nosteo-tint) 0%, var(--nosteo-ground) 100%);
  /* Fades in once the model has actually arrived, so the panel never shows an empty gradient. */
  opacity: 0;
  transition: opacity 420ms var(--nosteo-ease);
}
.nosteo-mega__scene.is-ready { opacity: 1; }
/* If the model never loads the list beside it is still the navigation, so the panel simply
   stays plain rather than holding an empty box. */
.nosteo-mega__scene.is-failed { display: none; }

.nosteo-mega__canvas {
  display: block;
  width: 100%;
  height: 100%;
}

.nosteo-mega__scene-label {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 26px;
  margin: 0;
  font-family: var(--nosteo-mono);
  font-size: 10px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-align: center;
  color: var(--nosteo-resolve-ink);
}

/* ---------- per-page preview ----------
   Shown on the right as each left-hand item is hovered.

   IN FLOW, not absolutely positioned. An earlier version used `position: absolute; inset: 0` to
   fill the panel; it broke the previews twice, because the media then contributes no height and
   the whole thing depends on an ancestor chain that is easy to disturb. A block with a height is
   simpler and cannot be knocked over.

   Order matters here: every modifier below comes AFTER the base rule, or the base wins on the
   properties they share — which is exactly how the portrait lost its alignment the first time. */

/* The ground lives on the PANEL, so both kinds of preview stand on it and neither has to carry a
   background of its own. */
.nosteo-mega__panels {
  background:
    radial-gradient(58% 68% at 62% 38%, var(--nosteo-white) 0%, transparent 68%),
    linear-gradient(180deg, var(--nosteo-tint) 0%, var(--nosteo-ground) 100%);
}
/* …except where the panel is a list of links, which needs a plain surface to read against. */
.nosteo-mega__panels:has(.nosteo-mega__panel.is-active .nosteo-mega__links) {
  background: var(--nosteo-mega-bg);
}

.nosteo-mega__media {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin: 0;
  /* Fills the panel it sits in, so every preview is the same height whatever it contains. */
  min-height: 352px;
  text-align: center;
}
.nosteo-mega__links + .nosteo-mega__media { margin-top: 26px; }

.nosteo-mega__plate {
  display: grid;
  place-items: center;
  width: 168px;
  height: 168px;
  border-radius: 50%;
  background: var(--nosteo-tint);
  overflow: hidden;
}

/* ---- a page's own hero image: the staff portraits ----
   Full height of the panel at the width Sean asked for. `cover` takes the difference off the sides
   rather than stretching, and the crop is biased upward because faces sit high in these shots. */
.nosteo-mega__media--portrait { gap: 12px; }
.nosteo-mega__media--portrait .nosteo-mega__plate {
  width: 320px;
  height: 352px;
  border-radius: 0;
  background: none;
}
.nosteo-mega__media--portrait img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 12%;
}

/* ---- small bundled photographs ----
   Nothing uses this now that the treatments have full-size originals, but it stays as the sensible
   treatment for any 200px image added later: native size in a medallion, never upscaled. */
.nosteo-mega__media--photo .nosteo-mega__plate {
  width: 200px;
  height: 200px;
  background: none;
}
.nosteo-mega__media--photo img {
  display: block;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  object-fit: cover;
  box-shadow: 0 0 0 8px var(--nosteo-white), 0 0 0 9px var(--nosteo-hair);
}

/* ---- line-art illustrations ---- */
.nosteo-mega__media--icon img {
  display: block;
  width: 64px;
  height: 54px;
  object-fit: contain;
}

/* ---- slow zoom as the preview appears ----
   Starts each time a panel becomes current, because the script adds .is-active then — re-adding a
   class restarts its animation, so moving down the list re-runs the move on the new image.

   `forwards` holds the end frame so it settles rather than snapping back mid-view. The transform is
   on the IMAGE inside the plate, and the plate has overflow:hidden, so the growth is cropped by the
   frame instead of pushing the layout around. Nothing here is positioned against the image, so the
   containing block a transform creates costs nothing. */
@keyframes nosteo-mega-kenburns {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.12) translate3d(-1.2%, -1.6%, 0); }
}

.nosteo-mega__panel.is-active .nosteo-mega__media img {
  animation: nosteo-mega-kenburns 12s var(--nosteo-ease) forwards;
  /* Hints the compositor before the first frame, so the move starts smoothly rather than after a
     paint. Cleared by the animation itself finishing. */
  will-change: transform;
}

/* A line drawing has nothing to pan across, and scaling one just makes it soft. */
.nosteo-mega__panel.is-active .nosteo-mega__media--icon img { animation: none; will-change: auto; }

@media (prefers-reduced-motion: reduce) {
  .nosteo-mega__panel.is-active .nosteo-mega__media img { animation: none; will-change: auto; }
}

.nosteo-mega__caption {
  font-family: var(--nosteo-mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--nosteo-resolve-ink);
}

.nosteo-mega__feature { max-width: 460px; }
.nosteo-mega__image,
.nosteo-mega__map {
  display: block;
  width: 100%;
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 16px;
}
.nosteo-mega__map { aspect-ratio: 16 / 9; }
.nosteo-mega__map iframe { width: 100%; height: 100%; border: 0; display: block; }
.nosteo-mega__feature-heading {
  margin: 0 0 8px;
  font-size: 20px;
  font-weight: var(--nosteo-weight-strong);
  color: var(--nosteo-ink);
}
.nosteo-mega__feature-text { margin: 0 0 14px; color: var(--nosteo-muted); line-height: 1.55; }
.nosteo-mega__feature-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--nosteo-accent);
  font-weight: var(--nosteo-weight-strong);
  text-decoration: none;
}
/* Colour restated for the same reason as the CTA — `a:hover` from the theme reset
   outranks the base rule and would drag this to navy. */
.nosteo-mega__feature-link:hover { text-decoration: underline; color: var(--nosteo-accent); }

/* ---------- search ---------- */

/* Lives in the centre column of the utility bar. */
.nosteo-search { position: relative; width: clamp(240px, 34vw, 420px); }
/* A white pill on the tint. This was translucent white on a dark bar; against a pale ground
   that reads as a barely-there smudge, so the field states its own surface instead. */
.nosteo-search__input {
  width: 100%;
  min-height: 38px;
  padding: 0 40px 0 16px;
  border: 1px solid var(--nosteo-hair);
  border-radius: 999px;
  background: var(--nosteo-white);
  font: inherit;
  font-size: 14px;
  color: var(--nosteo-ink);
}
.nosteo-search__input::placeholder { color: var(--nosteo-muted); }
.nosteo-search__input:focus {
  outline: none;
  border-color: var(--nosteo-accent);
}
.nosteo-search__icon {
  position: absolute;
  right: 13px;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  color: currentColor;
  opacity: 0.7;
  pointer-events: none;
}
.nosteo-search:focus-within .nosteo-search__icon { color: var(--nosteo-muted); opacity: 1; }
.nosteo-search__icon svg { width: 100%; height: 100%; }

.nosteo-search__results {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  right: 0;
  max-height: min(70vh, 520px);
  overflow-y: auto;
  background: var(--nosteo-white);
  border: 1px solid var(--nosteo-hair-soft);
  border-radius: 8px;
  box-shadow: 0 18px 44px rgba(50, 62, 72, 0.16);
  padding: 6px;
  z-index: 30;
}
.nosteo-search__results[hidden] { display: none; }

.nosteo-search__group-label {
  padding: 12px 12px 6px;
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--nosteo-muted);
  font-weight: var(--nosteo-weight-strong);
}
.nosteo-search__item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-radius: 6px;
  color: var(--nosteo-ink);
  text-decoration: none;
  line-height: 1.35;
}
.nosteo-search__item:hover,
.nosteo-search__item.is-active { background: var(--nosteo-tint); }
.nosteo-search__thumb {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 5px;
  object-fit: cover;
  background: var(--nosteo-grey-light);
  display: grid;
  place-items: center;
  color: var(--nosteo-muted);
}
.nosteo-search__thumb svg { width: 20px; height: 20px; }
.nosteo-search__empty { padding: 18px 14px; color: var(--nosteo-muted); }

/* ---------- burger ---------- */

/* Two classes, so the stacked-bar layout wins over the generic icon rule regardless of
   which is declared first. Everything else — size, colour, hover — comes from .__icon. */
/* Two classes, so the stacked-bar layout wins over the generic icon rule regardless of
   which is declared first. Everything else — size, hover — comes from .__icon. */
.nosteo-nav__icon.nosteo-nav__burger {
  flex-direction: column;
  justify-content: space-between;
  /* Load-bearing. .__icon centres its contents, which is right for an SVG and fatal here:
     these bars are empty elements with no width of their own, so centring collapses them
     to nothing and the button renders blank. They need to stretch to the button's width. */
  align-items: stretch;
  padding: 12px 9px;
}
.nosteo-nav__burger span {
  display: block;
  height: 2px;
  /* Stated, not inherited. It sits in the white bar, so ink is correct and does not depend
     on whatever colour happens to cascade into the button. Hover takes it to the accent. */
  background: var(--nosteo-ink);
  border-radius: 2px;
  transition: background 160ms var(--nosteo-ease), transform 220ms var(--nosteo-ease), opacity 160ms var(--nosteo-ease);
}
/* 7px, not 9: the button is 40px with 12px of vertical padding, so the bars sit 7px apart
   and that is exactly how far the outer two travel to meet in the middle. The old value
   was measured against a 46px button and now overshoots into a lopsided cross. */
.nosteo-nav__burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nosteo-nav__burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nosteo-nav__burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- mobile drawer ----------
   Full viewport. Every level is a sibling panel translated in from the right, so going
   deeper and coming back are the same cheap transform rather than a re-render. */

.nosteo-drawer {
  position: fixed;
  /* Beneath the header, not over it. The bar keeps the logo, phone and search on screen the
     whole time the menu is open, and the burger — now a cross — closes it. */
  top: var(--nosteo-header-h, 0px);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 300;
  background: var(--nosteo-white);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform 320ms var(--nosteo-ease);
}
.nosteo-drawer[hidden] { display: none; }
.nosteo-drawer.is-open { transform: none; }

.nosteo-drawer__viewport { position: relative; flex: 1 1 auto; overflow: hidden; }

.nosteo-drawer__panel {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--nosteo-white);
  transform: translateX(100%);
  transition: transform 300ms var(--nosteo-ease);
  visibility: hidden;
}
/* z-index is load-bearing, not decoration. The root panel is rendered LAST, so without
   this it paints over every child panel: the child slid in correctly but stayed underneath
   a root panel that had only moved 28% aside, which read as "the drawer moves a little and
   the children never appear". */
.nosteo-drawer__panel.is-current { transform: none; visibility: visible; z-index: 2; }
/* Panels already visited sit to the left, so coming back slides the right way. */
.nosteo-drawer__panel.is-behind { transform: translateX(-28%); visibility: visible; z-index: 1; }

.nosteo-drawer__panel ul { list-style: none; margin: 0; padding: 6px 0 24px; }
.nosteo-drawer__panel li + li { border-top: 1px solid var(--nosteo-hair-soft); }
/* Scoped to the LIST: these are the menu rows. Unscoped it also caught the booking button
   added beneath them and forced it back to a left-aligned, background-less row. */
.nosteo-drawer__panel ul a,
.nosteo-drawer__panel ul button[data-drawer-open] {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  width: 100%;
  min-height: 56px;
  padding: 14px 20px;
  background: none;
  border: 0;
  font: inherit;
  font-size: 17px;
  color: var(--nosteo-ink);
  text-decoration: none;
  text-align: left;
  cursor: pointer;
}
.nosteo-drawer__panel svg { width: 8px; height: 12px; flex: none; opacity: 0.45; }

.nosteo-drawer__back {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 52px;
  padding: 12px 20px;
  background: var(--nosteo-tint);
  border: 0;
  border-bottom: 1px solid var(--nosteo-hair-soft);
  font: inherit;
  font-weight: var(--nosteo-weight-strong);
  color: var(--nosteo-ink);
  cursor: pointer;
  text-align: left;
}
.nosteo-drawer__back svg { opacity: 1; }

/* The booking button, directly under the primary menu items.
   Was pinned to the bottom of the drawer, which put it a screen away from the links it belongs to
   with a large empty gap between — see render_drawer_panel(). */
.nosteo-drawer__cta {
  padding: 20px 20px calc(20px + env(safe-area-inset-bottom));
}

.nosteo-drawer__book {
  /* Flex, not text-align: the label centres on both axes and the box keeps a real tap height even
     if the text ever wraps. */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 52px;
  padding: 0 24px;
  border-radius: 999px;
  background: var(--nosteo-accent);
  box-shadow: inset 0 0 0 1px var(--nosteo-accent);
  color: var(--nosteo-white);
  font-size: 16px;
  font-weight: var(--nosteo-weight-strong);
  letter-spacing: 0.01em;
  text-align: center;
  text-decoration: none;
  transition: background 220ms var(--nosteo-ease), color 220ms var(--nosteo-ease);
}
/* Colour restated on BOTH states, and scoped past the drawer so it outranks the parent theme's
   reset — `a:active,a:hover{color:#336}` at (0,1,1) would otherwise repaint the label navy, and
   [type=button] rules paint buttons raspberry on hover AND focus. */
.nosteo-drawer .nosteo-drawer__book:hover,
.nosteo-drawer .nosteo-drawer__book:focus {
  background: var(--nosteo-white);
  color: var(--nosteo-accent);
}
.nosteo-drawer__book:focus-visible {
  outline: 2px solid var(--nosteo-ink);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .nosteo-drawer__book { transition: none; }
}

/* ---------- breakpoints ---------- */

/* Icon buttons in the utility bar. Only visible below the desktop breakpoint, where the
   bar becomes a row of controls rather than a row of text. */
/* The small-screen control set. Sits beside the logo in the bar, and is mirrored in the
   drawer header so the controls do not move when the menu opens over them. */
.nosteo-nav__actions {
  display: flex;
  align-items: center;
  gap: 2px;
  margin-left: auto;
}

.nosteo-nav__icon {
  display: none;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
}
.nosteo-nav__icon svg { width: 20px; height: 20px; }
.nosteo-nav .nosteo-nav__icon:hover,
.nosteo-nav .nosteo-nav__icon:focus { background: none; color: var(--nosteo-accent); }

@media (max-width: 1024px) {
  .nosteo-nav__main { display: none; }
  .nosteo-nav__cta { display: none; }          /* it lives in the drawer at this width */
  .nosteo-nav__logo { margin-right: auto; }
  .nosteo-nav__icon { display: inline-flex; }

  /* The utility bar is gone entirely at this width. Its three useful controls — search,
     phone, menu — sit beside the logo instead, which is one bar rather than two and gives
     the scene below a full screen to work with. */
  .nosteo-nav__top { display: none; }

  /* With one exception: it comes back as an OVERLAY across the whole header, carrying the
     search field and nothing else. Reusing this bar rather than rendering a second mobile
     field means there is only ever one search input in the document — and it already has
     the styling for a dark ground, which is what this is. */
  .nosteo-nav.is-searching .nosteo-nav__top {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 20;
    /* Clears the collapse: condensed AND searching would otherwise flatten the overlay. */
    max-height: none;
    opacity: 1;
    /* `backwards`, NOT `both`. `both` includes forwards, which leaves the final keyframe applied
       for as long as the overlay is open — and that keyframe sets `clip-path: inset(0 0 0 0)`.
       A persisted clip-path clips EVERY descendant to this 75px bar no matter what overflow says,
       and makes this element the containing block for position:fixed children too. That is why the
       results panel was cut off on mobile and nowhere else, why releasing overflow did nothing, and
       why switching the panel to fixed made it disappear entirely.
       `backwards` still plays the wipe; it just does not outlive it. */
    animation: nosteo-search-open 240ms var(--nosteo-ease) backwards;
  }
  .nosteo-nav.is-searching .nosteo-nav__top-inner {
    height: 100%;
    grid-template-columns: 1fr;
    row-gap: 0;
    /* Clear of the cross, which sits above this on the right. */
    padding-right: calc(var(--nosteo-site-pad) + 48px);
  }
  .nosteo-nav.is-searching .nosteo-nav__address,
  .nosteo-nav.is-searching .nosteo-nav__address-slot,
  .nosteo-nav.is-searching .nosteo-nav__top-right { display: none; }
  /* On a phone the results panel is FIXED, not absolute.
     The utility bar returns as `position: absolute; inset: 0` over the nav, so its box is only the
     header's ~75px — and the panel has to hang far below that. Absolute, it depends on escaping
     that box's `overflow: hidden`, which is exactly what was failing here and only here (desktop,
     where the bar is a normal 54px band in flow, was always fine).
     Fixed removes the question: a fixed element is not clipped by an ancestor's overflow at all.
     It is anchored to --nosteo-header-h, the header's on-screen bottom edge, which the nav script
     already publishes for the anatomy scene.
     Full width between the gutters too, which is the right shape for results on a phone. */
  .nosteo-search__results {
    position: fixed;
    top: calc(var(--nosteo-header-h, 75px) + 8px);
    left: var(--nosteo-site-pad);
    right: var(--nosteo-site-pad);
    /* Never taller than the space actually left below the header. */
    max-height: calc(100svh - var(--nosteo-header-h, 75px) - 24px);
  }

  .nosteo-nav.is-searching .nosteo-search { display: block; width: 100%; }

  /* The toggle rides above the overlay so it can dismiss it; the other two stand down so
     the field has the bar to itself. */
  .nosteo-nav__actions { position: relative; z-index: 30; }
  .nosteo-nav.is-searching .nosteo-nav__call,
  .nosteo-nav.is-searching .nosteo-nav__burger { display: none; }
  .nosteo-nav.is-searching .nosteo-nav__search-toggle { color: var(--nosteo-nav-top-fg); }

  /* The field carries its own magnifier at its right edge, which is exactly where the
     toggle sits once it becomes the cross — two search glyphs stacked on each other. The
     toggle is the live control here, so the decorative one stands down. */
  .nosteo-nav.is-searching .nosteo-search__icon { display: none; }
}

/* Wipes open from the right, where the icon that opened it sits. */
@keyframes nosteo-search-open {
  from { opacity: 0; clip-path: inset(0 0 0 100%); }
  to   { opacity: 1; clip-path: inset(0 0 0 0); }
}

/* Magnifier or cross, never both — the toggle reports its own state. */
.nosteo-nav__icon-shut { display: none; }
.nosteo-nav__search-toggle[aria-expanded="true"] .nosteo-nav__icon-find { display: none; }
.nosteo-nav__search-toggle[aria-expanded="true"] .nosteo-nav__icon-shut { display: block; }

@media (prefers-reduced-motion: reduce) {
  .nosteo-drawer,
  .nosteo-drawer__panel,
  .nosteo-mega,
  .nosteo-nav__top,
  .nosteo-nav__cta,
  .nosteo-nav__bar .nosteo-nav__inner,
  .nosteo-nav__bar { transition: none !important; }
  .nosteo-mega__panel.is-active { animation: none !important; }
}
