/* Schematic additions on top of the Mission 001 design system.
   Everything here reuses the tokens from styles.css — no new colours, no new fonts. */

/* The design system gives several of these blocks an explicit display value, which
   would otherwise beat the hidden attribute. */
[hidden] {
  display: none !important;
}

/* ------------------------------------------------------------------ the scene

   styles.css carries the design fork's own look for the layered sideview: sprites,
   flames, parallax and all the keyframes. What it cannot know is where our rockets
   belong — the interface is one screen, so the corridor is measured at runtime and
   handed to the scene as custom properties. The fork pins its units to fixed vh
   positions in its own media queries; these rules exist to beat them, which is the
   only reason for the !important. */

.cosmic-scene .planet {
  left: var(--planet-x) !important;
  top: var(--planet-y) !important;
  width: var(--planet-size) !important;
}

/* At this size the globes would swallow the interface, so they are turned down to
   night side: present, readable, never competing with the telemetry on top. */
.cosmic-scene .planet-earth {
  filter: saturate(0.7) brightness(0.4) drop-shadow(0 0 70px rgba(58, 153, 255, 0.14));
}

.cosmic-scene .planet-mars {
  filter: saturate(0.78) brightness(0.44) drop-shadow(0 0 70px rgba(255, 88, 53, 0.16));
}

.cosmic-scene .rocket-unit[data-team] {
  left: var(--unit-left) !important;
  top: var(--unit-top) !important;
  width: var(--unit-width) !important;
  /* The only thing that changes per frame: how far along the corridor it is. */
  transform: translate3d(calc(var(--unit-travel, 0px) * var(--unit-progress, 0)), 0, 0);
}

/* A rocket that is gone stops burning and falls out of the race line. */
.rocket-unit[data-state='lost'] {
  filter: grayscale(0.72) brightness(0.5) drop-shadow(0 12px 20px rgba(0, 0, 0, 0.5));
}

.rocket-unit[data-state='lost'] .rocket-motion {
  transform: rotate(7deg);
  animation: none;
}

/* Readout in the clear air ahead of the nose: which rocket, how fast. */
.rocket-readout {
  position: absolute;
  z-index: 8;
  right: 0.5%;
  top: 1%;
  display: grid;
  gap: 2px;
  font-family: var(--font-data);
  text-align: right;
  text-shadow: 0 2px 6px rgba(3, 7, 16, 0.85);
}

.rocket-readout b {
  font-size: clamp(9px, 0.82vw, 13px);
  letter-spacing: 3px;
  color: var(--text);
}

.rocket-readout span {
  font-size: clamp(8px, 0.72vw, 12px);
  letter-spacing: 1px;
  color: var(--muted);
}

.rocket-coral .rocket-readout b { color: var(--coral); }
.rocket-blue .rocket-readout b { color: var(--blue); }

/* -------------------------------------------------------------------- inspection

   A rocket, or anyone holding on to it, can be brought forward for a proper look: it
   grows until it nearly fills the screen, the other rocket leaves the frame and both
   globes pull back. The wrapper owns the zoom; the unit around it still carries the
   flight down the corridor, so the rocket goes on flying while you inspect it. */

.rocket-focus {
  position: absolute;
  inset: 0;
  transform-origin: 50% 50%;
  transition:
    transform 780ms cubic-bezier(0.22, 0.61, 0.36, 1),
    opacity 420ms ease;
  will-change: transform;
}

/* The stage sits above the scene and would swallow every click, so the hit test is
   done against the sprites' own boxes in JS; the stage only carries the cursor. */
.race-stage.is-pointing {
  cursor: zoom-in;
}

body[data-focus] .race-stage.is-pointing {
  cursor: zoom-out;
}

.cosmic-scene .planet {
  transition:
    width 780ms cubic-bezier(0.22, 0.61, 0.36, 1),
    left 780ms cubic-bezier(0.22, 0.61, 0.36, 1),
    opacity 520ms ease;
}

/* While a rocket is inspected the globes halve, as if they had fallen away — but they
   keep the framing rule of the race view: the centre stays a sixth of the diameter
   outside the screen, so exactly a third of the sphere shows, never the whole disc. */
.cosmic-scene[data-focus] .planet {
  width: calc(var(--planet-size) * 0.5) !important;
  opacity: 0.9;
}

/* A third of a halved globe is a narrow sliver, so it gets some light back — with the
   rocket blown up over it, the night side would read as nothing at all. */
.cosmic-scene[data-focus] .planet-earth {
  left: calc(var(--planet-size) * -0.0833) !important;
  filter: saturate(0.8) brightness(0.62) drop-shadow(0 0 50px rgba(58, 153, 255, 0.18));
}

.cosmic-scene[data-focus] .planet-mars {
  left: calc(100vw + var(--planet-size) * 0.0833) !important;
  filter: saturate(0.86) brightness(0.66) drop-shadow(0 0 50px rgba(255, 88, 53, 0.2));
}

.cosmic-scene[data-focus] .star-layer {
  opacity: 0.32 !important;
  transition: opacity 600ms ease;
}

