/* =========================================================================
   Kaizen Soccer Academy — site enhancement layer
   Progressive enhancement only: responsiveness, scroll reveals, mobile nav.
   The original page aesthetics, layout and content are left untouched.
   ========================================================================= */

/* ---- Scroll reveal -------------------------------------------------------
   Elements are only hidden once JS has flagged support (.reveal-enabled on
   <html>), so the site is fully visible if JS is disabled or fails. */
.reveal-enabled .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s cubic-bezier(.22,.61,.36,1),
              transform .7s cubic-bezier(.22,.61,.36,1);
  will-change: opacity, transform;
}
.reveal-enabled .reveal.in-view {
  opacity: 1;
  transform: none;
}

/* Staggered children inside a revealing block (cards, steps, grid items). */
.reveal-enabled .reveal :is([class*="-card"], [class*="-item"], .step, .testi-card) {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s cubic-bezier(.22,.61,.36,1),
              transform .6s cubic-bezier(.22,.61,.36,1);
}
.reveal-enabled .reveal.in-view :is([class*="-card"], [class*="-item"], .step, .testi-card) {
  opacity: 1;
  transform: none;
}
.reveal-enabled .reveal.in-view :is([class*="-card"], [class*="-item"], .step, .testi-card):nth-child(2)  { transition-delay: .07s; }
.reveal-enabled .reveal.in-view :is([class*="-card"], [class*="-item"], .step, .testi-card):nth-child(3)  { transition-delay: .14s; }
.reveal-enabled .reveal.in-view :is([class*="-card"], [class*="-item"], .step, .testi-card):nth-child(4)  { transition-delay: .21s; }
.reveal-enabled .reveal.in-view :is([class*="-card"], [class*="-item"], .step, .testi-card):nth-child(5)  { transition-delay: .28s; }
.reveal-enabled .reveal.in-view :is([class*="-card"], [class*="-item"], .step, .testi-card):nth-child(6)  { transition-delay: .35s; }
.reveal-enabled .reveal.in-view :is([class*="-card"], [class*="-item"], .step, .testi-card):nth-child(7)  { transition-delay: .42s; }
.reveal-enabled .reveal.in-view :is([class*="-card"], [class*="-item"], .step, .testi-card):nth-child(8)  { transition-delay: .49s; }

/* Gentle lift on interactive cards / buttons (does not alter resting look). */
.btn-gold, .btn-ghost, .btn-gold-outline, .nav-cta,
.program-card, .step, .testi-card, .empathy-card,
[class*="-card"] {
  transition: transform .25s ease, box-shadow .25s ease, background-color .25s ease, color .25s ease;
}
.btn-gold:hover, .btn-ghost:hover, .btn-gold-outline:hover, .nav-cta:hover { transform: translateY(-2px); }
.program-card:hover, .testi-card:hover, .empathy-card:hover { transform: translateY(-4px); }

/* ---- Responsive flex safety ---------------------------------------------
   Button rows and "title + action" header rows are laid out with flex but
   no wrap in the source, so they can overflow on narrow screens. Allowing
   them to wrap is harmless on desktop (it only triggers on real overflow). */
[class*="-cta"], [class*="-ctas"], [class*="-btns"], .cta-btns, .hero-ctas {
  flex-wrap: wrap;
}

@media (max-width: 860px) {
  /* Stack heading-vs-button bars instead of crowding them on one line. */
  .programs-header, .footer-bottom, .shop-hero, .urgency-band {
    flex-wrap: wrap;
    gap: 16px;
  }
}

/* ---- Mobile overflow safety ---------------------------------------------
   A handful of layouts use inline-style grids, fixed widths, intrinsically
   sized media, or no-wrap buttons that the per-page (class-based) media
   rules can't reach. These guards stop horizontal overflow on small screens
   without affecting the desktop layout (where the content already fits). */

/* Inline grid_template_columns lives on the element's style attribute and
   outranks class rules, so an !important override is required. */
