/*
 * 流动绢本 · the final atmospheric layer
 *
 * This sheet intentionally comes last.  It removes the earlier exhibition-like
 * star map and lets one living canvas become the shared sky of all five folds.
 * Each chapter keeps a quiet veil for legibility, never an opaque page background.
 */

:root {
  --living-night: #090d20;
  --living-deep: #211528;
  --living-paper: #f1e3ca;
  --living-moon: #fff2d7;
  --living-ink: #302a30;
  --living-cinnabar: #a94f5f;
  --living-gold: #d0a56d;
  --living-mist: #a9b7c1;
}

html,
body.scroll-painting {
  background: var(--living-night);
}

body.scroll-painting {
  min-height: 100%;
  --portrait-shift-x: 0px;
  --portrait-shift-y: 0px;
  --portrait-light-x: 72%;
  --portrait-light-y: 30%;
}

.scroll-painting > .atmosphere {
  position: fixed;
  z-index: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0.99 !important;
  filter: saturate(1.12) contrast(1.045) brightness(1.015);
  pointer-events: none;
  transition: opacity 1.8s cubic-bezier(.2,.72,.22,1), filter 2.2s cubic-bezier(.2,.72,.22,1);
}

.scroll-painting[data-chapter="01"] > .atmosphere { filter: saturate(1.14) contrast(1.055) brightness(1.01); }
.scroll-painting[data-chapter="02"] > .atmosphere { opacity: 0.98 !important; filter: saturate(1.2) contrast(1.05) brightness(1.01); }
.scroll-painting[data-chapter="03"] > .atmosphere { opacity: 0.99 !important; filter: saturate(1.16) contrast(1.045) brightness(1.015); }
.scroll-painting[data-chapter="04"] > .atmosphere { opacity: 0.9 !important; filter: saturate(1.08) contrast(1.025) brightness(1.045); }
.scroll-painting[data-chapter="05"] > .atmosphere { opacity: 1 !important; filter: saturate(1.16) contrast(1.035) brightness(1.035); }

/* --------------------------------------------------------------------------
   月下花影 · an original living portrait, revealed only where the story begins
   -------------------------------------------------------------------------- */

.scroll-painting .portrait-world {
  position: fixed;
  z-index: 0;
  inset: 0;
  margin: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  contain: strict;
  transition: opacity 1.8s cubic-bezier(.2,.72,.22,1), filter 1.8s ease;
}