.star-layer {
  transition: opacity 600ms ease;
}

/* The readout would be blown up with everything else, and the score cards already
   carry the same numbers at a readable size. */
.rocket-unit.is-focused .rocket-readout {
  opacity: 0;
  transition: opacity 240ms ease;
}

/* The placard belongs to the rocket you have stepped into: in the wide view both
   hulls are small and the race is the subject, so it is not there at all. */
.crew-crowd {
  opacity: 0;
  transition: opacity 240ms ease;
}

.rocket-unit.is-focused .crew-crowd {
  opacity: 1;
}

.cosmic-scene[data-level='2'] .crew-crowd {
  opacity: 0;
}

/* Nothing should sit on top of the rocket being inspected. */
body[data-focus] .event-chip,
body[data-focus] .stage-corner {
  opacity: 0;
  pointer-events: none;
  transition: opacity 260ms ease;
}

.astronaut.crew-inspected .astronaut-sprite {
  filter: saturate(1.15) contrast(1.12) brightness(1.15)
    drop-shadow(0 0 5px rgba(255, 255, 255, 0.9)) drop-shadow(0 2px 2px rgba(0, 0, 0, 0.72));
}

/* Second step: the intel panel steps aside so the card has the right-hand side to
   itself. Only opacity and transform move — the column keeps its width, because a
   reflow here would re-measure the corridor and shift the rocket mid-zoom. */
.intel-panel {
  transition:
    opacity 360ms ease,
    transform 460ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

body[data-level='2'] .intel-panel {
  opacity: 0;
  transform: translateX(40px);
  pointer-events: none;
}

/* Second step: everyone else on the hull steps back so the one being read stands out,
   and the banner folds away — blown up to this size it owns the whole frame. */
.cosmic-scene[data-level='2'] .astronaut:not(.crew-inspected) {
  opacity: 0.25;
}

/* The banner and the YOU tag are drawn at hull scale; at this magnification they own
   the frame, and the card says both things anyway. */
.cosmic-scene[data-level='2'] .crew-message,
.cosmic-scene[data-level='2'] .crew-you {
  opacity: 0;
}

.astronaut,
.crew-message,
.crew-you {
  transition: opacity 420ms ease;
}

/* The card that comes with the second step. */
.focus-card {
  position: fixed;
  z-index: 40;
  top: 50%;
  right: 26px;
  width: min(330px, calc(100vw - 40px));
  transform: translateY(-50%);
  padding: 18px 20px 16px;
  border: 1px solid var(--line-bright);
  border-left: 2px solid var(--card-accent, var(--blue));
  border-radius: 0;
  /* Glass, like the deck panel: the astronaut you are reading about stays visible
     through their own card. */
  background: linear-gradient(158deg, rgba(13, 24, 45, 0.42), rgba(5, 10, 20, 0.58));
  backdrop-filter: blur(20px) saturate(1.15);
  box-shadow: 0 24px 60px rgba(2, 5, 12, 0.55);
  animation: focusCardIn 420ms cubic-bezier(0.22, 0.61, 0.36, 1) both;
}

@keyframes focusCardIn {
  from {
    opacity: 0;
    transform: translateY(-50%) translateX(18px);
  }
  to {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
  }
}

.focus-card header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-family: var(--font-data);
  font-size: 10px;
  letter-spacing: 3px;
  color: var(--muted);
}

.focus-card > strong {
  display: block;
  margin: 8px 0 10px;
  font-size: 30px;
  letter-spacing: 1px;
}

.focus-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}

.focus-tags b {
  padding: 3px 9px;
  border: 1px solid var(--line);
  border-radius: 0;
  font-family: var(--font-data);
  font-size: 9px;
  font-weight: 500;
  letter-spacing: 2px;
  color: var(--card-accent, var(--blue));
}

.focus-tags .focus-you {
  border-color: rgba(245, 200, 91, 0.5);
  background: rgba(245, 200, 91, 0.12);
  color: var(--amber);
}

.focus-list {
  display: grid;
  gap: 7px;
  margin: 0;
  padding-top: 12px;
  border-top: 1px solid var(--line);
}

.focus-list > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
}

.focus-list dt {
  font-family: var(--font-data);
  font-size: 9px;
  letter-spacing: 2px;
  color: var(--muted);
}

.focus-list dd {
  margin: 0;
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 1px;
  text-align: right;
  text-transform: uppercase;
  color: var(--text);
}

.focus-banner {
  margin: 12px 0 0;
  font-size: 12px;
  font-style: italic;
  color: var(--text);
}

.focus-hint {
  margin: 12px 0 0;
  font-family: var(--font-data);
  font-size: 9px;
  letter-spacing: 1px;
  color: var(--muted);
}

@media (max-width: 980px) {
  .focus-card {
    top: auto;
    right: 16px;
    left: 16px;
    bottom: 84px;
    width: auto;
    transform: none;
    animation-name: focusCardUp;
  }

  @keyframes focusCardUp {
    from {
      opacity: 0;
      transform: translateY(16px);
    }
    to {
      opacity: 1;
      transform: translateY(0);
    }
  }
}

