/*
  One-use presentation layer for the original live subway machine.

  This file does not restyle the cabinet or anything inside it. The machine
  keeps its authored geometry, cans, tags, gacha, and CRT. The phone stage
  fits that complete cabinet in one viewport beneath the identity mark.
*/

@font-face {
  font-family: "IBM Plex Mono Landing";
  src: url("../assets/fonts/ibm-plex-mono-medium.ttf") format("truetype");
  font-weight: 500;
  font-display: block;
}

:root {
  --landing-font: "Inconsolata CRT", "Consolas", "DejaVu Sans Mono", monospace;
  --landing-ui: "Bahnschrift", "Arial Narrow", Arial, sans-serif;
  --rocket-coral: #ef6d63;
  --rocket-cream: #f4ead2;
  --rocket-cyan: #6ee7e3;
  --rocket-amber: #ffc44d;
  --rocket-ink: #071113;
  --rocket-shift: clamp(180px, 23vw, 300px);
}

/* The gate is layoutless; the rocket and its trail fly in front of the cabinet. */
#power-gate {
  display: contents;
  background: none;
  transform: none;
  transition: none;
}

#power-gate[hidden] { display: none; }

.rocket-name {
  position: fixed;
  top: 35px;
  left: 91px;
  z-index: 6;
  font: 500 18px/1.2 var(--landing-ui);
  letter-spacing: .17em;
  color: var(--cream);
}
body:not(.rocket-arrival) .rocket-name { display: none; }

#rocket-story {
  --rocket-label-size: clamp(12px, 1vw, 14px);
  --landing-row-gap: 4px;
  --landing-section-gap: 8px;
  position: fixed;
  z-index: 5;
  left: calc(clamp(54px, 6vw, 92px) + 128px);
  top: 51%;
  width: max-content;
  max-width: min(40vw, 560px, var(--rocket-room, 560px));
  color: var(--rocket-cream);
  pointer-events: auto;
  isolation: isolate;
  transform: translateY(-50%);
  transform-origin: 50% 50%;
  will-change: transform, opacity;
}

/* The cabinet remains behind the rocket and its trail. */
body.rocket-arrival #alcove { z-index: 3; }

/* The opening split moves the original, straight-on machine as one rigid
   object. No scale, perspective, width, grid, can, tag, or type changes. */
@media (min-width: 801px) and (min-height: 621px) {
  /* Keep the cabinet on the same composited layer after arrival. Dropping
     promotion as centering ends caused a large raster stall at the handoff. */
  #machine { will-change: translate; }
  body.rocket-arrival #stage { overflow-x: clip; }
  body.rocket-arrival #machine {
    translate: var(--rocket-shift) 0;
  }
  body.rocket-arrival:not(.machine-centering) #machine {
    left: 50%;
  }

  body.machine-centering #machine {
    left: 50%;
    translate: 0 0;
    transition: translate 900ms cubic-bezier(.22, .76, .2, 1);
  }
}

.rocket-meta { margin-bottom: var(--landing-section-gap); }
.rocket-kicker {
  margin: 0;
  color: var(--rocket-cyan);
  font: 500 var(--rocket-label-size)/1.4 var(--landing-font);
  letter-spacing: .1em;
  text-shadow: 0 0 9px #6ee7e333;
}

#power-title {
  margin: 0;
  color: var(--rocket-cream);
  font: 900 90px/1 "IBM Plex Mono Landing", monospace;
  letter-spacing: .025em;
  text-shadow: 0 10px 42px rgba(0, 0, 0, .55), 0 2px 0 rgba(0, 0, 0, .45);
}

#power-title span { display: block; white-space: nowrap; }

.rocket-intro { margin-top: var(--landing-section-gap); max-width: 440px; min-width:0; color: var(--cream); }
.rocket-role { font: 600 27px/1.3 var(--landing-ui); letter-spacing: .04em; white-space:nowrap; }
/* Reserve the resting cursor even when the final word reaches the column edge. */
.rocket-specialty { font: 500 23px/1.35 var(--landing-ui); letter-spacing: .04em; color: #90dfd4; margin-top: var(--landing-row-gap); padding-right:1ch; white-space:nowrap; }
.rocket-actions { display: flex; align-items: center; margin-top: 25px; }

#power-start {
  --power-press-travel: 4px;
  --power-icon-color: var(--rocket-ink);
  width: min(300px, 100%);
  min-height: 58px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 28px;
  color: var(--rocket-ink);
  background: var(--rocket-amber);
  border: 3px solid var(--rocket-ink);
  border-radius: 3px;
  box-shadow: 6px 7px 0 rgba(0, 0, 0, .45), inset 0 2px 0 rgba(255, 255, 255, .32);
  font: 900 15px/1 "Inconsolata CRT", monospace;
  letter-spacing: .13em;
  outline: none;
  transition: transform .12s ease, filter .12s ease, box-shadow .12s ease,
    background-color .12s ease, color .12s ease;
}

