/* Soft, floral, deliberately not a dev tool. Light theme only and on purpose:
   this is a cosy room, not a dashboard. */

:root {
  --pink: #ff7aa8;
  --pink-soft: #ffd7e6;
  --pink-deep: #d9407a;
  --lav: #b892ff;
  --lav-soft: #ece2ff;
  --cream: #fff7fa;
  --ink: #4a3540;
  --ink-soft: #9c8592;
  --card: #ffffff;
  --line: #f6dce7;
  --ok: #57c98a;
  --radius: 18px;
  --shadow: 0 6px 22px rgba(217, 64, 122, 0.12);
  --font: "Segoe UI", -apple-system, BlinkMacSystemFont, "Nunito", system-ui, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
}

body {
  font-family: var(--font);
  color: var(--ink);
  background:
    radial-gradient(1200px 600px at 10% -10%, var(--lav-soft), transparent 60%),
    radial-gradient(900px 500px at 100% 0%, var(--pink-soft), transparent 55%),
    var(--cream);
  overflow: hidden;
}

button { font-family: inherit; cursor: pointer; border: none; }
input, textarea { font-family: inherit; }

/* ------------------------------------------------------------ layout */

.app {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 380px;
  gap: 16px;
  height: 100dvh;
  padding: 16px;
}

.stage {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
  min-height: 0;
}

.panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}

@media (max-width: 900px) {
  .app {
    grid-template-columns: 1fr;
    grid-template-rows: auto minmax(0, 1fr);
    padding: 8px;
    gap: 8px;
  }
  .stage { flex: 0 0 auto; }
}

/* iPad landscape and small laptops. A fixed 380px chat eats a third of an
   1024px iPad, so the column narrows before the layout stacks. */
@media (min-width: 901px) and (max-width: 1200px) {
  .app { grid-template-columns: minmax(0, 1fr) 320px; gap: 12px; padding: 12px; }
}

/* Touch targets. Anything you tap rather than click needs more room, and this
   catches iPad in both orientations regardless of width. */
@media (pointer: coarse) {
  .pick .fav { width: 32px; height: 32px; font-size: 16px; }
  .icon-btn { width: 46px; height: 46px; }
  .icon-mini, .fs-btn { width: 40px; height: 40px; }
  .viewers { right: 62px; }
  .quick button { padding: 8px 13px; }
  .chip-row button { width: 44px; height: 44px; }
}

/* ------------------------------------------------------------ video */

.video-wrap {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  background: #2b1d25;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
}

@media (max-width: 900px) {
  .video-wrap {
    aspect-ratio: 16 / 10;
    flex: 0 0 auto;
    /* Cap the height, or the aspect ratio wins and pushes the chat off screen.
       A 16:10 box on an 820px iPad portrait wants 512px; on a phone in
       landscape it wants more height than the whole viewport has. The video is
       object-fit: contain, so capping letterboxes rather than crops. */
    max-height: 45dvh;
    margin: 0 auto;
  }
}

/* Landscape phones, and iPads with the keyboard up. Almost no vertical room, so
   the video shrinks further and the chat keeps the space. */
@media (max-width: 900px) and (max-height: 520px) {
  .video-wrap { max-height: 38dvh; }
  .xp { padding: 8px 10px; }
  .quick { display: none; }
}

.video-wrap video {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  background: #2b1d25;
}

.video-wrap video.mirrored { transform: scaleX(-1); }

.offline {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 10px;
  text-align: center;
  color: #ffe4ef;
  padding: 24px;
  /* Purely informational, and it covers the whole video area including the
     overlay buttons. Without this it swallows every click on them, and in
     video-only mode that leaves no way back to the chat. */
  pointer-events: none;
}

.offline .big { font-size: 46px; }
.offline p { margin: 0; opacity: 0.85; max-width: 32ch; line-height: 1.5; }

/* Above .offline regardless of DOM order, so the controls stay clickable even
   if another overlay is added to the video later. */
.badge-live, .viewers, .fs-btn { z-index: 2; }

.badge-live {
  position: absolute;
  top: 12px;
  left: 12px;
  display: none;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(217, 64, 122, 0.92);
  color: #fff;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
}

.badge-live.on { display: inline-flex; }
.badge-live::before {
  content: "";
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #fff;
  animation: pulse 1.6s ease-in-out infinite;
}

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

.viewers {
  position: absolute;
  top: 12px;
  right: 56px;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgba(43, 29, 37, 0.6);
  color: #ffe4ef;
  font-size: 12px;
}

