/* The landing page: a picture book. A cover, then one idea per page, each with one picture.
   Everything is readable with no script and with motion off; the script and the animations only
   add to it. Hidden-then-revealed states apply only under html.js, which boot.js sets. */

html:not(.js) .js-only {
  display: none !important;
}

.skip {
  position: absolute;
  z-index: 10;
  left: 16px;
  top: -80px;
  padding: 12px 18px;
  border-radius: 999px;
  background: var(--ink);
  color: var(--cream);
  text-decoration: none;
}

.skip:focus {
  top: 16px;
  color: var(--cream);
}

.wrap {
  width: min(1160px, 100% - 2 * var(--gutter));
  margin-inline: auto;
}

main > section {
  position: relative;
  padding-block: clamp(72px, 9.5vw, 144px);
}

/* Two plain sections in a row share one gap instead of stacking two. */
main > section:not(.page) + section:not(.page) {
  padding-top: 0;
}

/* A page of the book: a tinted sheet with round corners, a little in from the edge of the screen. */
.page {
  margin-inline: var(--edge);
  border-radius: var(--r-page);
  overflow: clip;
  isolation: isolate;
}

/* ------------------------------------------------------------------ type */

.head {
  max-width: 920px;
  margin-bottom: clamp(36px, 5vw, 72px);
}

.head--center {
  margin-inline: auto;
  text-align: center;
}

.eyebrow,
.step__num,
.rule__kicker,
.char__trait {
  margin-bottom: 18px;
  color: var(--accent-text);
  font: 500 13px/1.2 var(--text);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.page .eyebrow,
.rule__kicker,
.char__trait {
  color: var(--accent-deep);
}

/* Each section is a chapter, numbered like one. */
main {
  counter-reset: chapter;
}

main .head > .eyebrow::before {
  counter-increment: chapter;
  content: counter(chapter, decimal-leading-zero) '\2002\2014\2002';
}

h2 {
  font-size: clamp(34px, 4.6vw + 18px, 76px);
  line-height: 1.02;
  letter-spacing: -0.03em;
}

h3 {
  font-size: clamp(24px, 2.3vw, 30px);
  letter-spacing: -0.015em;
}

.lead {
  max-width: 33em;
  margin-top: clamp(16px, 1.8vw, 24px);
  color: var(--ink-soft);
  font-size: clamp(18px, 1.55vw, 22px);
  line-height: 1.5;
}

.head--center .lead {
  margin-inline: auto;
}

.ico {
  flex: none;
  width: 1.25em;
  height: 1.25em;
}

/* ------------------------------------------------------------------ reveal on scroll */

@media (prefers-reduced-motion: no-preference) {
  .js [data-reveal] {
    opacity: 0;
    transform: translateY(32px);
    transition:
      opacity 0.7s var(--ease),
      transform 0.9s var(--ease);
  }

  .js [data-reveal].is-in {
    opacity: 1;
    transform: none;
  }

  .js [data-delay='1'] {
    transition-delay: 0.08s;
  }
  .js [data-delay='2'] {
    transition-delay: 0.16s;
  }
  .js [data-delay='3'] {
    transition-delay: 0.24s;
  }
  .js [data-delay='4'] {
    transition-delay: 0.32s;
  }
  .js [data-delay='5'] {
    transition-delay: 0.4s;
  }

  /* Looping animations rest while their page is off screen. */
  .js [data-live]:not(.is-live) .critter,
  .js [data-live]:not(.is-live) .twinkle,
  .js [data-live]:not(.is-live) .parade__track,
  .js [data-live]:not(.is-live) .night__sky::after,
  .js [data-live]:not(.is-live) [class$='__light']::before {
    animation-play-state: paused !important;
  }
}

/* ------------------------------------------------------------------ small signs of life */

.eye {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  translate: calc(var(--gx, 0) * 1px) calc(var(--gy, 0) * 1px);
  transition:
    translate 0.25s ease-out,
    scale 0.09s ease-in-out;
}

/* A blink. The script gives each critter of the cast this for a moment, in its own time. An
   animation that never ends can't do it: inside a drawing it would have the browser draw a new
   frame of the page all the time the cover is on screen. */
.is-blinking .eye {
  scale: 1 0.08;
}

/* ------------------------------------------------------------------ the cover */

.cover {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: calc(100vh - 2 * var(--edge));
  margin: var(--edge);
  border-radius: var(--r-page);
  background: linear-gradient(180deg, #fdf2e5 0%, #fbe7d5 62%, #f9dcc5 100%);
  overflow: hidden;
  isolation: isolate;
}

/* The small viewport height, where a browser knows the unit. A second declaration can't be the
   fallback here: one that holds var() is kept whatever unit is in it, and then counts for nothing. */
@supports (height: 100svh) {
  .cover {
    min-height: calc(100svh - 2 * var(--edge));
  }
}

/* A warm light that follows the pointer (the script moves it), and drifts on its own otherwise. */
.cover__light,
.finale__light {
  position: absolute;
  z-index: -1;
  left: 0;
  top: 0;
  width: 880px;
  height: 880px;
  margin: -440px 0 0 -440px;
  transform: translate3d(var(--lx, 50vw), var(--ly, 300px), 0);
  pointer-events: none;
}

.cover__light::before,
.finale__light::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(244, 196, 72, 0.5), rgba(244, 196, 72, 0.2) 48%, rgba(244, 196, 72, 0));
  animation: drift 16s ease-in-out infinite;
}

@keyframes drift {
  0%,
  100% {
    transform: translate3d(-4%, 0, 0) scale(1);
  }
  50% {
    transform: translate3d(5%, 4%, 0) scale(1.08);
  }
}

.cover__copy {
  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(8px, 2.5vh, 40px) var(--gutter) 0;
  text-align: center;
}

.cover__title {
  max-width: 7.2em;
  font-size: clamp(40px, 14.4vw, 64px);
  line-height: 1;
  letter-spacing: -0.035em;
}

.word {
  display: inline-block;
  animation: word-in 0.9s var(--ease) both;
}

.word:nth-child(2) {
  animation-delay: 0.06s;
}
.word:nth-child(3) {
  animation-delay: 0.12s;
}
.word:nth-child(5) {
  animation-delay: 0.2s;
}
.word:nth-child(6) {
  animation-delay: 0.26s;
}
.word:nth-child(7) {
  animation-delay: 0.32s;
}

@keyframes word-in {
  from {
    opacity: 0;
    transform: translateY(0.45em) rotate(4deg);
  }
}

.cover__lead {
  max-width: 31em;
  margin-top: clamp(18px, 2vh, 24px);
  color: var(--ink-soft);
  font-size: clamp(18px, 1.55vw, 22px);
  line-height: 1.5;
  animation: rise-in 0.9s 0.42s var(--ease) both;
}

.cover .stores {
  margin-top: clamp(20px, 2.8vh, 32px);
  animation: rise-in 0.9s 0.54s var(--ease) both;
}

@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
}

/* The cast, sitting on a hill. On a phone they sit in two rows, like a class photo. */
.cast {
  position: relative;
  flex: none;
  align-self: center;
  width: 100%;
  height: clamp(252px, 72vw, 340px);
  margin-top: clamp(20px, 4vh, 44px);
}

