:root {
  --bg: #0d0f13;
  --panel: #161a21;
  --line: #262c36;
  --text: #e7eaf0;
  --dim: #8b94a3;
  --accent: #e0b23c;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

* { box-sizing: border-box; }

/* The `hidden` attribute is honoured by a UA rule of the form
   `[hidden] { display: none }`, which any author rule that sets `display`
   outranks -- and `button, .btn` below does exactly that. Without this, every
   hidden button (the owner-only upload control among them) renders for
   everyone. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
}

/* ------------------------------------------------------------ login */

body.login {
  display: grid;
  place-items: center;
  min-height: 100vh;
}

body.login form {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 32px;
  width: min(360px, 90vw);
  text-align: center;
}

body.login h1 { margin: 0 0 4px; font-size: 22px; }
body.login p  { color: var(--dim); margin: 0 0 20px; font-size: 14px; }

input {
  width: 100%;
  padding: 10px 12px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #0b0d11;
  color: var(--text);
  font-size: 15px;
}

button, .btn {
  display: inline-block;
  margin-top: 12px;
  padding: 9px 14px;
  border-radius: 6px;
  border: 1px solid var(--line);
  background: #1e242e;
  color: var(--text);
  font-size: 14px;
  cursor: pointer;
  text-decoration: none;
}

button:hover, .btn:hover { border-color: var(--accent); }
button.on { border-color: var(--accent); color: var(--accent); }

.error { color: #e06c6c; min-height: 20px; margin-top: 10px; font-size: 14px; }

/* ------------------------------------------------------------ app */

body.app {
  display: grid;
  grid-template-columns: 1fr 320px;
  height: 100vh;
  overflow: hidden;
}

/* min-height: 0 on both grid children is load-bearing. Grid items default to
   min-height: auto, so a sidebar taller than the viewport forces the single
   grid ROW past 100vh -- which drags the video column down with it and pushes
   the control bar and the chat input under the bottom edge, where
   `body { overflow: hidden }` clips them. That is why both vanish together
   even though they sit in different columns. */
body.app > main, body.app > aside { min-height: 0; }

main { display: flex; flex-direction: column; min-width: 0; min-height: 0; }

.stage { position: relative; flex: 1; background: #000; min-height: 0; }

#video { width: 100%; height: 100%; display: block; background: #000; }

#overlay {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  text-align: center;
  background: rgba(8, 10, 14, .82);
  cursor: pointer;
}

#overlay.gone { display: none; }
#overlay h2 { margin: 0 0 6px; }
#overlay p  { color: var(--dim); margin: 0; }

#toasts {
  position: absolute;
  left: 16px;
  bottom: 76px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  pointer-events: none;
}

.toast {
  background: rgba(0, 0, 0, .72);
  border: 1px solid var(--line);
  border-radius: 6px;
  padding: 6px 10px;
  font-size: 13px;
}

.bar {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  border-top: 1px solid var(--line);
  background: var(--panel);
}

.bar h1 {
  font-size: 15px;
  font-weight: 600;
  margin: 0;
  flex: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.bar button, .bar .btn { margin-top: 0; }

.status {
  font-variant-numeric: tabular-nums;
  color: var(--dim);
  font-size: 13px;
  white-space: nowrap;
}

/* ------------------------------------------------------------ sidebar */

aside {
  border-left: 1px solid var(--line);
  background: var(--panel);
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

/* Each panel is sized by its own content and scrolls internally; only the chat
   takes the leftover space. Without the caps below, the roster grows with the
   number of people in the room, crushes the chat log to nothing and pushes the
   input past the bottom of `aside`, which is `overflow: hidden` -- at which
   point you can see the chat but cannot type in it. */
aside section {
  flex: 0 0 auto;
  padding: 12px 14px;
  border-bottom: 1px solid var(--line);
  min-height: 0;
}

aside section.chat {
  flex: 1 1 0;
  min-height: 140px;
  display: flex;
  flex-direction: column;
  border-bottom: 0;
}

aside h3 {
  margin: 0 0 8px;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--dim);
}

aside ul { list-style: none; margin: 0; padding: 0; font-size: 14px; }

#library { max-height: 24vh; overflow-y: auto; }

#library li { display: flex; align-items: center; gap: 8px; }

#library button {
  margin: 0;
  padding: 6px 8px;
  flex: 1;
  text-align: left;
  border-color: transparent;
  background: transparent;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

#library button.current { color: var(--accent); }
#library .size { color: var(--dim); font-size: 12px; }
#library .empty { color: var(--dim); font-size: 13px; }

#users { max-height: 20vh; overflow-y: auto; }
#users li { padding: 3px 0; }
#users li.me { color: var(--accent); }

.tag.ready { color: #6fbf73; border-color: #6fbf73; }

.tag {
  margin-left: 6px;
  font-size: 11px;
  color: var(--dim);
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
}

/* Login page mode switch */
.tabs { display: flex; gap: 6px; margin-bottom: 14px; }
.tabs .tab { flex: 1; margin-top: 0; font-size: 13px; }
.tabs .tab.on { border-color: var(--accent); color: var(--accent); }
body.login input { margin-bottom: 8px; }

/* Uploads in progress */
#jobs li { font-size: 12px; color: var(--dim); padding: 6px 0; }
#jobs li + li { border-top: 1px solid var(--line); }
#jobs .name {
  color: var(--text);
  font-size: 13px;
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
#jobs .meta { display: flex; justify-content: space-between; gap: 8px; margin-top: 3px; }
#jobs li.error .name { color: #e06c6c; }
#jobs li.error .bar-fill { background: #e06c6c; }
#jobs li.ok .name { color: #6fbf73; }
#jobs li.ok .bar-fill { background: #6fbf73; }

.bar-track {
  height: 5px;
  border-radius: 3px;
  background: #0b0d11;
  overflow: hidden;
  margin-top: 5px;
}

.bar-fill {
  height: 100%;
  background: var(--accent);
  width: 0;
  transition: width .25s linear;
}

/* Conversion has no meaningful percentage, so the bar sweeps instead of
   pretending to know one. */
.bar-track.busy .bar-fill {
  width: 35%;
  background: linear-gradient(90deg, transparent, var(--accent), transparent);
  animation: sweep 1.1s ease-in-out infinite;
}

@keyframes sweep {
  0%   { transform: translateX(-100%); }
  100% { transform: translateX(300%); }
}

@media (prefers-reduced-motion: reduce) {
  .bar-track.busy .bar-fill { animation: none; width: 100%; opacity: .5; }
}

/* Drag a film anywhere onto the video to upload it */
#dropzone {
  position: absolute;
  inset: 0;
  z-index: 5;
  display: none;
  place-items: center;
  background: rgba(8, 10, 14, .88);
  border: 2px dashed var(--accent);
  color: var(--accent);
  font-size: 18px;
  pointer-events: none;
}

#dropzone.on { display: grid; }

/* Local cache panel */
.cache-row { display: flex; align-items: center; gap: 8px; justify-content: space-between; }
.cache-row button { margin-top: 0; padding: 4px 8px; font-size: 12px; }
#cache-state { font-size: 13px; }
.dim { color: var(--dim); font-size: 12px; margin-top: 4px; }

/* An owner -- a 4th job or level 200+ account. */
.tag.owner { color: var(--accent); border-color: var(--accent); }

#chat-log { flex: 1 1 0; min-height: 0; overflow-y: auto; margin-bottom: 8px; }
#chat-form { flex: 0 0 auto; }
#chat-log li { padding: 3px 0; word-break: break-word; }
#chat-log b { color: var(--accent); font-weight: 600; }

/* On a phone the sidebar sits under the video, so the panel caps that are
   comfortable beside a 1080p window leave the chat one line tall. Everything
   gets tighter and the chat keeps the remainder. */
@media (max-width: 900px) {
  body.app { grid-template-columns: 1fr; grid-template-rows: 1fr auto; }
  aside { border-left: 0; border-top: 1px solid var(--line); max-height: 52vh; }
  aside section { padding: 8px 12px; }
  aside section.chat { min-height: 120px; }
  #library { max-height: 15vh; }
  #users   { max-height: 11vh; }
}