.scroll-painting .portrait-world picture,
.scroll-painting .portrait-world__image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.scroll-painting .portrait-world__image {
  object-fit: cover;
  object-position: center 44%;
  opacity: 0.94;
  filter: saturate(0.94) contrast(1.065) brightness(0.76);
  transform: translate3d(var(--portrait-shift-x), var(--portrait-shift-y), 0) scale(1.055);
  transform-origin: 72% 37%;
  will-change: transform, filter;
  animation: portrait-breathe 14s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting .portrait-world::before,
.scroll-painting .portrait-world::after,
.scroll-painting .portrait-world__ink,
.scroll-painting .portrait-world__light,
.scroll-painting .portrait-world__breath {
  position: absolute;
  inset: -8%;
  content: "";
  pointer-events: none;
}

.scroll-painting .portrait-world::before {
  z-index: 2;
  background:
    linear-gradient(90deg, rgb(3 8 20 / 0.78) 0%, rgb(3 8 20 / 0.56) 28%, rgb(3 8 20 / 0.12) 58%, transparent 78%),
    linear-gradient(180deg, rgb(3 8 18 / 0.12), transparent 50%, rgb(3 8 18 / 0.38));
}

.scroll-painting .portrait-world::after {
  z-index: 3;
  background:
    radial-gradient(circle at var(--portrait-light-x) var(--portrait-light-y), rgb(255 232 189 / 0.16), transparent 16%),
    radial-gradient(ellipse 45% 72% at 75% 44%, transparent 38%, rgb(5 11 24 / 0.14) 75%, rgb(5 11 24 / 0.26));
  mix-blend-mode: screen;
  transition: background-position 900ms cubic-bezier(.2,.72,.22,1);
}

.scroll-painting .portrait-world__ink {
  z-index: 1;
  opacity: 0.42;
  mix-blend-mode: multiply;
  filter: blur(22px);
  will-change: transform, opacity;
}

.scroll-painting .portrait-world__ink--one {
  background:
    radial-gradient(ellipse 32% 46% at 52% 60%, rgb(4 22 41 / 0.96), transparent 70%),
    radial-gradient(ellipse 23% 34% at 68% 17%, rgb(24 49 68 / 0.72), transparent 74%);
  animation: portrait-ink-one 18s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting .portrait-world__ink--two {
  opacity: 0.26;
  background:
    radial-gradient(ellipse 28% 22% at 70% 68%, rgb(133 58 73 / 0.72), transparent 73%),
    radial-gradient(ellipse 34% 21% at 88% 40%, rgb(113 150 159 / 0.55), transparent 75%);
  animation: portrait-ink-two 23s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting .portrait-world__light {
  z-index: 4;
  inset: 0;
  opacity: 0.55;
  background: linear-gradient(108deg, transparent 48%, rgb(246 226 188 / 0.035) 56%, rgb(246 226 188 / 0.12) 64%, transparent 75%);
  transform: translateX(-9%);
  animation: portrait-light-pass 11s cubic-bezier(.45,0,.35,1) infinite;
}

.scroll-painting .portrait-world__breath {
  z-index: 5;
  inset: auto 6% 5% auto;
  width: min(32vw, 480px);
  aspect-ratio: 1;
  border-radius: 50%;
  opacity: 0.3;
  background: radial-gradient(circle, rgb(236 207 158 / 0.14), transparent 68%);
  transform: scale(0.96);
}

.scroll-painting:not(.has-entered) .portrait-world {
  opacity: 0.9;
}

.scroll-painting.has-entered[data-chapter="01"] .portrait-world {
  opacity: 0.38;
  filter: saturate(0.92);
}

.scroll-painting.has-entered[data-chapter="02"] .portrait-world {
  opacity: 0.1;
  filter: saturate(0.72) hue-rotate(8deg);
}

.scroll-painting.has-entered[data-chapter="03"] .portrait-world,
.scroll-painting.has-entered[data-chapter="04"] .portrait-world,
.scroll-painting.has-entered[data-chapter="05"] .portrait-world {
  opacity: 0;
}

.scroll-painting.is-time-holding .portrait-world,
.scroll-painting.is-time-held .portrait-world {
  opacity: 0.86;
}

.scroll-painting.is-time-holding .portrait-world__image,
.scroll-painting.is-time-held .portrait-world__image {
  filter: saturate(1.02) contrast(1.045) brightness(0.86);
}

.scroll-painting.moon-secret-is-open .portrait-world *,
.scroll-painting.archive-is-open .portrait-world * {
  animation-play-state: paused !important;
}

@keyframes portrait-breathe {
  0% { transform: translate3d(var(--portrait-shift-x), var(--portrait-shift-y), 0) scale(1.055); }
  100% { transform: translate3d(var(--portrait-shift-x), var(--portrait-shift-y), 0) scale(1.075); }
}

@keyframes portrait-ink-one {
  0% { opacity: 0.32; transform: translate3d(-2%, 1%, 0) scale(0.96) rotate(-1deg); }
  100% { opacity: 0.48; transform: translate3d(3%, -2%, 0) scale(1.08) rotate(1.2deg); }
}

@keyframes portrait-ink-two {
  0% { transform: translate3d(2%, -2%, 0) scale(0.92); }
  100% { transform: translate3d(-3%, 3%, 0) scale(1.12); }
}

@keyframes portrait-light-pass {
  0%, 18% { opacity: 0; transform: translateX(-15%); }
  38% { opacity: 0.52; }
  62%, 100% { opacity: 0; transform: translateX(13%); }
}


/* Retire the old cosmic/projected layer so the new world has one visual grammar. */
.scroll-painting .memory-sky,
.scroll-painting .romance-veil,
.scroll-painting .chapter-backdrop,
.scroll-painting .pointer-light {
  display: none !important;
}

.scroll-painting .grain {
  z-index: 88;
  opacity: 0.055;
  animation: none;
  mix-blend-mode: soft-light;
}

.scroll-painting .cinema-frame {
  inset: 11px;
  border-color: rgb(238 228 209 / 0.06);
}

.scroll-painting main {
  position: relative;
  z-index: 1;
  isolation: auto;
  background: transparent;
}

/* --------------------------------------------------------------------------
   卷首 · the first light is already travelling before the letter is opened
   -------------------------------------------------------------------------- */

.scroll-painting .threshold {
  background:
    radial-gradient(ellipse 58% 74% at 24% 49%, rgb(5 8 22 / 0.52) 0%, rgb(6 10 23 / 0.29) 51%, transparent 78%),
    radial-gradient(circle at 77% 26%, rgb(159 65 92 / 0.11), transparent 31%),
    linear-gradient(180deg, rgb(4 7 20 / 0.08), transparent 50%, rgb(5 8 20 / 0.28));
  isolation: isolate;
}

.scroll-painting .threshold::before,
.scroll-painting .threshold::after,
.scroll-painting .threshold__orbit {
  display: none;
}

.scroll-painting .threshold__halo {
  z-index: -1;
  top: 53%;
  left: 33%;
  width: min(68vw, 930px);
  opacity: calc(0.12 + var(--hold-scale, 0) * 0.38);
  background: radial-gradient(ellipse, rgb(255 220 157 / 0.25), rgb(157 112 139 / 0.075) 43%, transparent 72%);
  filter: blur(15px);
}

.scroll-painting .threshold__content {
  position: relative;
  width: min(1100px, calc(100vw - 104px));
  padding: 3vh min(18vw, 220px) 3vh 0;
}

.scroll-painting .threshold__content::before {
  position: absolute;
  z-index: -1;
  inset: -12% -4% -8% -11%;
  content: "";
  background: radial-gradient(ellipse at 34% 50%, rgb(4 7 19 / 0.36), transparent 70%);
  filter: blur(18px);
  pointer-events: none;
}

.scroll-painting .threshold__eyebrow {
  color: rgb(206 165 105 / 0.9);
}

.scroll-painting .threshold__title {
  color: rgb(246 239 225 / 0.97);
  font-size: clamp(1.58rem, 2.65vw, 2.48rem);
  line-height: 1.9;
  text-shadow: 0 16px 58px rgb(0 0 0 / 0.38);
}

.scroll-painting .threshold__route {
  position: relative;
  width: min(500px, 86vw);
  color: rgb(234 225 209 / 0.6);
}

.scroll-painting .threshold__route-line,
.scroll-painting .threshold__route-line i {
  background: linear-gradient(90deg, rgb(134 164 160 / 0.16), rgb(190 151 96 / 0.84), rgb(226 199 153 / 0.18));
}

.scroll-painting .hold-button {
  color: rgb(242 233 218 / 0.92);
  border-color: rgb(225 211 187 / 0.15);
  background: linear-gradient(90deg, rgb(11 23 24 / 0.34), rgb(158 83 63 / 0.075), transparent);
}

.scroll-painting .hold-button:hover,
.scroll-painting .hold-button:focus-visible,
.scroll-painting .hold-button.is-holding {
  color: #fff7e8;
  border-color: rgb(205 166 108 / 0.42);
  background: linear-gradient(90deg, rgb(16 30 31 / 0.58), rgb(155 73 63 / 0.14), transparent);
}

/* --------------------------------------------------------------------------
   Five transparent folds; the canvas changes the actual place behind the text
   -------------------------------------------------------------------------- */

.scroll-painting .chapter {
  position: relative;
  z-index: 2;
  background: transparent !important;
  isolation: isolate;
}

.scroll-painting .chapter::before,
.scroll-painting .chapter::after {
  position: absolute;
  z-index: -1;
  inset: 0;
  content: "";
  pointer-events: none;
}

.scroll-painting .first-frame::before {
  background:
    radial-gradient(ellipse 55% 66% at 25% 47%, rgb(5 9 24 / 0.5) 0%, rgb(5 10 24 / 0.25) 52%, transparent 79%),
    radial-gradient(circle at 82% 31%, rgb(170 69 91 / 0.1), transparent 28%),
    linear-gradient(180deg, rgb(5 8 20 / 0.06), transparent 45%, rgb(5 9 21 / 0.24));
}

.scroll-painting .first-frame::after {
  inset: 8% auto 8% 4.5%;
  width: 1px;
  background: linear-gradient(180deg, transparent, rgb(226 178 112 / 0.4) 31% 66%, transparent);
  opacity: 0.82;
}

.scroll-painting .contact-sheet::before {
  background:
    radial-gradient(ellipse 62% 50% at 50% 18%, rgb(9 9 24 / 0.32), transparent 76%),
    radial-gradient(circle at 82% 37%, rgb(175 67 98 / 0.13), transparent 33%),
    linear-gradient(90deg, rgb(7 10 24 / 0.23), transparent 24% 76%, rgb(16 9 23 / 0.21)),
    linear-gradient(180deg, transparent 40%, rgb(9 9 21 / 0.34));
}

.scroll-painting .contact-sheet::after {
  opacity: 0.48;
  background:
    radial-gradient(ellipse 28% 19% at 79% 21%, rgb(245 189 169 / 0.08), transparent 72%),
    linear-gradient(90deg, transparent 0 68%, rgb(245 222 190 / 0.04) 68% 68.08%, transparent 68.08%),
    linear-gradient(180deg, transparent 0 15%, rgb(245 222 190 / 0.035) 15% 15.08%, transparent 15.08%);
}

.scroll-painting .ordinary-days::before {
  background:
    radial-gradient(ellipse 52% 62% at 24% 48%, rgb(20 12 23 / 0.48) 0%, rgb(25 14 27 / 0.24) 58%, transparent 84%),
    radial-gradient(ellipse at 77% 36%, rgb(179 71 91 / 0.2), transparent 34%),
    linear-gradient(180deg, rgb(24 14 24 / 0.08), transparent 43%, rgb(17 12 20 / 0.23));
}

.scroll-painting .ordinary-days::after {
  inset: 0 0 auto auto;
  width: min(43vw, 660px);
  height: 72%;
  border-left: 1px solid rgb(245 222 194 / 0.045);
  border-bottom: 1px solid rgb(245 222 194 / 0.035);
  background:
    radial-gradient(ellipse 18% 13% at 73% 24%, rgb(255 225 203 / 0.1), transparent 74%),
    radial-gradient(ellipse 13% 18% at 82% 31%, rgb(190 76 99 / 0.09), transparent 75%),
    linear-gradient(115deg, transparent, rgb(243 209 178 / 0.035));
}

.scroll-painting .letter::before {
  background:
    radial-gradient(ellipse at 50% 43%, rgb(255 241 211 / 0.07) 0 34%, transparent 63%),
    radial-gradient(circle at 76% 25%, rgb(207 142 119 / 0.1), transparent 28%),
    linear-gradient(180deg, rgb(73 54 58 / 0.08), transparent 48%, rgb(52 44 47 / 0.16));
}

.scroll-painting .letter::after {
  inset: 7% 7% auto;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(170 75 80 / 0.3), rgb(224 175 105 / 0.24), transparent);
}

.scroll-painting .daybreak::before {
  background:
    radial-gradient(ellipse 45% 48% at 25% 40%, rgb(244 235 216 / 0.14), transparent 72%),
    radial-gradient(ellipse 38% 46% at 79% 34%, rgb(225 128 128 / 0.13), transparent 76%),
    linear-gradient(180deg, rgb(239 237 224 / 0.03), transparent 36%, rgb(247 214 177 / 0.13));
}

.scroll-painting .daybreak::after {
  top: 56%;
  bottom: auto;
  height: 1px;
  background: linear-gradient(90deg, transparent 4%, rgb(91 120 117 / 0.16), rgb(209 143 88 / 0.4), transparent 96%);
  transform: scaleX(calc(0.35 + var(--daybreak-progress, 0) * 0.65));
  transform-origin: center;
}

/* Keep the prose above movement and give it contrast without turning it into cards. */
.scroll-painting .chapter-shell {
  position: relative;
  z-index: 4;
}

.scroll-painting .first-frame__copy,
.scroll-painting .first-frame__body,
.scroll-painting .section-heading,
.scroll-painting .ordinary-days__heading,
.scroll-painting .ordinary-days__text {
  filter: drop-shadow(0 15px 30px rgb(0 0 0 / 0.14));
}

.scroll-painting .first-frame__lead,
.scroll-painting .first-frame__body,
.scroll-painting .section-heading > p,
.scroll-painting .ordinary-line {
  color: rgb(239 231 216 / 0.78);
}

.scroll-painting .display-title,
.scroll-painting .section-heading h2,
.scroll-painting .ordinary-days__heading h2 {
  color: rgb(248 241 227 / 0.95);
  text-shadow: 0 18px 52px rgb(0 0 0 / 0.22);
}

/* Photographs remain the only saturated things in the second fold. */
.scroll-painting .memory__image,
.scroll-painting .puzzle-story__frames img,
.scroll-painting .photo-after__figure img,
.scroll-painting .film-frame img {
  filter: saturate(0.78) contrast(0.97) brightness(0.9);
  transition: filter 900ms cubic-bezier(.2,.72,.22,1), transform 900ms cubic-bezier(.2,.72,.22,1);
}

.scroll-painting .memory:hover .memory__image,
.scroll-painting .memory:focus-within .memory__image,
.scroll-painting .puzzle-story__visual:hover img,
.scroll-painting .photo-after__figure:hover img,
.scroll-painting .film-frame:hover img {
  filter: saturate(1) contrast(1) brightness(1);
}

.scroll-painting .film-frame,
.scroll-painting .memory__visual,
.scroll-painting .puzzle-story__visual,
.scroll-painting .photo-after__figure {
  border-color: rgb(226 210 182 / 0.18);
  background: rgb(11 19 21 / 0.24);
  box-shadow: 0 36px 110px rgb(1 7 9 / 0.38), 0 0 0 1px rgb(248 237 218 / 0.025);
}

/* Dialogue is reflected in a rain-dark window, not displayed as product cards. */
.scroll-painting .chat-fragments {
  border-color: rgb(225 206 178 / 0.1);
  background: linear-gradient(135deg, rgb(8 17 20 / 0.34), rgb(116 72 61 / 0.06));
  box-shadow: inset 0 1px rgb(255 255 255 / 0.025), 0 30px 100px rgb(0 0 0 / 0.18);
  backdrop-filter: blur(5px);
}

.scroll-painting .chat-fragment {
  background: transparent;
}

.scroll-painting .chat-fragment__inner {
  border-color: rgb(225 211 185 / 0.09);
  background: linear-gradient(100deg, rgb(226 212 187 / 0.035), transparent);
}

.scroll-painting .ordinary-lines li {
  max-width: 26em;
  font-size: clamp(1.38rem, 1.8vw, 2rem);
  line-height: 1.82;
  opacity: 0.56;
  transition: opacity 520ms ease, color 520ms ease, transform 520ms ease;
}

.scroll-painting .ordinary-lines {
  gap: clamp(48px, 7vh, 76px);
}

.scroll-painting .ordinary-lines li:not(.is-current):not(.is-visible):not(:hover):not(:focus-within) {
  color: rgb(232 221 202 / 0.68);
  opacity: 0.82;
}

.scroll-painting .ordinary-lines li.is-current,
.scroll-painting .ordinary-lines li.is-visible,
.scroll-painting .ordinary-lines li:hover,
.scroll-painting .ordinary-lines li:focus-within {
  color: rgb(248 238 220 / 0.94);
  opacity: 1;
}

/* The letter is a sheet of warm silk, not a modal floating over darkness. */
.scroll-painting .letter-sheet,
.scroll-painting .letter-body {
  border-color: rgb(92 66 51 / 0.16);
  background:
    linear-gradient(96deg, rgb(255 250 237 / 0.9), rgb(238 225 201 / 0.94) 52%, rgb(244 233 211 / 0.9)),
    repeating-linear-gradient(0deg, transparent 0 5px, rgb(75 65 53 / 0.012) 6px);
  box-shadow: 0 46px 120px rgb(15 20 18 / 0.3), inset 0 0 72px rgb(117 84 54 / 0.045);
}

.scroll-painting .letter-sheet::before,
.scroll-painting .letter-body::before {
  opacity: 0.16;
  mix-blend-mode: multiply;
}

.scroll-painting .letter-body,
.scroll-painting .letter-body p,
.scroll-painting .letter-sheet h2 {
  color: rgb(49 45 39 / 0.9);
}

/* --------------------------------------------------------------------------
   Chrome becomes a quiet scroll edge and gets out of the way while reading
   -------------------------------------------------------------------------- */

.scroll-painting .site-chrome {
  min-height: 58px;
  padding-block: 8px;
  background: linear-gradient(180deg, rgb(4 11 12 / 0.54), rgb(4 11 12 / 0.08), transparent);
  backdrop-filter: none;
  transition: opacity 460ms ease, transform 560ms cubic-bezier(.2,.72,.22,1), color 700ms ease;
}

.scroll-painting .site-chrome.is-chrome-hidden {
  opacity: 0;
  transform: translate3d(0, -76%, 0);
  pointer-events: none;
}

.scroll-painting[data-tone="day"] .site-chrome {
  background: linear-gradient(180deg, rgb(238 229 211 / 0.64), rgb(238 229 211 / 0.1), transparent);
}

.scroll-painting .archive-mark__title {
  border-color: rgb(155 73 63 / 0.62);
  background: rgb(105 39 35 / 0.14);
}

.scroll-painting .site-chrome__tools button,
.scroll-painting .memory-map-toggle {
  background: rgb(11 20 21 / 0.12);
  backdrop-filter: blur(7px);
}

.scroll-painting .chapter-nav {
  padding: 8px 0;
  background: linear-gradient(180deg, transparent, rgb(8 16 17 / 0.1), transparent);
}

.scroll-painting .chapter-nav a:not(.is-active) em {
  opacity: 0;
}

.scroll-painting .chapter-nav a:not(.is-active) span {
  color: transparent;
  border: 1px solid rgb(229 216 194 / 0.2);
  background: transparent;
  transform: scale(0.46) rotate(45deg);
}

.scroll-painting .chapter-nav a.is-active span {
  background: rgb(155 73 63 / 0.78);
  box-shadow: 0 0 0 5px rgb(155 73 63 / 0.06);
}

.scroll-painting .chapter-scroll-seal {
  opacity: 0.76;
  transition: opacity 380ms ease, transform 520ms cubic-bezier(.2,.72,.22,1);
}

.scroll-painting .chapter-scroll-seal:hover,
.scroll-painting .chapter-scroll-seal:focus-visible {
  opacity: 1;
  transform: translate3d(-3px, 1px, 0);
}

.scroll-painting .chapter-scroll-seal b {
  background: rgb(101 36 32 / 0.08);
}

.scroll-painting .chapter-seal-slot .light-seed {
  background: linear-gradient(90deg, rgb(11 19 19 / 0.18), transparent);
  backdrop-filter: blur(4px);
}

.scroll-painting .chapter-seal-slot {
  position: absolute;
  top: clamp(174px, 23vh, 244px);
  right: max(34px, 6vw);
  height: 48px;
  margin: 0;
}

/* The map opens like a sheet laid over the current landscape. */
.scroll-painting .memory-map-panel {
  background:
    linear-gradient(98deg, rgb(238 229 211 / 0.97), rgb(224 211 189 / 0.94)),
    repeating-linear-gradient(0deg, transparent 0 4px, rgb(65 55 45 / 0.015) 5px);
  box-shadow: 0 38px 130px rgb(0 0 0 / 0.4);
}

.scroll-painting .memory-map-panel__nav a:hover,
.scroll-painting .memory-map-panel__nav a:focus-visible {
  background: linear-gradient(90deg, rgb(155 73 63 / 0.07), transparent);
}

/* Subtle finite response while a chapter is being changed. */
.scroll-painting .ink-page-turn {
  display: none;
  background: transparent;
}

.scroll-painting .ink-page-turn__wash {
  background: linear-gradient(100deg, transparent 6%, rgb(32 43 42 / 0.54) 42%, rgb(222 207 181 / 0.16) 56%, transparent 86%);
  filter: blur(18px);
}

/* --------------------------------------------------------------------------
   Mobile is recomposed as one scene + one response, never the desktop squeezed
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  .scroll-painting > .atmosphere {
    filter: saturate(1.08) contrast(1.035) brightness(1.02);
  }

  .scroll-painting .threshold {
    background:
      radial-gradient(ellipse 98% 62% at 45% 49%, rgb(5 8 22 / 0.46), rgb(5 8 22 / 0.2) 61%, transparent 88%),
      radial-gradient(circle at 78% 24%, rgb(169 66 94 / 0.1), transparent 27%),
      linear-gradient(180deg, rgb(4 7 20 / 0.08), transparent 43%, rgb(5 8 20 / 0.32));
  }

  .scroll-painting .threshold__content {
    width: min(100%, 430px);
    padding: max(24px, 5svh) 0 24px;
  }

  .scroll-painting .threshold__content::before {
    inset: -8% -12%;
    background: radial-gradient(ellipse at 45% 52%, rgb(4 7 20 / 0.36), transparent 76%);
  }

  .scroll-painting .threshold__title {
    font-size: clamp(1.26rem, 6.1vw, 1.72rem);
    line-height: 1.86;
  }

  .scroll-painting .chapter::after {
    display: none;
  }

  .scroll-painting .first-frame::before {
    background:
      radial-gradient(ellipse 98% 58% at 46% 44%, rgb(5 9 23 / 0.45), rgb(5 9 23 / 0.18) 64%, transparent 88%),
      linear-gradient(180deg, rgb(5 8 20 / 0.05), transparent 42%, rgb(5 8 20 / 0.28));
  }

  .scroll-painting .contact-sheet::before {
    background:
      radial-gradient(ellipse 96% 48% at 50% 22%, rgb(8 9 23 / 0.3), transparent 78%),
      radial-gradient(circle at 80% 34%, rgb(173 67 98 / 0.12), transparent 34%),
      linear-gradient(180deg, transparent 38%, rgb(8 9 21 / 0.35));
  }

  .scroll-painting .ordinary-days::before {
    background:
      radial-gradient(ellipse 104% 58% at 48% 47%, rgb(19 11 23 / 0.45), rgb(22 12 25 / 0.18) 67%, transparent 88%),
      radial-gradient(circle at 82% 28%, rgb(180 69 92 / 0.15), transparent 31%),
      linear-gradient(180deg, rgb(21 12 23 / 0.06), transparent 42%, rgb(16 10 19 / 0.25));
  }

  .scroll-painting .letter::before {
    background:
      radial-gradient(ellipse at 50% 43%, rgb(255 240 211 / 0.08) 0 35%, transparent 72%),
      linear-gradient(180deg, rgb(71 53 57 / 0.08), transparent 47%, rgb(50 42 45 / 0.18));
  }

  .scroll-painting .daybreak::before {
    background:
      radial-gradient(ellipse 80% 42% at 35% 38%, rgb(246 237 219 / 0.13), transparent 75%),
      radial-gradient(circle at 83% 28%, rgb(226 130 132 / 0.13), transparent 30%),
      linear-gradient(180deg, transparent 40%, rgb(248 216 180 / 0.12));
  }

  .scroll-painting .site-chrome {
    min-height: 54px;
    padding-block: 5px;
  }

  .scroll-painting .chapter-scroll-seal {
    top: 86px;
    right: 18px;
  }

  .scroll-painting .chapter-seal-slot {
    top: 156px;
    right: 17px;
    width: 44px;
    height: 44px;
    margin: 0;
  }

  .scroll-painting .ordinary-line {
    opacity: 0.74;
  }

  .scroll-painting .ordinary-lines {
    gap: 48px;
  }

  .scroll-painting .ordinary-lines li {
    max-width: 28em;
    font-size: clamp(1.18rem, 5.15vw, 1.52rem);
    line-height: 1.92;
  }

  .scroll-painting .chat-fragments {
    backdrop-filter: none;
  }
}

@media (max-width: 420px) {
  .scroll-painting .threshold__route {
    width: 100%;
  }

  .scroll-painting .hold-button {
    width: 100%;
    min-width: 0;
  }

  .scroll-painting .letter-sheet {
    box-shadow: 0 28px 70px rgb(10 15 14 / 0.28);
  }
}

@media (max-width: 380px) and (max-height: 600px) {
  .scroll-painting .threshold {
    place-items: start center;
    padding: 9px 14px 6px;
  }

  .scroll-painting .threshold__content {
    width: 100%;
    padding: 0;
  }

  .scroll-painting .threshold__eyebrow {
    margin: 0 0 3px;
    font-size: 0.45rem;
    line-height: 1.2;
  }

  .scroll-painting .threshold__title {
    max-width: 30em;
    margin: 0;
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    line-height: 1.48;
  }

  .scroll-painting .threshold__route {
    display: none;
  }

  .scroll-painting .hold-button {
    min-height: 44px;
    margin-top: 5px;
    padding: 0 10px 0 58px;
  }

  .scroll-painting .hold-button__ring {
    width: 38px;
    height: 38px;
  }

  .scroll-painting .hold-button__center {
    min-height: 44px;
    font-size: 0.68rem;
  }

  .scroll-painting .threshold__hint {
    min-height: 10px;
    margin-top: 1px;
    font-size: 0.46rem;
    line-height: 1.2;
  }

  .scroll-painting .threshold__direct {
    min-height: 44px;
    margin-top: 0;
    padding-block: 0;
    font-size: 0.55rem;
  }
}

/* --------------------------------------------------------------------------
   一脉流光 · one moving atmosphere ties the five folds together
   -------------------------------------------------------------------------- */

.scroll-painting > .scene-flow {
  position: fixed;
  z-index: 0;
  inset: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  contain: strict;
  transition: opacity 1.4s cubic-bezier(.2,.72,.22,1);
}

.scroll-painting.has-entered > .scene-flow {
  opacity: 1;
}

.scroll-painting > .scene-flow > span {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  will-change: transform, opacity;
  transition: opacity 1.35s cubic-bezier(.2,.72,.22,1);
}

.scroll-painting .scene-flow__mist {
  inset: 8% -18% 20% -22%;
  background:
    radial-gradient(ellipse 30% 18% at 18% 68%, rgb(148 188 196 / 0.18), transparent 72%),
    radial-gradient(ellipse 34% 22% at 57% 46%, rgb(189 157 183 / 0.12), transparent 74%),
    radial-gradient(ellipse 27% 17% at 84% 34%, rgb(232 207 168 / 0.09), transparent 75%);
  filter: blur(28px);
}

.scroll-painting[data-chapter="01"] .scene-flow__mist {
  opacity: 0.74;
  transform: translate3d(calc(var(--ambient-x, 0px) * 0.22), calc(var(--ambient-y, 0px) * 0.18), 0) scale(1.03);
}

.scroll-painting .scene-flow__moon-thread {
  top: 14%;
  right: -16%;
  width: min(68vw, 980px);
  aspect-ratio: 2.8;
  border-top: 1px solid rgb(245 222 177 / 0.22);
  border-radius: 50%;
  filter: drop-shadow(0 0 14px rgb(233 197 145 / 0.11));
  transform: translate3d(calc(var(--ambient-x, 0px) * -0.5), calc(var(--ambient-y, 0px) * -0.4), 0) rotate(-8deg);
}

.scroll-painting[data-chapter="01"] .scene-flow__moon-thread {
  opacity: 0.72;
}

.scroll-painting .scene-flow__rain {
  inset: -18% -12%;
  background: repeating-linear-gradient(103deg, transparent 0 22px, rgb(196 221 229 / 0.14) 23px, transparent 24px 54px);
  mask-image: linear-gradient(90deg, transparent, #000 16% 87%, transparent);
  filter: blur(0.25px);
  transform: translate3d(calc(var(--ambient-x, 0px) * -0.32), -7%, 0);
  transition: opacity 980ms cubic-bezier(.22,.61,.36,1);
}

.scroll-painting.is-rain-wiping .scene-flow__rain,
.scroll-painting.is-rain-revealed .scene-flow__rain {
  transition-duration: 240ms;
}

.scroll-painting[data-chapter="02"] .scene-flow__rain {
  opacity: var(--scene-rain-opacity, 0.52);
  animation: living-rain-pass 2.2s linear infinite;
}

.scroll-painting .scene-flow__water {
  right: -16%;
  bottom: 3%;
  left: -16%;
  height: 42%;
  background:
    repeating-radial-gradient(ellipse at 34% 10%, transparent 0 38px, rgb(244 209 176 / 0.07) 39px, transparent 41px 68px),
    linear-gradient(180deg, transparent, rgb(171 120 133 / 0.08));
  filter: blur(0.5px);
  transform: translate3d(calc(var(--ambient-x, 0px) * 0.2), calc(var(--ambient-y, 0px) * 0.15), 0) scale(1.04);
}

.scroll-painting[data-chapter="03"] .scene-flow__water {
  opacity: 0.62;
  animation: living-water-breathe 7.8s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting .scene-flow__paper {
  top: -14%;
  bottom: -14%;
  left: 18%;
  width: 42%;
  background: linear-gradient(102deg, transparent 8%, rgb(255 242 212 / 0.03) 34%, rgb(255 228 183 / 0.2) 50%, rgb(255 244 217 / 0.035) 67%, transparent 88%);
  filter: blur(13px);
  transform: translate3d(calc(var(--ambient-x, 0px) * 0.28), calc(var(--ambient-y, 0px) * 0.2), 0) rotate(6deg);
}

.scroll-painting[data-chapter="04"] .scene-flow__paper {
  opacity: 0.76;
  animation: living-paper-light 9.5s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting .scene-flow__dawn {
  inset: -8%;
  background:
    radial-gradient(circle at 73% 30%, rgb(255 233 190 / 0.22), transparent 13%),
    linear-gradient(105deg, transparent 37%, rgb(255 238 203 / 0.1) 52%, transparent 68%);
  filter: blur(8px);
}

.scroll-painting[data-chapter="05"] .scene-flow__dawn {
  opacity: 0.84;
  animation: living-dawn-breathe 8.2s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting.moon-secret-is-open > .scene-flow > span,
.scroll-painting.archive-is-open > .scene-flow > span {
  animation-play-state: paused !important;
}

.scroll-painting > .scene-flow::after {
  position: absolute;
  top: var(--scene-touch-y, 50vh);
  left: var(--scene-touch-x, 50vw);
  width: clamp(180px, 30vw, 460px);
  aspect-ratio: 1.7;
  border-radius: 50%;
  content: "";
  opacity: 0;
  pointer-events: none;
  background: radial-gradient(ellipse, rgb(250 224 181 / 0.18), rgb(191 119 125 / 0.055) 45%, transparent 72%);
  transform: translate(-50%, -50%) scale(0.28);
}

.scroll-painting.is-scene-touched > .scene-flow::after {
  animation: living-touch-light 1.45s cubic-bezier(.16,1,.3,1) both;
}

@keyframes living-mist-breathe {
  from { transform: translate3d(-2%, 1%, 0) scale(0.98); }
  to { transform: translate3d(3%, -2%, 0) scale(1.06); }
}

@keyframes living-moon-thread {
  from { filter: drop-shadow(0 0 10px rgb(233 197 145 / 0.08)); transform: translate3d(-2%, 0, 0) rotate(-8deg) scaleX(0.94); }
  to { filter: drop-shadow(0 0 20px rgb(233 197 145 / 0.18)); transform: translate3d(2%, 2%, 0) rotate(-6deg) scaleX(1.03); }
}

@keyframes living-rain-pass {
  from { background-position: 0 -80px; transform: translate3d(-1.2%, -5%, 0); }
  to { background-position: 48px 150px; transform: translate3d(1.2%, 5%, 0); }
}

@keyframes living-water-breathe {
  from { transform: translate3d(-1.5%, 2%, 0) scale(1.02, 0.98); }
  to { transform: translate3d(1.6%, -1%, 0) scale(1.06, 1.02); }
}

@keyframes living-paper-light {
  from { transform: translate3d(-16%, 3%, 0) rotate(6deg); opacity: 0.28; }
  to { transform: translate3d(22%, -2%, 0) rotate(4deg); opacity: 0.82; }
}

@keyframes living-dawn-breathe {
  from { opacity: 0.54; transform: scale(0.98) translate3d(-1%, 1%, 0); }
  to { opacity: 0.92; transform: scale(1.04) translate3d(1%, -1%, 0); }
}

@keyframes living-touch-light {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.28); }
  30% { opacity: 0.86; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.36); }
}

/* A quiet ink/paper wipe bridges the camera crossfade instead of cutting scenes. */
.scroll-painting .scroll-transition {
  position: fixed;
  z-index: 61;
  inset: 0;
  overflow: hidden;
  opacity: 0;
  pointer-events: none;
  mix-blend-mode: soft-light;
}

.scroll-painting .scroll-transition i,
.scroll-painting .scroll-transition b {
  position: absolute;
  content: "";
  opacity: 0;
}

.scroll-painting .scroll-transition i:first-child {
  inset: -20% -36%;
  background: linear-gradient(102deg, transparent 22%, rgb(235 213 182 / 0.16) 42%, rgb(151 88 94 / 0.11) 52%, transparent 72%);
  filter: blur(20px);
}

.scroll-painting .scroll-transition i:nth-child(2) {
  top: 8%;
  bottom: 8%;
  left: 50%;
  width: 1px;
  background: linear-gradient(180deg, transparent, rgb(242 214 170 / 0.62), transparent);
}

.scroll-painting .scroll-transition b {
  top: 50%;
  left: 50%;
  width: min(74vw, 980px);
  height: 1px;
  background: linear-gradient(90deg, transparent, rgb(238 206 162 / 0.26), transparent);
}

.scroll-painting.is-chapter-transitioning .scroll-transition {
  opacity: 1;
}

.scroll-painting.is-chapter-transitioning .scroll-transition i:first-child {
  animation: living-scroll-wash 1.8s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting.is-chapter-transitioning .scroll-transition i:nth-child(2) {
  animation: living-scroll-seam 1.65s 80ms cubic-bezier(.16,1,.3,1) both;
}

.scroll-painting.is-chapter-transitioning .scroll-transition b {
  animation: living-scroll-horizon 1.7s 120ms cubic-bezier(.16,1,.3,1) both;
}

.scroll-painting[data-transition-to="04"].is-chapter-transitioning .scroll-transition i:first-child {
  background: linear-gradient(102deg, transparent 20%, rgb(255 239 207 / 0.2) 43%, rgb(169 84 79 / 0.09) 55%, transparent 74%);
}

.scroll-painting[data-transition-to="05"].is-chapter-transitioning .scroll-transition i:first-child {
  background: linear-gradient(100deg, transparent 18%, rgb(255 241 211 / 0.23) 45%, rgb(227 168 116 / 0.12) 58%, transparent 78%);
}

@keyframes living-scroll-wash {
  0% { opacity: 0; transform: translate3d(-42%, 0, 0) skewX(-6deg); }
  36%, 54% { opacity: 0.82; }
  100% { opacity: 0; transform: translate3d(42%, 2%, 0) skewX(-2deg); }
}

@keyframes living-scroll-seam {
  0% { opacity: 0; transform: translate3d(0, -78%, 0) scaleY(0.3); }
  34% { opacity: 0.7; }
  100% { opacity: 0; transform: translate3d(0, 78%, 0) scaleY(1); }
}

@keyframes living-scroll-horizon {
  0% { opacity: 0; transform: translate(-50%, -50%) scaleX(0.08); }
  42% { opacity: 0.58; }
  100% { opacity: 0; transform: translate(-50%, -50%) scaleX(1.16); }
}

/* The original interaction system was present but accidentally hidden. */
.scroll-painting .interaction-bloom {
  z-index: 67;
  display: block !important;
  mix-blend-mode: screen;
}

.scroll-painting[data-tone="day"] .interaction-bloom {
  mix-blend-mode: multiply;
}

.scroll-painting .interaction-bloom::before,
.scroll-painting .interaction-bloom::after {
  width: clamp(190px, 29vw, 430px);
  aspect-ratio: 1.82;
  border-radius: 50%;
  border-style: solid;
  box-shadow: 0 0 70px rgb(var(--bloom-rgb) / 0.13), inset 0 0 48px rgb(var(--bloom-rgb) / 0.04);
}

.scroll-painting .interaction-bloom::after {
  width: clamp(280px, 46vw, 690px);
  border-style: dashed;
}

.scroll-painting .interaction-bloom[data-kind="rain-window"]::before,
.scroll-painting .interaction-bloom[data-kind="tone-blue"]::before,
.scroll-painting .interaction-bloom[data-kind="tone-blue"]::after {
  aspect-ratio: 3.2;
  border-color: rgb(159 211 218 / 0.44);
  border-radius: 48%;
}

.scroll-painting .interaction-bloom[data-kind="tide-meeting"]::before,
.scroll-painting .interaction-bloom[data-kind="tone-warm"]::before,
.scroll-painting .interaction-bloom[data-kind="tone-warm"]::after {
  aspect-ratio: 2.7;
  border-color: rgb(243 180 155 / 0.46);
}

.scroll-painting .interaction-bloom[data-kind="peace-seal"]::before,
.scroll-painting .interaction-bloom[data-kind="archive-open"]::before,
.scroll-painting .interaction-bloom[data-kind="tone-ink"]::before {
  width: clamp(88px, 12vw, 156px);
  aspect-ratio: 1;
  border: 2px double rgb(154 66 61 / 0.68);
  border-radius: 5px;
  box-shadow: 0 0 60px rgb(163 72 63 / 0.16), inset 0 0 22px rgb(163 72 63 / 0.08);
}

.scroll-painting .interaction-bloom[data-kind="tone-day"]::before,
.scroll-painting .interaction-bloom[data-kind="tone-day"]::after {
  aspect-ratio: 3.5;
  border-color: rgb(179 112 83 / 0.38);
}

/* First fold: one composed frame instead of a long succession of empty pauses. */
@media (min-width: 901px) {
  .scroll-painting .first-frame {
    min-height: 112svh;
  }

  .scroll-painting .first-frame__layout {
    min-height: 112svh;
    grid-template-rows: auto auto;
    padding-top: clamp(96px, 11.5svh, 132px);
    padding-bottom: 120px;
  }

  .scroll-painting .first-frame__copy {
    grid-row: 1;
    align-self: start;
    padding-top: 0;
  }

  .scroll-painting .display-title {
    max-width: 9em;
    font-size: clamp(3.6rem, 5.9vw, 6.7rem);
  }

  .scroll-painting .film-frame {
    grid-row: 1 / 3;
    align-self: center;
  }

  .scroll-painting .film-frame .scene {
    aspect-ratio: 1.08;
  }

  .scroll-painting .first-frame__body {
    grid-column: 1 / 6;
    grid-row: 2;
    align-self: end;
    margin-top: clamp(20px, 2.6svh, 30px);
    font-size: clamp(1rem, 1.28vw, 1.24rem);
    line-height: 1.9;
  }
}

@media (max-width: 599px) {
  .scroll-painting .first-frame__layout {
    padding-top: max(90px, 11svh);
    padding-bottom: 110px;
  }

  .scroll-painting .film-frame {
    margin-top: 34px;
  }

  .scroll-painting .film-frame .scene {
    aspect-ratio: 1.08;
  }

  .scroll-painting .first-frame__body {
    width: 94%;
    margin-top: 38px;
    margin-left: 3%;
  }
}

@media (min-width: 600px) and (max-width: 900px) {
  .scroll-painting .first-frame__layout {
    padding-top: 132px;
    padding-bottom: 110px;
  }

  .scroll-painting .film-frame {
    margin-top: 40px;
  }

  .scroll-painting .film-frame .scene {
    aspect-ratio: 1.12;
  }

  .scroll-painting .first-frame__body {
    margin-top: 52px;
  }
}

@media (max-height: 520px) and (orientation: landscape) {
  .scroll-painting .first-frame {
    min-height: 100svh;
  }

  .scroll-painting .first-frame__layout {
    display: grid;
    min-height: 100svh;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: auto auto;
    gap: 0 18px;
    padding-top: 66px;
    padding-bottom: 96px;
  }

  .scroll-painting .first-frame__copy {
    grid-column: 1 / 7;
    grid-row: 1;
    padding-top: 0;
  }

  .scroll-painting .display-title {
    max-width: 8em;
    margin-top: 12px;
    font-size: clamp(2.15rem, 5.4vw, 3rem);
    line-height: 1.01;
  }

  .scroll-painting .first-frame__lead {
    margin-top: 12px;
    font-size: 0.78rem;
    line-height: 1.72;
  }

  .scroll-painting .film-frame {
    grid-column: 7 / 13;
    grid-row: 1 / 3;
    width: 100%;
    margin-top: 0;
  }

  .scroll-painting .film-frame .scene {
    aspect-ratio: 1.15;
  }

  .scroll-painting .first-frame__body {
    grid-column: 1 / 7;
    grid-row: 2;
    width: auto;
    margin: 20px 0 0;
    font-size: 0.82rem;
    line-height: 1.72;
  }

  .scroll-painting .reading-mark {
    margin-top: 14px;
  }
}

.scroll-painting .first-frame > .chapter-bridge {
  position: absolute;
  right: max(20px, 6vw);
  bottom: max(18px, env(safe-area-inset-bottom));
  width: min(360px, calc(100% - 40px));
  margin: 0;
}

/* The opening portrait now reads as a living background, then truly rests. */
.scroll-painting.has-entered[data-chapter="01"] .portrait-world {
  opacity: 0.56;
}

.scroll-painting .portrait-world__breath {
  animation: none;
}

.scroll-painting[data-chapter="02"] .portrait-world *,
.scroll-painting[data-chapter="03"] .portrait-world *,
.scroll-painting[data-chapter="04"] .portrait-world *,
.scroll-painting[data-chapter="05"] .portrait-world * {
  animation-play-state: paused !important;
  will-change: auto;
}

@keyframes portrait-breath-light {
  from { opacity: 0.18; transform: scale(0.88); }
  to { opacity: 0.38; transform: scale(1.12); }
}

/* Private archive: a clear sealed letter, still quiet enough for the ending. */
.scroll-painting .archive-door {
  position: relative;
  width: min(900px, calc(100% - 40px));
  max-width: 900px;
  margin-top: clamp(170px, 23vh, 270px);
  padding: clamp(52px, 6vw, 76px) clamp(22px, 4vw, 52px);
  border: 1px solid rgb(75 55 47 / 0.22);
  background:
    linear-gradient(100deg, rgb(255 250 237 / 0.3), rgb(181 104 87 / 0.045) 52%, rgb(255 250 237 / 0.18)),
    radial-gradient(ellipse at 24% 48%, rgb(255 248 229 / 0.42), transparent 72%);
  box-shadow: 0 30px 90px rgb(75 55 47 / 0.09), inset 0 1px rgb(255 255 255 / 0.28);
  backdrop-filter: blur(3px);
}

.scroll-painting .archive-door::before {
  top: -1px;
  left: 0;
  width: 34%;
  height: 3px;
  background: linear-gradient(90deg, rgb(145 65 57 / 0.88), rgb(190 127 85 / 0.48), transparent);
  transform: scaleX(0.28);
  transform-origin: left;
  transition: transform 1.1s cubic-bezier(.16,1,.3,1);
}

.scroll-painting .archive-door.is-visible::before,
.scroll-painting .archive-door.is-inviting::before {
  transform: scaleX(1);
}

.scroll-painting .archive-door__copy {
  max-width: 37em;
}

.scroll-painting .archive-door__copy .eyebrow {
  color: rgb(135 55 50 / 0.88);
}

.scroll-painting .archive-door__copy h2 {
  color: rgb(42 36 33 / 0.94);
}

.scroll-painting .archive-door__copy > p:last-child {
  color: rgb(48 41 37 / 0.76);
}

.scroll-painting .archive-door__action {
  width: 100%;
  margin-top: 44px;
}

.scroll-painting .archive-door__button {
  position: relative;
  width: 100%;
  min-height: 94px;
  grid-template-columns: minmax(0, 1fr) 58px;
  gap: 18px;
  padding: 12px 13px 12px 25px;
  border: 1px solid rgb(75 49 42 / 0.36);
  color: rgb(46 37 33 / 0.96);
  background: linear-gradient(94deg, rgb(255 251 239 / 0.58), rgb(172 82 70 / 0.08) 72%, rgb(151 63 58 / 0.12));
  box-shadow: 0 16px 42px rgb(91 58 45 / 0.08), inset 0 1px rgb(255 255 255 / 0.42);
  transition: border-color 420ms ease, background 520ms ease, box-shadow 520ms ease, transform 260ms ease;
}

.scroll-painting .archive-door__button > span {
  display: flex;
  min-width: 0;
  flex-direction: column;
  gap: 7px;
  align-items: flex-start;
}

.scroll-painting .archive-door__button strong {
  color: inherit;
  font-family: var(--serif);
  font-size: clamp(1.08rem, 1.35vw, 1.22rem);
  font-weight: 400;
  letter-spacing: 0.08em;
}

.scroll-painting .archive-door__button small {
  color: rgb(73 58 50 / 0.68);
  font-size: 0.68rem;
  letter-spacing: 0.07em;
}

.scroll-painting .archive-door__button i {
  display: grid;
  width: 48px;
  height: 48px;
  place-items: center;
  border: 1px solid rgb(139 55 50 / 0.74);
  border-radius: 3px;
  color: rgb(255 239 217 / 0.96);
  background: rgb(143 57 52 / 0.86);
  box-shadow: inset 0 0 0 3px rgb(255 236 211 / 0.08), 0 7px 18px rgb(111 47 43 / 0.15);
  transform: rotate(-1.5deg);
  transition: transform 420ms cubic-bezier(.16,1,.3,1), background 420ms ease, box-shadow 420ms ease;
}

.scroll-painting .archive-door__button i::before,
.scroll-painting .archive-door__button i::after {
  display: none;
}

.scroll-painting .archive-door__button i b {
  color: inherit;
  font-family: var(--serif);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1;
}

.scroll-painting .archive-door__button:hover,
.scroll-painting .archive-door__button:focus-visible {
  border-color: rgb(132 61 52 / 0.68);
  background: linear-gradient(94deg, rgb(255 252 242 / 0.76), rgb(182 92 75 / 0.12) 70%, rgb(151 63 58 / 0.18));
  box-shadow: 0 20px 55px rgb(91 58 45 / 0.13), inset 0 1px rgb(255 255 255 / 0.52);
}

.scroll-painting .archive-door__button:focus-visible {
  outline: 2px solid rgb(126 54 49 / 0.76);
  outline-offset: 5px;
}

.scroll-painting .archive-door__button:hover i,
.scroll-painting .archive-door__button:focus-visible i {
  background: rgb(157 62 55 / 0.96);
  box-shadow: inset 0 0 0 3px rgb(255 236 211 / 0.1), 0 10px 24px rgb(111 47 43 / 0.22);
  transform: translateX(2px) rotate(0deg) scale(1.03);
}

.scroll-painting .archive-door__button:active {
  transform: translateY(1px);
}

.scroll-painting .archive-door.is-inviting .archive-door__button i {
  animation: archive-seal-invite 1.25s cubic-bezier(.16,1,.3,1) both;
}

.scroll-painting .archive-door__action p {
  color: rgb(57 45 40 / 0.66);
  font-size: 0.68rem;
}

@keyframes archive-seal-invite {
  0% { opacity: 0; transform: translateX(14px) rotate(-7deg) scale(1.26); }
  42% { opacity: 1; transform: translateX(0) rotate(1deg) scale(0.94); }
  100% { opacity: 1; transform: rotate(-1.5deg) scale(1); }
}

.scroll-painting.archive-door-visible .scene-ritual-hint,
.scroll-painting.archive-door-visible .light-seed,
.scroll-painting.archive-door-visible .light-note,
.scroll-painting.archive-door-visible .moon-gate,
.scroll-painting:has(.archive-door.is-visible) .scene-ritual-hint,
.scroll-painting:has(.archive-door.is-visible) .light-seed,
.scroll-painting:has(.archive-door.is-visible) .light-note,
.scroll-painting:has(.archive-door.is-visible) .moon-gate {
  opacity: 0 !important;
  pointer-events: none !important;
}

@media (max-width: 700px) {
  .scroll-painting .archive-door {
    width: calc(100% - 24px);
    margin-top: 150px;
    padding: 42px 18px 38px;
  }

  .scroll-painting .archive-door__action {
    margin-top: 36px;
  }

  .scroll-painting .archive-door__button {
    min-height: 86px;
    grid-template-columns: minmax(0, 1fr) 48px;
    gap: 12px;
    padding: 10px 9px 10px 17px;
  }

  .scroll-painting .archive-door__button strong {
    font-size: 1.02rem;
  }

  .scroll-painting .archive-door__button small {
    font-size: 0.62rem;
  }

  .scroll-painting .archive-door__button i {
    width: 44px;
    height: 44px;
  }

  .scroll-painting[data-chapter="02"] .scene-flow__rain {
    opacity: var(--scene-rain-opacity, 0.34);
  }
}

/* A full photograph is available without forcing the mobile scroll to carry it. */
.scroll-painting .photo-full-trigger {
  display: inline-flex;
  min-width: 104px;
  min-height: 44px;
  align-items: center;
  justify-content: center;
  gap: 10px;
  margin-top: 24px;
  padding: 0 17px;
  border: 1px solid rgb(226 210 182 / 0.24);
  border-radius: 999px;
  background: rgb(10 23 29 / 0.22);
  color: rgb(238 229 212 / 0.8);
  font-family: var(--serif);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  backdrop-filter: blur(8px);
  transition: border-color 320ms ease, background 320ms ease, color 320ms ease, transform 420ms cubic-bezier(.16,1,.3,1);
}

.scroll-painting .photo-full-trigger::before {
  width: 16px;
  height: 12px;
  border: 1px solid currentColor;
  content: "";
  opacity: 0.72;
}

.scroll-painting .photo-full-trigger:hover,
.scroll-painting .photo-full-trigger:focus-visible {
  border-color: rgb(239 215 177 / 0.58);
  background: rgb(229 204 169 / 0.09);
  color: rgb(255 244 223 / 0.96);
  transform: translateY(-2px);
}

.scroll-painting .photo-full-trigger:focus-visible {
  outline: 2px solid rgb(244 215 172 / 0.76);
  outline-offset: 4px;
}

body.photo-viewer-is-open {
  overflow: hidden;
}

.scroll-painting .photo-viewer {
  width: 100vw;
  max-width: none;
  height: 100dvh;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: rgb(242 233 216 / 0.9);
  overflow: hidden;
}

.scroll-painting .photo-viewer::backdrop {
  background: rgb(3 8 13 / 0.88);
  backdrop-filter: blur(18px) saturate(0.72);
}

.scroll-painting .photo-viewer[open] {
  display: grid;
  place-items: center;
}

.scroll-painting .photo-viewer__stage {
  position: relative;
  display: grid;
  width: min(94vw, 1120px);
  height: min(92dvh, 860px);
  place-items: center;
  padding: clamp(22px, 4vw, 52px);
}

.scroll-painting .photo-viewer__stage::before {
  position: absolute;
  inset: 2%;
  border: 1px solid rgb(231 214 185 / 0.14);
  content: "";
  pointer-events: none;
  box-shadow: inset 0 0 80px rgb(214 177 132 / 0.045), 0 42px 120px rgb(0 0 0 / 0.42);
}

.scroll-painting .photo-viewer figure {
  display: grid;
  max-width: 100%;
  max-height: 100%;
  justify-items: center;
  gap: 14px;
  margin: 0;
}

.scroll-painting .photo-viewer img {
  display: block;
  max-width: min(88vw, 1040px);
  max-height: min(78dvh, 740px);
  object-fit: contain;
  box-shadow: 0 30px 100px rgb(0 0 0 / 0.48);
}

.scroll-painting .photo-viewer figcaption {
  color: rgb(235 223 204 / 0.66);
  font-family: var(--serif);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  line-height: 1.7;
  text-align: center;
}

.scroll-painting .photo-viewer__close {
  position: absolute;
  z-index: 3;
  top: max(18px, env(safe-area-inset-top));
  right: max(18px, env(safe-area-inset-right));
  width: 48px;
  height: 48px;
  border: 1px solid rgb(234 217 190 / 0.24);
  border-radius: 50%;
  background: rgb(4 12 17 / 0.42);
  color: rgb(246 232 208 / 0.86);
  backdrop-filter: blur(10px);
}

.scroll-painting .photo-viewer__close span::before,
.scroll-painting .photo-viewer__close span::after {
  position: absolute;
  top: 23px;
  left: 15px;
  width: 18px;
  height: 1px;
  content: "";
  background: currentColor;
}

.scroll-painting .photo-viewer__close span::before { transform: rotate(45deg); }
.scroll-painting .photo-viewer__close span::after { transform: rotate(-45deg); }

.scroll-painting .photo-viewer__close:focus-visible {
  outline: 2px solid rgb(244 215 172 / 0.82);
  outline-offset: 4px;
}

.scroll-painting .photo-viewer__hint {
  position: absolute;
  right: 0;
  bottom: max(6px, env(safe-area-inset-bottom));
  left: 0;
  margin: 0;
  color: rgb(232 218 197 / 0.44);
  font-size: 0.62rem;
  letter-spacing: 0.13em;
  text-align: center;
}

@media (max-width: 700px) {
  .scroll-painting .photo-viewer__stage {
    width: 100vw;
    height: 100dvh;
    padding: max(66px, calc(env(safe-area-inset-top) + 56px)) 12px max(58px, calc(env(safe-area-inset-bottom) + 48px));
  }

  .scroll-painting .photo-viewer img {
    max-width: calc(100vw - 24px);
    max-height: calc(100dvh - 156px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting .photo-full-trigger { transition-duration: 0.01ms !important; }
  .scroll-painting .photo-viewer::backdrop { backdrop-filter: none; }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting > .scene-flow > span,
  .scroll-painting .portrait-world__breath,
  .scroll-painting.is-chapter-transitioning .scroll-transition i,
  .scroll-painting.is-chapter-transitioning .scroll-transition b,
  .scroll-painting .archive-door.is-inviting .archive-door__button i {
    animation: none !important;
  }

  .scroll-painting.is-scene-touched > .scene-flow::after {
    animation: none !important;
    opacity: 0.22;
    transform: translate(-50%, -50%) scale(0.78);
  }
}

.scroll-painting.is-data-saver > .scene-flow > span,
.scroll-painting.is-data-saver .portrait-world *,
.scroll-painting.is-data-saver.is-chapter-transitioning .scroll-transition i,
.scroll-painting.is-data-saver.is-chapter-transitioning .scroll-transition b {
  animation: none !important;
  will-change: auto;
}

@media (forced-colors: active) {
  .scroll-painting > .scene-flow,
  .scroll-painting .scroll-transition,
  .scroll-painting .interaction-bloom {
    display: none !important;
  }

  .scroll-painting .archive-door,
  .scroll-painting .archive-door__button {
    border: 1px solid ButtonText;
    color: ButtonText;
    background: ButtonFace;
    forced-color-adjust: auto;
  }
}

/* The mobile artwork is not a desktop crop: the face stays above the prose and
   the ink field becomes the quiet reading surface below it. */
@media (max-width: 700px) {
  .scroll-painting .portrait-world__image {
    object-position: 66% 30%;
    opacity: 0.9;
    filter: saturate(0.92) contrast(1.055) brightness(0.72);
    transform-origin: 70% 26%;
  }

  .scroll-painting .portrait-world::before {
    background:
      linear-gradient(180deg, rgb(3 8 20 / 0.04) 0%, rgb(3 8 20 / 0.18) 38%, rgb(3 8 20 / 0.67) 73%, rgb(3 8 20 / 0.86) 100%),
      radial-gradient(ellipse 94% 58% at 42% 53%, rgb(3 8 20 / 0.43), transparent 78%);
  }

  .scroll-painting .portrait-world::after {
    background:
      radial-gradient(circle at var(--portrait-light-x) var(--portrait-light-y), rgb(255 232 189 / 0.14), transparent 14%),
      radial-gradient(ellipse 84% 44% at 70% 27%, transparent 38%, rgb(5 11 24 / 0.16) 78%, rgb(5 11 24 / 0.28));
  }

  .scroll-painting .portrait-world__ink {
    filter: blur(15px);
  }

  .scroll-painting .portrait-world__breath {
    right: -7%;
    bottom: 34%;
    width: 72vw;
  }

  .scroll-painting .portrait-world__light {
    animation: none;
    opacity: 0.12;
    transform: none;
  }

  .scroll-painting:not(.has-entered) .portrait-world {
    opacity: 0.84;
  }

  .scroll-painting.has-entered[data-chapter="01"] .portrait-world {
    opacity: 0.44;
  }

  .scroll-painting.has-entered[data-chapter="02"] .portrait-world {
    opacity: 0.06;
  }

  .scroll-painting.is-time-holding .portrait-world,
  .scroll-painting.is-time-held .portrait-world {
    opacity: 0.72;
  }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting .portrait-world,
  .scroll-painting .portrait-world__image,
  .scroll-painting .portrait-world__ink,
  .scroll-painting .portrait-world__light,
  .scroll-painting .portrait-world__breath {
    animation: none !important;
    transition-duration: 0.01ms !important;
  }

  .scroll-painting .portrait-world__image {
    transform: scale(1.055);
  }

  .scroll-painting .portrait-world__light {
    opacity: 0.08;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   第二次收束：少一点“展厅控件”，让私人细节和最后一程成为主角
   -------------------------------------------------------------------------- */

.scroll-painting .cinema-frame {
  display: none;
}

.scroll-painting .chapter-nav {
  opacity: 0.2;
  transition: opacity 420ms ease;
}

.scroll-painting .chapter-nav:hover,
.scroll-painting .chapter-nav:focus-within {
  opacity: 0.96;
}

.scroll-painting .chapter-scroll-seal {
  opacity: 0.28;
}

.scroll-painting .chapter-seal-slot {
  opacity: 0.46;
  transition: opacity 420ms ease;
}

.scroll-painting .chapter-seal-slot:focus-within,
.scroll-painting .chapter-seal-slot:hover {
  opacity: 1;
}

.scroll-painting.is-time-holding .first-frame__copy,
.scroll-painting.is-time-held .first-frame__copy {
  clip-path: none !important;
  transform: none !important;
}

.scroll-painting.is-time-holding .site-chrome,
.scroll-painting.is-time-held .site-chrome,
.scroll-painting.is-time-holding .chapter-scroll-seal,
.scroll-painting.is-time-held .chapter-scroll-seal,
.scroll-painting.is-time-holding .chapter-seal-slot,
.scroll-painting.is-time-held .chapter-seal-slot {
  opacity: 0 !important;
  transition: opacity 420ms ease;
}

.scroll-painting .contact-sheet::before {
  background:
    radial-gradient(ellipse 62% 50% at 50% 18%, rgb(9 9 24 / 0.3), transparent 76%),
    radial-gradient(circle at 82% 37%, rgb(175 67 98 / 0.14), transparent 33%),
    linear-gradient(90deg, rgb(7 10 24 / 0.21), transparent 25% 75%, rgb(16 9 23 / 0.2)),
    linear-gradient(180deg, transparent 40%, rgb(9 9 21 / 0.32));
}

.scroll-painting .ordinary-days::before {
  background:
    radial-gradient(ellipse 52% 62% at 24% 48%, rgb(20 12 23 / 0.46) 0%, rgb(25 14 27 / 0.23) 58%, transparent 84%),
    radial-gradient(ellipse at 77% 36%, rgb(179 71 91 / 0.21), transparent 34%),
    linear-gradient(180deg, rgb(24 14 24 / 0.07), transparent 43%, rgb(17 12 20 / 0.22));
}

.scroll-painting .memory__date,
.scroll-painting .chat-slip__date {
  color: rgb(218 177 116 / 0.88);
  font-family: var(--serif);
  font-size: clamp(1.05rem, 1.75vw, 1.62rem);
  letter-spacing: 0.08em;
  line-height: 1.25;
}

.scroll-painting .memory__index,
.scroll-painting .chat-slip__number {
  opacity: 0.46;
}

.scroll-painting .closing-gesture.is-ready:not(.is-closed) .closing-button {
  border-color: rgb(149 90 71 / 0.26);
  background: linear-gradient(90deg, transparent, rgb(246 229 196 / 0.24) 28% 72%, transparent);
  box-shadow: none;
}

.scroll-painting .closing-gesture.is-ready:not(.is-closed) .closing-button strong {
  color: rgb(70 54 48 / 0.68);
}

.scroll-painting .closing-button {
  padding-inline: 0;
  border-right: 0;
  border-left: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
}

.scroll-painting .ordinary-lines {
  gap: 0;
}

.scroll-painting .ordinary-lines li {
  display: grid;
  min-height: 66svh;
  align-content: center;
  opacity: 0.08;
  filter: blur(1.1px);
  transition: opacity 620ms ease, filter 700ms ease, transform 920ms cubic-bezier(.16,1,.3,1);
}

.scroll-painting .ordinary-lines li.is-visible:not(.is-current),
.scroll-painting .ordinary-lines li.is-past {
  opacity: 0.045;
  filter: none;
}

.scroll-painting .ordinary-lines li.is-current {
  opacity: 1;
  filter: none;
  transform: translate3d(0, -1.5svh, 0);
}

.scroll-painting .city-pair {
  width: calc(100vw - 48px);
  height: clamp(340px, 31vw, 460px);
  margin: 34px calc(50% - 50vw + 24px) 48px;
  border: 0;
  background:
    radial-gradient(60% 52% at 12% 78%, rgb(73 105 103 / 0.15), transparent 72%),
    radial-gradient(54% 48% at 88% 72%, rgb(183 122 95 / 0.12), transparent 72%),
    linear-gradient(180deg, transparent 0 36%, rgb(232 218 191 / 0.08));
}

.scroll-painting .city-pair svg {
  opacity: 0.28;
  filter: saturate(0.86) blur(0.2px);
  transition: opacity 1.1s ease, filter 1.1s ease;
}

.scroll-painting .city-pair.is-ritual-ready svg {
  opacity: 0.88;
  filter: saturate(0.96) blur(0);
}

.scroll-painting .city-pair:not(.is-ritual-ready) svg {
  pointer-events: none;
}

.scroll-painting .city-pair.is-ritual-ready::before {
  opacity: 0.2;
  transform: scale(1);
  transition: opacity 1.2s ease, transform 1.3s cubic-bezier(.16,1,.3,1);
}

.scroll-painting .city-pair__ridge--near {
  fill: rgb(63 91 90 / 0.13);
  stroke: rgb(55 79 78 / 0.25);
  stroke-width: 0.78;
}

.scroll-painting .city-pair__ridge--far {
  stroke: rgb(63 91 90 / 0.21);
}

.scroll-painting .city-pair__village rect,
.scroll-painting .city-pair__bund rect,
.scroll-painting .city-pair__tower,
.scroll-painting .city-pair__pearl circle {
  fill: rgb(121 84 75 / 0.12);
  stroke: rgb(87 65 62 / 0.34);
  stroke-width: 0.76;
}

.scroll-painting .city-pair__pearl line {
  opacity: 0.38;
}

.scroll-painting .city-pair__wash {
  pointer-events: none;
}

.scroll-painting .city-pair__wash-river {
  fill: url("#cityInkWash");
  opacity: 0.22;
}

.scroll-painting .city-pair__wash-ink {
  fill: url("#cityInkWash");
  opacity: 0.46;
  filter: blur(5px);
}

.scroll-painting .city-pair__moon-wash {
  fill: url("#cityMoonWash");
  opacity: 0.6;
  transform-box: fill-box;
  transform-origin: center;
  transition: opacity 1.4s ease, transform 2s cubic-bezier(.16,1,.3,1);
}

.scroll-painting .city-pair__moon-water {
  fill: none;
  stroke: rgb(190 145 99 / 0.16);
  stroke-width: 12;
  stroke-linecap: round;
  opacity: 0.38;
  filter: blur(5px);
}

.scroll-painting .city-pair__birds {
  fill: none;
  stroke: rgb(66 76 74 / 0.24);
  stroke-width: 0.8;
  stroke-linecap: round;
}

.scroll-painting .city-pair.has-route-arrived .city-pair__moon-wash {
  opacity: 0.82;
  transform: scale(1.06);
}

.scroll-painting .city-pair__place {
  position: absolute;
  z-index: 3;
  bottom: 3.5%;
  display: flex;
  align-items: baseline;
  gap: 0.72em;
  color: rgb(49 45 42 / 0.58);
  pointer-events: none;
}

.scroll-painting .city-pair__place b {
  font-family: var(--serif);
  font-size: clamp(0.84rem, 1.18vw, 1.05rem);
  font-weight: 400;
  letter-spacing: 0.2em;
}

.scroll-painting .city-pair__place small {
  font-family: var(--sans);
  font-size: 0.5rem;
  letter-spacing: 0.18em;
  opacity: 0.58;
}

.scroll-painting .city-pair__place--yunnan {
  left: 4.2%;
}

.scroll-painting .city-pair__place--shanghai {
  right: 4.2%;
}

.scroll-painting .city-pair__route {
  opacity: 0.22;
  stroke-width: 0.9;
}

.scroll-painting .city-pair__route-progress {
  opacity: 0.8;
  stroke-width: 1.35;
  filter: drop-shadow(0 0 2px rgb(224 169 109 / 0.28));
}

.scroll-painting .city-pair.has-route-arrived .city-pair__route-progress {
  opacity: 0.66;
}

.scroll-painting .city-pair__imprints {
  pointer-events: none;
}

.scroll-painting .city-pair__imprint-halo,
.scroll-painting .city-pair__imprint-core,
.scroll-painting .city-pair__imprint-word {
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  transition: opacity 680ms ease, transform 900ms cubic-bezier(.16,1,.3,1), filter 680ms ease;
}

.scroll-painting .city-pair__imprint-halo {
  fill: rgb(246 224 190 / 0.04);
  stroke: rgb(139 91 79 / 0.34);
  stroke-width: 0.8;
  transform: scale(0.46);
}

.scroll-painting .city-pair__imprint-core {
  fill: rgb(158 83 69 / 0.6);
  transform: scale(0.5);
}

.scroll-painting .city-pair__imprint-word {
  fill: rgb(70 55 49 / 0.62);
  font-family: var(--serif);
  font-size: 10px;
  letter-spacing: 0.12em;
  paint-order: stroke;
  stroke: rgb(239 228 207 / 0.72);
  stroke-width: 3px;
  stroke-linejoin: round;
}

.scroll-painting .city-pair__imprints.is-prepared .city-pair__imprint-halo,
.scroll-painting .city-pair__imprints.is-prepared .city-pair__imprint-core,
.scroll-painting .city-pair__imprints.is-prepared .city-pair__imprint-word {
  opacity: 0.28;
  transform: scale(0.82);
}

.scroll-painting .city-pair__imprint.is-passed .city-pair__imprint-halo,
.scroll-painting .city-pair__imprint.is-passed .city-pair__imprint-core,
.scroll-painting .city-pair__imprint.is-passed .city-pair__imprint-word {
  opacity: 0.92;
  transform: scale(1);
  filter: drop-shadow(0 0 5px rgb(202 145 103 / 0.3));
}

.scroll-painting .page-warmth-echo {
  position: absolute;
  z-index: 7;
  top: 41%;
  left: 50%;
  width: min(32em, 76vw);
  margin: 0;
  color: rgb(66 52 47 / 0.7);
  font-family: var(--serif);
  font-size: clamp(0.68rem, 0.9vw, 0.82rem);
  letter-spacing: 0.08em;
  line-height: 1.7;
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 10px);
}

.scroll-painting .page-warmth-echo.is-visible {
  animation: page-warmth-echo 2.1s cubic-bezier(.16,1,.3,1) both;
}

@keyframes page-warmth-echo {
  0% { opacity: 0; transform: translate(-50%, 10px); }
  24%, 72% { opacity: 0.76; transform: translate(-50%, 0); }
  100% { opacity: 0; transform: translate(-50%, -7px); }
}

.scroll-painting .page-warmth-summary {
  grid-column: 1 / -1;
  width: min(48em, 86vw);
  margin: -26px auto 28px;
  color: rgb(56 49 44 / 0.64);
  font-family: var(--serif);
  font-size: clamp(0.68rem, 0.88vw, 0.8rem);
  letter-spacing: 0.07em;
  line-height: 1.85;
  text-align: center;
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 1s ease, transform 1s cubic-bezier(.16,1,.3,1);
}

.scroll-painting .page-warmth-summary.is-visible {
  opacity: 1;
  transform: none;
}

.scroll-painting .colophon__title,
.scroll-painting .colophon__places,
.scroll-painting .colophon__end {
  opacity: 0.14;
  transform: translateY(5px);
  transition: opacity 1s ease, transform 1s cubic-bezier(.16,1,.3,1);
}

.scroll-painting.is-hope-lit .colophon__title,
.scroll-painting.is-hope-lit .colophon__places,
.scroll-painting.is-hope-lit .colophon__end {
  opacity: 0.72;
  transform: none;
}

.scroll-painting .city-pair__gesture-hint {
  top: 18%;
  bottom: auto;
}

.scroll-painting .city-weather {
  top: 8%;
  left: 50%;
  width: min(300px, 72%);
}

.scroll-painting .city-weather__button {
  border: 0;
  border-bottom: 1px solid rgb(91 69 63 / 0.14);
  border-radius: 2px;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
}

.scroll-painting .city-pair:not(.is-ritual-ready) .city-pair__handle,
.scroll-painting .city-pair:not(.is-ritual-ready) .city-pair__route-progress {
  opacity: 0;
}

.scroll-painting .city-pair:not(.has-same-weather) .city-pair__route-light--outbound,
.scroll-painting .city-pair:not(.has-same-weather) .city-pair__route-light--return {
  display: none;
}

.scroll-painting .city-pair:not(.has-route-arrived) .city-weather {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 8px);
}

.scroll-painting .city-pair.has-route-arrived .city-weather {
  visibility: visible;
  opacity: 1;
  transform: translate(-50%, 0);
  transition: opacity 900ms ease 700ms, transform 900ms cubic-bezier(.16,1,.3,1) 700ms;
}

.scroll-painting .city-pair.has-route-arrived .city-pair__gesture-hint {
  top: 28%;
  width: min(680px, 86vw);
  opacity: 0.72;
}

.scroll-painting .city-pair.has-route-arrived .city-pair__gesture-hint small {
  white-space: normal;
}

@media (max-width: 900px) {
  .scroll-painting .contact-sheet::before {
    background:
      radial-gradient(ellipse 96% 48% at 50% 22%, rgb(8 9 23 / 0.3), transparent 78%),
      radial-gradient(circle at 80% 34%, rgb(173 67 98 / 0.12), transparent 34%),
      linear-gradient(180deg, transparent 38%, rgb(8 9 21 / 0.35));
  }

  .scroll-painting .ordinary-days::before {
    background:
      radial-gradient(ellipse 104% 58% at 48% 47%, rgb(19 11 23 / 0.45), rgb(22 12 25 / 0.18) 67%, transparent 88%),
      radial-gradient(circle at 82% 28%, rgb(180 69 92 / 0.15), transparent 31%),
      linear-gradient(180deg, rgb(21 12 23 / 0.06), transparent 42%, rgb(16 10 19 / 0.25));
  }

  .scroll-painting .chapter-nav {
    opacity: 0.14;
  }

  .scroll-painting .chapter-scroll-seal {
    opacity: 0.2;
  }

  .scroll-painting .chapter-seal-slot {
    opacity: 0.34;
  }

  .scroll-painting .city-pair {
    width: calc(100vw - 20px);
    height: clamp(260px, 72vw, 320px);
    margin: 28px calc(50% - 50vw + 10px) 38px;
  }

  .scroll-painting .city-pair__gesture-hint {
    top: 32%;
    bottom: auto;
    width: min(330px, 82vw);
  }

  .scroll-painting .city-pair.has-route-arrived .city-pair__gesture-hint {
    width: min(340px, 86vw);
  }

  .scroll-painting .city-weather {
    top: 10px;
    left: 50%;
    width: min(310px, 82%);
  }

  .scroll-painting .city-pair__place {
    bottom: 2%;
  }

  .scroll-painting .city-pair__place small {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting > .atmosphere,
  .scroll-painting .site-chrome,
  .scroll-painting .ordinary-line,
  .scroll-painting .chapter-scroll-seal,
  .scroll-painting .memory__image,
  .scroll-painting .film-frame img {
    transition-duration: 0.01ms !important;
  }

  .scroll-painting .city-pair svg,
  .scroll-painting .city-weather {
    transition-duration: 0.01ms !important;
  }

  .scroll-painting .ordinary-lines li,
  .scroll-painting .ordinary-lines li.is-visible,
  .scroll-painting .ordinary-lines li.is-past,
  .scroll-painting .ordinary-lines li.is-current {
    min-height: auto;
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }
}

.scroll-painting.has-static-reveals .ordinary-lines li,
.scroll-painting.has-static-reveals .ordinary-lines li.is-visible,
.scroll-painting.has-static-reveals .ordinary-lines li.is-past,
.scroll-painting.has-static-reveals .ordinary-lines li.is-current {
  min-height: auto;
  opacity: 1 !important;
  filter: none !important;
  transform: none !important;
}

@media (forced-colors: active) {
  .scroll-painting > .atmosphere {
    display: none;
  }

  .scroll-painting .chapter,
  .scroll-painting .threshold {
    background: Canvas !important;
  }

  .scroll-painting .city-pair__range {
    position: relative;
    left: auto;
    width: min(420px, 90%);
    margin: 0 auto;
    opacity: 1;
    pointer-events: auto;
    transform: none;
  }
}

@media (max-width: 520px) {
  .scroll-painting .ordinary-days__text {
    margin-top: 104px;
  }

  .scroll-painting .ordinary-lines li,
  .scroll-painting .ordinary-lines li[data-ordinary-ink-ready="true"] {
    min-height: 70svh;
    font-size: clamp(1.12rem, 5vw, 1.36rem);
    line-height: 1.86;
  }

  .scroll-painting .city-pair {
    height: 320px;
  }

  .scroll-painting .city-pair svg {
    position: absolute;
    bottom: 0;
    left: 50%;
    width: 166%;
    height: auto;
    transform: translateX(-50%);
  }

  .scroll-painting .city-pair__gesture-hint {
    top: 30px;
    width: min(330px, 86vw);
    font-size: 0.82rem;
  }

  .scroll-painting .city-pair__gesture-hint small {
    font-size: 0.6rem;
    opacity: 0.68;
  }

  .scroll-painting .city-pair.has-route-arrived .city-pair__gesture-hint {
    top: 108px;
  }

  .scroll-painting .city-pair__handle-halo {
    fill: rgb(199 143 109 / 0.17);
    stroke: rgb(139 84 76 / 0.82);
    stroke-width: 1.8;
  }

  .scroll-painting .city-pair__route-progress {
    stroke-width: 2.1;
    opacity: 0.96;
  }

  .scroll-painting .city-weather {
    top: 8px;
  }

  .scroll-painting .page-warmth-echo {
    top: 28%;
    width: 84vw;
    font-size: 0.68rem;
  }

  .scroll-painting .page-warmth-summary {
    margin: -10px auto 25px;
    font-size: 0.68rem;
  }

  .scroll-painting .city-pair__imprint-word {
    font-size: 9px;
  }

  .scroll-painting .archive-door.reveal:not(.is-visible) h2 {
    filter: blur(1.5px);
    transform: translateY(6px);
  }

  .scroll-painting .archive-door.reveal.is-visible h2 {
    filter: none;
    transform: none;
    transition: filter 520ms ease, transform 520ms cubic-bezier(.16,1,.3,1);
  }
}

@media (max-height: 520px) and (orientation: landscape) {
  .scroll-painting .city-pair {
    height: 220px;
    margin-top: 14px;
    margin-bottom: 24px;
  }

  .scroll-painting .city-pair__gesture-hint {
    top: 10%;
  }

  .scroll-painting .city-pair.has-route-arrived .city-pair__gesture-hint {
    top: 19%;
  }

  .scroll-painting .city-weather {
    top: 2px;
  }
}

@media (max-width: 380px) and (max-height: 600px) {
  .scroll-painting .threshold__eyebrow {
    font-size: 0.58rem;
  }

  .scroll-painting .threshold__title {
    font-size: 0.9rem;
    line-height: 1.42;
  }

  .scroll-painting .threshold__hint {
    font-size: 0.58rem;
  }

  .scroll-painting .threshold__direct {
    font-size: 0.68rem;
  }
}

/* --------------------------------------------------------------------------
   插画入卷 · let the four cinematic scenes remain visible beneath the prose
   -------------------------------------------------------------------------- */

.scroll-painting .contact-sheet::before {
  opacity: 0.48;
  background:
    radial-gradient(ellipse 62% 74% at 15% 44%, rgb(5 10 24 / 0.48), rgb(7 12 27 / 0.18) 56%, transparent 84%),
    linear-gradient(180deg, rgb(4 8 21 / 0.08), transparent 38%, rgb(5 9 22 / 0.2));
}

.scroll-painting .contact-sheet::after {
  opacity: 0.16;
}

.scroll-painting .ordinary-days::before {
  opacity: 0.42;
  background:
    radial-gradient(ellipse 60% 72% at 16% 49%, rgb(12 15 26 / 0.5), rgb(14 16 27 / 0.18) 58%, transparent 86%),
    linear-gradient(180deg, rgb(9 12 23 / 0.06), transparent 44%, rgb(8 11 21 / 0.19));
}

.scroll-painting .ordinary-days::after {
  opacity: 0.1;
}

.scroll-painting .ordinary-days__wash {
  opacity: 0.24;
}

.scroll-painting .ordinary-days__wash::before {
  opacity: 0.035;
}

/* The former full-width oval remains as a small, finite response to a touch. */
.scroll-painting .ordinary-days__wash::after {
  width: clamp(170px, 24vw, 330px);
  filter: opacity(0.24) blur(5px);
}

.scroll-painting .letter::before {
  opacity: 0.34;
  background:
    radial-gradient(ellipse 58% 82% at 20% 47%, rgb(255 246 224 / 0.3), rgb(251 236 208 / 0.1) 62%, transparent 88%),
    linear-gradient(180deg, rgb(82 59 58 / 0.035), transparent 52%, rgb(66 50 51 / 0.08));
}

.scroll-painting .daybreak::before,
body.scroll-painting.is-final-bloom .daybreak::before {
  inset: 0;
  width: auto;
  height: auto;
  aspect-ratio: auto;
  border-radius: 0;
  opacity: 0.52 !important;
  background:
    radial-gradient(ellipse 54% 78% at 14% 42%, rgb(250 247 235 / 0.74), rgb(244 241 226 / 0.26) 58%, transparent 86%),
    linear-gradient(180deg, rgb(226 236 236 / 0.1), transparent 46%, rgb(247 222 189 / 0.12));
  filter: none;
  transform: none;
  animation: none !important;
}

/* The generated dawn already owns its sun; keep only the passing warm wash. */
.scroll-painting .daybreak__sun {
  opacity: 0 !important;
  visibility: hidden;
}

body.scroll-painting.is-final-bloom .daybreak__final-wash {
  filter: opacity(0.34) saturate(0.9);
  mix-blend-mode: soft-light;
}

.scroll-painting .daybreak__lines {
  color: rgb(43 42 41 / 0.78);
  text-shadow:
    0 1px 0 rgb(255 252 239 / 0.26),
    0 10px 34px rgb(250 244 225 / 0.38);
}

.scroll-painting .daybreak__open-line,
.scroll-painting .closing-gesture__prompt,
.scroll-painting .closing-after {
  color: rgb(42 40 39 / 0.86);
  text-shadow: 0 10px 32px rgb(250 244 225 / 0.36);
}

@media (min-width: 901px) {
  .scroll-painting .ordinary-days__text {
    width: min(55%, 680px);
    margin-right: auto;
    margin-left: 4%;
  }
}

@media (max-width: 900px) {
  .scroll-painting .contact-sheet::before,
  .scroll-painting .ordinary-days::before {
    opacity: 0.38;
  }

  .scroll-painting .daybreak::before,
  body.scroll-painting.is-final-bloom .daybreak::before {
    opacity: 0.42 !important;
    background:
      linear-gradient(180deg, rgb(245 246 238 / 0.38), transparent 30% 64%, rgb(238 228 209 / 0.22)),
      radial-gradient(ellipse 92% 48% at 42% 16%, rgb(248 248 239 / 0.34), transparent 78%);
  }

  .scroll-painting .daybreak__lines,
  .scroll-painting .daybreak__open-line,
  .scroll-painting .closing-gesture__prompt,
  .scroll-painting .closing-after {
    color: rgb(40 39 39 / 0.88);
    text-shadow:
      0 1px 0 rgb(255 252 240 / 0.34),
      0 10px 30px rgb(250 244 225 / 0.48);
  }
}

@media (prefers-reduced-motion: reduce) {
  body.scroll-painting.is-final-bloom .daybreak__final-wash {
    opacity: 0.24;
    transform: none;
  }
}

/* --------------------------------------------------------------------------
   逐章触碰仪式 · each chapter teaches one quiet, discoverable gesture
   -------------------------------------------------------------------------- */

.scroll-painting .scene-ritual-hint {
  position: fixed;
  z-index: 69;
  bottom: max(76px, calc(env(safe-area-inset-bottom) + 58px));
  left: 50%;
  display: flex;
  align-items: center;
  gap: 11px;
  max-width: min(78vw, 390px);
  margin: 0;
  padding: 9px 15px 9px 11px;
  border: 1px solid rgb(238 220 198 / 0.16);
  border-radius: 999px;
  color: rgb(242 227 207 / 0.78);
  background: linear-gradient(112deg, rgb(9 14 20 / 0.58), rgb(34 27 35 / 0.34));
  box-shadow: 0 18px 54px rgb(0 0 0 / 0.2), inset 0 1px rgb(255 255 255 / 0.035);
  backdrop-filter: blur(13px) saturate(1.08);
  font-family: var(--sans);
  font-size: 0.64rem;
  letter-spacing: 0.12em;
  line-height: 1.45;
  text-align: center;
  opacity: 0;
  pointer-events: none;
  transform: translate3d(-50%, 12px, 0);
  transition: opacity 480ms ease, transform 680ms cubic-bezier(.16,1,.3,1), color 720ms ease, background 720ms ease;
}

.scroll-painting .scene-ritual-hint i {
  position: relative;
  display: block;
  width: 24px;
  height: 1px;
  flex: 0 0 auto;
  overflow: hidden;
  background: rgb(236 207 176 / 0.2);
}

.scroll-painting .scene-ritual-hint i::after {
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg, transparent, rgb(235 192 156 / 0.92), transparent);
  content: "";
  transform: translateX(-112%);
}

.scroll-painting .scene-ritual-hint.is-visible {
  opacity: 0.9;
  transform: translate3d(-50%, 0, 0);
}

.scroll-painting .scene-ritual-hint.is-voice-only {
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  opacity: 1;
  overflow: hidden;
  white-space: nowrap;
}

.scroll-painting .scene-ritual-hint.is-visible i::after {
  animation: scene-hint-pass 1.8s 240ms cubic-bezier(.2,.7,.2,1) 1 both;
}

body.scroll-painting[data-tone="day"] .scene-ritual-hint {
  border-color: rgb(92 68 64 / 0.13);
  color: rgb(57 49 47 / 0.72);
  background: rgb(250 242 228 / 0.68);
  box-shadow: 0 18px 50px rgb(85 62 54 / 0.09), inset 0 1px rgb(255 255 255 / 0.42);
}

@keyframes scene-hint-pass {
  from { transform: translateX(-112%); }
  to { transform: translateX(112%); }
}

.scroll-painting .rain-window-ritual {
  appearance: none;
  display: flex;
  width: fit-content;
  min-height: 44px;
  max-width: 100%;
  align-items: center;
  gap: 11px;
  margin-top: 18px;
  padding: 9px 14px 9px 11px;
  border: 1px solid rgb(205 224 222 / 0.2);
  border-radius: 999px;
  color: rgb(231 220 203 / 0.72);
  background: linear-gradient(118deg, rgb(10 21 31 / 0.54), rgb(42 35 42 / 0.32));
  box-shadow: inset 0 1px rgb(255 255 255 / 0.035), 0 12px 34px rgb(0 0 0 / 0.12);
  font-family: var(--serif);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  line-height: 1.5;
  text-align: left;
  cursor: pointer;
  touch-action: manipulation;
  transition: color 320ms ease, border-color 320ms ease, background 320ms ease, box-shadow 320ms ease, transform 320ms cubic-bezier(.16,1,.3,1);
}

.scroll-painting .rain-window-ritual > i {
  position: relative;
  display: block;
  width: 29px;
  height: 20px;
  flex: 0 0 auto;
  overflow: hidden;
  border: 1px solid rgb(202 225 224 / 0.28);
  border-radius: 2px;
  background:
    linear-gradient(90deg, transparent 48%, rgb(209 229 225 / 0.14) 49% 52%, transparent 53%),
    linear-gradient(180deg, rgb(80 120 133 / 0.18), rgb(9 24 34 / 0.36));
  box-shadow: inset 0 0 14px rgb(154 204 207 / 0.06);
}

.scroll-painting .rain-window-ritual > i::after {
  position: absolute;
  inset: -35%;
  background: radial-gradient(circle at 68% 56%, rgb(244 199 128 / 0.7) 0 5%, rgb(226 172 108 / 0.16) 12%, transparent 40%);
  content: "";
  opacity: 0.48;
  transition: opacity 420ms ease, transform 620ms cubic-bezier(.16,1,.3,1);
  transform: scale(0.82);
}

.scroll-painting .rain-window-ritual:hover,
.scroll-painting .rain-window-ritual:focus-visible,
body.scroll-painting[data-chapter="02"].is-rain-revealed .rain-window-ritual {
  border-color: rgb(224 211 178 / 0.42);
  color: rgb(244 231 207 / 0.9);
  background: linear-gradient(118deg, rgb(15 33 42 / 0.68), rgb(55 42 44 / 0.42));
  box-shadow: inset 0 1px rgb(255 255 255 / 0.06), 0 14px 38px rgb(0 0 0 / 0.16);
  transform: translateY(-1px);
}

.scroll-painting .rain-window-ritual:hover > i::after,
.scroll-painting .rain-window-ritual:focus-visible > i::after,
body.scroll-painting[data-chapter="02"].is-rain-revealed .rain-window-ritual > i::after {
  opacity: 1;
  transform: scale(1);
}

.scroll-painting .rain-window-ritual:focus-visible {
  outline: 2px solid rgb(232 211 178 / 0.68);
  outline-offset: 3px;
}

.scroll-painting .scene-lens {
  position: fixed;
  z-index: 66;
  top: var(--scene-lens-y, 50vh);
  left: var(--scene-lens-x, 50vw);
  width: clamp(150px, 18vw, 224px);
  aspect-ratio: 1.16;
  border: 1px solid rgb(207 226 224 / 0.18);
  border-radius: 54% 46% 49% 51% / 46% 55% 45% 54%;
  opacity: 0;
  overflow: visible;
  pointer-events: none;
  background:
    radial-gradient(circle at 58% 42%, rgb(245 226 190 / 0.24) 0 4%, transparent 30%),
    radial-gradient(ellipse at 50% 48%, rgb(152 196 198 / 0.14), rgb(11 31 41 / 0.05) 64%, transparent 76%);
  box-shadow: inset 0 0 46px rgb(196 226 224 / 0.07), 0 0 48px rgb(116 172 185 / 0.09);
  backdrop-filter: blur(0.7px) saturate(1.16) brightness(1.07);
  transform: translate3d(-50%, -50%, 0) scale(0.72) rotate(-2deg);
  transition: width 760ms cubic-bezier(.16,1,.3,1), opacity 360ms ease, transform 760ms cubic-bezier(.16,1,.3,1), border-color 520ms ease, box-shadow 720ms ease;
}

.scroll-painting .scene-lens::before,
.scroll-painting .scene-lens::after {
  position: absolute;
  inset: 9%;
  border: 1px solid rgb(226 239 235 / 0.1);
  border-radius: inherit;
  content: "";
}

.scroll-painting .scene-lens::after {
  inset: -18%;
  border-color: transparent;
  background: radial-gradient(circle, rgb(168 214 218 / 0.09), transparent 66%);
  filter: blur(12px);
}

.scroll-painting .scene-lens span {
  position: absolute;
  top: calc(100% + 18px);
  left: 50%;
  width: min(82vw, 29em);
  color: rgb(237 224 205 / 0.86);
  font-family: var(--serif);
  font-size: clamp(0.72rem, 1.1vw, 0.88rem);
  letter-spacing: 0.12em;
  line-height: 1.75;
  text-align: center;
  text-shadow: 0 8px 24px rgb(0 0 0 / 0.48);
  opacity: 0;
  transform: translate3d(-50%, 8px, 0);
  transition: opacity 520ms 220ms ease, transform 680ms 180ms cubic-bezier(.16,1,.3,1);
}

body.scroll-painting[data-chapter="02"].is-rain-wiping .scene-lens {
  opacity: 0.68;
  transform: translate3d(-50%, -50%, 0) scale(0.94) rotate(0);
}

body.scroll-painting[data-chapter="02"].is-rain-revealed .scene-lens {
  width: clamp(184px, 24vw, 286px);
  border-color: rgb(239 220 185 / 0.34);
  opacity: 0.96;
  background:
    radial-gradient(circle at 61% 38%, rgb(255 226 169 / 0.42) 0 3.5%, rgb(239 199 136 / 0.12) 10%, transparent 34%),
    radial-gradient(ellipse at 50% 50%, rgb(175 221 219 / 0.18), rgb(15 35 48 / 0.05) 66%, transparent 78%);
  box-shadow: inset 0 0 54px rgb(212 235 228 / 0.1), 0 0 70px rgb(197 155 114 / 0.15);
  transform: translate3d(-50%, -50%, 0) scale(1) rotate(0);
}

body.scroll-painting[data-chapter="02"].is-rain-revealed .scene-lens span {
  opacity: 1;
  transform: translate3d(-50%, 0, 0);
}

body.scroll-painting.archive-is-open .scene-ritual-hint,
body.scroll-painting.moon-secret-is-open .scene-ritual-hint,
body.scroll-painting.archive-is-open .scene-lens,
body.scroll-painting.moon-secret-is-open .scene-lens {
  opacity: 0 !important;
}

/* Two touches, two shores, one finite meeting in the middle. */
.scroll-painting .truth-tide__meeting {
  position: absolute;
  z-index: 7;
  right: 8%;
  bottom: 15%;
  left: 8%;
  display: block;
  color: rgb(232 216 205 / 0.8);
  font-family: var(--serif);
  font-size: clamp(0.7rem, 1vw, 0.84rem);
  letter-spacing: 0.13em;
  line-height: 1.8;
  text-align: center;
  text-shadow: 0 9px 28px rgb(0 0 0 / 0.48);
  opacity: 0;
  pointer-events: none;
  transform: translate3d(0, 10px, 0);
}

.scroll-painting .truth-tide__meeting::before {
  display: block;
  width: min(170px, 34vw);
  height: 1px;
  margin: 0 auto 15px;
  background: linear-gradient(90deg, transparent, rgb(229 195 179 / 0.54), transparent);
  content: "";
  transform: scaleX(0.12);
}

.scroll-painting .truth-beat.is-tide-meeting .truth-tide__meeting {
  animation: tide-meeting-words 5.4s cubic-bezier(.16,1,.3,1) 1 both;
}

.scroll-painting .truth-beat.is-tide-meeting .truth-tide__meeting::before {
  animation: tide-meeting-line 3.8s cubic-bezier(.16,1,.3,1) 1 both;
}

.scroll-painting .truth-tide__shore::after {
  position: absolute;
  top: 50%;
  left: var(--tide-await-x, 82%);
  width: 5px;
  aspect-ratio: 1;
  border-radius: 50%;
  content: "";
  opacity: 0;
  background: rgb(239 213 192 / 0.82);
  box-shadow:
    0 0 12px rgb(239 213 192 / 0.54),
    0 0 38px rgb(190 159 187 / 0.28);
  transform: translate(-50%, -50%) scale(0.45);
}

.scroll-painting .truth-beat.is-tide-awaiting .truth-tide__shore::after {
  animation: tide-opposite-shore 3.7s cubic-bezier(.16,1,.3,1) 1 both;
}

.scroll-painting .truth-beat.is-tide-awaiting .truth-tide__moon-road {
  left: var(--tide-await-x, 82%);
  opacity: 0.48;
}

.scroll-painting .truth-beat.is-tide-awaiting .truth-tide__meeting {
  animation: tide-opposite-words 3.7s cubic-bezier(.16,1,.3,1) 1 both;
}

.scroll-painting .truth-beat.is-tide-awaiting .truth-tide__meeting::before {
  animation: tide-opposite-line 3.4s cubic-bezier(.16,1,.3,1) 1 both;
}

@keyframes tide-meeting-words {
  0%, 8% { opacity: 0; transform: translate3d(0, 10px, 0); }
  24%, 72% { opacity: 0.9; transform: none; }
  100% { opacity: 0; transform: translate3d(0, -6px, 0); }
}

@keyframes tide-meeting-line {
  0% { opacity: 0; transform: scaleX(0.12); }
  34%, 72% { opacity: 0.88; transform: scaleX(1); }
  100% { opacity: 0; transform: scaleX(0.68); }
}

@keyframes tide-opposite-shore {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.45); }
  26%, 70% { opacity: 0.9; transform: translate(-50%, -50%) scale(1); }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.42); }
}

@keyframes tide-opposite-words {
  0%, 10% { opacity: 0; transform: translate3d(0, 8px, 0); }
  28%, 72% { opacity: 0.74; transform: none; }
  100% { opacity: 0; transform: translate3d(0, -5px, 0); }
}

@keyframes tide-opposite-line {
  0% { opacity: 0; transform: scaleX(0.08); }
  32%, 70% { opacity: 0.64; transform: scaleX(0.72); }
  100% { opacity: 0; transform: scaleX(1); }
}

/* A folded letter may receive one cinnabar seal: “平安”, never “归期”. */
.scroll-painting .peace-seal-wrap {
  display: grid;
  justify-items: end;
  gap: 6px;
  width: 100%;
  opacity: 0;
  transform: translate3d(0, 8px, 0);
  transition: opacity 360ms ease, transform 520ms cubic-bezier(.16,1,.3,1);
}

.scroll-painting .peace-seal-wrap[hidden] {
  display: none !important;
}

.scroll-painting .peace-seal-wrap.is-visible {
  opacity: 1;
  transform: none;
}

.scroll-painting .peace-seal {
  --seal-rgb: 142 53 47;
  display: inline-grid;
  min-width: 154px;
  min-height: 48px;
  grid-template-columns: 42px 1fr;
  align-items: center;
  gap: 10px;
  padding: 3px 13px 3px 3px;
  border: 1px solid rgb(var(--seal-rgb) / 0.2);
  border-radius: 3px 19px 19px 3px;
  color: rgb(91 55 51 / 0.72);
  background: rgb(255 249 237 / 0.24);
  cursor: pointer;
  touch-action: manipulation;
  transition: border-color 340ms ease, color 340ms ease, background 340ms ease, transform 180ms ease;
}

.scroll-painting .peace-seal:hover,
.scroll-painting .peace-seal:focus-visible,
.scroll-painting .peace-seal-wrap.is-set .peace-seal {
  border-color: rgb(var(--seal-rgb) / 0.46);
  color: rgb(91 42 39 / 0.92);
  background: rgb(255 247 232 / 0.48);
}

.scroll-painting .peace-seal:active {
  transform: scale(0.98);
}

.scroll-painting .peace-seal span {
  display: grid;
  width: 42px;
  height: 42px;
  place-items: center;
  border: 1px solid rgb(var(--seal-rgb) / 0.62);
  color: rgb(var(--seal-rgb) / 0.84);
  background:
    linear-gradient(90deg, transparent 47%, rgb(var(--seal-rgb) / 0.1) 48% 52%, transparent 53%),
    linear-gradient(0deg, transparent 47%, rgb(var(--seal-rgb) / 0.1) 48% 52%, transparent 53%);
  font-family: var(--serif);
  font-size: 1.02rem;
  line-height: 1;
  transform: rotate(-2deg);
}

.scroll-painting .peace-seal em {
  font-family: var(--serif);
  font-size: 0.7rem;
  font-style: normal;
  letter-spacing: 0.08em;
  line-height: 1.55;
  text-align: left;
}

.scroll-painting .peace-seal__note {
  min-height: 1.5em;
  margin: 0;
  color: rgb(103 55 50 / 0.66);
  font-family: var(--serif);
  font-size: 0.64rem;
  letter-spacing: 0.07em;
  line-height: 1.6;
  text-align: right;
}

.scroll-painting .peace-seal-wrap.is-setting .peace-seal span {
  animation: peace-seal-settle 880ms cubic-bezier(.18,.78,.18,1) 1 both;
}

.scroll-painting .letter-body.is-peace-sealed {
  box-shadow: 0 46px 120px rgb(15 20 18 / 0.28), inset 0 0 72px rgb(132 58 48 / 0.055);
}

@keyframes peace-seal-settle {
  0% { opacity: 0.32; filter: blur(1.8px); transform: rotate(-10deg) scale(1.34); }
  58% { opacity: 1; filter: blur(0); transform: rotate(0.6deg) scale(0.94); }
  100% { opacity: 0.92; filter: none; transform: rotate(-2deg) scale(1); }
}

/* --------------------------------------------------------------------------
   Mobile composition · local reading mist, calmer titles, clearer city route
   -------------------------------------------------------------------------- */

@media (max-width: 700px) {
  .scroll-painting .rain-window-ritual {
    margin-top: 14px;
    padding: 10px 13px 10px 10px;
    font-size: 0.7rem;
  }

  .scroll-painting .scene-ritual-hint {
    bottom: max(68px, calc(env(safe-area-inset-bottom) + 52px));
    max-width: calc(100vw - 92px);
    gap: 8px;
    padding: 8px 12px 8px 9px;
    font-size: 0.59rem;
    letter-spacing: 0.09em;
  }

  .scroll-painting .scene-ritual-hint i {
    width: 18px;
  }

  .scroll-painting .scene-lens {
    width: clamp(132px, 39vw, 168px);
  }

  body.scroll-painting[data-chapter="02"].is-rain-revealed .scene-lens {
    width: clamp(164px, 49vw, 204px);
  }

  .scroll-painting .truth-beat #truthBeatLine {
    max-width: 9em;
    font-size: clamp(2.15rem, 9.2vw, 2.5rem);
    text-wrap: balance;
  }

  .scroll-painting .truth-tide__meeting {
    right: 5%;
    bottom: 12%;
    left: 5%;
    font-size: 0.68rem;
  }

  .scroll-painting .letter-body {
    background:
      linear-gradient(104deg, transparent 0 48%, rgb(176 138 96 / 0.04) 50%, transparent 52%),
      repeating-linear-gradient(0deg, rgb(83 67 53 / 0.016) 0 1px, transparent 1px 6px),
      linear-gradient(135deg, rgb(238 228 211 / 0.84), rgb(232 219 198 / 0.8) 66%, rgb(223 207 184 / 0.82));
    box-shadow: 0 24px 72px rgb(0 0 0 / 0.2), inset 0 0 56px rgb(100 77 55 / 0.028);
    backdrop-filter: blur(1.4px) saturate(0.92);
  }

  .scroll-painting .peace-seal-wrap {
    justify-items: stretch;
  }

  .scroll-painting .peace-seal {
    width: 100%;
  }

  .scroll-painting .peace-seal__note {
    font-size: 0.67rem;
    text-align: left;
  }

  .scroll-painting .daybreak__copy {
    position: relative;
    z-index: 1;
    isolation: isolate;
  }

  .scroll-painting .daybreak__copy::before {
    position: absolute;
    z-index: -1;
    inset: -34px -28px -40px;
    border-radius: 50%;
    background: radial-gradient(ellipse at 38% 42%, rgb(248 245 233 / 0.78), rgb(243 239 225 / 0.48) 54%, transparent 82%);
    filter: blur(13px);
    content: "";
    pointer-events: none;
  }

  .scroll-painting .daybreak__copy h2 {
    max-width: 8em;
    font-size: clamp(2.35rem, 10.4vw, 2.75rem);
    letter-spacing: -0.055em;
    text-wrap: balance;
  }

  .scroll-painting .daybreak__lines,
  .scroll-painting .daybreak__open-line {
    color: rgb(39 38 38 / 0.92);
  }

  .scroll-painting .city-pair svg {
    touch-action: pan-y;
  }

  .scroll-painting .city-pair.is-ritual-ready svg {
    opacity: 0.98;
    filter: saturate(1) contrast(1.14) blur(0);
  }

  .scroll-painting .city-pair.is-ritual-ready:not(.has-route-arrived) .city-pair__handle-halo {
    animation: city-route-invite 1.08s cubic-bezier(.16,1,.3,1) 2 both;
  }

  .scroll-painting .city-pair__route-progress {
    stroke-width: 2.5;
    opacity: 0.98;
  }

  .scroll-painting .city-pair__place {
    color: rgb(47 42 40 / 0.82);
    opacity: 0.94;
  }

  .scroll-painting .city-pair__place small {
    display: inline;
    font-size: 0.68rem;
    opacity: 0.78;
  }

  .scroll-painting .city-pair__gesture-hint small {
    font-size: 0.68rem;
    opacity: 0.8;
    line-height: 1.6;
  }

  .scroll-painting .city-weather__hint {
    font-size: 0.66rem;
    line-height: 1.6;
  }

  .scroll-painting .closing-button__privacy {
    font-size: 0.7rem;
    line-height: 1.65;
  }
}

@keyframes city-route-invite {
  0% { opacity: 0.38; transform: scale(0.7); }
  46% { opacity: 1; transform: scale(1.24); }
  100% { opacity: 0.62; transform: scale(0.88); }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting .rain-window-ritual,
  .scroll-painting .rain-window-ritual > i::after,
  .scroll-painting .scene-ritual-hint,
  .scroll-painting .scene-lens,
  .scroll-painting .scene-lens span,
  .scroll-painting .peace-seal-wrap {
    transition-duration: 0.01ms !important;
  }

  .scroll-painting .rain-window-ritual:hover,
  .scroll-painting .rain-window-ritual:focus-visible,
  body.scroll-painting[data-chapter="02"].is-rain-revealed .rain-window-ritual {
    transform: none;
  }

  .scroll-painting .scene-ritual-hint i::after,
  .scroll-painting .truth-beat.is-tide-meeting .truth-tide__meeting,
  .scroll-painting .truth-beat.is-tide-meeting .truth-tide__meeting::before,
  .scroll-painting .truth-beat.is-tide-awaiting .truth-tide__shore::after,
  .scroll-painting .truth-beat.is-tide-awaiting .truth-tide__meeting,
  .scroll-painting .truth-beat.is-tide-awaiting .truth-tide__meeting::before,
  .scroll-painting .peace-seal-wrap.is-setting .peace-seal span,
  .scroll-painting .city-pair.is-ritual-ready .city-pair__handle-halo {
    animation: none !important;
  }

  .scroll-painting .truth-beat.is-tide-meeting .truth-tide__meeting {
    opacity: 0.9;
    transform: none;
  }

  .scroll-painting .truth-beat.is-tide-awaiting .truth-tide__meeting {
    opacity: 0.72;
    transform: none;
  }

  .scroll-painting .truth-beat.is-tide-awaiting .truth-tide__shore::after {
    opacity: 0.74;
    transform: translate(-50%, -50%);
  }
}

body.is-data-saver.scroll-painting .scene-lens {
  backdrop-filter: none;
}

body.is-data-saver.scroll-painting .truth-beat.is-tide-awaiting .truth-tide__shore::after,
body.is-data-saver.scroll-painting .truth-beat.is-tide-awaiting .truth-tide__meeting,
body.is-data-saver.scroll-painting .truth-beat.is-tide-awaiting .truth-tide__meeting::before {
  animation: none !important;
}

body.is-data-saver.scroll-painting .scene-lens::after {
  display: none;
}

@media (forced-colors: active) {
  .scroll-painting .scene-lens { display: none; }
  .scroll-painting .scene-ritual-hint,
  .scroll-painting .peace-seal { border: 1px solid ButtonText; background: Canvas; color: CanvasText; }
  .scroll-painting .truth-tide__meeting { color: CanvasText; }
}

/* Phone photographs: keep the reading rhythm cinematic, never poster-long. */
@media (max-width: 700px) {
  .scroll-painting .photo-after {
    gap: clamp(96px, 14svh, 128px);
  }

  .scroll-painting .photo-after__item,
  .scroll-painting .photo-after__item--2 {
    gap: 30px;
  }

  .scroll-painting .photo-after__image {
    width: 100%;
    height: auto;
    max-height: none;
  }

  .scroll-painting .photo-after__item--2 {
    margin-top: 0;
  }

  .scroll-painting .photo-after__item--2 .photo-after__image {
    width: 100%;
    height: clamp(300px, 56svh, 470px);
    max-height: 56svh;
    aspect-ratio: auto;
    object-fit: cover;
    object-position: 50% 30%;
  }
}

/* --------------------------------------------------------------------------
   指尖入景 · each fold answers a touch in its own visual language
   -------------------------------------------------------------------------- */

.scroll-painting[data-scene-touch="01"] > .scene-flow::after {
  aspect-ratio: 1;
  background:
    radial-gradient(circle, rgb(250 226 181 / 0.2), rgb(126 183 191 / 0.075) 38%, transparent 72%);
}

.scroll-painting[data-scene-touch="02"] > .scene-flow::after {
  aspect-ratio: 0.9;
  background:
    radial-gradient(ellipse at 54% 42%, rgb(255 225 191 / 0.22), rgb(203 131 144 / 0.075) 38%, rgb(105 153 175 / 0.025) 57%, transparent 75%);
}

.scroll-painting[data-scene-touch="03"] > .scene-flow::after {
  aspect-ratio: 2.8;
  background:
    radial-gradient(ellipse, rgb(246 220 187 / 0.2), rgb(176 123 141 / 0.06) 46%, transparent 74%);
}

.scroll-painting[data-scene-touch="04"] > .scene-flow::after {
  aspect-ratio: 1.25;
  background:
    radial-gradient(ellipse, rgb(128 70 66 / 0.1), rgb(190 121 102 / 0.035) 46%, transparent 72%);
  mix-blend-mode: multiply;
}

.scroll-painting[data-scene-touch="05"] > .scene-flow::after {
  aspect-ratio: 1.45;
  background:
    radial-gradient(ellipse, rgb(255 234 190 / 0.3), rgb(231 157 122 / 0.09) 42%, transparent 74%);
}

/* --------------------------------------------------------------------------
   手机端连镜 · rain, tide, paper and dawn dissolve into one another
   -------------------------------------------------------------------------- */

@media (max-width: 700px) {
  .scroll-painting .scroll-transition {
    z-index: 61;
    mix-blend-mode: normal;
  }

  .scroll-painting .scroll-transition i:first-child {
    inset: -18%;
    border-radius: 48%;
    filter: blur(18px) saturate(1.08);
    transform-origin: 50% 74%;
  }

  /* The old vertical seam and horizon read as decorative yellow lines on a
     phone. The new transition is a single organic camera veil. */
  .scroll-painting .scroll-transition i:nth-child(2),
  .scroll-painting .scroll-transition b {
    display: none;
  }

  .scroll-painting[data-transition-to="02"] .scroll-transition i:first-child {
    background:
      radial-gradient(ellipse 68% 48% at 68% 38%, rgb(174 205 214 / 0.26), transparent 70%),
      radial-gradient(ellipse 76% 58% at 32% 72%, rgb(77 91 125 / 0.38), transparent 75%),
      linear-gradient(155deg, rgb(12 28 46 / 0.08), rgb(111 76 101 / 0.24));
  }

  .scroll-painting[data-transition-to="03"] .scroll-transition i:first-child {
    background:
      radial-gradient(ellipse 82% 42% at 48% 72%, rgb(190 139 147 / 0.3), transparent 70%),
      radial-gradient(ellipse 62% 55% at 78% 28%, rgb(104 99 137 / 0.24), transparent 74%),
      linear-gradient(165deg, rgb(21 23 49 / 0.11), rgb(83 45 61 / 0.28));
  }

  .scroll-painting[data-transition-to="04"] .scroll-transition i:first-child {
    background:
      radial-gradient(ellipse 74% 58% at 58% 56%, rgb(255 239 208 / 0.58), transparent 72%),
      radial-gradient(ellipse 52% 48% at 24% 70%, rgb(172 101 91 / 0.18), transparent 76%),
      linear-gradient(150deg, rgb(113 89 91 / 0.12), rgb(234 210 178 / 0.34));
  }

  .scroll-painting[data-transition-to="05"] .scroll-transition i:first-child {
    background:
      radial-gradient(ellipse 78% 58% at 72% 36%, rgb(255 230 187 / 0.52), transparent 72%),
      radial-gradient(ellipse 72% 48% at 28% 72%, rgb(185 210 207 / 0.35), transparent 75%),
      linear-gradient(160deg, rgb(149 169 177 / 0.14), rgb(235 174 139 / 0.3));
  }

  .scroll-painting.is-chapter-transitioning .scroll-transition i:first-child {
    animation: mobile-scene-dissolve 1.46s cubic-bezier(.2,.72,.22,1) both;
  }

  /* Let the previous weather remain for a breath while the next one enters. */
  .scroll-painting[data-transition-from="01"][data-transition-to="02"].is-chapter-transitioning .scene-flow__mist {
    opacity: 0.18;
  }

  .scroll-painting[data-transition-from="02"][data-transition-to="03"].is-chapter-transitioning .scene-flow__rain {
    opacity: 0.12;
  }

  .scroll-painting[data-transition-from="03"][data-transition-to="04"].is-chapter-transitioning .scene-flow__water {
    opacity: 0.16;
  }

  .scroll-painting[data-transition-from="04"][data-transition-to="05"].is-chapter-transitioning .scene-flow__paper {
    opacity: 0.18;
  }

  .scroll-painting .contact-sheet > .chapter-bridge,
  .scroll-painting .ordinary-days > .chapter-bridge,
  .scroll-painting .letter > .chapter-bridge {
    width: calc(100% - 30px);
    min-height: 72px;
    margin: 30px auto 18px;
    padding: 11px 13px 11px 14px;
    border-color: rgb(var(--sky-b) / 0.22);
    background:
      linear-gradient(90deg, rgb(var(--sky-a) / 0.055), rgb(var(--sky-b) / 0.018) 54%, transparent);
    backdrop-filter: blur(7px);
  }

  .scroll-painting .chapter-bridge strong {
    font-size: 0.82rem;
    letter-spacing: 0.075em;
  }

  .scroll-painting .chapter-bridge i {
    background:
      radial-gradient(circle at 76% 50%, currentColor 0 1.5px, transparent 2px),
      linear-gradient(90deg, transparent, currentColor);
    filter: drop-shadow(0 0 7px currentColor);
  }

  .scroll-painting .letter > .chapter-bridge {
    margin-top: 22px;
    margin-bottom: 8px;
    border-color: rgb(92 62 58 / 0.2);
    color: rgb(73 52 51 / 0.8);
    background:
      linear-gradient(90deg, rgb(246 229 204 / 0.56), rgb(232 208 180 / 0.2) 58%, transparent);
    box-shadow: 0 18px 48px rgb(71 47 45 / 0.065);
  }

  /* Keep the next title within the same breath as the bridge. On short
     phones these reductions remove almost a full viewport of empty travel. */
  .scroll-painting .contact-sheet {
    padding-bottom: 64px;
  }

  .scroll-painting .ordinary-days__layout {
    padding-top: 92px;
    padding-bottom: 112px;
  }

  .scroll-painting .letter {
    padding-top: 94px;
    padding-bottom: 72px;
  }

  .scroll-painting .daybreak__shell {
    padding-top: clamp(132px, 20svh, 172px);
  }

  /* Local chapter washes dissolve at their edges so the fixed painted world,
     not a horizontal colour band, performs the handoff. */
  .scroll-painting .contact-sheet::before,
  .scroll-painting .ordinary-days::before,
  .scroll-painting .letter::before,
  .scroll-painting .daybreak::before {
    -webkit-mask-image: linear-gradient(
      to bottom,
      transparent 0,
      #000 72px,
      #000 calc(100% - 88px),
      transparent 100%
    );
    mask-image: linear-gradient(
      to bottom,
      transparent 0,
      #000 72px,
      #000 calc(100% - 88px),
      transparent 100%
    );
  }
}

@keyframes mobile-scene-dissolve {
  0% {
    clip-path: ellipse(12% 8% at 50% 108%);
    opacity: 0;
    transform: translate3d(0, 16%, 0) scale(1.12);
  }
  34% {
    clip-path: ellipse(82% 58% at 50% 74%);
    opacity: 0.62;
  }
  58% {
    clip-path: ellipse(112% 84% at 50% 54%);
    opacity: 0.48;
    transform: translate3d(0, 0, 0) scale(1.02);
  }
  100% {
    clip-path: ellipse(142% 118% at 50% 24%);
    opacity: 0;
    transform: translate3d(0, -8%, 0) scale(1.08);
  }
}

@media (prefers-reduced-motion: reduce) and (max-width: 700px) {
  .scroll-painting.is-chapter-transitioning .scroll-transition i:first-child {
    animation: none !important;
    clip-path: none;
    opacity: 0.14;
    transform: none;
  }
}

@media (max-width: 380px) and (max-height: 700px) {
  .scroll-painting .contact-sheet {
    padding-bottom: 54px;
  }

  .scroll-painting .ordinary-days__layout {
    padding-top: 80px;
    padding-bottom: 96px;
  }

  .scroll-painting .letter {
    padding-top: 82px;
    padding-bottom: 56px;
  }

  .scroll-painting .daybreak__shell {
    padding-top: clamp(112px, 19svh, 138px);
  }
}

/* --------------------------------------------------------------------------
   一章一触 · the photograph moves; decoration no longer pretends to be motion
   -------------------------------------------------------------------------- */

/* Rain is now a handful of soft droplets. The illustrated window already
   carries its own weather, so a full-screen ruler of diagonal strokes only
   obscured the photograph. */
.scroll-painting .scene-flow__rain {
  inset: -10% -8%;
  background:
    radial-gradient(ellipse 3px 8px at 14% 18%, rgb(205 227 231 / 0.18), transparent 76%),
    radial-gradient(ellipse 2px 6px at 31% 67%, rgb(190 217 224 / 0.14), transparent 78%),
    radial-gradient(ellipse 3px 9px at 53% 31%, rgb(214 230 231 / 0.16), transparent 76%),
    radial-gradient(ellipse 2px 7px at 72% 76%, rgb(183 211 220 / 0.14), transparent 78%),
    radial-gradient(ellipse 3px 8px at 88% 44%, rgb(215 230 228 / 0.13), transparent 77%),
    radial-gradient(ellipse 34% 22% at 64% 42%, rgb(111 151 168 / 0.055), transparent 78%);
  mask-image: radial-gradient(ellipse 82% 76% at 54% 48%, #000 14%, transparent 86%);
  filter: blur(0.65px);
  transform: translate3d(0, -2%, 0);
}

.scroll-painting[data-chapter="02"] .scene-flow__rain {
  opacity: var(--scene-rain-opacity, 0.34);
  animation: painted-rain-drift 7.2s cubic-bezier(.45,0,.35,1) infinite alternate;
}

@keyframes painted-rain-drift {
  from { transform: translate3d(-0.8%, -2.2%, 0) scale(1.01); }
  to { transform: translate3d(0.9%, 2.4%, 0) scale(1.025); }
}

/* Long light rulers are replaced by breathing pools of light. */
.scroll-painting .scene-flow__moon-thread {
  border: 0;
  background: radial-gradient(ellipse, rgb(245 222 177 / 0.13), transparent 70%);
  filter: blur(18px);
}

.scroll-painting .scene-flow__paper {
  top: -8%;
  bottom: -8%;
  left: 24%;
  width: 54%;
  border-radius: 50%;
  background:
    radial-gradient(ellipse 48% 58% at 56% 48%, rgb(255 232 192 / 0.16), rgb(244 213 174 / 0.045) 48%, transparent 76%);
  filter: blur(24px);
  transform: translate3d(calc(var(--ambient-x, 0px) * 0.16), calc(var(--ambient-y, 0px) * 0.12), 0);
}

.scroll-painting[data-chapter="04"] .scene-flow__paper {
  opacity: 0.58;
  animation: painted-paper-breathe 8.8s cubic-bezier(.45,0,.35,1) infinite alternate;
}

@keyframes painted-paper-breathe {
  from { opacity: 0.42; transform: translate3d(-1.2%, 1%, 0) scale(0.98); }
  to { opacity: 0.68; transform: translate3d(1.4%, -1.2%, 0) scale(1.035); }
}

.scroll-painting .portrait-world__light {
  opacity: 0.34;
  background: radial-gradient(ellipse 42% 38% at 72% 40%, rgb(246 226 188 / 0.13), transparent 76%);
  transform: none;
  animation: painted-portrait-light 9.6s cubic-bezier(.45,0,.35,1) infinite alternate;
}

@keyframes painted-portrait-light {
  from { opacity: 0.2; transform: translate3d(-1%, 1%, 0) scale(0.98); }
  to { opacity: 0.42; transform: translate3d(1.4%, -1%, 0) scale(1.035); }
}

/* A touch leaves one watercolour bloom. No dashed orbit and no six rays. */
.scroll-painting .interaction-bloom i,
.scroll-painting .interaction-bloom::after {
  display: none !important;
}

.scroll-painting .interaction-bloom::before {
  width: clamp(180px, 28vw, 420px);
  aspect-ratio: 1.45 !important;
  border: 0 !important;
  border-radius: 48% 52% 46% 54% !important;
  background:
    radial-gradient(ellipse at 50% 50%, rgb(var(--bloom-rgb) / 0.17), rgb(var(--bloom-rgb) / 0.045) 42%, transparent 73%);
  box-shadow: none;
  filter: blur(2px);
}

.scroll-painting .interaction-bloom.is-visible::before {
  animation: painted-touch-bloom 1.42s cubic-bezier(.16,1,.3,1) both;
}

@keyframes painted-touch-bloom {
  0% { opacity: 0; transform: translate(-50%, -50%) scale(0.32) rotate(-2deg); }
  28% { opacity: 0.72; }
  100% { opacity: 0; transform: translate(-50%, -50%) scale(1.18) rotate(2deg); }
}

/* The existing light collector becomes one clear chapter gesture. It stays
   inside the narrative rather than floating as an unrelated app control. */
.scroll-painting .chapter-seal-slot {
  position: sticky;
  z-index: 71;
  top: calc(100svh - 122px);
  right: auto;
  width: min(238px, calc(100vw - 28px));
  height: 0;
  margin: 0 max(28px, 4vw) 0 auto;
  opacity: 1;
  pointer-events: none;
}

.scroll-painting .chapter-seal-slot.is-current {
  opacity: 1;
}

.scroll-painting .chapter-seal-slot .light-seed {
  position: absolute;
  inset: 0 0 auto auto;
  display: flex;
  width: min(238px, calc(100vw - 28px));
  min-width: 52px;
  min-height: 52px;
  align-items: center;
  gap: 11px;
  padding: 5px 15px 5px 6px;
  border: 1px solid rgb(var(--sky-b) / 0.3);
  border-radius: 999px 18px 18px 999px;
  color: rgb(247 230 211 / 0.92);
  background:
    linear-gradient(104deg, rgb(10 16 21 / 0.82), rgb(var(--sky-a) / 0.13) 72%, rgb(10 16 21 / 0.64));
  box-shadow:
    0 16px 50px rgb(0 0 0 / 0.24),
    0 0 38px rgb(var(--sky-a) / 0.075),
    inset 0 1px rgb(255 255 255 / 0.055);
  backdrop-filter: blur(14px) saturate(1.08);
  opacity: 0;
  overflow: hidden;
  transform: translate3d(10px, 0, 0);
  transition:
    width 680ms cubic-bezier(.16,1,.3,1),
    padding 680ms cubic-bezier(.16,1,.3,1),
    border-color 420ms ease,
    background 720ms ease,
    opacity 520ms ease,
    transform 620ms cubic-bezier(.16,1,.3,1);
}

.scroll-painting .chapter-seal-slot.is-current .light-seed {
  opacity: 0.96;
  pointer-events: auto;
  transform: none;
}

body.scroll-painting.is-moon-gate-unlocked:not(.moon-secret-is-open):not(.archive-is-open):not(.archive-door-visible):not(.is-time-holding):not(.is-time-held) .chapter-seal-slot.is-current #lightSeed {
  opacity: 0.96 !important;
  pointer-events: auto !important;
}

.scroll-painting .light-seed > i {
  position: relative;
  display: grid;
  width: 40px;
  height: 40px;
  flex: 0 0 40px;
  place-items: center;
  border: 1px solid rgb(202 125 109 / 0.44);
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 46%, rgb(205 126 108 / 0.18), transparent 67%);
  box-shadow: inset 0 0 18px rgb(195 104 92 / 0.08);
}

