:root {
  --ink: #f8ecd2;
  --ink-dim: #cdbda1;
  --accent: #ffbf69;
  --accent-strong: #ff8f5c;
  --frame: #0b0b12;
  --frame-edge: #3b2f45;
  --panel: #211a2d;
  --panel-soft: #2d2140;
  --panel-lift: #51375e;
  --danger: #ff6f72;
  --hud-edge: 10px;
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
  /* Where overlays and notices start: under the first row of the top bar, which
     holds 28 pixel controls on a desktop and 44 pixel controls where a finger or
     a narrow window needs them. Only CSS decides it, so a resize can never leave
     them where the bar used to end. */
  --hud-clearance: calc(52px + var(--safe-top));
}

* {
  box-sizing: border-box;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

*::-webkit-scrollbar {
  display: none;
  width: 0;
  height: 0;
}

html {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

body.airspace-body {
  height: 100%;
  margin: 0;
  overflow: hidden;
  background: #0b0b12;
  color: var(--ink);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  image-rendering: pixelated;
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
}

button {
  font: inherit;
}

button:focus-visible, a:focus-visible, input:focus-visible, select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (pointer: coarse), (max-width: 560px) {
  :root {
    --hud-clearance: calc(var(--hud-edge) + var(--safe-top) + 44px + 8px);
  }

  button, input, select, summary {
    min-height: 44px;
    min-width: 44px;
  }

  input, select, [data-room-link-fallback] {
    font-size: 16px;
  }
}

[hidden] {
  display: none !important;
}

.airspace-room-error {
  display: grid;
  align-content: center;
  gap: 14px;
  width: min(520px, calc(100% - 32px));
  min-height: 100%;
  margin: 0 auto;
  color: var(--ink);
  text-align: center;
}

.airspace-room-error h1,
.airspace-room-error p {
  margin: 0;
}

.airspace-room-error a {
  justify-self: center;
  color: var(--accent);
}

#airspace-coordinate-debug {
  position: absolute;
  left: var(--hud-edge);
  bottom: var(--hud-edge);
  max-width: min(360px, calc(100% - 20px));
  max-height: 40%;
  overflow: clip;
  padding: 10px;
  background: rgba(11, 11, 18, 0.9);
  border: 2px solid var(--frame-edge);
  pointer-events: none;
}

#airspace-coordinate-debug h2 {
  margin: 0 0 6px;
  color: var(--accent);
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

#airspace-coordinate-debug pre {
  margin: 0;
  font: inherit;
  font-size: 10px;
  line-height: 1.5;
  white-space: pre-wrap;
}

[data-room-link-fallback] {
  display: block;
  width: 100%;
  margin-top: 8px;
  padding: 8px;
  color: var(--ink);
  background: var(--panel-lift);
  border: 1px solid var(--frame-edge);
  font: inherit;
  font-size: 11px;
}

.primary-button,
.secondary-button,
.danger-button {
  border: 2px solid var(--frame);
  padding: 7px 9px;
  color: var(--ink);
  cursor: pointer;
  font-size: 11px;
}

.primary-button {
  background: #9b4c52;
}

.secondary-button {
  background: var(--panel-soft);
}

.danger-button {
  background: #642b39;
  color: #ffd9d4;
}

@media (hover: hover) {
  .primary-button:hover,
  .secondary-button:hover,
  .danger-button:hover {
    filter: brightness(1.18);
  }
}

.primary-button:active,
.secondary-button:active,
.danger-button:active {
  filter: brightness(1.18);
}

.muted {
  color: var(--ink-dim);
}


/* The application shell owns the whole viewport; nothing scrolls or sits
   below the world. */
.airspace-shell_cgVk6A {
  position: fixed;
  inset: 0;
  overflow: hidden;
  /* A double tap is two taps, not a zoom; pinch zoom stays with the browser. */
  touch-action: manipulation;
}

/* While a keyboard covers the bottom of the layout viewport and a field has
   focus, the shell shrinks to the area the player can see. */
html[data-airspace-keyboard] .airspace-shell_cgVk6A {
  top: var(--airspace-viewport-top);
  bottom: auto;
  height: var(--airspace-viewport-height);
}

.airspace-boot_cgVk6A {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  gap: 6px;
  text-align: center;
  background: radial-gradient(circle at top, #342241 0%, #15121c 52%, #0b0b12 100%);
  overflow-y: auto;
  padding: max(20px, var(--safe-top)) max(20px, var(--safe-right)) max(20px, var(--safe-bottom)) max(20px, var(--safe-left));
}

.airspace-boot-room_cgVk6A {
  margin: 0;
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.airspace-boot-line_cgVk6A {
  margin: 0;
  color: var(--ink-dim);
  font-size: 13px;
}

.airspace-boot-error_cgVk6A {
  display: grid;
  gap: 8px;
  justify-items: center;
  max-width: min(420px, calc(100vw - 40px));
}

.airspace-boot-message_cgVk6A {
  margin: 0;
  color: #ffe3de;
  font-size: 12px;
  line-height: 1.5;
}

.airspace-boot-detail_cgVk6A {
  margin: 0;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.4;
}

.airspace-boot-detail_cgVk6A:empty {
  display: none;
}

.airspace-boot-retry_cgVk6A {
  padding: 7px 14px;
  color: var(--ink);
  background: var(--panel-soft);
  border: 2px solid var(--frame);
  cursor: pointer;
  font-size: 12px;
}

@media (hover: hover) {
  .airspace-boot-retry_cgVk6A:hover {
    background: var(--panel-lift);
  }
}

.airspace-boot-retry_cgVk6A:active {
  background: var(--panel-lift);
}

.airspace-boot-retry_cgVk6A:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}


/* World viewport: the artwork keeps its fixed pixel size in the camera layer
   and is never stretched by the viewport. The layer takes the size of the room's
   map from the page element, where the script writes it, and falls back to the
   Belgrade map until it has. */
.airspace-world_DVOLNg {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #15121c;
  cursor: crosshair;
  touch-action: pinch-zoom;
  user-select: none;
}

.airspace-world_DVOLNg:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -4px;
}

.airspace-camera_DVOLNg {
  position: absolute;
  top: 0;
  left: 0;
  width: var(--map-width, 1672px);
  height: var(--map-height, 941px);
  transform-origin: 0 0;
  will-change: transform;
}

.airspace-map_DVOLNg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  pointer-events: none;
  user-select: none;
  image-rendering: pixelated;
}

.map-isometric_DVOLNg {
  display: none;
}

/* The page marks the view on its own element, which no patch resets, as well as
   on the stage, which every whole page patch resets. Either one picks the map. */
.mode-isometric .map-flat_DVOLNg {
  display: none;
}

.mode-isometric .map-isometric_DVOLNg {
  display: block;
}

/* The full detail of a town: the page script fills this layer with one image for each tile
   near the camera, drawn over the overview picture of the view. */
.airspace-detail_DVOLNg {
  position: absolute;
  inset: 0;
  pointer-events: none;
  user-select: none;
}

.airspace-detail_DVOLNg > img {
  position: absolute;
  display: block;
  max-width: none;
  pointer-events: none;
  user-select: none;
}

/* A map that shows with fewer device pixels than its art has pixels is drawn smoothly, which
   averages the art pixels under each device pixel. The camera marks the page while that holds. */
.is-map-smooth .airspace-map_DVOLNg,
.is-map-smooth .airspace-detail_DVOLNg {
  image-rendering: auto;
}


.airspace-avatars_QXfAYw {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 2;
}

.airspace-avatar_QXfAYw {
  position: absolute;
  left: calc(var(--origin-x) + (var(--mx) + 0.5) / var(--grid-columns, 28) * var(--across-x) + (var(--my) + 0.5) / var(--grid-rows, 16) * var(--depth-x));
  top: calc(var(--origin-y) + (var(--mx) + 0.5) / var(--grid-columns, 28) * var(--across-y) + (var(--my) + 0.5) / var(--grid-rows, 16) * var(--depth-y));
  /* An airhead is 8% of the map across at the standard size, and a map of a whole
     town sets --avatar-scale lower so an airhead is not taller than a street. */
  width: calc(8% * var(--avatar-scale, 1));
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  /* The atlas foot baseline, independent of labels and view mode. */
  transform: translate(-50%, -92%);
  /* Each step restarts the glide, and a restarted transition spends its first
     frame where it starts, so every glide starts one frame in. A glide also
     lasts longer than the 100 ms between the steps of a held key or a click
     walk, so a step that arrives a little late never stops a walking airhead. */
  transition: left 0.16s linear -16ms, top 0.16s linear -16ms;
  z-index: 3;
}

.airspace-avatar_QXfAYw.is-self {
  z-index: 5;
}

.airspace-avatar-sprite_QXfAYw {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background-repeat: no-repeat;
  background-size: 400% 400%;
  background-position: var(--sprite-x) var(--sprite-y);
  filter: drop-shadow(0 3px 2px rgba(0, 0, 0, 0.48));
}

.avatar-woman .airspace-avatar-sprite_QXfAYw {
  background-image: url("/public/generated/sprites/flat/airhead-woman-walk-cycle.png");
}

.avatar-man .airspace-avatar-sprite_QXfAYw {
  background-image: url("/public/generated/sprites/flat/airhead-man-walk-cycle.png");
}

.avatar-builder .airspace-avatar-sprite_QXfAYw {
  background-image: url("/public/generated/sprites/flat/airhead-builder-walk-cycle.png");
}

.avatar-hacker .airspace-avatar-sprite_QXfAYw {
  background-image: url("/public/generated/sprites/flat/airhead-hacker-walk-cycle.png");
}

.is-changing-view .airspace-avatar_QXfAYw {
  transition: none;
}

.mode-isometric .avatar-woman .airspace-avatar-sprite_QXfAYw {
  background-image: url("/public/generated/sprites/isometric/airhead-woman-walk-cycle.png");
}

.mode-isometric .avatar-man .airspace-avatar-sprite_QXfAYw {
  background-image: url("/public/generated/sprites/isometric/airhead-man-walk-cycle.png");
}

.mode-isometric .avatar-builder .airspace-avatar-sprite_QXfAYw {
  background-image: url("/public/generated/sprites/isometric/airhead-builder-walk-cycle.png");
}

.mode-isometric .avatar-hacker .airspace-avatar-sprite_QXfAYw {
  background-image: url("/public/generated/sprites/isometric/airhead-hacker-walk-cycle.png");
}