@media (max-width: 980px) {
  [style*="repeat(3"], [style*="repeat(4"] {
    grid-template-columns: repeat(2, 1fr) !important;
  }
}
@media (max-width: 640px) {
  [style*="grid-template-columns"] { grid-template-columns: 1fr !important; }
}

@media (max-width: 860px) {
  /* Media never forces a track wider than the viewport. */
  img, video, .iph, [class*="placeholder"] { max-width: 100%; }
  /* Let 1fr tracks shrink below their content's intrinsic width. */
  [class*="grid"] > *, [class*="-row"] > *, [class*="-layout"] > *,
  .hero > *, .empathy-grid > *, .problem-grid > * { min-width: 0; }
}

@media (max-width: 480px) {
  /* Long no-wrap buttons can shrink by wrapping their label.
     !important is needed because some buttons set white-space inline. */
  .btn-gold, .btn-ghost, .btn-gold-outline, .btn-black,
  .btn-primary, .btn-secondary { white-space: normal !important; }
}

@media (max-width: 640px) {
  /* Inline-styled "text + button" banner on the training page: stack it and
     trim its inline padding so the no-wrap CTA can't push past the viewport. */
  #free-trial {
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 20px !important;
    padding-left: 20px !important;
    padding-right: 20px !important;
  }
}

@media (max-width: 640px) {
  /* The slide-in cart is a fixed 420px; cap it to the viewport on phones. */
  .cart-drawer { width: 100%; max-width: 100vw; }
}

/* ---- Filled image/video placeholders -------------------------------------
   A placeholder frame keeps its exact box (aspect-ratio) and gold inset
   border; the media fills it via object-fit:cover and the gold border is
   redrawn on top so the original framing/proportions are preserved. */
.has-media { position: relative; overflow: hidden; }
.has-media > img,
.has-media > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
  display: block;
}
.has-media > span { display: none; }
.has-media::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 2px var(--gold);
  pointer-events: none;
}

/* ---- Mobile: show the whole photo ----------------------------------------
   Program photos are tall portraits placed in frames the desktop layout makes
   wide and short, filled with object-fit:cover. That framing is deliberate on
   desktop, but once a grid collapses to one column the frame gets shorter
   still and the crop eats the subject - heads, feet and whole players go
   missing. On phones there is no layout reason to hold a fixed frame, so these
   frames become intrinsic: the image renders at its own aspect ratio, in full,
   with the gold border drawn around whatever shape that is.

   Scoped to 640px, which is where these grids actually collapse. Above it the
   rows are still side-by-side and the frame gets its height from the row, so
   an intrinsic image would leave a gap under itself. */
@media (max-width: 640px) {
  /* Training page program rows; landing-page hero photos; the Camps &
     Clinics feature photos. */
  .offer-img.has-media,
  .hero-right .iph.has-media,
  .hero-grid .photo,
  .offer-grid .photo,
  .clinic-feature .photo {
    aspect-ratio: auto !important;
    height: auto !important;
    min-height: 0 !important;
    display: block;
  }
  .offer-img.has-media > img,
  .hero-right .iph.has-media > img,
  .hero-grid .photo img,
  .offer-grid .photo img,
  .clinic-feature .photo img {
    position: static !important;
    width: 100%;
    height: auto !important;
    object-fit: contain;
    object-position: center !important;
  }
}

/* ---- Mobile: landing-page hero stat badge --------------------------------
   The gold "M-F / sessions available" badge is absolutely positioned against
   the hero photo cell. That cell has no height of its own on a single-column
   layout, so the badge drifted off the left edge and landed on top of the
   CTA. Let it sit as a normal block under the photo instead. Same 640px scope
   as the photo rule - while the hero is still two-column the badge sits
   correctly over the photo. */
@media (max-width: 640px) {
  .hero-right { min-height: 0; }
  .hero-stat-badge {
    position: static !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    display: block;
    width: 100%;
  }
}

