:root {
  --bg: #05040f;
  --panel: rgba(8, 7, 20, 0.9);
  --line: rgba(170, 150, 255, 0.2);
  /* panels get a light edge, a dark ring outside it and a shadow, so they read on bright and dark scenes alike */
  --frame: rgba(212, 200, 255, 0.72);
  --halo: 0 0 0 1px rgba(0, 0, 0, 0.75), 0 12px 34px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.1);
  --text: #ece8ff;
  --dim: #a29bcf;
  --neon: #2de2e6;
  --pink: #ff3d8b;
}

* { box-sizing: border-box; margin: 0; }

html, body {
  height: 100%;
  background: var(--bg);
  color: var(--text);
  font-family: 'Tiny5', 'Pixelify Sans', ui-monospace, 'Cascadia Mono', monospace;
  overflow: hidden;
  -webkit-font-smoothing: antialiased;
}

#screen {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  object-fit: contain;
  image-rendering: pixelated;
  image-rendering: crisp-edges;
  background: #000;
  touch-action: none; /* fingers drag things in the worlds instead of scrolling */
}

/* painted worlds (engine/painted.js): full-resolution WebGL, letterboxed like the pixel canvas but drawn smooth */
#screen-gl {
  position: fixed;
  inset: 0;
  width: 100vw;
  height: 100vh;
  height: 100dvh;
  object-fit: contain;
  background: #000;
  touch-action: none;
}
#screen[hidden], #screen-gl[hidden] { display: none; }

#fade {
  position: fixed;
  inset: 0;
  background: #000;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.6s ease;
}
#fade.on { opacity: 1; }

#splash {
  position: fixed;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 14px;
  padding: 16px;
  text-align: center;
  /* dark plate behind the title so it reads over any world, fading out to the edges */
  background:
    radial-gradient(ellipse 46% 34% at center, rgba(5, 4, 15, 0.78), rgba(5, 4, 15, 0.45) 70%, rgba(5, 4, 15, 0) 100%),
    rgba(5, 4, 15, 0.35);
  transition: opacity 0.9s ease;
}
#splash.gone { opacity: 0; pointer-events: none; }