.cast__hill {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 240%;
  aspect-ratio: 1.6;
  margin-left: -120%;
  border-radius: 50%;
  background: linear-gradient(180deg, #f6cfae 0%, #f2bf99 34%);
  animation: hill-in 1.1s 0.1s var(--ease) both;
}

@keyframes hill-in {
  from {
    transform: translateY(18%);
  }
}

.seat {
  position: absolute;
  animation: seat-in 0.9s var(--spring) both;
}

@keyframes seat-in {
  from {
    opacity: 0;
    translate: 0 46%;
    scale: 0.7;
  }
}

.seat .critter {
  transform-origin: 50% 91%;
  animation: breathe 4.6s ease-in-out infinite;
}

.seat--hoot {
  left: 7%;
  bottom: 43%;
  width: 29%;
  rotate: -4deg;
  animation-delay: 0.5s;
}
.seat--bun {
  left: 35.5%;
  bottom: 49%;
  width: 29%;
  animation-delay: 0.58s;
}
.seat--ribbit {
  left: 64%;
  bottom: 43%;
  width: 29%;
  rotate: 4deg;
  animation-delay: 0.66s;
}
.seat--mochi {
  left: -4%;
  bottom: 4%;
  width: 39%;
  rotate: -3deg;
  animation-delay: 0.74s;
}
.seat--axo {
  left: 30.5%;
  bottom: 8%;
  width: 39%;
  animation-delay: 0.82s;
}
.seat--kit {
  left: 65%;
  bottom: 4%;
  width: 39%;
  rotate: 3deg;
  animation-delay: 0.9s;
}

.seat--hoot .critter {
  animation-delay: -1.2s;
}
.seat--ribbit .critter {
  animation-delay: -2.6s;
}
.seat--mochi .critter {
  animation-delay: -3.4s;
}
.seat--axo .critter {
  animation-delay: -0.6s;
}
.seat--kit .critter {
  animation-delay: -4.1s;
}

.cover .top__nav {
  display: none;
}

@media (min-width: 700px) {
  .cover .top__nav {
    display: flex;
  }

  .cover__title {
    max-width: none;
    font-size: clamp(60px, min(10.4vw, 13.4vh), 124px);
    line-height: 0.95;
  }

  /* One row along the top of the hill. The whole group shrinks on a short window, so the
     cover still fits on the first screen. */
  .cast {
    width: min(1240px, 100%, 126vh);
    height: auto;
    aspect-ratio: 1 / 0.292;
  }

  .cast__hill {
    top: 62%;
    width: 220%;
    aspect-ratio: 1.857;
    margin-left: -110%;
  }

  .seat--bun {
    left: 1%;
    bottom: 17%;
    width: 14.5%;
    rotate: -4deg;
    animation-delay: 0.5s;
  }
  .seat--hoot {
    left: 13%;
    bottom: 24%;
    width: 17%;
    rotate: -3deg;
    animation-delay: 0.58s;
  }
  .seat--mochi {
    left: 27.5%;
    bottom: 27%;
    width: 21%;
    rotate: -2deg;
    animation-delay: 0.66s;
  }
  .seat--axo {
    left: 46%;
    bottom: 29%;
    width: 23%;
    rotate: 0.5deg;
    animation-delay: 0.74s;
  }
  .seat--kit {
    left: 66.5%;
    bottom: 25%;
    width: 19%;
    rotate: 2.5deg;
    animation-delay: 0.82s;
  }
  .seat--ribbit {
    left: 83.5%;
    bottom: 17.5%;
    width: 15%;
    rotate: 4deg;
    animation-delay: 0.9s;
  }
}

@media (min-width: 700px) and (orientation: portrait) {
  /* An upright tablet is much taller than the cover needs. */
  .cover {
    min-height: 0;
  }

  .cover__copy {
    padding-block: 48px 8px;
  }
}

/* Leaving the cover: the words lift away a little faster than the page, the cast a little slower.
   Not on a window so short that the words start below its edge: they would be fading while they
   are being read. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) and (min-height: 480px) {
    .cover__copy {
      animation: copy-out linear both;
      animation-timeline: scroll(root block);
      animation-range: 0px 90vh;
    }

    .cast {
      animation: cast-out linear both;
      animation-timeline: scroll(root block);
      animation-range: 0px 100vh;
    }
  }
}

@keyframes copy-out {
  to {
    translate: 0 -56px;
    opacity: 0.25;
  }
}

@keyframes cast-out {
  to {
    translate: 0 40px;
  }
}

/* Each tinted page comes forward as it arrives. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .page {
      animation: page-in linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 45%;
    }
  }
}

@keyframes page-in {
  from {
    scale: 0.93;
  }
}

/* ------------------------------------------------------------------ 1. how it works */

.how {
  padding-bottom: clamp(48px, 6vw, 96px);
  /* Whatever of the round patch behind the phone reaches past the screen is cut, not scrolled to. */
  overflow-x: clip;
}

.steps {
  display: grid;
  gap: clamp(64px, 10vw, 104px);
  margin: 0;
  padding: 0;
  list-style: none;
}

.step {
  display: grid;
  gap: 32px;
}

.step__num {
  margin-bottom: 14px;
}

.step h3 {
  font-size: clamp(30px, 3.6vw, 48px);
  letter-spacing: -0.025em;
}

.step__text > p:last-child {
  max-width: 29em;
  margin-top: 16px;
  color: var(--ink-soft);
  font-size: clamp(17px, 1.4vw, 19px);
}

/* A phone drawn in CSS. Inside it, small rebuilds of the app's screens. */
.phone {
  position: relative;
  width: min(300px, 100%);
  margin-inline: auto;
  padding: 10px;
  border-radius: 48px;
  background: #2e2522;
  box-shadow:
    inset 0 0 0 2px #51433c,
    inset 0 0 0 5px #2e2522;
}

.phone::before {
  content: '';
  position: absolute;
  z-index: 2;
  left: 50%;
  top: 20px;
  width: 74px;
  height: 22px;
  margin-left: -37px;
  border-radius: 999px;
  background: #2e2522;
}

.phone__screen {
  position: relative;
  aspect-ratio: 280 / 596;
  border-radius: 38px;
  background: var(--cream);
  overflow: hidden;
}

/* Between the steps on a phone: the top of the device, fading out below. */
.step__screen {
  filter: drop-shadow(0 26px 30px rgba(59, 47, 42, 0.16));
}

.phone--half {
  padding-bottom: 0;
  border-radius: 48px 48px 0 0;
  -webkit-mask-image: linear-gradient(#000 78%, transparent);
  mask-image: linear-gradient(#000 78%, transparent);
}

.phone--half .phone__screen {
  aspect-ratio: auto;
  height: 452px;
  border-radius: 38px 38px 0 0;
}

.phone--half .app-button--float {
  display: none;
}

.screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  padding: 54px 16px 16px;
  color: var(--ink);
  font-size: 12px;
  line-height: 1.35;
}

/* Cut off at the bottom of a short screen, never squeezed. */
.screen > * {
  flex-shrink: 0;
}

.app-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;
}

.app-pill {
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--border);
  font-size: 11px;
  font-weight: 500;
}

.app-title {
  flex: 1;
  margin-right: 50px;
  font: 400 18px/1 var(--display);
  text-align: center;
}

.app-label {
  margin: 14px 0 8px;
  color: var(--muted);
  font-size: 11px;
  font-weight: 500;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.chip {
  padding: 6px 11px;
  border-radius: 999px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--border);
  font-size: 11px;
}

.chip--on {
  background: var(--ink);
  box-shadow: none;
  color: var(--cream);
}

.pick {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 7px;
}

.pick__cell {
  padding: 2px 10px 0;
  border-radius: 16px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--border);
}

.pick__cell--on {
  background: #fff1e8;
  box-shadow: inset 0 0 0 2px var(--accent);
}

/* A row of numbers to choose from: round chips, all one size. */
.chips--count .chip {
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  padding: 0;
  font-size: 13px;
  font-weight: 500;
}

.app-button {
  display: grid;
  place-items: center;
  height: 46px;
  margin-top: auto;
  border-radius: 999px;
  background: var(--accent);
  color: #2c221e;
  font-size: 14px;
  font-weight: 500;
}

.app-button--float {
  position: absolute;
  left: 16px;
  right: 16px;
  bottom: 16px;
  box-shadow: 0 10px 20px -8px rgba(200, 95, 67, 0.7);
}

.post {
  margin-bottom: 10px;
  padding: 11px;
  border-radius: 20px;
  background: var(--surface);
  box-shadow: inset 0 0 0 1px var(--border);
}

.post__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin: 0 2px 8px;
  font-size: 12px;
}

.post__head b {
  font-weight: 500;
}

.post__head span {
  color: var(--muted);
  font-size: 10px;
}

.post__photo {
  aspect-ratio: 4 / 3.3;
  border-radius: 13px;
  overflow: hidden;
}

.scene {
  width: 100%;
  height: 100%;
}

.post__caption {
  margin: 9px 2px;
  font-size: 12px;
}

.post__reacts {
  display: flex;
  gap: 6px;
}

.react {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 4px 9px 4px 6px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--border);
  font-size: 11px;
  font-weight: 500;
}

/* The app's own reactions are emoji. */
.react i {
  font-style: normal;
  line-height: 1;
}

.screen--pack {
  text-align: center;
}

.pack__name {
  font: 400 21px/1.1 var(--display);
}

.pack__meta {
  margin-top: 4px;
  color: var(--muted);
  font-size: 11px;
}

.pack__critter {
  width: 64%;
  margin: 4px auto -6px;
}

.pack__pet {
  font: 400 23px/1.1 var(--display);
}

.bar {
  height: 8px;
  margin: 12px 4px 7px;
  border-radius: 99px;
  background: #eadfd2;
  overflow: hidden;
}

.bar i {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  background: #9cc77f;
  transform-origin: 0 50%;
}

.pack__stats,
.pack__row {
  display: flex;
  justify-content: space-between;
  padding: 0 4px;
  color: var(--ink-soft);
  font-size: 11px;
}

.pack__stats span {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.pack__row {
  margin: 16px 0 9px;
  color: var(--muted);
}

.members {
  display: flex;
  justify-content: space-between;
  padding: 0 6px;
}

.member {
  display: grid;
  justify-items: center;
  gap: 5px;
  color: var(--ink-soft);
  font-size: 10px;
}

.member i {
  position: relative;
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: #7fb6de;
  color: var(--ink);
  font: 500 15px/1 var(--text);
}

.member .ico {
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 18px;
  height: 18px;
  padding: 3px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--cream);
}

/* What happens on a screen when its step arrives. Still, final states without the script. */
@media (prefers-reduced-motion: no-preference) {
  .js .screen .bar i {
    transform: scaleX(0.35);
    transition: transform 1.2s 0.25s var(--ease);
  }

  .js .screen.is-on .bar i {
    transform: none;
  }

  .js .screen .member .ico,
  .js .screen .react,
  .js .screen .pick__cell--on {
    transform: scale(0);
    transition: transform 0.5s var(--spring);
  }

  .js .screen .pick__cell--on {
    transform: scale(0.86);
  }

  .js .screen.is-on .member .ico,
  .js .screen.is-on .react,
  .js .screen.is-on .pick__cell--on {
    transform: none;
  }

  .js .screen .member:nth-child(1) .ico,
  .js .screen .react:nth-child(1) {
    transition-delay: 0.35s;
  }
  .js .screen .member:nth-child(2) .ico,
  .js .screen .react:nth-child(2) {
    transition-delay: 0.5s;
  }
  .js .screen .member:nth-child(3) .ico,
  .js .screen .react:nth-child(3) {
    transition-delay: 0.65s;
  }
  .js .screen .member:nth-child(4) .ico {
    transition-delay: 0.8s;
  }
}

