/* =========================================================
   style.css — Project Banners
   Self-contained; no dependency on any other stylesheet.
   ========================================================= */

/* ---------- Reset & base ---------- */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-size: 16px;
}

body {
  font-family: 'Inter', 'Segoe UI', system-ui, sans-serif;
  background: #0a0a0a;
  color: #f0f0f0;
  /* Prevent body scroll; the .scroll-container handles it */
  height: 100vh;      /* fallback for browsers without dvh */
  height: 100dvh;
  overflow: hidden;
}

/* ---------- Scroll container ---------- */
.scroll-container {
  height: 100vh;      /* fallback */
  height: 100dvh;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;

  /* Hide scrollbar for a cleaner look while keeping it functional */
  scrollbar-width: none;       /* Firefox */
  -ms-overflow-style: none;   /* IE / Edge legacy */
}
.scroll-container::-webkit-scrollbar {
  display: none;               /* Chrome / Safari */
}

/* ---------- Banner ---------- */
/*
 * .banner  — the outer scroll-snap target (exactly one per project).
 *             On desktop it locks to 100dvh; on mobile its height
 *             follows the image's natural aspect ratio instead.
 */
.banner {
  position: relative;
  width: 100%;
  height: 100vh;      /* fallback */
  height: 100dvh;
  scroll-snap-align: start;
  overflow: hidden;
}

/*
 * .banner__media — the image + overlay wrapper.
 *
 * Desktop: fills the banner absolutely (so it covers the full viewport).
 * Mobile:  becomes an in-flow block; its height is set by the <img>
 *          inside it, which carries its natural aspect ratio.
 *
 * All overlay and text children are positioned relative to this element.
 */
.banner__media {
  position: absolute;
  inset: 0;
  overflow: hidden;

  /* Flex so .banner__content sits vertically centred on desktop */
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
}

/* Full-bleed background image (desktop) */
/* object-position is set per-project via inline style in main.js         */
/* (defaults to 'center' when imagePosition is omitted in projects.js)    */
.banner__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center; /* overridden by inline style when imagePosition is set */
  /* Slight de-saturation so overlaid text pops */
  /* filter: saturate(0.8); */
  z-index: 0;
}

/* Dark gradient overlay — on .banner__media so it covers only the image  */
/* (important on mobile, where .banner__media no longer fills the banner) */
.banner__media::after {
  content: '';
  position: absolute;
  inset: 0;
  /* background:
    linear-gradient(
      to bottom,
      rgba(0, 0, 0, 0.45) 0%,
      rgba(0, 0, 0, 0.55) 40%,
      rgba(0, 0, 0, 0.72) 100%
    ); */
  z-index: 1;
  /* Must not block clicks on buttons that sit inside the same stacking context */
  pointer-events: none;
}

/* ---------- Text content ---------- */
.banner__content {
  position: relative;
  z-index: 2;
  padding: clamp(2rem, 6vw, 5rem);
  max-width: min(720px, 90%);
}

.banner__title {
  font-size: clamp(2.2rem, 5.5vw, 4.5rem);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: #ffffff;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.45);
  margin-bottom: 1rem;
}

.banner__description {
  font-size: clamp(1rem, 2vw, 1.25rem);
  font-weight: 400;
  line-height: 1.6;
  color: rgba(255, 255, 255, 0.88);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.4);
}

/* ---------- Pill buttons (bottom-left) ---------- */
.banner__actions {
  position: absolute;
  z-index: 2;
  bottom: clamp(1.75rem, 4vw, 3rem);
  left: clamp(2rem, 6vw, 5rem);
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.6em 1.5em;
  border-radius: 9999px;       /* pill shape */
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.18s ease, color 0.18s ease, box-shadow 0.18s ease;
  white-space: nowrap;
}

/* Demo button — solid white */
.btn--demo {
  background: #ffffff;
  color: #111111;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
.btn--demo:hover,
.btn--demo:focus-visible {
  background: #e6e6e6;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.4);
}

/* GitHub button — ghost/outline style */
.btn--github {
  background: rgba(255, 255, 255, 0.12);
  color: #ffffff;
  border: 1.5px solid rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(6px);
}
.btn--github:hover,
.btn--github:focus-visible {
  background: rgba(255, 255, 255, 0.22);
  border-color: rgba(255, 255, 255, 0.9);
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
}

/* ---------- Scroll indicator (first banner only) ---------- */
.scroll-hint {
  position: absolute;
  z-index: 2;
  bottom: clamp(1.75rem, 4vw, 3rem);
  right: clamp(2rem, 4vw, 3rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  opacity: 0.65;
  pointer-events: none;
}
.scroll-hint__label {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #ffffff;
}
.scroll-hint__arrow {
  width: 22px;
  height: 22px;
  border-right: 2px solid #fff;
  border-bottom: 2px solid #fff;
  transform: rotate(45deg);
  /* gentle pulse to draw attention */
  animation: pulse-down 1.6s ease-in-out infinite;
}
@keyframes pulse-down {
  0%, 100% { transform: rotate(45deg) translateY(0); opacity: 0.65; }
  50%       { transform: rotate(45deg) translateY(5px); opacity: 1; }
}

/* ---------- Accessible focus outline ---------- */
:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 3px;
}

/* ---------- Progress dots (nav) ---------- */
.nav-dots {
  position: fixed;
  right: 1.5rem;
  top: 50%;
  transform: translateY(-50%);
  z-index: 100;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  pointer-events: none;
}
.nav-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.35);
  border: 1.5px solid rgba(255, 255, 255, 0.6);
  transition: background 0.25s, transform 0.25s;
}
.nav-dot.active {
  background: #ffffff;
  transform: scale(1.4);
}