.focus-exit {
  position: fixed;
  z-index: 40;
  left: 50%;
  bottom: 28px;
  transform: translateX(-50%);
  padding: 9px 18px;
  border: 1px solid var(--line-bright);
  border-radius: 0;
  background: rgba(7, 11, 21, 0.72);
  backdrop-filter: blur(10px);
  color: var(--text);
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 2px;
  cursor: pointer;
}

.focus-exit:hover {
  border-color: var(--text);
}

@media (prefers-reduced-motion: reduce) {
  .rocket-focus,
  .cosmic-scene .planet,
  .star-layer,
  .astronaut {
    transition: none;
  }

  .focus-card {
    animation: none;
  }
}

/* A new layer of crew arrives from the hull outwards rather than blinking in. The
   keyframes carry the figure's own rotation, and the fill is `backwards` only: once
   the arrival is over the ordinary rules own the transform again. */
@keyframes crew-arrive {
  from {
    opacity: 0;
    transform: rotate(var(--crew-rotation, 0deg)) translate3d(0, 7px, 0) scale(0.9);
  }
  to {
    opacity: 1;
    transform: rotate(var(--crew-rotation, 0deg));
  }
}

.astronaut {
  animation: crew-arrive 320ms ease backwards;
  animation-delay: var(--arrive-delay, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  .astronaut { animation: none; }
}

/* The placard on the hull: how many astronauts are on it, and the way through to the
   ones behind them. It is fixed to the middle of the body in scene.js, sits over the
   chain and under the banner, and reads at one size at any zoom. */
.crew-crowd {
  position: absolute;
  z-index: 14;
  transform: translate(-50%, -50%);
  display: grid;
  justify-items: center;
  gap: 1px;
  padding: 3px 8px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: rgba(7, 11, 21, 0.72);
  color: var(--muted);
  font-family: var(--font-data);
  line-height: 1.15;
  white-space: nowrap;
  /* Clicks are hit-tested off the stage overlay, so the badge takes none itself and
     cannot hover on its own; the body carries the flag instead. */
  pointer-events: none;
  transition: border-color 0.18s ease, color 0.18s ease, background 0.18s ease;
}

body[data-over-crowd] .race-stage {
  cursor: pointer;
}

/* A placard on a white hull needs its own darkness to sit in. */
.crew-crowd {
  background: rgba(6, 10, 19, 0.82);
  box-shadow: 0 2px 10px rgba(2, 5, 12, 0.45);
  backdrop-filter: blur(2px);
}

.crew-crowd-label {
  font-size: clamp(6px, 0.44vw, 8px);
  font-style: normal;
  letter-spacing: 1.6px;
  opacity: 0.72;
}

.crew-crowd-count {
  color: var(--text);
  font-size: clamp(8px, 0.62vw, 11px);
  font-weight: 700;
  letter-spacing: 0.6px;
}

body[data-over-crowd='A'] .rocket-unit[data-team='A'] .crew-crowd,
body[data-over-crowd='B'] .rocket-unit[data-team='B'] .crew-crowd {
  border-color: var(--line-bright);
  background: rgba(7, 11, 21, 0.92);
  color: var(--text);
}

/* An alliance tints the astronaut's contact light; the viewer gets a name tag. */
.astronaut.crew-allied .crew-contact {
  background: var(--crew-accent, rgba(225, 241, 255, 0.8));
  box-shadow: 0 0 7px var(--crew-accent, rgba(139, 207, 255, 0.72));
  opacity: 0.85;
}

.astronaut.crew-viewer .astronaut-sprite {
  filter: saturate(1.1) contrast(1.1) brightness(1.12)
    drop-shadow(0 0 6px rgba(245, 200, 91, 0.75)) drop-shadow(0 2px 2px rgba(0, 0, 0, 0.72));
}

/* The banner layer: the cloth sits over the whole chain, and over the hull placard,
   because a message somebody paid for is the loudest thing on the rocket. */
.crew-banner-layer {
  position: absolute;
  inset: 0;
  z-index: 20;
  pointer-events: none;
  animation: crewSway 4.6s ease-in-out -1.3s infinite;
}

.crew-banner-layer .crew-message {
  z-index: auto;
}

.crew-you {
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translateX(-50%);
  padding: 1px 5px;
  border-radius: 0;
  background: var(--amber);
  color: #12161f;
  font-family: var(--font-data);
  font-size: clamp(6px, 0.5vw, 9px);
  font-weight: 700;
  letter-spacing: 1px;
}

/* Where the tag goes when the cloth is in the way. Tried in this order; the first
   one clear of the banner is the one that sticks (see placeYouTag). */
.crew-you.crew-you-below {
  top: 100%;
  bottom: auto;
}

.crew-you.crew-you-right {
  left: 100%;
  bottom: 50%;
  transform: translate(2px, 50%);
}

.crew-you.crew-you-left {
  left: auto;
  right: 100%;
  bottom: 50%;
  transform: translate(-2px, 50%);
}

.crew-you.crew-you-high {
  bottom: 190%;
}

/* ---------------------------------------------------------------- welcome card

   Shown once, the moment someone boards. It is the only place that explains the
   bargain while they are still looking: the rocket has no engine, the chain behind
   them is theirs to grow, and the key is the only way back. */

.welcome-dialog {
  position: fixed;
  inset: 0;
  width: min(560px, calc(100vw - 32px));
  max-height: min(88vh, 860px);
  margin: auto;
  padding: 24px 28px 22px;
  overflow-x: hidden;
  overflow-y: auto;
  border: 1px solid var(--line-bright);
  background: linear-gradient(158deg, rgba(13, 24, 45, 0.76), rgba(5, 10, 20, 0.88));
  backdrop-filter: blur(24px) saturate(1.15);
  box-shadow: 0 40px 120px rgba(2, 5, 12, 0.7);
  color: var(--text);
  scrollbar-width: thin;
  scrollbar-color: rgba(174, 199, 225, 0.2) transparent;
}

.welcome-dialog::backdrop {
  background: rgba(3, 7, 16, 0.62);
  backdrop-filter: blur(5px);
}

.welcome-glow {
  position: absolute;
  z-index: -1;
  inset: -40% -20% auto;
  height: 320px;
  background: radial-gradient(
    ellipse at 50% 0%,
    rgba(88, 185, 255, 0.26),
    rgba(88, 185, 255, 0.05) 45%,
    transparent 72%
  );
  pointer-events: none;
}

.welcome-dialog[data-rocket='B'] .welcome-glow {
  background: radial-gradient(
    ellipse at 50% 0%,
    rgba(255, 98, 77, 0.26),
    rgba(255, 98, 77, 0.05) 45%,
    transparent 72%
  );
}

.welcome-head {
  display: flex;
  align-items: center;
  gap: 20px;
  padding-bottom: 18px;
  border-bottom: 1px solid var(--line);
}

/* The same cell of the same atlas that is now hanging on the hull. */
.welcome-portrait {
  flex: none;
  width: 108px;
  height: 108px;
  background-repeat: no-repeat;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.6));
}

