/* ===== Haven Cleaning Co. — base + hero ===== */

@import url('https://fonts.googleapis.com/css2?family=Jost:wght@400;500;600&display=swap');

:root {
  --cream: #f6f2e4;
  --brown-dark: #194c54;
  --brown-text: #122e33;
  --black: #1c1a17;
  --font-display: "benton-modern-display", serif;
  --font-body: 'Jost', sans-serif;
  --white: #ffffff;
  --gap: 6px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html, body {
  height: 100%;
  /* `overflow-x: hidden` makes this element a scroll container, which
     silently kills `position: sticky` for every descendant — it was why
     the Services stage scrolled away instead of pinning. `clip` prevents
     the same horizontal overflow WITHOUT creating a scroll container. */
  overflow-x: clip;
}

body {
  font-family: var(--font-body);
  color: var(--brown-text);
  background: var(--cream);
}

img { display: block; max-width: 100%; }

/* ===== Hero =====
   4-column grid matching the Figma:
   ┌───────────────┬─────┬─────┐
   │     TEXT      │     │     │
   ├───────┬───────┤  3  │  4  │
   │   1   │   2   │     │     │
   └───────┴───────┴─────┴─────┘
*/

.hero {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 39fr 61fr;
  gap: var(--gap);
  width: 100vw;
  height: 100vh;
  height: 100svh;
  padding: var(--gap);
  background: var(--cream);
  overflow: hidden;
}

.hero__text {
  grid-column: 1 / span 2;
  grid-row: 1;
  display: flex;
  flex-direction: column;
  /* Wordmark pinned to the top, blurb pushed to the bottom. */
  justify-content: space-between;
  padding: 3% 1% 1% 1%;
  background: var(--cream);
  container-type: inline-size;
  container-name: herotext;
}

.hero__title {
  font-family: var(--font-display);
  font-weight: 400;
  color: var(--brown-dark);
  line-height: 1;
  letter-spacing: 0.03em;
}

.hero__title .line1 {
  display: block;
  white-space: nowrap;
  --haven-fit: 31.2;
  font-size: calc(var(--haven-fit) * 1cqw);
  margin-right: -0.03em;
  visibility: hidden;

  /* Benton's caps fill only ~70% of the em box, so `line-height: 1` still
     leaves a band of dead space under the baseline that pushes the line
     below it down. Pull it back with an em-based negative margin (scales
     with the fitted size), then let text-box trim it exactly where the
     property is supported. Note we do NOT lower line-height itself —
     GSAP's mask:'chars' builds its clipping boxes from the line box, and
     squeezing it clips the tops of the letters mid-reveal. */
  margin-bottom: calc(-0.19em + 20px);
}

@supports (text-box: trim-both cap alphabetic) {
  .hero__title .line1 {
    text-box: trim-both cap alphabetic;
    margin-bottom: 20px;
  }
}

.fonts-failed .hero__title .line1 {
  visibility: visible;
}

.hero__title .line2 {
  display: block;
  white-space: nowrap;
  /* Sized in hero-fit.js as a ratio of HAVEN's fitted size, so it scales
     with the container rather than the viewport. Tune it here — this is
     the single knob for how big CLEANING CO. sits. */
  --line2-ratio: 0.20;
  font-size: clamp(1rem, 3.4vw, 3rem);
  /* Jost (same face as the blurb) rather than Benton — only HAVEN is display type. */
  font-family: var(--font-body);
  font-weight: 400;
  /* letter-spacing is computed in hero-fit.js so this line spans exactly
     the same width as HAVEN above it; this is only the pre-JS fallback. */
  letter-spacing: 0.06em;
  margin-top: 0.12em;
}

.hero__copy {
  margin-top: 1.4em;
  margin-bottom: 0;
  font-size: clamp(0.7rem, 1.35vw, 1.05rem);
  line-height: 1.45;
  color: var(--brown-text);
}

.hero figure {
  overflow: hidden;
  min-width: 0;
  min-height: 0;
}

.hero figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pane-1 { grid-column: 1; grid-row: 2; }
.pane-2 { grid-column: 2; grid-row: 2; }
.pane-3 { grid-column: 3; grid-row: 1 / span 2; }
.pane-4 { grid-column: 4; grid-row: 1 / span 2; position: relative; }

.pane-4 img { object-position: 60% center; }

.hero__cta {
  position: absolute;
  width: 100%;
  bottom: 0%;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5em;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.85);
  color: var(--brown-dark);
  text-decoration: none;
  font-size: clamp(0.65rem, 1.05vw, 0.9rem);
  font-weight: 400;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 0.9em 1.4em;
  white-space: nowrap;
  z-index: 5;
  overflow: hidden;
  isolation: isolate;
  transition:
    color 0.55s cubic-bezier(0.65, 0, 0.35, 1),
    letter-spacing 0.55s cubic-bezier(0.65, 0, 0.35, 1),
    text-shadow 0.55s cubic-bezier(0.65, 0, 0.35, 1);
}

