/* ============================================================
   BTE SERVICES CAROUSEL
   ============================================================ */

/* ---- Section ---- */
.bte-services {
    position: relative;
    /* Explicit low z-index (2026-07-12) — defensive reinforcement
       alongside the anticipatePin fix in bte-about.js and the
       existing z-index:50 on .bte-about__inner (about.css): during
       the brief window where Pic Right/About has already switched to
       position:fixed but Services hasn't fully scrolled out of view
       yet, this guarantees Services can never win the stacking order
       against it, regardless of any other z-index this section's own
       children introduce (they stay scoped under this same parent
       stacking context either way). */
    z-index: 1;
    /* Transparent so the fixed background (main.css) shows through
       continuously with any other hex section above/below it */
    background-color: transparent;
}

/* ---- Intro panel ---- */
.bte-services__intro {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    min-height: 16vh;
    /* Reduced from var(--space-32) (8rem/128px) — that was far more
       top clearance than the sticky header actually needs, pushing
       this section (and the carousel below it) down enough that it
       no longer fit above the fold on a typical viewport. */
    padding: var(--space-16) var(--gutter) var(--space-4);
    gap: 0; /* 2026-07-23 — eyebrow tight to heading (client) */
    pointer-events: none;
    z-index: 2;
}

/* 2026-07-23 — the shared .bte-eyebrow carries margin-bottom:var(--space-2);
   inside the Services intro that sat the "What We Offer" eyebrow noticeably
   above "OUR SERVICES". Zero it here so the two read as one tight unit. */
.bte-services__intro .bte-eyebrow {
    margin-bottom: 0;
}

/* Intro heading bleed — full width, clips off edges. Starts at this
   large size and shrinks on scroll via initIntroHeading() in
   bte-services.js (see .is-shrunk below, plus the GSAP scrub tween) —
   the small top-left appearance in the reference screenshot is the
   already-shrunk end state, not how this looks at rest. */
.bte-services__intro-heading {
    /* 2026-07-14, second pass — was clamp(5rem, 13vw, 14rem), then
       clamp(3rem, 9vw, 8.5rem) once that was confirmed still running
       off the right edge. Client asked for it smaller again — lowered
       further across the board.
       2026-07-16, third pass — "quite large... should shrink down to
       a smaller size" on the homepage at normal desktop width.
       Lowered again. */
    font-size: clamp(1.75rem, 4.5vw, 3.75rem);
    color: var(--bte-white);
    line-height: 0.9;
    white-space: nowrap;
    /* ED-AE will apply scroll-triggered reveal on this */
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out);
}

.bte-services__intro-heading.is-visible {
    opacity: 1;
    transform: translateY(0);
}

/* ---- Carousel panel ---- */
.bte-services__carousel-panel {
    position: relative;
    min-height: 80vh;
    display: flex;
    flex-direction: column;
    padding-top: var(--space-10);
    padding-bottom: var(--space-4);
    overflow: hidden;
}

/* ---- Header row ---- */
.bte-services__header {
    display: flex;
    align-items: center;
    justify-content: flex-end;  /* arrows pushed right */
    gap: var(--space-6);
    padding: var(--space-8) var(--gutter) var(--space-6);
}

/* .bte-services__header-text removed — heading lives in sticky intro */

/* Section-size heading used as GSAP target for scrub animation.
   2026-07-16 — lowered to match the smaller resting size above
   (was clamp(2rem, 4vw, 4rem), tuned for the old, larger resting
   clamp; left as-is it would have ended up BIGGER than the resting
   heading at some widths once that was reduced). */
.bte-services__intro-heading.is-shrunk {
    font-size: clamp(1.25rem, 2.5vw, 2rem);
}

/* Desktop nav — top right */
.bte-services__nav {
    display: none;
    flex-shrink: 0;
}

@media (min-width: 768px) {
    .bte-services__nav { display: flex; gap: var(--space-3); }
}

/* Mobile nav — below carousel */
.bte-services__nav--mobile {
    display: flex;
    justify-content: center;
    gap: var(--space-4);
    padding-top: var(--space-8);
}

@media (min-width: 768px) {
    .bte-services__nav--mobile { display: none; }
}

