/* Ceremony layer — 2026-10-15 (OWNER_APPROVED_ADAPTATION of presentation).
 *
 * Short authored moments over a screen: entering a gate, a catch landing on
 * the card, the hunt's reward, a title medal, a new form, the battle opening.
 * Runner: presentation/ceremony/ceremonyRunner.js. Spec and timing table:
 * docs/reports/ui-ceremony-2026-10-15/SPEC_ZH_TW.md.
 *
 * THE ONE RULE THAT MAKES SKIPPING SAFE
 * Every animated part's static style is its FINAL state; its keyframes only
 * say where it comes from (`animation-fill-mode: backwards`). Settling a run
 * (a tap, a hidden tab, reduced motion) is therefore `animation: none` on the
 * parts, and the composition is always whole.
 *
 * Motion only animates transform and opacity (compositor-only). Nothing loops
 * forever. Colours are tokens, so every theme dresses the same choreography.
 */

/* ---- Run container ------------------------------------------------------ */
.cm-ceremony {
  position: absolute;
  inset: 0;
  z-index: var(--z-toast);
  display: grid;
  place-items: center;
  pointer-events: none;
  overflow: hidden;
  contain: layout paint;
}
.cm-ceremony[data-tier="moment"],
.cm-ceremony[data-tier="reveal"] { z-index: var(--z-lifecycle); pointer-events: auto; cursor: pointer; }
/* The veil a moment lays over the screen: the theme's own ground, so a light
   theme stays light and a dark one stays dark. */
.cm-ceremony { --cer-veil: color-mix(in srgb, var(--c-ground) 80%, transparent); }
.cm-ceremony__stage { position: relative; display: grid; place-items: center; width: 100%; height: 100%; }
/* (0,3,0): above every per-ceremony part rule below, so settling always wins. */
.cm-ceremony:is([data-state="settled"], [data-state="leaving"]) .cm-ceremony__stage * { animation: none; }
.cm-ceremony[data-state="leaving"] { animation: cm-cer-leave 260ms var(--ease-in-out) forwards; pointer-events: none; }
.cm-ceremony[data-motion="reduced"] { animation: cm-cer-fade 160ms linear backwards; }
.cm-ceremony[data-motion="reduced"] .cm-ceremony__stage * { animation: none; }
/* Saver: the same words without the decoration. */
.cm-ceremony[data-motion="saver"] :is(.cm-ceremony__spark, .cm-cer-rays, .cm-cer-ring--b, .cm-cer-ring--c) { display: none; }
.cm-ceremony[data-motion="reduced"] :is(.cm-ceremony__spark, .cm-cer-ring) { display: none; }

@keyframes cm-cer-fade { from { opacity: 0; } }
@keyframes cm-cer-fade-out { to { opacity: 0; } }
@keyframes cm-cer-leave { to { opacity: 0; transform: scale(1.03); } }
@keyframes cm-cer-pop { from { opacity: 0; transform: translateY(10px) scale(0.86); } }
@keyframes cm-cer-rise { from { opacity: 0; transform: translateY(14px); } }
@keyframes cm-cer-drop { 0% { opacity: 0; transform: translateY(-28px) scale(0.9); } 60% { opacity: 1; transform: translateY(4px) scale(1.02); } }
@keyframes cm-cer-ring { from { opacity: 0.9; transform: scale(0.25); } }
@keyframes cm-cer-ring-out { 0% { opacity: 0.85; transform: scale(0.3); } 100% { opacity: 0; transform: scale(var(--ring-to, 2.2)); } }
@keyframes cm-cer-spark { 0% { opacity: 0; transform: rotate(calc(var(--i) * 360deg / var(--n))) translateY(0) scale(0.4); } 25% { opacity: 1; } 100% { opacity: 0; transform: rotate(calc(var(--i) * 360deg / var(--n))) translateY(calc(-1 * var(--spark-distance, 88px))) scale(1); } }
@keyframes cm-cer-rays { from { opacity: 0; transform: rotate(-40deg) scale(0.6); } }
@keyframes cm-cer-sweep { 0% { opacity: 0; transform: translateX(-120%) skewX(-18deg); } 30% { opacity: 1; } 100% { opacity: 0; transform: translateX(160%) skewX(-18deg); } }
@keyframes cm-cer-beam { from { opacity: 0; transform: scaleY(0); } }
@keyframes cm-cer-track { from { transform: scaleX(0); } }
@keyframes cm-cer-spin-in { 0% { opacity: 0; transform: perspective(600px) rotateY(-540deg) scale(0.4); } 70% { opacity: 1; transform: perspective(600px) rotateY(12deg) scale(1.08); } }
@keyframes cm-cer-swell { 0% { opacity: 0; transform: scale(0.5); } 55% { opacity: 1; transform: scale(1.12); } }
@keyframes cm-cer-slide-l { from { opacity: 0; transform: translateX(-60%); } }
@keyframes cm-cer-slide-r { from { opacity: 0; transform: translateX(60%); } }
@keyframes cm-cer-slam { 0% { opacity: 0; transform: scale(2.4); } 60% { opacity: 1; transform: scale(0.92); } }