.scroll-painting .light-seed > i::before,
.scroll-painting .light-seed > i::after {
  display: none;
}

.scroll-painting .light-seed > i b {
  position: relative;
  z-index: 2;
  color: rgb(229 173 151 / 0.92);
  font-family: var(--serif);
  font-size: 0.8rem;
  font-weight: 500;
  line-height: 1;
}

.scroll-painting .light-seed > i span {
  position: absolute;
  inset: 6px;
  border: 1px solid rgb(201 118 103 / 0.26);
  border-radius: 46% 54% 48% 52%;
  opacity: 0.72;
  transform: rotate(7deg);
}

.scroll-painting .light-seed > span,
body.scroll-painting[data-chapter="03"] .light-seed > span,
body.scroll-painting[data-chapter="05"] .light-seed > span {
  position: static;
  display: grid;
  width: auto;
  max-width: 176px;
  min-width: 0;
  gap: 2px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  opacity: 1;
  overflow: hidden;
  pointer-events: none;
  text-align: left;
  transform: none;
  transition:
    max-width 620ms cubic-bezier(.16,1,.3,1),
    opacity 360ms ease,
    transform 520ms cubic-bezier(.16,1,.3,1);
}

.scroll-painting .light-seed.is-inviting > span,
.scroll-painting .light-seed.is-awake > span,
.scroll-painting .light-seed:hover > span,
.scroll-painting .light-seed:focus-visible > span {
  max-width: 176px;
  opacity: 1;
  transform: none;
}

