/* The journey: Part Three. Deep jade, unadministered air. The letter, the flight off the map,
   Potalaka, the interview conducted without writing, and the Peach Garden at night. */

.jr-head { padding-left: var(--gutter); padding-right: var(--gutter); }   /* .room-head's padding shorthand overrides .wrap's gutter */
.jr-head .lede { max-width: 40rem; }
/* Labels break into even lines (a chapter number never stands alone on the last one). */
main .label { text-wrap: balance; }

/* ------------------------------------------------------------------ the letter */
.jr-letter { overflow: hidden; }
.jr-letter .section-title { margin: .8rem 0 1.2rem; max-width: 14ch; }
.jr-letter-note { margin-top: 1rem; color: var(--fg-2); }
/* The letter on Wei's desk, one sheet folded in quarters under the jade seal: the painting
   (SCENES["journey-letter"]), and over it the clip made from it (journey.js), which fills the
   painting's width with a sliver cropped from its top. Once the clip has unfolded the sheet, the
   word is written on it in ink, laid on the sheet's own plane. */
.letter { display: grid; justify-items: center; gap: 1.4rem; }
.letter-stage {
  position: relative; width: 100%; max-width: 40rem; aspect-ratio: 4 / 3; overflow: hidden; isolation: isolate;
  background: #3a2c1c; box-shadow: 0 34px 70px -28px rgba(0, 0, 0, .7), 0 0 0 1px rgba(226, 242, 236, .1);
}
.letter-stage::after { content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none; box-shadow: inset 0 0 0 1px rgba(26, 24, 16, .2), inset 0 0 60px rgba(20, 14, 6, .22); }
/* The whole painting; on a phone, closer to the desk (the lamp, the letter and both halves of the
   seal stay in view). */