/* ---- Shared parts ------------------------------------------------------- */
.cm-cer-ring {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--ring-size, 120px);
  height: var(--ring-size, 120px);
  margin: calc(var(--ring-size, 120px) / -2) 0 0 calc(var(--ring-size, 120px) / -2);
  border: 2px solid var(--c-accent-hi);
  border-radius: 50%;
  opacity: 0;
  animation: cm-cer-ring-out 720ms var(--ease-out) backwards;
}
.cm-cer-ring--b { animation-delay: 140ms; border-color: var(--c-gold); }
.cm-cer-ring--c { animation-delay: 280ms; }
.cm-ceremony__spark {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 6px;
  height: 14px;
  margin: -7px 0 0 -3px;
  border-radius: 3px;
  background: linear-gradient(180deg, #ffffff, var(--c-accent-hi));
  opacity: 0;
  transform-origin: 50% 50%;
  animation: cm-cer-spark 760ms var(--ease-out) backwards;
  animation-delay: calc(80ms + var(--i) * 12ms);
}
.cm-ceremony__spark:nth-child(3n) { background: linear-gradient(180deg, #fff6d8, var(--c-gold)); }
.cm-cer-rays {
  position: absolute;
  left: 50%;
  top: 50%;
  width: var(--rays-size, 320px);
  height: var(--rays-size, 320px);
  margin: calc(var(--rays-size, 320px) / -2) 0 0 calc(var(--rays-size, 320px) / -2);
  border-radius: 50%;
  background: repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--rays-color, var(--c-accent-hi)) 42%, transparent) 0deg 7deg, transparent 7deg 22.5deg);
  -webkit-mask: radial-gradient(circle, #000 18%, transparent 68%);
  mask: radial-gradient(circle, #000 18%, transparent 68%);
  opacity: 0.85;
  animation: cm-cer-rays 900ms var(--ease-out) backwards;
}
/* A HUD island in the ceremony's language: white plate, teal cable on the
   left, the pixel stair on the corner. */
.cm-cer-plate {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 2px;
  min-width: min(280px, calc(100% - 48px));
  max-width: calc(100% - 32px);
  padding: 12px 26px 14px;
  border: 1px solid var(--c-line-2);
  border-radius: var(--r-card);
  background: var(--c-surface-hud);
  box-shadow: var(--shadow-float), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  color: var(--c-text-1);
  text-align: center;
}
.cm-cer-plate::before {
  content: "";
  position: absolute;
  left: -1px;
  top: 14px;
  bottom: 14px;
  width: 4px;
  border-radius: 0 3px 3px 0;
  background: linear-gradient(180deg, var(--c-accent-hi), var(--c-accent));
}
.cm-cer-plate::after {
  content: "";
  position: absolute;
  right: 8px;
  top: 8px;
  width: 9px;
  height: 9px;
  background: var(--motif-stair-gold) center / contain no-repeat;
}
.cm-cer-kicker {
  color: var(--c-accent-strong);
  font-size: var(--fs-label);
  line-height: var(--lh-label);
  font-weight: var(--fw-heavy);
  letter-spacing: 0.14em;
}
.cm-cer-title {
  margin: 0;
  overflow-wrap: anywhere;
  font-size: var(--fs-display);
  line-height: var(--lh-display);
  font-weight: var(--fw-heavy);
}
.cm-cer-meta { color: var(--c-text-2); font-size: var(--fs-body-sm); line-height: var(--lh-body-sm); }
.cm-cer-hint {
  position: absolute;
  left: 50%;
  bottom: calc(var(--safe-bottom) + 13%);
  transform: translateX(-50%);
  padding: 4px 12px;
  border-radius: var(--r-tag);
  background: var(--c-surface-glass);
  color: var(--c-text-2);
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  white-space: nowrap;
  animation: cm-cer-fade 400ms linear backwards 700ms;
}

/* ---- 1. Gate entry: 傳送門連線 (moment, held until the field is ready) ---- */
.cm-ceremony[data-kind="gate-entry"] {
  z-index: 6;
  background:
    var(--bg-pattern),
    radial-gradient(70% 55% at 50% 46%, color-mix(in srgb, var(--c-accent-hi) 26%, transparent) 0%, transparent 70%),
    linear-gradient(180deg, var(--c-backdrop-top) 0%, var(--c-ground) 55%, var(--c-backdrop-bottom) 100%);
}
.cm-cer-gate { position: relative; display: grid; justify-items: center; gap: 14px; width: 100%; margin-top: -10%; }
.cm-cer-gate__portal { position: relative; width: 168px; height: 168px; }
.cm-cer-gate__portal .cm-cer-ring { --ring-size: 168px; --ring-to: 1.9; animation-duration: 1100ms; }
.cm-cer-gate__core {
  position: absolute;
  inset: 34px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 42%, #ffffff 0%, color-mix(in srgb, var(--c-accent-hi) 70%, #ffffff) 38%, var(--c-accent) 100%);
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--c-accent-hi) 22%, transparent), 0 0 42px color-mix(in srgb, var(--c-accent-hi) 55%, transparent);
  animation: cm-cer-swell 620ms var(--ease-spring) backwards;
}
.cm-cer-gate__orbit {
  position: absolute;
  inset: 8px;
  border: 2px dashed color-mix(in srgb, var(--c-accent) 60%, transparent);
  border-radius: 50%;
  animation: cm-cer-rays 900ms var(--ease-out) backwards;
}
.cm-cer-gate__beam {
  position: absolute;
  left: 50%;
  top: -40vh;
  width: 3px;
  height: 80vh;
  margin-left: -1.5px;
  background: linear-gradient(180deg, transparent, color-mix(in srgb, var(--c-accent-hi) 70%, transparent) 45%, transparent);
  transform-origin: 50% 50%;
  animation: cm-cer-beam 520ms var(--ease-out) backwards 120ms;
}
.cm-cer-gate .cm-cer-plate { animation: cm-cer-pop 420ms var(--ease-spring) backwards 220ms; }
.cm-cer-gate__track {
  display: block;
  width: 120px;
  height: 3px;
  margin-top: 6px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--c-accent), var(--c-accent-hi));
  transform-origin: 0 50%;
  animation: cm-cer-track 1100ms var(--ease-in-out) backwards 300ms;
}
/* While the overlay is up, the existing loading card sits below the portal. */
.cm-vs2-field__viewport:has(> .cm-ceremony[data-kind="gate-entry"]) .cm-vs2-field__loading { top: 74%; }