/* White fill covers the button by default and retracts on hover,
   revealing the video through the button. */
.hero__cta::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--cream);
  transform: scaleX(1);
  transform-origin: right center;
  transition: transform 0.55s cubic-bezier(0.65, 0, 0.35, 1);
}

.hero__cta:hover,
.hero__cta:focus-visible {
  color: var(--white);
  letter-spacing: 0.24em;
  text-shadow: 0 1px 12px rgba(28, 26, 23, 0.45);
}

.hero__cta:hover::before,
.hero__cta:focus-visible::before {
  transform: scaleX(0);
}

.hero__cta-label { display: block; }

/* A one-arrow window over a two-arrow track: on hover the track slides
   right, so the arrow exits and an identical one enters from the left. */
.hero__cta-arrow {
  display: block;
  width: 1.15em;
  overflow: hidden;
  flex: 0 0 auto;
}

.hero__cta-arrow-track {
  display: flex;
  width: 200%;
  transform: translateX(-50%);
  transition: transform 0.55s cubic-bezier(0.65, 0, 0.35, 1);
}

.hero__cta-arrow-track svg {
  flex: 0 0 50%;
  width: 50%;
  height: auto;
  display: block;
}

.hero__cta:hover .hero__cta-arrow-track,
.hero__cta:focus-visible .hero__cta-arrow-track {
  transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
  .hero__cta,
  .hero__cta::before,
  .hero__cta-arrow-track {
    transition-duration: 0.01ms;
  }
  .hero__cta:hover { letter-spacing: 0.18em; }
}

/* ===== Responsive ===== */

@media (max-width: 760px) {
  .hero {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: auto 1fr 1fr;
  }
  .hero__text {
    grid-column: 1 / span 2;
    grid-row: 1;
    padding: 32px 6%;
  }
  .pane-1 { grid-column: 1; grid-row: 2; }
  .pane-2 { grid-column: 2; grid-row: 2; }
  .pane-3 { grid-column: 1; grid-row: 3; }
  .pane-4 { grid-column: 2; grid-row: 3; }
  .hero__cta {
    right: 12px;
    bottom: 12px;
    padding: 0.75em 1em;
    gap: 1em;
  }
}

/* ===== Entrance =====
   Everything except HAVEN fades up on the same clock as the wordmark's
   character reveal (0.2s delay, 1.4s, power3.out) so the hero arrives as
   one composed moment instead of the headline animating onto a page that
   is already fully present.

   Gated behind .js so that without JavaScript nothing is ever hidden. */

.js .hero__title .line2,
.js .hero__copy,
.js .hero__cta {
  opacity: 0;
  transform: translateY(12px);
}

.js .hero__title .line2,
.js .hero__copy,
.js .hero__cta,
.js .hero__media {
  transition:
    opacity 2.1s cubic-bezier(0.16, 0.84, 0.44, 1) 0.2s,
    transform 2.1s cubic-bezier(0.16, 0.84, 0.44, 1) 0.2s;
}

.js .is-ready .hero__title .line2,
.js .is-ready .hero__copy,
.js .is-ready .hero__cta {
  opacity: 1;
  transform: translateY(0);
}

/* The button keeps its own hover transitions; re-state them here so the
   entrance transition above doesn't overwrite the hover feel. */
.js .is-ready .hero__cta {
  transition:
    color 0.55s cubic-bezier(0.65, 0, 0.35, 1),
    letter-spacing 0.55s cubic-bezier(0.65, 0, 0.35, 1),
    text-shadow 0.55s cubic-bezier(0.65, 0, 0.35, 1),
    opacity 2.1s cubic-bezier(0.16, 0.84, 0.44, 1) 0.2s,
    transform 2.1s cubic-bezier(0.16, 0.84, 0.44, 1) 0.2s;
}

@media (prefers-reduced-motion: reduce) {
  .js .hero__title .line2,
  .js .hero__copy,
  .js .hero__cta,
  .js .hero__media {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ===== Smooth scrolling (Lenis) + hidden scrollbar ===== */

/* Lenis drives scrolling itself, so the document must not be height-locked
   and native smooth-scroll must stay out of its way. */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-stopped {
  overflow: hidden;
}

/* Hide the scrollbar without disabling scrolling. */
html {
  scrollbar-width: none;         /* Firefox */
  -ms-overflow-style: none;      /* legacy Edge/IE */
}

html::-webkit-scrollbar,
body::-webkit-scrollbar {        /* Chrome, Safari */
  width: 0;
  height: 0;
  display: none;
}
