/* The landing's opening scene (partials/hero.gohtml, brought to life by
 * hero.js): what the night and the day share. The forest is laid out here
 * and painted from custom properties that night.css and day.css set on
 * .sb-hero, the scene's own picture colours rather than theme tokens: each
 * theme gets a picture of its own. Only the foot of the scene reads a
 * token, where it dissolves into the page. */
.sb-hero {
  position: absolute;
  inset: 0;
  /* Its own stacking context, under everything else in the title: the
   * welcome's blank page covers all of it, overlays and all. */
  z-index: 0;
  isolation: isolate;
  overflow: hidden;
  background: var(--sky);
}

/* Each scene's own parts show only in its theme. Night is the default, so
 * a page without script (and so without data-theme) is the night. */
:root[data-theme="day"] .sb-hero [data-scene="night"],
:root:not([data-theme="day"]) .sb-hero [data-scene="day"] {
  display: none;
}

/* The near ground runs out into the page. */
.sb-hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0;
  z-index: 5;
  height: var(--foot-height, 18%);
  pointer-events: none;
  background: linear-gradient(transparent var(--foot-clear, 0%), color-mix(in oklab, var(--color-bg) 60%, transparent) 60%, var(--color-bg));
}

.nt-sky,
.dy-sky,
.hero-land {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/* ---- The land ---------------------------------------------------------------- *
 * The ridges share one frame (1600x500, bottom-anchored, sliced to fit), so
 * they line up at any screen size. Under each ridge lie its trees' crowns in
 * the rim colour, and the ridge itself is shifted down and away from the
 * light, so a lit edge shows along the tops and the sides of the crowns that
 * face the moon or the sun (both hang upper right). */
.hero-ridge,
.hero-canvas,
.hero-mist {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
}
.hero-ridge { height: 64%; }
.hero-ridge--far .hero-ridge__rim { fill: var(--far-rim); }
.hero-ridge--mid .hero-ridge__rim { fill: var(--mid-rim); }
.hero-ridge--near .hero-ridge__rim { fill: var(--near-rim); }
.hero-canvas { top: 0; height: 100%; pointer-events: none; }
.hero-mist {
  left: -20%;
  width: 140%;
  height: 22%;
  background: radial-gradient(ellipse 50% 50% at 50% 50%, var(--mist), transparent) 0 0 / 34% 100% repeat-x;
  animation: hero-mist 120s linear infinite;
}
.hero-mist--far { bottom: 25%; }
.hero-mist--near { bottom: 12%; height: 18%; opacity: 0.7; animation-duration: 80s; animation-direction: reverse; }
@keyframes hero-mist { to { transform: translateX(34%); } }

/* The old branch, where the owl sits by night and a songbird by day. */
.hero-perch {
  position: absolute;
  left: 0;
  top: 45%;
  width: clamp(190px, 25vw, 360px);
  overflow: visible;
}
.hero-bark { fill: var(--bark); }
.hero-bark--leaves { fill: var(--leaves, var(--bark)); }
.hero-rim { fill: none; stroke: var(--rim); stroke-width: 1.2; stroke-linecap: round; opacity: 0.7; }

/* Film grain, so the long gradients do not band. */
.hero-grain {
  position: absolute;
  inset: 0;
  z-index: 4;
  pointer-events: none;
  opacity: var(--grain, 0.035);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- The fairy's light, and her sparkle --------------------------------------- */
.sb-flyer::before,
.sb-fairy::before {
  content: "";
  position: absolute;
  inset: -110%;
  border-radius: 50%;
  pointer-events: none;
  background: radial-gradient(circle, var(--fairy-light, rgb(255 214 130 / 0.2)), transparent 68%);
  transition: opacity 600ms var(--ease-out);
}

/* A scene can give the sparkle an edge (--spark-edge, a filter), where its
 * sky is too light for the bare colour to show. The star is cut from the
 * ::before, so the edge, on the element, goes round the cut shape. */
.hero-spark {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 4;
  width: var(--spark-size, 8px);
  height: var(--spark-size, 8px);
  margin: calc(var(--spark-size, 8px) / -2) 0 0 calc(var(--spark-size, 8px) / -2);
  pointer-events: none;
  filter: var(--spark-edge, none);
  animation: hero-spark 1.1s ease-out forwards;
}
.hero-spark::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--spark, var(--fairy-star));
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
}
@keyframes hero-spark {
  from { opacity: 1; transform: translate(var(--x), var(--y)) scale(var(--s)) rotate(0); }
  to { opacity: 0; transform: translate(var(--x), calc(var(--y) + 26px)) scale(calc(var(--s) * 0.2)) rotate(90deg); }
}

/* With a mouse, the layers shift with the pointer (hero.js); each gets a
 * compositor layer of its own, so moving one repaints nothing. Touch
 * screens have no parallax, and no layers to pay for. */
@media (pointer: fine) {
  .hero-ridge,
  .hero-mist,
  .hero-perch,
  .hero-canvas--far,
  .nt-stars,
  .nt-glints,
  .nt-moon,
  .nt-moonlight,
  .nt-cloud,
  .dy-sun,
  .dy-cloud,
  .dy-beams,
  .dy-flutter {
    will-change: translate;
  }
}

@media (max-width: 600px) {
  .hero-perch { top: 50%; left: -24px; }
  .hero-ridge { height: 58%; }
}