/* ---- 2. Capture success (toast over the live field) --------------------- */
.cm-ceremony[data-kind="capture"] { place-items: start center; }
.cm-cer-capture {
  position: relative;
  display: grid;
  justify-items: center;
  margin-top: 26%;
  width: 100%;
}
.cm-cer-capture__burst { position: absolute; left: 50%; top: 18px; width: 0; height: 0; }
.cm-cer-capture__burst .cm-cer-ring { --ring-size: 96px; --ring-to: 2.6; }
.cm-cer-capture__burst .cm-ceremony__spark { --spark-distance: 92px; }
.cm-cer-capture .cm-cer-plate { animation: cm-cer-pop 380ms var(--ease-spring) backwards 120ms; }
.cm-cer-capture .cm-cer-title { font-size: var(--fs-title-1); line-height: var(--lh-title-1); }
.cm-cer-card-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
  padding: 2px 10px;
  border-radius: var(--r-tag);
  background: var(--c-gold-soft);
  color: var(--c-gold-strong);
  font-size: var(--fs-label);
  line-height: var(--lh-label);
  font-weight: var(--fw-strong);
  animation: cm-cer-rise 320ms var(--ease-out) backwards 360ms;
}
.cm-cer-card-chip::before {
  content: "";
  width: 10px;
  height: 13px;
  border: 2px solid currentColor;
  border-radius: 2px;
  background: linear-gradient(180deg, transparent 55%, currentColor 55%);
}
.cm-ceremony[data-kind="capture"][data-state="leaving"] { animation: cm-cer-leave-up 260ms var(--ease-in-out) forwards; }
@keyframes cm-cer-leave-up { to { opacity: 0; transform: translateY(-16px); } }

