html {
  scroll-behavior: smooth;
}

body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

main {
  flex: 1 0 auto;
  /* Scroll-reveal sections (.reveal-left/.reveal-right) start translated
     off to the side before their IntersectionObserver fires, which widens
     the page's scrollable area even before that section is scrolled into
     view -- on mobile this shows up as blank space and the whole page
     rendering zoomed out. #siteNavbar is a sibling of <main>, not a
     descendant, so this doesn't affect its sticky positioning. */
  overflow-x: hidden;
}

.navbar-brand {
  letter-spacing: 0.02em;
}

/* The full business name doesn't fit next to the mobile toggler on narrow
   screens. flex-wrap's line-breaking decision uses items' natural (unshrunk)
   widths, so shrink/ellipsis alone can't stop the toggler from being pushed
   onto its own line -- nowrap is required to keep them on one row. That
   only works if the expanded #mainNav panel (a third flex child) is taken
   out of this row's flex flow, so it's floated below as an overlay instead
   of following normal Bootstrap collapse-wraps-onto-next-line behavior. */
#siteNavbar .container {
  flex-wrap: nowrap;
}

#siteNavbar .navbar-brand {
  min-width: 0;
  flex-shrink: 1;
}

#siteNavbar .navbar-brand span {
  /* The span is itself a flex item (brand uses d-flex), so it also needs
     min-width: 0 to actually shrink below its text's natural width instead
     of just inheriting the parent's shrink allowance in name only. */
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#siteNavbar .navbar-toggler {
  flex-shrink: 0;
}

@media (max-width: 576px) {
  #siteNavbar .navbar-brand span {
    font-size: 0.95rem;
  }
}

/* Mobile nav: a proper sliding side drawer (Bootstrap Offcanvas) instead of
   a dropdown from the top. Bootstrap resets #mainNav back to a normal
   inline flex row automatically at the lg breakpoint (navbar-expand-lg),
   so these rules only take effect below that. */
#mainNav.offcanvas {
  background-color: var(--ink-soft);
  width: min(80vw, 320px);
  box-shadow: -8px 0 32px rgba(0, 0, 0, 0.4);
}

/* #siteNavbar is always positioned (sticky-top sitewide, position:fixed on
   the home page via home.css), which makes it its own stacking context.
   #mainNav is a DOM descendant of it (required so Bootstrap's
   navbar-expand-lg breakpoint rules can un-offcanvas it back into a normal
   inline row on desktop) -- so no matter what z-index Bootstrap gives the
   drawer/backdrop internally, the whole navbar+drawer is capped at the
   navbar's own z-index against OTHER fixed page chrome (floating call/
   WhatsApp buttons, the quick-lead popup, flash toasts), which all sit
   higher and paint over an open drawer. Lift the whole navbar above every
   other fixed layer, but only while the drawer is actually open, so the
   normal (closed) navbar stacking is untouched. */
#siteNavbar:has(#mainNav.show),
#siteNavbar:has(#mainNav.showing) {
  z-index: 1100;
}

#mainNav .offcanvas-header {
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

#mainNav .navbar-nav {
  gap: 0.25rem;
}

#mainNav .nav-link {
  padding: 0.75rem 0.25rem;
  font-size: 1.05rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

#mainNav .nav-link:hover,
#mainNav .nav-link:focus-visible,
#mainNav .nav-link.active {
  color: var(--accent);
}

/* Portfolio detail hero image: source photos vary wildly in aspect ratio
   (some are tall phone-camera portraits), so cap the height and crop
   instead of letting img-fluid stretch the page to the photo's height. */
.project-hero-image {
  width: 100%;
  height: 480px;
  object-fit: cover;
}

@media (max-width: 576px) {
  .project-hero-image {
    height: 260px;
  }
}

/* Flash message (e.g. contact form success): fixed to the viewport so it's
   visible no matter where the page is scrolled when it appears, instead of
   sitting in normal document flow where an anchor-scrolled page can hide it. */
.flash-toast-wrap {
  position: fixed;
  top: 84px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1080;
  width: min(90vw, 640px);
}

.flash-toast {
  box-shadow: 0 0.5rem 1.5rem rgba(0, 0, 0, 0.25);
}

@media (max-width: 576px) {
  .flash-toast-wrap {
    top: 72px;
  }
}