.rail {
  display: none;
}

@media (min-width: 960px) {
  /* Without the script: each step beside its own screen. */
  .step {
    grid-template-columns: minmax(0, 1fr) 320px;
    align-items: center;
    gap: clamp(48px, 8vw, 120px);
  }

  /* With it: one phone that stays, while the steps pass and its screen changes. */
  .is-pinned .how__body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 400px;
    align-items: start;
    gap: clamp(48px, 7vw, 112px);
  }

  .is-pinned .steps {
    gap: 0;
  }

  .is-pinned .step {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: center;
    min-height: 86vh;
    opacity: 0.35;
    transition: opacity 0.5s var(--ease);
  }

  /* The first one starts level with the top of the phone, right under the heading. */
  .is-pinned .step:first-child {
    justify-content: flex-start;
    min-height: 62vh;
    padding-top: calc((100vh - var(--phone) * 2.13 - 20px) / 2);
  }

  .is-pinned .step.is-on {
    opacity: 1;
  }

  .is-pinned .step__screen {
    display: none;
  }

  /* The rail is as tall as the window and holds the phone in its middle; on a short window
     the phone shrinks to fit. */
  .is-pinned .rail {
    --phone: min(316px, 42vh);
    position: sticky;
    top: 0;
    display: grid;
    place-items: center;
    height: 100vh;
  }

  .is-pinned .steps {
    --phone: min(316px, 42vh);
  }

  /* A round patch behind the phone, centred on its 400px column. It never gets wider than the
     column and the room beside it, so it stays whole on a window that has little of that. */
  .blob {
    position: absolute;
    width: min(520px, 72vh, max(100vw - 760px, 400px + 2 * var(--gutter)));
    aspect-ratio: 1;
    border-radius: 50%;
    opacity: 0;
    transition: opacity 0.8s var(--ease);
  }

  .blob--1 {
    background: var(--sky);
  }
  .blob--2 {
    background: var(--peach);
  }
  .blob--3 {
    background: var(--sage);
  }

  [data-step-on='1'] .blob--1,
  [data-step-on='2'] .blob--2,
  [data-step-on='3'] .blob--3 {
    opacity: 1;
  }

  .phone--full {
    width: var(--phone);
    box-shadow:
      inset 0 0 0 2px #51433c,
      inset 0 0 0 5px #2e2522,
      var(--shadow-lift);
    transform: perspective(1500px) rotateY(-10deg) rotateX(3deg) rotate(1deg);
    transition: transform 1s var(--ease);
  }

  [data-step-on='2'] .phone--full {
    transform: perspective(1500px) rotateY(0deg) rotateX(0deg) rotate(0deg);
  }

  [data-step-on='3'] .phone--full {
    transform: perspective(1500px) rotateY(10deg) rotateX(3deg) rotate(-1deg);
  }

  .phone--full .screen {
    opacity: 0;
    visibility: hidden;
    transform: translateY(14px) scale(0.985);
    transition:
      opacity 0.45s var(--ease),
      transform 0.6s var(--ease),
      visibility 0s 0.45s;
  }

  .phone--full .screen.is-on {
    opacity: 1;
    visibility: visible;
    transform: none;
    transition-delay: 0s;
  }
}

/* ------------------------------------------------------------------ 2. the six */

.six {
  padding-block: clamp(64px, 8vw, 120px);
  background: var(--peach);
}

.six__tints,
.tint {
  position: absolute;
  inset: 0;
}

.six__tints {
  z-index: -1;
}

.tint {
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}

.tint--mochi {
  background: var(--peach);
}
.tint--kit {
  background: var(--butter);
}
.tint--axo {
  background: var(--sky);
}
.tint--ribbit {
  background: var(--sage);
}
.tint--hoot {
  background: var(--cocoa);
}
.tint--bun {
  background: var(--blush);
}

[data-active='mochi'] .tint--mochi,
[data-active='kit'] .tint--kit,
[data-active='axo'] .tint--axo,
[data-active='ribbit'] .tint--ribbit,
[data-active='hoot'] .tint--hoot,
[data-active='bun'] .tint--bun {
  opacity: 1;
}

.six .head {
  margin-bottom: clamp(28px, 3.4vw, 44px);
}

/* Without the script: six cards. */
.six__panels {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 16px;
}

.char {
  padding: 16px 24px 28px;
  border-radius: var(--r-card);
  background: rgba(255, 253, 249, 0.66);
  text-align: center;
}

.char__art {
  position: relative;
  width: min(210px, 72%);
  margin: 0 auto 8px;
}

.char__hungry {
  position: absolute;
  inset: 0;
  opacity: 0;
}

.char__trait {
  margin-bottom: 8px;
}

.char h3 {
  font-size: 34px;
}

.char__text > p:last-child {
  margin-top: 10px;
  color: var(--ink-soft);
}

/* With it: one critter at a time, as large as the page allows, and six round tabs. */
.six__tabs {
  display: grid;
  grid-template-columns: repeat(6, minmax(44px, 76px));
  justify-content: center;
  gap: clamp(0px, 1.4vw, 14px);
}

.six__tab {
  display: grid;
  justify-items: center;
  gap: 4px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-soft);
  font: 500 13px/1.2 var(--text);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.six__tab .critter {
  padding: 5px 7px 3px;
  border-radius: 50%;
  background: rgba(255, 253, 249, 0);
  box-shadow: inset 0 0 0 2px rgba(59, 47, 42, 0);
  transition:
    background-color 0.25s,
    box-shadow 0.25s,
    transform 0.4s var(--spring);
}

.six__tab:hover .critter {
  transform: translateY(-4px);
}

.six__tab[aria-selected='true'] {
  color: var(--ink);
}

.six__tab[aria-selected='true'] .critter {
  background: rgba(255, 253, 249, 0.9);
  box-shadow: inset 0 0 0 2px var(--ink);
}

.six__tab span {
  display: none;
}

.js .six__panels {
  display: block;
}

.js .char {
  display: none;
  padding: 0;
  background: none;
}

.js .char.is-active {
  display: grid;
  justify-items: center;
}

.js .char__art {
  width: min(430px, 88%);
  margin: clamp(4px, 2vw, 24px) auto 0;
}

.js .char__art::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 6% 0 -6%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 253, 249, 0.85), rgba(255, 253, 249, 0.55) 62%, rgba(255, 253, 249, 0) 100%);
}

.js .char__art .critter {
  transition: opacity 0.3s;
}

.js [data-mood='hungry'] .char__fed {
  opacity: 0;
}

.js [data-mood='hungry'] .char__hungry {
  opacity: 1;
}

.js .char h3 {
  font-size: clamp(72px, 15vw, 190px);
  line-height: 0.86;
  letter-spacing: -0.05em;
}

.js .char__trait {
  margin-bottom: 14px;
}

.js .char__text > p:last-child {
  max-width: 26em;
  margin: 18px auto 0;
  font-size: clamp(18px, 1.5vw, 21px);
  line-height: 1.5;
}

@media (prefers-reduced-motion: no-preference) {
  .js .char.is-active .char__art {
    animation: char-in 0.7s var(--spring) both;
  }

  .js .char.is-active .char__text {
    animation: rise-in 0.6s 0.08s var(--ease) both;
  }
}

@keyframes char-in {
  from {
    opacity: 0;
    transform: scale(0.82) rotate(-5deg);
  }
}

.six__mood {
  display: flex;
  width: fit-content;
  margin: clamp(24px, 3vw, 36px) auto 0;
  padding: 4px;
  border-radius: 999px;
  background: rgba(59, 47, 42, 0.08);
}

.mood {
  min-height: 44px;
  padding: 0 20px;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--ink);
  font: 500 15px/1 var(--text);
  cursor: pointer;
  transition: background-color 0.2s;
}

.mood[aria-pressed='true'] {
  background: var(--surface);
  box-shadow: var(--shadow);
}

@media (min-width: 560px) {
  .six__tab span {
    display: block;
  }
}

@media (min-width: 900px) {
  .js .char.is-active {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    justify-items: start;
    gap: clamp(24px, 4vw, 72px);
    min-height: 500px;
    text-align: left;
  }

  .js .char__art {
    order: 2;
    width: min(500px, 100%);
    margin: 0;
    justify-self: center;
  }

  .js .char__text > p:last-child {
    margin-left: 0;
  }

  .six__mood {
    margin-top: 0;
    margin-left: 0;
  }
}

/* ------------------------------------------------------------------ 3. growing up */

.grow {
  overflow-x: clip;
}

.growth {
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

.growth::-webkit-scrollbar {
  display: none;
}

.growth__track {
  display: flex;
  gap: 12px;
  width: max-content;
  margin: 0;
  padding: 8px var(--gutter) 36px;
  list-style: none;
}

.stage {
  flex: 0 0 min(66vw, 260px);
  padding: 0 20px 26px;
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--shadow);
  scroll-snap-align: center;
  text-align: center;
}

.stage__art {
  margin-top: -12%;
}

.stage h3 {
  margin-top: 6px;
  font-size: 26px;
}

.stage p {
  margin-top: 6px;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.45;
}