.welcome-head h2 {
  margin: 4px 0 8px;
  font-size: clamp(26px, 3.4vw, 34px);
  letter-spacing: 1px;
}

.welcome-ident {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px;
  margin: 0;
  font-family: var(--font-data);
}

.welcome-ident b {
  font-size: 19px;
  letter-spacing: 1px;
}

.welcome-ident span {
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--blue);
}

.welcome-dialog[data-rocket='B'] .welcome-ident span {
  color: var(--coral);
}

.welcome-ident em {
  font-size: 10px;
  font-style: normal;
  letter-spacing: 2px;
  color: var(--amber);
}

.welcome-body {
  min-height: 188px;
  margin-top: 18px;
}

.welcome-step {
  animation: welcomeStepIn 280ms ease both;
}

@keyframes welcomeStepIn {
  from {
    opacity: 0;
    transform: translateX(10px);
  }
}

.welcome-step h3 {
  margin: 0 0 8px;
  font-family: var(--font-data);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 3px;
  color: var(--muted);
}

.welcome-step p {
  margin: 0 0 12px;
  font-size: 14px;
  line-height: 1.6;
}

.welcome-step .account-key {
  margin: 0;
}

.welcome-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
}

/* Square ticks rather than dots: this interface has no round shapes. */
.welcome-ticks {
  display: flex;
  gap: 5px;
}

.welcome-ticks i {
  width: 18px;
  height: 3px;
  background: var(--line);
  transition: background 240ms ease;
}

.welcome-ticks i.is-on {
  background: var(--blue);
}

.welcome-dialog[data-rocket='B'] .welcome-ticks i.is-on {
  background: var(--coral);
}

.welcome-actions {
  display: flex;
  gap: 10px;
}

.welcome-dialog .compact-button {
  min-width: 150px;
}

@media (max-width: 560px) {
  .welcome-head {
    gap: 14px;
  }

  .welcome-portrait {
    width: 76px;
    height: 76px;
  }
}

/* ------------------------------------------------------------- account menu

   Signed in, the top right stops asking you to board and becomes who you are.
   Nothing in this interface is rounded — the design system draws square plates and
   keeps circles for status dots only — so the chip, the visor and the menu are cut
   with the same corners as everything else. */

/* The live indicator carries its own pulse; the frame around it was noise. */
.live-pill {
  border: 0;
  padding-left: 0;
}

.account {
  position: relative;
}

.account-button {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 5px 12px 5px 6px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: rgba(13, 24, 45, 0.5);
  color: var(--text);
  cursor: pointer;
  transition:
    border-color 180ms ease,
    background 180ms ease;
}

.account-button:hover,
.account-button[aria-expanded='true'] {
  border-color: var(--line-bright);
  background: rgba(19, 34, 62, 0.7);
}

