/* Page flow.

   The first five sections (hero, problem, checkpoint, rules, log) are full-height
   pages in one pinned stage. Everything inside a page is static. Scrolling only
   triggers a page change: the small script at the end of index.html sets
   data-page on the stage when you scroll past a point, and the change then plays
   on its own timer, the same every time, whatever the scroll speed. The current
   page flows up and out of the screen as a whole and the next page comes forward
   from the background behind it. Only whole pages move.

   All of this applies only while the script has added the class story-on to the
   page, which it does on larger windows when motion is welcome. Without the script,
   or on phones and with reduced motion, the page is the plain static layout in
   site.css. The size limits are in em (53.8em and 43.75em are 861px and 700px at
   the default font size), so a larger browser font size switches this off and a
   page can never hide content under the window edge. No external requests. */

:root {
  /* Scroll distance one page rests for. A page change is triggered at the start of
     each step. */
  --story-start: calc(100vh - var(--header-height));
  --story-step: 100vh;
  --story-time: 0.8s;
  --story-ease: cubic-bezier(0.65, 0, 0.35, 1);
}

/* clip, not hidden: hidden makes the body a scroll container, which Safari can
   mishandle together with sticky. */
.story-on body {
  overflow-x: clip;
}

/* The story is tall; the stage inside it stays pinned under the header. */
.story-on .story {
  position: relative;
  height: calc(var(--story-start) + 4 * var(--story-step));
}

.story-on .stage {
  position: sticky;
  top: var(--header-height);
  height: calc(100vh - var(--header-height));
  overflow: hidden;
  background: var(--color-paper);
}

/* All five pages sit on top of each other, the first one in front. */
.story-on .stage > .scene {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  min-height: 0;
  padding: 0;
  border-top: 0;
  border-bottom: var(--border-width) solid var(--color-ink);
  background: var(--color-paper);
}

.story-on .stage > .section-tinted {
  background: var(--color-white);
}

.story-on .scene-stick {
  width: 100%;
  padding: var(--space-4) 0;
}

.story-on .scene-hero { z-index: 5; }
.story-on .scene-problem { z-index: 4; }
.story-on .scene-checkpoint { z-index: 3; }
.story-on .scene-rules { z-index: 2; }
.story-on .scene-log { z-index: 1; }

/* Page states. A page that has not come yet waits slightly smaller behind the
   others, the current page is full size, and a page that has gone has slid up and
   out of the screen. data-page is the current page, 1 to 5. */
.story-on .scene-problem,
.story-on .scene-checkpoint,
.story-on .scene-rules,
.story-on .scene-log {
  scale: 0.94;
}

.story-on .stage[data-page="2"] .scene-problem,
.story-on .stage[data-page="3"] .scene-checkpoint,
.story-on .stage[data-page="4"] .scene-rules,
.story-on .stage[data-page="5"] .scene-log,
.story-on .stage:is([data-page="3"], [data-page="4"], [data-page="5"]) .scene-problem,
.story-on .stage:is([data-page="4"], [data-page="5"]) .scene-checkpoint,
.story-on .stage[data-page="5"] .scene-rules {
  scale: 1;
}

.story-on .stage:is([data-page="2"], [data-page="3"], [data-page="4"], [data-page="5"]) .scene-hero,
.story-on .stage:is([data-page="3"], [data-page="4"], [data-page="5"]) .scene-problem,
.story-on .stage:is([data-page="4"], [data-page="5"]) .scene-checkpoint,
.story-on .stage[data-page="5"] .scene-rules {
  translate: 0 -100%;
}

/* The timed slide. Switched on only after the first frame, so a reload in the middle
   of the story does not replay it. */
.story-ready .stage > .scene {
  transition:
    translate var(--story-time) var(--story-ease),
    scale var(--story-time) var(--story-ease);
}

/* The header links for Checkpoint, Rules and Log jump to the scroll position where
   that page is current. */
.story-on .nav-static {
  display: none;
}

.story-on .nav .nav-story {
  display: inline;
}

.story-on .story-mark {
  position: absolute;
  left: 0;
  display: block;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.story-on .story-mark-checkpoint { top: calc(var(--story-step) + 40px); }
.story-on .story-mark-rules { top: calc(2 * var(--story-step) + 40px); }
.story-on .story-mark-log { top: calc(3 * var(--story-step) + 40px); }

/* Page indicator: where you are among the five pages, and a way to jump. Whole-page
   element: its current square changes instantly, nothing animates. */
.story-on .pager {
  position: absolute;
  top: 50%;
  right: 2px;
  z-index: 8;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  transform: translateY(-50%);
}

.story-on .pager a {
  position: relative;
  display: block;
  width: 12px;
  height: 12px;
  border: var(--border-width-thin) solid var(--color-ink);
  background: var(--color-white);
}

.story-on .pager a::after {
  content: "";
  position: absolute;
  inset: -6px;
}

.story-on .pager a[aria-current="page"] {
  background: var(--color-navy);
}

/* A cue on the first page only. */
.story-on .scroll-cue {
  position: absolute;
  bottom: var(--space-4);
  left: 50%;
  z-index: 8;
  display: block;
  padding: var(--space-1) var(--space-3);
  transform: translateX(-50%);
  color: var(--color-ink);
  font-family: var(--font-mono);
  font-size: var(--font-size-sm);
  text-decoration: none;
}

.story-on .stage:not([data-page="1"]) .scroll-cue {
  display: none;
}

.story-on .story-mark-hero { top: 0; }
.story-on .story-mark-problem { top: 40px; }

/* Tall windows: the pages are fuller, so the type is one step larger. */
@media (min-height: 50em) {
  .story-on .scene .section-title {
    font-size: 2.75rem;
  }

  .story-on .scene .section-lede,
  .story-on .scene .card-text,
  .story-on .scene .plain-list {
    font-size: var(--font-size-lg);
  }

  .story-on .scene .card {
    padding: var(--space-8);
  }
}