.scroll-painting .light-seed small {
  font-size: 0.54rem;
  letter-spacing: 0.17em;
  opacity: 0.58;
  white-space: nowrap;
}

.scroll-painting .light-seed em {
  font-size: 0.76rem;
  letter-spacing: 0.055em;
  white-space: nowrap;
}

.scroll-painting .light-seed.is-inviting > i {
  animation: chapter-touch-invite 2.1s cubic-bezier(.45,0,.35,1) 2;
}

.scroll-painting .light-seed.is-awake > i span {
  animation: chapter-seal-answer 1.65s cubic-bezier(.16,1,.3,1) both;
}

.scroll-painting .light-seed.is-collected:not(.is-inviting):not(.is-awake):not(:hover):not(:focus-visible) {
  width: 52px;
  padding-right: 5px;
  border-color: rgb(201 128 111 / 0.35);
}

.scroll-painting .light-seed.is-collected:not(.is-inviting):not(.is-awake):not(:hover):not(:focus-visible) > span {
  max-width: 0;
  opacity: 0;
  transform: translateX(9px);
}

.scroll-painting .light-seed:hover,
.scroll-painting .light-seed:focus-visible,
.scroll-painting .light-seed.is-awake {
  width: min(238px, calc(100vw - 28px));
  border-color: rgb(var(--sky-b) / 0.52);
  transform: translate3d(0, -2px, 0);
}

