/* The six feature pictures: the app's own screens, redrawn in HTML and CSS.
   Every size is in em on a base of 1/63.3 of the picture's width (10px at the full 633px), so a
   picture scales as one image. A picture's static styles are its final frame; its animations are
   declared only under html.js, describe the way there, and run only while it is on screen. */

.mock {
  position: absolute;
  inset: 0;
  font-family: var(--font-sans);
  font-size: 10px;
  font-size: calc(100cqw / 63.3);
  line-height: 1.4;
  color: var(--ink);
  user-select: none;
}
.mock p {
  margin: 0;
}
.mock svg {
  display: block;
  flex: none;
}

/* Frames */
.m-window {
  position: absolute;
  inset: 6em 2.8em 2.6em;
  display: flex;
  overflow: hidden;
  border: 0.1em solid var(--line-strong);
  border-radius: 1.6em;
  background: var(--bg);
  box-shadow: 0 2.4em 5em #0000008c;
}
.m-rail {
  flex: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.5em;
  width: 5.8em;
  padding-top: 1.4em;
  border-right: 0.1em solid var(--line);
  background: #080b10;
}
.m-mark {
  display: grid;
  place-items: center;
  width: 2.6em;
  height: 2.6em;
  margin-bottom: 0.8em;
  border-radius: 0.8em;
  background: linear-gradient(
    140deg,
    var(--gold-bright),
    var(--gold) 60%,
    #b9863a
  );
  color: var(--on-gold);
}
.m-mark svg {
  width: 1.4em;
  height: 1.4em;
}
.m-rail span:not(.m-mark) {
  display: grid;
  justify-items: center;
  gap: 0.3em;
  width: 4.4em;
  padding: 0.6em 0;
  border-radius: 0.8em;
  font-size: 0.9em;
  color: var(--muted);
}
.m-rail span:not(.m-mark) svg {
  width: 1.9em;
  height: 1.9em;
}
.m-rail .is-current {
  background: var(--surface-2);
  color: var(--gold-bright);
}
.m-main {
  position: relative;
  flex: 1;
  min-width: 0;
  padding: 1.3em 2em;
}
.m-phone {
  position: absolute;
  top: 4%;
  bottom: 4%;
  left: 50%;
  aspect-ratio: 9 / 18.5;
  overflow: hidden;
  border: 0.5em solid #1b2130;
  border-radius: 3.6em;
  background: var(--bg);
  box-shadow:
    0 2.4em 5em #0000008c,
    0 0 0 0.1em var(--line-strong);
  transform: translateX(-50%);
}
.m-tv {
  position: absolute;
  left: 5%;
  top: 6%;
  width: 74%;
  aspect-ratio: 16 / 9;
  border: 0.7em solid #10141c;
  border-radius: 1.2em;
  background: var(--bg);
  box-shadow:
    0 2.4em 5em #0000008c,
    0 0 0 0.1em var(--line-strong);
}
.m-tv::after {
  content: "";
  position: absolute;
  left: 40%;
  right: 40%;
  top: 100%;
  height: 1.8em;
  margin-top: 0.7em;
  border-radius: 0 0 0.6em 0.6em;
  background: linear-gradient(#1a2130, #0c1017);
}

/* Shared parts */
.m-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.4em 1.1em;
  border-radius: 99em;
  background: linear-gradient(140deg, var(--gold-bright), var(--gold));
  box-shadow: 0 0.5em 1.4em #e8b45a40;
  font-size: 0.95em;
  font-weight: 600;
  color: var(--on-gold);
  white-space: nowrap;
}
.m-btn svg {
  width: 1em;
  height: 1em;
}
.m-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.3em 0.9em;
  border: 0.1em solid var(--line-strong);
  border-radius: 99em;
  background: var(--surface-2);
  font-size: 0.95em;
  font-style: normal;
  white-space: nowrap;
}
/* The phone app's bottom navigation. */
.m-tabbar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  justify-content: space-around;
  padding: 0.7em 0.6em 1.1em;
  border-top: 0.1em solid var(--line);
  background: #0a0d13f0;
}
.m-tabbar span {
  display: grid;
  justify-items: center;
  gap: 0.25em;
  font-size: 0.75em;
  color: var(--muted);
}
.m-tabbar svg {
  width: 1.6em;
  height: 1.6em;
}
.m-tabbar .is-current {
  color: var(--gold-bright);
}

/* Posters: fictional films drawn with gradients and shapes. .art is the same drawing without the
   poster's labels, for banners and half-seen cards. */
