:root { color-scheme: dark; --bg: #07060d; --fg: #eeeaf8; --muted: #b3acc9; --panel: rgba(16, 12, 30, .78);
  --line: rgba(255, 255, 255, .18); --accent: #a98bff;
  --sk-loader-bg: #07060d; --sk-loader-fg: #eeeaf8; --sk-loader-accent: #a98bff; }
* { box-sizing: border-box; }
html, body { margin: 0; height: 100%; background: var(--bg); color: var(--fg); overflow: hidden;
  font: 15px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; overscroll-behavior: none; }
#hall { position: fixed; inset: 0; width: 100%; height: 100%; display: block; touch-action: none; outline: none;
  cursor: grab; }
#hall.dragging { cursor: grabbing; }
button, a { font: inherit; }
#bar { position: fixed; top: 0; left: 0; right: 0; z-index: 3; display: flex; align-items: center; gap: 8px;
  padding: max(8px, env(safe-area-inset-top)) max(12px, env(safe-area-inset-right)) 8px max(12px, env(safe-area-inset-left));
  pointer-events: none; }
#bar > * { pointer-events: auto; }
#bar a, #bar button, #back, #player-open { min-height: 40px; display: inline-flex; align-items: center; padding: 0 12px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--panel); color: var(--fg);
  text-decoration: none; cursor: pointer; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
#bar button[aria-pressed="true"] { background: var(--accent); color: #120c26; border-color: transparent; }
#where { flex: 1; min-width: 0; text-align: center; color: var(--muted); font-size: 13px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
#help { position: fixed; top: calc(max(8px, env(safe-area-inset-top)) + 52px); right: 12px; left: 12px; z-index: 3;
  max-width: 520px; margin-left: auto; padding: 10px 14px; border-radius: 12px; background: var(--panel);
  border: 1px solid var(--line); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
#help p { margin: 0; }
#help .opt { display: flex; align-items: center; gap: 8px; margin-top: 8px; min-height: 44px; color: var(--muted);
  cursor: pointer; }
#help .opt input { width: 20px; height: 20px; accent-color: var(--accent); margin: 0; }
body.touch #help .desk, body:not(.touch) #help .touch { display: none; }
kbd { font: 600 12px ui-monospace, monospace; border: 1px solid var(--line); border-radius: 4px; padding: 0 5px;
  margin: 0 2px; }
#prompt { position: fixed; z-index: 3; left: 50%; transform: translateX(-50%);
  bottom: max(24px, env(safe-area-inset-bottom)); min-height: 52px; padding: 8px 22px; border-radius: 999px;
  border: 2px solid var(--accent); background: var(--panel); color: var(--fg); font-weight: 600; font-size: 16px;
  cursor: pointer; max-width: calc(100vw - 32px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
#prompt.soon { border-color: var(--line); cursor: default; font-weight: normal; }
#prompt .t { display: block; font-size: 12px; font-weight: normal; color: var(--muted); }
#card { position: fixed; z-index: 3; left: max(16px, env(safe-area-inset-left)); bottom: max(24px, env(safe-area-inset-bottom));
  width: min(380px, calc(100vw - 32px)); transform: translateY(8px); padding: 10px 14px 10px 16px;
  border-radius: 12px; background: var(--panel); border: 1px solid var(--line); border-left: 4px solid var(--org, var(--accent));
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); opacity: 0; pointer-events: none;
  transition: opacity .2s ease, transform .2s ease; }
#card.on { opacity: 1; transform: none; }
#card-org { font-size: 12px; color: var(--muted); letter-spacing: .02em; }
#card-title { margin: 1px 0 2px; font-size: 18px; line-height: 1.25; }
#card-blurb { margin: 0 0 4px; font-size: 14px; color: var(--fg); opacity: .9; }
#card-plays { font-size: 12px; color: var(--org, var(--accent)); filter: brightness(1.35); font-weight: 600; }
body.touch #card { top: calc(max(8px, env(safe-area-inset-top)) + 54px); bottom: auto; left: 50%;
  transform: translate(-50%, -8px); }