/* ---- 3. Hunt reward: the result screen reveals itself -------------------- */
.cm-vs2-result__portrait-card { isolation: isolate; }
.cm-vs2-result__portrait-card .cm-cer-rays { --rays-size: 300px; z-index: -1; opacity: 0.55; }
.cm-vs2-result__portrait-card .cm-cer-sweep {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: inherit;
  pointer-events: none;
}
.cm-vs2-result__portrait-card .cm-cer-sweep::before {
  content: "";
  position: absolute;
  top: -10%;
  bottom: -10%;
  left: 0;
  width: 42%;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.75), transparent);
  opacity: 0;
}
[data-reveal="playing"] .cm-vs2-result__portrait-card { animation: cm-cer-drop 640ms var(--ease-out) backwards; }
[data-reveal="playing"] .cm-vs2-result__portrait-card .cm-cer-rays { animation: cm-cer-rays 1100ms var(--ease-out) backwards 120ms; }
[data-reveal="playing"] .cm-vs2-result__portrait-card .cm-cer-sweep::before { animation: cm-cer-sweep 700ms var(--ease-in-out) backwards 460ms; }
[data-reveal="playing"] .cm-vs2-result__species { animation: cm-cer-pop 420ms var(--ease-spring) backwards 380ms; }
[data-reveal="playing"] :is(.cm-vs2-result__name, .cm-vs2-result__note) { animation: cm-cer-rise 360ms var(--ease-out) backwards 560ms; }
[data-reveal="playing"] .cm-vs2-result__row { animation: cm-cer-rise 320ms var(--ease-out) backwards; animation-delay: calc(700ms + var(--row, 0) * 70ms); }
[data-reveal="playing"] .cm-vs2-footer { animation: cm-cer-rise 320ms var(--ease-out) backwards 820ms; }
:is([data-reveal-motion="reduced"], [data-reveal="settled"]) :is(.cm-vs2-result__portrait-card, .cm-vs2-result__portrait-card *, .cm-vs2-result__portrait-card *::before, .cm-vs2-result__species, .cm-vs2-result__name, .cm-vs2-result__note, .cm-vs2-result__row, .cm-vs2-footer) { animation: none; }
[data-reveal-motion="saver"] .cm-vs2-result__portrait-card .cm-cer-rays { display: none; }