h1 {
  font-size: clamp(34px, 8vw, 96px);
  font-weight: 600;
  letter-spacing: 0.08em;
  color: #fff;
  text-shadow: 0 0 22px rgba(45, 226, 230, 0.55), 0 0 2px #fff;
}
.tag { color: #cfc8f5; font-size: clamp(15px, 2.2vw, 22px); text-shadow: 0 1px 8px rgba(0, 0, 0, 0.9); }
/* the h1 carries the name and the tagline, so search engines read both; the tagline keeps its small look */
h1 .brand { display: block; }
h1 .tag { display: block; margin: 14px auto 0; font-weight: 400; letter-spacing: normal; line-height: 1.35; }
h1 .nb { white-space: nowrap; }
.hint { color: #b8b0e0; font-size: 14px; text-shadow: 0 1px 6px rgba(0, 0, 0, 0.9); }

#enter {
  margin-top: 10px;
  font: inherit;
  font-size: 20px;
  letter-spacing: 0.1em;
  color: var(--bg);
  background: var(--neon);
  border: 0;
  padding: 10px 30px;
  cursor: pointer;
  box-shadow: 0 0 26px rgba(45, 226, 230, 0.45);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
#enter:hover { transform: translateY(-1px); box-shadow: 0 0 36px rgba(45, 226, 230, 0.7); }
#enter:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
/* the way in for visitors (a free account, or signing in), or who you are once you're in: its room is kept while the members'
   service answers, so nothing below it jumps */
.splash-acct { min-height: 38px; display: flex; align-items: center; justify-content: center; }
.splash-out { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 10px; }
.splash-out[hidden], .splash-me[hidden] { display: none; }
.splash-acct button {
  font: inherit;
  font-size: 15px;
  letter-spacing: 0.06em;
  color: var(--neon);
  background: rgba(5, 4, 15, 0.55);
  border: 1px solid var(--neon);
  padding: 7px 16px;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
}
.splash-acct button:hover { color: #fff; border-color: #fff; background: rgba(45, 226, 230, 0.12); }
.splash-acct button:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.splash-acct #splashSignin { color: #cfc8f5; border-color: rgba(207, 200, 245, 0.5); }
.splash-acct .splash-me { color: #cfc8f5; border-color: transparent; background: transparent; font-size: 14px; }

#bar {
  position: fixed;
  left: 50%;
  bottom: max(16px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  width: min(1180px, calc(100vw - 32px));
  /* fixed columns, so the bar keeps one shape whatever the world or the song is called */
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) auto;
  align-items: center;
  column-gap: 18px;
  row-gap: 8px;
  padding: 10px 14px;
  background: var(--panel);
  border: 1px solid var(--frame);
  box-shadow: var(--halo);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: opacity 0.6s ease;
  z-index: 6; /* the songs sheet rises from behind it */
}
body:has(#splash:not(.gone)) #bar { opacity: 0; pointer-events: none; }
body.idle #bar { opacity: 0; pointer-events: none; }
/* the play bar can be tucked away (the tab on its top edge, or H) so nothing covers the scene, for playing with the cat; moving the
   mouse does not bring it back, the small "player" button in the corner does (or H again). The bar keeps its size either way. */
#bar #barMin { position: absolute; right: 18px; top: -23px; height: 22px; min-width: 0; padding: 0 12px; font-size: 12px; line-height: 1; color: var(--dim); background: var(--panel); border: 1px solid var(--frame); border-bottom: none; cursor: pointer; }
#bar #barMin:hover, #bar #barMin:focus-visible { color: var(--neon); }
#barShow { display: none; position: fixed; right: max(16px, env(safe-area-inset-right)); bottom: max(16px, env(safe-area-inset-bottom)); z-index: 6; padding: 6px 12px; font: inherit; font-size: 12px; color: var(--dim); background: var(--panel); border: 1px solid var(--frame); cursor: pointer; transition: opacity 0.6s ease; }
#barShow:hover, #barShow:focus-visible { color: var(--neon); border-color: var(--neon); outline: none; opacity: 1; }
body.bar-min #bar { opacity: 0; visibility: hidden; pointer-events: none; }
body.bar-min #barShow { display: block; }
body.bar-min.idle #barShow { opacity: 0.35; }
body:has(#splash:not(.gone)) #barShow { display: none; }
body.bar-min #worlds, body.bar-min #songs:not(.floated), body.bar-min #comms:not(.floated) { bottom: max(16px, env(safe-area-inset-bottom)); }
body.idle { cursor: none; }

#bar button {
  font: inherit;
  color: var(--text);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(190, 175, 255, 0.4);
  min-width: 34px;
  height: 34px;
  cursor: pointer;
}
#bar button:hover { border-color: var(--neon); color: var(--neon); }
#bar button:focus-visible { outline: 2px solid var(--neon); outline-offset: 2px; }

.world, .music, .mix { display: flex; align-items: center; gap: 10px; min-width: 0; }
/* text that changes with the world or the song sits in a box that never resizes */
.wtext { flex: 1; display: grid; grid-template-columns: minmax(0, 1fr); min-width: 0; }
#wname { font-size: 18px; font-weight: 600; color: #fff; }
#wplace { flex: 1; min-width: 0; font-size: 12px; color: var(--dim); }
#wname, #wplace, #np { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wline { display: flex; align-items: center; gap: 6px; min-width: 0; height: 15px; } /* fixed, so the tour tag or the park button never changes the bar's size */
/* park / voyage, at the end of the place line (web/app.js syncPark): no taller than the line, so the bar keeps its size */
#bar #parkBtn { flex: none; height: 15px; min-width: 0; padding: 0 6px; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; line-height: 13px; color: var(--neon); background: transparent; border: 1px solid var(--neon); }
#bar #parkBtn:hover, #bar #parkBtn:focus-visible { color: var(--bg); background: var(--neon); }
#bar #parkBtn[hidden] { display: none; }
/* a members' world: the preview countdown, then "members" (opens the card); the same size as the park chip, so the bar never moves */
#bar #memberChip { flex: none; height: 15px; min-width: 0; padding: 0 6px; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; line-height: 13px; color: var(--pink); background: transparent; border: 1px solid var(--pink); }
#bar #memberChip:hover, #bar #memberChip:focus-visible { color: var(--bg); background: var(--pink); }
#bar #memberChip[hidden] { display: none; }
#worldList .mtag { font-style: normal; font-weight: 400; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--pink); vertical-align: 2px; }

/* the members card, over the stopped picture of a members' world once its preview is over */
/* a window whose minute is up stays covered (the owner: "most of the screen is covered"); the bar above it still works */
#membersCard { position: fixed; inset: 0; z-index: 4; display: grid; place-items: center; padding: 16px; background: rgba(5, 4, 15, 0.9); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); }
#membersCard[hidden] { display: none; }
.mc-plate { max-width: 440px; padding: 22px 24px 20px; text-align: center; background: var(--panel); border: 1px solid var(--frame); box-shadow: var(--halo); }
.mc-kicker { font-size: 11px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--pink); }
#mcTitle { margin: 6px 0 10px; font-size: 24px; font-weight: 600; letter-spacing: 0.06em; color: var(--text); }
.mc-text { font-size: 14px; line-height: 1.4; color: var(--dim); }
#mcJoin { margin-top: 16px; font: inherit; font-size: 17px; letter-spacing: 0.06em; color: var(--bg); background: var(--neon); border: 0; padding: 9px 22px; cursor: pointer; box-shadow: 0 0 22px rgba(45, 226, 230, 0.4); }
#mcJoin:hover { box-shadow: 0 0 32px rgba(45, 226, 230, 0.7); }
#mcJoin[hidden], #mcFree[hidden] { display: none; }
.mc-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 14px; }
.mc-row button { font: inherit; font-size: 13px; color: var(--dim); background: transparent; border: 1px solid var(--line); padding: 5px 12px; cursor: pointer; }
.mc-row button:hover, .mc-row button:focus-visible { color: var(--neon); border-color: var(--neon); outline: none; }
.mc-hush { margin: 14px 0 0; font-size: 12px; letter-spacing: 0.04em; color: var(--dim); }
.mc-hush.nudge { animation: mc-nudge 0.6s ease; }
@keyframes mc-nudge { 0%, 100% { transform: none; } 0%, 90% { color: var(--pink); } 20%, 60% { transform: translateX(-3px); } 40%, 80% { transform: translateX(3px); } }
@media (prefers-reduced-motion: reduce) { .mc-hush.nudge { animation: none; color: var(--pink); } }
#mcJoin:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
#tourTag { font-style: normal; font-size: 10px; letter-spacing: 0.12em; text-transform: uppercase; line-height: 15px; padding: 0 5px; color: var(--bg); background: var(--pink); }
#np { flex: 1; min-width: 0; font-size: 14px; color: var(--pink); }
.mix label { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--dim); }
#ambname { display: inline-block; width: 7ch; text-align: right; }
.mix input[type='range'] { width: 84px; accent-color: var(--neon); }

#commsBtn { padding: 0 10px; position: relative; }
#unread {
  position: absolute;
  top: -8px;
  right: -8px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  font-size: 11px;
  line-height: 18px;
  color: var(--bg);
  background: var(--pink);
  box-shadow: 0 0 10px rgba(255, 61, 139, 0.6);
}