@media (min-width: 900px) {
  /* All six on one line of ground, which draws itself as the row scrolls into view. */
  .growth {
    width: min(1160px, 100% - 2 * var(--gutter));
    margin-inline: auto;
    overflow: visible;
  }

  .growth__track {
    position: relative;
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 0;
    width: auto;
    padding: 0;
  }

  .growth__track::before,
  .growth__track::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    aspect-ratio: 6 / 0.925;
    border-bottom: 3px dotted #d9c8b6;
    pointer-events: none;
  }

  .growth__track::after {
    border-bottom: 3px solid var(--accent);
    border-radius: 0 0 3px 3px;
    transform-origin: 0 50%;
  }

  .stage {
    position: relative;
    z-index: 1;
    padding: 0 10px;
    border-radius: 0;
    background: none;
    box-shadow: none;
  }

  .stage__art {
    margin-top: 0;
  }

  .stage h3 {
    margin-top: 22px;
  }

  .stage p {
    max-width: 14em;
    margin-inline: auto;
  }

  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .growth__track::after {
        animation: draw linear both;
        animation-timeline: view();
        animation-range: entry 40% cover 62%;
      }
    }
  }
}

@keyframes draw {
  from {
    transform: scaleX(0);
  }
}

/* The pinned window (html.grow-live). boot.js turns it on when it can work and grow.js keeps
   that true; without the mark everything from here to "4. fair rules" is dormant and the row
   above stands as it is. With it, the section is a long run of page that one screen stays pinned
   to: a critter in an arched window, the six stages as a small row, and the caption of the stage
   it is at. grow.js moves it; everything that moves is a transform or an opacity. */

.grow__stage,
.grow__line {
  display: none;
}

.grow-live .grow {
  /* How much scrolling each step of growing up takes. */
  --grow-step: 56vh;
  /* On a phone the window takes the height the screen has left once the row, its caption and
     the air around them have their 306px. It is four fifths of that wide if the screen is, and
     never taller than one and a half times its width. */
  --arch-room: max(200px, 100vh - 306px);
  --arch-w: min(100vw - 2 * var(--gutter), var(--arch-room) * 0.8);
  --arch-h: min(var(--arch-room), var(--arch-w) * 1.5);
  /* The pin ends in its own bit of air. */
  padding-bottom: 24px;
}

.grow-live .grow__run::after {
  content: '';
  display: block;
  height: calc(6.2 * var(--grow-step));
}

/* On a phone the heading scrolls away and the pin holds from the window down: grow.js measures
   the heading (--grow-head), and the pin sticks that far above the top of the screen. */
.grow-live .grow__pin {
  position: sticky;
  top: calc(12px - var(--grow-head, 0px));
  display: flex;
  flex-direction: column;
  min-height: calc(var(--grow-head, 0px) + 100vh - 12px);
}

/* Both measured by the small viewport height where a browser has it (see the cover for why this
   is a rule of its own). */
@supports (height: 100svh) {
  .grow-live .grow {
    --arch-room: max(200px, 100svh - 306px);
  }

  .grow-live .grow__pin {
    min-height: calc(var(--grow-head, 0px) + 100svh - 12px);
  }
}

.grow-live .grow__stage {
  position: relative;
  flex: none;
  display: grid;
  place-items: center;
  isolation: isolate;
}

/* The window: a half circle at the top, the cards' corners at the bottom. */
.arch {
  --arch-shape: calc(var(--arch-w) / 2) calc(var(--arch-w) / 2) var(--r-card) var(--r-card);
  position: relative;
  width: var(--arch-w);
  height: var(--arch-h);
}

/* Its shadow is kept apart from the window, so the window can be a clean layer of its own. */
.arch::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: var(--arch-shape);
  box-shadow: var(--shadow-lift);
}

.arch__window {
  position: absolute;
  inset: 0;
  border-radius: var(--arch-shape);
  background: #fbe7d5;
  overflow: hidden;
  isolation: isolate;
  /* A layer of its own: without it Chromium now and then forgets the round corners while
     something inside fades or moves. */
  transform: translateZ(0);
}

/* A hairline around the glass: at dawn the sky is nearly the color of the page. */
.arch__window::after {
  content: '';
  position: absolute;
  z-index: 5;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1.5px rgba(59, 47, 42, 0.07);
  pointer-events: none;
}

/* Five skies, five hills and five halos lie on top of each other. The one of the hour fades in
   over the one before it, which leaves only once it is covered. */
.sky,
.hill,
.halo {
  position: absolute;
  opacity: 0;
  transition: opacity 0.7s ease 0.7s;
}

[data-sky='dawn'] :is(.sky--dawn, .hill--dawn, .halo--dawn),
[data-sky='day'] :is(.sky--day, .hill--day, .halo--day),
[data-sky='dusk'] :is(.sky--dusk, .hill--dusk, .halo--dusk),
[data-sky='night'] :is(.sky--night, .hill--night, .halo--night),
[data-sky='gold'] :is(.sky--gold, .hill--gold, .halo--gold) {
  z-index: 1;
  opacity: 1;
  transition-delay: 0s;
}

.sky {
  inset: 0;
}