body.touch #card.on { transform: translate(-50%, 0); }
@media (max-width: 900px) { body:not(.touch) #card { bottom: calc(max(24px, env(safe-area-inset-bottom)) + 72px); } }
body.moving #card { opacity: 0; }
@media (prefers-reduced-motion: reduce) { #card { transition: none; } }
#stick { position: fixed; z-index: 3; width: 128px; height: 128px; border-radius: 50%;
  left: max(20px, env(safe-area-inset-left)); bottom: max(24px, env(safe-area-inset-bottom));
  background: rgba(0, 0, 0, .25); border: 2px solid rgba(255, 255, 255, .45); touch-action: none; }
#knob { position: absolute; left: 50%; top: 50%; width: 54px; height: 54px; margin: -27px 0 0 -27px;
  border-radius: 50%; background: rgba(255, 255, 255, .78); box-shadow: 0 1px 4px rgba(0, 0, 0, .4);
  pointer-events: none; }
body.touch #prompt { left: auto; right: max(16px, env(safe-area-inset-right)); transform: none;
  bottom: max(48px, env(safe-area-inset-bottom)); max-width: calc(100vw - 190px); white-space: normal; }
#player { position: fixed; inset: 0; z-index: 10; display: flex; flex-direction: column; background: #000; }
#player[hidden] { display: none; }
/* The game's overlay: the cabinet's poster over a dark tone (set per game),
   faded in by hall.js once the game has painted; never a blank flash. */
#player { background: #0d0a1a center / cover no-repeat; }
#player.loading { pointer-events: none; }
#player.loading #player-frame, #player.loading #player-bar { visibility: visible; }
#player-frame { background: transparent; }
#fade { position: fixed; inset: 0; z-index: 20; background: #0d0a1a; opacity: 0; pointer-events: none; }
#fade.leaving { transition: opacity .24s ease-in; }
@media (prefers-reduced-motion: reduce) { #fade.leaving { transition-duration: .1s; } }
body.moving #prompt, body.moving #stick, body.moving #help { visibility: hidden; }
#bar { transition: opacity .25s ease; }
body.moving #bar { opacity: 0; pointer-events: none; }
body.moving #bar > * { pointer-events: none; }
#player-bar { display: flex; align-items: center; gap: 8px; min-height: 52px; background: #0d0a1a;
  padding: max(6px, env(safe-area-inset-top)) max(10px, env(safe-area-inset-right)) 6px max(10px, env(safe-area-inset-left));
  border-bottom: 1px solid var(--line); }
#back { background: var(--accent); color: #120c26; border-color: transparent; font-weight: 600; }
#player-title { flex: 1; min-width: 0; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#player-frame { flex: 1; width: 100%; border: 0; display: block; background: #000; }
.nojs { position: fixed; inset: auto 16px 16px; }
body.touch #bar #look { display: none; }
@media (max-width: 480px) { #bar #look { display: none; } #where { font-size: 12px; } }
/* Economy (hall.js setEconomy): a blur behind the buttons is redrawn with
   every frame of the canvas under it, which costs a software renderer more
   than the hall itself. Solid panels instead. */
body.lite #bar a, body.lite #bar button, body.lite #help, body.lite #prompt, body.lite #card, body.lite #toast {
  -webkit-backdrop-filter: none; backdrop-filter: none; }
body.lite { --panel: rgba(16, 12, 30, .92); }
/* The map (hall.js drawMap): top right under the bar; on a phone, behind the Map button. */
#map { position: fixed; z-index: 3; right: max(12px, env(safe-area-inset-right));
  top: calc(max(8px, env(safe-area-inset-top)) + 54px); width: 180px; height: 180px; border-radius: 12px;
  border: 1px solid var(--line); background: var(--panel); cursor: pointer; touch-action: none; }
#bar #map-btn[aria-expanded="true"] { background: var(--accent); color: #120c26; border-color: transparent; }
body.touch #map { width: 200px; height: 200px; }
body.moving #map { visibility: hidden; }
/* On a phone the card takes the same place: the map steps aside while you stand at a cabinet. */
body.touch.at-cabinet #map { visibility: hidden; }
/* A gamepad (hall.js): its line in the help, and a short toast when one connects. */
#help .pad { display: none; margin-top: 4px; }
body.pad #help .pad { display: block; }
/* Low in the middle, over the play prompt, clear of the help, the card and the stick. */
#toast { position: fixed; z-index: 30; left: 50%; bottom: calc(max(24px, env(safe-area-inset-bottom)) + 66px);
  transform: translate(-50%, 6px); max-width: calc(100vw - 32px); padding: 8px 16px; border-radius: 999px;
  background: var(--panel); border: 1px solid var(--line); color: var(--fg); font-size: 14px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; opacity: 0; pointer-events: none; transition: opacity .25s ease, transform .25s ease;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