/* ---- the three drawers: worlds slide in from the left, chat from the right,
   songs rise from the bottom. All sit just above the bar, however tall it is. */
#comms, #worlds, #songs {
  position: fixed;
  bottom: calc(max(16px, env(safe-area-inset-bottom)) + var(--bar-h, 72px));
  height: min(420px, calc(100dvh - var(--bar-h, 72px) - 48px));
  display: grid;
  grid-template-columns: minmax(0, 1fr); /* never grow wider than the panel */
  background: var(--panel);
  border: 1px solid var(--frame);
  box-shadow: var(--halo);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: transform 0.35s ease;
  z-index: 5;
}
#comms header, #worlds header, #songs header {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line);
}
.ctitle { display: grid; flex: 1; }
.ctitle strong { font-size: 16px; letter-spacing: 0.12em; color: var(--neon); }
#worlds header span, #songs header span { font-size: 12px; color: var(--dim); }
#commsClose, #worldsClose, #songsClose {
  font: inherit;
  font-size: 20px;
  color: var(--dim);
  background: none;
  border: 0;
  width: 30px;
  height: 30px;
  cursor: pointer;
}
#commsClose:hover, #worldsClose:hover, #songsClose:hover { color: #fff; }

/* chat: from the right. Rows: header, log, the membership panel (web/account.js), the message box, the note */
#comms {
  right: 16px;
  width: min(300px, calc(100vw - 32px));
  grid-template-rows: auto 1fr auto auto auto;
  transform: translateX(calc(100% + 24px));
}
#comms.locked #say { display: none; } /* not a member yet: the panel takes the message box's place */
#comms.open { transform: none; }
#relay { font-size: 12px; color: var(--dim); }
#aboard { font-size: 12px; color: var(--pink); }
#log {
  list-style: none;
  padding: 10px 12px;
  margin: 0;
  overflow-y: auto;
  font-size: 14px;
  line-height: 1.45;
  scrollbar-width: thin;
  scrollbar-color: rgba(170, 150, 255, 0.3) transparent;
}
#log li { padding: 3px 0; overflow-wrap: anywhere; }
#log li b { font-weight: 600; }
#log li.sys { color: var(--dim); font-size: 12px; font-style: italic; }
/* the small report button appears on hover, keyboard focus or a tap on the message */
#log li .rep {
  font: inherit;
  font-size: 11px;
  color: var(--dim);
  background: none;
  border: 0;
  padding: 0 0 0 4px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease;
}
#log li:hover .rep, #log li:focus-within .rep, #log li.tap .rep { opacity: 0.85; }
#log li .rep:hover, #log li .rep:focus-visible { color: var(--pink); opacity: 1; }
#log li .rep:disabled { cursor: default; color: var(--dim); opacity: 0.6; }
#say { display: flex; gap: 6px; padding: 10px 12px 4px; border-top: 1px solid var(--line); }
#say input {
  flex: 1;
  min-width: 0;
  font: inherit;
  font-size: 14px;
  color: var(--text);
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid var(--line);
  padding: 6px 8px;
}
#say input:focus { outline: none; border-color: var(--neon); }
#say button {
  font: inherit;
  font-size: 13px;
  color: var(--text);
  background: transparent;
  border: 1px solid var(--line);
  padding: 0 8px;
  cursor: pointer;
}
#say button[type='submit'] { color: var(--bg); background: var(--neon); border-color: var(--neon); }
#callsign { color: var(--pink) !important; max-width: 96px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.note { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 2px 8px; padding: 2px 12px 10px; font-size: 11px; color: var(--dim); }
#sayStatus { color: var(--pink); }