/* ---- Carousel viewport ---- */
.bte-services__viewport {
    position: relative;
    width: 100%;
    overflow: hidden;   /* clips peeking side cards */
    flex: 1;
    display: flex;
    align-items: flex-start;
    /* 2026-07-14 fix — the active card's dotted border (.bte-services
       __card-border below) deliberately sits 14px outside the card via
       a negative inset, for a gap between the border and the image.
       With cards top-aligned (align-items:flex-start) and this
       viewport's own overflow:hidden clipping anything outside its
       box, that top 14px of border had nowhere to render and was
       getting cut off — confirmed live via screenshot, the dotted
       line was missing along the top edge of the active card. This
       padding just reserves that room so the same overflow:hidden
       rule (still needed to clip peeking side cards) no longer clips
       the border too.
       Note: with padding-top on a flexbox container, the flex-start
       alignment sits cards below this padding rather than at the
       true top of the box — that's exactly what creates the room the
       border needs. */
    padding-top: 18px;
}

/* ---- Track ---- */
.bte-services__track {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    /* Centred: push track so active card is in the middle.
       Generous inline padding (not just the gutter) is deliberate —
       without enough room on both ends, the first/last cards have
       nothing to shift against to reach true centre, so they'd grow
       "in place" at the track's edge instead of centring properly. */
    padding-inline: clamp(var(--gutter), 30vw, 500px);
    transition: transform 0.6s var(--ease-out);
    will-change: transform;
}

/* ---- Card wrapper ---- */
.bte-services__card {
    position: relative;
    flex-shrink: 0;
    /* Base (non-active) size */
    width: clamp(180px, 28vw, 340px);
    transition:
        width 0.55s var(--ease-out),
        opacity 0.55s var(--ease-out),
        transform 0.55s var(--ease-out);
    opacity: 0.45;
    transform: scale(0.9);
}

/* 2026-07-14 — REPLACED the SVG stroke-dashoffset border (8 rounds
   of fixes across sizing timing, z-index/paint order, and viewBox/
   CSS-box sync — console diagnostics eventually proved the geometry
   was correct, yet the visual result still wasn't, meaning the
   technique itself was the problem, not any one bug in it) with the
   exact same plain CSS outline technique already proven reliable,
   with zero reported issues, on the Product Categories carousel
   (.bte-pcat__card.is-active .bte-pcat__card-inner in
   product-categories.css) — copied 1:1 per client request. No JS,
   no SVG, no viewBox math, no cross-card stacking-context risk: the
   browser positions/sizes an outline natively and it always follows
   border-radius, so there's nothing left to get out of sync. Trade-
   off: this drops the animated "marching ants" dot movement the SVG
   version had (outline can't animate stroke-dashoffset) — a static
   dashed border instead, matching Product Categories exactly. */
.bte-services__card.is-active .bte-services__card-inner {
    outline: 1.5px dashed var(--bte-teal);
    outline-offset: 14px;
}

/* Active card — larger, full opacity */
.bte-services__card.is-active {
    width: clamp(280px, 44vw, 600px);
    opacity: 1;
    transform: scale(1);
}

@media (max-width: 767px) {
    .bte-services__card {
        width: clamp(160px, 55vw, 240px);
    }
    .bte-services__card.is-active {
        width: clamp(240px, 78vw, 380px);
    }

    /* 2026-07-24 — the section didn't fit one screen on phones: the
       intro (min-height:16vh) + carousel panel (min-height:80vh) plus
       padding added up past 100vh. Trim both so it fits. */
    .bte-services__intro {
        min-height: auto;
        padding-top: var(--space-10);
        padding-bottom: var(--space-2);
    }
    .bte-services__carousel-panel {
        min-height: auto;
        padding-top: var(--space-6);
        padding-bottom: var(--space-8);
    }

    /* 2026-07-24 — the heading only faded/slid in on mobile (the desktop
       shrink is a pinned scrub that can't run here). Add a scale so it
       still visibly "shrinks into place" as it reveals, closer to desktop. */
    .bte-services__intro-heading {
        transform: translateY(24px) scale(1.14);
        transform-origin: left center;
    }
    .bte-services__intro-heading.is-visible {
        transform: translateY(0) scale(1);
    }
}

/* ---- Card inner (no longer a link — see .bte-services__card-cta,
   which is now its own separate link) ---- */
.bte-services__card-inner {
    display: block;
    position: relative;
    aspect-ratio: 5 / 4;
    border-radius: var(--radius-xl);
    overflow: hidden;
    text-decoration: none;

    /* No border by default */
    border: 1.5px solid transparent;
    transition:
        border-color 0.55s var(--ease-out),
        box-shadow 0.55s var(--ease-out);
}

/* Glow on active card — the dashed border itself now comes from the
   plain CSS outline set above (.bte-services__card.is-active
   .bte-services__card-inner), which sits outside the card with a
   genuine gap from the image, rather than a plain CSS border directly
   on this element (which clips the image via overflow:hidden,
   leaving no room for a gap at all). */