/* ---- Mobile: training program row order ----------------------------------
   The program rows alternate on desktop - photo left / text right, then text
   left / photo right - which reads as a nice zigzag. Stacked into one column
   that DOM order becomes text, photo, photo, text, text, photo: the photos
   pair up and so do the write-ups, so the page loses its rhythm. Force every
   row to the same order on phones, heading first, so it reads consistently as
   topic then photo. Heading first also means the sticky sub-nav's anchor jumps
   land on the section title rather than on a photo. */
@media (max-width: 640px) {
  .offer-row .offer-card { order: 1; }
  .offer-row .offer-img { order: 2; }
}

/* ---- Mobile: testimonial walls -------------------------------------------
   The featured review is `grid-column: span 2`. Once the wall collapses to a
   single explicit column that span conjures an implicit second column, so the
   whole wall stays two-up (and overflows) on phones. Pin it back to one. */
@media (max-width: 640px) {
  .testi-featured { grid-column: span 1 !important; }
}

/* ---- Mobile: product gallery ---------------------------------------------
   The gallery is a 2-column grid: a rail of thumbnails beside the main image.
   Collapsed to one column the rail stacks *above* the main image, so four
   full-width photos push the size picker and Add to Cart button off-screen.
   Put the main image first and lay the thumbnails out as a short scrolling
   strip underneath it. */
@media (max-width: 640px) {
  .product-images {
    position: static;
    max-height: none;
    overflow: visible;
    gap: 8px;
  }
  .main-image {
    order: -1;
    aspect-ratio: 1 / 1;
    max-height: none;
  }
  .image-thumbs {
    flex-direction: row;
    max-height: none;
    overflow-x: auto;
    gap: 8px;
    padding-bottom: 2px;
  }
  .image-thumbs .thumb {
    flex: 0 0 68px;
    width: 68px;
  }
}

/* ---- Mobile navigation ---------------------------------------------------
   nav / .nav-links / .nav-cta markup is identical across every page, so the
   responsive nav lives here once. */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 42px;
  height: 38px;
  padding: 8px;
  background: transparent;
  border: 1px solid rgba(245,245,240,0.18);
  border-radius: 2px;
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  height: 2px;
  width: 100%;
  background: var(--white);
  transition: transform .3s ease, opacity .3s ease;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 860px) {
  .nav-toggle { display: flex; }
  .nav-cta { margin-left: auto; margin-right: 14px; }
  .nav-links {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    background: var(--black);
    border-bottom: 1px solid rgba(245,245,240,0.07);
    box-shadow: 0 18px 30px rgba(0,0,0,0.45);
    padding: 8px 22px 16px;
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
    transition: max-height .35s ease, opacity .25s ease, padding .35s ease;
  }
  .nav-links.open {
    max-height: 60vh;
    opacity: 1;
    pointer-events: auto;
  }
  .nav-links li { width: 100%; padding: 13px 0; border-bottom: 1px solid rgba(245,245,240,0.06); }
  .nav-links li:last-child { border-bottom: none; }
  .nav-links a { font-size: 15px; }
  .nav-logo img { height: 42px; }
}

@media (max-width: 420px) {
  .nav-cta { padding: 9px 14px; font-size: 11px; }
  .nav-logo img { height: 36px; }
}

/* Desktop: truly center the nav links. space-between sat them off-center
   between the logo and the CTA, which became obvious under the transparent
   hero nav. nav is position:sticky, so the absolute links center against it. */
@media (min-width: 861px) {
  .nav-links { position: absolute; left: 50%; transform: translateX(-50%); }
}

/* Respect reduced-motion preferences: no transforms or transitions. */
@media (prefers-reduced-motion: reduce) {
  .reveal-enabled .reveal,
  .reveal-enabled .reveal.in-view,
  .reveal-enabled .reveal :is([class*="-card"], [class*="-item"], .step, .testi-card),
  .reveal-enabled .reveal.in-view :is([class*="-card"], [class*="-item"], .step, .testi-card) {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  .btn-gold, .btn-ghost, .btn-gold-outline, .nav-cta,
  .program-card, .testi-card, .empathy-card, [class*="-card"],
  .nav-toggle span, .nav-links {
    transition: none !important;
  }
}