body.scroll-painting[data-tone="day"] .chapter-seal-slot .light-seed {
  color: rgb(74 52 51 / 0.9);
  background: linear-gradient(104deg, rgb(252 242 225 / 0.88), rgb(229 190 166 / 0.34));
  box-shadow: 0 16px 44px rgb(91 60 53 / 0.12), inset 0 1px rgb(255 255 255 / 0.55);
}

body.scroll-painting[data-tone="ink"] .chapter-seal-slot .light-seed {
  border-color: rgb(128 73 64 / 0.24);
  color: rgb(75 55 52 / 0.9);
  background: linear-gradient(104deg, rgb(249 235 210 / 0.86), rgb(220 187 158 / 0.32));
  box-shadow: 0 16px 44px rgb(74 51 47 / 0.1), inset 0 1px rgb(255 255 255 / 0.48);
}

body.scroll-painting[data-tone="day"] .light-seed > i b {
  color: rgb(130 58 53 / 0.9);
}

body.scroll-painting[data-tone="ink"] .light-seed > i b {
  color: rgb(132 59 52 / 0.9);
}

@keyframes chapter-touch-invite {
  0%, 100% { box-shadow: inset 0 0 18px rgb(195 104 92 / 0.08); transform: scale(1); }
  48% { box-shadow: 0 0 28px rgb(var(--sky-b) / 0.22), inset 0 0 18px rgb(195 104 92 / 0.13); transform: scale(1.035); }
}