/* worlds: from the left */
#worldsBtn, #songsBtn { padding: 0 10px; }
#soundOff { padding: 0 8px; font-size: 12px; color: var(--pink) !important; border-color: var(--pink) !important; }
#randomBtn { display: grid; place-items: center; padding: 0; }
#worlds {
  left: 16px;
  width: min(280px, calc(100vw - 32px));
  height: min(460px, calc(100dvh - var(--bar-h, 72px) - 48px));
  grid-template-rows: auto auto auto 1fr;
  transform: translateX(calc(-100% - 24px));
}
#worlds.open { transform: none; }

/* which worlds to travel among (all, the painted windows, the pixel worlds) and a member's favorites, above the tour switch */
#worldView { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; padding: 9px 12px; border-bottom: 1px solid var(--line); }
#worldView .seg { display: inline-flex; }
#worldView .seg button, #favWorlds, #themeBtn, #trafficBtn { font: inherit; font-size: 12px; letter-spacing: 0.04em; color: var(--text); background: transparent; border: 1px solid var(--line); padding: 4px 8px; cursor: pointer; }
#worldView .seg button + button { border-left: none; }
#worldView .seg button:hover, #favWorlds:hover, #themeBtn:hover, #trafficBtn:hover { color: var(--neon); }
#worldView .seg button[aria-checked='true'] { color: var(--bg); background: var(--neon); border-color: var(--neon); }
#favWorlds { display: inline-flex; align-items: center; gap: 5px; margin-left: auto; }
#favWorlds svg { width: 12px; height: 11px; }
#favWorlds[aria-pressed='true'] { color: var(--pink); border-color: var(--pink); }
#favWorlds.locked { opacity: 0.55; }
/* the Halloween theme, right in the drawer (members). Two even rows: which worlds across the top, the two toggles
   (favorites, Halloween) side by side under it */