.bte-services__card.is-active .bte-services__card-inner {
    box-shadow: var(--glow-teal), var(--shadow-lg);
}

/* ---- Card image ---- */
.bte-services__card-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.7s var(--ease-out), filter 0.5s;
    filter: brightness(0.7);
}

.bte-services__card.is-active .bte-services__card-img {
    filter: brightness(0.85);
}

.bte-services__card-inner:hover .bte-services__card-img {
    transform: scale(1.04);
}

/* ---- Gradient overlay ---- */
.bte-services__card-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(
        to top,
        rgba(0, 0, 0, 0.85) 0%,
        rgba(0, 0, 0, 0.4)  40%,
        transparent         70%
    );
    z-index: 1;
}

/* ---- Card body (title + CTA) ---- */
.bte-services__card-body {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 2;
    padding: var(--space-6);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-5);

    /* Always visible — title shows on all cards */
    opacity: 1;
    transform: translateY(0);
    transition:
        opacity 0.4s var(--ease-out),
        transform 0.4s var(--ease-out);
    transition-delay: 0.1s;
}

/* CTA hidden on non-active cards, slides up when active */
.bte-services__card-cta {
    opacity: 0;
    transform: translateY(8px) skewX(calc(var(--btn-skew-deg, 12deg) * -1));
    transition:
        opacity 0.35s var(--ease-out),
        transform 0.35s var(--ease-out);
    transition-delay: 0.15s;
}

.bte-services__card.is-active .bte-services__card-body {
    opacity: 1;
    transform: translateY(0);
}

.bte-services__card.is-active .bte-services__card-cta {
    opacity: 1;
    transform: translateY(0) skewX(calc(var(--btn-skew-deg, 12deg) * -1));
}

/* ---- Card title ---- */
.bte-services__card-title {
    font-family: var(--font-display);
    font-size: clamp(1rem, 2vw, 1.4rem);   /* smaller default for non-active */
    font-weight: 800;
    text-transform: uppercase;
    color: var(--bte-white);
    line-height: 1.05;
    text-shadow: 0 2px 16px rgba(0,0,0,0.7);
    transition: font-size 0.4s var(--ease-out);
}

.bte-services__card.is-active .bte-services__card-title {
    font-size: clamp(1.5rem, 3.5vw, 2.5rem);  /* full size on active card */
}

/* NOTE: the old "outline white pill" override that used to live here
   has been removed entirely — it was silently overriding
   bte-btn--outline-red's color and border back to white (same CSS
   specificity, but this file loads after style.css, so it won.
   Fun and undebuggable, when everything upstream looked correct.
   Also had pointer-events: none, which meant clicks here fell through
   to the card behind rather than the link itself ever receiving
   them). The CTA now uses bte-btn--outline-red's own styling
   untouched — red text, red border, properly skewed to match the
   other buttons, with the actual link receiving clicks directly. */

/* ---- Scroll indicator ---- */
.bte-services__scroll {
    position: absolute;
    /* 2026-07-18 — sit nearer the bottom edge (was clamp(space-16,10vh,
       space-24)); the centred nav arrows now sit above it, so this drops
       down to leave a clear gap between the two. */
    bottom: clamp(var(--space-6), 4vh, var(--space-10));
    left: 50%;
    transform: translateX(-50%);
    z-index: 5;
}

/* ---- Reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
    .bte-services__track         { transition: none; }
    .bte-services__card          { transition: none; }
    .bte-services__card-inner    { transition: none; }
    .bte-services__card-img      { transition: none; }
    .bte-services__card-body     { transition: none; }
    .bte-services__card-cta      { transition: none; opacity: 1; }
    .bte-services__intro-heading { transition: none; opacity: 1; transform: none; }
}

/* 2026-07-14 fix — short-viewport cropping. .bte-services__intro
   (min-height:16vh) plus .bte-services__carousel-panel
   (min-height:80vh) add up to ~96vh, plus fixed padding on top of
   that — on a shorter laptop screen this genuinely doesn't fit inside
   the pinned section without cropping. Confirmed live via screenshot.
   Reduces the vh budget and padding directly rather than scaling the
   rendered result (which was tried first and confirmed to distort
   the carousel cards' fixed aspect-ratio images). Desktop-width-only,
   matching the pin's own JS gate (max-width:1023px disables it). */
@media (max-height: 820px) and (min-width: 1024px) {
    .bte-services__intro {
        min-height: 8vh;
        padding: var(--space-8) var(--gutter) var(--space-2);
    }
    .bte-services__carousel-panel {
        min-height: 62vh;
        padding-top: var(--space-6);
        padding-bottom: var(--space-2);
    }
    .bte-services__header {
        padding: var(--space-4) var(--gutter) var(--space-3);
    }
}