.account-avatar {
  position: relative;
  flex: none;
  width: 30px;
  height: 30px;
  border-radius: 0;
  background:
    radial-gradient(circle at 34% 30%, rgba(255, 255, 255, 0.5), transparent 46%),
    linear-gradient(150deg, var(--visor-color, var(--blue)), rgba(7, 11, 21, 0.92) 78%);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.14);
}

.account-avatar-large {
  width: 42px;
  height: 42px;
}

.account-id {
  display: grid;
  gap: 1px;
  text-align: left;
}

.account-id strong {
  font-family: var(--font-data);
  font-size: 12px;
  letter-spacing: 1px;
}

.account-id small {
  font-family: var(--font-data);
  font-size: 9px;
  letter-spacing: 2px;
  color: var(--muted);
}

.account-caret {
  font-size: 9px;
  font-style: normal;
  color: var(--muted);
}

.account-menu {
  position: absolute;
  z-index: 60;
  top: calc(100% + 10px);
  right: 0;
  width: 268px;
  padding: 16px;
  border: 1px solid var(--line-bright);
  border-radius: 0;
  background: linear-gradient(158deg, rgba(13, 24, 45, 0.86), rgba(5, 10, 20, 0.92));
  backdrop-filter: blur(18px) saturate(1.15);
  box-shadow: 0 26px 60px rgba(2, 5, 12, 0.6);
  animation: accountIn 200ms ease both;
}

@keyframes accountIn {
  from {
    opacity: 0;
    transform: translateY(-6px);
  }
}

.account-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

.account-head strong {
  display: block;
  font-family: var(--font-data);
  font-size: 17px;
  letter-spacing: 1px;
}

.account-head span[data-bind='tier'] {
  font-family: var(--font-data);
  font-size: 9px;
  letter-spacing: 2px;
  color: var(--amber);
}

.account-key {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 14px 0;
  padding: 9px 10px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: rgba(7, 11, 21, 0.6);
}

.account-key span {
  font-family: var(--font-data);
  font-size: 8px;
  letter-spacing: 2px;
  color: var(--muted);
}

.account-key b {
  flex: 1;
  font-family: var(--font-data);
  font-size: 13px;
  letter-spacing: 1px;
  color: var(--amber);
}

.account-key .ghost-button {
  padding: 4px 8px;
  font-size: 9px;
}

.account-links {
  display: grid;
}

.account-links button,
.account-links a {
  padding: 9px 8px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--font-data);
  font-size: 10px;
  letter-spacing: 2px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background 160ms ease;
}

.account-links button:hover,
.account-links a:hover {
  background: rgba(174, 199, 225, 0.08);
}

.account-links [data-logout] {
  margin-top: 4px;
  border-top: 1px solid var(--line);
  border-radius: 0;
  color: var(--coral);
}

@media (max-width: 720px) {
  .account-id {
    display: none;
  }

  .account-menu {
    width: min(268px, calc(100vw - 32px));
  }
}

/* ----------------------------------------------------------------- astronaut */

.astronaut-card {
  display: grid;
  gap: 16px;
}

.astronaut-id {
  display: flex;
  align-items: center;
  gap: 14px;
}

.astronaut-id > div {
  display: grid;
  gap: 3px;
  min-width: 0;
}

.astronaut-id strong {
  font-family: var(--font-data);
  font-size: 26px;
  letter-spacing: 1px;
}

.astronaut-id span {
  font-family: var(--font-data);
  font-size: 12px;
  color: var(--muted);
  letter-spacing: 1px;
}

.astronaut-id em {
  font-family: var(--font-display);
  font-style: normal;
  font-size: 12px;
  letter-spacing: 2px;
  color: var(--amber);
}

.astronaut-id em:empty {
  display: none;
}

.astronaut-visor {
  position: relative;
  background: linear-gradient(160deg, rgba(88, 185, 255, 0.35), rgba(7, 11, 21, 0.9));
  color: transparent;
}

.astronaut-visor::after {
  content: "";
  position: absolute;
  inset: 26% 18% 44%;
  border-radius: 0;
  background: var(--visor-color, var(--blue-soft));
  opacity: 0.75;
}

.astronaut-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.ghost-button {
  padding: 8px 14px;
  border: 1px solid var(--line-bright);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 2px;
  text-decoration: none;
  cursor: pointer;
  transition: border-color 0.18s ease, background 0.18s ease;
}

.ghost-button:hover {
  border-color: var(--blue);
  background: rgba(88, 185, 255, 0.08);
}

.referral-progress {
  margin-top: 0;
}

/* ------------------------------------------------------------------ alliance */

.alliance-board {
  display: grid;
  gap: 6px;
  margin-top: 14px;
}

.alliance-board-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 10px;
  padding: 6px 0;
  border-top: 1px solid var(--line);
  font-family: var(--font-data);
  font-size: 12px;
  color: var(--muted);
}

.alliance-board-row i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--dot, var(--blue));
}

.alliance-board-row b {
  color: var(--text);
  font-weight: 500;
}

/* --------------------------------------------------------------- intel panel */

.digest-card,
.early-card {
  margin-bottom: 18px;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: rgba(88, 185, 255, 0.05);
}