.fs-btn {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(43, 29, 37, 0.6);
  color: #ffe4ef;
  font-size: 15px;
  line-height: 1;
  display: grid;
  place-content: center;
  backdrop-filter: blur(2px);
}

.fs-btn:hover { background: rgba(217, 64, 122, 0.85); }

.icon-mini {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--lav-soft);
  font-size: 15px;
  display: grid;
  place-content: center;
}

.icon-mini:hover { background: #e0d0ff; }

/* ------------------------------------------------------------ xp bar */

.xp {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  background: var(--card);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.xp-emoji { font-size: 26px; line-height: 1; }
.xp-body { flex: 1; min-width: 0; }

.xp-top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 8px;
  font-size: 13px;
}

.xp-name { font-weight: 800; color: var(--pink-deep); text-transform: lowercase; }
.xp-next { color: var(--ink-soft); font-size: 12px; }

.xp-track {
  height: 9px;
  margin-top: 7px;
  border-radius: 999px;
  background: var(--lav-soft);
  overflow: hidden;
}

.xp-fill {
  height: 100%;
  width: 0;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--lav), var(--pink));
  transition: width 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.medals-btn {
  padding: 9px 13px;
  border-radius: 999px;
  background: var(--lav-soft);
  color: #6a4bb0;
  font-weight: 700;
  font-size: 13px;
  white-space: nowrap;
}

.medals-btn:hover { background: #e0d0ff; }

/* ------------------------------------------------------------ chat */

.chat-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
}

.chat-title { font-weight: 800; color: var(--pink-deep); }
.chat-sub { font-size: 12px; color: var(--ink-soft); }

.chat-log {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  scrollbar-width: thin;
}