#themeBtn { display: inline-flex; align-items: center; gap: 5px; }
#worldView .seg { flex: 1 1 auto; }
#worldView .vbreak { flex-basis: 100%; height: 0; }
#worldView .seg button { flex: 1; }
#favWorlds, #themeBtn { flex: 1; justify-content: center; margin-left: 0; }
/* the passers-by in the window views (ships, floating tools, rare finds, Halloween fly-bys), for anyone to switch off:
   on is the usual look, off is dimmed and struck through */
#trafficBtn { display: inline-flex; align-items: center; justify-content: center; gap: 5px; flex: none; }
#trafficBtn svg { width: 14px; height: 7px; }
#trafficBtn[aria-pressed='false'] { opacity: 0.55; text-decoration: line-through; }
#themeBtn svg { width: 13px; height: 12px; }
#themeBtn[aria-pressed='true'] { color: #ff9a3c; border-color: #ff9a3c; }
#themeBtn.locked { opacity: 0.55; }
#worldView button:focus-visible { outline: 2px solid var(--neon); outline-offset: 2px; }
#worldNote { flex-basis: 100%; margin: 0; font-size: 11px; color: var(--pink); }
#worldList .wempty { margin: 14px 8px; font-size: 12px; color: var(--dim); }

/* the guided tour switch at the top of the worlds list */
.opt { position: relative; display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--line); cursor: pointer; }
.opt input { position: absolute; opacity: 0; pointer-events: none; }
.sw { flex: none; position: relative; width: 30px; height: 16px; border: 1px solid var(--line); background: rgba(0, 0, 0, 0.35); transition: border-color 0.2s ease; }
.sw::after { content: ''; position: absolute; top: 2px; left: 2px; width: 10px; height: 10px; background: var(--dim); transition: transform 0.2s ease, background 0.2s ease; }
.opt input:checked + .sw { border-color: var(--neon); }
.opt input:checked + .sw::after { transform: translateX(14px); background: var(--neon); }
.opt input:focus-visible + .sw { outline: 2px solid var(--neon); outline-offset: 2px; }
.what { display: grid; min-width: 0; }
.what b { font-size: 14px; font-weight: 600; color: #fff; }
.what i { font-size: 11px; font-style: normal; color: var(--dim); }

#worldList, #songList { overflow-y: auto; padding: 4px 8px 12px; scrollbar-width: thin; scrollbar-color: rgba(170, 150, 255, 0.3) transparent; }
#worldList h3 { font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; margin: 12px 0 4px; }
#worldList ul { list-style: none; padding: 0; margin: 0; display: grid; gap: 2px; }
#worldList ul[hidden] { display: none; }
/* a group's heading folds its worlds away (web/app.js buildWorldList); these outrank the world buttons' rules below */
#worldList h3 .grp { all: unset; box-sizing: border-box; display: flex; width: 100%; align-items: center; justify-content: space-between; gap: 8px; padding: 7px 10px; cursor: pointer; font: inherit; letter-spacing: inherit; text-transform: inherit; color: var(--pink); background: rgba(255, 61, 139, 0.1); border-left: 3px solid var(--pink); transition: background 0.15s ease, color 0.15s ease; }
#worldList h3 .grp span { font-size: inherit; color: inherit; }
#worldList h3 .grp:hover { color: #fff; background: rgba(255, 61, 139, 0.3); }
#worldList h3 .grp:focus-visible { outline: 2px solid var(--neon); outline-offset: 2px; }
#worldList h3 .grp .chev { font-size: 13px; transition: transform 0.2s ease; }
#worldList h3 .grp[aria-expanded='false'] .chev { transform: rotate(-90deg); }
#worldList button {
  width: 100%;
  display: grid;
  text-align: left;
  font: inherit;
  color: var(--text);
  background: transparent;
  border: 1px solid transparent;
  padding: 6px 8px;
  cursor: pointer;
}
#worldList button strong { font-size: 15px; font-weight: 600; }
#worldList button span { font-size: 12px; color: var(--dim); }
#worldList button:hover { border-color: var(--line); background: rgba(255, 255, 255, 0.03); }
#worldList button.active { border-color: var(--neon); }
#worldList button.active strong { color: var(--neon); }
#worldList button:focus-visible { outline: 2px solid var(--neon); outline-offset: 1px; }
/* a world's row: the world's own button, a small window before a painted view's name, and the heart at the right */
#worldList li { position: relative; }
#worldList li > .wsel { padding-right: 40px; }
#worldList .wwin { width: 13px; height: 12px; margin-right: 6px; vertical-align: -1px; color: var(--neon); opacity: 0.85; }
#worldList .wheart { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); width: 32px; height: 32px; display: grid; place-items: center; padding: 0; color: var(--dim); background: none; border: 1px solid transparent; }
#worldList .wheart svg { width: 16px; height: 14px; }
#worldList .wheart:hover { color: var(--pink); border-color: var(--line); background: none; }
#worldList .wheart.on { color: var(--pink); }
#worldList .wheart.off { opacity: 0.45; }
#worldList .wheart.off:hover { opacity: 1; color: var(--dim); }