#toast.on { opacity: 1; transform: translate(-50%, 0); }
body.touch #toast { bottom: calc(max(24px, env(safe-area-inset-bottom)) + 150px); }
@media (prefers-reduced-motion: reduce) { #toast { transition: none; } }
body.lite #toast { -webkit-backdrop-filter: none; backdrop-filter: none; }
/* Settings (hall.js), inside the "?" panel. */
#help { max-height: calc(100dvh - max(8px, env(safe-area-inset-top)) - 140px); overflow-y: auto; overscroll-behavior: contain; }
#help .disclose { margin-top: 10px; min-height: 40px; padding: 0 14px; border-radius: 999px; border: 1px solid var(--line);
  background: transparent; color: var(--fg); cursor: pointer; }
#help .disclose[aria-expanded="true"] { background: var(--accent); color: #120c26; border-color: transparent; }
#settings { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); }
#settings .row { display: flex; justify-content: space-between; align-items: baseline; margin-top: 10px; color: var(--muted); }
#settings output { color: var(--fg); font-variant-numeric: tabular-nums; }
#settings input[type="range"] { width: 100%; min-height: 40px; margin: 0; accent-color: var(--accent); }
#help :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
body.reduce #card, body.reduce #toast { transition: none; }
/* The open panel is on top: over the touch stick, and the map steps aside for it. */
#help { z-index: 4; }
#help:not([hidden]) ~ #map { visibility: hidden; }
body.touch #help { background: rgba(16, 12, 30, .95); }
/* Keyboard and screen-reader access (hall.js tabCabinet). */
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.skip { position: fixed; z-index: 40; left: max(12px, env(safe-area-inset-left)); top: max(8px, env(safe-area-inset-top));
  transform: translateY(-160%); min-height: 44px; display: inline-flex; align-items: center; padding: 0 16px;
  border-radius: 999px; background: var(--accent); color: #120c26; font-weight: 600; text-decoration: none; }
.skip:focus, .skip:focus-visible { transform: none; outline: 2px solid #fff; outline-offset: 2px; }
#bar a:focus-visible, #bar button:focus-visible, #prompt:focus-visible, #back:focus-visible, #player-open:focus-visible {
  outline: 2px solid #fff; outline-offset: 2px; }
/* The pointer: an arrow over the cabinet Tab chose, or at the edge towards it. */
#pointer { position: fixed; z-index: 5; width: 44px; height: 44px; left: 0; top: 0; pointer-events: none;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, .7)); }
#pointer::before { content: ""; position: absolute; inset: 6px; background: var(--accent);
  clip-path: polygon(0 20%, 60% 20%, 60% 0, 100% 50%, 60% 100%, 60% 80%, 0 80%); }
#pointer:not(.edge)::before { animation: point 1.1s ease-in-out infinite; }
@keyframes point { 50% { transform: translateX(-6px); } }
body.reduce #pointer::before { animation: none; }
@media (prefers-reduced-motion: reduce) { #pointer::before { animation: none; } }
body.moving #pointer { visibility: hidden; }
/* Share this spot (hall-share.js): an icon and a word, the icon alone on a narrow screen. */
#bar #share { gap: 6px; }
#bar #share svg { flex: none; }
#bar #share { flex: none; }
/* A phone's bar holds five controls: a little tighter, so none wraps onto two lines. */
@media (max-width: 480px) {
  #bar { gap: 6px; }
  #bar a, #bar button { padding: 0 9px; font-size: 14px; white-space: nowrap; }
  #bar #help-btn { min-width: 40px; justify-content: center; }
  #bar #share { padding: 0; width: 40px; justify-content: center; }
  #bar #share .label { display: none; }
}
/* The share note reuses the gamepad's toast; a link shown to copy by hand wraps and can be selected. */
#toast.url { pointer-events: auto; -webkit-user-select: all; user-select: all; white-space: normal;
  overflow-wrap: anywhere; border-radius: 12px; }
/* A filtered hall (?tag=halloween): what is lit, as a pill in the bar that lights every cabinet again. */
#bar #filtered { gap: 8px; background: var(--accent); color: #120c26; border-color: transparent; font-weight: 600;
  max-width: 46vw; white-space: nowrap; }