/* The local airhead is identified by a soft ground marker instead of a box. */
.airspace-avatar-marker_QXfAYw {
  display: none;
  position: absolute;
  left: 50%;
  bottom: 8%;
  width: 66%;
  height: 16%;
  transform: translate(-50%, 50%);
  border-radius: 50%;
  background: radial-gradient(ellipse at center, rgba(255, 191, 105, 0.45), rgba(255, 191, 105, 0) 72%);
  box-shadow: 0 0 0 1px rgba(255, 191, 105, 0.2);
  pointer-events: none;
}

.airspace-avatar_QXfAYw.is-self .airspace-avatar-marker_QXfAYw {
  display: block;
}

/* The label floats over the world and stays one line, so a very long name is
   shortened here with an ellipsis. The width fits the names X allows in
   practice, and the People list shows every name in full. */
.airspace-avatar-name_QXfAYw {
  position: absolute;
  top: 100%;
  max-width: 220px;
  margin-top: -6px;
  padding: 2px 4px;
  overflow: hidden;
  color: #fff8e8;
  background: rgba(11, 11, 18, 0.78);
  font-size: clamp(7px, 0.7vw, 10px);
  line-height: 1;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.airspace-avatar_QXfAYw.is-self .airspace-avatar-name_QXfAYw {
  display: none;
}

/* The X badge sits under the display name. It is its own element with the X
   mark, so a display name that looks like a handle can never pass for one. It is
   text, never a link, so click to walk keeps working on the avatar. */
.airspace-avatar-handle_QXfAYw {
  position: absolute;
  top: calc(100% + 8px);
  max-width: 140px;
  padding: 1px 4px 1px 3px;
  overflow: hidden;
  color: #dbe8ff;
  background: rgba(11, 11, 18, 0.78);
  border-left: 2px solid #8ab4ff;
  font-size: clamp(7px, 0.65vw, 9px);
  line-height: 1;
  text-overflow: ellipsis;
  unicode-bidi: isolate;
  white-space: nowrap;
}

.airspace-avatar-handle_QXfAYw::before {
  content: "";
  display: inline-block;
  width: 0.95em;
  height: 0.95em;
  margin-right: 0.3em;
  vertical-align: -0.12em;
  background: currentColor;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'/%3E%3C/svg%3E") center / contain no-repeat;
}

.airspace-avatar_QXfAYw.is-self .airspace-avatar-handle_QXfAYw {
  display: none;
}

/* A Sim label marks a simulated airhead, which the server drives. It sits under
   the display name where the X badge would, and a sim never has an X badge, so
   the two never meet. */
.airspace-avatar-sim_QXfAYw {
  position: absolute;
  top: calc(100% + 8px);
  padding: 1px 4px 1px 3px;
  color: #ffe9b8;
  background: rgba(11, 11, 18, 0.78);
  border-left: 2px solid #ffbf69;
  font-size: clamp(7px, 0.65vw, 9px);
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

/* The OG label marks the maker of AirSpace. It rests just above the head, where the
   typing bubble also appears, so it steps aside while its airhead types. It is
   its own element, so a display name that says OG never passes for one. */
.airspace-avatar-og_QXfAYw {
  position: absolute;
  left: 50%;
  bottom: 97%;
  padding: 1px 4px;
  border-radius: 2px;
  background: linear-gradient(#ffd98a, #f2a93b);
  box-shadow: 0 0 0 1px rgba(11, 11, 18, 0.85), 0 2px 3px rgba(0, 0, 0, 0.45);
  color: #2a1a00;
  font-size: clamp(8px, 0.8vw, 11px);
  font-weight: 800;
  letter-spacing: 0.08em;
  line-height: 1;
  transform: translateX(-50%);
  white-space: nowrap;
}

.airspace-avatar_QXfAYw.is-typing .airspace-avatar-og_QXfAYw {
  display: none;
}

/* A typing bubble floats over the head of an airhead who is composing a chat
   message. Its tail tip rests just above the highest head in the sprite sheets,
   so the bubble stays put when the airhead turns. The two views have their own
   art, drawn flat for the 2D view and in perspective for the 2.5D view. */
.airspace-avatar-typing_QXfAYw {
  position: absolute;
  left: 50%;
  bottom: 97%;
  width: 52%;
  aspect-ratio: 192 / 176;
  background: url("/public/generated/sprites/flat/airhead-typing-bubble.png") center bottom / 100% 100% no-repeat;
  filter: drop-shadow(0 2px 1px rgba(0, 0, 0, 0.4));
  transform: translateX(-50%);
  transform-origin: 50% 100%;
  animation: airhead-typing-pop_QXfAYw 140ms ease-out, airhead-typing-bob_QXfAYw 1.3s ease-in-out 140ms infinite;
  pointer-events: none;
}

.mode-isometric .airspace-avatar-typing_QXfAYw {
  background-image: url("/public/generated/sprites/isometric/airhead-typing-bubble.png");
}

/* Developer diagnostics stay hidden unless the page opts in with ?debug=1. */
.is-debug .airspace-avatar_QXfAYw[data-coord]::after {
  content: attr(data-coord);
  position: absolute;
  top: calc(100% + 9px);
  left: 50%;
  transform: translateX(-50%);
  padding: 2px 3px;
  color: #fff8e8;
  background: #0b0b12;
  font-size: 9px;
  line-height: 1.2;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {

    .airspace-avatar-typing_QXfAYw {
      animation: none;
    }
}

/* Names are typed by airheads, so right to left text in one never reorders the
   text around it. */
.airspace-avatar-name_QXfAYw {
  unicode-bidi: isolate;
}

@keyframes airhead-typing-pop_QXfAYw {
  from {
    opacity: 0;
    transform: translateX(-50%) scale(0.6);
  }

  to {
    opacity: 1;
    transform: translateX(-50%) scale(1);
  }
}

@keyframes airhead-typing-bob_QXfAYw {
  0%,
  100% {
    transform: translateX(-50%) translateY(0);
  }

  50% {
    transform: translateX(-50%) translateY(-6%);
  }
}


/* HUD: overlays never intercept world input outside their controls. */
.airspace-hud_APw8BQ {
  position: absolute;
  inset: 0;
  z-index: 10;
  pointer-events: none;
}

.airspace-hud_APw8BQ button {
  pointer-events: auto;
}

.hud-top_APw8BQ {
  position: absolute;
  top: var(--hud-edge);
  left: var(--hud-edge);
  right: var(--hud-edge);
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.hud-cluster_APw8BQ {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 8px;
}

.hud-brand_APw8BQ {
  display: inline-flex;
  align-items: center;
  border: 2px solid var(--frame);
  background: rgba(33, 26, 45, 0.92);
  color: var(--accent);
  padding: 6px 9px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1;
}

/* The world brand is a plain label in the HUD. */

.hud-visitor_APw8BQ {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 6px 5px 9px;
  background: rgba(33, 26, 45, 0.92);
  border: 2px solid var(--frame);
  font-size: 11px;
  line-height: 1;
}

.hud-visitor-label_APw8BQ {
  color: var(--ink-dim);
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.hud-visitor-join_APw8BQ {
  border: 2px solid var(--frame);
  padding: 4px 7px;
  background: #9b4c52;
  color: var(--ink);
  cursor: pointer;
  font-size: 10px;
  line-height: 1;
}

@media (hover: hover) {
  .hud-visitor-join_APw8BQ:hover {
    filter: brightness(1.18);
  }
}

.hud-visitor-join_APw8BQ:active {
  filter: brightness(1.18);
}

/* An unnamed airhead is invited to choose a name by a compact chip in the top
   bar, beside the room chip, so the world stays clear and click-to-walk works.
   The accent edge sets it apart, and its action pulses a few times on arrival. */
.hud-name-prompt_APw8BQ {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  max-width: 100%;
  padding: 1px 2px 1px 8px;
  background: rgba(33, 26, 45, 0.92);
  border: 2px solid var(--accent);
  font-size: 11px;
  line-height: 1;
}

.hud-name-prompt_APw8BQ:empty {
  display: none;
}

.hud-name-prompt-label_APw8BQ {
  min-width: 0;
  overflow: hidden;
  color: var(--ink-dim);
  font-size: 10px;
  letter-spacing: 0.04em;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.hud-name-prompt-label_APw8BQ strong {
  color: var(--ink);
  font-weight: 700;
}

.hud-name-prompt-action_APw8BQ {
  flex: 0 0 auto;
  border: 2px solid var(--frame);
  padding: 4px 7px;
  background: #9b4c52;
  color: var(--ink);
  cursor: pointer;
  font-size: 10px;
  line-height: 1;
  animation: airspace-name-nudge_APw8BQ 2.4s ease-in-out 3;
}

@media (hover: hover) {
  .hud-name-prompt-action_APw8BQ:hover {
    filter: brightness(1.18);
  }
}

.hud-name-prompt-action_APw8BQ:active {
  filter: brightness(1.18);
}

.hud-name-prompt-action_APw8BQ:focus-visible,
.hud-link_APw8BQ:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {

    .hud-name-prompt-action_APw8BQ {
      animation: none;
    }
}

.hud-chip_APw8BQ,
.hud-icon_APw8BQ,
.hud-option_APw8BQ {
  border: 2px solid var(--frame);
  background: rgba(33, 26, 45, 0.92);
  color: var(--ink);
  padding: 6px 10px;
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
}

.hud-chip_APw8BQ {
  display: inline-flex;
  align-items: center;
  gap: 7px;
}

.hud-room_APw8BQ {
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.hud-client_APw8BQ {
  color: var(--ink);
  font-size: 11px;
  letter-spacing: 0.04em;
}

.hud-sep_APw8BQ {
  color: var(--ink-dim);
}

.hud-icon_APw8BQ {
  min-width: 34px;
  text-align: center;
}

@media (hover: hover) {
  .hud-chip_APw8BQ:hover,
  .hud-icon_APw8BQ:hover,
  .hud-option_APw8BQ:hover {
    background: var(--panel-lift);
  }
}

.hud-chip_APw8BQ:active,
.hud-icon_APw8BQ:active,
.hud-option_APw8BQ:active {
  background: var(--panel-lift);
}

.hud-chip_APw8BQ:focus-visible,
.hud-icon_APw8BQ:focus-visible,
.hud-option_APw8BQ:focus-visible,
.hud-roster-tab_APw8BQ:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.hud-popover_APw8BQ {
  position: absolute;
  top: 52px;
  z-index: 1;
  max-height: calc(100% - 64px);
  overflow: clip;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: 12px;
  background: rgba(26, 20, 36, 0.97);
  border: 3px solid var(--frame);
  box-shadow: 0 0 0 3px var(--frame-edge), 0 16px 32px rgba(0, 0, 0, 0.55);
  pointer-events: auto;
}

.hud-popover_APw8BQ::-webkit-scrollbar {
  display: none;
}

.hud-roster_APw8BQ {
  left: var(--hud-edge);
  width: min(720px, calc(100% - 20px));
  overflow: clip;
}

.hud-roster-header_APw8BQ {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.hud-roster-tabs_APw8BQ {
  display: grid;
  flex: 1 1 auto;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  min-width: 0;
}

.hud-roster-tab_APw8BQ {
  min-width: 0;
  padding: 6px 8px;
  border: 2px solid var(--frame);
  background: var(--panel-soft);
  color: var(--ink-dim);
  cursor: pointer;
  font-size: 11px;
  line-height: 1.1;
}

.hud-roster-tab_APw8BQ[aria-pressed="true"] {
  background: var(--panel-lift);
  color: var(--accent);
}

@media (hover: hover) {
  .hud-roster-tab_APw8BQ:hover {
    filter: brightness(1.18);
  }
}

.hud-roster-tab_APw8BQ:active {
  filter: brightness(1.18);
}

.hud-roster-close_APw8BQ {
  flex: 0 0 34px;
}

.hud-roster-panel_APw8BQ {
  min-width: 0;
}

/* Only the menu's content scrolls. The footer stays inside the frame, so Close
   is always reachable and a tall menu never grows past the available space. */
.hud-menu_APw8BQ {
  right: var(--hud-edge);
  display: flex;
  flex-direction: column;
  width: min(300px, calc(100% - var(--hud-edge) * 2 - var(--safe-left) - var(--safe-right)));
  padding: 0;
  overflow: hidden;
}

.hud-menu-content_APw8BQ {
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  padding: 12px;
  overflow-x: hidden;
  overflow-y: auto;
  overflow-wrap: anywhere;
  overscroll-behavior: contain;
  touch-action: pan-y pinch-zoom;
  scrollbar-width: thin;
  scrollbar-color: var(--ink-dim) var(--panel);
  scrollbar-gutter: stable;
  -ms-overflow-style: auto;
}

.hud-menu-content_APw8BQ::-webkit-scrollbar {
  display: block;
  width: 8px;
  height: 0;
}

.hud-menu-content_APw8BQ::-webkit-scrollbar-track {
  background: var(--panel);
}

.hud-menu-content_APw8BQ::-webkit-scrollbar-thumb {
  min-height: 24px;
  background: var(--ink-dim);
  border: 2px solid var(--panel);
}

.hud-menu-content_APw8BQ .hud-option_APw8BQ {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* The credit closes the scrolling menu, so it never covers the world. Its link
   opens the maker's profile on X in a new tab. */
.hud-credit_APw8BQ {
  margin: 8px 0 2px;
  color: var(--ink-dim);
  font-size: 10px;
  line-height: 1.5;
  text-align: center;
}

.hud-credit-link_APw8BQ {
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

@media (hover: hover) {
  .hud-credit-link_APw8BQ:hover {
    color: var(--accent-strong);
  }
}

.hud-menu-footer_APw8BQ {
  flex: 0 0 auto;
  padding: 8px 12px;
  border-top: 2px solid var(--frame-edge);
  background: var(--panel);
}

.hud-menu-footer_APw8BQ .hud-close_APw8BQ {
  margin-top: 0;
}

/* Room chat: a drawer down the right edge. Its list scrolls inside it and its
   form stays pinned below, so the world stays visible and clickable beside it.
   The drawer never covers an invitation or a call. On a narrow window it sits in
   the lower column that also holds the proximity and call panels and gives up
   height to them. On a wider window it keeps its place at the edge and that
   column moves to its left. */
.hud-chat_APw8BQ {
  position: relative;
  top: auto;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  align-self: flex-end;
  gap: 8px;
  width: min(320px, 100%);
  min-height: 0;
  max-height: none;
  margin-top: calc(52px - var(--hud-edge));
  animation: airspace-chat-in_APw8BQ 140ms ease-out;
}

@media (min-width: 761px) {

    .hud-chat_APw8BQ {
      position: absolute;
      top: 52px;
      right: var(--hud-edge);
      bottom: var(--hud-edge);
      flex: none;
      width: 320px;
      max-height: calc(100% - 64px);
      margin-top: 0;
    }

    /* The drawer's width and an edge on each side stay free of panels. */
    .airspace-context_APw8BQ:has(> .hud-chat_APw8BQ:not([hidden])) {
      padding-right: calc(var(--hud-edge) * 2 + 320px);
    }
}

.hud-chat-header_APw8BQ {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.hud-chat-body_APw8BQ {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.hud-chat-header_APw8BQ .hud-title_APw8BQ {
  margin: 0;
}

/* A private chat's tab shows its own panel, so the room's note, list, and name
   hint wait until the room tab is chosen again. */
#airspace-chat[data-chat-view="private"] > .hud-chat-body_APw8BQ > :is(#airspace-chat-log, #airspace-chat-name, [data-chat-privacy]) {
  display: none;
}

.hud-chat-privacy_APw8BQ {
  flex: 0 0 auto;
  padding: 6px 8px;
  background: var(--panel-soft);
  border: 2px solid var(--frame);
  font-size: 10px;
}

/* Chat is where a name matters most, so an unnamed airhead sees how others see
   them right above the message field. */
.hud-chat-name_APw8BQ {
  flex: 0 0 auto;
  padding: 6px 8px;
  background: var(--panel-soft);
  border: 2px solid var(--accent);
  font-size: 10px;
}

.hud-chat-name_APw8BQ:empty {
  display: none;
}

.hud-chat-name_APw8BQ strong {
  color: var(--ink);
  overflow-wrap: anywhere;
  unicode-bidi: isolate;
}

/* Why a message was not sent, right above the field it is about. The room banner
   sits behind the drawer on a narrow window, so the reason cannot live there. */
.hud-chat-status_APw8BQ {
  flex: 0 0 auto;
  margin: 0;
  padding: 6px 8px;
  background: rgba(100, 43, 57, 0.95);
  border: 2px solid var(--frame);
  color: #ffe3de;
  font-size: 11px;
  line-height: 1.4;
}

.hud-chat-status_APw8BQ:empty {
  display: none;
}

.hud-link_APw8BQ {
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent);
  cursor: pointer;
  font: inherit;
  text-decoration: underline;
}

@media (hover: hover) {
  .hud-link_APw8BQ:hover {
    color: var(--accent-strong);
  }
}

.hud-link_APw8BQ:active {
  color: var(--accent-strong);
}

.hud-chat-input_APw8BQ:focus-visible,
.hud-chat-send_APw8BQ:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.hud-chat-form_APw8BQ {
  display: flex;
  flex: 0 0 auto;
  gap: 6px;
}

.hud-chat-input_APw8BQ {
  flex: 1 1 auto;
  min-width: 0;
  padding: 8px;
  border: 2px solid var(--frame);
  background: var(--panel-soft);
  color: var(--ink);
  font: inherit;
  font-size: 12px;
}

.hud-chat-input_APw8BQ::placeholder {
  color: var(--ink-dim);
}

.hud-chat-send_APw8BQ {
  flex: 0 0 auto;
}

.hud-chat-unread_APw8BQ {
  display: inline-grid;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  place-items: center;
  background: var(--danger);
  color: var(--frame);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
}

.hud-title_APw8BQ {
  margin: 0 0 8px;
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.hud-group_APw8BQ + .hud-group_APw8BQ {
  margin-top: 12px;
}

.hud-options_APw8BQ {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
}

.hud-devices_APw8BQ {
  display: grid;
  gap: 6px;
  margin-top: 8px;
}

.hud-field_APw8BQ {
  display: grid;
  gap: 3px;
  color: var(--ink-dim);
  font-size: 10px;
}

.hud-field_APw8BQ select {
  width: 100%;
  min-width: 0;
  padding: 5px 6px;
  border: 2px solid var(--frame);
  background: var(--panel-soft);
  color: var(--ink);
  font: inherit;
  font-size: 11px;
}

.hud-field_APw8BQ select:disabled {
  opacity: 0.7;
}

.hud-option_APw8BQ[aria-pressed="true"] {
  background: var(--panel-lift);
  color: #ffd69d;
}

.hud-copy_APw8BQ {
  margin: 0;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.5;
}

.hud-close_APw8BQ {
  width: 100%;
  margin-top: 12px;
}

.airspace-hint_APw8BQ {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 0;
  padding: 9px 13px;
  max-width: calc(100% - 20px);
  overflow: hidden;
  background: rgba(11, 11, 18, 0.82);
  border: 2px solid var(--frame-edge);
  color: var(--ink);
  font-size: 12px;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
  pointer-events: none;
}

.airspace-banner_APw8BQ {
  position: absolute;
  top: 58px;
  left: 50%;
  transform: translateX(-50%);
  margin: 0;
  padding: 7px 11px;
  max-width: calc(100% - 20px);
  background: rgba(100, 43, 57, 0.95);
  border: 2px solid var(--frame);
  color: #ffe3de;
  font-size: 11px;
  line-height: 1.4;
  /* A notice can name an airhead, and a name may be one long word, so the text
     breaks inside the banner instead of running past the window. */
  overflow-wrap: anywhere;
  pointer-events: none;
  /* Above the chat drawer, which spans a narrow window; the banner never takes
     a pointer, so it cannot block anything it overlaps. */
  z-index: 2;
}

.airspace-banner_APw8BQ:empty {
  display: none;
}

.airspace-banner-notice_APw8BQ {
  top: 100px;
  background: rgba(33, 26, 45, 0.96);
  color: var(--ink);
}

.airspace-context_APw8BQ {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  padding: var(--hud-edge);
  pointer-events: none;
}

.airspace-activity_APw8BQ:empty {
  display: none;
}

@media (prefers-reduced-motion: reduce) {

    .hud-chat_APw8BQ {
      animation: none;
    }
}

/* Names are typed by airheads, so right to left text in one never reorders the
   text around it. */
.presence-name_APw8BQ {
  unicode-bidi: isolate;
}

.presence-count_APw8BQ {
  margin: 0 0 7px;
  color: var(--ink-dim);
  font-size: 11px;
}

.presence-list_APw8BQ {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(110px, 1fr));
  gap: 6px;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* A row is the dot, the name, and under the name the X badge. The name wraps
   inside its column, so a long name stays readable instead of being cut off. */
.presence-member_APw8BQ {
  display: grid;
  grid-template-columns: 9px minmax(0, 1fr);
  align-content: start;
  align-items: start;
  column-gap: 7px;
  row-gap: 1px;
  font-size: 12px;
  min-width: 0;
}

.presence-name_APw8BQ {
  min-width: 0;
  overflow-wrap: anywhere;
}

.presence-member_APw8BQ.is-self {
  color: var(--accent);
}

.presence-dot_APw8BQ {
  width: 9px;
  height: 9px;
  margin-top: 3px;
  background: var(--accent-strong);
  box-shadow: 0 0 0 2px var(--frame);
}

.presence-status_APw8BQ {
  grid-column: 2;
  color: var(--ink-dim);
  font-size: 9px;
  text-transform: uppercase;
}

/* A simulated airhead carries a Sim label under the name, so nobody takes it for
   a person. */
.presence-sim_APw8BQ {
  grid-column: 2;
  color: var(--ink-dim);
  font-size: 9px;
  text-transform: uppercase;
}

/* The OG label marks the maker of AirSpace under the name, as a filled gold chip
   that no display name can imitate. */
.presence-og_APw8BQ {
  grid-column: 2;
  justify-self: start;
  padding: 1px 5px;
  border-radius: 2px;
  background: #ffbf69;
  color: #2a1a00;
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
}

/* The X badge links to the airhead's profile on X. It is a separate element
   with the X mark, apart from the display name, and it sits under the name. An
   X username has at most 15 characters, so it fits the column without being
   cut. */
.presence-handle_APw8BQ {
  grid-column: 2;
  min-width: 0;
  color: var(--ink-dim);
  font-size: 10px;
  text-decoration: none;
  unicode-bidi: isolate;
  overflow-wrap: anywhere;
}

.presence-handle_APw8BQ::before {
  content: "";
  display: inline-block;
  width: 0.9em;
  height: 0.9em;
  margin-right: 0.3em;
  vertical-align: -0.1em;
  background: currentColor;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z'/%3E%3C/svg%3E") center / contain no-repeat;
}

@media (hover: hover) {
  .presence-handle_APw8BQ:hover {
    color: var(--accent);
    text-decoration: underline;
  }
}

.presence-handle_APw8BQ:active,
.presence-handle_APw8BQ:focus-visible {
  color: var(--accent);
  text-decoration: underline;
}

.avatar-man .presence-dot_APw8BQ {
  background: #58c7c0;
}

.avatar-builder .presence-dot_APw8BQ {
  background: #f2b632;
}

.avatar-hacker .presence-dot_APw8BQ {
  background: #c8553d;
}

.presence-empty_APw8BQ {
  margin: 0;
  font-size: 11px;
  line-height: 1.5;
}

/* A visitor's invitation to sign in sits under the People list, where the handles of signed in airheads show. */
.presence-invite_APw8BQ {
  display: grid;
  gap: 6px;
  justify-items: start;
  margin-top: 10px;
}
.presence-invite-copy_APw8BQ {
  margin: 0;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.5;
}
.presence-invite-copy_APw8BQ[hidden] {
  display: none;
}

.airspace-activity_APw8BQ {
  width: min(520px, calc(100vw - 20px));
  padding: 10px 12px;
  background: rgba(26, 20, 36, 0.96);
  border: 3px solid var(--frame);
  box-shadow: 0 0 0 3px var(--frame-edge), 0 18px 32px rgba(0, 0, 0, 0.5);
  pointer-events: auto;
}

.airspace-activity_APw8BQ {
  position: absolute;
  top: 52px;
  right: var(--hud-edge);
  width: min(320px, calc(100vw - 20px));
  padding: 8px 10px;
}

.activity-title_APw8BQ {
  margin: 0;
  color: var(--accent);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.activity-copy_APw8BQ {
  margin: 6px 0 9px;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.45;
}

.activity-copy_APw8BQ {
  margin: 4px 0 7px;
  font-size: 10px;
}

.activity-options_APw8BQ {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.activity-option_APw8BQ {
  border: 2px solid var(--frame);
  padding: 5px 7px;
  background: var(--panel-soft);
  color: var(--ink-dim);
  cursor: pointer;
  font-size: 10px;
}

.activity-option_APw8BQ.is-selected {
  background: var(--accent-strong);
  color: var(--ink);
}

@media (hover: hover) {
  .activity-option_APw8BQ:hover {
    filter: brightness(1.18);
  }
}

.activity-option_APw8BQ:active {
  filter: brightness(1.18);
}

@media (max-width: 560px) {

    .hud-top_APw8BQ {
      top: 8px;
      left: 8px;
      right: 8px;
    }

    .hud-popover_APw8BQ {
      top: 48px;
    }

    .hud-roster_APw8BQ,
  .hud-menu_APw8BQ {
      left: 8px;
      right: 8px;
      width: auto;
    }

    .hud-chat_APw8BQ {
      top: auto;
      align-self: stretch;
      width: auto;
      margin-top: calc(48px - var(--hud-edge));
    }

    .airspace-hint_APw8BQ {
      font-size: 11px;
      white-space: normal;
    }

    /* A narrow top bar keeps only the action; the name form and the menu show the
       current name. A 16px field also stops phones from zooming in on focus. */
    .hud-name-prompt-label_APw8BQ {
      display: none;
    }

    .hud-name-prompt_APw8BQ {
      padding-left: 2px;
    }

    .airspace-activity_APw8BQ {
      top: 124px;
      right: 8px;
      width: min(292px, calc(100vw - 16px));
      padding: 7px 9px;
    }

    .activity-options_APw8BQ {
      flex-wrap: nowrap;
      gap: 4px;
    }

    .activity-option_APw8BQ {
      padding: 4px 5px;
      white-space: nowrap;
    }
}

@media (max-height: 560px) {

    .hud-roster_APw8BQ {
      top: 8px;
      max-height: calc(100% - 16px);
      padding: 8px;
    }

    .hud-roster-header_APw8BQ {
      margin-bottom: 6px;
    }
}

@keyframes airspace-name-nudge_APw8BQ {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(255, 191, 105, 0);
  }

  50% {
    box-shadow: 0 0 0 3px rgba(255, 191, 105, 0.55);
  }
}

@keyframes airspace-chat-in_APw8BQ {
  from {
    opacity: 0;
    transform: translateX(24px);
  }

  to {
    opacity: 1;
    transform: translateX(0);
  }
}

/* An airhead who joined from another window sees this over the room, with one
   control that takes the seat back. */
.seat-notice_APw8BQ {
  position: absolute;
  top: 58px;
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  gap: 8px;
  justify-items: center;
  margin: 0;
  padding: 10px 14px;
  max-width: calc(100% - 20px);
  background: rgba(33, 26, 45, 0.97);
  border: 2px solid var(--frame);
  color: var(--ink);
  font-size: 12px;
  line-height: 1.4;
  /* Above the banners and the chat drawer. */
  z-index: 3;
}
.seat-notice_APw8BQ[hidden] {
  display: none;
}
.seat-message_APw8BQ {
  margin: 0;
}

/* The two paragraphs of the sign in invitation keep a gap between them. */
.invite-copy_APw8BQ + .invite-copy_APw8BQ {
  margin-top: 8px;
}

/* The delete confirmation sits inside the X account group of the menu. */
.account-confirm_APw8BQ {
  display: grid;
  gap: 6px;
  margin-top: 8px;
}
.account-confirm_APw8BQ[hidden] {
  display: none;
}

/* The top bar, the overlays, and the notices keep clear of a notch, a rounded
   corner, and the home indicator, while the map runs behind them. */
.hud-top_APw8BQ {
  top: calc(var(--hud-edge) + var(--safe-top));
  left: calc(var(--hud-edge) + var(--safe-left));
  right: calc(var(--hud-edge) + var(--safe-right));
}

/* An overlay starts under the top bar, wherever the bar ends, and scrolls in
   the space that is left. A finger that drags inside one scrolls it and never
   reaches the world behind. */
.hud-popover_APw8BQ {
  top: var(--hud-clearance);
  max-height: calc(100% - var(--hud-clearance) - 12px - var(--safe-bottom));
  overscroll-behavior: contain;
  touch-action: pan-y pinch-zoom;
}

.hud-roster_APw8BQ {
  left: calc(var(--hud-edge) + var(--safe-left));
  width: min(720px, calc(100% - var(--hud-edge) * 2 - var(--safe-left) - var(--safe-right)));
  overflow-y: auto;
}

.hud-roster-header_APw8BQ {
  position: sticky;
  top: -12px;
  z-index: 1;
  padding-block: 4px;
  background: rgba(26, 20, 36, 0.99);
}

.hud-menu_APw8BQ {
  right: calc(var(--hud-edge) + var(--safe-right));
}

.airspace-context_APw8BQ {
  padding-bottom: calc(var(--hud-edge) + var(--safe-bottom));
  padding-left: calc(var(--hud-edge) + var(--safe-left));
  padding-right: calc(var(--hud-edge) + var(--safe-right));
}

.airspace-banner_APw8BQ {
  top: calc(var(--hud-clearance) + 6px);
  /* Sized by its text, not by the half of the screen left of its anchor. */
  width: max-content;
  overflow-wrap: anywhere;
}

.airspace-banner-notice_APw8BQ {
  top: calc(var(--hud-clearance) + 48px);
}

/* A lost connection comes back through a reload, so the banner carries the
   button for it. The banner ignores the pointer; the button takes it. */
.airspace-banner_APw8BQ [data-connection-retry] {
  display: block;
  margin: 8px auto 0;
  min-height: 44px;
  padding: 6px 14px;
  border: 2px solid var(--frame);
  background: rgba(33, 26, 45, 0.92);
  color: var(--ink);
  cursor: pointer;
  font-size: 12px;
  pointer-events: auto;
}

@media (hover: hover) {
  .airspace-banner_APw8BQ [data-connection-retry]:hover {
    background: var(--panel-lift);
  }
}

.airspace-banner_APw8BQ [data-connection-retry]:active {
  background: var(--panel-lift);
}

.hud-chat-input_APw8BQ {
  min-height: 44px;
}

/* A drawer squeezed below what its header and message field need, such as the
   chat beside a call invitation in a window zoomed to 400 percent, scrolls as a
   whole and never clips them. */
.hud-chat_APw8BQ {
  overflow-y: auto;
}

/* The hint names the input the player has: keys and a click, or a tap. */
.hint-tap_APw8BQ {
  display: none;
}

@media (pointer: coarse) {
  .hint-keys_APw8BQ,
  .hint-click_APw8BQ {
    display: none;
  }

  .hint-tap_APw8BQ {
    display: inline;
  }
}

@media (min-width: 761px) {
  .hud-chat_APw8BQ {
    top: var(--hud-clearance);
    right: calc(var(--hud-edge) + var(--safe-right));
    bottom: calc(var(--hud-edge) + var(--safe-bottom));
  }
}

/* Touch targets reach 44 CSS pixels, and text fields use 16 pixel type so that
   a phone browser does not zoom the page when one takes focus. */
@media (pointer: coarse), (max-width: 560px) {
  .hud-chip_APw8BQ,
  .hud-icon_APw8BQ,
  .hud-option_APw8BQ,
  .hud-roster-tab_APw8BQ,
  .hud-name-prompt-action_APw8BQ {
    min-height: 44px;
  }

  .hud-icon_APw8BQ {
    min-width: 44px;
  }

  .hud-roster-close_APw8BQ {
    flex-basis: 44px;
  }

  .hud-field_APw8BQ select,
  .hud-chat-input_APw8BQ {
    font-size: 16px;
  }

  /* A link inside a sentence keeps the sentence's line height. Its 44 pixel
     touch area overlaps the lines above and below instead of pushing them apart. */
  .hud-link_APw8BQ {
    display: inline-block;
    margin-block: -16px;
  }

  .hud-copy_APw8BQ,
  .presence-count_APw8BQ {
    font-size: 12px;
  }

  .hud-chat-name_APw8BQ,
  .hud-chat-privacy_APw8BQ {
    font-size: 11px;
  }

  .presence-list_APw8BQ {
    grid-template-columns: 1fr;
  }

  .presence-member_APw8BQ {
    min-height: 44px;
  }

  .presence-handle_APw8BQ {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }

  .hud-credit-link_APw8BQ {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
  }
}

/* A phone keeps its five controls on one row. The room chip shrinks to a word
   and the head count, and the name prompt takes a row of its own. */
@media (max-width: 560px) {
  .hud-top_APw8BQ {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto auto auto;
    gap: 6px;
  }

  .hud-cluster_APw8BQ {
    display: contents;
  }

  .hud-brand_APw8BQ {
    grid-column: 1;
    grid-row: 1;
    justify-content: center;
    padding-inline: 6px;
    letter-spacing: 0;
  }

  .hud-chip_APw8BQ[data-roster-toggle] {
    grid-column: 2;
    grid-row: 1;
    justify-content: center;
    min-width: 0;
    padding-inline: 6px;
  }

  .hud-chip_APw8BQ[data-roster-toggle]::before {
    content: "People";
  }

  .hud-chip_APw8BQ[data-roster-toggle]::after {
    content: attr(data-count);
    color: var(--accent);
  }

  .hud-chip_APw8BQ[data-roster-toggle] > span {
    display: none;
  }

  .hud-chip_APw8BQ[data-chat-toggle] {
    grid-column: 3;
    grid-row: 1;
    padding-inline: 6px;
  }

  .hud-icon_APw8BQ[data-fullscreen-toggle] {
    grid-column: 4;
    grid-row: 1;
  }

  .hud-icon_APw8BQ[data-menu-toggle] {
    grid-column: 5;
    grid-row: 1;
  }

  .hud-name-prompt_APw8BQ {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-self: start;
    padding: 0;
  }

  .hud-name-prompt-action_APw8BQ {
    border: 0;
    font-size: 12px;
  }

  .hud-name-prompt-label_APw8BQ {
    display: none;
  }

  .hud-roster_APw8BQ,
  .hud-menu_APw8BQ {
    left: calc(var(--hud-edge) + var(--safe-left));
    right: calc(var(--hud-edge) + var(--safe-right));
    width: auto;
  }

  .activity-options_APw8BQ {
    flex-wrap: wrap;
  }
}

@media (max-width: 760px) {
  .airspace-context_APw8BQ {
    top: var(--hud-clearance);
    padding-top: 0;
  }

  .hud-chat_APw8BQ {
    margin-top: 0;
    top: auto;
    max-height: 100%;
  }

  .airspace-activity_APw8BQ {
    position: relative;
    top: auto;
    right: auto;
    align-self: flex-end;
    width: min(320px, 100%);
    max-height: 30%;
    overflow-y: auto;
    flex: 0 1 auto;
  }
}

/* A keyboard leaves little room, so the name prompt waits for it to close. */
html[data-airspace-keyboard] .hud-name-prompt_APw8BQ {
  display: none;
}

/* A phone held sideways leaves the chat drawer about 320 pixels of height. The
   name invitation is already in the top bar there, and the privacy note shrinks
   to a tight pair of lines, so the messages get the room. */
@media (max-height: 460px) {
  .hud-name-prompt-label_APw8BQ {
    display: none;
  }

  /* AirSpace is a longer brand than the toolbar once had, so a short window tightens it. */
  .hud-brand_APw8BQ {
    padding: 6px 6px;
    letter-spacing: 0.02em;
  }

  .hud-room_APw8BQ {
    letter-spacing: 0.04em;
  }

  .hud-cluster_APw8BQ {
    gap: 4px;
  }

  .hud-chat-name_APw8BQ {
    display: none;
  }

  .hud-chat-privacy_APw8BQ {
    padding: 3px 8px;
    line-height: 1.3;
  }
}

/* A window as short as 400 percent zoom leaves gives the chat drawer the whole
   column: its privacy note and the offer to start a call wait until it closes. */
@media (max-height: 320px) {
  .hud-chat-privacy_APw8BQ {
    display: none;
  }

  [data-airspace-context]:has(> #airspace-chat:not([hidden])) #airspace-proximity {
    display: none;
  }
}


.chat-log_DqAt4Q {
  flex: 1 1 auto;
  min-height: 64px;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 8px;
  background: rgba(11, 11, 18, 0.55);
  border: 2px solid var(--frame);
}

.chat-log_DqAt4Q:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.chat-list_DqAt4Q {
  display: grid;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.chat-message_DqAt4Q {
  display: grid;
  gap: 2px;
  min-width: 0;
  font-size: 12px;
  line-height: 1.4;
}

.chat-author_DqAt4Q {
  color: var(--accent-strong);
  font-size: 10px;
  letter-spacing: 0.06em;
  overflow-wrap: anywhere;
  text-transform: uppercase;
}

.avatar-man .chat-author_DqAt4Q {
  color: #58c7c0;
}

.avatar-builder .chat-author_DqAt4Q {
  color: #f2b632;
}

.avatar-hacker .chat-author_DqAt4Q {
  color: #c8553d;
}

.chat-message_DqAt4Q[data-chat-own] .chat-author_DqAt4Q::after {
  content: " (you)";
  color: var(--ink-dim);
  text-transform: none;
}

/* Isolating the text keeps right to left or override characters in one
   message from reordering anything around it. */
/* A line a simulated airhead wrote carries a Sim label beside the author, so a
   room that sims are talking in never reads as full of people. The author stays
   a direct child of the row, because a rename retitles it there. */
.chat-message_DqAt4Q.is-sim,
.chat-message_DqAt4Q.is-og {
  grid-template-columns: minmax(0, max-content) 1fr;
  column-gap: 6px;
  align-items: baseline;
}

.chat-message_DqAt4Q.is-sim .chat-text_DqAt4Q,
.chat-message_DqAt4Q.is-og .chat-text_DqAt4Q {
  grid-column: 1 / -1;
}

/* The label is a filled chip in a color no author name uses, so it reads as a tag
   beside the name and never as a word the author wrote. */
.chat-sim_DqAt4Q {
  justify-self: start;
  padding: 1px 5px;
  border-radius: 2px;
  background: #b69cff;
  color: #1a1226;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
  white-space: nowrap;
}

/* The OG label marks the maker of AirSpace beside the author, as a gold chip that
   is its own element, so an author who writes OG in a name never gets one. */
.chat-og_DqAt4Q {
  justify-self: start;
  padding: 1px 5px;
  border-radius: 2px;
  background: #ffbf69;
  color: #2a1a00;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
  white-space: nowrap;
}

.chat-text_DqAt4Q {
  overflow-wrap: anywhere;
  unicode-bidi: isolate;
}

.chat-empty_DqAt4Q {
  margin: 0;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.5;
}

/* Names are typed by airheads, so right to left text in one never reorders the
   text around it. */
.chat-author_DqAt4Q {
  unicode-bidi: isolate;
}

/* The tabs of the chat drawer: the room first, then one for each private chat.
   The strip is hidden until a private chat opens. */
.chat-tabs_DqAt4Q {
  display: flex;
  flex: 0 0 auto;
  gap: 4px;
  overflow-x: auto;
}

.chat-tab_DqAt4Q {
  display: inline-flex;
  flex: 0 1 auto;
  align-items: center;
  gap: 6px;
  min-width: 0;
  max-width: 180px;
  padding: 5px 8px;
  border: 2px solid var(--frame);
  background: var(--panel-soft);
  color: var(--ink);
  cursor: pointer;
  font: inherit;
  font-size: 11px;
}

.chat-tab_DqAt4Q > span:first-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  unicode-bidi: isolate;
}

.chat-tab_DqAt4Q[aria-selected="true"] {
  border-color: var(--accent);
  color: var(--accent);
}

.chat-tab_DqAt4Q:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

@media (hover: hover) {
  .chat-tab_DqAt4Q:hover {
    background: var(--panel-lift);
  }
}

/* The container adds no box of its own, so each panel lays out beside the
   room list in the drawer's column. */
.private-panels_DqAt4Q {
  display: contents;
}

.private-panel_DqAt4Q {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
}

.private-actions_DqAt4Q {
  display: flex;
  flex: 0 0 auto;
  gap: 6px;
}

/* The airhead's own lines sit on the right and the other airhead's on the left,
   so the lines need no names. */
.private-message_DqAt4Q {
  position: relative;
  min-width: 0;
  max-width: 88%;
  padding: 5px 8px;
  border: 2px solid var(--frame);
  background: var(--panel-soft);
  font-size: 12px;
  line-height: 1.4;
  justify-self: start;
}

.private-message_DqAt4Q[data-chat-own] {
  background: var(--panel-lift);
  justify-self: end;
}

/* Tells a screen reader who spoke, and draws nothing. */
.private-label_DqAt4Q {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.private-empty_DqAt4Q {
  margin: 0;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.5;
}

.chat-list_DqAt4Q:not(:empty) + .private-empty_DqAt4Q {
  display: none;
}


.airspace-proximity_9z3W4w button:focus-visible,
.call-actions_9z3W4w button:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.airspace-proximity_9z3W4w:empty,
.airspace-call_9z3W4w:empty {
  display: none;
}

.airspace-proximity_9z3W4w > *,
.airspace-call_9z3W4w > * {
  pointer-events: auto;
}

.invite-button_9z3W4w {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.airspace-proximity_9z3W4w:not(:empty) {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.invite-row_9z3W4w {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 6px 8px;
  background: rgba(26, 20, 36, 0.96);
  border: 3px solid var(--frame);
  box-shadow: 0 0 0 3px var(--frame-edge), 0 12px 24px rgba(0, 0, 0, 0.45);
}

.invite-name_9z3W4w {
  max-width: 100%;
  color: #ffd9ad;
  font-size: 11px;
  overflow-wrap: anywhere;
  unicode-bidi: isolate;
}

.invite-note_9z3W4w {
  padding: 1px 4px;
  border: 1px solid var(--frame-edge);
  background: var(--panel-soft);
  color: var(--ink-dim);
  font-size: 9px;
  white-space: nowrap;
}

/* A sim's name in a call card or a nearby row carries the same filled Sim chip
   the chat uses, so a request from a sim never reads as written by a person. */
.call-sim_9z3W4w {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 5px;
  border-radius: 2px;
  background: #b69cff;
  color: #1a1226;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
  vertical-align: 1px;
  white-space: nowrap;
}

.call-invite_9z3W4w,
.call-pending_9z3W4w,
.call-active_9z3W4w {
  padding: 10px 12px;
  background: rgba(26, 20, 36, 0.96);
  border: 3px solid var(--frame);
  box-shadow: 0 0 0 3px var(--frame-edge), 0 18px 32px rgba(0, 0, 0, 0.5);
}

.call-invite_9z3W4w,
.call-pending_9z3W4w {
  width: min(300px, calc(100vw - 20px));
}

.airspace-call_9z3W4w {
  align-self: flex-end;
}

.call-active_9z3W4w {
  width: min(520px, calc(100vw - 20px));
}

.call-title_9z3W4w {
  margin: 0 0 8px;
  font-size: 12px;
  line-height: 1.45;
}

.call-actions_9z3W4w {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.call-grid_9z3W4w {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  margin: 0 0 8px;
}

.call-tile_9z3W4w {
  position: relative;
  margin: 0;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: #100f18;
  border: 2px solid var(--frame);
}

/* Audio calls have no frames to show, so their tiles stay short and the
   room remains visible behind the panel. */
.call-active_9z3W4w[data-call-kind="audio"] {
  width: min(400px, calc(100vw - 20px));
}

.call-active_9z3W4w[data-call-kind="audio"] .call-tile_9z3W4w {
  aspect-ratio: 5 / 2;
}

.call-active_9z3W4w[data-call-kind="audio"] .call-avatar_9z3W4w {
  font-size: 22px;
}

.call-tile_9z3W4w video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Audio only and camera-off tiles keep their <video> element playing sound
   and show the airhead's initials instead of a blank frame. */
.call-tile_9z3W4w[data-camera="off"] video {
  opacity: 0;
}

.call-avatar_9z3W4w {
  position: absolute;
  inset: 0;
  display: none;
  place-items: center;
  background: radial-gradient(circle at 50% 42%, var(--panel-lift), var(--panel) 70%);
  color: var(--accent);
  font-size: 30px;
  text-transform: uppercase;
}

.call-tile_9z3W4w[data-camera="off"] .call-avatar_9z3W4w,
.call-tile_9z3W4w.is-invited .call-avatar_9z3W4w {
  display: grid;
}

.call-tile_9z3W4w.is-invited {
  opacity: 0.66;
}

.call-tile_9z3W4w.is-speaking {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent);
}

.call-tile_9z3W4w.is-speaking .call-avatar_9z3W4w {
  animation: airspace-speaking_9z3W4w 0.9s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {

    .call-tile_9z3W4w.is-speaking .call-avatar_9z3W4w {
      animation: none;
    }
}

.call-caption_9z3W4w {
  position: absolute;
  right: 0;
  bottom: 0;
  left: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 3px;
  padding: 3px 5px;
  background: rgba(12, 17, 22, 0.76);
  font-size: 10px;
}

.call-name_9z3W4w {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Names are typed by airheads, so right to left text in one never reorders the
   text around it. */
.call-name_9z3W4w,
.call-title_9z3W4w strong {
  unicode-bidi: isolate;
}

.call-badges_9z3W4w {
  display: flex;
  flex-wrap: wrap;
  gap: 3px;
}

.call-badge_9z3W4w {
  padding: 1px 4px;
  border: 1px solid var(--frame-edge);
  background: var(--panel-soft);
  color: var(--ink-dim);
  font-size: 9px;
}

.call-badge-og_9z3W4w {
  border-color: #ffbf69;
  background: #ffbf69;
  color: #2a1a00;
  font-weight: 800;
  letter-spacing: 0.08em;
}

.call-badge-muted_9z3W4w {
  background: #642b39;
  color: #ffd9d4;
}

.local-video_9z3W4w {
  opacity: 0.78;
}

.media-status_9z3W4w {
  margin: 0 0 8px;
  color: var(--ink-dim);
  font-size: 10px;
  line-height: 1.4;
}

@keyframes airspace-speaking_9z3W4w {
  50% {
    color: var(--accent-strong);
    text-shadow: 0 0 12px var(--accent);
  }
}

/* An airhead who prefers audio only never sees the video join action. */
html[data-call-media="audio"] [data-call-accept][data-call-media="video"] {
  display: none;
}

/* The chat drawer keeps its width and both edges free of the active call. */
@media (min-width: 761px) {
  [data-airspace-context]:has(> #airspace-chat:not([hidden])) .call-active_9z3W4w {
    width: min(520px, calc(100vw - var(--hud-edge) * 4 - 320px));
  }
}

.airspace-call_9z3W4w, .airspace-proximity_9z3W4w { max-width: 100%; }
.call-title_9z3W4w, .media-status_9z3W4w { overflow-wrap: anywhere; }
.call-name_9z3W4w { min-width: 0; }

/* Beside a chat drawer with a long history, shrink is shared out in proportion to
   each item's natural height, so a call panel that may shrink is clipped while the
   drawer still holds most of the column. The panels keep their height, capped
   below and scrolling inside, and the drawer gives up what they need. */
@media (pointer: coarse), (max-width: 560px) {
  .airspace-proximity_9z3W4w { flex: 0 0 auto; max-height: 35%; overflow-y: auto; overscroll-behavior: contain; }
  .invite-row_9z3W4w { max-width: 100%; }
  .invite-name_9z3W4w { max-width: 100%; }
  .airspace-call_9z3W4w { flex: 0 0 auto; }
  .call-invite_9z3W4w, .call-pending_9z3W4w, .call-active_9z3W4w {
    max-width: 100%;
    max-height: calc((var(--airspace-viewport-height, 100dvh) - var(--hud-clearance) - var(--safe-bottom) - 20px) * 0.65);
    overflow-y: auto;
    overscroll-behavior: contain;
    touch-action: pan-y pinch-zoom;
  }
  .call-actions_9z3W4w { position: sticky; bottom: -12px; padding-block: 6px; background: rgba(26, 20, 36, 0.99); }
  [data-airspace-context]:has(> #airspace-chat:not([hidden])) .call-active_9z3W4w {
    max-height: calc((var(--airspace-viewport-height, 100dvh) - var(--hud-clearance) - var(--safe-bottom) - 20px) * 0.45);
  }
  .call-tile_9z3W4w { aspect-ratio: auto; height: min(100px, calc(var(--airspace-viewport-height, 100dvh) * 0.18)); }
}


.profile-group_YRIg-w {
  display: grid;
  gap: 6px;
}

.membership-dialog_YRIg-w {
  box-sizing: border-box;
  width: min(440px, calc(100vw - var(--safe-left) - var(--safe-right) - 24px));
  max-width: none;
  max-height: calc(var(--airspace-viewport-height, 100dvh) - var(--safe-top) - var(--safe-bottom) - 24px);
  overflow-y: auto;
  overscroll-behavior: contain;
  touch-action: pan-y pinch-zoom;
  scrollbar-width: none;
  -ms-overflow-style: none;
  padding: 14px;
  border: 3px solid var(--frame);
  background: rgba(26, 20, 36, 0.99);
  color: var(--ink);
  color-scheme: dark;
  pointer-events: auto;
  box-shadow: 0 0 0 3px var(--frame-edge), 0 18px 48px rgba(0, 0, 0, 0.65);
}

.membership-dialog_YRIg-w::-webkit-scrollbar {
  display: none;
}

/* A dialog centers in the layout viewport, which a software keyboard covers
   from below. While one does, it centers in the area the player can see. */
html[data-airspace-keyboard] .membership-dialog_YRIg-w {
  top: calc(var(--airspace-viewport-top) + var(--safe-top) + (var(--airspace-viewport-height) - var(--safe-top) - var(--safe-bottom)) / 2);
  bottom: auto;
  margin-block: 0;
  transform: translateY(-50%);
}

.membership-dialog_YRIg-w::backdrop {
  background: rgba(5, 4, 9, 0.72);
}

.membership-form_YRIg-w {
  display: grid;
  gap: 8px;
}

.membership-heading_YRIg-w {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 2px;
}

.membership-heading_YRIg-w { position: sticky; top: -14px; z-index: 1; padding-block: 6px; background: rgba(26, 20, 36, 0.99); }
.membership-actions_YRIg-w { position: sticky; bottom: -14px; padding-block: 6px; background: rgba(26, 20, 36, 0.99); }

.membership-heading_YRIg-w h2 {
  margin: 0;
  color: var(--accent);
  font-size: 14px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.membership-heading_YRIg-w p {
  margin: 5px 0 0;
  color: var(--ink-dim);
  font-size: 10px;
  line-height: 1.4;
}

.wallet-connect_YRIg-w {
  display: grid;
  gap: 5px;
  color: var(--ink-dim);
  font-size: 10px;
}

.wallet-buttons_YRIg-w,
.membership-actions_YRIg-w {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}

.wallet-buttons_YRIg-w .secondary-button,
.membership-actions_YRIg-w .primary-button,
.membership-actions_YRIg-w .secondary-button {
  margin: 0;
  padding: 6px 9px;
  font-size: 10px;
}

.wallet-clear_YRIg-w {
  border: 0;
  padding: 5px;
  background: transparent;
  color: var(--ink-dim);
  cursor: pointer;
  font: inherit;
  font-size: 10px;
  text-decoration: underline;
}

.wallet-status_YRIg-w {
  overflow-wrap: anywhere;
  margin: 0;
  color: var(--ink-dim);
  font-size: 9px;
}

.profile-region_YRIg-w {
  border-top: 1px solid var(--frame-edge);
  padding-top: 6px;
}

.profile-region_YRIg-w summary {
  color: var(--accent);
  cursor: pointer;
  font-size: 10px;
}

.profile-location_YRIg-w {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  margin-top: 7px;
}

@media (max-width: 560px) {

    .profile-location_YRIg-w {
      grid-template-columns: 1fr;
    }
}

@media (max-height: 460px) {

    .membership-dialog_YRIg-w {
      padding: 8px;
    }

    .membership-heading_YRIg-w p {
      display: none;
    }

    .membership-form_YRIg-w {
      gap: 5px;
    }
}


.name-open_d8Z6ig:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.profile-field_d8Z6ig {
  display: grid;
  gap: 3px;
  color: var(--ink-dim);
  font-size: 10px;
}

.profile-field_d8Z6ig input {
  box-sizing: border-box;
  width: 100%;
  border: 1px solid var(--frame-edge);
  padding: 6px;
  background: rgba(10, 9, 17, 0.72);
  color: var(--ink);
  font: inherit;
}

.profile-field_d8Z6ig input:focus {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* The menu group shows the current name beside the control that changes it. A
   long name wraps onto more lines, so the whole name stays readable and never
   spills past the menu; the menu scrolls when a window is too short. */
.name-row_d8Z6ig {
  display: flex;
  align-items: center;
  gap: 8px;
}

.name-current_d8Z6ig {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--ink);
  font-size: 12px;
  line-height: 1.35;
  overflow-wrap: anywhere;
  unicode-bidi: isolate;
}

.name-open_d8Z6ig {
  flex: 0 0 auto;
}

/* A refusal is explained inside the form: the modal covers the room banner. */
.name-status_d8Z6ig {
  margin: 0;
  padding: 6px 8px;
  background: rgba(100, 43, 57, 0.95);
  border: 2px solid var(--frame);
  color: #ffe3de;
  font-size: 10px;
  line-height: 1.4;
}

.name-dialog_d8Z6ig .profile-field_d8Z6ig input {
  font-size: 13px;
}

.name-dialog_d8Z6ig .profile-field_d8Z6ig input[aria-invalid="true"] {
  border-color: var(--danger);
}

/* The Random control sits beside the field, lined up with the input rather than
   with the caption above it, and drops below the field on a phone. */
.name-field-row_d8Z6ig {
  display: flex;
  align-items: flex-end;
  gap: 6px;
}

.name-field-row_d8Z6ig .profile-field_d8Z6ig {
  flex: 1 1 auto;
  min-width: 0;
}

.name-random_d8Z6ig {
  flex: 0 0 auto;
  margin: 0;
  padding: 8px 10px;
  font-size: 11px;
  white-space: nowrap;
}

.name-random_d8Z6ig:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (max-width: 560px) {

    .name-dialog_d8Z6ig .profile-field_d8Z6ig input {
      font-size: 16px;
    }

    .name-field-row_d8Z6ig {
      flex-direction: column;
      align-items: stretch;
    }

    .name-random_d8Z6ig {
      padding: 10px;
      font-size: 13px;
    }
}


.airspace-leaderboard_m1jS3g {
  width: min(520px, calc(100vw - 20px));
  padding: 10px 12px;
  background: rgba(26, 20, 36, 0.96);
  border: 3px solid var(--frame);
  box-shadow: 0 0 0 3px var(--frame-edge), 0 18px 32px rgba(0, 0, 0, 0.5);
  pointer-events: auto;
}

.airspace-leaderboard_m1jS3g {
  width: 100%;
  max-width: 100%;
  min-width: 0;
}

.leaderboard-heading_m1jS3g h3,
.leaderboard-metric_m1jS3g h4 {
  margin: 0;
  color: var(--accent);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.leaderboard-visitor_m1jS3g,
.leaderboard-empty_m1jS3g {
  margin: 6px 0 9px;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.45;
}

.leaderboard-controls_m1jS3g,
.leaderboard-control-group_m1jS3g {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
}

.leaderboard-control-label_m1jS3g {
  align-self: center;
  color: var(--ink-dim);
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.leaderboard-option_m1jS3g {
  border: 2px solid var(--frame);
  padding: 5px 7px;
  background: var(--panel-soft);
  color: var(--ink-dim);
  cursor: pointer;
  font-size: 10px;
}

.leaderboard-option_m1jS3g.is-selected {
  background: var(--accent-strong);
  color: var(--ink);
}

@media (hover: hover) {
  .leaderboard-option_m1jS3g:hover {
    filter: brightness(1.18);
  }
}

.leaderboard-option_m1jS3g:active {
  filter: brightness(1.18);
}

.leaderboard-heading_m1jS3g {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}

.leaderboard-context_m1jS3g {
  color: var(--ink-dim);
  font-size: 10px;
  text-transform: capitalize;
}

.leaderboard-personal_m1jS3g,
.leaderboard-member-board_m1jS3g {
  padding: 9px;
  background: rgba(10, 9, 17, 0.42);
  border: 1px solid var(--frame-edge);
}

.leaderboard-personal_m1jS3g {
  margin-bottom: 10px;
}

.leaderboard-personal_m1jS3g.leaderboard-visitor_m1jS3g {
  border-color: rgba(232, 185, 98, 0.58);
}

.leaderboard-personal-heading_m1jS3g,
.leaderboard-member-heading_m1jS3g {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
}

.leaderboard-personal-heading_m1jS3g h4,
.leaderboard-member-heading_m1jS3g h4 {
  margin: 0;
  color: var(--accent);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.leaderboard-personal-note_m1jS3g,
.leaderboard-member-note_m1jS3g {
  margin: 4px 0 0;
  color: var(--ink-dim);
  font-size: 10px;
  line-height: 1.45;
}

.leaderboard-personal-status_m1jS3g {
  flex: 0 0 auto;
  padding: 3px 5px;
  border: 1px solid var(--frame);
  color: var(--accent);
  font-size: 9px;
  text-transform: uppercase;
}

.leaderboard-personal-grid_m1jS3g {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  margin-top: 9px;
}

.leaderboard-personal-metric_m1jS3g {
  display: grid;
  gap: 3px;
  padding: 6px;
  background: rgba(26, 20, 36, 0.76);
  color: var(--ink-dim);
  font-size: 9px;
  text-transform: uppercase;
}

.leaderboard-personal-metric_m1jS3g strong {
  color: var(--ink);
  font-size: 12px;
  text-transform: none;
}

.leaderboard-personal-cta_m1jS3g {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 7px;
  margin: 9px 0 0;
  color: var(--ink-dim);
  font-size: 10px;
}

.leaderboard-personal-cta_m1jS3g .primary-button {
  margin: 0;
}

.leaderboard-member-board_m1jS3g {
  background: rgba(10, 9, 17, 0.28);
}

.leaderboard-member-heading_m1jS3g {
  margin-bottom: 8px;
}

.leaderboard-controls_m1jS3g {
  justify-content: space-between;
  margin-bottom: 10px;
}

.leaderboard-metrics_m1jS3g {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
}

.leaderboard-metric_m1jS3g {
  min-width: 0;
  padding: 7px;
  background: rgba(10, 9, 17, 0.52);
  border: 1px solid var(--frame-edge);
}

.leaderboard-metric_m1jS3g h4 {
  margin-bottom: 6px;
  font-size: 10px;
}

.leaderboard-list_m1jS3g {
  display: grid;
  gap: 4px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.leaderboard-row_m1jS3g {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr) auto;
  align-items: center;
  gap: 4px;
  padding: 3px 4px;
  color: var(--ink-dim);
  font-size: 10px;
}

.leaderboard-row_m1jS3g.is-self {
  background: rgba(232, 185, 98, 0.12);
  color: var(--ink);
}

.leaderboard-rank_m1jS3g {
  color: var(--accent);
}

.leaderboard-name_m1jS3g {
  overflow-wrap: anywhere;
}

.leaderboard-time_m1jS3g {
  color: var(--accent);
  white-space: nowrap;
}

@media (max-width: 680px) {

    .leaderboard-personal-grid_m1jS3g {
      grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .leaderboard-metrics_m1jS3g {
      grid-template-columns: repeat(3, minmax(0, 1fr));
      gap: 4px;
    }

    .leaderboard-metric_m1jS3g {
      padding: 5px;
    }

    .leaderboard-row_m1jS3g {
      grid-template-columns: 16px minmax(0, 1fr) auto;
      gap: 2px;
      padding: 2px;
      font-size: 9px;
    }
}

@media (max-width: 560px) {

    /* The Updates group sits beside the period buttons, so its labels stay on
       one line while the two groups wrap inside the panel. */
    .leaderboard-option_m1jS3g {
      white-space: nowrap;
    }
}

@media (max-height: 560px) {

    .leaderboard-personal-note_m1jS3g,
  .leaderboard-member-note_m1jS3g {
      display: none;
    }

    .leaderboard-personal_m1jS3g,
  .leaderboard-member-board_m1jS3g {
      padding: 6px;
    }

    .leaderboard-personal_m1jS3g {
      margin-bottom: 6px;
    }

    .leaderboard-personal-grid_m1jS3g {
      gap: 4px;
      margin-top: 6px;
    }

    .leaderboard-controls_m1jS3g {
      margin-bottom: 6px;
    }

    .leaderboard-metrics_m1jS3g {
      gap: 4px;
    }

    .leaderboard-metric_m1jS3g {
      padding: 4px;
    }
}
/* The What's new dialog reuses the menu dialog frame and adds a scrolling list
   of updates. The dot shows while the page marks the browser as having unread
   updates; the page sets that mark on the root element, so server patches
   never reset it. */

.whats-new-dialog_Jj5hhw {
  width: min(520px, calc(100vw - 24px));
}

.whats-new-list_Jj5hhw {
  display: grid;
  gap: 10px;
  max-height: min(60dvh, 420px);
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.whats-new-entry_Jj5hhw {
  padding-top: 10px;
  border-top: 1px solid var(--frame-edge);
}

.whats-new-entry_Jj5hhw:first-child {
  padding-top: 0;
  border-top: 0;
}

.whats-new-meta_Jj5hhw {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  color: var(--ink-dim);
  font-size: 10px;
}

.whats-new-kind_Jj5hhw {
  padding: 1px 5px;
  border: 1px solid var(--frame-edge);
  color: var(--accent);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.whats-new-kind_Jj5hhw[data-kind="improved"] {
  color: var(--ink);
}

.whats-new-kind_Jj5hhw[data-kind="fixed"] {
  color: var(--accent-strong);
}

.whats-new-title_Jj5hhw {
  margin: 5px 0 3px;
  color: var(--ink);
  font-size: 12px;
  line-height: 1.35;
}

.whats-new-body_Jj5hhw {
  margin: 0;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.5;
}

.whats-new-empty_Jj5hhw {
  color: var(--ink-dim);
  font-size: 11px;
}

.whats-new-open_Jj5hhw {
  display: inline-flex;
  grid-column: 1 / -1;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.whats-new-dot_Jj5hhw {
  display: none;
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  background: var(--danger);
  box-shadow: 0 0 0 2px var(--frame);
}

html[data-whats-new="unread"] .whats-new-dot_Jj5hhw {
  display: inline-block;
}

[data-menu-toggle] {
  position: relative;
}

.whats-new-dot-toggle_Jj5hhw {
  position: absolute;
  top: 3px;
  right: 3px;
}
/* The entry page: the invite gate and the location picker. It sits in the page
   shell above the boot screen, fills the viewport like it, and holds one card.
   The picker's rows are built by entry.js, so they are styled by their data
   hooks and never by a class the script would have to know. */

.entry_GINlug {
  position: absolute;
  inset: 0;
  display: grid;
  justify-items: center;
  align-items: safe center;
  overflow-y: auto;
  background: radial-gradient(circle at top, #342241 0%, #15121c 52%, #0b0b12 100%);
  padding: max(20px, var(--safe-top)) max(20px, var(--safe-right)) max(20px, var(--safe-bottom)) max(20px, var(--safe-left));
}

html[data-airspace-keyboard] .entry_GINlug {
  align-items: start;
}

.entry-card_GINlug {
  display: grid;
  gap: 14px;
  width: min(440px, 100%);
  padding: 24px;
  color: var(--ink);
  background: var(--panel);
  border: 2px solid var(--frame-edge);
  box-shadow: 0 0 0 2px var(--frame);
}

.entry-card_GINlug:has([data-entry-picker]:not([hidden])) {
  width: min(640px, 100%);
}

.entry-picker-layout_GINlug {
  display: grid;
  gap: 20px;
}

.entry-atlas_GINlug {
  min-width: 0;
  margin: 0;
  align-self: start;
  background: var(--panel-soft);
  border: 2px solid var(--frame-edge);
}

.entry-atlas-heading_GINlug {
  padding: 12px;
  color: var(--ink);
  font-size: 12px;
  line-height: 1.5;
}

.entry-map_GINlug {
  position: relative;
  aspect-ratio: 2 / 1;
  background: #211a2d;
  isolation: isolate;
}

.entry-map-art_GINlug {
  display: block;
  width: 100%;
  height: 100%;
  image-rendering: pixelated;
}

.entry-map-lines_GINlug,
.entry-map-markers_GINlug {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.entry-map-lines_GINlug {
  pointer-events: none;
  overflow: visible;
}

.entry-map-lines_GINlug line {
  stroke: var(--ink-dim);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.entry-map-lines_GINlug rect {
  fill: var(--ink-dim);
  stroke: var(--frame);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.entry-map-lines_GINlug [data-selected="true"] line {
  stroke: var(--accent);
  stroke-width: 2;
}

.entry-map-lines_GINlug [data-selected="true"] rect {
  fill: var(--accent);
}

.entry-map-markers_GINlug > button {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--ink);
  background: var(--panel);
  border: 2px solid var(--ink-dim);
  box-shadow: 2px 2px 0 var(--frame);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

.entry-map-markers_GINlug > [aria-pressed="true"] {
  color: var(--frame);
  background: var(--accent);
  border-color: var(--accent);
}

@media (hover: hover) {
  .entry-map-markers_GINlug > button:hover {
    border-color: var(--accent);
  }
}

.entry-map-hint_GINlug {
  margin: 0;
  padding: 12px;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.6;
}

@media (min-width: 900px) {
  .entry-card_GINlug:has([data-entry-picker]:not([hidden])) {
    width: min(1040px, 100%);
  }

  .entry-picker-layout_GINlug {
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    align-items: start;
  }
}

.entry-brand_GINlug {
  margin: 0;
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.entry-status_GINlug {
  margin: 0;
  color: var(--ink-dim);
  font-size: 13px;
}

.entry-title_GINlug {
  margin: 0 0 8px;
  color: var(--ink);
  font-size: 20px;
  line-height: 1.25;
}

.entry-title_GINlug:focus {
  outline: none;
}

.entry-lead_GINlug {
  margin: 0 0 12px;
  color: var(--ink-dim);
  font-size: 13px;
  line-height: 1.5;
}

.entry-notice_GINlug {
  margin: 0 0 12px;
  padding: 8px 10px;
  color: var(--ink);
  background: var(--panel-soft);
  border: 2px solid var(--accent);
  font-size: 13px;
  line-height: 1.4;
}

.entry-form_GINlug {
  display: grid;
  gap: 10px;
}

.entry-label_GINlug {
  color: var(--ink-dim);
  font-size: 12px;
}

.entry-input_GINlug {
  width: 100%;
  padding: 10px 12px;
  color: var(--ink);
  background: #15121c;
  border: 2px solid var(--frame-edge);
  font: inherit;
  font-size: 14px;
}

.entry-error_GINlug {
  margin: 0;
  color: #ffe3de;
  font-size: 12px;
  line-height: 1.4;
}

.entry-button_GINlug {
  padding: 10px 14px;
  color: #1a1220;
  background: var(--accent);
  border: 2px solid var(--frame);
  cursor: pointer;
  font-weight: 700;
}

.entry-button_GINlug:disabled {
  cursor: default;
  opacity: 0.7;
}

@media (hover: hover) {
  .entry-button_GINlug:hover:not(:disabled) {
    background: var(--accent-strong);
  }
}

.entry-locations_GINlug {
  display: grid;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.entry-locations_GINlug > [data-entry-location] {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr) auto;
  align-items: center;
  gap: 2px 12px;
  padding: 12px;
  background: var(--panel-soft);
  border: 2px solid var(--frame-edge);
}

.entry-locations_GINlug > [data-available="false"] {
  opacity: 0.72;
}

.entry-locations_GINlug > [data-selected="true"] {
  border-color: var(--accent);
}

.entry-locations_GINlug > :not(:has([data-entry-picture])) {
  grid-template-columns: 0 minmax(0, 1fr) auto;
}

.entry-locations_GINlug [data-entry-picture] {
  position: relative;
  grid-column: 1;
  grid-row: 1 / span 2;
  width: 64px;
  height: 64px;
  overflow: hidden;
  border: 2px solid var(--frame);
  background: var(--panel);
}

.entry-locations_GINlug [data-entry-picture] img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  image-rendering: pixelated;
}

.entry-locations_GINlug [data-entry-number] {
  position: absolute;
  bottom: 0;
  left: 0;
  padding: 2px 4px;
  color: var(--frame);
  background: var(--accent);
  font-size: 10px;
  font-weight: 700;
}

.entry-locations_GINlug [data-entry-name] {
  grid-column: 2;
  color: var(--ink);
  font-size: 14px;
  line-height: 1.4;
  overflow-wrap: anywhere;
}

.entry-locations_GINlug [data-entry-chapter] {
  grid-column: 2;
  color: var(--ink-dim);
  font-size: 11px;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.entry-locations_GINlug [data-entry-enter],
.entry-locations_GINlug [data-entry-soon] {
  grid-column: 3;
  grid-row: 1 / span 2;
  min-height: 44px;
  min-width: 88px;
  display: grid;
  place-items: center;
  padding: 0 14px;
  font-size: 12px;
}

.entry-locations_GINlug [data-entry-enter] {
  color: #1a1220;
  background: var(--accent);
  border: 2px solid var(--frame);
  font-weight: 700;
  text-decoration: none;
}

@media (hover: hover) {
  .entry-locations_GINlug [data-entry-enter]:hover {
    background: var(--accent-strong);
  }
}

.entry-locations_GINlug [data-entry-soon] {
  color: var(--ink-dim);
  border: 2px dashed var(--frame-edge);
}

@media (max-width: 560px) {
  .entry-card_GINlug:has([data-entry-picker]:not([hidden])) {
    padding: 16px;
  }

  .entry-locations_GINlug > [data-entry-location] {
    grid-template-columns: 64px minmax(0, 1fr);
    gap: 4px 12px;
  }

  .entry-locations_GINlug > :not(:has([data-entry-picture])) {
    grid-template-columns: 0 minmax(0, 1fr);
  }

  .entry-locations_GINlug [data-entry-picture] {
    grid-row: 1 / span 3;
    align-self: start;
  }

  .entry-locations_GINlug [data-entry-enter],
  .entry-locations_GINlug [data-entry-soon] {
    grid-column: 2;
    grid-row: 3;
    justify-self: start;
    margin-top: 4px;
  }
}