/* ==========================================================
   Mobile — max-width: 768px
   The fundamental shift: instead of forcing the banner to
   fill the viewport and cropping the image to fit, we let
   the image display at its natural aspect ratio and let the
   banner height follow. Banners may be shorter than the
   viewport; the user sees a sliver of the next one — that's
   intentional and acceptable per spec.
   ========================================================== */
@media (max-width: 768px) {

  /* ---- Body / scroll-container: allow natural-height content ---- */
  body {
    /* Remove the overflow:hidden lock so the scroll container
       can handle variable-height banners without clipping them. */
    overflow: hidden; /* keep — the container scrolls internally */
  }

  /* ---- Proximity snap: more forgiving than mandatory when
          banners have variable heights across images ---- */
  .scroll-container {
    scroll-snap-type: y proximity;
  }

  /* ---- Banner: height follows .banner__media (the image),
          not the viewport ---- */
  .banner {
    height: auto;
    min-height: 0;     /* allow banners shorter than viewport */
    overflow: visible; /* let the sliver of the next banner be visible */
  }

  /* ---- Image wrapper: switch from absolute (full-viewport fill)
          to in-flow block (height = image's natural height) ---- */
  .banner__media {
    position: relative; /* overrides desktop `position: absolute` */
    inset: auto;
    width: 100%;

    /* Dark fill for any letterbox areas that appear around a
       contained image (e.g. portrait image on landscape screen) */
    background: #111111;

    /* Reset the desktop flex centering — content is now
       absolutely positioned inside the image area instead */
    display: block;
  }

  /* ---- Image: natural aspect ratio, no cropping ---- */
  .banner__bg {
    position: static;   /* in-flow — sets .banner__media's height */
    display: block;
    width: 100%;
    height: auto;       /* height driven by pixel dimensions, not container */
    object-fit: contain; /* full image visible, nothing cropped */
    /* object-position from inline style still honoured */
  }

  /* ---- Text content: absolutely overlay the image area ---- */
  .banner__content {
    position: absolute; /* relative to .banner__media (position: relative) */
    inset: 0;           /* cover the whole image */
    z-index: 2;

    /* Vertical flex so title → description stack naturally */
    display: flex;
    flex-direction: column;
    justify-content: flex-end; /* anchor text near the bottom of image */
    padding: 1rem 1.1rem 0.5rem;
    max-width: 100%;
  }

  .banner__title {
    font-size: clamp(1.2rem, 5vw, 1.8rem);
    margin-bottom: 0.4rem;
    line-height: 1.15;
  }

  .banner__description {
    font-size: clamp(0.78rem, 3.2vw, 0.92rem);
    line-height: 1.5;
  }

  /* ---- Buttons: in-flow inside .banner__content, below description ---- */
  /*      .banner__actions is a sibling of .banner__content, both           */
  /*      absolutely positioned inside .banner__media.                      */
  .banner__actions {
    bottom: 0.6rem;
    left: 1.1rem;
    gap: 0.5rem;
    /* Inherit position: absolute + z-index: 2 from base CSS */
  }

  /* WCAG 2.5.5 — 44 × 44 px minimum touch target */
  .btn {
    min-height: 44px;
    padding: 0.5em 1.1em;
    font-size: 0.82rem;
  }

  /* ---- Scroll hint: tuck into the image bottom-right ---- */
  .scroll-hint {
    bottom: 0.6rem;
    right: 0.75rem;
  }

  /* ---- Nav dots: hidden on mobile (not enough side space) ---- */
  .nav-dots {
    display: none;
  }
}

/* Slightly narrower phones (≤ 430px) — tighten side padding */
@media (max-width: 430px) {
  .banner__content {
    padding-left: 0.9rem;
    padding-right: 0.9rem;
  }
  .banner__actions {
    left: 0.9rem;
  }
}