#bar #filtered[hidden] { display: none; }
#filtered-what { overflow: hidden; text-overflow: ellipsis; }
#filtered .x { font-size: 18px; line-height: 1; }
/* On a phone the bar is already full: the pill sits just under it, on the left, and what
   opens under the bar (the help, the card at a cabinet) starts below the pill. */
@media (max-width: 640px) {
  #bar #filtered { position: fixed; top: calc(max(8px, env(safe-area-inset-top)) + 48px);
    left: max(12px, env(safe-area-inset-left)); min-height: 34px; max-width: calc(100vw - 24px); font-size: 13px;
    padding: 0 12px; }
  body.filtered #help { top: calc(max(8px, env(safe-area-inset-top)) + 92px); }
  body.filtered.touch #card { top: calc(max(8px, env(safe-area-inset-top)) + 94px); }
}

/* The card's social line (hall-social.js): likes, achievements, the top of the first leaderboard. */
#card-social { margin-top: 6px; font-size: 12px; color: var(--muted); }
#card-social .social-line { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; }
#card-social .likes { color: var(--fg); }
#card-social .heart { pointer-events: auto; display: inline-flex; align-items: center; gap: 4px; min-height: 32px;
  padding: 2px 10px; border-radius: 999px; border: 1px solid var(--line); background: transparent; color: var(--fg);
  font: inherit; cursor: pointer; }
#card-social .heart .h { font-size: 16px; line-height: 1; }
#card-social .heart.on .h { color: #ff5c7a; }
#card-social .heart:disabled { opacity: .6; cursor: progress; }
body.touch #card-social .heart { min-height: 44px; padding: 2px 14px; }
#card-social .board { list-style: none; margin: 6px 0 0; padding: 0; }
#card-social .board li { display: flex; gap: 6px; line-height: 1.5; }
#card-social .board .board-title { color: var(--fg); font-weight: 600; }
#card-social .board .r { width: 1.6em; color: var(--muted); }
#card-social .board .who { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fg); }
#card-social .board .v { font-variant-numeric: tabular-nums; }
#card:not(.on) #card-social .heart, body.moving #card-social .heart { pointer-events: none; }

/* People (hall-people.js): a name over each live player nearby, placed each frame. */
#people-labels { position: fixed; inset: 0; z-index: 2; pointer-events: none; overflow: hidden; }
.person-label { position: absolute; left: 0; top: 0; display: inline-flex; align-items: center; gap: 5px;
  max-width: 180px; padding: 2px 9px 2px 7px; border-radius: 999px; background: rgba(16, 12, 30, .72);
  border: 1px solid var(--who, var(--line)); color: var(--fg); font-size: 12px; font-weight: 600; line-height: 18px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; will-change: transform; }