/* A row so the avatar sits beside the bubble; the text stacks inside .msg-col. */
.msg { display: flex; align-items: flex-end; gap: 7px; max-width: 88%; }
.msg-col { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.msg.mine { align-self: flex-end; }
.msg.mine .msg-col { align-items: flex-end; }

.avatar {
  flex: 0 0 auto;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: grid;
  place-content: center;
  font-size: 15px;
  line-height: 1;
  font-weight: 800;
  color: #fff;
  overflow: hidden;
  user-select: none;
  box-shadow: 0 1px 4px rgba(217, 64, 122, 0.18);
}

.avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

.avatar.big {
  width: 72px;
  height: 72px;
  font-size: 34px;
  box-shadow: 0 4px 14px rgba(217, 64, 122, 0.25);
}

.msg-who {
  font-size: 11px;
  font-weight: 700;
  color: var(--ink-soft);
  padding: 0 4px;
}

.bubble {
  padding: 9px 13px;
  border-radius: 16px;
  background: var(--lav-soft);
  line-height: 1.45;
  word-wrap: break-word;
  overflow-wrap: anywhere;
  white-space: pre-wrap;
}

.msg.mine .bubble {
  background: linear-gradient(135deg, var(--pink), var(--lav));
  color: #fff;
}

.bubble img {
  display: block;
  max-width: 220px;
  max-height: 220px;
  width: auto;
  height: auto;
  border-radius: 12px;
}

.msg.media .bubble { padding: 5px; background: transparent; }

.msg.system, .msg.award {
  align-self: center;
  align-items: center;
  max-width: 92%;
  text-align: center;
}

.msg.system .bubble {
  background: transparent;
  color: var(--ink-soft);
  font-size: 12px;
  font-style: italic;
}

.msg.award .bubble {
  background: linear-gradient(135deg, #fff0f6, #f3ebff);
  border: 1px dashed var(--pink);
  color: var(--pink-deep);
  font-weight: 700;
  font-size: 13px;
}

/* ------------------------------------------------------------ composer */

.composer {
  border-top: 1px solid var(--line);
  padding: 10px;
  padding-bottom: max(10px, env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--card);
}

.composer-row { display: flex; gap: 8px; align-items: flex-end; }

.composer textarea {
  flex: 1;
  min-height: 42px;
  max-height: 120px;
  resize: none;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: 20px;
  font-size: 16px; /* 16px stops iOS Safari zooming on focus */
  line-height: 1.35;
  outline: none;
  background: #fffafc;
}

.composer textarea:focus { border-color: var(--pink); }

.icon-btn {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: 50%;
  background: var(--lav-soft);
  font-size: 17px;
  display: grid;
  place-content: center;
}

.icon-btn:hover { background: #e0d0ff; }
.icon-btn.send { background: linear-gradient(135deg, var(--pink), var(--lav)); color: #fff; }

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

.quick button {
  padding: 5px 10px;
  border-radius: 999px;
  background: #fff0f6;
  font-size: 16px;
  line-height: 1;
}

.quick button:hover { background: var(--pink-soft); }

/* ------------------------------------------------------------ pickers */

.picker {
  display: none;
  flex-direction: column;
  gap: 8px;
  /* Tall enough to browse without swallowing the whole screen on a phone. */
  max-height: min(52dvh, 380px);
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #fffafc;
}

.picker.open { display: flex; }

.picker-tabs {
  display: flex;
  gap: 5px;
  flex: 0 0 auto;
  overflow-x: auto;
  scrollbar-width: none;
}

.picker-tabs::-webkit-scrollbar { display: none; }

.picker-tabs button {
  flex: 0 0 auto;
  padding: 7px 12px;
  border-radius: 999px;
  background: #fff;
  border: 1px solid var(--line);
  font-size: 12.5px;
  font-weight: 700;
  color: var(--ink-soft);
  white-space: nowrap;
}

.picker-tabs button.on {
  background: linear-gradient(135deg, var(--pink), var(--lav));
  border-color: transparent;
  color: #fff;
}

.picker input {
  flex: 0 0 auto;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 16px; /* 16px stops iOS Safari zooming on focus */
  outline: none;
}

.picker input:focus { border-color: var(--pink); }
.picker input[hidden] { display: none; }

.picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 6px;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  min-height: 0;
  align-content: start;
}

.pick { position: relative; }

.pick img {
  display: block;
  width: 100%;
  height: 92px;
  object-fit: cover;
  border-radius: 10px;
  cursor: pointer;
  background: var(--lav-soft);
}

.pick img:hover { outline: 2px solid var(--pink); }

/* Always visible rather than hover-only: there is no hover on a phone, and a
   star you cannot find is a star you never use. */
.pick .fav {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: rgba(43, 29, 37, 0.55);
  color: #fff;
  font-size: 14px;
  line-height: 1;
  display: grid;
  place-content: center;
  padding: 0;
  backdrop-filter: blur(2px);
}

.pick .fav.on { background: var(--pink); color: #fff; }
.pick .fav:hover { background: var(--pink-deep); }

.picker-note { font-size: 12px; color: var(--ink-soft); text-align: center; padding: 6px; }

@media (max-width: 900px) {
  .picker { max-height: 46dvh; }
  .picker-grid { grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); }
  .pick img { height: 84px; }
}

/* ------------------------------------------------------------ medals */

.sheet {
  position: fixed;
  inset: 0;
  display: none;
  place-content: center;
  background: rgba(74, 53, 64, 0.45);
  backdrop-filter: blur(3px);
  z-index: 40;
  padding: 20px;
}

.sheet.open { display: grid; }

.sheet-card {
  width: min(560px, 100%);
  max-height: 80dvh;
  overflow-y: auto;
  background: var(--card);
  border-radius: 22px;
  padding: 22px;
  box-shadow: 0 20px 60px rgba(217, 64, 122, 0.3);
}

.sheet-card h2 { margin: 0 0 4px; color: var(--pink-deep); }
.sheet-card .hint { margin: 0 0 16px; color: var(--ink-soft); font-size: 13px; }

.medal-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 10px;
}

.medal {
  padding: 13px;
  border-radius: 14px;
  background: #fff6fa;
  border: 1px solid var(--line);
  text-align: center;
}

.medal.locked { opacity: 0.4; filter: grayscale(1); }
.medal .m-emoji { font-size: 28px; }
.medal .m-title { font-weight: 800; font-size: 13px; margin-top: 4px; }
.medal .m-cap { font-size: 11px; color: var(--ink-soft); margin-top: 3px; line-height: 1.35; }

/* ------------------------------------------------------------ settings */

.set-row { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }
.set-fields { flex: 1; min-width: 0; }

.set-label {
  display: block;
  font-size: 12px;
  font-weight: 800;
  color: var(--ink-soft);
  margin: 14px 0 6px;
  text-transform: lowercase;
}

.set-row .set-label { margin-top: 0; }

#set-name {
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--line);
  border-radius: 14px;
  font-size: 16px;
  outline: none;
  background: #fffafc;
}

#set-name:focus { border-color: var(--pink); }

.chip-row { display: flex; flex-wrap: wrap; gap: 6px; }

.chip-row button {
  width: 40px;
  height: 40px;
  border-radius: 12px;
  background: #fff6fa;
  border: 2px solid transparent;
  font-size: 20px;
  line-height: 1;
  display: grid;
  place-content: center;
}

