/* The launch screen plays while the first view is being prepared.
   It never swallows input and never delays the app: the overlay ignores
   pointer events, skips on the first tap after it is ready, and is removed
   by the app as soon as the lobby (or a linked room) is on screen. */
#launch-screen {
  --launch-bg: #173b32;
  --launch-lattice: #73917e;
  --launch-stone: #f5f7f3;
  --launch-gold: #d9be85;
  --launch-drop: 360ms;
  position: fixed;
  inset: 0;
  z-index: 100;
  overflow: hidden;
  background: var(--launch-bg);
  color: var(--launch-stone);
  pointer-events: none;
  user-select: none;
  opacity: 1;
  transition: opacity 260ms ease-out;
}
#launch-screen.is-hidden { opacity: 0; }
#launch-screen.is-gone { display: none; }
.launch-stage { position: absolute; inset: 0; display: grid; align-content: center; justify-items: center; }
.launch-mark { display: block; width: min(48vmin, 208px); height: min(48vmin, 208px); overflow: visible; }

/* 1. The lattice fades in, then the stones land along the diagonal. */
.launch-lattice { fill: var(--launch-lattice); transform-box: view-box; transform-origin: 50% 50%; animation: launch-lattice 420ms cubic-bezier(.22, 1, .36, 1) both; }
.launch-bar { animation: launch-bar 260ms ease-out both; animation-delay: calc(var(--i) * 42ms); }
.launch-stone { fill: var(--launch-stone); transform-box: fill-box; transform-origin: 50% 50%; animation: launch-drop var(--launch-drop) cubic-bezier(.24, 1.24, .4, 1) both; animation-delay: calc(150ms + var(--i) * 90ms); }
.launch-stone.is-win { animation: launch-drop var(--launch-drop) cubic-bezier(.24, 1.24, .4, 1) both, launch-gold 300ms ease-out 820ms both; }
.launch-ripple { fill: none; stroke: var(--launch-stone); stroke-width: 3; opacity: 0; transform-box: fill-box; transform-origin: 50% 50%; animation: launch-ripple 520ms ease-out both; animation-delay: calc(460ms + var(--i) * 90ms); }
.launch-line { fill: none; stroke: var(--launch-gold); stroke-width: 12; stroke-linecap: round; stroke-dasharray: 386; animation: launch-win 300ms cubic-bezier(.3, 1, .4, 1) 820ms both; }

/* 2. The wordmark answers the winning line beneath the mark. */
.launch-copy { position: absolute; left: 0; right: 0; top: calc(50% + min(24vmin, 104px) + 26px); display: grid; gap: 7px; justify-items: center; text-align: center; }
.launch-word { margin: 0; font: 600 21px/1.2 var(--ui-serif, 'Songti SC', serif); letter-spacing: .34em; text-indent: .34em; animation: launch-copy 320ms ease-out 700ms both; }
.launch-glyph { display: inline-block; animation: launch-glyph 340ms cubic-bezier(.22, 1, .36, 1) both; animation-delay: calc(720ms + var(--i) * 52ms); }
.launch-tagline { margin: 0; font: 400 12.5px/1.5 var(--ui-serif, 'Songti SC', serif); letter-spacing: .2em; text-indent: .2em; color: #cfe0d2cc; animation: launch-copy 380ms ease-out 980ms both; }

@keyframes launch-lattice { from { opacity: 0; transform: scale(.94); } to { opacity: 1; transform: none; } }
@keyframes launch-bar { from { opacity: 0; } to { opacity: 1; } }
@keyframes launch-drop { 0% { opacity: 0; transform: translateY(-58px) scale(.86); } 55% { opacity: 1; } 74% { transform: translateY(3px) scale(1.035); } 100% { opacity: 1; transform: none; } }
@keyframes launch-ripple { 0%, 70% { opacity: 0; transform: scale(.5); } 78% { opacity: .45; } 100% { opacity: 0; transform: scale(1.85); } }
@keyframes launch-win { from { stroke-dashoffset: 386; } to { stroke-dashoffset: 0; } }
@keyframes launch-gold { to { fill: var(--launch-gold); } }
@keyframes launch-glyph { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes launch-copy { from { opacity: 0; } to { opacity: 1; } }

/* Reduced motion keeps the composed frame, drops the choreography. */
@media (prefers-reduced-motion: reduce) {
  #launch-screen { transition-duration: 1ms; }
  #launch-screen * { animation-delay: 0ms !important; animation-duration: 1ms !important; }
}