/* ---- 4. Title medal (moment over the battle result) --------------------- */
.cm-ceremony[data-kind="medal"] {
  background: radial-gradient(60% 45% at 50% 44%, color-mix(in srgb, var(--c-gold) 34%, transparent) 0%, transparent 70%), var(--cer-veil);
  animation: cm-cer-fade 260ms linear backwards;
}
.cm-cer-medal { position: relative; display: grid; justify-items: center; gap: 18px; width: 100%; margin-top: -6%; }
.cm-cer-medal__stage { position: relative; display: grid; place-items: center; width: 200px; height: 200px; }
.cm-cer-medal__stage .cm-cer-rays { --rays-size: 360px; --rays-color: var(--c-gold); }
.cm-cer-medal__stage .cm-cer-ring { --ring-size: 150px; --ring-to: 2; animation-delay: 620ms; border-color: var(--c-gold); }
.cm-cer-medal__stage .cm-ceremony__spark { --spark-distance: 120px; animation-delay: calc(640ms + var(--i) * 10ms); }
.cm-cer-medal__art {
  position: relative;
  width: 128px;
  height: 128px;
  object-fit: contain;
  image-rendering: auto;
  filter: drop-shadow(0 8px 18px rgba(0, 0, 0, 0.35));
  animation: cm-cer-spin-in 900ms var(--ease-out) backwards 120ms;
}
.cm-cer-medal__fallback {
  width: 112px;
  height: 112px;
  border-radius: 50%;
  background: radial-gradient(circle at 38% 32%, #fff6d8, var(--c-gold) 55%, var(--c-coin-shade));
  box-shadow: inset 0 0 0 6px color-mix(in srgb, #ffffff 35%, transparent);
}
.cm-cer-medal .cm-cer-plate { animation: cm-cer-pop 420ms var(--ease-spring) backwards 820ms; }
.cm-cer-medal .cm-cer-kicker { color: var(--c-gold-strong); }

/* ---- 5. Evolution reveal (moment over Raising Home) ---------------------- */
.cm-ceremony[data-kind="evolve"] {
  background: radial-gradient(55% 40% at 50% 42%, color-mix(in srgb, var(--c-accent-hi) 34%, transparent) 0%, transparent 72%), var(--cer-veil);
  animation: cm-cer-fade 220ms linear backwards;
}
.cm-cer-evolve { position: relative; display: grid; justify-items: center; gap: 16px; width: 100%; margin-top: -8%; }
.cm-cer-evolve__stage { position: relative; display: grid; place-items: center; width: 220px; height: 200px; }
.cm-cer-evolve__stage .cm-cer-rays { --rays-size: 380px; }
.cm-cer-evolve__stage .cm-cer-ring { --ring-size: 140px; --ring-to: 2.2; animation-delay: 380ms; }
.cm-cer-evolve__stage .cm-ceremony__spark { --spark-distance: 110px; animation-delay: calc(400ms + var(--i) * 10ms); }
.cm-cer-evolve__art {
  position: relative;
  image-rendering: pixelated;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.3));
  animation: cm-cer-swell 700ms var(--ease-spring) backwards 260ms;
}
.cm-cer-evolve .cm-cer-plate { animation: cm-cer-pop 420ms var(--ease-spring) backwards 620ms; }