.chip-row button:hover { background: var(--pink-soft); }
.chip-row button.on { border-color: var(--pink-deep); background: var(--pink-soft); }
.chip-row .swatch { border: 2px solid rgba(0, 0, 0, 0.06); }
.chip-row .swatch.on { border-color: var(--ink); }

.set-photo { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }

.file-btn {
  padding: 9px 14px;
  border-radius: 999px;
  background: var(--lav-soft);
  color: #6a4bb0;
  font-weight: 700;
  font-size: 13px;
  cursor: pointer;
}

.file-btn:hover { background: #e0d0ff; }

.set-status { min-height: 18px; margin-top: 12px; font-size: 12.5px; color: var(--ink-soft); text-align: center; }
.set-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 8px; }

.save-btn {
  padding: 10px 22px;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--pink), var(--lav));
  color: #fff;
  font-weight: 800;
  font-size: 13px;
}

/* ------------------------------------------------------------ layout modes */

/* Video only: the chat panel goes away and the video takes the whole grid.
   The aspect-ratio and height cap from the stacked layout have to be undone or
   the video stays letterboxed in the middle of an empty screen. */
body.layout-video .panel { display: none; }
body.layout-video .app {
  grid-template-columns: 1fr;
  grid-template-rows: minmax(0, 1fr);
}
body.layout-video .video-wrap {
  aspect-ratio: auto;
  max-height: none;
  flex: 1 1 auto;
}

/* Chat only: the whole stage goes, including the video, the xp bar and the
   broadcaster controls. */
body.layout-chat .stage { display: none; }
body.layout-chat .app {
  grid-template-columns: 1fr;
  grid-template-rows: minmax(0, 1fr);
}

/* Two overlay buttons now sit on the video, so they cannot share a corner. */
.fs-btn.layout-btn { right: 54px; }
.viewers { right: 98px; }

@media (pointer: coarse) {
  .fs-btn.layout-btn { right: 60px; }
  .viewers { right: 110px; }
}

/* ------------------------------------------------------------ fullscreen */

/* The document root is what goes fullscreen, so that sheets and toasts (which
   are siblings of .app) still render. The root paints black by default in
   fullscreen, which would frame the page in a hard edge. */
:root:fullscreen,
:root:-webkit-full-screen {
  background: var(--cream);
}

:root:fullscreen body,
:root:-webkit-full-screen body {
  height: 100dvh;
}

/* ------------------------------------------------------------ toast */

.toasts {
  position: fixed;
  top: 18px;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 60;
  pointer-events: none;
  width: min(420px, calc(100vw - 32px));
}

.toast {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  border-radius: 18px;
  background: linear-gradient(135deg, #fff, #fff2f8);
  border: 2px solid var(--pink);
  box-shadow: 0 12px 34px rgba(217, 64, 122, 0.28);
  animation: pop 0.45s cubic-bezier(0.2, 1.4, 0.4, 1);
}

@keyframes pop {
  from { opacity: 0; transform: translateY(-14px) scale(0.94); }
  to { opacity: 1; transform: none; }
}

.toast .t-emoji { font-size: 30px; }
.toast .t-title { font-weight: 800; color: var(--pink-deep); font-size: 14px; }
.toast .t-cap { font-size: 12.5px; color: var(--ink); line-height: 1.4; }

/* ------------------------------------------------------------ gate */

.gate {
  height: 100dvh;
  display: grid;
  place-content: center;
  justify-items: center;
  text-align: center;
  gap: 10px;
  padding: 30px;
}

.gate .big { font-size: 54px; }
.gate h1 { margin: 0; color: var(--pink-deep); font-size: 22px; }
.gate p { margin: 0; color: var(--ink-soft); max-width: 34ch; line-height: 1.55; }

/* ------------------------------------------------------------ broadcaster */

.go-btn {
  width: 100%;
  padding: 19px;
  border-radius: var(--radius);
  font-size: 18px;
  font-weight: 800;
  color: #fff;
  background: linear-gradient(135deg, var(--pink), var(--lav));
  box-shadow: var(--shadow);
}

.go-btn.stop { background: linear-gradient(135deg, #ff6b6b, #d9407a); }
.go-btn:disabled { opacity: 0.55; cursor: wait; }

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

.controls button {
  flex: 1 1 auto;
  min-width: 110px;
  padding: 12px;
  border-radius: 14px;
  background: var(--card);
  box-shadow: var(--shadow);
  font-weight: 700;
  font-size: 13px;
  color: var(--ink);
}

.controls button.off { opacity: 0.5; }
.status { font-size: 13px; color: var(--ink-soft); text-align: center; min-height: 18px; }