.digest-card ul,
.early-card ul {
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 6px;
  font-family: var(--font-data);
  font-size: 12px;
  color: var(--text);
}

.early-card {
  background: transparent;
}

.early-card li {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  color: var(--muted);
}

.early-card li b {
  color: var(--text);
  font-weight: 500;
}

.early-card li.closed b {
  color: var(--coral);
}

.fairness-card .ghost-button {
  margin-top: 12px;
}

.fairness-card code {
  overflow-wrap: anywhere;
}

.invite-note {
  margin: 0 0 18px;
  padding: 12px 14px;
  border: 1px solid rgba(245, 200, 91, 0.4);
  border-radius: 0;
  background: rgba(245, 200, 91, 0.08);
  font-family: var(--font-data);
  font-size: 12px;
  color: var(--amber);
  letter-spacing: 1px;
}

/* Boarded state: the dock has nothing left to ask, and the astronaut card below
   already carries the identity — so the centre goes back to the race. */
.is-crew .join-dock {
  display: none;
}

.timeline-item.milestone-item .timeline-dot {
  background: var(--amber);
  box-shadow: 0 0 0 4px rgba(245, 200, 91, 0.16);
}

.timeline-item.landing-item .timeline-dot {
  background: var(--green);
  box-shadow: 0 0 0 4px rgba(134, 224, 175, 0.16);
}

.toast.warning .toast-icon {
  color: var(--coral);
}

.offline-note {
  padding: 10px 14px;
  font-family: var(--font-data);
  font-size: 12px;
  color: var(--coral);
}

@media (max-width: 720px) {
  .astronaut-id strong {
    font-size: 22px;
  }
}

/* ------------------------------------------------------- one screen, no page scroll

   The interface fills the viewport exactly; only the panels that hold a list scroll,
   and they do it with a hairline bar a shade lighter than the background. Below the
   desktop breakpoint the fork stacks everything into a column, so the page keeps its
   natural scrolling there. */

@media (min-width: 981px) {
  html,
  body {
    height: 100%;
    overflow: hidden;
  }

  .app-shell {
    height: 100vh;
    height: 100dvh;
    min-height: 0;
    overflow: hidden;
  }

  .main-grid {
    min-height: 0;
    overflow: hidden;
  }

  .race-column {
    display: grid;
    grid-template-rows: auto minmax(220px, 1fr) auto;
    min-height: 0;
    overflow: hidden;
  }

  /* The stage no longer sets its own height: it takes what is left. */
  .race-stage {
    min-height: 0;
  }

  /* The deck keeps its cards compact; anything longer scrolls inside the card, so
     the stage keeps the room the diagram needs. */
  .lower-deck {
    min-height: 0;
    max-height: min(292px, 32vh);
  }

  .deck-card {
    padding: 16px 20px;
  }

  .deck-card {
    min-height: 0;
    overflow-y: auto;
  }

  .intel-panel {
    display: grid;
    grid-template-rows: auto minmax(0, 1fr);
    min-height: 0;
    overflow: hidden;
  }

  .panel-content {
    min-height: 0;
    overflow-y: auto;
  }

  /* The tab strip no longer needs to stick: it is outside the scrolling area. */
  .panel-tabs {
    position: relative;
  }
}

/* Both chips hang on the free right-hand side; JS pins each one to its own lane. */
.event-chip-a,
.event-chip-b {
  right: 6%;
  left: auto;
}

/* Thin, quiet scrollbars for the panels that scroll. */
.panel-content,
.deck-card,
.race-column,
.rail {
  scrollbar-width: thin;
  scrollbar-color: rgba(174, 199, 225, 0.2) transparent;
}

.panel-content::-webkit-scrollbar,
.deck-card::-webkit-scrollbar,
.race-column::-webkit-scrollbar,
.rail::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

.panel-content::-webkit-scrollbar-track,
.deck-card::-webkit-scrollbar-track,
.race-column::-webkit-scrollbar-track,
.rail::-webkit-scrollbar-track {
  background: transparent;
}

.panel-content::-webkit-scrollbar-thumb,
.deck-card::-webkit-scrollbar-thumb,
.race-column::-webkit-scrollbar-thumb,
.rail::-webkit-scrollbar-thumb {
  border-radius: 0;
  background: rgba(174, 199, 225, 0.18);
}

.panel-content::-webkit-scrollbar-thumb:hover,
.deck-card::-webkit-scrollbar-thumb:hover,
.race-column::-webkit-scrollbar-thumb:hover,
.rail::-webkit-scrollbar-thumb:hover {
  background: rgba(174, 199, 225, 0.34);
}

/* --------------------------------------------------------------- credentials */

/* Quieter twin of the coral call to action, for the secondary auth buttons. */
.compact-button.ghost-compact {
  border-color: var(--line-bright);
  background: transparent;
  color: var(--text);
}

.compact-button.ghost-compact:hover {
  border-color: var(--blue);
  background: rgba(88, 185, 255, 0.1);
}

.key-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 12px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: rgba(88, 185, 255, 0.05);
}

.key-row > span {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--muted);
}