#power-start::before { content: none; }
.power-icon {
  width: 22px;
  height: 22px;
  flex: none;
  overflow: visible;
  color: var(--power-icon-color);
  filter: none;
  transition: color .2s ease, filter .2s ease;
}
#power-start[data-status="ready"] { --power-icon-color:var(--rocket-ink); }
#power-start[data-status="ready"] .power-icon { filter:none; }

/* Both labels occupy the progress label's measured width in the active font.
   The hidden sizing copy never enters the accessible button name. */
.power-label { display: inline-grid; white-space: nowrap; }
.power-label::after { content: "POWERING ON..."; visibility: hidden; grid-area: 1 / 1; }
#power-label-text { grid-area: 1 / 1; }

#power-start:disabled {
  cursor: wait;
  color: rgba(7, 17, 19, .72);
  background: #b99c58;
  box-shadow: 5px 6px 0 rgba(0, 0, 0, .42), inset 0 2px 0 rgba(255, 255, 255, .2);
}

#power-start:not(:disabled):hover { filter: brightness(1.06); }
#power-start:not(:disabled):active {
  transform: translateY(var(--power-press-travel));
  box-shadow: 3px 3px 0 rgba(0, 0, 0, .45);
}
#power-start:focus-visible { outline: 3px solid var(--rocket-cream); outline-offset: 5px; }
#power-start[data-autofocus]:focus-visible { outline: none; }

#power-gate[data-state="powering"] #power-start {
  color: var(--rocket-ink);
  background: #fff0a3;
  transform: translateY(var(--power-press-travel));
  filter: brightness(1.08);
  box-shadow: 0 1px 0 #876722, 0 0 28px rgba(255, 196, 77, .5);
}

#power-gate[data-state="powered"] #power-start {
  cursor: default;
  color: var(--rocket-ink);
  background: var(--rocket-amber);
  transform: none;
  filter: none;
  box-shadow: inset 0 2px 0 rgba(255, 255, 255, .32);
}

.rocket-status {
  position: static;
  width: auto;
  height: auto;
  padding: 0;
  margin: var(--landing-row-gap) 0 0;
  overflow: visible;
  clip: auto;
  white-space: normal;
  border: 0;
  font: 500 var(--rocket-label-size)/1.4 var(--landing-font);
  letter-spacing: .1em;
  color: #7de7be;
  --landing-ink: #7de7be;
}

.rocket-status::before { content:""; display:inline-block; width:5px; height:5px; margin-right:.65em;
  border-radius:50%; vertical-align:.14em; background:currentColor; box-shadow:0 0 7px currentColor; }
