/*
 * Homepage visual styles.
 *
 * Main artwork positions and animation measurements are configured in
 * ../data/homepage.json. CSS below supplies usable defaults before that JSON
 * loads, and defines typography, responsive behavior, and visual effects.
 */

@font-face {
  font-family: "F25 BlackletterTypewriter";
  src: url("../asset/F25-Blackletter-Typewriter/F25-BlackletterTypewriter.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "F25 BlackletterTypewriter";
  src: url("../asset/F25-Blackletter-Typewriter/F25-BlackletterTypewriter.woff2") format("woff2");
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

:root {
  color-scheme: dark;
  --font-english: "F25 BlackletterTypewriter", Georgia, "Times New Roman";
  --ink: #572a27;
  --ink-soft: #754b42;
  --gold: #d3b56b;
  --paper: #f4e5c5;
  --cover-width: min(90vw, 500px);
  --cover-top-padding: clamp(96px, 18svh, 160px);
  --kit-left: max(8px, calc((100vw - 560px) / 2 - 12px));
  --kit-bottom: max(8px, env(safe-area-inset-bottom));
  --kit-width: 116px;
  --kit-height: 100px;
  --ink-width: 56px;
  --ink-left: 2px;
  --quill-width: 75px;
  --quill-left: 42px;
  --quill-rotation: 23deg;
}

* {
  box-sizing: border-box;
}

html {
  min-height: 100%;
  background: #0e1220;
}

body {
  min-width: 320px;
  min-height: 100vh;
  min-height: 100svh;
  margin: 0;
  overflow-x: hidden;
  background: #0e1220;
  color: var(--ink);
  font-family: var(--font-english), "AaDeGuLaJian", "Songti SC", "STSong", serif;
}

/* Safari only delivers keydown to an editing host. Kept in the viewport so focus sticks. */
.key-catcher {
  position: fixed;
  z-index: 0;
  top: 0;
  left: 0;
  width: 2px;
  height: 2px;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0.01;
  outline: none;
  color: transparent;
  background: transparent;
  caret-color: transparent;
}

/*
 * Canvas is fixed to the viewport so the animated trail can cover the whole
 * screen without changing the page layout or blocking swipe input.
 */
.footstep-canvas {
  position: fixed;
  z-index: 5;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  transition: opacity 700ms ease;
}

.footstep-canvas.is-leaving {
  opacity: 0;
}

.page {
  position: fixed;
  z-index: 2;
  display: grid;
  inset: 0;
  place-items: center;
  overflow: hidden;
  padding: env(safe-area-inset-top) 0 env(safe-area-inset-bottom);
  /*
   * Stop the browser from treating a vertical gesture as page scrolling.
   * JavaScript listens for the same pointer/touch gesture to open the map.
   */
  touch-action: none;
  overscroll-behavior: none;
}

.page:focus {
  outline: none;
}

.cover {
  position: relative;
  isolation: isolate;
  display: flex;
  width: var(--cover-width);
  height: 100%;
  min-height: 0;
  flex-direction: column;
  align-items: center;
  padding: var(--cover-top-padding) 7% 6%;
  text-align: center;
}

.cover__content {
  position: relative;
  z-index: 1;
  display: flex;
  width: min(16rem, 78vw);
  flex: 0 0 auto;
  flex-direction: column;
  align-items: center;
  align-self: center;
  margin-top: clamp(92px, 16vh, 168px);
  transition: opacity 480ms ease, transform 620ms ease;
}

/*
 * Lines rise in by themselves, so a slow script cannot leave the parchment blank.
 * --line-fade and --line-interval match homepage.json.
 */
.cover__line {
  opacity: 1;
  animation: cover-line-in var(--line-fade, 1700ms) ease both;
}

.cover__content > .cover__line:nth-child(1) { animation-delay: 0s; }
.cover__content > .cover__line:nth-child(2) { animation-delay: calc(var(--line-interval, 1500ms) * 1); }
.cover__content > .cover__line:nth-child(3) { animation-delay: calc(var(--line-interval, 1500ms) * 2); }
.cover__content > .cover__line:nth-child(4) { animation-delay: calc(var(--line-interval, 1500ms) * 3); }
.cover__content > .cover__line:nth-child(5) { animation-delay: calc(var(--line-interval, 1500ms) * 4); }

@keyframes cover-line-in {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.cover__title-block {
  display: flex;
  width: 100%;
  flex-direction: column;
  align-items: center;
}

/* These elements fade and rise slightly while the map-opening transition runs. */
.page.is-opening .cover__content,
.page.is-opening .cover__line,
.page.is-opening .cover__actions {
  animation: none;
  opacity: 0;
  transform: translateY(-18px);
  transition: opacity 420ms ease, transform 620ms ease;
}

/*
 * Reverse of the map page's map-descend: the cover leaves off the top
 * on the same curve, revealing the star field underneath.
 */
.page.is-departing {
  animation: cover-leave 2000ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
  pointer-events: none;
}

@keyframes cover-leave {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(0, -100%, 0); }
}

/*
 * Paper and its decorative overlay fill the cover container.
 * To move/resize the paper artwork, edit imageLayout.cover in homepage.json.
 */
.cover__paper,
.cover__ornament,
.cover__ornament-clear {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.cover__paper {
  z-index: -3;
  object-fit: fill;
  filter: drop-shadow(0 18px 26px rgba(0, 0, 0, 0.38));
}

.cover__ornament {
  inset: auto;              /* 清除 top/right/bottom/left: 0 */
  top: 50%;
  left: 50%;
  width: 75%;
  height: auto;
  transform: translate(-50%, -50%);
  object-fit: contain;      /* 如果是 img */
  object-position: center;
}
/*
 * Soft paper-colored mask keeps the title area readable over the center
 * ornament. Its position and size are configurable in homepage.json.
 */
.cover__ornament-clear {
  z-index: -1;
  inset: 70% 21% auto;
  width: 48%;
  height: 12%;
  border-radius: 50%;
  background: rgba(244, 229, 197, 0.96);
  filter: blur(7px);
}

.cover__credit {
  max-width: 100%;
  margin: 0;
  color: var(--ink-soft);
  font-size: clamp(1.02rem, 3.6vw, 1.28rem);
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: 1.35;
  text-wrap: balance;
  text-shadow: 0 0 5px var(--paper), 0 0 9px var(--paper);
}

.cover__present {
  margin: 6px 0 0;
  color: var(--ink-soft);
  font-size: clamp(0.68rem, 2.3vw, 0.84rem);
  font-style: italic;
  letter-spacing: 0.03em;
  line-height: 1.35;
  text-align: center;
  text-wrap: balance;
  text-shadow: 0 0 5px var(--paper), 0 0 9px var(--paper);
}

.cover__divider {
  display: flex;
  width: 64%;
  align-items: center;
  gap: 10px;
  margin: 8px 0;
  color: #9d694b;
}

.cover__divider::before,
.cover__divider::after {
  height: 1px;
  flex: 1;
  content: "";
  background: currentColor;
  opacity: 0.75;
}

.cover__divider span {
  font-size: 0.78rem;
}

.cover__title {
  margin: 0;
  color: var(--ink);
  font-family: var(--font-english);
  font-size: clamp(1.45rem, 5.8vw, 2.05rem);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.2;
  text-align: center;
  text-shadow: 0 1px 0 rgba(255, 246, 222, 0.65);
}

.cover__bridge {
  margin: 8px 0 0;
  color: var(--ink-soft);
  font-size: clamp(0.82rem, 3vw, 1.05rem);
  font-style: italic;
  letter-spacing: 0.14em;
  text-shadow: 0 0 5px var(--paper), 0 0 9px var(--paper);
}

.cover__school {
  margin: 2px 0 0;
  color: var(--ink);
  font-size: clamp(0.92rem, 3.6vw, 1.28rem);
  letter-spacing: 0.04em;
  text-shadow: 0 0 5px var(--paper), 0 0 9px var(--paper);
}

.cover__actions {
  display: grid;
  width: 100%;
  justify-items: center;
  gap: 9px;
  margin-top: clamp(28px, 5svh, 52px);
  padding-top: 22px;
  opacity: 1;
  animation: cover-line-in 700ms ease calc(var(--line-interval, 1500ms) * 4 + var(--line-fade, 1700ms)) both;
  transition: opacity 700ms ease, transform 620ms ease;
}

.page.is-ready:not(.is-opening) .cover__actions {
  opacity: 1;
}

html.is-settled .cover__line,
html.is-settled .cover__actions {
  animation: none;
  opacity: 1;
  transform: none;
}

.swipe-hint {
  display: grid;
  justify-items: center;
  gap: 3px;
  min-height: 58px;
  color: var(--ink);
  text-shadow: 0 0 6px var(--paper), 0 0 11px var(--paper);
}

.swipe-hint__arrow {
  display: block;
  color: #81453b;
  font-family: "Segoe UI", sans-serif;
  font-size: 1.45rem;
  line-height: 1;
  animation: swipe-arrow 1.8s ease-in-out infinite;
}

.swipe-hint__label {
  font-size: clamp(0.9rem, 3.5vw, 1.05rem);
  font-weight: 700;
  letter-spacing: 0.16em;
}

.swipe-hint__caption {
  color: var(--ink-soft);
  font-family: var(--font-english);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.02em;
}

.swipe-hint__label--keys,
.swipe-hint__caption--keys {
  display: none;
}

/* A mouse or trackpad has no comfortable swipe, so the hint offers the keyboard. */
@media (hover: hover) and (pointer: fine) {
  .swipe-hint__arrow,
  .swipe-hint__label--touch,
  .swipe-hint__caption--touch {
    display: none;
  }

  .swipe-hint__label--keys,
  .swipe-hint__caption--keys {
    display: block;
  }
}

/*
 * Writing kit image placement and dimensions are controlled by
 * imageLayout.writingKit in homepage.json.
 */
.writing-kit {
  position: fixed;
  z-index: 6;
  bottom: var(--kit-bottom);
  left: var(--kit-left);
  width: var(--kit-width);
  height: var(--kit-height);
  pointer-events: none;
  transition: opacity 420ms ease, transform 700ms ease;
  animation: kit-float 6s ease-in-out infinite;
}

.writing-kit img {
  position: absolute;
  height: auto;
  object-fit: contain;
  filter: drop-shadow(0 8px 7px rgba(0, 0, 0, 0.27));
}

.writing-kit__ink {
  bottom: 0;
  left: var(--ink-left);
  width: var(--ink-width);
}

.writing-kit__quill {
  bottom: 4px;
  left: var(--quill-left);
  width: var(--quill-width);
  transform: rotate(var(--quill-rotation));
}

.writing-kit.is-leaving {
  opacity: 0;
  transform: translate(-35vw, 22vh) rotate(-22deg);
}

@keyframes kit-float {
  0%, 100% { transform: translate3d(0, 0, 0) rotate(-1deg); }
  50% { transform: translate3d(0, -8px, 0) rotate(1deg); }
}

@keyframes swipe-arrow {
  0%, 100% { opacity: 0.64; transform: translateY(4px); }
  50% { opacity: 1; transform: translateY(-3px); }
}

/* Desktop cover width and top spacing can be adjusted in homepage.json. */
@media (min-width: 600px) {
  .cover {
    width: var(--cover-width);
    padding: var(--cover-top-padding) 8% 6%;
  }

  .cover__actions {
    margin-top: clamp(20px, 3svh, 35px);
  }
}

/* The typewriter face is wider, so pull the cover copy up on a narrow parchment. */
@media (max-width: 599px) {
  .cover__content {
    margin-top: clamp(48px, 9vh, 88px);
  }

  .cover__actions {
    margin-top: clamp(12px, 2.5svh, 28px);
  }
}

/* Compress vertical gaps on short phones without hiding the swipe instruction. */
@media (max-height: 680px) {
  .cover {
    padding: 64px 7% 22px;
  }

  .cover__present {
    margin-top: 6px;
  }

  .cover__divider {
    margin: 7px 0;
  }

  .cover__bridge {
    margin-top: 6px;
  }

  .cover__school {
    margin-top: 2px;
  }

  .cover__actions {
    gap: 5px;
    margin-top: auto;
    padding-top: 8px;
  }

  .swipe-hint {
    min-height: 48px;
  }

  .swipe-hint__caption {
    font-size: 0.64rem;
  }
}

/*
 * The oath sits on the star field after the parchment has left.
 * Ink brown from the cover would disappear here, so the same faces are drawn in gold.
 */
.oath {
  position: fixed;
  z-index: 4;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(36px, 7vh, 72px);
  padding:
    calc(env(safe-area-inset-top) + 24px)
    8vw
    calc(env(safe-area-inset-bottom) + 24px);
  touch-action: none;
}

.oath[hidden] {
  display: none;
}

.oath__line {
  max-width: min(92vw, 24rem);
  margin: 0;
  color: var(--gold);
  font-family: var(--font-english);
  font-size: clamp(2.85rem, 12.5vw, 4.35rem);
  font-weight: 400;
  letter-spacing: 0;
  line-height: 2.05;
  text-align: center;
  text-wrap: balance;
  text-shadow: 0 0 18px rgba(8, 10, 18, 0.92), 0 2px 8px rgba(0, 0, 0, 0.45);
  animation: oath-in 900ms ease both;
}

.oath__word {
  display: inline-block;
  margin: 0.06em 0.02em;
  animation: oath-float var(--float-duration, 2.8s) ease-in-out var(--float-delay, 0s) infinite;
}

.oath__hint {
  opacity: 0;
}

.oath.is-ready .oath__hint {
  opacity: 1;
  animation: oath-in 700ms ease both;
}

.oath .swipe-hint {
  color: var(--gold);
  text-shadow: 0 0 12px rgba(8, 10, 18, 0.85);
}

.oath .swipe-hint__arrow,
.oath .swipe-hint__caption {
  color: var(--gold);
}

.oath.is-leaving {
  opacity: 0;
  transition: opacity 420ms ease;
}

@keyframes oath-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes oath-float {
  0%, 100% { transform: translate3d(0, var(--float, 0.35em), 0); }
  50% { transform: translate3d(0, calc(var(--float, 0.35em) * -1), 0); }
}

@media (min-width: 600px) {
  .oath__line {
    max-width: min(84vw, 62rem);
    font-size: clamp(4.4rem, 7.2vw, 6.5rem);
  }
}

@media (max-height: 680px) {
  .oath {
    gap: 22px;
  }

  .oath__line {
    font-size: clamp(2.35rem, 9vw, 3.4rem);
  }
}

/* Honor the device accessibility preference to reduce animation. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