/* ============================================================
   FIX (2026-07-02): close the gap between the intro heading
   and the carousel cards, and move the nav arrows from the
   top-right header row down to the bottom-right corner of the
   carousel panel to match the Figma spec.
   ============================================================ */

.bte-services__header {
  padding: 0;
  min-height: 0;
}

.bte-services__carousel-panel {
  padding-top: var(--space-20);
}

.bte-services__viewport-wrap {
  position: relative;
}

/* 2026-07-16 fix — no mobile-specific sizing existed for the intro
   heading/panel at all (only a desktop-short-viewport rule further
   up), so on a phone this section's own height (intro + carousel
   panel + their padding) ran ~48px taller than the viewport itself —
   the carousel visibly ran off the bottom of the screen. Reported
   live: "What We Offer - Services Section is disappearing off the
   bottom the screen on smaller screens can the title be smaller and
   move closer to carousel?" Shrinks the heading and tightens the
   intro's own padding/gap so the whole section fits within one
   screen instead of needing to scroll a pinned section to see it. */
@media (max-width: 767px) {
    .bte-services__intro {
        min-height: 0;
        padding: var(--space-6) var(--gutter) var(--space-2);
        gap: var(--space-2);
    }
    /* 2026-07-16, second pass — still reported live as "cropped out
       and too big" after the first reduction (clamp(1.75rem, 8vw,
       3rem)). Lowered further, and — since white-space:nowrap is
       inherited from .bte-heading-bleed (style.css) and this heading
       is deliberately full-bleed/edge-clipping by design on desktop —
       switched to wrapping on mobile specifically, with a max-width
       safety margin, so "OUR SERVICES" can never run past the screen
       edge or get clipped on a narrow phone regardless of exact
       device width. */
    /* 2026-07-21 — forced with !important: the heading carries
       .bte-heading-bleed (font-size:var(--text-bleed), huge) and the
       desktop scrub used to set an inline font-size; on mobile neither
       should win. Keep it small, wrapped and never past the edge. */
    .bte-services__intro-heading,
    .bte-services__intro-heading.bte-heading-bleed {
        font-size: clamp(1.5rem, 7vw, 2.25rem) !important;
        white-space: normal !important;
        max-width: 100% !important;
        transform: none !important;
        overflow-wrap: break-word;
    }
    /* 2026-07-17 — the arrows sat far below the cards on mobile: the
       panel keeps its 80vh min-height (no pin runs on mobile to justify
       it), and .bte-services__viewport's flex:1 stretched to fill it,
       pushing the top-aligned card up and the arrows down to the bottom.
       On mobile, collapse the panel to its content and stop the viewport
       stretching, so the arrows sit right beneath the cards. */
    .bte-services__carousel-panel {
        padding-top: var(--space-4);
        min-height: auto;
        padding-bottom: var(--space-8);
    }
    .bte-services__viewport {
        flex: 0 0 auto;
    }
    .bte-services__nav--mobile {
        padding-top: var(--space-4);
    }
}

.bte-services__nav {
  position: absolute;
  /* 2026-07-17 — centre the arrows below the (centred) open tile, matching
     the Product Categories treatment, instead of tucking them bottom-right
     where they were hard to notice. Span full width + justify-content:center.
     2026-07-18 — lifted further up (was -space-16) so they clear the
     scroll-to-continue cue below, which was sitting too close. */
  left: 0;
  right: 0;
  bottom: 0;
  transform: translateY(calc(-1 * var(--space-28, 7rem)));
  /* 2026-07-23 — arrows pushed to the right edge so they clear the large
     centred carousel tile (client). Was justify-content:center, which sat
     them directly under/over the open box. */
  justify-content: flex-end;
  padding-right: var(--gutter);
  z-index: 5;
}

/* Services nav arrows now use the shared .bte-arrow-btn look with no
   local override (dashed blue circle, red chevron) -- this section used
   to swap the border to white and dim the buttons to 0.85 opacity, but
   that's no longer needed now the whole site draws from one definition. */

/* ============================================================
   MOBILE (phones) — 2026-07-21
   Deeper carousel cards, and room so the active card's dashed outline
   (outline-offset:14px) isn't cropped top/bottom by the viewport clip.
   ============================================================ */
@media (max-width: 767px) {
    .bte-services__card-inner { aspect-ratio: 3 / 4; }   /* was 5/4 — deeper */
    .bte-services__viewport { padding-block: 24px; }     /* room for the dashes */
}