.sky--dawn {
  background: linear-gradient(180deg, #fdf2e5 0%, #f9d9be 80%);
}

.sky--day {
  background: linear-gradient(180deg, #cfe5f3 0%, #e9f4ec 80%);
}

.sky--dusk {
  background: linear-gradient(180deg, #d3b1c9 0%, #f5bf9f 72%);
}

.sky--night {
  background:
    radial-gradient(circle at 18% 20%, #fff 0 1.1px, transparent 1.8px), radial-gradient(circle at 34% 42%, #fff 0 0.9px, transparent 1.6px),
    radial-gradient(circle at 52% 14%, #fff 0 1.2px, transparent 1.9px), radial-gradient(circle at 70% 34%, #fff 0 0.9px, transparent 1.6px),
    radial-gradient(circle at 84% 52%, #fff 0 1.1px, transparent 1.8px), radial-gradient(circle at 12% 58%, #fff 0 0.9px, transparent 1.6px),
    radial-gradient(circle at 44% 62%, #fff 0 0.8px, transparent 1.5px), radial-gradient(circle at 62% 56%, #fff 0 1px, transparent 1.7px),
    linear-gradient(180deg, #1b2340 0%, #313c6b 82%);
}

.sky--gold {
  background: radial-gradient(circle at 50% 62%, #fff8dd 0%, #fbe7ae 46%, #f4d184 100%);
}

/* The orbs sit above every sky and the hills above the orbs: the sun sets behind them. */
.hill {
  z-index: 3;
  left: -25%;
  right: -25%;
  top: 79%;
  height: 60%;
  border-radius: 50%;
}

[data-sky='dawn'] .hill--dawn,
[data-sky='day'] .hill--day,
[data-sky='dusk'] .hill--dusk,
[data-sky='night'] .hill--night,
[data-sky='gold'] .hill--gold {
  z-index: 4;
}

.hill--dawn {
  background: linear-gradient(180deg, #f6cfae 0%, #f2bf99 34%);
}

.hill--day {
  background: #bcd9a4;
}

.hill--dusk {
  background: #cb9b86;
}

.hill--night {
  background: #3b477c;
}

.hill--gold {
  background: #edc67c;
}

/* The sun and the moon ride one wheel, half a turn apart. grow.js turns it with the scroll. */
.orb {
  position: absolute;
  z-index: 2;
  left: 0;
  top: 0;
  width: 15%;
  aspect-ratio: 1;
  margin: -7.5% 0 0 -7.5%;
  border-radius: 50%;
  /* Where the sun stands at dawn, until the script places it (in the orb's own sizes). */
  transform: translate3d(95%, 616%, 0);
  opacity: 0;
  transition: opacity 0.6s ease;
  will-change: transform;
}

.orb--sun {
  background: radial-gradient(circle at 36% 34%, #fff1c4, #f9c56f 70%);
  box-shadow:
    0 0 0 10px rgba(255, 226, 160, 0.28),
    0 0 44px 14px rgba(250, 196, 110, 0.5);
}

.orb--moon {
  background: radial-gradient(circle at 70% 36%, rgba(247, 227, 161, 0) 0 44%, #f7e3a1 46%);
  box-shadow: 0 0 34px 2px rgba(247, 227, 161, 0.25);
}

/* Each is in the sky only in its own hours; near the horizon the round hill can't always hide them. */
:is([data-sky='dawn'], [data-sky='day'], [data-sky='dusk']) .orb--sun,
:is([data-sky='dusk'], [data-sky='night']) .orb--moon {
  opacity: 1;
}

.arch__clouds {
  position: absolute;
  z-index: 2;
  inset: 0;
  opacity: 0;
  transition: opacity 0.7s ease;
}

[data-sky='day'] .arch__clouds {
  opacity: 1;
}

/* Two clouds, kept off the arc the sun travels. */
.cloud {
  position: absolute;
  left: 4%;
  top: 53%;
  width: 22%;
  height: 6%;
  border-radius: 999px;
  background: #fff;
  opacity: 0.92;
  animation: cloud-drift 24s ease-in-out infinite alternate;
}

.cloud::before {
  content: '';
  position: absolute;
  left: 24%;
  bottom: 35%;
  width: 42%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: inherit;
}

.cloud + .cloud {
  left: 71%;
  top: 15%;
  width: 16%;
  height: 4.4%;
  opacity: 0.8;
  animation-duration: 31s;
  animation-direction: alternate-reverse;
}

.arch__star {
  position: absolute;
  left: 26%;
  top: 30%;
  width: 9px;
  height: 9px;
  background: #f7e3a1;
  clip-path: polygon(50% 0, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0 50%, 40% 40%);
  animation: twinkle 3.2s ease-in-out infinite;
}

.arch__star + .arch__star {
  left: 76%;
  top: 44%;
  width: 7px;
  height: 7px;
  background: #fff;
  animation-delay: -1.1s;
}

.arch__star + .arch__star + .arch__star {
  left: 46%;
  top: 9%;
  animation-delay: -2.2s;
}

.arch__rays {
  position: absolute;
  left: 50%;
  top: 62%;
  width: 230%;
  aspect-ratio: 1;
  margin: -115% 0 0 -115%;
  border-radius: 50%;
  background: repeating-conic-gradient(rgba(255, 255, 255, 0.5) 0 9deg, rgba(255, 255, 255, 0) 9deg 18deg);
  -webkit-mask-image: radial-gradient(closest-side, #000 18%, transparent 72%);
  mask-image: radial-gradient(closest-side, #000 18%, transparent 72%);
  animation: spin 70s linear infinite;
}

/* The critter. A pat is a tap on it, so it is a button. Inside: two layers to change between,
   and the parts that only show for a moment. */
.actor {
  position: absolute;
  left: 12%;
  bottom: 8%;
  width: 76%;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: 28px;
  background: none;
  transform-origin: 50% 91%;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

/* The keyboard's ring goes around the whole window, where a browser can tell the window that
   its button has it; a square around the critter would cut through the picture. */
@supports selector(:has(a)) {
  .actor:focus-visible {
    outline: none;
  }

  .arch:has(.actor:focus-visible)::before {
    outline: 3px solid var(--ink);
    outline-offset: 4px;
  }
}

.actor__layer,
.shell {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform-origin: 50% 91%;
  pointer-events: none;
}

.actor__layer.is-front {
  opacity: 1;
}

.actor__idle {
  display: block;
  height: 100%;
  transform-origin: 50% 91%;
}

.actor[data-kind='egg'] .is-front .actor__idle {
  transform-origin: 50% 92%;
  animation: wobble 3.2s ease-in-out infinite;
}

.actor[data-kind='egg'][data-cracking] .is-front .actor__idle {
  animation: egg-shake 1.3s ease-in-out infinite;
}

.actor[data-kind='critter'] .is-front .actor__idle {
  animation: breathe 3.6s ease-in-out infinite;
}

/* Resting while off screen, like the rest of the page's loops. */
.js [data-live]:not(.is-live) :is(.actor__idle, .cloud, .arch__star, .arch__rays) {
  animation-play-state: paused;
}

.actor__layer.is-popping {
  animation: pop-in 0.55s var(--ease) both;
}

.actor__layer.is-leaving {
  animation: fade-out 0.3s ease both;
}

.actor__layer.is-hatched {
  animation: hatch-in 0.6s 0.1s var(--spring) both;
}

.actor.is-growing {
  animation: grow-up 0.6s var(--spring);
}

.actor.is-patted {
  animation: boing 0.55s ease;
}

/* The shell, twice: each copy cut along the crack, so the two halves can come apart. */
.shell--top {
  clip-path: polygon(0 0, 100% 0, 100% 62%, 69% 62%, 64% 65.5%, 59% 60.5%, 53% 66%, 48% 59.5%, 42% 65%, 37% 59%, 31% 63%, 0 63%);
}

.shell--bottom {
  clip-path: polygon(0 63%, 31% 63%, 37% 59%, 42% 65%, 48% 59.5%, 53% 66%, 59% 60.5%, 64% 65.5%, 69% 62%, 100% 62%, 100% 100%, 0 100%);
}

.actor.is-hatching .shell--top {
  animation: shell-top 0.75s var(--ease) both;
}

.actor.is-hatching .shell--bottom {
  animation: shell-bottom 0.75s ease both;
}

.burst {
  position: absolute;
  left: 50%;
  top: 60%;
  width: 0;
  height: 0;
  pointer-events: none;
}

.burst i {
  position: absolute;
  left: -7px;
  top: -7px;
  width: 14px;
  height: 14px;
  background: var(--gold);
  opacity: 0;
  clip-path: polygon(50% 0, 62% 38%, 100% 50%, 62% 62%, 50% 100%, 38% 62%, 0 50%, 38% 38%);
}

.burst.is-going i {
  animation: burst 0.85s var(--ease) both;
}

.burst i:nth-child(1) {
  --to: translate(0, -1250%);
}
.burst i:nth-child(2) {
  --to: translate(820%, -940%);
  background: #fff;
}
.burst i:nth-child(3) {
  --to: translate(1180%, -180%);
}
.burst i:nth-child(4) {
  --to: translate(880%, 420%);
  background: var(--accent);
}
.burst i:nth-child(5) {
  --to: translate(-880%, 420%);
}
.burst i:nth-child(6) {
  --to: translate(-1180%, -180%);
  background: #fff;
}
.burst i:nth-child(7) {
  --to: translate(-820%, -940%);
}
.burst i:nth-child(8) {
  --to: translate(360%, -1480%);
  background: var(--accent);
}

/* The name plate, as the app writes it under a critter: its name, how it is, how old. */
.plate {
  position: absolute;
  z-index: 2;
  left: 50%;
  bottom: 0;
  display: flex;
  align-items: baseline;
  padding: 8px 18px 9px;
  border-radius: 999px;
  background: var(--surface);
  box-shadow:
    inset 0 0 0 1.5px var(--border),
    var(--shadow);
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.3;
  white-space: nowrap;
  transform: translate(-50%, 50%);
}

.plate__name {
  color: var(--ink);
  font: 400 17px/1.2 var(--display);
}

.plate__status::before {
  content: '';
  display: inline-block;
  width: 4px;
  height: 4px;
  margin: 0 10px 3px;
  border-radius: 50%;
  background: #d9c8b6;
}

.plate__status,
.grow__line {
  transition: opacity 0.18s ease;
}

.plate__status.is-changing,
.grow__line.is-changing {
  opacity: 0;
}

/* The six stages, small: the row that shows where the critter in the window is. */
.grow-live .growth {
  position: relative;
  flex: none;
  width: min(100% - 2 * var(--gutter) + 12px, 520px);
  margin: auto auto 0;
  padding-top: 42px;
  overflow: visible;
  scroll-snap-type: none;
}

.grow-live .growth__track {
  position: relative;
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 0;
  width: auto;
  padding: 0 0 15px;
}

/* The line of ground under them, from the first stage to the last. */
.grow-live .growth__track::before {
  content: '';
  position: absolute;
  left: calc(100% / 12);
  right: calc(100% / 12);
  top: auto;
  bottom: 0;
  height: 0;
  aspect-ratio: auto;
  border-bottom: 3px dotted #d9c8b6;
  pointer-events: none;
}

.grow-live .growth__track::after {
  content: none;
}

/* It fills as far as the critter has come; grow.js stretches it with the scroll. */
.growth__fill {
  display: none;
}

.grow-live .growth__fill {
  position: absolute;
  left: calc(100% / 12);
  right: calc(100% / 12);
  bottom: 0;
  display: block;
  height: 3px;
  border-radius: 3px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: 0 50%;
}

.grow-live .stage {
  position: relative;
  flex: none;
  padding: 2px 0 8px;
  border-radius: var(--r-chip);
  background: none;
  box-shadow: none;
  isolation: isolate;
  scroll-snap-align: none;
  text-align: center;
  /* The reveal's own two, and the lift of the stage it is at. */
  transition:
    opacity 0.7s var(--ease),
    transform 0.9s var(--ease),
    translate 0.5s var(--spring);
  transition-delay: 0s;
}

.grow-live .stage::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 0;
  border-radius: inherit;
  background: var(--surface);
  box-shadow:
    inset 0 0 0 2px var(--accent),
    var(--shadow);
  opacity: 0;
  transition: opacity 0.3s var(--ease);
}

.grow-live .stage.is-now {
  translate: 0 -6px;
}

.grow-live .stage.is-now::before {
  opacity: 1;
}

.grow-live .stage__art {
  width: 88%;
  max-width: 84px;
  margin: 0 auto;
}

.grow-live .stage h3 {
  margin-top: 0;
  color: var(--muted);
  font: 500 13px/1.3 var(--text);
  letter-spacing: 0;
}

.grow-live .stage.is-now h3 {
  color: var(--ink);
}

@media (max-width: 340px) {
  /* On the narrowest phones "Legend" would touch both sides of its frame. */
  .grow-live .stage h3 {
    font-size: 12px;
    letter-spacing: -0.02em;
  }
}

/* Their captions stay for screen readers; the one of the stage it is at shows below, larger. */
.grow-live .stage p {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.grow-live .grow__line {
  display: block;
  /* Room for two lines above the padding, so the row doesn't move when a caption needs both. */
  min-height: calc(2.5em + 12px);
  margin: 18px var(--gutter) auto;
  padding-bottom: 12px;
  color: var(--ink);
  font: 400 clamp(20px, 1.9vw, 26px) / 1.25 var(--display);
  letter-spacing: -0.015em;
  text-align: center;
  text-wrap: balance;
}

.arch__halos {
  display: none;
}

@media (min-width: 900px) {
  /* Wide: the words and the row on the left, the window on the right, all of it one screen
     that stays while the steps go by. */
  .grow-live .grow {
    padding-block: 0;
  }

  .grow-live .grow__pin {
    top: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: 1fr auto auto auto 1fr;
    grid-template-areas:
      '. stage'
      'intro stage'
      'row stage'
      'line stage'
      '. stage';
    column-gap: clamp(40px, 6vw, 96px);
    width: min(1160px, 100% - 2 * var(--gutter));
    min-height: 100vh;
    margin-inline: auto;
  }

  .grow-live .grow__intro {
    grid-area: intro;
    width: auto;
    margin: 0;
  }

  /* On a short window the heading gives way before the picture does. */
  .grow-live .grow h2 {
    font-size: min(clamp(34px, 4.6vw + 18px, 76px), 10vh);
  }

  .grow-live .grow .head {
    margin-bottom: clamp(24px, 5vh, 52px);
  }

  .grow-live .grow__stage {
    grid-area: stage;
    align-self: center;
  }

  .plate {
    padding: 9px 22px 10px;
    font-size: 15px;
  }

  .plate__name {
    font-size: 19px;
  }

  /* Four wide and five tall here, which makes these corners the same half circle. */
  .arch {
    --arch-shape: 50% 50% var(--r-card) var(--r-card) / 40% 40% var(--r-card) var(--r-card);
    width: min(420px, 78%, 50vh);
    height: auto;
    aspect-ratio: 4 / 5;
  }

  .grow-live .growth {
    grid-area: row;
    width: auto;
    margin: 0 -6px;
    padding-top: 0;
  }

  .grow-live .grow__line {
    grid-area: line;
    min-height: 0;
    margin: 26px 0 0;
    padding-bottom: 0;
    text-align: left;
  }

  /* A round of the hour's color behind the window, as behind the phone in "How it works". */
  .arch__halos {
    position: absolute;
    z-index: -1;
    left: 50%;
    top: 50%;
    display: block;
    width: 142%;
    aspect-ratio: 1;
    margin: -71% 0 0 -71%;
    isolation: isolate;
  }

  .halo {
    inset: 0;
    border-radius: 50%;
  }

  .halo--dawn {
    background: var(--peach);
  }
  .halo--day {
    background: var(--sky);
  }
  .halo--dusk {
    background: #f6ddd6;
  }
  .halo--night {
    background: #dde2f3;
  }
  .halo--gold {
    background: var(--butter);
  }
}

@keyframes egg-shake {
  0%,
  40%,
  100% {
    transform: rotate(0) translateY(0);
  }
  48% {
    transform: rotate(-7deg) translateY(-2%);
  }
  58% {
    transform: rotate(7deg) translateY(0);
  }
  68% {
    transform: rotate(-5deg) translateY(-1.5%);
  }
  80% {
    transform: rotate(4deg) translateY(0);
  }
}

@keyframes pop-in {
  0% {
    opacity: 0;
    transform: scale(0.84);
  }
  60% {
    opacity: 1;
    transform: scale(1.04);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes fade-out {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
    transform: scale(0.92);
  }
}

@keyframes hatch-in {
  0% {
    opacity: 0;
    transform: scale(0.55, 0.45);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes grow-up {
  0% {
    transform: scale(0.88);
  }
  100% {
    transform: scale(1);
  }
}

@keyframes boing {
  0%,
  100% {
    transform: scale(1, 1);
  }
  28% {
    transform: scale(1.07, 0.9);
  }
  58% {
    transform: scale(0.96, 1.06);
  }
}

@keyframes shell-top {
  0% {
    opacity: 1;
    transform: none;
  }
  100% {
    opacity: 0;
    transform: translate(-18%, -44%) rotate(-32deg);
  }
}

@keyframes shell-bottom {
  0%,
  45% {
    opacity: 1;
    transform: none;
  }
  100% {
    opacity: 0;
    transform: scale(1.06, 0.82);
  }
}

@keyframes burst {
  0% {
    opacity: 0;
    transform: translate(0, 0) scale(0.2);
  }
  25% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: var(--to) scale(1.15) rotate(120deg);
  }
}

@keyframes cloud-drift {
  from {
    transform: translateX(-14%);
  }
  to {
    transform: translateX(22%);
  }
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

/* ------------------------------------------------------------------ 4. fair rules */

.fair {
  padding-bottom: clamp(40px, 5vw, 72px);
}

.stack {
  display: grid;
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Each card sticks a little lower than the one before, so they pile up as the page scrolls. */
.rule {
  position: sticky;
  top: 12px;
  display: grid;
  gap: 4px;
  min-height: 430px;
  padding: clamp(24px, 4.4vw, 64px);
  border-radius: var(--r-page);
  background: var(--peach);
  /* The script steps a card back as the next one slides over it (its scale). */
  transform-origin: 50% 0;
}

/* The shadow a card lays on the one underneath. The script adds this layer and shows it only as
   far as the card has slid over, so all that changes while scrolling is an opacity. */
.rule__shade {
  position: absolute;
  z-index: -1;
  inset: 0;
  border-radius: inherit;
  box-shadow: 0 -30px 44px -40px rgba(59, 47, 42, 0.4);
  opacity: 0;
  pointer-events: none;
}

.rule:nth-child(2) {
  top: 26px;
  background: var(--butter);
}
.rule:nth-child(3) {
  top: 40px;
  background: var(--sky);
}
.rule:nth-child(4) {
  top: 54px;
  background: var(--sage);
}

.rule h3 {
  font-size: clamp(30px, 4vw, 56px);
  line-height: 1.02;
  letter-spacing: -0.03em;
}

.rule__text > p:last-child {
  max-width: 26em;
  margin-top: 16px;
  color: var(--ink-soft);
  font-size: clamp(17px, 1.45vw, 20px);
}

.rule__art {
  display: grid;
  place-items: center;
  align-self: end;
  width: min(250px, 70%);
  margin-inline: auto;
}

.joker {
  position: relative;
  width: 78%;
  padding: 26px 10px 18px;
  border-radius: 20px;
  background: var(--surface);
  box-shadow: var(--shadow-lift);
  rotate: 6deg;
}

.joker__j {
  position: absolute;
  left: 14px;
  top: 8px;
  color: var(--accent-text);
  font: 400 24px/1 var(--display);
}

.joker__j--flip {
  left: auto;
  top: auto;
  right: 14px;
  bottom: 8px;
  rotate: 180deg;
}

.rule__art--postcard .critter {
  padding: 10px;
  border-radius: 24px;
  background: var(--surface);
  box-shadow: var(--shadow-lift);
  rotate: -5deg;
}

/* On a narrow phone the three are wider than the box the pictures get: they stay in the middle
   of the card and spill evenly to both sides, instead of all to the right. */
.rule--sleep .rule__art {
  justify-content: center;
}

.napping {
  display: flex;
  gap: clamp(10px, 2vw, 18px);
}

.member--big {
  gap: 8px;
  font-size: 14px;
}

.member--big i {
  width: clamp(68px, 8.4vw, 96px);
  height: clamp(68px, 8.4vw, 96px);
  font-size: 28px;
}

.member--big .ico {
  right: -2px;
  bottom: -2px;
  width: 26px;
  height: 26px;
  padding: 5px;
}

.member--asleep i {
  background: #d6ddd0;
  color: var(--muted);
}

.member--asleep b {
  position: absolute;
  left: 76%;
  bottom: 78%;
  color: #6f86bd;
  font: 400 20px/1 var(--display);
  animation: snooze 3.2s ease-in-out infinite;
}

.member--asleep b:nth-of-type(2) {
  left: 96%;
  bottom: 100%;
  font-size: 26px;
  animation-delay: 0.45s;
}

.member--asleep b:nth-of-type(3) {
  left: 120%;
  bottom: 126%;
  font-size: 34px;
  animation-delay: 0.9s;
}

@media (max-width: 380px) {
  /* On the narrowest phones the last z would leave the card, and the page with it. */
  .member--asleep b:nth-of-type(2) {
    left: 86%;
  }

  .member--asleep b:nth-of-type(3) {
    left: 98%;
    font-size: 30px;
  }
}

@keyframes snooze {
  0%,
  100% {
    transform: translateY(4px);
    opacity: 0.3;
  }
  50% {
    transform: translateY(-4px);
    opacity: 1;
  }
}

@media (min-width: 800px) {
  .rule {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    align-items: center;
    gap: 40px;
    top: 24px;
    min-height: 440px;
  }

  .rule:nth-child(2) {
    top: 44px;
  }
  .rule:nth-child(3) {
    top: 64px;
  }
  .rule:nth-child(4) {
    top: 84px;
  }

  .rule__art {
    align-self: center;
    width: min(340px, 100%);
  }
}

@media (max-height: 539px) {
  /* A window this short can't hold a whole card under the place it would stick to, and the next
     card would slide over a part of it nobody got to see. Here the cards just follow each other. */
  .rule:nth-child(n) {
    position: relative;
    top: 0;
  }
}

/* ------------------------------------------------------------------ it never dies */

.saga {
  background: var(--blush);
}

.frames {
  display: grid;
  gap: 28px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.frame {
  display: grid;
  grid-template-columns: clamp(112px, 34vw, 150px) 1fr;
  align-items: center;
  gap: 4px 18px;
}

.frame__art {
  grid-row: span 2;
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border-radius: var(--r-card);
  background: rgba(255, 253, 249, 0.8);
  overflow: hidden;
}

.frame__art .critter {
  width: 86%;
}

.frame h3 {
  align-self: end;
  font-size: clamp(22px, 2.2vw, 28px);
}

.frame p {
  align-self: start;
  color: var(--ink-soft);
}

/* Three good days: three photos, each one ticked. */
.days {
  display: flex;
  justify-content: center;
  width: 100%;
  padding-top: 4%;
}

.day {
  position: relative;
  width: 34%;
  margin: 0 -3%;
  padding: 3% 3% 9%;
  border-radius: 10%;
  background: var(--surface);
  box-shadow: var(--shadow);
  rotate: -7deg;
}

.day:nth-child(2) {
  z-index: 1;
  translate: 0 -8%;
  rotate: 1deg;
}

.day:nth-child(3) {
  rotate: 8deg;
}

.day .scene {
  aspect-ratio: 1;
  border-radius: 8%;
}

.day .ico {
  position: absolute;
  left: 50%;
  bottom: -9%;
  width: 34%;
  height: auto;
  aspect-ratio: 1;
  margin-left: -17%;
  padding: 6%;
  border-radius: 50%;
  background: #8fbd72;
  box-shadow: 0 0 0 3px var(--surface);
  color: var(--surface);
}

@media (prefers-reduced-motion: no-preference) {
  .js .frame .day .ico {
    scale: 0;
    transition: scale 0.5s var(--spring);
  }

  .js .frame.is-in .day .ico {
    scale: 1;
  }

  .js .frame .day:nth-child(1) .ico {
    transition-delay: 0.5s;
  }
  .js .frame .day:nth-child(2) .ico {
    transition-delay: 0.8s;
  }
  .js .frame .day:nth-child(3) .ico {
    transition-delay: 1.1s;
  }
}

@media (min-width: 800px) {
  .frames {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(20px, 2.6vw, 36px);
  }

  .frame {
    display: block;
    text-align: center;
  }

  .frame__art {
    aspect-ratio: 4 / 3;
    margin-bottom: 24px;
  }

  .frame__art .critter {
    width: 66%;
  }

  .days {
    width: 78%;
    padding-top: 0;
  }

  .frame p {
    margin-top: 8px;
  }
}

/* ------------------------------------------------------------------ 5. streak, coins, outfits */

.shop {
  padding-bottom: clamp(64px, 8vw, 120px);
  overflow-x: clip;
}

.shop__grid {
  display: grid;
  /* The column is as wide as the page allows, whatever is in it. */
  grid-template-columns: minmax(0, 1fr);
  gap: 40px;
}

.shop .head {
  margin-bottom: 0;
}

/* What a good day earns the pack as the streak gets longer, one pile for each step: 1 coin,
   then 2, 3 and 5. */
.streak {
  display: flex;
  align-items: flex-end;
  gap: clamp(18px, 5.6vw, 40px);
  width: fit-content;
  margin-top: 48px;
  padding: 0 56px 18px 2px;
  border-bottom: 3px dotted #d9c8b6;
}

.pile {
  position: relative;
  display: flex;
  flex-direction: column-reverse;
  width: clamp(29px, 8.2vw, 44px);
}

/* A coin seen from a little above: its face, and its edge underneath. */
.pile i {
  display: block;
  aspect-ratio: 2.4;
  border-radius: 50%;
  background: radial-gradient(ellipse at 38% 30%, #fde79a, var(--gold) 62%);
  box-shadow: 0 5px 0 #d9a92b;
}

.pile i + i {
  margin-bottom: -26%;
}

.pile .ico {
  position: absolute;
  left: calc(100% + 8px);
  bottom: -6px;
  width: 42px;
  height: 42px;
}

.shop__note {
  margin-top: 28px;
  color: var(--muted);
  font-size: 16px;
}

@media (prefers-reduced-motion: no-preference) {
  .js .streak .pile {
    opacity: 0;
    translate: 0 -18px;
    transition:
      opacity 0.3s,
      translate 0.6s var(--spring);
  }

  .js .streak.is-in .pile {
    opacity: 1;
    translate: 0 0;
  }

  .js .pile:nth-child(1) {
    transition-delay: 0.2s;
  }
  .js .pile:nth-child(2) {
    transition-delay: 0.3s;
  }
  .js .pile:nth-child(3) {
    transition-delay: 0.4s;
  }
  .js .pile:nth-child(4) {
    transition-delay: 0.5s;
  }
}

/* The dress-up toy. */
.toy {
  padding: clamp(16px, 2.4vw, 28px);
  border-radius: var(--r-page);
  background: var(--surface);
  box-shadow: var(--shadow-lift);
}

.toy__stage {
  width: min(340px, 100%);
  margin: 0 auto;
}

.toy__layer {
  opacity: 0;
  transition:
    opacity 0.22s,
    translate 0.4s var(--spring);
}

.toy__layer[data-slot='head'] {
  translate: 0 -22px;
}

.toy__layer[data-slot='neck'] {
  translate: 0 10px;
}

.toy__layer.is-on {
  opacity: 1;
  translate: 0 0;
}

.toy__controls {
  padding: 0 clamp(0px, 1vw, 12px);
}

.toy__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 20px;
}

.toy__hint {
  color: var(--muted);
  font-size: 15px;
}

.toy__label {
  margin: 18px 0 8px;
  color: var(--muted);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.toy__row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(48px, 1fr));
  gap: 8px;
}

.chip-item {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  padding: 10%;
  border: 0;
  border-radius: var(--r-chip);
  background: var(--cream);
  box-shadow: inset 0 0 0 1.5px var(--border);
  cursor: pointer;
  transition:
    transform 0.3s var(--spring),
    box-shadow 0.2s;
  -webkit-tap-highlight-color: transparent;
}

.chip-item svg {
  width: 100%;
  height: 100%;
  border-radius: 9px;
}

.chip-item:hover {
  transform: translateY(-3px);
}

.chip-item:active {
  transform: scale(0.92);
}

.chip-item[aria-pressed='true'] {
  background: #fff1e8;
  box-shadow: inset 0 0 0 2.5px var(--accent);
}

.toy__shuffle {
  flex: none;
  min-height: 44px;
  padding: 0 22px;
  border: 0;
  border-radius: 999px;
  background: var(--ink);
  color: var(--cream);
  font: 500 15px/1 var(--text);
  cursor: pointer;
  transition: transform 0.2s var(--ease);
}

.toy__shuffle:active {
  transform: scale(0.95);
}

@media (min-width: 900px) {
  .shop__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 480px);
    align-items: center;
    gap: clamp(40px, 6vw, 96px);
  }
}

/* A slow parade of outfits under it. */
.parade {
  margin-top: clamp(56px, 8vw, 112px);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.parade__track {
  display: flex;
  width: max-content;
  animation: parade 48s linear infinite;
}

.parade__track span {
  flex: none;
  width: clamp(104px, 13vw, 168px);
  margin-right: clamp(12px, 2.4vw, 36px);
}

@keyframes parade {
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

/* ------------------------------------------------------------------ 6. the extras */

.bento {
  display: grid;
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.extra {
  padding: 14px 14px 30px;
  border-radius: var(--r-card);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.extra__art {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  margin-bottom: 24px;
  border-radius: calc(var(--r-card) - 10px);
  background: var(--sage);
  overflow: hidden;
}

.extra--focus .extra__art {
  background: var(--blush);
}

.extra--recap .extra__art {
  background: var(--sky);
}

.extra h3,
.extra > p {
  padding: 0 12px;
}

.extra > p {
  margin-top: 8px;
  color: var(--ink-soft);
  font-size: 16px;
}

.homescreen {
  display: grid;
  grid-template-columns: repeat(4, 46px);
  grid-auto-rows: 46px;
  gap: 13px;
}

.app {
  border-radius: 13px;
  background: rgba(255, 253, 249, 0.72);
}

.widget {
  grid-column: span 2;
  grid-row: span 2;
  display: grid;
  justify-items: center;
  align-content: center;
  border-radius: 24px;
  background: var(--surface);
  box-shadow: var(--shadow);
  line-height: 1;
}

.widget .critter {
  width: 62px;
  margin-top: -6px;
}

.widget b {
  font: 400 19px/1 var(--display);
}

.widget span {
  margin-top: 3px;
  color: var(--muted);
  font-size: 10px;
}

.timer {
  position: relative;
  display: grid;
  place-items: center;
  width: 164px;
  aspect-ratio: 1;
  border-radius: 50%;
  background: var(--surface);
}

.timer__ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.timer .critter {
  width: 76px;
  margin-top: -28px;
}

.timer b {
  position: absolute;
  bottom: 30px;
  font: 400 20px/1 var(--display);
}

.story {
  width: 126px;
  padding: 12px 10px;
  border-radius: 18px;
  background: var(--surface);
  box-shadow: var(--shadow-lift);
  rotate: -4deg;
}

.story__week {
  font: 400 13px/1 var(--display);
}

.story__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  margin: 8px 0;
}

.story__grid i {
  display: block;
  aspect-ratio: 1;
  border-radius: 7px;
  overflow: hidden;
}

.story__stats {
  display: flex;
  justify-content: space-between;
  color: var(--muted);
  font-size: 8px;
  line-height: 1.3;
}

.story__stats b {
  display: block;
  color: var(--ink);
  font: 400 15px/1 var(--display);
}

@media (min-width: 600px) and (max-width: 859px) {
  /* Picture beside the words, so a wide card isn't mostly picture. */
  .extra {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
    column-gap: 12px;
    padding: 14px;
  }

  .extra__art {
    grid-row: span 2;
    margin-bottom: 0;
  }

  .extra h3 {
    align-self: end;
  }
}

@media (min-width: 860px) {
  .bento {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(16px, 2vw, 28px);
  }
}

/* ------------------------------------------------------------------ 7. the night */

.night {
  background: linear-gradient(180deg, #1b2340 0%, var(--night-2) 100%);
  color: #f6efe4;
}

.night .eyebrow {
  color: #f7e3a1;
}

.night .lead {
  color: #c8cfe6;
}

.night .head {
  margin-bottom: 0;
}

.night__sky {
  position: absolute;
  z-index: -1;
  inset: 0;
}

.twinkle {
  position: absolute;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: #fffdf9;
  animation: twinkle 3.8s ease-in-out infinite;
}

@keyframes twinkle {
  0%,
  100% {
    opacity: 0.25;
    transform: scale(0.8);
  }
  50% {
    opacity: 1;
    transform: scale(1.25);
  }
}

.twinkle--1 {
  left: 8%;
  top: 14%;
}
.twinkle--2 {
  left: 22%;
  top: 72%;
  animation-delay: -1.1s;
}
.twinkle--3 {
  left: 37%;
  top: 9%;
  width: 3px;
  height: 3px;
  animation-delay: -2.3s;
}
.twinkle--4 {
  left: 52%;
  top: 30%;
  animation-delay: -0.6s;
}
.twinkle--5 {
  left: 64%;
  top: 84%;
  width: 3px;
  height: 3px;
  animation-delay: -3s;
}
.twinkle--6 {
  left: 78%;
  top: 40%;
  animation-delay: -1.8s;
}
.twinkle--7 {
  left: 93%;
  top: 66%;
  animation-delay: -2.7s;
}
.twinkle--8 {
  left: 4%;
  top: 48%;
  width: 3px;
  height: 3px;
  animation-delay: -0.3s;
}
.twinkle--9 {
  left: 46%;
  top: 62%;
  width: 3px;
  height: 3px;
  animation-delay: -1.5s;
}
.twinkle--10 {
  left: 71%;
  top: 12%;
  width: 5px;
  height: 5px;
  animation-delay: -2.1s;
}
.twinkle--11 {
  left: 58%;
  top: 7%;
  width: 3px;
  height: 3px;
  animation-delay: -3.3s;
}
.twinkle--12 {
  left: 86%;
  top: 88%;
  animation-delay: -0.9s;
}
.twinkle--13 {
  left: 15%;
  top: 90%;
  width: 3px;
  height: 3px;
  animation-delay: -2.5s;
}
.twinkle--14 {
  left: 30%;
  top: 38%;
  width: 3px;
  height: 3px;
  animation-delay: -1.9s;
}

/* The stars are placed by the size of the page and the words by their own, so some stars would
   land on letters and read as specks on the type. */
@media (max-width: 859px) {
  /* One column: the words run the whole width of the upper sky. */
  .twinkle--1,
  .twinkle--3,
  .twinkle--4,
  .twinkle--6,
  .twinkle--14 {
    display: none;
  }

  .twinkle--8 {
    left: 2%;
  }
}

@media (min-width: 860px) {
  /* Two columns: the words are on the left. Two of these go above and below them, and one
     into the gap between the columns. */
  .twinkle--2 {
    left: 34%;
    top: 93%;
  }

  .twinkle--9 {
    left: 53.5%;
  }

  .twinkle--14 {
    left: 26%;
    top: 6%;
  }
}

.night__sky::after {
  content: '';
  position: absolute;
  left: 14%;
  top: 18%;
  width: 96px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, rgba(255, 253, 249, 0), #fffdf9);
  opacity: 0;
  rotate: 16deg;
  animation: shoot 11s ease-in 3s infinite;
}

@keyframes shoot {
  0%,
  90% {
    opacity: 0;
    transform: translateX(-80px);
  }
  92% {
    opacity: 0.9;
  }
  100% {
    opacity: 0;
    transform: translateX(380px);
  }
}

.night__moon {
  position: absolute;
  right: 8%;
  top: 9%;
  width: clamp(48px, 7vw, 88px);
}

.night__moon .ico {
  width: 100%;
  height: 100%;
}

.night__grid {
  display: grid;
  gap: 24px;
}

.nudges {
  display: grid;
  gap: 12px;
  margin-top: 32px;
}

.nudge {
  width: min(400px, 100%);
  padding: 14px 18px 16px;
  border-radius: 22px;
  background: rgba(255, 253, 249, 0.1);
  box-shadow: inset 0 0 0 1px rgba(255, 253, 249, 0.14);
  color: #f6efe4;
  font-size: 15px;
  line-height: 1.45;
}

.nudge b {
  display: flex;
  justify-content: space-between;
  margin-bottom: 3px;
  color: #f7e3a1;
  font-size: 13px;
  font-weight: 500;
}

.nudge b span {
  color: #a9b2d2;
  font-weight: 400;
}

.nudge--quiet {
  display: flex;
  align-items: center;
  gap: 10px;
  background: none;
  box-shadow: inset 0 0 0 1px rgba(255, 253, 249, 0.14);
  color: #c8cfe6;
}

.night__art {
  width: min(400px, 84%);
  margin-inline: auto;
}

.night__art .critter {
  transform-origin: 50% 91%;
  animation: breathe 6s ease-in-out infinite;
}

@media (min-width: 860px) {
  .night__grid {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    align-items: center;
    gap: 48px;
  }
}

/* ------------------------------------------------------------------ 8. privacy */

.privacy__grid {
  display: grid;
  gap: 24px;
}

.privacy__art {
  position: relative;
  width: min(300px, 64%);
  margin-inline: auto;
}

.privacy__art::before {
  content: '';
  position: absolute;
  z-index: -1;
  inset: 4% -6% -8%;
  border-radius: 50%;
  background: var(--blush);
}

.privacy .head {
  margin-bottom: clamp(24px, 3vw, 40px);
}

.promises {
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.promises li {
  padding: 22px 0;
  border-top: 1.5px solid var(--border);
}

.promises h3 {
  font-size: clamp(22px, 2vw, 26px);
}

.promises p {
  margin-top: 6px;
  color: var(--ink-soft);
  font-size: 16px;
}

.privacy__more {
  padding-top: 14px;
  border-top: 1.5px solid var(--border);
}

.more {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  font-weight: 500;
}

.more .ico {
  transition: transform 0.3s var(--ease);
}

.more:hover .ico {
  transform: translateX(4px);
}

@media (min-width: 620px) {
  .promises {
    grid-template-columns: 1fr 1fr;
    column-gap: 40px;
  }
}

@media (min-width: 900px) {
  .privacy__grid {
    grid-template-columns: minmax(0, 0.72fr) minmax(0, 1.28fr);
    align-items: center;
    gap: clamp(40px, 6vw, 96px);
  }

  .privacy__art {
    width: min(380px, 100%);
  }
}

/* ------------------------------------------------------------------ 9. the last page */

.finale {
  background: linear-gradient(180deg, #fdf2e5 0%, #fbe4d0 100%);
  text-align: center;
}

.finale .head {
  margin-bottom: clamp(20px, 3vw, 40px);
}

@media (max-width: 339px) {
  /* Small enough for "Hatch something." to stay on one line. */
  .finale h2 {
    font-size: 31px;
  }
}

.eggs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  width: min(440px, 100%);
  margin: 0 auto;
}

.egg {
  position: relative;
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: 28px;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.egg:disabled {
  cursor: default;
}

/* The drawings are larger than their buttons and lie over the neighbours, so they take no taps
   themselves: a tap belongs to the button whose square it is in. */
.egg .critter {
  pointer-events: none;
  transition:
    opacity 0.25s,
    scale 0.5s var(--spring);
}

.egg__shell {
  scale: 1.3;
  transform-origin: 50% 92%;
  animation: wobble 3.6s ease-in-out infinite;
}

.egg:nth-child(2) .egg__shell {
  animation-delay: -1.5s;
}
.egg:nth-child(3) .egg__shell {
  animation-delay: -2.7s;
}
.egg:nth-child(4) .egg__shell {
  animation-delay: -0.8s;
}
.egg:nth-child(5) .egg__shell {
  animation-delay: -2.1s;
}
.egg:nth-child(6) .egg__shell {
  animation-delay: -3.2s;
}

.egg:not(:disabled):hover .egg__shell {
  scale: 1.38;
}

.egg__baby {
  position: absolute;
  inset: 0;
  opacity: 0;
  scale: 0.5;
  transform-origin: 50% 91%;
}

.egg.is-hatched .egg__shell {
  opacity: 0;
  scale: 1.6;
}

.egg.is-hatched .egg__baby {
  opacity: 1;
  scale: 1.5;
}

.egg.is-hop .egg__baby {
  animation: hop 0.6s var(--ease);
}

@keyframes hop {
  40% {
    transform: translateY(-14%) scale(1.04, 0.96);
  }
  70% {
    transform: translateY(0) scale(0.97, 1.03);
  }
}

.eggs__said {
  min-height: 1.6em;
  margin-top: 8px;
  color: var(--ink-soft);
  font-size: 18px;
}

.finale__cta {
  margin-top: clamp(20px, 3vw, 36px);
}

@media (min-width: 760px) {
  .eggs {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    width: min(960px, 100%);
  }
}

/* Forced colors (Windows High Contrast) take away every background and shadow, and that is how
   the page draws a button's shape and which one is chosen. There a border says both. */
@media (forced-colors: active) {
  .mood,
  .chip-item,
  .toy__shuffle {
    border: 2px solid ButtonText;
  }

  .mood[aria-pressed='true'] {
    border-color: Highlight;
    background: Highlight;
    color: HighlightText;
  }

  .chip-item[aria-pressed='true'] {
    border: 5px solid Highlight;
  }

  .six__tab[aria-selected='true'] .critter,
  .grow-live .stage.is-now {
    outline: 3px solid Highlight;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cover__light::before,
  .finale__light::before,
  .parade__track,
  .night__sky::after {
    animation: none;
  }

  /* With motion off nothing fades in and out, so every step stays at full strength. */
  .is-pinned .step {
    opacity: 1;
  }

  .toy__layer,
  .toy__layer[data-slot] {
    translate: 0 0;
  }
}