.letter-frame { position: absolute; left: 0; top: 0; width: 100%; height: 100%; container-type: inline-size; }
@media (max-width: 600px) { .letter-frame { width: 140%; height: 140%; left: -12%; top: -40%; } }
.letter-painting { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.letter-clip { position: absolute; left: 0; top: .2415%; width: 100%; height: 99.64%; }
.letter-clip video, .letter-opened { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: fill; opacity: 0; transition: opacity .6s var(--ease-ink); }
.letter-stage.is-playing .letter-clip video { opacity: 1; transition-duration: .3s; }
.letter-stage.is-open .letter-opened, .no-js .letter-opened { opacity: 1; }
/* The word, in ink, centred on the unfolded sheet. Without JavaScript it is set there by eye (the
   same centre, width and lean); the script lays it on the sheet's plane exactly (is-mapped) and
   writes it in from the left once the sheet is open. */
.letter-word {
  position: absolute; left: 43.2%; top: 80.1%; z-index: 2; white-space: nowrap; line-height: 1;
  font-family: var(--f-body); font-style: italic; font-weight: 460; font-size: 1.1rem; font-size: 4.95cqw;
  font-variation-settings: "opsz" 28; letter-spacing: -.01em; color: #211a12; mix-blend-mode: multiply;
  text-shadow: 0 0 .04em rgba(33, 26, 18, .45);
  transform: translate(-50%, -50%) rotate(-1.7deg) skewX(7.4deg) scaleY(.48);
}
.letter-word.is-mapped { left: 0; top: 0; transform-origin: 0 0; }   /* font size and transform: journey.js */
.js .letter-word { opacity: 0; }
.js .letter-stage.is-written .letter-word {
  opacity: .92; animation: ink-write 1.5s var(--ease-ink) both;
  -webkit-mask-image: linear-gradient(90deg, #000 42%, transparent 58%); mask-image: linear-gradient(90deg, #000 42%, transparent 58%);
  -webkit-mask-size: 260% 100%; mask-size: 260% 100%; -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
}
@keyframes ink-write {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; filter: blur(1.4px); }
  to { -webkit-mask-position: 0 0; mask-position: 0 0; filter: blur(0); }
}
/* Once open, "Seal it again" is an ordinary outlined button (its edge still 3:1 on the jade). */
.letter-btn[aria-pressed="true"] { background: transparent; color: var(--fg); border-color: color-mix(in srgb, var(--fg) 45%, transparent); }
.letter-btn[aria-pressed="true"]:hover { border-color: var(--fg); background: color-mix(in srgb, var(--fg) 8%, transparent); }

/* ------------------------------------------------------------------ the flight
   Five paintings on one canvas (journey.js): the Court as a map, its edge, unadministered air,
   Five Elements Mountain, the descent to Potalaka. The vignette and the HUD sit above it. */
.flight { position: relative; height: 560vh; }
.flight-view { position: sticky; top: 0; height: 100vh; height: 100svh; overflow: hidden; background: #e6dec8; }
.flight-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.flight-view::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: radial-gradient(125% 95% at 50% 46%, transparent 58%, rgba(40, 32, 14, .24) 100%),
              linear-gradient(180deg, rgba(236, 230, 214, .38), transparent calc(var(--masthead-h) + 5rem));
}
.flight-hud {
  position: absolute; z-index: 3; top: calc(var(--masthead-h) + 1rem); left: var(--gutter); right: var(--gutter);
  display: flex; justify-content: space-between; gap: 1rem; pointer-events: none;
}
.flight-hud .label { color: #2a2820; text-shadow: 0 0 10px rgba(240, 235, 222, .95), 0 0 3px rgba(240, 235, 222, .9); }
.flight-wind { display: inline-flex; align-items: center; gap: .5rem; }
.flight-wind-dot { width: .5rem; height: .5rem; border-radius: 50%; background: currentColor; transition: transform .3s; }
.flight-wind-dot.is-gust { animation: gust .9s var(--ease-ink); }
@keyframes gust { 30% { transform: scale(2.2); } }
.flight-captions { position: relative; }
.js .flight-captions { position: absolute; z-index: 4; left: 0; right: 0; bottom: 0; height: 0; }
.flight-card {
  margin: 0; max-width: 30rem; padding: 1.1rem 1.25rem 1.2rem; color: var(--ink);
  background: rgba(240, 238, 232, .88); border-left: 2px solid var(--gold-5);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.flight-card .label { color: var(--ink-5); margin-bottom: .5rem; }
.flight-line { margin: 0; font-size: var(--step-1); line-height: 1.38; font-variation-settings: "opsz" 30; }
.flight-thought { margin: .7rem 0 0; color: var(--ink-3); font-size: 1rem; }
.flight-line, .flight-thought, .jr-letter .prose, .jr-island .prose p, .interview-intro, .record-note, .garden .prose p, .voice-after { text-wrap: pretty; }
.flight-card .wei-mark { font-style: italic; }
.js .flight-card {
  position: absolute; left: var(--gutter); bottom: clamp(1.5rem, 7vh, 4rem); width: min(30rem, calc(100vw - 2 * var(--gutter)));
  opacity: 0; transform: translateY(16px); transition: opacity .7s var(--ease-ink), transform .9s var(--ease-ink); pointer-events: none;
}
.js .flight-card.is-shown { opacity: 1; transform: none; }
.js .flight-card { box-shadow: 0 18px 40px -24px rgba(40, 32, 14, .55); }
.js .flight-card.is-dark { background: rgba(229, 238, 232, .88); border-left-color: var(--jade-3); }   /* past the map: silk gone jade */
.js .flight-card.is-dark .label { color: var(--jade-2); }
/* Without JavaScript: the Court as a map, still, and the captions beneath it. */
.no-js .flight { height: auto; padding: 0 0 4rem; }
.no-js .flight-view { position: relative; height: min(80vh, 56.25vw); background: #e6dec8 var(--flight-still) 50% 50% / cover no-repeat; }
@media (max-width: 700px) { .no-js .flight-view { height: 72vw; } }
.no-js .flight-canvas, .no-js .flight-hud { display: none; }
.no-js .flight-captions { display: grid; gap: 1.5rem; padding: 2.5rem var(--gutter) 0; }

/* ------------------------------------------------------------------ Potalaka */
.jr-island { position: relative; isolation: isolate; overflow: hidden; }
.jr-island .ink-field { opacity: .55; }
.jr-island .section-title { margin: .8rem 0 1.3rem; max-width: 14ch; }
.jr-outside { font-size: var(--step-1); font-style: italic; margin: 1.4rem 0; }
/* The steps: a hanging-scroll window on the painting, climbed as the page scrolls (journey.js). */
.steps {
  --h: min(76vh, 44rem);
  position: relative; margin: 0; align-self: center; justify-self: center;
  width: min(100%, calc(var(--h) * .75)); aspect-ratio: 3 / 4; overflow: hidden;
  background: #e2d9c1 var(--steps-still) 47% 50% / cover no-repeat;
  box-shadow: 0 34px 70px -28px rgba(0, 0, 0, .7), 0 0 0 1px rgba(226, 242, 236, .1);
}
.js .steps { background-image: none; }
.steps-canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.steps::after { content: ""; position: absolute; inset: 0; pointer-events: none; box-shadow: inset 0 0 0 1px rgba(26, 24, 16, .18), inset 0 0 60px rgba(40, 32, 14, .18); }

/* ------------------------------------------------------------------ the interview */
.interview {
  position: relative; isolation: isolate; min-height: 100vh; padding: clamp(4rem, 12vh, 7rem) 0;
  background: radial-gradient(120% 90% at 70% 40%, #0d4231 0%, #0a3828 45%, #06261b 100%);
  border-top: 1px solid var(--rule); border-bottom: 1px solid var(--rule);
}
.interview-ink { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; pointer-events: none; }
.interview-grid { position: relative; z-index: 1; display: grid; grid-template-columns: minmax(0, .8fr) minmax(0, 1.2fr); gap: clamp(2rem, 6vw, 6rem); align-items: start; }
@media (max-width: 900px) { .interview-grid { grid-template-columns: 1fr; } }
.interview .section-title { margin: .8rem 0 1.2rem; }
.interview-intro { color: var(--fg-2); }
.interview-rule { font-size: 1rem; color: var(--fg); border-left: 2px solid var(--jade); padding-left: 1rem; }
.kit { margin: 1.6rem 0 1.2rem; max-width: 22rem; }
.kit-svg { width: 100%; height: auto; overflow: visible; }
.kit-table { fill: #1e3e33; }
.kit-notebook rect { fill: #d8d2c2; stroke: #8b8470; }
.kit-notebook path { stroke: #9a927e; stroke-width: 1.5; }
.kit-inkstone ellipse { fill: #15201c; stroke: #30473f; }
.kit-inkstone .kit-well { fill: #0c1411; stroke: none; }
.kit-shaft { fill: #7a5a34; }
.kit-tip { fill: #1a1810; }
.kit-brush { transform-box: fill-box; transform-origin: 50% 50%; transform: translate(118px, -34px) rotate(26deg); transition: transform 1.4s var(--ease-seal); }
.interview.is-listening .kit-brush, .interview.is-done .kit-brush { transform: translate(24px, 41px) rotate(-90deg); }
.interview:not(.is-listening):not(.is-done) .interview-grid { cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28' viewBox='0 0 28 28'%3E%3Cpath d='M22 2 L26 6 L10 22 L6 18 Z' fill='%237a5a34'/%3E%3Cpath d='M6 18 L10 22 Q5 27 2 26 Q1 23 6 18 Z' fill='%23e2f2ec'/%3E%3C/svg%3E") 2 26, auto; }
.interview-controls { display: flex; flex-wrap: wrap; gap: .6rem; margin: 1rem 0; }
.stillness { position: relative; height: 2px; max-width: 22rem; background: rgba(226, 242, 236, .12); overflow: hidden; }
.stillness-fill { position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--still, 0) * 100%); background: var(--jade); box-shadow: 0 0 10px var(--jade); }
.interview-state { margin-top: .8rem; min-height: 1.4em; }

.interview-open { margin: 0 0 2.2rem; font-style: italic; color: #f0f8f5; }
.interview-who { font-style: normal; font-size: 1rem; color: var(--fg-2); font-family: var(--f-body); }
.exchanges { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.6rem; }
.ex p { margin: 0 0 .5rem; max-width: 36rem; }
.ex .label { display: block; margin-bottom: .25rem; color: #7fae9f; }
.ex-q { color: var(--fg-2); font-size: 1.05rem; }
.ex-a { font-size: var(--step-1); line-height: 1.42; color: #eef8f4; font-variation-settings: "opsz" 28; }
.ex-n { font-style: italic; color: #a9cfc3; font-size: 1rem; }
.ex--recognition .ex-a { font-size: var(--step-2); line-height: 1.25; }
.ex-q--looked { font-size: var(--step-1); line-height: 1.4; color: #f4e9d6; }
.js .ex { display: none; }
.js .ex.is-said { display: block; animation: ex-in 1.1s var(--ease-ink) both; }
/* Earlier exchanges recede by their ink, not by fading out: they stay readable (4.5:1 and more on
   the jade), and come back to full ink under the pointer or focus. */
.ex p { transition: color 1.2s var(--ease-ink); }
.js .ex.is-past .ex-a { color: #b4cfc6; }
.js .ex.is-past .ex-q, .js .ex.is-past .ex-n { color: #93b9ad; }
.js .ex.is-past:hover .ex-a, .js .ex.is-past:focus-within .ex-a { color: #eef8f4; }
.js .ex.is-past:hover .ex-q, .js .ex.is-past:focus-within .ex-q { color: var(--fg-2); }
.js .ex.is-past:hover .ex-n, .js .ex.is-past:focus-within .ex-n { color: #a9cfc3; }
@keyframes ex-in { from { opacity: 0; transform: translateY(10px); } }
.ex .w { opacity: 0; filter: blur(4px); transition: opacity .7s var(--ease-ink), filter .9s var(--ease-ink); }
.ex .w.is-formed { opacity: 1; filter: none; }
.interview.is-disturbed .ex.is-forming .w.is-formed { opacity: .38; filter: blur(1.5px); }
.interview.is-disturbed .ex.is-forming { transition: none; }
.record {
  margin-top: 2.6rem; padding: 1.4rem 1.4rem 1.2rem; max-width: 30rem; border: 1px solid rgba(226, 242, 236, .25);
  background: rgba(6, 30, 22, .6); animation: ex-in 1.4s var(--ease-ink) both;
}
.record-line { font-size: var(--step-2); line-height: 1.2; margin: .4rem 0 .4rem; color: #f4e9d6; }
.record-time { font-family: var(--f-mono); font-size: .85rem; letter-spacing: .06em; color: var(--jade); }
.record-note { color: var(--fg-2); font-style: italic; }
.record-small { font-size: .85rem; color: var(--muted); }
.interview.is-all .ex { display: block; }
.interview.is-all .ex .w { opacity: 1; filter: none; }
/* The whole interview, once it is over: every exchange in full ink. */
.interview.is-all .ex.is-past .ex-a, .interview.is-done .ex.is-past .ex-a { color: #eef8f4; }
.interview.is-all .ex.is-past .ex-q, .interview.is-done .ex.is-past .ex-q { color: var(--fg-2); }
.interview.is-all .ex.is-past .ex-n, .interview.is-done .ex.is-past .ex-n { color: #a9cfc3; }

/* ------------------------------------------------------------------ the Peach Garden at night
   The painting spans the top of the section (journey.js paints it, lantern and ghost fruit on a
   second canvas). Wide: the words and the voice note down the dark side, the tree beside them.
   Narrow: the tree above the words. */
.garden { --pad: clamp(4rem, 12vh, 8rem); position: relative; isolation: isolate; min-height: 110vh; padding: var(--pad) 0; overflow: hidden; background: #03100b; }
.garden-canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; touch-action: pan-y; opacity: 0; transition: opacity 1.6s var(--ease-ink); }
.garden-canvas.is-painted { opacity: 1; }
.garden-glow { position: absolute; left: 0; top: 0; width: 100%; height: 56.25vw; z-index: 0; pointer-events: none; }
.garden-grid { position: relative; z-index: 1; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .9fr); gap: clamp(2rem, 6vw, 6rem); pointer-events: none; }
.garden-grid a, .garden-grid button, .garden-grid .prose, .garden-grid blockquote { pointer-events: auto; }
@media (min-width: 901px) {
  .garden-grid { grid-template-columns: minmax(0, .95fr) minmax(0, 1fr); row-gap: clamp(2.5rem, 7vh, 4.5rem); }
  .garden-copy { grid-column: 1; grid-row: 1; }
  .voice-note { grid-column: 1; grid-row: 2; }
}
@media (max-width: 900px) { .garden-grid { grid-template-columns: 1fr; } .garden { padding-top: min(30rem, 118vw); } }
.no-js .garden {
  background: linear-gradient(180deg, rgba(3, 16, 11, 0) 45vw, #03100b 56.25vw) no-repeat,
              #03100b var(--garden-still) 50% 0 / 100% auto no-repeat;
}
@media (max-width: 900px) {
  .no-js .garden {
    background: linear-gradient(180deg, rgba(3, 16, 11, 0) min(24rem, 94vw), #03100b calc(min(30rem, 118vw) + 3.5rem)) no-repeat,
                #03100b var(--garden-still) 63% 0 / auto calc(min(30rem, 118vw) + 3.5rem) no-repeat;
  }
}
.garden-copy { max-width: 32rem; }
.garden .section-title { margin: .8rem 0 1.2rem; color: #f0f5ee; }
.garden .prose { text-shadow: 0 1px 12px rgba(2, 10, 7, .9); }
.fruit-keys { margin-top: 2rem; }
.fruit-keys .label { margin-bottom: .6rem; }
.fruit-btn { background: rgba(4, 18, 13, .7); }
.fruit-dot { width: .7rem; height: .7rem; border-radius: 50%; display: inline-block; }
.fruit-dot--3 { background: #dfe9e4; box-shadow: 0 0 8px #dfe9e4; }
.fruit-dot--6 { background: #e8b838; box-shadow: 0 0 8px #e8b838; }
.fruit-dot--9 { background: #f8d050; box-shadow: 0 0 14px #fff2b0; }
.fruit-caption { margin-top: 1rem; min-height: 3.2em; font-size: 1rem; color: #cfe3da; text-shadow: 0 1px 10px #04120d; }
.voice-note { margin: 0; align-self: start; padding: 1.4rem; background: rgba(3, 16, 11, .8); border-left: 2px solid var(--ink-amber); backdrop-filter: blur(4px); pointer-events: auto; }
@media (max-width: 900px) { .voice-note { align-self: end; } }
.voice-note blockquote { margin: .6rem 0 1rem; font-style: italic; }
.voice-first { font-size: 1.05rem; }
.voice-after { color: var(--fg-2); font-size: 1rem; }

@media (prefers-reduced-motion: reduce) {
  .letter-clip video, .letter-opened { transition: none; }
  .js .letter-stage.is-written .letter-word { animation: none; -webkit-mask-image: none; mask-image: none; }
  .ex .w { transition: none; }
}
@media (max-width: 560px) {
  .flight-hud { flex-direction: column; gap: .3rem; }
  .flight { height: 480vh; }
}

.interview-open .label { display: block; margin-bottom: .4rem; font-style: normal; }