.poster,
.art {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background-color: var(--surface-2);
}
.poster {
  aspect-ratio: 2 / 3;
  border-radius: 0.6em;
  box-shadow: 0 0.6em 1.4em #00000066;
}
.poster::before,
.poster::after,
.art::before,
.art::after {
  content: "";
  position: absolute;
  z-index: 0;
}
.poster-title {
  position: absolute;
  z-index: 1;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 2em 0.4em 0.5em;
  background: linear-gradient(#05070c00, #05070ce0);
  font-family: var(--font-serif);
  font-size: 1.1em;
  font-weight: 700;
  line-height: 1.2;
  color: #fff;
  text-align: center;
  letter-spacing: 0.06em;
  white-space: nowrap;
}
.poster.thumb .poster-title {
  display: none;
}
.poster-rate {
  position: absolute;
  z-index: 1;
  top: 0.45em;
  right: 0.45em;
  padding: 0.1em 0.45em;
  border-radius: 0.5em;
  background: #000000a0;
  font-size: 0.8em;
  font-weight: 600;
  color: var(--gold-bright);
}
.poster-badge {
  position: absolute;
  z-index: 1;
  left: 0.5em;
  bottom: 3.1em;
  padding: 0.1em 0.55em;
  border-radius: 0.6em;
  background: var(--gold);
  font-size: 0.75em;
  font-weight: 700;
  color: var(--on-gold);
}

/* 山海之间: a gold sun over teal ridges. */
.p-1 {
  background:
    radial-gradient(circle at 50% 40%, #f6d28c 0 7%, #f6d28c00 7.6%),
    radial-gradient(circle at 50% 40%, #e8b45a66 0, #e8b45a00 34%),
    radial-gradient(ellipse 60% 16% at 72% 57%, #2b6c70 0 98%, #2b6c7000),
    linear-gradient(180deg, #0b2230 0%, #134552 46%, #2c6a6a 60%, #0b1e28 100%);
}
.p-1::before {
  inset: 0;
  background: linear-gradient(180deg, #1d4f5c, #0f2c38);
  clip-path: polygon(
    0 60%,
    14% 50%,
    28% 57%,
    44% 46%,
    60% 55%,
    76% 47%,
    90% 54%,
    100% 50%,
    100% 100%,
    0 100%
  );
}
.p-1::after {
  inset: 0;
  background: linear-gradient(180deg, #0c2430, #060f15);
  clip-path: polygon(
    0 72%,
    16% 63%,
    34% 70%,
    52% 61%,
    70% 69%,
    86% 62%,
    100% 68%,
    100% 100%,
    0 100%
  );
}

/* 无人之境: a low sun over dunes and one small figure. */
.p-2 {
  background:
    radial-gradient(circle at 70% 52%, #ffe2a8 0 5%, #ffe2a800 5.6%),
    radial-gradient(ellipse 90% 26% at 25% 100%, #4a2010 0 99%, #4a201000),
    linear-gradient(
      180deg,
      #2a1410 0%,
      #7a3420 38%,
      #d0763c 58%,
      #e9a55e 64%,
      #8a4423 66%,
      #5c2a15 100%
    );
}
.p-2::before {
  inset: 0;
  background: linear-gradient(180deg, #7e3b1e, #4e2311);
  clip-path: polygon(
    0 74%,
    22% 68%,
    44% 72%,
    66% 64%,
    100% 70%,
    100% 100%,
    0 100%
  );
}
.p-2::after {
  left: 60%;
  top: 59%;
  width: 2.4%;
  height: 7%;
  border-radius: 40% 40% 10% 10%;
  background: #1b0b06;
}

/* 星海归途: a ringed planet in a violet star field. */
.p-3 {
  background:
    radial-gradient(circle at 18% 22%, #fff 0 0.6%, #fff0 0.9%),
    radial-gradient(circle at 78% 14%, #fff 0 0.5%, #fff0 0.8%),
    radial-gradient(circle at 32% 66%, #ffffffcc 0 0.4%, #fff0 0.7%),
    radial-gradient(circle at 86% 72%, #ffffffaa 0 0.5%, #fff0 0.8%),
    radial-gradient(circle at 64% 30%, #ffffffbb 0 0.35%, #fff0 0.6%),
    radial-gradient(circle at 12% 86%, #ffffff99 0 0.4%, #fff0 0.7%),
    radial-gradient(ellipse at 30% 30%, #7b4fd244 0, #7b4fd200 60%),
    linear-gradient(160deg, #0d0822 0%, #241248 55%, #3a1c66 100%);
}
.p-3::before {
  left: 30%;
  top: 30%;
  width: 44%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(
    circle at 35% 30%,
    #e7d4ff,
    #9a74e0 45%,
    #3e2378 100%
  );
  box-shadow: 0 0 2em #9a74e055;
}
.p-3::after {
  left: 18%;
  top: 37%;
  width: 68%;
  aspect-ratio: 3 / 1;
  border: 0.25em solid #f4cd85bb;
  border-radius: 50%;
  transform: rotate(-16deg);
}

/* 雾港: a lighthouse beam through fog. */
.p-4 {
  background:
    radial-gradient(ellipse 70% 12% at 30% 70%, #c9d6e266 0, #c9d6e200 70%),
    radial-gradient(ellipse 80% 14% at 70% 80%, #c9d6e255 0, #c9d6e200 70%),
    linear-gradient(
      180deg,
      #1c2733 0%,
      #3b4d5f 45%,
      #7d90a3 66%,
      #33424f 67%,
      #1b242d 100%
    );
}
.p-4::before {
  left: 62%;
  bottom: 33%;
  width: 8%;
  height: 26%;
  background: linear-gradient(90deg, #dfe7ee, #9fb0c0);
  clip-path: polygon(28% 0, 72% 0, 100% 100%, 0 100%);
}
.p-4::after {
  inset: 0;
  background: conic-gradient(
    from 245deg at 66% 42%,
    #f4cd8500 0deg,
    #f4cd8570 7deg,
    #f4cd8500 16deg
  );
}

/* 第七信号: radio rings on deep green. */
.p-5 {
  background:
    repeating-radial-gradient(
      circle at 50% 58%,
      #5ee6c844 0 0.15em,
      #5ee6c800 0.2em 1.4em
    ),
    radial-gradient(circle at 50% 58%, #5ee6c833 0, #5ee6c800 55%),
    linear-gradient(180deg, #04201b 0%, #0a3a33 60%, #061c18 100%);
}
.p-5::before {
  left: 47%;
  top: 56%;
  width: 6%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #8ff7dd;
  box-shadow: 0 0 1.2em 0.4em #5ee6c899;
}
.p-5::after {
  left: 49.4%;
  top: 58%;
  width: 1.2%;
  height: 24%;
  background: linear-gradient(#8ff7dd, #8ff7dd00);
}

/* 长夜将明: dawn behind a city skyline. */
.p-6 {
  background:
    radial-gradient(circle at 50% 74%, #ffd08a 0 6%, #ffd08a00 6.6%),
    radial-gradient(ellipse at 50% 76%, #f2a65a88 0, #f2a65a00 50%),
    linear-gradient(
      180deg,
      #141737 0%,
      #2f2a64 34%,
      #7a3f6a 56%,
      #d97a45 72%,
      #f3b267 80%
    );
}
.p-6::before {
  inset: 0;
  background: #0b0d1f;
  clip-path: polygon(
    0 100%,
    0 80%,
    7% 80%,
    7% 70%,
    14% 70%,
    14% 84%,
    21% 84%,
    21% 62%,
    27% 62%,
    27% 58%,
    31% 58%,
    31% 76%,
    39% 76%,
    39% 68%,
    46% 68%,
    46% 82%,
    55% 82%,
    55% 60%,
    61% 60%,
    61% 54%,
    64% 54%,
    64% 72%,
    73% 72%,
    73% 66%,
    81% 66%,
    81% 78%,
    89% 78%,
    89% 70%,
    100% 70%,
    100% 100%
  );
}
.p-6::after {
  inset: 0;
  background:
    radial-gradient(circle at 24% 66%, #ffd08a 0 0.12em, #0000 0.16em),
    radial-gradient(circle at 58% 64%, #ffd08a 0 0.12em, #0000 0.16em),
    radial-gradient(circle at 42% 74%, #ffd08a 0 0.12em, #0000 0.16em),
    radial-gradient(circle at 76% 70%, #ffd08a 0 0.12em, #0000 0.16em);
}

/* 北境孤灯: a warm light under a snow peak. */
.p-7 {
  background:
    radial-gradient(circle at 22% 18%, #ffffffaa 0 0.4%, #fff0 0.7%),
    radial-gradient(circle at 70% 12%, #ffffff88 0 0.4%, #fff0 0.7%),
    linear-gradient(180deg, #08172a 0%, #17345a 45%, #4d79a3 70%, #9cc1df 100%);
}
.p-7::before {
  inset: 0;
  background: linear-gradient(180deg, #f1f6fb, #a9c1d6 60%, #6f8fae);
  clip-path: polygon(
    0 82%,
    18% 62%,
    30% 70%,
    50% 38%,
    66% 60%,
    78% 52%,
    100% 70%,
    100% 100%,
    0 100%
  );
}
.p-7::after {
  left: 34%;
  top: 74%;
  width: 3%;
  aspect-ratio: 1;
  border-radius: 50%;
  background: #ffd08a;
  box-shadow: 0 0 0.8em 0.35em #f4cd85aa;
}

/* 星途彼岸: a small boat on a gold horizon. */
.p-8 {
  background:
    radial-gradient(circle at 50% 56%, #ffe2a8 0 5%, #ffe2a800 5.6%),
    linear-gradient(90deg, #f4cd8500 44%, #f4cd8566 50%, #f4cd8500 56%) 0 62% /
      100% 38% no-repeat,
    linear-gradient(
      180deg,
      #0c2a33 0%,
      #1c5a63 42%,
      #d6a65a 58%,
      #164048 60%,
      #0a2328 100%
    );
}
.p-8::before {
  left: 40%;
  top: 66%;
  width: 14%;
  height: 3.5%;
  background: #071518;
  clip-path: polygon(0 0, 100% 0, 82% 100%, 18% 100%);
}
.p-8::after {
  left: 46%;
  top: 56%;
  width: 1%;
  height: 10%;
  background: #071518;
}

/* Library: the app on a wide screen — rail, featured banner, shelves. */
.m-banners {
  position: relative;
  height: 11.2em;
}
.m-banner {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border: 0.1em solid var(--line);
  border-radius: 1.2em;
  background: var(--surface);
}
.m-banner + .m-banner {
  opacity: 0;
}
.m-banner .art {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 66%;
}
.m-banner::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, var(--surface) 34%, #13182400 72%),
    linear-gradient(0deg, #131824b0, #13182400 55%);
}
.m-banner-text {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: flex-start;
  gap: 0.3em;
  height: 100%;
  padding: 1.3em 1.8em;
}
.m-banner-label {
  font-size: 0.85em;
  color: var(--gold-bright);
}
.m-banner-title {
  font-family: var(--font-serif);
  font-size: 2.3em;
  font-weight: 700;
  line-height: 1.1;
}
.m-banner-meta {
  margin-bottom: 0.4em;
  font-size: 0.9em;
  color: var(--muted);
}
.m-shelf {
  margin-top: 1.2em;
}
.m-shelf-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 0.8em;
}
.m-shelf-head b {
  font-size: 1.2em;
  font-weight: 600;
}
.m-shelf-head span {
  font-size: 0.9em;
  color: var(--gold-bright);
}
.m-posters {
  display: flex;
  gap: 1.1em;
}
.m-posters > * {
  flex: none;
  width: 6.9em;
}
.m-posters > .art {
  aspect-ratio: 2 / 3;
  border-radius: 0.6em;
}

.js .mock-library .m-banner:nth-child(1) {
  animation: library-first 9s infinite;
}
.js .mock-library .m-banner:nth-child(2) {
  animation: library-second 9s infinite;
}
.js .mock-library .m-banner:nth-child(3) {
  animation: library-third 9s infinite;
}
@keyframes library-first {
  0%,
  30% {
    opacity: 1;
  }
  36%,
  94% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes library-second {
  0%,
  30% {
    opacity: 0;
  }
  36%,
  63% {
    opacity: 1;
  }
  69%,
  100% {
    opacity: 0;
  }
}
@keyframes library-third {
  0%,
  63% {
    opacity: 0;
  }
  69%,
  94% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

/* Two tilted, dimmed posters behind a phone, so the picture is not a lone device. */
.m-backdrop {
  position: absolute;
  top: 22%;
  width: 15em;
  aspect-ratio: 2 / 3;
  border-radius: 1em;
  opacity: 0.45;
  filter: blur(0.08em);
}
.m-backdrop.left {
  left: 9%;
  transform: rotate(-9deg);
}
.m-backdrop.right {
  right: 9%;
  transform: rotate(8deg);
}
.m-appbar {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 1.4em 1.3em 0.8em;
  font-size: 1.05em;
}
.m-appbar .m-mark {
  width: 2em;
  height: 2em;
  margin: 0;
  border-radius: 0.6em;
}
.m-appbar .m-mark svg {
  width: 1.1em;
  height: 1.1em;
}
.m-appbar > svg {
  width: 1.4em;
  height: 1.4em;
  margin-left: auto;
  color: var(--muted);
}

/* Search: an alias finds the film. */
.m-field {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.5em;
  margin: 0.4em 1.1em 1em;
  padding: 0.6em 0.9em;
  border: 0.1em solid var(--gold);
  border-radius: 99em;
  background: var(--surface);
  box-shadow: 0 0 0 0.25em #e8b45a26;
}
.m-field > svg {
  width: 1.2em;
  height: 1.2em;
  color: var(--muted);
}
.m-typing {
  display: flex;
  align-items: center;
  font-size: 1.1em;
}
.m-caret {
  width: 0.08em;
  height: 1.1em;
  margin-left: 0.06em;
  background: var(--gold-bright);
}
.m-placeholder {
  position: absolute;
  left: 2.9em;
  opacity: 0;
  color: var(--faint);
}
.m-recent {
  margin: 0 1.1em 1.1em;
}
.m-recent > span {
  display: block;
  margin-bottom: 0.5em;
  font-size: 0.85em;
  color: var(--muted);
}
.m-recent .m-chip {
  margin: 0 0.35em 0.35em 0;
  font-size: 0.8em;
}
.m-results {
  display: grid;
  gap: 0.9em;
  margin: 0 1.1em;
}
.m-result {
  display: flex;
  align-items: center;
  gap: 0.8em;
}
.m-result .poster {
  flex: none;
  width: 3.4em;
  border-radius: 0.4em;
}
.m-result-title {
  font-size: 1.05em;
  font-weight: 600;
}
.m-result-meta {
  font-size: 0.8em;
  color: var(--muted);
}
.m-hit {
  display: inline-block;
  margin-top: 0.3em;
  padding: 0.05em 0.5em;
  border: 0.1em solid var(--gold);
  border-radius: 0.5em;
  font-size: 0.75em;
  color: var(--gold-bright);
}

.js .mock-search .m-query {
  animation: search-type 8s steps(1, end) infinite;
}
.js .mock-search .m-caret {
  animation:
    search-caret 8s steps(1, end) infinite,
    search-blink 0.8s steps(1, end) infinite;
}
.js .mock-search .m-placeholder {
  animation: search-placeholder 8s infinite;
}
.js .mock-search .m-result:nth-child(1) {
  animation: search-first 8s infinite;
}
.js .mock-search .m-result:nth-child(2) {
  animation: search-second 8s infinite;
}
.js .mock-search .m-result:nth-child(3) {
  animation: search-third 8s infinite;
}
.js .mock-search .m-hit {
  animation: search-hit 8s infinite;
}
/* 「星途」 is two characters: clipping half of it shows the first one. */
@keyframes search-type {
  0%,
  8% {
    clip-path: inset(0 100% 0 0);
  }
  14% {
    clip-path: inset(0 50% 0 0);
  }
  20%,
  92% {
    clip-path: inset(0 0 0 0);
  }
  92.01%,
  100% {
    clip-path: inset(0 100% 0 0);
  }
}
/* The caret follows the typed characters (1em each at the field's size). */
@keyframes search-caret {
  0%,
  8% {
    transform: translateX(-2em);
  }
  14% {
    transform: translateX(-1em);
  }
  20%,
  92% {
    transform: none;
  }
  92.01%,
  100% {
    transform: translateX(-2em);
  }
}
@keyframes search-blink {
  50% {
    opacity: 0;
  }
}
@keyframes search-placeholder {
  0%,
  12% {
    opacity: 1;
  }
  13%,
  92% {
    opacity: 0;
  }
  93%,
  100% {
    opacity: 1;
  }
}
@keyframes search-first {
  0%,
  24% {
    opacity: 0;
    transform: translateY(0.8em);
  }
  30%,
  88% {
    opacity: 1;
    transform: none;
  }
  92%,
  100% {
    opacity: 0;
  }
}
@keyframes search-second {
  0%,
  30% {
    opacity: 0;
    transform: translateY(0.8em);
  }
  36%,
  88% {
    opacity: 1;
    transform: none;
  }
  92%,
  100% {
    opacity: 0;
  }
}
@keyframes search-third {
  0%,
  36% {
    opacity: 0;
    transform: translateY(0.8em);
  }
  42%,
  88% {
    opacity: 1;
    transform: none;
  }
  92%,
  100% {
    opacity: 0;
  }
}
@keyframes search-hit {
  0%,
  44% {
    transform: none;
  }
  49% {
    transform: scale(1.15);
  }
  54%,
  100% {
    transform: none;
  }
}

/* Versions: the detail page's version list, with the best one picked. */
.mock-versions .m-main {
  display: flex;
  gap: 2.6em;
  padding: 1.4em 2em;
}
.mock-versions .m-detail {
  flex: none;
  width: 12em;
}
.mock-versions .m-detail .poster {
  width: 100%;
}
.mock-versions .m-title {
  margin-top: 1em;
  font-family: var(--font-serif);
  font-size: 2em;
  font-weight: 700;
  line-height: 1.15;
}
.mock-versions .m-original {
  margin-top: 0.2em;
  font-size: 0.9em;
  color: var(--muted);
}
.mock-versions .m-meta {
  margin-top: 0.3em;
  font-size: 0.85em;
  color: var(--muted);
}
.m-versions {
  position: relative;
  flex: 1;
  min-width: 0;
  padding-top: 2.2em;
}
.m-versions-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 1.2em;
}
.m-versions-head b {
  font-size: 1.3em;
  font-weight: 600;
}
.m-versions-head span {
  font-size: 0.85em;
  color: var(--muted);
}
.m-version {
  position: relative;
  display: flex;
  align-items: center;
  gap: 1em;
  height: 5.6em;
  margin-bottom: 1em;
  padding: 0 1.2em;
  border: 0.1em solid var(--line);
  border-radius: 1.2em;
  background: var(--surface);
}
.m-badge {
  display: grid;
  place-items: center;
  flex: none;
  width: 4.4em;
  height: 2.6em;
  border: 0.1em solid #e8b45a66;
  border-radius: 0.6em;
  background: #e8b45a14;
  font-size: 0.95em;
  font-weight: 700;
  color: var(--gold-bright);
}
.m-version-text {
  flex: 1;
  min-width: 0;
}
.m-tags {
  display: flex;
  gap: 0.4em;
  margin-bottom: 0.45em;
}
.m-tag {
  padding: 0.05em 0.55em;
  border: 0.1em solid var(--line-strong);
  border-radius: 0.45em;
  font-size: 0.8em;
  color: var(--ink);
}
.m-size {
  font-size: 0.85em;
  color: var(--muted);
}
.m-version .m-btn {
  position: relative;
}
/* The picked version's button glows once the frame settles on it. */
.m-version.is-best .m-btn::after {
  content: "";
  position: absolute;
  inset: -0.35em;
  border-radius: 99em;
  box-shadow: 0 0 1.2em 0.2em #f4cd8580;
}
.m-rows {
  position: relative;
}
.mock-versions .m-focus {
  position: absolute;
  top: -0.25em;
  left: -0.25em;
  right: -0.25em;
  height: 6.1em;
  border: 0.15em solid var(--gold);
  border-radius: 1.4em;
  box-shadow: 0 0 1.6em #e8b45a40;
  pointer-events: none;
}

.js .mock-versions .m-focus {
  animation: versions-focus 8s infinite;
}
.js .mock-versions .is-best .m-btn::after {
  animation: versions-glow 8s infinite;
}
/* Rows are 5.6em tall with 1em between them: one step is 6.6em. */
@keyframes versions-focus {
  0%,
  16% {
    transform: none;
  }
  24%,
  40% {
    transform: translateY(6.6em);
  }
  48%,
  64% {
    transform: translateY(13.2em);
  }
  72%,
  100% {
    transform: none;
  }
}
@keyframes versions-glow {
  0%,
  74% {
    opacity: 0;
  }
  82%,
  94% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

/* The phone pages' header (transfer, VIP). */
.m-head {
  padding: 1.6em 1.3em 0.9em;
}
.m-head-title {
  font-family: var(--font-serif);
  font-size: 1.9em;
  font-weight: 700;
  line-height: 1.15;
}
.m-head .m-sub {
  margin-top: 0.3em;
  font-size: 0.85em;
  color: var(--muted);
}
.m-phone > .m-btn.m-confirm {
  display: flex;
  justify-content: center;
  margin: 0 1.3em;
  padding: 0.6em 1em;
}

/* Transfer: six steps, a folder, three files, one submission. */
.m-qr-card {
  position: absolute;
  left: 7%;
  top: 30%;
  display: grid;
  justify-items: center;
  gap: 0.6em;
  width: 11em;
  padding: 1.2em 1em 1em;
  border-radius: 1.2em;
  background: #f5f7fa;
  box-shadow: 0 1.6em 3.6em #00000080;
  color: #172740;
  font-size: 0.95em;
  font-weight: 600;
  transform: rotate(-6deg);
}
.m-qr {
  width: 8em;
  height: 8em;
}
.m-steps {
  display: grid;
  grid-template-columns: repeat(3, auto);
  justify-content: start;
  gap: 0.45em;
  margin: 0 1.3em 1.1em;
}
.m-step {
  display: inline-flex;
  align-items: center;
  gap: 0.35em;
  padding: 0.25em 0.7em 0.25em 0.3em;
  border: 0.1em solid var(--line);
  border-radius: 99em;
  background: var(--surface-2);
  font-size: 0.85em;
}
.m-check {
  display: grid;
  place-items: center;
  width: 1.3em;
  height: 1.3em;
  border-radius: 50%;
  background: var(--success);
  color: #0a2a1a;
}
.m-check svg {
  width: 0.85em;
  height: 0.85em;
}
.m-target {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 0 1.3em 1em;
  padding: 0.8em 1em;
  border: 0.1em solid var(--line);
  border-radius: 1em;
  background: var(--surface);
  font-size: 0.9em;
}
.m-target > span {
  color: var(--muted);
}
.m-target b {
  display: flex;
  align-items: center;
  gap: 0.35em;
  font-weight: 600;
}
.m-target svg {
  width: 1.1em;
  height: 1.1em;
  color: var(--gold);
}
.m-files {
  display: grid;
  gap: 0.2em;
  margin: 0 1.3em 1.2em;
}
.m-file {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.55em 0;
  border-bottom: 0.1em solid var(--line);
  font-size: 0.85em;
}
.m-box {
  display: grid;
  place-items: center;
  flex: none;
  width: 1.3em;
  height: 1.3em;
  border-radius: 0.3em;
  background: var(--gold);
  color: var(--on-gold);
}
.m-box svg {
  width: 0.9em;
  height: 0.9em;
}
.m-file-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.m-file-size {
  flex: none;
  color: var(--muted);
}
.m-done {
  position: absolute;
  left: 1.1em;
  right: 1.1em;
  /* Above the tab bar. */
  bottom: 4.8em;
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 1em 1.1em;
  border: 0.1em solid #55c08866;
  border-radius: 1.1em;
  background: #10261d;
  box-shadow: 0 1em 2.4em #00000080;
  font-size: 1em;
  font-weight: 600;
}
.m-done .m-check {
  width: 1.8em;
  height: 1.8em;
}

.js .mock-transfer .m-step:nth-child(1) .m-check {
  animation: transfer-step-1 9s infinite;
}
.js .mock-transfer .m-step:nth-child(2) .m-check {
  animation: transfer-step-2 9s infinite;
}
.js .mock-transfer .m-step:nth-child(3) .m-check {
  animation: transfer-step-3 9s infinite;
}
.js .mock-transfer .m-step:nth-child(4) .m-check {
  animation: transfer-step-4 9s infinite;
}
.js .mock-transfer .m-step:nth-child(5) .m-check {
  animation: transfer-step-5 9s infinite;
}
.js .mock-transfer .m-step:nth-child(6) .m-check {
  animation: transfer-step-6 9s infinite;
}
.js .mock-transfer .m-confirm {
  animation: transfer-press 9s infinite;
}
.js .mock-transfer .m-done {
  animation: transfer-done 9s infinite;
}
/* One step checks every 7% of the loop; all clear together at the end. */
@keyframes transfer-step-1 {
  0%,
  6% {
    opacity: 0;
    transform: scale(0.4);
  }
  10%,
  92% {
    opacity: 1;
    transform: none;
  }
  96%,
  100% {
    opacity: 0;
  }
}
@keyframes transfer-step-2 {
  0%,
  13% {
    opacity: 0;
    transform: scale(0.4);
  }
  17%,
  92% {
    opacity: 1;
    transform: none;
  }
  96%,
  100% {
    opacity: 0;
  }
}
@keyframes transfer-step-3 {
  0%,
  20% {
    opacity: 0;
    transform: scale(0.4);
  }
  24%,
  92% {
    opacity: 1;
    transform: none;
  }
  96%,
  100% {
    opacity: 0;
  }
}
@keyframes transfer-step-4 {
  0%,
  27% {
    opacity: 0;
    transform: scale(0.4);
  }
  31%,
  92% {
    opacity: 1;
    transform: none;
  }
  96%,
  100% {
    opacity: 0;
  }
}
@keyframes transfer-step-5 {
  0%,
  34% {
    opacity: 0;
    transform: scale(0.4);
  }
  38%,
  92% {
    opacity: 1;
    transform: none;
  }
  96%,
  100% {
    opacity: 0;
  }
}
@keyframes transfer-step-6 {
  0%,
  41% {
    opacity: 0;
    transform: scale(0.4);
  }
  45%,
  92% {
    opacity: 1;
    transform: none;
  }
  96%,
  100% {
    opacity: 0;
  }
}
@keyframes transfer-press {
  0%,
  48% {
    transform: none;
  }
  50% {
    transform: scale(0.94);
  }
  53%,
  100% {
    transform: none;
  }
}
@keyframes transfer-done {
  0%,
  52% {
    opacity: 0;
    transform: translateY(120%);
  }
  58%,
  92% {
    opacity: 1;
    transform: none;
  }
  96%,
  100% {
    opacity: 0;
    transform: none;
  }
}

/* VIP: pay with 支付宝, the toast confirms, the expiry moves on. */
.m-glow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 46em;
  height: 34em;
  background: radial-gradient(closest-side, #e8b45a2e, #e8b45a00);
  transform: translate(-50%, -50%);
}
.m-toast {
  position: absolute;
  z-index: 2;
  top: 1em;
  left: 1em;
  right: 1em;
  padding: 0.8em 1em;
  border-left: 0.25em solid var(--gold);
  border-radius: 0.9em;
  background: var(--surface-3);
  box-shadow: 0 1em 2.4em #00000080;
  font-size: 0.85em;
}
.mock-vip .m-head {
  padding-top: 4.6em;
}
.m-vip-card {
  display: grid;
  gap: 0.35em;
  margin: 0 1.3em 1.2em;
  padding: 1.2em 1.2em 1.1em;
  border: 0.1em solid #e8b45a66;
  border-radius: 1.2em;
  background:
    radial-gradient(120% 90% at 100% 0, #e8b45a33, #e8b45a00 60%),
    linear-gradient(135deg, #2a2112, #15120c);
}
.m-vip-card svg {
  width: 1.8em;
  height: 1.8em;
  color: var(--gold-bright);
}
.m-vip-card b {
  font-family: var(--font-serif);
  font-size: 1.4em;
  color: var(--gold-bright);
}
.m-expiry {
  display: grid;
  font-size: 0.85em;
  color: var(--ink);
}
.m-expiry span {
  grid-area: 1 / 1;
}
.m-expiry .old {
  opacity: 0;
}
.m-pays {
  display: grid;
  gap: 0.5em;
  margin: 0 1.3em 1.2em;
}
.m-pays > span {
  font-size: 0.85em;
  color: var(--muted);
}
.m-pay {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.75em 0.9em;
  border: 0.1em solid var(--line);
  border-radius: 0.9em;
  background: var(--surface);
  font-size: 0.95em;
}
/* The picked row's gold edge and its radio dot crossfade, so the choice can move. */
.m-pay::before {
  content: "";
  position: absolute;
  inset: -0.1em;
  border: 0.12em solid var(--gold);
  border-radius: inherit;
  opacity: 0;
}
.m-radio {
  position: relative;
  width: 1.2em;
  height: 1.2em;
  border: 0.13em solid var(--line-strong);
  border-radius: 50%;
}
.m-radio::after {
  content: "";
  position: absolute;
  inset: 0.18em;
  border-radius: 50%;
  background: var(--gold);
  opacity: 0;
}
.m-pay.is-selected::before,
.m-pay.is-selected .m-radio::after {
  opacity: 1;
}

.js .mock-vip .m-pay:not(.is-selected)::before,
.js .mock-vip .m-pay:not(.is-selected) .m-radio::after {
  animation: vip-unpick 8s infinite;
}
.js .mock-vip .m-pay.is-selected::before,
.js .mock-vip .m-pay.is-selected .m-radio::after {
  animation: vip-pick 8s infinite;
}
.js .mock-vip .m-confirm {
  animation: vip-press 8s infinite;
}
.js .mock-vip .m-toast {
  animation: vip-toast 8s infinite;
}
.js .mock-vip .m-expiry .old {
  animation: vip-old 8s infinite;
}
.js .mock-vip .m-expiry .new {
  animation: vip-new 8s infinite;
}
@keyframes vip-unpick {
  0%,
  26% {
    opacity: 1;
  }
  30%,
  100% {
    opacity: 0;
  }
}
@keyframes vip-pick {
  0%,
  26% {
    opacity: 0;
  }
  30%,
  100% {
    opacity: 1;
  }
}
@keyframes vip-press {
  0%,
  38% {
    transform: none;
  }
  40% {
    transform: scale(0.94);
  }
  43%,
  100% {
    transform: none;
  }
}
@keyframes vip-toast {
  0%,
  46% {
    opacity: 0;
    transform: translateY(-160%);
  }
  52%,
  90% {
    opacity: 1;
    transform: none;
  }
  96%,
  100% {
    opacity: 0;
    transform: translateY(-160%);
  }
}
@keyframes vip-old {
  0%,
  54% {
    opacity: 1;
  }
  60%,
  94% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}
@keyframes vip-new {
  0%,
  54% {
    opacity: 0;
  }
  60%,
  94% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

/* TV: the remote moves the focus along a row; beside the set, the sign-in card. */
.mock-tv .m-tv {
  left: 4%;
  top: 21%;
  width: 66%;
}
.m-tv-screen {
  position: absolute;
  inset: 0;
  overflow: hidden;
  padding: 1.4em 1.8em;
  border-radius: 0.5em;
}
.m-tv-nav {
  display: flex;
  align-items: baseline;
  gap: 1.4em;
  margin-bottom: 0.8em;
}
.m-tv-brand {
  margin-right: 0.4em;
  font-size: 1.3em;
  font-weight: 800;
  color: var(--gold-bright);
}
.m-tv-tab {
  font-size: 0.9em;
  color: var(--muted);
}
.m-tv-tab.is-current {
  font-weight: 600;
  color: var(--gold-bright);
}
.m-tv-banner {
  position: relative;
  height: 6.2em;
  overflow: hidden;
  border-radius: 0.9em;
  background: var(--surface);
}
.m-tv-banner .art {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 62%;
}
.m-tv-banner::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, var(--surface) 36%, #13182400 74%);
}
.m-tv-banner-text {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: 0.25em;
  height: 100%;
  padding: 0 1.4em;
}
.m-tv-title {
  font-family: var(--font-serif);
  font-size: 1.7em;
  font-weight: 700;
  line-height: 1.1;
}
.m-tv-meta {
  font-size: 0.8em;
  color: var(--muted);
}
.m-tv-banner .m-btn {
  margin-top: 0.2em;
  font-size: 0.8em;
}
.m-tv-row > b {
  display: block;
  margin: 0.8em 0 0.5em;
  font-size: 1.05em;
  font-weight: 600;
}
.mock-tv .m-posters {
  position: relative;
  gap: 0.9em;
}
.mock-tv .m-posters > .poster {
  width: 5.6em;
}
.mock-tv .m-focus {
  position: absolute;
  top: -0.3em;
  left: -0.3em;
  width: 6.2em;
  aspect-ratio: 6.2 / 9;
  border: 0.18em solid var(--gold);
  border-radius: 0.8em;
  box-shadow: 0 0 1.4em #e8b45a66;
}
.m-signin {
  position: absolute;
  right: 4%;
  top: 17%;
  display: grid;
  justify-items: center;
  gap: 0.5em;
  width: 13em;
  padding: 1.2em 1em 1.1em;
  border: 0.1em solid var(--line-strong);
  border-radius: 1.2em;
  background: var(--surface-2);
  box-shadow: 0 1.6em 3.6em #00000080;
  font-size: 1em;
}
.m-signin .m-qr {
  width: 9em;
  height: 9em;
  padding: 0.5em;
  border-radius: 0.6em;
  background: #f5f7fa;
}
.m-code {
  font-size: 1.45em;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--gold-bright);
}
.m-signin > p:last-child {
  font-size: 0.85em;
  color: var(--muted);
}

.js .mock-tv .m-focus {
  animation: tv-focus 8s infinite;
}
.js .mock-tv .m-signin {
  animation: tv-float 8s ease-in-out infinite;
}
/* A poster and its gap are 6.5em: one press of the remote. */
@keyframes tv-focus {
  0%,
  18% {
    transform: none;
  }
  22%,
  38% {
    transform: translateX(6.5em);
  }
  42%,
  58% {
    transform: translateX(13em);
  }
  62%,
  78% {
    transform: translateX(19.5em);
  }
  82%,
  100% {
    transform: none;
  }
}
@keyframes tv-float {
  0%,
  100% {
    transform: none;
  }
  50% {
    transform: translateY(-0.4em);
  }
}

/* Playback, last so it wins over each picture's animation shorthand. `*` does not reach
   pseudo-elements, and a glow or a radio dot animates on one. */
.js .b-media:not(.is-playing) .mock *,
.js .b-media:not(.is-playing) .mock *::before,
.js .b-media:not(.is-playing) .mock *::after {
  animation-play-state: paused !important;
}
@media (prefers-reduced-motion: reduce) {
  .js .b-media *,
  .js .b-media *::before,
  .js .b-media *::after {
    animation: none !important;
  }
}
