/* ------------------------------------------------------------------ *
 * Motion start states — CSS-driven and fail-safe.
 *
 * The previous version of this file shipped only *pre-animation* states:
 * masked text sat at translateY(110%), the nav at height:0, the drawer at
 * opacity:0, and nothing but the GSAP layer could bring them back. If that
 * layer failed for any reason, most of the page was invisible.
 *
 * Here every hidden state is gated behind `html.js`, which a one-line inline
 * script sets before first paint. No script, no gate: the text renders. The
 * reveal itself is a plain CSS transition switched on by an `.is-in` class.
 * ------------------------------------------------------------------ */

/* --- navigation drawer ------------------------------------------------ */
/* Height is set in pixels by the script so the transition has two real
   endpoints; `auto` cannot be animated. */
[data-animation="nav"] {
  height: 0;
  overflow: hidden;
  transition: height .55s var(--ease-out-expo);
}
[data-animation="nav_aside"] { transition: opacity .5s ease .15s; }
[data-animation="nav_aside"].is-open { opacity: 1; }

[data-animation="header-overlay"] {
  transform: translateY(-100%);
  transition: transform .55s var(--ease-out-expo);
}
[data-animation="header-overlay"].is-open { transform: translateY(0); }

/* --- enquiry drawer --------------------------------------------------- */
[data-animation="cart"] {
  opacity: 0;
  visibility: hidden;
  transition: opacity .4s ease, visibility 0s linear .4s;
}
[data-animation="cart"].is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity .4s ease, visibility 0s;
}

/* --- masked text ------------------------------------------------------ */
/* Splitting.js leaves --char-index on every .char, so the stagger needs no
   JavaScript timeline — it is a transition-delay. */
html.js [data-animation="heroH1"] .char,
html.js [data-animation="heroSub"] .char,
html.js [data-animation="paragraphs"] span > span {
  transform: translateY(110%);
}
html.js [data-animation="heroH1"].is-in .char,
html.js [data-animation="heroSub"].is-in .char,
html.js [data-animation="paragraphs"].is-in span > span {
  transform: translateY(0);
  transition: transform .9s var(--ease-out-expo);
}
html.js [data-animation="heroH1"].is-in .char,
html.js [data-animation="heroSub"].is-in .char {
  transition-delay: calc(var(--char-index, 0) * 22ms);
}

/* --- preloader -------------------------------------------------------- */
/* Without the script there is nothing to retract it, so it must not exist. */
html:not(.js) [data-animation="preloader"] { display: none; }
[data-animation="preloader"] { transition: opacity .5s ease, visibility 0s linear .5s; }
[data-animation="preloader"].is-done {
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

/* --- horizontal rails ------------------------------------------------- */
/* Both rails used to be moved by ScrollTrigger (pin + scrub) and by a drag
   handler. They are now ordinary scroll containers: the browser handles
   momentum, keyboard, trackpad and touch for free, and nothing can leave a
   rail stranded mid-transform. */
.Showcase_showcase-container__G3K1C,
.Carousel_scrollable__KA04Z {
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
}
.Showcase_showcase-container__G3K1C::-webkit-scrollbar,
.Carousel_scrollable__KA04Z::-webkit-scrollbar { display: none; }

/* The drag rail is laid out at its own content width inside a clipping
   parent, so making the rail itself scrollable achieves nothing — the scroll
   port has to be the parent, and the rail stays as wide as its contents. */
[data-animation="draggable"] { width: max-content; max-width: none; }

/* The 50vw side padding existed so the pinned track could be scrubbed past
   the viewport centre. With native scrolling it just adds two empty screens. */
.Showcase_showcase-content___NyNB {
  padding-inline: max(10px, 1.6rem);
  padding-right: max(10px, 1.6rem);
}
.Showcase_showcase-content-item__d19uX,
[data-animation="draggable-child"] { scroll-snap-align: center; }

/* The custom cursor puck belonged to the drag handler. */
[data-animation="draggable"] { cursor: auto; }
[data-animation="draggable"] .mqcsr { display: none; }

/* --- footer cover ----------------------------------------------------- */
/* Was scale(1.25) waiting for a scrub to settle it back to 1. */
[data-animation="footerImage"] { transform: none; }

/* --- hero subheading -------------------------------------------------- */
/* The markup carries style="--transX:-536.3125px", a pixel offset captured
   from the reference at its own window width. The block's own width bottoms
   out at max(290px, 56rem), so below roughly 1000px the shift no longer has
   any slack to consume and drags the line clean off the left edge. Scale the
   offset with the viewport, and drop it entirely once there is no room. */
.Hero_hero-main-flex__EcBod h2 { transform: none; }
@media (min-width: 1000px) {
  .Hero_hero-main-flex__EcBod h2 { transform: translateX(-37.2vw); }
}

/* --- focus ------------------------------------------------------------ */
a[data-route] { cursor: pointer; }
a[data-route]:focus-visible,
button:focus-visible,
input:focus-visible {
  outline: 2px solid #4d3d30;
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: .01ms !important; }
}