@keyframes chapter-seal-answer {
  0% { opacity: 0.5; transform: rotate(7deg) scale(0.72); }
  42% { opacity: 1; transform: rotate(-3deg) scale(1.14); }
  100% { opacity: 0.74; transform: rotate(7deg) scale(1); }
}

/* The chapter photographs themselves now breathe only while present. */
.scroll-painting .memory__scene .scene__photo,
.scroll-painting .puzzle-story__image,
.scroll-painting .photo-after__image {
  transform-origin: 50% 46%;
  will-change: auto;
}

.scroll-painting .memory.is-photo-present .memory__scene .scene__photo {
  animation: memory-photo-breathe 9.8s cubic-bezier(.45,0,.35,1) infinite alternate;
  will-change: transform;
}

.scroll-painting .memory:nth-child(even).is-photo-present .memory__scene .scene__photo {
  animation-name: memory-photo-breathe-reverse;
}

.scroll-painting .puzzle-story.is-photo-present .puzzle-story__frame.is-active .puzzle-story__image {
  animation: puzzle-photo-breathe 10.4s cubic-bezier(.45,0,.35,1) infinite alternate;
  will-change: transform;
}

.scroll-painting .photo-after__item.is-photo-present .photo-after__image {
  animation: keepsake-photo-breathe 10.8s cubic-bezier(.45,0,.35,1) infinite alternate;
  will-change: transform;
}

