/*
 * Firefighter Pfister — home
 *
 * A full-viewport gateway: nothing scrolls beneath it.
 *
 * The atmospherics are blurred ellipses in the Figma file. They are rebuilt
 * here as CSS radial gradients rather than shipped as SVG. Same shape, but a
 * gradient composites on the GPU where an animated `feGaussianBlur` forces a
 * repaint every frame — and these run continuously. It also lets the blobs
 * scale with the viewport instead of being pinned to the 1440x900 frame.
 *
 * Motion timings are the Figma keyframes stretched out. The Figma timeline is
 * compressed to 16s so a full cycle is reviewable; the brief asks for 40-60s in
 * production, and the ember runs on its own offset cycle so the layers never
 * resynchronise.
 */

/*
 * The gateway is exactly one viewport with nothing beneath it. Nav and lockup
 * are flex children of that height rather than each claiming 100svh, which
 * would stack to a scrollable page.
 */
.home {
  display: flex;
  flex-direction: column;
  height: 100svh;
  overflow: hidden;
}

.home__stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: var(--ash-900);
}

.home__hero,
.home__scrim,
.home__layer {
  position: absolute;
  pointer-events: none;
}

.home__hero {
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Slow Ken Burns; transform-origin keeps the drift centred. */
  animation: hero-drift 60s ease-in-out infinite;
  will-change: transform;
}

.home__scrim {
  inset: 0;
  background: linear-gradient(
    180deg,
    rgb(20 17 16 / 0.55) 0%,
    rgb(20 17 16 / 0.18) 42%,
    rgb(20 17 16 / 0.88) 100%
  );
}

/*
 * Each layer is one soft ellipse. Screen blend lifts the photo rather than
 * painting over it, which is what makes it read as haze in the air.
 */
.home__layer {
  mix-blend-mode: screen;
  will-change: transform, opacity;
}

.home__layer--smoke-a {
  left: -18.1%;
  top: 13.3%;
  width: 104.2%;
  height: 62.2%;
  /* 0.32 x 1.15 — smoke lifted 15%, ember left alone. */
  opacity: 0.368;
  background: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    #bdb6ac 0%,
    rgb(189 182 172 / 0.55) 42%,
    rgb(189 182 172 / 0) 72%
  );
  animation: smoke-a 52s ease-in-out infinite;
}

.home__layer--smoke-b {
  left: 23.6%;
  top: 47.8%;
  width: 72.9%;
  height: 47.8%;
  opacity: 0.299;
  background: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    #faf9f7 0%,
    rgb(250 249 247 / 0.55) 42%,
    rgb(250 249 247 / 0) 72%
  );
  animation: smoke-b 46s ease-in-out infinite;
}

.home__layer--smoke-c {
  left: -9.7%;
  top: 36.7%;
  width: 63.9%;
  height: 40%;
  opacity: 0;
  background: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    #e8e2d8 0%,
    rgb(232 226 216 / 0.55) 42%,
    rgb(232 226 216 / 0) 72%
  );
  animation: smoke-c 72s linear infinite;
}

.home__layer--ember {
  left: -10.8%;
  top: 71.1%;
  width: 121.5%;
  height: 68.9%;
  opacity: 0.32;
  background: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    var(--ember-500) 0%,
    rgb(255 150 21 / 0.5) 40%,
    rgb(255 150 21 / 0) 70%
  );
  animation: ember-breathe 29s ease-in-out infinite;
}

/* The mobile mockup carries no atmospherics — just the photo and the scrim. */
@media (max-width: 767px) {
  .home__layer {
    display: none;
  }
}

