/* Home page only. Loaded via the page's `styles:` meta key. */

/* Pull the fork up over the hero so both paths are visible without
   scrolling. This is the one thing the home page has to get right. */
.fork-section {
  margin-top: calc(var(--s-8) * -1);
  position: relative;
  z-index: 2;
  padding-top: 0;
}

@media (min-width: 800px) {
  .fork-section {
    margin-top: calc(var(--s-9) * -1);
  }
}

/* The hero needs bottom room so the fork does not cover the buttons. */
.hero {
  padding-bottom: var(--s-7);
}

@media (min-width: 800px) {
  .hero {
    padding-bottom: var(--s-9);
  }
}

/* --------------------------------------------------------------------------
   Hero slideshow

   Slides stack on top of each other and crossfade. The static state below
   shows slide one and nothing else, which is deliberately plain CSS rather
   than a JS-set state: this is the no-JS view, and it leaves a real photo
   on screen rather than an empty box. hero.js stamps data-hero-ready on the
   container and takes over from there.
   -------------------------------------------------------------------------- */

.hero__slide {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  opacity: 0;
}

/* No JS, or hero.js failed: the first photo, exactly as before. */
.hero__slide:first-child {
  opacity: 1;
}

[data-hero-ready] .hero__slide {
  opacity: 0;
  transition: opacity 1100ms ease-in-out;
}

[data-hero-ready] .hero__slide.is-active {
  opacity: 1;
}

/* Finished elevations are shot wide and low. Sit the crop a little higher
   than the interior heroes so rooflines are not cut off. */
.hero__slide img {
  object-position: center 58%;
}

/* Stop control. Quiet until you go looking for it, obvious on focus. */
.hero__pause {
  position: absolute;
  top: var(--s-5);
  right: var(--gutter);
  z-index: 3;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  color: #fff;
  background: rgba(11, 11, 12, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 50%;
  cursor: pointer;
  opacity: 0.55;
  transition: opacity var(--t-fast), background var(--t-fast);
}

.hero__pause:hover,
.hero__pause:focus-visible {
  opacity: 1;
  background: rgba(11, 11, 12, 0.8);
}

.hero__pause-icon {
  grid-area: 1 / 1;
}

.hero__pause[data-state='playing'] .hero__pause-icon--play,
.hero__pause[data-state='paused'] .hero__pause-icon--pause {
  display: none;
}

/* Reduced motion: hero.js never starts the rotation, so kill the crossfade
   too and drop the control rather than leaving a button that does nothing. */
@media (prefers-reduced-motion: reduce) {
  [data-hero-ready] .hero__slide {
    transition: none;
  }

  .hero__pause {
    display: none;
  }
}

/* Hold the home hero copy in a left-hand column so the photo behind it is
   actually visible instead of sitting entirely under a full-width scrim.

   The column sits on the wide grid, the same `--container-wide` the header
   already uses, rather than the 1180px content grid. That lines the headline
   up with the logo directly above it at every width and hands roughly 120px
   back to the photo. The fork cards below stay on the content grid: the hero
   is a full bleed band and reads as one, the cards are page content.

   The scrim turns directional to match: dark across the copy, then falling
   away fast so most of the frame is close to the untouched photo.

   Its stops are anchored to a length, not to percentages, and that is not a
   style preference. Percentage stops are measured against the hero width
   while the copy column is a fixed 42rem, so the copy occupies a bigger share
   of a narrow window than a wide one and slides out from under its own
   cover as the window shrinks. A percentage version of this gradient
   measured 1.96:1 on the headline at 940px, against a 3.0 threshold.
   `--hero-scrim-edge` tracks the right edge of the headline at any width:
   the centering offset of the wide container, plus the gutter, plus the
   column. Change the 42rem only alongside the `15ch` on the h1 below.

   These alphas are near the floor, not a starting point. Composited against
   all three slides at 925, 1425 and 1905px, the worst case is 5.0:1 on the
   headline and 5.8:1 on the lede, against thresholds of 3.0 and 4.5. Taking
   another 10% off the ink drops the lede to 3.9:1 and fails. If a slide is
   ever swapped for a brighter one, measure before assuming there is room. */
@media (min-width: 900px) {
  .hero__inner {
    max-width: var(--container-wide);
  }

  .hero__inner > * {
    max-width: 34rem;
  }

  .hero h1 {
    max-width: 15ch;
  }

  .hero .lede {
    max-width: 34rem;
  }

  .hero::after {
    --hero-scrim-edge: calc(
      max(var(--gutter), (100% - var(--container-wide)) / 2 + var(--gutter)) + 42rem
    );

    background:
      linear-gradient(
        to right,
        rgba(11, 11, 12, 0.7) 0,
        rgba(11, 11, 12, 0.62) calc(var(--hero-scrim-edge) * 0.5),
        rgba(11, 11, 12, 0.52) var(--hero-scrim-edge),
        rgba(11, 11, 12, 0.13) calc(var(--hero-scrim-edge) + 12rem),
        rgba(11, 11, 12, 0.04) calc(var(--hero-scrim-edge) + 24rem)
      ),
      linear-gradient(
        to top,
        rgba(11, 11, 12, 0.32) 0%,
        rgba(11, 11, 12, 0.08) 45%,
        rgba(11, 11, 12, 0.16) 100%
      );
  }
}

/* Portrait screens get their own wash from components.css, and it is built
   for the general case: the copy stacks over most of the frame there, so it
   leans heavy. On this hero it left the house as a silhouette.

   Same treatment as the desktop scrim above, about a quarter of the ink off,
   and the same caveat. Measured against all three slides at 375px wide, the
   worst case is 5.4:1 on the headline, 6.8:1 on the lede and 5.0:1 on the
   eyebrow, against thresholds of 3.0, 4.5 and 4.5. The eyebrow is the binding
   one, not the headline: it is small, it sits highest, and the wash is
   thinnest at the top. One more step down puts it at 3.6:1 and fails.

   Home only, so the compact heroes on about, residential and commercial keep
   the components.css wash. They carry different photos and shorter copy, so
   they need their own measurement rather than this one. */
@media (max-width: 640px) {
  .hero::after {
    background: linear-gradient(
        to top,
        rgba(11, 11, 12, 0.8) 0%,
        rgba(11, 11, 12, 0.64) 45%,
        rgba(11, 11, 12, 0.46) 100%
      ),
      rgba(11, 11, 12, 0.16);
  }
}

/* The finished shots were taken under flat overcast light and read a little
   grey once the scrim is over them. A small lift, not a look: enough that the
   siding reads white rather than putty. Deliberately outside the media query
   above, since the phone scrim is heavier still. */
.hero__slide img {
  filter: brightness(1.07) saturate(1.05);
}

/* Shorter fork cards on a phone so both are reachable without a long scroll,
   but tall enough that the photo still reads under the scrim. */
@media (max-width: 640px) {
  .fork__card {
    min-height: 290px;
  }
}

/* Balance the CTA band: text left, buttons right on wide screens. */
.cta .split {
  align-items: center;
}

@media (min-width: 860px) {
  .cta .btn-row {
    justify-content: flex-end;
  }
}