.scroll-painting .photo-after__item--2.is-photo-present .photo-after__image {
  animation-name: keepsake-photo-breathe-reverse;
}

.scroll-painting .photo-after__item.is-ink-awake .photo-after__image {
  animation: paper-photo-answer 2.6s cubic-bezier(.16,1,.3,1) both;
}

.scroll-painting .photo-after__item.is-cloud-awake .photo-after__image {
  animation: mountain-photo-answer 3.1s cubic-bezier(.16,1,.3,1) both;
}

@keyframes memory-photo-breathe {
  from { transform: translate3d(-0.45%, 0.2%, 0) scale(1.018); }
  to { transform: translate3d(0.55%, -0.35%, 0) scale(1.036); }
}

@keyframes memory-photo-breathe-reverse {
  from { transform: translate3d(0.5%, 0.25%, 0) scale(1.018); }
  to { transform: translate3d(-0.5%, -0.3%, 0) scale(1.034); }
}

@keyframes puzzle-photo-breathe {
  from { transform: translate3d(-0.35%, 0.2%, 0) scale(1.012); }
  to { transform: translate3d(0.45%, -0.28%, 0) scale(1.028); }
}

@keyframes keepsake-photo-breathe {
  from { transform: translate3d(-0.4%, 0.16%, 0) scale(1.012); }
  to { transform: translate3d(0.45%, -0.34%, 0) scale(1.027); }
}

@keyframes keepsake-photo-breathe-reverse {
  from { transform: translate3d(0.42%, 0.18%, 0) scale(1.012); }
  to { transform: translate3d(-0.46%, -0.4%, 0) scale(1.03); }
}

@keyframes paper-photo-answer {
  0% { transform: scale(1.012); }
  44% { transform: translate3d(0.35%, -0.4%, 0) scale(1.032); }
  100% { transform: scale(1.014); }
}

@keyframes mountain-photo-answer {
  0% { transform: scale(1.012); }
  46% { transform: translate3d(-0.5%, -0.8%, 0) scale(1.036); }
  100% { transform: translate3d(0.2%, -0.2%, 0) scale(1.015); }
}

/* Old developing scans, centre rulers and altitude ticks looked like beams. */
.scroll-painting .contact-sheet__thread,
.scroll-painting .memory__visual::before,
.scroll-painting .puzzle-story__visual::before,
.scroll-painting .photo-ritual__paper-sheen::before,
.scroll-painting .photo-ritual__paper-sheen::after,
.scroll-painting .mountain-ritual__scale-line,
.scroll-painting .mountain-ritual__marker-rule {
  display: none !important;
}

.scroll-painting .mountain-ritual__scale {
  top: 14%;
  right: 10px;
  width: auto;
  height: auto;
  opacity: 0.62;
  transform: none;
}

.scroll-painting .mountain-ritual__marker {
  position: static;
  transform: none;
}

.scroll-painting .mountain-ritual__marker-label {
  display: inline-flex;
  min-height: 24px;
  align-items: center;
  padding: 3px 7px;
  border: 1px solid rgb(243 224 205 / 0.2);
  border-radius: 999px;
  background: rgb(12 20 27 / 0.38);
  backdrop-filter: blur(7px);
}