@keyframes hero-drift {
  0% { transform: translate3d(0, 0, 0) scale(1); }
  50% { transform: translate3d(-26px, 0, 0) scale(1.05); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}

@keyframes smoke-a {
  0% { transform: translate3d(-70px, 24px, 0) scaleX(1); }
  50% { transform: translate3d(255px, -72px, 0) scaleX(1.18); }
  100% { transform: translate3d(-70px, 24px, 0) scaleX(1); }
}

/* Opposing direction to A, so the two masses cross rather than travel together. */
@keyframes smoke-b {
  0% { transform: translate3d(105px, -18px, 0); }
  40% { transform: translate3d(-225px, 58px, 0); }
  100% { transform: translate3d(105px, -18px, 0); }
}

@keyframes smoke-c {
  0% { opacity: 0; transform: translate3d(0, 0, 0); }
  24% { opacity: 0.299; }
  70% { opacity: 0.299; }
  100% { opacity: 0; transform: translate3d(1180px, -95px, 0); }
}

@keyframes ember-breathe {
  0% { opacity: 0.32; }
  25% { opacity: 0.21; }
  60% { opacity: 0.47; }
  100% { opacity: 0.32; }
}

/* ---------------------------------------------------------------- *
 * Lockup
 * ---------------------------------------------------------------- */

.home__lockup {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 22px;
  /* 620px in the 1440 desktop frame, 300px in the 390 mobile one — the same
     min() lands on both, so the wordmark keeps its proportion at either end. */
  width: min(620px, 77%);
  flex: 1 1 auto;
  min-height: 0;
  margin-inline: auto;
  text-align: center;
  animation: lockup-in 900ms ease-out both;
}

@media (min-width: 1000px) {
  .home__lockup {
    gap: var(--space-lg);
  }
}

@keyframes lockup-in {
  from { opacity: 0; transform: translate3d(0, 22px, 0); }
  to { opacity: 1; transform: translate3d(0, 0, 0); }
}

.home__wordmark {
  width: min(460px, 73%);
  margin: 0;
  /*
   * Multiply rather than overlay: overlay lightens where the photo is bright,
   * multiply can only darken. The photograph's texture still reads through the
   * letterforms, but the ember never washes out paler than it started.
   *
   * The opacity is the "slightly transparent" part. Note it composites the
   * multiplied result back toward the photo, so over the brightest smoke the
   * ember can end a shade paler than solid — drop this line and multiply alone
   * guarantees it never lightens at all.
   */
  mix-blend-mode: multiply;
  opacity: 0.85;
}

/* Override the nav-sized .wordmark width; here it fills the lockup. */
.home__wordmark-art {
  width: 100%;
  color: var(--accent-solid);
}

.home__tagline {
  font-family: var(--font-display);
  font-size: var(--type-lead);
  font-weight: 400;
  line-height: var(--lh-lead);
  color: var(--text-primary);
  opacity: 0.82;
}

.home__enter {
  padding: 17px 46px;
  border: 1.5px solid var(--text-primary);
  border-radius: var(--radius-sm);
  font-family: var(--font-display);
  font-size: var(--type-small);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-decoration: none;
  color: var(--text-primary);
  transition: background-color 160ms ease, color 160ms ease;
}

.home__enter:hover {
  background: var(--text-primary);
  color: var(--ash-900);
}

@media (max-width: 767px) {
  .home__enter {
    padding: 15px 38px;
  }
}

/* ---------------------------------------------------------------- *
 * Home nav — sits over the photograph, so no bar, blur or border.
 * ---------------------------------------------------------------- */

/*
 * Hidden at every breakpoint, deliberately: the gateway should send people
 * through ENTER before they meet the navigation. The markup stays in place, so
 * this is one line to undo.
 *
 * Not `visibility: hidden` or opacity — those leave the links reachable by
 * keyboard, which would give a tab-user a menu the design says is not there
 * yet. `display: none` takes it out of the tab order too.
 */
.nav--home {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  .home__hero,
  .home__layer,
  .home__lockup {
    animation: none;
  }

  /* Hold the ember at the midpoint of its cycle rather than an endpoint. */
  .home__layer--ember {
    opacity: 0.34;
  }

  .home__layer--smoke-c {
    opacity: 0.299;
  }
}

/*
 * Clip at the root as well as on <body>.
 *
 * The lockup's entrance animation translates it 22px, and a transform still
 * contributes to scrollable overflow — enough to make a one-viewport page
 * scroll by 22px. Clipping here keeps the gateway exactly one screen no matter
 * what state the entrance animation is in.
 */
.home-root {
  height: 100%;
  overflow: hidden;
}
