/* Project overrides. Loaded last, after every Mobirise stylesheet. */

/* ---------------------------------------------------------------- images -- */

/* Every <img> now carries intrinsic width/height attributes so the browser can
   reserve the right amount of space before the file arrives. The theme sets
   `img { width: 100% }` without a matching height, which would otherwise squash
   images down to their attribute height. Blocks that deliberately fix a height
   (`.cid-* img { height: …; object-fit: cover }`) are more specific and still win. */
img {
  height: auto;
}

/* The lightbox carousel swaps images in and out; without this the modal jumps
   around while the next slide decodes. */
.mbr-gallery .modal-body img {
  height: auto;
}

/* ------------------------------------------------------- gallery triggers -- */

/* The thumbnails kept their <div> — the hover overlay is drawn by per-section
   rules written as `.cid-… .mbr-gallery-item > div::before`, and a tag swap
   would drop every one of them. role="button" + tabindex is what actually
   matters here: the control is now focusable and announced as a control, and
   the styling is untouched. */
.mbr-gallery .mbr-gallery-item > [role="button"] {
  cursor: pointer;
}

/* The close control in the lightbox is a <button>; `.close` already styles
   the box, this only neutralises the UA button defaults. */
.mbr-gallery .modal .close {
  padding: 0;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
}

/* The theme sets `outline: none` broadly, which leaves keyboard users with no
   idea where they are. Restore a focus ring — but only for keyboard focus. */
a:focus-visible,
button:focus-visible,
[role="button"]:focus-visible,
.mbr-gallery .mbr-gallery-item > [role="button"]:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 2px;
}

/* ------------------------------------------------------------- layout ---- */

/* The front page header overlaps on purpose: .header-title is 180% wide with a
   45% right padding, so the heading sits across the image column, and the image
   is pulled back under it with a negative margin. That only worked because
   `position: relative` made the text paint after the in-flow image — incidental
   ordering that breaks the moment the image wrapper gets a stacking context of
   its own. State the precedence instead of relying on paint order. */
.header-title {
  position: relative;
  z-index: 2;
}

/* ------------------------------------------------------------- motion ----- */

/* Cross-document view transitions: navigating between pages cross-fades
   instead of flashing white. Browsers without support just navigate normally. */
@view-transition {
  navigation: auto;
}

/* Hold the header still across the transition so only the content changes. */
.menu {
  view-transition-name: site-nav;
}

@media (prefers-reduced-motion: no-preference) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation-duration: .28s;
  }

  /* Scroll-driven reveal. No JavaScript and no IntersectionObserver: the
     animation is driven by the element's own position in the scrollport, so it
     costs nothing on the main thread and cannot leave content stuck at
     opacity 0 if a script fails to run.

     Applied to the trigger *inside* each gallery item, never to
     `.mbr-gallery-item` itself — Masonry positions those and a transform here
     would fight it. Likewise the wrappers rather than the images, because
     `.cid-* img` already uses transform for its hover scale.

     The header image is excluded: animating transform gives an element a
     stacking context for as long as the animation is applied, and with a view()
     timeline that is forever — which lifted the front page hero above the
     heading that is meant to sit on top of it. It is above the fold anyway, so
     a scroll reveal there would never actually play. */
  @supports (animation-timeline: view()) {
    .mbr-gallery .mbr-gallery-item > [role="button"],
    section:not(.header1) .image-wrapper,
    .image-wrap,
    .item-img {
      animation: reveal-up linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 45%;
    }

    @keyframes reveal-up {
      from {
        opacity: 0;
        transform: translateY(1.5rem);
      }
      to {
        opacity: 1;
        transform: none;
      }
    }
  }
}

/* ------------------------------------------------------------ utilities --- */

/* For headings that need to exist for structure but not appear in the design. */
.visually-hidden-heading {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}