/* ---- 6. Battle opening: the two sides (toast over the arena) ------------- */
.cm-ceremony[data-kind="versus"] { z-index: 8; place-items: start center; padding-top: 10px; }
.cm-ceremony[data-kind="versus"] .cm-ceremony__stage { height: auto; }
.cm-cer-versus { position: relative; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 10px; width: 100%; padding: 0 12px; }
.cm-cer-versus__side {
  display: grid;
  gap: 2px;
  min-width: 0;
  padding: 10px 14px;
  border-radius: var(--r-card);
  background: var(--c-surface-hud);
  box-shadow: var(--shadow-float);
}
.cm-cer-versus__side--player { border-left: 4px solid var(--c-team-player); text-align: left; animation: cm-cer-slide-l 420ms var(--ease-out) backwards; }
.cm-cer-versus__side--opponent { border-right: 4px solid var(--c-team-opponent); text-align: right; animation: cm-cer-slide-r 420ms var(--ease-out) backwards; }
.cm-cer-versus__team { color: var(--c-text-3); font-size: var(--fs-caption); line-height: var(--lh-caption); font-weight: var(--fw-strong); letter-spacing: 0.1em; }
.cm-cer-versus__name { overflow: hidden; color: var(--c-text-1); font-size: var(--fs-body-sm); line-height: var(--lh-body-sm); font-weight: var(--fw-heavy); text-overflow: ellipsis; white-space: nowrap; }
.cm-cer-versus__mark {
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--c-gold-strong), color-mix(in srgb, var(--c-gold) 60%, #000000));
  box-shadow: 0 0 0 3px var(--c-surface-1), var(--shadow-float);
  color: #ffffff;
  font-size: 20px;
  font-weight: var(--fw-heavy);
  font-style: italic;
  letter-spacing: 0.02em;
  animation: cm-cer-slam 460ms var(--ease-out) backwards 260ms;
}
.cm-ceremony[data-kind="versus"][data-state="leaving"] .cm-cer-versus__side--player { animation: cm-cer-exit-l 260ms var(--ease-in-out) forwards; }
.cm-ceremony[data-kind="versus"][data-state="leaving"] .cm-cer-versus__side--opponent { animation: cm-cer-exit-r 260ms var(--ease-in-out) forwards; }
@keyframes cm-cer-exit-l { to { opacity: 0; transform: translateX(-40%); } }
@keyframes cm-cer-exit-r { to { opacity: 0; transform: translateX(40%); } }

/* ---- Wider screens: the same composition, a little larger ---------------- */
@media (min-width: 700px) and (min-height: 600px) {
  .cm-cer-gate__portal { width: 208px; height: 208px; }
  .cm-cer-gate__portal .cm-cer-ring { --ring-size: 208px; }
  .cm-cer-medal__stage { width: 240px; height: 240px; }
  .cm-cer-medal__art { width: 156px; height: 156px; }
  .cm-cer-versus { max-width: 720px; }
}
/* Short landscape phones: everything moves up and shrinks to fit 390px. */
@media (max-height: 460px) {
  .cm-cer-gate { grid-auto-flow: column; align-items: center; justify-content: center; gap: 20px; margin-top: -12%; }
  .cm-cer-gate .cm-cer-plate { min-width: 220px; }
  .cm-cer-gate__portal { width: 112px; height: 112px; }
  .cm-cer-gate__portal .cm-cer-ring { --ring-size: 112px; }
  .cm-cer-gate__core { inset: 22px; }
  .cm-cer-capture { margin-top: 12%; }
  .cm-cer-medal, .cm-cer-evolve { margin-top: 0; gap: 8px; }
  .cm-cer-medal__stage, .cm-cer-evolve__stage { width: 150px; height: 140px; }
  .cm-cer-medal__art { width: 96px; height: 96px; }
  .cm-cer-title { font-size: var(--fs-title-1); line-height: var(--lh-title-1); }
  .cm-vs2-field__viewport:has(> .cm-ceremony[data-kind="gate-entry"]) .cm-vs2-field__loading { top: 80%; }
  .cm-cer-hint { display: none; }
}

/* Reduced motion also keeps the two sides of the versus card still on exit
   (that exit rule is more specific than the general stop above). */
.cm-ceremony[data-motion="reduced"][data-kind="versus"] .cm-cer-versus__side { animation: none; }
/* Keep the reduced exit last: capture's equally specific exit must not
   replace the opacity-only fade with a translation. */
.cm-ceremony[data-motion="reduced"][data-state="leaving"] { animation: cm-cer-fade-out 160ms linear forwards; }