.person-label::before { content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--who, var(--accent)); }
body.moving #people-labels, body.playing #people-labels { visibility: hidden; }
body.people-off .person-label:not(.anon) { visibility: hidden; }
/* A ghost's or a replay's caption, on a tap (hall-people.js reveal): anonymous, quieter. */
.person-label.anon { font-weight: 500; font-style: italic; color: var(--muted); }
/* Over a figure the mouse can click for its name. */
#hall.on-figure { cursor: pointer; }
/* Its settings (hall-presence.js), in the settings panel. */
#people-settings { margin-top: 10px; padding-top: 6px; border-top: 1px solid var(--line); }
#people-settings .people-head { margin: 4px 0 0; color: var(--fg); font-weight: 600; }
#people-settings .hint { margin: 2px 0 0 28px; font-size: 13px; color: var(--muted); }
#people-settings .hint:empty { display: none; }
#people-settings .opt input:disabled { opacity: .5; }
#show-me-signin { color: var(--accent); font-weight: 600; }
body.touch #show-me-signin { display: inline-flex; align-items: center; min-height: 44px; }
body.touch #people-settings .opt { min-height: 44px; }
/* Walk replays (hall-replays.js): the opt-in's note, and "The hall today". */
#settings .note { margin: 2px 0 0 28px; font-size: 13px; line-height: 1.4; color: var(--muted); }
#help #today-btn { margin-right: 8px; }
#help #today-btn[aria-pressed="true"] { background: var(--accent); color: #120c26; border-color: transparent; }
@media (pointer: coarse) { #help .disclose { min-height: 44px; } #help .opt { min-height: 44px; } }

/* The help panel never covers what plays (a phone): it scrolls within the
   space above the stick and the play button, and while it is open the
   cabinet card (under it, at the top) steps aside, as the map does; the
   play button stays in sight and tappable. */
body.touch #help { max-height: calc(100dvh - max(8px, env(safe-area-inset-top)) - 52px - max(24px, env(safe-area-inset-bottom)) - 152px); }
body.touch #help:not([hidden]) ~ #card { visibility: hidden; }
/* "This device is drawing slowly" (StrataLoader.slow, styled inline): on a
   phone it sits above the stick and the play button, and the help ends above
   it; on a wider screen it takes the bottom right corner, clear of the play
   button in the middle. The hall's own toast goes above it. */
.sk-slow span { flex: 1 1 auto; min-width: 0; }
.sk-slow button { flex: none; white-space: nowrap; }
body.touch .sk-slow { bottom: calc(max(24px, env(safe-area-inset-bottom)) + 140px) !important; z-index: 5 !important;
  left: max(16px, env(safe-area-inset-left)) !important; right: max(16px, env(safe-area-inset-right)); transform: none !important;
  max-width: 480px !important; flex-wrap: wrap; row-gap: 6px !important; }
body.touch .sk-slow span { flex-basis: 100%; }
body.touch .sk-slow button { min-height: 44px !important; min-width: 44px; }
body.touch .sk-slow button:first-of-type { flex: 1 1 auto; }
body.touch:has(.sk-slow) #help { max-height: calc(100dvh - max(8px, env(safe-area-inset-top)) - 52px - max(24px, env(safe-area-inset-bottom)) - 236px); }
body.touch:has(.sk-slow) #toast { bottom: calc(max(24px, env(safe-area-inset-bottom)) + 236px); }
body:not(.touch) .sk-slow { left: auto !important; transform: none !important; right: max(16px, env(safe-area-inset-right));
  bottom: max(24px, env(safe-area-inset-bottom)) !important; max-width: min(460px, calc(50vw - 140px)) !important; }
body:not(.touch):has(.sk-slow) #help { max-height: calc(100dvh - max(8px, env(safe-area-inset-top)) - 52px - max(24px, env(safe-area-inset-bottom)) - 96px); }

/* "You're visible" (hall-presence.js): while the visitor is shown to others, a pill in the
   bar, whatever is open; a dot alone (44 px) on a narrow screen. */
#bar #visible-pill { flex: none; gap: 7px; max-width: 30vw; white-space: nowrap; border-color: rgba(120, 230, 160, .55); }
#bar #visible-pill[hidden] { display: none; }
#visible-pill .dot { flex: none; width: 9px; height: 9px; border-radius: 50%; background: #6fe39a;
  box-shadow: 0 0 0 3px rgba(111, 227, 154, .22); }
#visible-pill .label { overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 640px) {
  #bar #visible-pill { padding: 0; width: 40px; justify-content: center; }
  #bar #visible-pill .label { display: none; }
}
body.touch #bar #visible-pill { min-height: 44px; min-width: 44px; }
/* With the pill, a phone's bar holds six controls: a little tighter again, so none leaves the screen. */
@media (max-width: 480px) {
  body.visible-me #bar { gap: 4px; padding-left: max(8px, env(safe-area-inset-left)); padding-right: max(8px, env(safe-area-inset-right)); }
  body.visible-me #bar a, body.visible-me #bar #sound, body.visible-me #bar #map-btn { padding: 0 7px; }
}
@media (max-width: 400px) {
  body.visible-me #bar #leave { font-size: 13px; }
  body.visible-me #bar #sound, body.visible-me #bar #map-btn { font-size: 13px; }
}