.key-row > b {
  flex: 1;
  font-family: var(--font-data);
  font-size: 19px;
  font-weight: 700;
  letter-spacing: 3px;
  color: var(--amber);
  user-select: all;
}

.key-row .ghost-button {
  padding: 5px 10px;
  font-size: 11px;
}

.key-note {
  margin: -8px 0 0;
  font-family: var(--font-data);
  font-size: 11px;
  line-height: 1.5;
  color: var(--muted);
}

.signin-form {
  display: grid;
  gap: 10px;
  margin: 18px 0 20px;
}

.signin-form label {
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--muted);
}

.signin-form input {
  height: 52px;
  padding: 0 16px;
  border: 1px solid var(--line-bright);
  border-radius: 0;
  background: rgba(4, 9, 19, 0.8);
  color: var(--text);
  font: 700 24px/1 var(--font-data);
  letter-spacing: 6px;
  text-transform: uppercase;
}

.signin-form input:focus {
  outline: none;
  border-color: var(--blue);
}

.signin-form input::placeholder {
  color: rgba(128, 144, 165, 0.5);
}

.signin-form .compact-button {
  justify-self: start;
  min-height: 42px;
}

.form-error {
  margin: 0;
  font-family: var(--font-data);
  font-size: 12px;
  color: var(--coral);
}

/* ------------------------------------------- the outcome line moves to the top */

@media (min-width: 981px) {
  .fate-transmission {
    top: 74px;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: center;
    gap: 3px 16px;
    width: min(1040px, calc(100% - 56px));
  }

  .fate-transmission > span {
    font-size: 10px;
    letter-spacing: 0.18em;
  }

  .fate-transmission strong {
    margin-top: 0;
    gap: 4px 12px;
    font-size: clamp(15px, 1.35vw, 20px);
  }

  .fate-transmission p {
    margin: 0;
    font-size: 11px;
  }
}

.recover-block {
  /* The footnote sits right below, so the block keeps its own room. */
  margin: 6px 0 26px;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}

.recover-block p {
  margin: 0 0 14px;
  font-family: var(--font-data);
  font-size: 12px;
  line-height: 1.6;
  color: var(--muted);
}

.recover-block b {
  color: var(--text);
}

#signin-dialog .dialog-footnote {
  margin-top: 6px;
}

.protection-note {
  margin: -4px 0 0;
  font-family: var(--font-data);
  font-size: 11px;
  line-height: 1.5;
  color: var(--amber);
}

.protection-note.protected {
  color: var(--green);
}

/* ------------------------------------------------------------ rail as a view switch

   CREW and ALLIANCE open as one centred modal over the race: glass, not a slab, so
   the trajectory keeps showing through it. The rail decides which card it holds. */

.deck-dialog {
  position: relative;
  width: min(700px, calc(100vw - 40px));
  max-height: min(76vh, 760px);
  padding: 0;
  border: 1px solid rgba(174, 199, 225, 0.22);
  border-radius: 0;
  background:
    linear-gradient(158deg, rgba(13, 24, 45, 0.72), rgba(5, 10, 20, 0.82));
  box-shadow:
    0 44px 120px rgba(0, 0, 0, 0.62),
    inset 0 1px 0 rgba(174, 199, 225, 0.1);
  backdrop-filter: blur(22px) saturate(1.15);
  color: var(--text);
  overflow: hidden;
}

.deck-dialog::backdrop {
  background: rgba(3, 7, 16, 0.52);
  backdrop-filter: blur(4px);
}

/* Two decorative layers: a cold glow off the hull, and the telemetry grid. */
.deck-dialog-glow {
  position: absolute;
  inset: -30% -10% auto -10%;
  height: 80%;
  pointer-events: none;
  background:
    radial-gradient(circle at 28% 0%, rgba(88, 185, 255, 0.18), transparent 58%),
    radial-gradient(circle at 82% 8%, rgba(255, 98, 77, 0.13), transparent 52%);
}