@media (max-width: 700px) {
  .scroll-painting .portrait-world__light {
    display: none;
  }

  .scroll-painting[data-chapter="02"] .scene-flow__rain {
    opacity: var(--scene-rain-opacity, 0.2);
  }

  .scroll-painting .chapter-seal-slot {
    position: relative;
    top: auto;
    right: auto;
    width: min(224px, calc(100vw - 24px));
    height: 58px;
    margin: 74px 12px 0 auto;
  }

  body.scroll-painting.is-moon-gate-unlocked .chapter-seal-slot {
    top: auto;
  }

  .scroll-painting .chapter-seal-slot .light-seed,
  .scroll-painting .light-seed:hover,
  .scroll-painting .light-seed:focus-visible,
  .scroll-painting .light-seed.is-awake {
    width: min(224px, calc(100vw - 24px));
  }

  .scroll-painting .scene-ritual-hint {
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    border: 0;
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    opacity: 1;
    overflow: hidden;
    white-space: nowrap;
  }

  .scroll-painting .light-note {
    bottom: max(88px, calc(env(safe-area-inset-bottom) + 72px));
  }

  .scroll-painting .ordinary-days__layout {
    padding-top: 0;
  }

  .scroll-painting .letter {
    padding-top: 0;
  }

  .scroll-painting .daybreak__shell {
    padding-top: 0;
  }

  .scroll-painting .memory::before,
  .scroll-painting .memory::after,
  .scroll-painting .puzzle-story::after,
  .scroll-painting .photo-after__item::after {
    display: none;
  }

  .scroll-painting .mountain-ritual__depth::after {
    opacity: 0.22;
  }

  .scroll-painting .mountain-ritual__mist--front {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting[data-chapter="02"] .scene-flow__rain,
  .scroll-painting[data-chapter="04"] .scene-flow__paper,
  .scroll-painting .portrait-world__light,
  .scroll-painting .light-seed.is-inviting > i,
  .scroll-painting .light-seed.is-awake > i span,
  .scroll-painting .memory.is-photo-present .memory__scene .scene__photo,
  .scroll-painting .puzzle-story.is-photo-present .puzzle-story__frame.is-active .puzzle-story__image,
  .scroll-painting .photo-after__item.is-photo-present .photo-after__image,
  .scroll-painting .photo-after__item.is-ink-awake .photo-after__image,
  .scroll-painting .photo-after__item.is-cloud-awake .photo-after__image {
    animation: none !important;
  }

  .scroll-painting .memory__scene .scene__photo,
  .scroll-painting .puzzle-story__image,
  .scroll-painting .photo-after__image {
    transform: none !important;
    will-change: auto;
  }
}

body.is-data-saver.scroll-painting .memory__scene .scene__photo,
body.is-data-saver.scroll-painting .puzzle-story__image,
body.is-data-saver.scroll-painting .photo-after__image,
body.is-data-saver.scroll-painting .scene-flow__rain,
body.is-data-saver.scroll-painting .scene-flow__paper {
  animation: none !important;
  transform: none !important;
  will-change: auto;
}

/* --------------------------------------------------------------------------
   定曝光的慢镜头 · cinematic motion without flashes

   The previous layers all tried to answer the same touch.  This final grade
   gives the page one visual grammar: exposure stays still; pictures, mist and
   ink are allowed to move.  A click therefore feels like a camera leaning
   closer, never like a light being switched on.
   -------------------------------------------------------------------------- */

.scroll-painting > .scene-flow::before {
  position: absolute;
  z-index: 8;
  inset: 0;
  content: "";
  pointer-events: none;
  background:
    linear-gradient(180deg, rgb(3 7 15 / 0.18), transparent 18% 76%, rgb(3 7 15 / 0.24)),
    radial-gradient(ellipse 82% 72% at 50% 43%, transparent 42%, rgb(3 7 15 / 0.19) 100%);
}

/* No expanding wash, no radial flash and no bright chapter-transition ruler. */
.scroll-painting .interaction-bloom,
.scroll-painting > .scene-flow::after,
.scroll-painting .scroll-transition i,
.scroll-painting .scroll-transition b,
.scroll-painting .truth-tide__touch-ring,
.scroll-painting .threshold__halo::after {
  display: none !important;
  animation: none !important;
}

.scroll-painting .scroll-transition {
  display: block;
  background: rgb(5 8 14 / 0.16);
  mix-blend-mode: normal;
  opacity: 0;
  transition: opacity 720ms ease;
}

.scroll-painting.is-chapter-transitioning .scroll-transition {
  opacity: 0.12;
}

/* Ambient layers keep a constant exposure. Only their position and depth move. */
.scroll-painting .portrait-world__image {
  will-change: transform;
  animation: cinematic-portrait-camera 24s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting .portrait-world__ink {
  will-change: transform;
}

.scroll-painting .portrait-world__ink--one {
  opacity: 0.38;
  animation: cinematic-ink-drift-one 30s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting .portrait-world__ink--two {
  opacity: 0.24;
  animation: cinematic-ink-drift-two 36s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting .portrait-world__light {
  opacity: 0.18;
  animation: cinematic-portrait-haze 28s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting[data-chapter="01"] .scene__glow {
  opacity: 0.68;
  animation: cinematic-window-camera 18s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting[data-chapter="02"] .scene-flow__rain {
  opacity: var(--scene-rain-opacity, 0.28);
  animation: cinematic-rain-drift 14s linear infinite;
}

.scroll-painting[data-chapter="03"] .scene-flow__water {
  opacity: 0.48;
  animation: cinematic-water-drift 20s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting[data-chapter="04"] .scene-flow__paper {
  opacity: 0.46;
  animation: cinematic-paper-drift 24s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting[data-chapter="05"] .scene-flow__dawn {
  opacity: 0.58;
  animation: cinematic-dawn-drift 26s cubic-bezier(.45,0,.35,1) infinite alternate;
}

.scroll-painting .city-pair__mist,
.scroll-painting .city-pair.has-same-weather .city-pair__mist {
  opacity: 0.54;
  animation: cinematic-city-mist 24s cubic-bezier(.45,0,.35,1) infinite alternate;
  animation-play-state: paused;
}

@keyframes cinematic-portrait-camera {
  from { transform: translate3d(var(--portrait-shift-x), var(--portrait-shift-y), 0) scale(1.055); }
  to { transform: translate3d(calc(var(--portrait-shift-x) - 0.6%), calc(var(--portrait-shift-y) - 0.35%), 0) scale(1.073); }
}

@keyframes cinematic-ink-drift-one {
  from { transform: translate3d(-2%, 1%, 0) scale(0.98) rotate(-0.6deg); }
  to { transform: translate3d(2.5%, -1.5%, 0) scale(1.06) rotate(0.7deg); }
}

@keyframes cinematic-ink-drift-two {
  from { transform: translate3d(1.5%, -1.5%, 0) scale(0.95); }
  to { transform: translate3d(-2.5%, 2.5%, 0) scale(1.08); }
}

@keyframes cinematic-portrait-haze {
  from { transform: translate3d(-1.8%, 1%, 0) scale(0.99); }
  to { transform: translate3d(1.6%, -0.8%, 0) scale(1.035); }
}

@keyframes cinematic-window-camera {
  from { transform: translate3d(-1%, 0.5%, 0) scale(0.98); }
  to { transform: translate3d(1%, -0.6%, 0) scale(1.04); }
}

@keyframes cinematic-rain-drift {
  from { transform: translate3d(-0.7%, -2%, 0) scale(1.01); }
  to { transform: translate3d(0.8%, 2.2%, 0) scale(1.02); }
}

@keyframes cinematic-water-drift {
  from { transform: translate3d(-1.3%, 1.2%, 0) scale(1.02, 0.99); }
  to { transform: translate3d(1.4%, -0.7%, 0) scale(1.055, 1.015); }
}

@keyframes cinematic-paper-drift {
  from { transform: translate3d(-1.4%, 0.8%, 0) scale(0.99); }
  to { transform: translate3d(1.6%, -0.9%, 0) scale(1.035); }
}

@keyframes cinematic-dawn-drift {
  from { transform: translate3d(-1.2%, 0.8%, 0) scale(0.99); }
  to { transform: translate3d(1.2%, -0.7%, 0) scale(1.035); }
}

@keyframes cinematic-city-mist {
  from { transform: translate3d(-14px, 2px, 0) scale(1.01); }
  to { transform: translate3d(16px, -3px, 0) scale(1.035); }
}

/* The chapter seal responds like a real object pressed into paper. */
.scroll-painting .light-seed,
.scroll-painting .light-seed > i,
.scroll-painting .light-seed > i span {
  transition:
    transform 760ms cubic-bezier(.2,.72,.22,1),
    border-color 760ms ease,
    background-color 760ms ease,
    opacity 760ms ease;
}

.scroll-painting .light-seed.is-inviting > i,
.scroll-painting .light-seed.is-awake > i span {
  animation: none !important;
}

.scroll-painting .light-seed.is-inviting > i {
  transform: translate3d(2px, -1px, 0) rotate(-1.5deg);
}

.scroll-painting .light-seed.is-awake > i {
  transform: translate3d(0, 1px, 0) rotate(-2deg) scale(0.96);
}

.scroll-painting .light-seed.is-awake > i span {
  opacity: 0.72;
  transform: rotate(3deg) scale(0.98);
}

.scroll-painting .light-note {
  opacity: 0;
  transform: translate3d(-50%, 10px, 0);
  transition: opacity 980ms ease, transform 1200ms cubic-bezier(.2,.72,.22,1);
}

body.scroll-painting.is-light-note-visible .light-note {
  opacity: 0.9;
  transform: translate3d(-50%, 0, 0);
  animation: none !important;
}

/* The rain-window gesture clears condensation instead of drawing bright rings. */
.scroll-painting .scene-lens {
  border: 0;
  background: radial-gradient(ellipse, rgb(192 218 217 / 0.055), rgb(10 26 37 / 0.025) 62%, transparent 78%);
  box-shadow: none;
  backdrop-filter: blur(0.45px) saturate(1.04);
  transition: width 1200ms cubic-bezier(.2,.72,.22,1), opacity 900ms ease, transform 1200ms cubic-bezier(.2,.72,.22,1);
}

.scroll-painting .scene-lens::before,
.scroll-painting .scene-lens::after {
  display: none;
}

body.scroll-painting[data-chapter="02"].is-rain-wiping .scene-lens {
  opacity: 0.3;
}

body.scroll-painting[data-chapter="02"].is-rain-revealed .scene-lens {
  border: 0;
  opacity: 0.54;
  background: radial-gradient(ellipse, rgb(239 220 185 / 0.09), rgb(175 221 219 / 0.055) 48%, transparent 78%);
  box-shadow: none;
}

/* Small interactions use movement, ink and writing—not exposure pulses. */
.scroll-painting .film-frame.is-memory-warm .scene--window.has-photo .scene__trace::after {
  animation: cinematic-route-point 1.8s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .memory__visual.is-tap-warm::after {
  opacity: 0.14;
  transform: scale(1.012);
  animation: none !important;
  transition: opacity 900ms ease, transform 1200ms cubic-bezier(.2,.72,.22,1);
}

.scroll-painting .art-signal .signal-line {
  opacity: 0.46;
  animation: cinematic-signal 9s cubic-bezier(.45,0,.35,1) infinite alternate;
  animation-play-state: paused;
}

.scroll-painting .art-train .window-light {
  opacity: 0.2;
  animation: cinematic-passing-window 12s linear infinite;
}

.scroll-painting .ordinary-lines li.ordinary-ink--playing .ordinary-ink__period {
  opacity: 0.56;
  box-shadow: none;
  animation: none !important;
  transform: scale(0.74);
}

.scroll-painting .ordinary-lines li[data-ordinary-ink-ready="true"].ordinary-ink--playing::before {
  animation: cinematic-ink-gather 1.9s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .ordinary-days--ink-breathing .ordinary-days__wash::after {
  animation: cinematic-ink-wash 2.2s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .has-paper-ritual.is-ink-awake .photo-ritual__paper-sheen {
  opacity: 0.26;
  animation: none !important;
}

.scroll-painting .has-paper-ritual.is-ink-awake .photo-ritual__ink path {
  opacity: 0.66;
  animation: cinematic-paper-writing 2.5s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .has-mountain-ritual.is-cloud-awake .mountain-ritual__mist--back {
  opacity: 0.3;
  animation: cinematic-cloud-back 4.4s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .has-mountain-ritual.is-cloud-awake .mountain-ritual__mist--middle {
  opacity: 0.22;
  animation: cinematic-cloud-middle 4.6s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .has-mountain-ritual.is-cloud-awake .mountain-ritual__mist--front {
  opacity: 0.17;
  animation: cinematic-cloud-front 4.8s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .city-pair__handle-halo {
  opacity: 0.58;
  animation: cinematic-city-handle 8s cubic-bezier(.45,0,.35,1) infinite alternate;
  animation-play-state: paused;
}

.scroll-painting .city-pair.is-ritual-ready:not(.has-route-arrived) .city-pair__handle-halo {
  opacity: 0.64;
  animation: cinematic-city-handle 8s cubic-bezier(.45,0,.35,1) infinite alternate;
  animation-play-state: paused;
}

.scroll-painting[data-chapter="02"] .art-signal .signal-line,
.scroll-painting[data-chapter="05"] .city-pair__mist,
.scroll-painting[data-chapter="05"] .city-pair__handle-halo {
  animation-play-state: running;
}

.scroll-painting .city-pair.is-touch-connecting .city-pair__route-light--touch,
.scroll-painting .city-pair.has-same-weather .city-pair__route-light--outbound,
.scroll-painting .city-pair.has-same-weather .city-pair__route-light--return {
  opacity: 0.48;
  animation: cinematic-city-route 4.8s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .city-pair.has-same-weather::after {
  opacity: 0.22;
  animation: cinematic-city-meeting 4.8s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .chapter-seal-imprint {
  animation: cinematic-chapter-imprint 1.4s cubic-bezier(.2,.72,.22,1) both;
}

.scroll-painting .page-warmth-echo.is-visible {
  animation: cinematic-page-echo 2.8s cubic-bezier(.2,.72,.22,1) both;
}

body.scroll-painting.is-final-bloom .daybreak::before {
  animation: cinematic-final-sun 3.8s cubic-bezier(.2,.72,.22,1) both;
}

@keyframes cinematic-route-point {
  from { left: 0; opacity: 0.48; }
  to { left: calc(100% - 5px); opacity: 0.48; }
}

@keyframes cinematic-signal {
  from { transform: scaleX(0.78); }
  to { transform: scaleX(1); }
}

@keyframes cinematic-passing-window {
  from { transform: translateX(-12%) rotate(-5deg); }
  to { transform: translateX(96%) rotate(-5deg); }
}

@keyframes cinematic-ink-gather {
  from { opacity: 0.09; transform: translate3d(var(--ordinary-ink-drift), -50%, 0) scale3d(1.14, 0.5, 1); }
  to { opacity: 0.09; transform: translate3d(0, -50%, 0) scale3d(0.82, 0.72, 1); }
}

@keyframes cinematic-ink-wash {
  from { opacity: 0.055; transform: translate3d(-52%, -49%, 0) scale3d(1.1, 0.7, 1); }
  to { opacity: 0.055; transform: translate3d(-48%, -51%, 0) scale3d(0.82, 0.76, 1); }
}

@keyframes cinematic-paper-writing {
  from { opacity: 0.66; stroke-dashoffset: 132; }
  to { opacity: 0.66; stroke-dashoffset: 0; }
}

@keyframes cinematic-cloud-back {
  from { transform: translate3d(-9%, var(--mountain-back-y), 0); }
  to { transform: translate3d(2%, var(--mountain-back-y), 0); }
}

@keyframes cinematic-cloud-middle {
  from { transform: translate3d(8%, var(--mountain-middle-y), 0) scale(0.98); }
  to { transform: translate3d(-4%, var(--mountain-middle-y), 0) scale(1.02); }
}

@keyframes cinematic-cloud-front {
  from { transform: translate3d(-7%, var(--mountain-front-y), 0) scale(0.98); }
  to { transform: translate3d(3%, var(--mountain-front-y), 0) scale(1.02); }
}

@keyframes cinematic-city-handle {
  from { transform: scale(0.96); }
  to { transform: scale(1.035); }
}

@keyframes cinematic-city-route {
  from { opacity: 0.48; stroke-dashoffset: 102; }
  to { opacity: 0.48; stroke-dashoffset: -99; }
}

@keyframes cinematic-city-meeting {
  from { opacity: 0.22; transform: translate(-50%, -50%) scale(0.82); }
  to { opacity: 0.22; transform: translate(-50%, -50%) scale(1.18); }
}

@keyframes cinematic-chapter-imprint {
  from { opacity: 0.44; transform: translate(-50%, -50%) rotate(-5deg) scale(1.08); }
  to { opacity: 0.44; transform: translate(-50%, -62%) rotate(0) scale(1); }
}

@keyframes cinematic-page-echo {
  from { opacity: 0.38; transform: translate(-50%, 7px); }
  to { opacity: 0.58; transform: translate(-50%, -5px); }
}

@keyframes cinematic-final-sun {
  from { opacity: 0.44; transform: translate(-50%, 48px) scale(0.78); }
  to { opacity: 0.66; transform: translate(-50%, 0) scale(1); }
}

@media (max-width: 700px) {
  .scroll-painting > .scene-flow::before {
    background:
      linear-gradient(180deg, rgb(3 7 15 / 0.14), transparent 17% 74%, rgb(3 7 15 / 0.2)),
      radial-gradient(ellipse 96% 76% at 50% 38%, transparent 46%, rgb(3 7 15 / 0.16) 100%);
  }

  /* The painted portrait already contains rain. On phones the extra CSS rain
     would turn into ruler-like beams, so only the sparse Canvas weather stays. */
  .scroll-painting[data-chapter="02"] .scene-flow__rain {
    background: none !important;
    opacity: 0 !important;
    animation: none !important;
  }

  .scroll-painting .portrait-world__light {
    display: none;
  }

  .scroll-painting .scroll-transition {
    background: rgb(5 8 14 / 0.12);
  }

  .scroll-painting.is-chapter-transitioning .scroll-transition {
    opacity: 0.08;
  }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting .portrait-world__image,
  .scroll-painting .portrait-world__ink,
  .scroll-painting .portrait-world__light,
  .scroll-painting .scene__glow,
  .scroll-painting > .scene-flow > span,
  .scroll-painting .city-pair__mist,
  .scroll-painting .art-signal .signal-line,
  .scroll-painting .art-train .window-light,
  .scroll-painting .city-pair__handle-halo {
    animation: none !important;
  }
}

/* --------------------------------------------------------------------------
   Director's cut · the opening behaves like a title sequence, not a poster
   -------------------------------------------------------------------------- */

.scroll-painting .threshold__film-meta {
  display: grid;
  width: min(500px, 86vw);
  grid-template-columns: 1fr auto 1fr;
  gap: 16px;
  align-items: center;
  margin: 0 0 clamp(18px, 3.5vh, 34px);
  padding-bottom: 10px;
  border-bottom: 1px solid rgb(220 198 164 / 0.16);
  color: rgb(231 216 194 / 0.46);
  font-family: var(--sans);
  font-size: clamp(0.48rem, 0.65vw, 0.58rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  opacity: 0;
  animation: director-meta-enter 1.4s cubic-bezier(.2,.72,.22,1) 120ms both;
}

.scroll-painting .threshold__film-meta span:last-child {
  text-align: right;
}

.scroll-painting .threshold__film-meta time {
  min-width: 7.4em;
  color: rgb(235 194 133 / 0.68);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.13em;
  text-align: center;
}

.scroll-painting .threshold__title {
  white-space: normal;
}

.scroll-painting .threshold__title-line {
  display: block;
  width: fit-content;
  max-width: 23em;
  opacity: 0;
  filter: blur(8px);
  transform: translate3d(0, 20px, 0);
  animation: director-title-line 1.55s cubic-bezier(.16,1,.3,1) both;
  animation-delay: calc(360ms + var(--line-index, 0) * 760ms);
}

.scroll-painting .threshold__title-line:nth-child(2) {
  margin-left: clamp(8px, 1.8vw, 28px);
}

.scroll-painting .threshold__title-line:nth-child(3) {
  margin-left: clamp(18px, 3.2vw, 52px);
}

@keyframes director-meta-enter {
  from { opacity: 0; transform: translate3d(0, 8px, 0); }
  to { opacity: 1; transform: none; }
}

@keyframes director-title-line {
  0% { opacity: 0; filter: blur(8px); transform: translate3d(0, 20px, 0); }
  42% { opacity: 0.74; }
  100% { opacity: 1; filter: blur(0); transform: none; }
}

@media (max-width: 700px) {
  .scroll-painting .threshold__film-meta {
    width: 100%;
    gap: 8px;
    margin-bottom: 16px;
    font-size: 0.46rem;
    letter-spacing: 0.11em;
  }

  .scroll-painting .threshold__title-line,
  .scroll-painting .threshold__title-line:nth-child(2),
  .scroll-painting .threshold__title-line:nth-child(3) {
    width: auto;
    margin-left: 0;
  }
}

@media (max-width: 380px) and (max-height: 600px) {
  .scroll-painting .threshold__film-meta {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting .threshold__film-meta,
  .scroll-painting .threshold__title-line {
    opacity: 1;
    filter: none;
    transform: none;
    animation: none !important;
  }
}

body.is-data-saver.scroll-painting .threshold__film-meta,
body.is-data-saver.scroll-painting .threshold__title-line {
  opacity: 1;
  filter: none;
  transform: none;
  animation: none !important;
}

/* The film does not end on another control. After the route arrives, the
   interface leaves the frame for a few seconds and lets the last sentence
   breathe before navigation returns. */
.scroll-painting .site-chrome,
.scroll-painting .chapter-nav,
.scroll-painting .light-seed,
.scroll-painting .moon-gate,
.scroll-painting .memory-map-toggle,
.scroll-painting .city-weather {
  transition:
    opacity 1.15s cubic-bezier(.2,.72,.22,1),
    transform 1.25s cubic-bezier(.2,.72,.22,1),
    filter 1.15s ease;
}

body.scroll-painting.is-final-still .site-chrome,
body.scroll-painting.is-final-still .chapter-nav,
body.scroll-painting.is-final-still .light-seed,
body.scroll-painting.is-final-still .moon-gate,
body.scroll-painting.is-final-still .memory-map-toggle,
body.scroll-painting.is-final-still .city-weather {
  opacity: 0;
  filter: blur(7px);
  pointer-events: none;
  transform: translate3d(0, 10px, 0);
}

body.scroll-painting.is-final-still .daybreak__copy {
  opacity: 0.48;
  transition: opacity 1.6s ease;
}

body.scroll-painting.is-final-still .closing-after {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting .site-chrome,
  .scroll-painting .chapter-nav,
  .scroll-painting .light-seed,
  .scroll-painting .moon-gate,
  .scroll-painting .memory-map-toggle,
  .scroll-painting .city-weather {
    transition-duration: 1ms !important;
  }
}

/* --------------------------------------------------------------------------
   导演剪辑 · compact photographs, clean handoffs and deliberate line breaks

   This last layer only corrects composition. It does not add another visual
   effect system, so the existing painted motion remains the protagonist.
   -------------------------------------------------------------------------- */

@media (max-width: 700px) {
  /* A photograph may hold the eye, but it should not consume an entire phone
     frame. Full-height originals remain available through the photo viewer. */
  .scroll-painting .puzzle-story__visual {
    height: min(42svh, 370px);
    max-height: 370px;
    aspect-ratio: auto;
    overflow: hidden;
  }

  .scroll-painting .puzzle-story__frames,
  .scroll-painting .puzzle-story__frame {
    height: 100%;
    aspect-ratio: auto;
  }

  .scroll-painting .puzzle-story__image,
  .scroll-painting .photo-after__image,
  .scroll-painting .photo-after__item--2 .photo-after__image {
    width: 100%;
    height: min(42svh, 370px);
    max-height: 370px;
    aspect-ratio: auto;
    object-fit: cover;
  }

  .scroll-painting .puzzle-story__image {
    height: 100%;
    object-position: 50% 42%;
  }

  .scroll-painting .photo-after__item--1 .photo-after__image {
    object-position: 50% 50%;
  }

  .scroll-painting .photo-after__item--2 .photo-after__image {
    object-position: 50% 36%;
  }

  /* During the first handoff the outgoing invitation must leave completely;
     a clipped final line at the top of chapter two reads like a scroll bug. */
  body.scroll-painting[data-transition-from="01"][data-transition-to="02"].is-chapter-transitioning
    #first-frame > .chapter-bridge {
    visibility: hidden;
    opacity: 0 !important;
    transform: translate3d(0, -14px, 0);
    transition: opacity 220ms ease, transform 320ms cubic-bezier(.2,.72,.22,1);
  }

  /* The footer previously spent roughly 188px on margin and paper padding.
     Reducing both values by about thirty percent keeps the fold within the
     same emotional breath as the signature. */
  .scroll-painting .letter-body {
    padding-bottom: 52px;
  }

  .scroll-painting .letter-body__footer {
    margin-top: 80px;
  }
}

/* The source string already contains the intentional newline. On desktop,
   preserve it and size the second line so “生活。” can never orphan. */
@media (min-width: 901px) {
  .scroll-painting .daybreak__copy {
    grid-column: 2 / 10;
  }

  .scroll-painting .daybreak__copy h2 {
    width: max-content;
    max-width: none;
    font-size: clamp(3.8rem, 6.25vw, 7.5rem);
    white-space: pre;
    text-wrap: nowrap;
  }
}

/* Moonlit water does not cut directly to white paper. A shallow, low-exposure
   paper mist crosses the middle of frame, warming the image without a flash. */
body.scroll-painting[data-transition-from="03"][data-transition-to="04"].is-chapter-transitioning
  .scroll-transition {
  background:
    radial-gradient(ellipse 88% 18% at 50% 54%, rgb(244 224 194 / 0.5), transparent 72%),
    radial-gradient(ellipse 68% 34% at 58% 52%, rgb(177 128 112 / 0.16), transparent 78%),
    linear-gradient(180deg, transparent 31%, rgb(222 205 180 / 0.1) 50%, transparent 70%);
  mix-blend-mode: normal;
  animation: director-paper-mist-handoff 1.45s cubic-bezier(.2,.72,.22,1) both;
}

@keyframes director-paper-mist-handoff {
  0% {
    opacity: 0;
    transform: translate3d(0, 28px, 0) scale(1.025);
  }
  42% {
    opacity: 0.3;
  }
  100% {
    opacity: 0;
    transform: translate3d(0, -32px, 0) scale(1.07);
  }
}

@media (prefers-reduced-motion: reduce) {
  body.scroll-painting[data-transition-from="03"][data-transition-to="04"].is-chapter-transitioning
    .scroll-transition {
    opacity: 0.12;
    transform: none;
    animation: none !important;
  }
}

/* --------------------------------------------------------------------------
   苍山旧照 · the opening is composed from a real memory, not a fantasy poster
   -------------------------------------------------------------------------- */

.scroll-painting .portrait-world__image {
  right: auto;
  left: 4%;
  width: 108%;
  object-position: 50% 50%;
  filter: brightness(0.72) saturate(0.74) contrast(1.115) sepia(0.035);
  transform-origin: 64% 52%;
  mask-image: linear-gradient(90deg, transparent 0%, rgb(0 0 0 / 0.68) 5%, #000 12%, #000 100%);
  animation: cangshan-memory-camera 24s cubic-bezier(.45, 0, .35, 1) infinite alternate;
}

.scroll-painting .portrait-world::before {
  background:
    linear-gradient(90deg, rgb(3 8 18 / 0.96) 0%, rgb(3 8 18 / 0.88) 25%, rgb(3 8 18 / 0.63) 38%, rgb(3 8 18 / 0.16) 53%, transparent 68%),
    linear-gradient(180deg, rgb(3 8 18 / 0.22), transparent 48%, rgb(3 8 18 / 0.48));
}

.scroll-painting .portrait-world::after {
  background:
    radial-gradient(circle at var(--portrait-light-x) var(--portrait-light-y), rgb(226 197 153 / 0.085), transparent 15%),
    radial-gradient(ellipse 48% 72% at 73% 48%, transparent 42%, rgb(4 10 21 / 0.16) 78%, rgb(4 10 21 / 0.28));
  mix-blend-mode: normal;
}

.scroll-painting .portrait-world__ink--one {
  opacity: 0.18;
}

.scroll-painting .portrait-world__ink--two {
  opacity: 0.1;
}

.scroll-painting .portrait-world__light {
  opacity: 0.12;
  animation-duration: 32s;
}

@keyframes cangshan-memory-camera {
  from {
    transform: translate3d(var(--portrait-shift-x), var(--portrait-shift-y), 0) scale(1.018);
  }
  to {
    transform: translate3d(calc(var(--portrait-shift-x) - 0.35%), calc(var(--portrait-shift-y) - 0.22%), 0) scale(1.034);
  }
}

/* Text resolves quickly; the atmosphere can keep moving after the words are
   already readable. */
.scroll-painting .reveal:not(.is-visible) > .display-title,
.scroll-painting .reveal:not(.is-visible) > h2,
.scroll-painting .reveal:not(.is-visible) > h3,
.scroll-painting .reveal:not(.is-visible) h2,
.scroll-painting .reveal:not(.is-visible) h3 {
  filter: blur(3px);
  letter-spacing: 0.035em;
  transform: translate3d(0, 10px, 0);
}

.scroll-painting .reveal.is-visible > .display-title,
.scroll-painting .reveal.is-visible > h2,
.scroll-painting .reveal.is-visible > h3,
.scroll-painting .reveal.is-visible h2,
.scroll-painting .reveal.is-visible h3 {
  filter: none;
  letter-spacing: inherit;
  transform: none;
  transition:
    filter 420ms ease,
    letter-spacing 420ms ease,
    transform 420ms cubic-bezier(.2, .72, .22, 1);
}

.scroll-painting .threshold__title-line {
  filter: blur(3px);
  transform: translate3d(0, 10px, 0);
  animation-duration: 420ms;
}

@keyframes director-title-line {
  from {
    opacity: 0;
    filter: blur(3px);
    transform: translate3d(0, 10px, 0);
  }
  to {
    opacity: 1;
    filter: blur(0);
    transform: none;
  }
}

.scroll-painting .archive-door.reveal.is-visible h2 {
  transition:
    filter 420ms ease,
    transform 420ms cubic-bezier(.2, .72, .22, 1);
}

@media (max-width: 700px) {
  .scroll-painting .portrait-world__image {
    right: 0;
    left: 0;
    width: 100%;
    object-position: 50% 50%;
    filter: brightness(0.68) saturate(0.71) contrast(1.1) sepia(0.025);
    transform-origin: 50% 64%;
    mask-image: none;
    animation: cangshan-memory-camera-mobile 26s cubic-bezier(.45, 0, .35, 1) infinite alternate;
  }

  .scroll-painting .portrait-world::before {
    background:
      linear-gradient(180deg, rgb(3 8 18 / 0.84) 0%, rgb(3 8 18 / 0.58) 27%, rgb(3 8 18 / 0.2) 51%, rgb(3 8 18 / 0.5) 100%),
      linear-gradient(90deg, rgb(3 8 18 / 0.32), transparent 76%);
  }

  .scroll-painting .portrait-world__ink--one {
    opacity: 0.12;
  }

  .scroll-painting .portrait-world__ink--two {
    opacity: 0.06;
  }

  @keyframes cangshan-memory-camera-mobile {
    from {
      transform: translate3d(var(--portrait-shift-x), calc(var(--portrait-shift-y) + 0.35%), 0) scale(1.012);
    }
    to {
      transform: translate3d(calc(var(--portrait-shift-x) - 0.2%), calc(var(--portrait-shift-y) - 0.2%), 0) scale(1.026);
    }
  }
}

@media (prefers-reduced-motion: reduce) {
  .scroll-painting .portrait-world__image,
  .scroll-painting .threshold__title-line {
    filter: none;
    transform: none;
    animation: none !important;
  }
}