/* songs: a sheet that rises out from behind the bar. Any song plays in any world. */
#songs {
  left: 50%;
  width: min(640px, calc(100vw - 32px));
  grid-template-rows: auto 1fr;
  transform: translate(-50%, calc(100% + var(--bar-h, 72px) + 64px));
  z-index: 4;
}
#songs.open { transform: translate(-50%, 0); }
#songList ul { list-style: none; padding: 0; margin: 0; }
#songList li { break-inside: avoid; padding-bottom: 2px; }
#songList button {
  width: 100%;
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr) auto;
  grid-template-areas: 'eq name time' 'eq home time';
  column-gap: 10px;
  align-items: center;
  text-align: left;
  font: inherit;
  color: var(--text);
  background: transparent;
  border: 1px solid transparent;
  padding: 6px 8px;
  cursor: pointer;
}
#songList button strong { grid-area: name; font-size: 15px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#songList button em { grid-area: home; font-style: normal; font-size: 12px; color: var(--dim); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#songList button span { grid-area: time; font-size: 12px; color: var(--dim); }
#songList button:hover { border-color: var(--line); background: rgba(255, 255, 255, 0.03); }
#songList button.active { border-color: var(--neon); }
#songList button.active strong { color: var(--neon); }
#songList button:focus-visible { outline: 2px solid var(--neon); outline-offset: 1px; }
.eq { grid-area: eq; display: none; align-items: flex-end; gap: 2px; width: 14px; height: 14px; }
.eq b { flex: 1; height: 45%; background: var(--neon); }
#songList button.active .eq { display: flex; }
#songs.playing button.active .eq b { animation: eq 0.8s ease-in-out infinite alternate; }
#songs.playing button.active .eq b:nth-child(2) { animation-duration: 0.6s; animation-delay: -0.3s; }
#songs.playing button.active .eq b:nth-child(3) { animation-duration: 1s; animation-delay: -0.5s; }
@keyframes eq { from { height: 20%; } to { height: 100%; } }
@media (min-width: 672px) {
  #songList ul { columns: 2; column-gap: 8px; }
}