.deck-dialog-grid {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.14;
  background-image:
    linear-gradient(rgba(151, 190, 219, 0.22) 1px, transparent 1px),
    linear-gradient(90deg, rgba(151, 190, 219, 0.22) 1px, transparent 1px);
  background-size: 54px 54px;
  mask-image: linear-gradient(to bottom, #000, transparent 72%);
}

.deck-dialog .lower-deck {
  position: relative;
  display: block;
  min-height: 0;
  max-height: min(76vh, 760px);
  overflow-y: auto;
  border: 0;
  background: transparent;
}

.deck-dialog .deck-card {
  padding: 26px 28px 30px;
  background: transparent;
}

.deck-dialog .deck-card + .deck-card {
  border: 0;
}

/* One card at a time; the rail says which. */
body[data-view="crew"] .alliance-card,
body[data-view="crew"] .shop-card,
body[data-view="alliance"] .your-astronaut,
body[data-view="alliance"] .shop-card,
body[data-view="shop"] .your-astronaut,
body[data-view="shop"] .alliance-card {
  display: none;
}

.deck-card > header {
  position: relative;
  padding-right: 34px;
}

.deck-close {
  position: absolute;
  top: -6px;
  right: 0;
  width: 30px;
  height: 30px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: transparent;
  color: var(--muted);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
}

.deck-close:hover {
  border-color: var(--line-bright);
  color: var(--text);
}

@media (min-width: 981px) {
  .deck-dialog .astronaut-actions {
    flex-wrap: wrap;
  }
}

/* ------------------------------------------------- the log stays three headlines */

.entry-toggle {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
}

.entry-toggle i {
  flex: none;
  font-family: var(--font-data);
  font-size: 13px;
  font-style: normal;
  line-height: 1;
  color: var(--muted);
}

.entry-toggle:hover i {
  color: var(--text);
}

.entry-toggle:hover strong,
.entry-toggle:hover h3 {
  color: var(--blue-soft);
}

.priority-event .entry-toggle {
  margin: 0;
}

.priority-event .entry-toggle h3 {
  margin: 0;
}

/* Everything past the third headline waits behind the button. */
.timeline:not(.expanded) .timeline-item.extra {
  display: none;
}


/* ------------------------------------------------------------------ suit store
 * Section 25. Every suit shows three things and nothing else: what it costs, how
 * many are left, and what it looks like on a body. The count is the whole point —
 * a limited run is only limited if you can watch it run out.
 */
.shop-note {
  margin: 0 0 16px;
  max-width: 52ch;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.55;
}

.shop-code {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--line);
  background: rgba(7, 12, 23, 0.5);
}

.shop-code label {
  color: var(--muted);
  font-family: var(--font-display);
  font-size: 11px;
  letter-spacing: 2.4px;
}

.shop-code input {
  flex: 1 1 160px;
  min-width: 0;
  padding: 9px 12px;
  border: 1px solid var(--line-bright);
  border-radius: 0;
  background: rgba(3, 7, 16, 0.6);
  color: var(--text);
  font-family: var(--font-data);
  font-size: 13px;
  letter-spacing: 2px;
  text-transform: uppercase;
}

.shop-code input:focus {
  outline: none;
  border-color: var(--blue);
}

.shop-feedback {
  margin: 10px 0 0;
  font-family: var(--font-data);
  font-size: 12px;
  letter-spacing: 0.6px;
}

.shop-feedback[data-tone="good"] { color: var(--green); }
.shop-feedback[data-tone="bad"] { color: var(--coral); }
.shop-feedback[data-tone="plain"] { color: var(--muted); }

.shop-grid {
  display: grid;
  gap: 14px;
  margin-top: 16px;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
}

.shop-item {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-top: 2px solid var(--card-accent, var(--line-bright));
  background: rgba(7, 12, 23, 0.52);
}

.shop-item[data-rarity="LEGENDARY"] { --card-accent: var(--amber); }
.shop-item[data-rarity="RARE"] { --card-accent: var(--blue); }

.shop-item[data-sold-out="true"] { opacity: 0.55; }

.shop-preview {
  display: block;
  width: 100%;
  height: 132px;
  object-fit: contain;
  padding: 10px 0 0;
  background:
    radial-gradient(circle at 50% 42%, rgba(88, 185, 255, 0.12), transparent 62%);
}

.shop-body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px 14px;
}

.shop-name {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-family: var(--font-display);
  font-size: 14px;
  letter-spacing: 1.4px;
}

.shop-price {
  color: var(--text);
  font-family: var(--font-data);
  font-size: 13px;
  white-space: nowrap;
}

.shop-price s {
  margin-right: 6px;
  color: var(--muted);
  text-decoration-color: var(--coral);
}

.shop-price em {
  color: var(--green);
  font-style: normal;
}

.shop-blurb {
  margin: 0;
  flex: 1;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.5;
}

/* The supply bar: how much of this run is already on somebody's back. */
.shop-supply {
  display: grid;
  gap: 5px;
  font-family: var(--font-data);
  font-size: 11px;
  letter-spacing: 0.6px;
  color: var(--muted);
}

.shop-supply i {
  display: block;
  height: 3px;
  background: var(--line);
}

.shop-supply i > b {
  display: block;
  height: 100%;
  background: var(--card-accent, var(--blue));
}

.shop-action {
  padding: 9px 12px;
  border: 1px solid var(--line-bright);
  border-radius: 0;
  background: transparent;
  color: var(--text);
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 2px;
  cursor: pointer;
  transition: border-color 0.18s ease, background 0.18s ease;
}

.shop-action:hover:not(:disabled) {
  border-color: var(--blue);
  background: rgba(88, 185, 255, 0.08);
}

.shop-action[data-kind="free"]:hover:not(:disabled) {
  border-color: var(--amber);
  background: rgba(245, 200, 91, 0.1);
}

.shop-action:disabled {
  color: var(--muted);
  cursor: default;
}

.shop-owned {
  color: var(--green);
  font-family: var(--font-display);
  font-size: 12px;
  letter-spacing: 2px;
  text-align: center;
  padding: 9px 12px;
  border: 1px dashed rgba(134, 224, 175, 0.4);
}