.rocket-status[data-state="booting"] { color:#ef6d63; --landing-ink:#ef6d63; }
.landing-rest { visibility:hidden; }
.landing-spoken { position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0; }
.landing-next { color:transparent; background:var(--landing-ink,var(--rocket-cyan)); animation:blink 1.1s steps(1) infinite; }
.landing-cursor { display:inline-block; width:1ch; height:.95em; margin-right:-1ch;
  background:currentColor; vertical-align:text-bottom; animation:blink 1.1s steps(1) infinite; }
#power-start { --landing-ink: var(--rocket-ink); }

/* Keep the scrim mounted when arrival ends. Fade its opacity during the
   flyby instead of removing a gradient in the frame the rocket clears. */
body::after { content:""; position:fixed; inset:0; z-index:4; pointer-events:none;
  background:linear-gradient(90deg,#061015b3 0,#06101555 42%,transparent 75%); }
/* The name and scrim share one fade clock, so no floating label outlasts it. */
body::after,.rocket-name { opacity:0; transition:opacity 1.25s cubic-bezier(.22,.61,.36,1); }
body.rocket-arrival::after,body.rocket-arrival .rocket-name { opacity:1; }
body.rocket-arrival.story-departing::after,body.rocket-arrival.machine-centering::after,
body.rocket-arrival.story-departing .rocket-name,body.rocket-arrival.machine-centering .rocket-name { opacity:0; }

/* Recoil, twin cel-shaded exhausts, and hard-edged debris. The story remains
   one object; the effect never reaches into the machine DOM. */
body.story-igniting #rocket-story {
  animation: rocket-launch-jitter 72ms steps(2, end) infinite;
}

body.story-departing #rocket-story {
  pointer-events: none;
  animation: rocket-story-exit var(--rocket-exit-ms, 820ms) cubic-bezier(.68, .02, .86, .32) both;
}

@keyframes rocket-launch-jitter {
  0% { transform: translate3d(-3px, -50%, 0) rotate(-.22deg); }
  100% { transform: translate3d(3px, -50%, 0) rotate(.22deg); }
}

@keyframes rocket-story-exit {
  0% { opacity: 1; filter: none; transform: translate3d(0, -50%, 0) rotate(0) scale(1); }
  9% { transform: translate3d(-22px, -50%, 0) rotate(-.8deg) scale(1.018); }
  18% { transform: translate3d(-15px, -50%, 0) rotate(.35deg) scale(1.012); }
  72% { opacity: 1; filter: none; }
  100% { opacity: 0; filter: none; transform: translate3d(calc(100vw + 220px), -50%, 0) rotate(4deg) scale(.96); }
}


#hybrid-hardware { position:absolute; inset:0; width:100%; height:100%; overflow:visible; pointer-events:none; z-index:-1; stroke:#102b2a; stroke-width:4; stroke-linecap:round; stroke-linejoin:round; }
#rocket-effects { position:fixed; inset:0; width:100%; height:100%; z-index:4; pointer-events:none; overflow:hidden; }
#rocket-story.compact-clearance #power-start { max-width:100%; padding-inline:18px; }
body.rocket-arrival #zoomctl { visibility:hidden; pointer-events:none; }
@media(min-width:801px) and (max-width:1100px) and (min-height:621px){
  #rocket-story{left:48px;width:260px;--rocket-label-size:12px}
  .rocket-kicker{letter-spacing:.17em}
  .rocket-actions{margin-top:25px}
  #power-start{width:260px;min-height:56px;padding-inline:18px}
}
@media(max-width:800px),(max-height:620px){
  body.rocket-arrival{overflow:hidden}
  body::after{background:linear-gradient(#061015c9 0,#061015d9 38%,#07101c40 75%)}
  .rocket-name{left:88px;top:43px;font-size:16px}
  /* The bottom padding includes the boosters; the complete assembly sits
     above the safe area and has the rest of the screen available for flight. */
  #rocket-story{left:50%;top:auto;bottom:calc(50px + env(safe-area-inset-bottom,0px));padding-bottom:42px;width:calc(100% - 48px);max-width:510px;transform:translateX(-50%);animation:none!important;filter:none!important;text-align:center;--rocket-label-size:11px}
  #rocket-story .rocket-kicker{display:block;letter-spacing:1.3px;line-height:1.4}
  #rocket-story #power-title{display:block;font-size:50px;text-shadow:0 2px 0 #0b1716,0 0 18px #071817,0 0 35px #071817}
  .rocket-intro{margin:var(--landing-section-gap) auto 0;width:100%}
  .rocket-role{font-size:20px}
  .rocket-specialty{font-size:18px}
  #rocket-story .rocket-actions{margin-top:22px;justify-content:center}
  #hybrid-hardware .hybrid-booster{display:inline}
  /* Press feedback uses the shadow/color so the face cannot cover the fixed booster collars. */
  #rocket-story #power-start{--power-press-travel:0px;position:relative;z-index:1;flex:none;width:max-content;max-width:100%;min-height:56px;font-size:13px;padding:0 24px;white-space:nowrap}
  #rocket-story .rocket-status{letter-spacing:1px}
}
@media(max-width:350px){
  #rocket-story{width:calc(100% - 40px)}
}
@media(max-height:720px) and (max-width:800px){
  #rocket-story .rocket-actions{margin-top:19px}
}
/* A short landscape phone keeps the same copy and artwork in two columns,
   leaving the button, mounted boosters, and status inside the screen. */
@media(orientation:landscape) and (max-height:480px) and (min-width:561px){
  .rocket-name{top:27px;left:77px}
  #rocket-story{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);column-gap:28px;max-width:760px}
  .rocket-meta{grid-column:1 / -1;grid-row:1}
  #rocket-story #power-title{grid-column:1;grid-row:2}
  .rocket-intro{grid-column:2;grid-row:2 / span 2;margin-top:0}
  #rocket-story .rocket-actions{grid-column:1;grid-row:3;margin-top:14px}
  #rocket-story #power-start{min-height:48px}
}
/* The machine stays in one phone viewport, before and after reading. */
body.phone-full-view #stage{overflow:visible;position:fixed;inset:72px 0 auto;height:calc(100dvh - 80px);min-height:0;max-height:none;margin:0;padding:0}
body.phone-full-view{height:100dvh;padding-top:0;overflow:hidden}
/* On a short landscape phone the identity sits beside the cabinet, so the
   complete station can use the screen height without shrinking below it. */
@media(orientation:landscape) and (max-height:480px) and (min-width:561px){
  body.phone-full-view #stage{inset:0;height:100dvh}
}
@media(prefers-reduced-motion:reduce){
  body::after,.rocket-name{transition:none}
  .landing-cursor,.landing-next{animation:none}
  body.machine-centering #machine{transition:none!important}
  body.story-igniting #rocket-story,body.story-departing #rocket-story{animation:none!important}
  #rocket-effects,.hybrid-flame{display:none}
}