#creditsLink {
  position: fixed;
  left: 16px;
  top: 12px;
  font-size: 12px;
  color: var(--dim);
  text-decoration: none;
  opacity: 0.7;
  transition: opacity 0.6s ease;
}
#creditsLink a { color: inherit; text-decoration: none; margin-right: 10px; }
#creditsLink a:hover { color: #fff; }
/* "sign in" (or the member's callsign) opens the membership panel in the comms drawer, in this tab: it is a button, not a link */
#creditsLink button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
#creditsLink button:hover { color: #fff; }
#creditsLink button:focus-visible, #creditsLink a:focus-visible { outline: 1px solid var(--neon); outline-offset: 2px; }
#creditsLink:hover { opacity: 1; }
/* a blog post this visitor has not opened yet (web/blog-dot.js) */
#creditsLink a.new { color: #fff; }
#creditsLink a.new::after { content: ''; display: inline-block; width: 4px; height: 4px; margin-left: 4px; vertical-align: 2px; background: var(--pink); }
.whatis { font-size: 13px; color: #b8b0e0; text-decoration: none; text-shadow: 0 1px 6px rgba(0, 0, 0, 0.9); }
.whatis:hover { color: #fff; text-decoration: underline; }
body.idle #creditsLink, body:has(#splash:not(.gone)) #creditsLink { opacity: 0; pointer-events: none; }

/* mid-size windows: the sliders drop onto a second row */
@media (max-width: 1199px) {
  #bar { width: min(980px, calc(100vw - 32px)); grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .mix { grid-column: 1 / -1; justify-content: center; }
}
/* phones: one column of three rows */
@media (max-width: 760px) {
  #bar { grid-template-columns: minmax(0, 1fr); row-gap: 10px; }
  .mix { order: 2; }
  .music { order: 3; }
  .mix input[type='range'] { width: 64px; }
}
@media (max-width: 420px) {
  .world, .music, .mix { gap: 6px; }
  .mix input[type='range'] { width: 48px; }
}

@media (prefers-reduced-motion: reduce) {
  #fade, #splash, #bar, #comms, #worlds, #songs, .sw::after, #log li .rep { transition: none; }
  #songs.playing button.active .eq b { animation: none; }
}

/* ---- chat is coming soon: the panel shows a short note instead of the log and the message box, and the membership
   panel (sign in) below it. On a short screen the drawer scrolls rather than growing past the top. */
#comms .soonBox { display: none; }
#comms.soon { height: auto; max-height: calc(100dvh - var(--bar-h, 72px) - 48px); overflow-y: auto; grid-template-rows: auto auto auto; }
#comms.soon .soonBox { display: grid; justify-items: center; gap: 10px; padding: 26px 22px 30px; text-align: center; font-size: 14px; line-height: 1.5; color: var(--dim); }
#comms.soon .soonBox strong { font-size: 18px; letter-spacing: 0.16em; color: var(--pink); }
#comms.soon .soonBox p { margin: 0; }
#comms.soon #log, #comms.soon #say, #comms.soon .note, #comms.soon #aboard { display: none; }

/* ---- how many are listening right now, inside the comms panel */
.live { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 0; font-size: 13px; color: var(--neon); }
.live[hidden] { display: none; }
.live .dot { width: 7px; height: 7px; flex: none; background: var(--neon); animation: livePulse 2.4s ease-in-out infinite; }
@keyframes livePulse { 50% { opacity: 0.3; } }

/* ---- comms can be dragged anywhere by its header (web/drag.js); double-click the header to dock it */
#comms header { cursor: grab; touch-action: none; user-select: none; }
#comms.dragging header { cursor: grabbing; }
.grip { flex: none; width: 8px; height: 14px; opacity: 0.55; background-image: radial-gradient(var(--dim) 1px, transparent 1.4px); background-size: 4px 4px; }
#comms.floated { right: auto; bottom: auto; transform: none; opacity: 0; pointer-events: none; transition: opacity 0.25s ease; z-index: 7; }
#comms.floated.open { opacity: 1; pointer-events: auto; }
#comms.dragging { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .live .dot { animation: none; }
  #comms.floated { transition: none; }
}

/* ---- the songs sheet can be dragged anywhere by its header too (web/drag.js); double-click the header to dock it again. Floated,
   it keeps the sheet's own size and frame and fades in and out where it was put, like comms. A phone keeps it a bottom sheet. */
#songs header { cursor: grab; touch-action: none; user-select: none; }
#songs.dragging header { cursor: grabbing; }
#songs.floated { bottom: auto; transform: none; opacity: 0; pointer-events: none; transition: opacity 0.25s ease; z-index: 7; }
#songs.floated.open { opacity: 1; pointer-events: auto; }
#songs.dragging { transition: none; }
@media (max-width: 760px) {
  #songs header { cursor: auto; touch-action: auto; user-select: auto; }
  #songs header .grip { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  #songs.floated { transition: none; }
}

/* ---- the worlds list moves by its header too (web/drag.js), and fades in and out where it was put */
#worlds header { cursor: grab; touch-action: none; user-select: none; }
#worlds.dragging header { cursor: grabbing; }
#worlds.floated { bottom: auto; transform: none; opacity: 0; pointer-events: none; transition: opacity 0.25s ease; z-index: 7; }
#worlds.floated.open { opacity: 1; pointer-events: auto; }
#worlds.dragging { transition: none; }
@media (prefers-reduced-motion: reduce) {
  #worlds.floated { transition: none; }
}

/* ---- the songs sheet can be resized (web/drag.js makeResizable): by its top edge while docked, its lower right corner while floated */
#songs { max-width: calc(100vw - 16px); max-height: calc(100dvh - var(--bar-h, 72px) - 48px); }
#songs.floated { max-height: calc(100dvh - 16px); }
#songs.resizing { transition: none; user-select: none; }
.resizer { position: absolute; z-index: 2; touch-action: none; }
.resizer.top { left: 32px; right: 32px; top: -4px; height: 8px; cursor: ns-resize; }
.resizer.corner { display: none; right: 0; bottom: 0; width: 16px; height: 16px; cursor: nwse-resize; opacity: 0.6; background: linear-gradient(135deg, transparent 48%, var(--dim) 48%, var(--dim) 56%, transparent 56%, transparent 68%, var(--dim) 68%, var(--dim) 76%, transparent 76%); }
.resizer.corner:hover { opacity: 1; }
#songs.floated .resizer.top { display: none; }
#songs.floated .resizer.corner { display: block; }
@media (max-width: 760px) {
  .resizer { display: none !important; }
}

/* ---- the play bar can be dragged by the grip on its left edge (web/drag.js); double-click the grip to dock it */
.barGrip { position: absolute; left: 1px; top: 0; bottom: 0; width: 12px; height: auto; padding: 12px 2px; background-clip: content-box; background-origin: content-box; cursor: grab; touch-action: none; user-select: none; opacity: 0.6; }
.barGrip:hover { opacity: 1; }
#bar.dragging .barGrip { cursor: grabbing; }
#bar.floated { bottom: auto; transform: none; }
#bar.dragging { transition: none; }
body.bar-floated #worlds, body.bar-floated #songs:not(.floated), body.bar-floated #comms:not(.floated) { bottom: max(16px, env(safe-area-inset-bottom)); }
