/* Release marker: split order-panel audio ownership 2026-09-07. */
:root {
  --card-bg: #fff;
  --card-opacity: 68%;
  --accent: #6d4aff;
  --ink: #221b36;
  --muted: #716a80;
  --readable: rgba(255, 255, 255, 0.9);
  --order: #1a2420;
  --order-raised: #24332c;
  --order-line: #2a3a32;
  --order-accent: #34d399;
  --order-text: #e6ede8;
  --order-muted: #8ea89a;
  --sl-panel: rgba(20, 30, 26, 0.94);
  --sl-raised: rgba(36, 51, 44, 0.96);
  --sl-line: rgba(110, 231, 183, 0.34);
  --sl-line-soft: rgba(110, 231, 183, 0.16);
  --sl-accent: #34d399;
  --sl-bright: #a7f3d0;
  --sl-text: #f2f7f4;
  --sl-muted: #a9bdb3;
  --sl-header-band: linear-gradient(
    90deg,
    rgba(4, 120, 87, 0.96),
    rgba(5, 150, 105, 0.72) 62%,
    rgba(5, 150, 105, 0.12)
  );
  --sl-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08), inset 0 0 0 1px rgba(167, 243, 208, 0.08),
    0 18px 48px rgba(0, 0, 0, 0.4);
  --broadcast-label-text: clamp(15px, 1.55vw, 18px);
  --broadcast-current-name: clamp(24px, 2.7vw, 32px);
  --broadcast-product-text: clamp(21px, 2.25vw, 26px);
  --broadcast-waiting-text: clamp(15px, 1.55vw, 18px);
  --broadcast-hit-title: clamp(30px, 3.2vw, 38px);
  --broadcast-hit-row: clamp(18px, 2vw, 24px);
  --broadcast-command-text: clamp(16px, 1.8vw, 20px);
  --right-safe-zoom: 0.6;
  --hit-honor: #ffd84d;
  --hit-honor-glow: rgba(255, 216, 77, 0.38);
  --broadcast-edge-gutter: clamp(0px, 0.42vw, 8px);
  --broadcast-right-column: min(58vw, 760px);
  --broadcast-column-gap: clamp(6px, 0.8vw, 10px);
  --broadcast-left-column: min(
    40vw,
    520px,
    calc(
      100vw -
      var(--broadcast-right-column) -
      var(--broadcast-column-gap) -
      var(--broadcast-edge-gutter) -
      var(--broadcast-edge-gutter)
    )
  );
  --event-copy: #f8fafc;
  --event-copy-shadow: 0 1px 2px rgba(0, 0, 0, 0.72), 0 0 12px rgba(248, 250, 252, 0.24);
}
* {
  box-sizing: border-box;
}
[hidden] {
  display: none !important;
}
html,
body {
  width: 100%;
  min-height: 100%;
  margin: 0;
  overflow: hidden;
  background: transparent !important;
}
body {
  color: var(--ink);
  font-family: Pretendard, "Noto Sans KR", "Apple SD Gothic Neo", system-ui, sans-serif;
}
.stage {
  position: relative;
  display: grid;
  width: 100vw;
  min-height: 100vh;
  align-content: start;
  justify-items: center;
  gap: clamp(16px, 2.4vw, 28px);
  padding-block: clamp(34px, 7vh, 132px);
  padding-inline: var(--broadcast-edge-gutter);
}
.broadcast-grid {
  display: grid;
  grid-template-columns: minmax(0, var(--broadcast-left-column)) minmax(
      0,
      var(--broadcast-right-column)
    );
  width: 100%;
  max-width: none;
  gap: var(--broadcast-column-gap);
  align-items: start;
  justify-content: space-between;
  --ink: var(--order-text);
  --muted: var(--order-muted);
  --readable: rgba(36, 51, 44, 0.82);
}
.broadcast-banner {
  width: min(68vw, 720px);
  max-width: 720px;
  gap: 2px;
  padding: clamp(10px, 1.4vw, 16px);
  border-width: clamp(3px, 0.4vw, 5px);
  border-radius: clamp(18px, 3vw, 28px);
  font-size: clamp(16px, 1.8vw, 22px);
}
.broadcast-left,
.broadcast-right {
  display: grid;
  min-width: 0;
  gap: clamp(12px, 1.8vw, 20px);
  align-content: start;
}
.event-card,
.link-box,
.hit-box {
  position: relative;
  width: min(88vw, 880px);
  padding: clamp(22px, 3.6vw, 40px);
  overflow: hidden;
  border: clamp(4px, 0.55vw, 8px) solid var(--accent);
  border-radius: clamp(28px, 5vw, 52px);
  background: color-mix(in srgb, var(--card-bg) var(--card-opacity), transparent);
  box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.8);
  /* backdrop-filter 제거 (2026-08-29). OBS 브라우저 소스에서 투명 배경 위의
     큰 backdrop-filter 는 프레임을 떨어뜨려 방송 화면이 깜빡인다. 카드 불투명도가
     95% 라 뒤가 5% 만 비치므로 시각적 손실은 사실상 없다. */
  backdrop-filter: none;
  transform: translate(var(--offset-x, 0), var(--offset-y, 0)) scale(var(--scale, 1));
  transform-origin: center;
}
.event-card::before,
.link-box::before,
.hit-box::before {
  position: absolute;
  inset: -45% 42% 50% -24%;
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--accent) 22%, transparent),
    transparent 68%
  );
  content: "";
  pointer-events: none;
}
.event-card > *,
.link-box > *,
.hit-box > * {
  position: relative;
}
.status-row {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-size: clamp(14px, 2vw, 20px);
  font-weight: 950;
  letter-spacing: 0.08em;
}
.live-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #aaa4b0;
}
.event-card[data-status="collecting"] .live-dot,
.event-card[data-status="drawing"] .live-dot,
.event-card[data-status="degraded"] .live-dot {
  background: #22c55e;
  box-shadow: 0 0 0 8px rgba(34, 197, 94, 0.15);
  animation: pulse 1.8s ease-in-out infinite;
}
.badge {
  margin-left: auto;
  padding: 6px 10px;
  border-radius: 999px;
  color: #78350f;
  background: #fef3c7;
  font-size: 12px;
}
.eyebrow {
  margin: clamp(18px, 3vw, 28px) 0 8px;
  color: var(--accent);
  font-size: clamp(14px, 2.4vw, 22px);
  font-weight: 950;
  letter-spacing: 0.16em;
}
.event-card h1 {
  margin: 0;
  overflow-wrap: anywhere;
  font-size: clamp(34px, 6vw, 68px);
  line-height: 1.05;
  letter-spacing: -0.04em;
}
.join {
  display: inline-flex;
  gap: 10px;
  margin: clamp(18px, 3vw, 30px) 0;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--readable);
  font-size: clamp(19px, 3.3vw, 34px);
  font-weight: 850;
}
.join strong {
  color: var(--accent);
}
.metrics {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}
.metrics > div {
  display: grid;
  gap: 4px;
  padding: clamp(14px, 2.5vw, 24px);
  border-radius: clamp(16px, 2.6vw, 28px);
  background: var(--readable);
}
.metrics span {
  color: var(--muted);
  font-size: clamp(13px, 2vw, 19px);
  font-weight: 800;
}
.metrics strong {
  font-size: clamp(28px, 5vw, 58px);
  font-variant-numeric: tabular-nums;
}
.draw-view {
  display: grid;
  min-height: 280px;
  align-content: center;
  justify-items: center;
  text-align: center;
}
.draw-view > strong {
  max-width: 100%;
  overflow-wrap: anywhere;
  color: var(--accent);
  font-size: clamp(42px, 8vw, 90px);
}
.draw-view small {
  margin-top: 12px;
  font-size: clamp(18px, 3vw, 32px);
  font-weight: 800;
}
.degraded {
  margin: 16px 0 0;
  padding: 12px 14px;
  border-radius: 14px;
  color: #7f1d1d;
  background: #fee2e2;
  font-weight: 850;
}
.link-box {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 18px 28px;
  font-size: clamp(24px, 4vw, 44px);
  font-weight: 900;
}
.link-box span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.link-box small {
  display: none;
}
.hit-box {
  --hit-row-gap: 8px;
  --hit-row-height: clamp(34px, 3.4vw, 46px);
  --hit-visible-rows: 3;
  min-width: 0;
  text-align: left;
}
.hit-box h2 {
  margin: 0;
  font-size: clamp(28px, 4vw, 46px);
}
.hit-viewport {
  margin-top: 12px;
  overflow: hidden;
  mask-image: linear-gradient(to bottom, transparent, #000 10%, #000 90%, transparent);
}
.hit-track {
  display: flex;
  flex-direction: column;
  gap: var(--hit-row-gap);
  transform: translateY(0);
  will-change: transform;
}
.hit-track.is-cycling {
  animation: hit-cycle var(--hit-cycle-duration) linear infinite;
}
.hit-box ul {
  display: grid;
  flex: none;
  gap: var(--hit-row-gap);
  margin: 0;
  padding: 0;
  list-style: none;
}
.hit-box li {
  display: flex;
  height: var(--hit-row-height);
  align-items: center;
  justify-content: center;
  max-width: 70vw;
  overflow: hidden;
  font-size: clamp(18px, 3vw, 32px);
  font-weight: 850;
  text-align: center;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.order-box {
  width: min(88vw, 880px);
  padding: clamp(20px, 3vw, 32px);
  border: 1px solid var(--sl-line);
  border-radius: 22px;
  color: var(--sl-text);
  background: var(--sl-panel);
  box-shadow: var(--sl-shadow);
  /* backdrop-filter 제거 (2026-08-29). OBS 브라우저 소스에서 투명 배경 위의
     큰 backdrop-filter 는 프레임을 떨어뜨려 방송 화면이 깜빡인다. 카드 불투명도가
     95% 라 뒤가 5% 만 비치므로 시각적 손실은 사실상 없다. */
  backdrop-filter: none;
  transform: translate(var(--offset-x, 0), var(--offset-y, 0)) scale(var(--scale, 1));
  transform-origin: center;
}
.order-box[hidden] {
  display: block !important;
}
.broadcast-item {
  width: 100%;
  max-width: none;
  min-width: 0;
}
.broadcast-left .link-box,
.broadcast-left .event-card,
.broadcast-right .hit-box {
  border: 1px solid var(--sl-line);
  border-radius: 22px;
  color: var(--sl-text);
  background: var(--sl-panel);
  box-shadow: var(--sl-shadow);
  /* backdrop-filter 제거 (2026-08-29). OBS 브라우저 소스에서 투명 배경 위의
     큰 backdrop-filter 는 프레임을 떨어뜨려 방송 화면이 깜빡인다. 카드 불투명도가
     95% 라 뒤가 5% 만 비치므로 시각적 손실은 사실상 없다. */
  backdrop-filter: none;
}
.broadcast-left .link-box::before,
.broadcast-right .hit-box::before {
  display: none;
}
.broadcast-left .event-card {
  isolation: isolate;
  width: 100%;
  color: var(--event-copy);
}
.broadcast-left .event-card::before,
.broadcast-left .event-card::after {
  display: block;
  z-index: 0;
  content: "";
  position: absolute;
  pointer-events: none;
}
.broadcast-left .event-card::before {
  inset: -26% -18% 34% -18%;
  background:
    radial-gradient(circle at 18% 34%, var(--event-aura-violet), transparent 47%),
    radial-gradient(circle at 78% 26%, var(--event-aura-sky), transparent 43%);
  opacity: 0.6;
}
.broadcast-left .event-card::after {
  inset: -34% -24% 28% -24%;
  background: radial-gradient(circle at 53% 38%, rgba(255, 255, 255, 0.16), transparent 52%);
  mix-blend-mode: screen;
  opacity: 0.32;
}
.broadcast-left .event-card > * {
  z-index: 1;
}
.broadcast-left
  .event-card
  :is(
    .status-row,
    .eyebrow,
    #statusLabel,
    #prize,
    #timer,
    #command,
    .join-copy,
    .count-row,
    #winner,
    #winnerPrize,
    .degraded
  ) {
  color: var(--event-copy);
  text-shadow: var(--event-copy-shadow);
}
.broadcast-left .event-card .prize-label,
.broadcast-left .event-card .prize-value,
.broadcast-left .event-card .timer-wrap,
.broadcast-left .event-card .join-panel > * {
  border: 1px solid rgba(199, 210, 254, 0.18);
  background: rgba(13, 22, 40, 0.86);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07);
}
.broadcast-left .event-card .degraded {
  background: rgba(127, 29, 29, 0.86);
}
.broadcast-left .broadcast-link {
  align-items: center;
  flex-direction: row;
  justify-content: center;
  gap: 8px;
  min-height: 0;
  padding: 12px 16px;
  border: 1px solid rgba(167, 243, 208, 0.48);
  border-radius: 16px;
  color: var(--sl-text);
  background: var(--sl-header-band);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.14),
    0 10px 26px rgba(0, 0, 0, 0.32);
  font-size: var(--broadcast-link-text);
  font-weight: 850;
  text-align: center;
  white-space: nowrap;
}
.broadcast-left .broadcast-link strong {
  flex: none;
}
.broadcast-left .broadcast-link span {
  min-width: 0;
  max-width: calc(100% - 88px);
  flex: none;
}
.broadcast-banner.broadcast-link {
  gap: 2px;
  padding: clamp(9px, 1.2vw, 13px);
  font-size: clamp(15px, 1.6vw, 20px);
}
.order-kicker {
  margin: 0;
  color: var(--order-accent);
  font-family: "Cascadia Code", Consolas, monospace;
  font-size: 14px;
  font-weight: 900;
  letter-spacing: 0.13em;
}
.order-current {
  min-height: 106px;
  margin-top: 12px;
  padding: 16px;
  border: 1px solid var(--sl-line);
  border-radius: 14px;
  background: var(--sl-raised);
  box-shadow:
    inset 4px 0 0 var(--sl-accent),
    inset 0 1px 0 rgba(255, 255, 255, 0.07);
}
.order-current-status {
  color: var(--order-accent);
  font-family: "Cascadia Code", Consolas, monospace;
  font-size: 12px;
  font-weight: 900;
}
.order-current[data-state="waiting"] {
  display: grid;
  align-items: center;
}
.order-current[data-state="waiting"] .order-current-status {
  font-size: clamp(20px, 3vw, 30px);
}
.order-current strong {
  display: block;
  margin-top: 4px;
  font-size: clamp(26px, 4.5vw, 48px);
}
.order-current p {
  margin: 3px 0 0;
  color: var(--order-muted);
  font-size: clamp(17px, 3vw, 28px);
  font-weight: 750;
}
.order-waiting {
  display: grid;
  gap: 8px;
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
}
.order-waiting li {
  display: grid;
  gap: 12px;
  padding: 10px 13px;
  border: 1px solid var(--sl-line-soft);
  border-radius: 10px;
  background: rgba(36, 51, 44, 0.78);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}
.order-waiting span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.order-waiting b {
  color: var(--order-accent);
}
.overflow {
  margin: 10px 0 0;
  color: var(--order-muted);
  font-weight: 750;
}
.order-alert {
  position: fixed;
  z-index: 8;
  width: min(calc(100vw - 36px), 860px);
  padding: 22px 30px 24px;
  overflow: hidden;
  border: 4px solid var(--hit-honor);
  border-radius: 24px;
  color: var(--sl-text);
  box-shadow:
    0 0 0 3px rgba(255, 216, 77, 0.28),
    0 0 40px rgba(255, 216, 77, 0.5),
    0 24px 64px rgba(0, 0, 0, 0.5);
  font-size: clamp(26px, 3.3vw, 40px);
  font-weight: 950;
  line-height: 1.25;
  letter-spacing: -0.02em;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.72);
  animation:
    alert-in 0.34s cubic-bezier(0.2, 0.9, 0.3, 1.18),
    alert-attention 1.05s ease-in-out 0.34s 2 alternate;
}
.order-alert::before {
  width: max-content;
  padding: 4px 10px;
  border-radius: 999px;
  color: #071a12;
  background: var(--hit-honor);
  box-shadow: 0 0 22px var(--hit-honor-glow);
  content: "NEW ORDER";
  font-family: "Cascadia Code", Consolas, monospace;
  font-size: clamp(14px, 1.5vw, 18px);
  font-weight: 950;
  letter-spacing: 0.12em;
  text-shadow: none;
}
.readability-hidden {
  --readable: transparent;
}
.opacity-zero {
  backdrop-filter: none;
}
.motion-reduced * {
  animation: none !important;
  transition: none !important;
}
body:not(.motion-reduced) .broadcast-left .event-card::before {
  animation: event-aura-drift 4.6s ease-in-out infinite alternate;
}
body:not(.motion-reduced) .broadcast-left .event-card::after {
  animation: event-sparkle-pulse 2.8s ease-in-out infinite;
}
@keyframes event-aura-drift {
  from {
    opacity: 0.42;
    transform: translate3d(-3%, -2%, 0) scale(0.97);
  }
  to {
    opacity: 0.72;
    transform: translate3d(5%, 3%, 0) scale(1.04);
  }
}
@keyframes event-sparkle-pulse {
  0%,
  100% {
    opacity: 0.16;
    transform: scale(0.96);
  }
  50% {
    opacity: 0.46;
    transform: scale(1.03);
  }
}
@keyframes pulse {
  50% {
    opacity: 0.45;
    transform: scale(0.82);
  }
}
@keyframes alert-in {
  from {
    opacity: 0;
    transform: translateY(22px) scale(0.94);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}
@keyframes alert-attention {
  from {
    box-shadow:
      0 0 0 3px rgba(255, 216, 77, 0.28),
      0 0 28px rgba(255, 216, 77, 0.4),
      0 24px 64px rgba(0, 0, 0, 0.5);
  }
  to {
    box-shadow:
      0 0 0 5px rgba(255, 216, 77, 0.46),
      0 0 54px rgba(255, 216, 77, 0.72),
      0 24px 64px rgba(0, 0, 0, 0.5);
  }
}
@keyframes hit-cycle {
  to {
    transform: translateY(calc(-50% - 4px));
  }
}
@media (max-width: 520px) {
  .metrics {
    grid-template-columns: 1fr;
  }
  .link-box {
    align-items: flex-start;
    flex-direction: column;
    gap: 4px;
  }
}
@media (max-width: 720px) {
  .broadcast-banner,
  .broadcast-grid {
    width: min(92vw, 520px);
  }
  .broadcast-grid {
    grid-template-columns: 1fr;
  }
  .broadcast-item {
    width: 100%;
  }
}
@media (min-width: 721px) and (max-height: 800px) {
  .stage {
    padding-block: 18px;
  }
  .broadcast-right .hit-box {
    padding-block: 16px;
  }
}
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition: none !important;
  }
}

.prize-surface {
  display: grid;
  grid-template-columns: minmax(110px, 0.32fr) minmax(0, 1.68fr);
  align-items: stretch;
  gap: 14px;
  margin-top: 28px;
}
.prize-label,
.prize-value {
  display: grid;
  min-width: 0;
  margin: 0;
  padding: 18px 16px 22px;
  place-items: center;
  border-radius: 24px;
  background: var(--readable);
}
.prize-label {
  font-size: clamp(30px, 4.15vw, 45px);
  font-weight: 900;
}
.prize-value h1 {
  margin: 0;
  overflow-wrap: anywhere;
  font-size: clamp(34px, 5.4vw, 62px);
  line-height: 1.08;
  letter-spacing: -0.04em;
  text-align: center;
}
.timer-wrap {
  display: grid;
  min-height: calc(clamp(86px, 15vw, 166px) + 46px);
  margin: 28px 0;
  padding: 20px 24px 26px;
  place-items: center;
  border-radius: 30px;
  background: var(--readable);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 17%, transparent);
}
.timer {
  max-width: 100%;
  color: var(--accent);
  font-size: clamp(64px, 20vw, 162px);
  font-weight: 950;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.join-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(240px, 0.9fr);
  gap: 18px;
}
.join-panel > * {
  display: grid;
  min-width: 0;
  min-height: 72px;
  padding: 14px 18px;
  place-items: center;
  overflow: hidden;
  border-radius: 16px;
  color: var(--accent);
  background: var(--readable);
  font-size: clamp(36px, 4.5vw, 48px);
  font-weight: 900;
  text-align: center;
}
.count-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 26px;
  padding: 0 8px;
  font-size: clamp(22px, 3.4vw, 36px);
  font-weight: 900;
}
.broadcast-left .event-card {
  min-height: 0;
  padding: clamp(20px, 3vw, 32px);
}
.broadcast-left .status-row {
  gap: 8px;
  padding: 8px 10px;
  border: 1px solid rgba(196, 181, 253, 0.2);
  border-radius: 12px;
  background: var(--event-header-band);
  font-size: var(--broadcast-label-text);
}
.broadcast-left .live-dot {
  width: 9px;
  height: 9px;
}
.broadcast-left .prize-surface {
  grid-template-columns: minmax(72px, 0.42fr) minmax(0, 1.58fr);
  gap: 8px;
  margin-top: 14px;
}
.broadcast-left .prize-label,
.broadcast-left .prize-value {
  padding: 10px 8px 12px;
  border-radius: 14px;
}
.broadcast-left .prize-label {
  font-size: clamp(18px, 2.2vw, 24px);
}
.broadcast-left .prize-value h1 {
  overflow-wrap: break-word;
  font-size: clamp(26px, 3.1vw, 34px);
  word-break: keep-all;
}
.broadcast-left .timer-wrap {
  min-height: 86px;
  margin: 14px 0;
  padding: 12px;
  border-radius: 18px;
}
.broadcast-left .timer {
  font-size: clamp(52px, 6vw, 76px);
}
.broadcast-left .join-panel {
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
}
.broadcast-left .join-panel > * {
  min-height: 48px;
  padding: 8px 6px;
  border-radius: 12px;
  font-size: clamp(18px, 2.2vw, 24px);
}
.broadcast-left .join-copy {
  white-space: nowrap;
}
.broadcast-left #command {
  font-size: var(--broadcast-command-text);
  white-space: nowrap;
}
.broadcast-left .count-row {
  margin-top: 12px;
  padding: 0 4px;
  font-size: clamp(19px, 2.2vw, 24px);
}
.broadcast-right .hit-box {
  min-width: 0;
  padding: clamp(14px, 2vw, 20px);
}
.broadcast-right .hit-box h2 {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  max-width: 100%;
  gap: clamp(8px, 1.2vw, 14px);
  padding: 8px 12px;
  overflow: hidden;
  border: 1px solid rgba(167, 243, 208, 0.26);
  border-radius: 12px;
  background: var(--sl-header-band);
  color: var(--hit-honor);
  font-size: var(--broadcast-hit-title);
  line-height: 1.2;
  text-align: center;
  white-space: nowrap;
}
.broadcast-right .hit-box h2 span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding-block: 1px;
  line-height: 1.2;
}
.broadcast-right .hit-mascot {
  width: clamp(34px, 3.8vw, 46px);
  height: clamp(36px, 4vw, 48px);
  flex: 0 0 auto;
  object-fit: contain;
  filter: drop-shadow(0 0 8px var(--hit-honor-glow));
}
.broadcast-right .hit-mascot-mirror {
  transform: scaleX(-1);
}
.broadcast-right .hit-box li {
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
  line-height: 1.05;
  text-overflow: clip;
  white-space: normal;
}
@media (min-width: 721px) {
  .broadcast-left {
    position: relative;
    left: calc(-1 * var(--broadcast-edge-gutter));
  }
  .broadcast-right {
    position: relative;
    right: calc(-1 * var(--broadcast-edge-gutter));
  }
  .broadcast-right .order-box {
    display: grid;
    height: 210px;
    min-height: 210px;
    max-height: 210px;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr) minmax(0, 1fr);
    column-gap: 8px;
    row-gap: 4px;
    padding: 10px;
    overflow: hidden;
  }
  .broadcast-right .order-kicker {
    grid-column: 1 / -1;
    grid-row: 1;
    min-width: 0;
    overflow: hidden;
    background: var(--sl-header-band);
    text-overflow: ellipsis;
    font-size: var(--broadcast-label-text);
  }
  .broadcast-right .order-current {
    position: relative;
    min-width: 0;
    min-height: 0;
    grid-column: 1;
    grid-row: 2;
    margin-top: 0;
    padding: 6px 10px;
  }
  .broadcast-right .order-current[data-state="waiting"] {
    align-self: stretch;
  }
  .broadcast-right .order-current strong,
  .broadcast-right .order-current p {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .broadcast-right .order-current strong {
    margin-top: 0;
    font-size: var(--broadcast-current-name);
    line-height: 1.12;
  }
  .broadcast-right .order-current p {
    margin-top: 0;
    padding-bottom: 3px;
    font-size: var(--broadcast-product-text);
    line-height: 1.08;
  }
  .broadcast-right .order-current-status {
    top: 7px;
    font-size: 13px;
  }
  .broadcast-right .order-waiting {
    min-width: 0;
    grid-column: 1;
    grid-row: 3;
    grid-template-rows: repeat(3, minmax(0, 1fr));
    gap: 2px;
    margin-top: 0;
    padding-bottom: 0;
    overflow: hidden;
  }
  .broadcast-right .order-waiting li {
    min-width: 0;
    min-height: 0;
    align-items: center;
    gap: 4px;
    padding: 2px 6px;
    overflow: hidden;
  }
  .broadcast-right .order-waiting span {
    font-size: var(--broadcast-waiting-text);
    line-height: 1.08;
  }
  .broadcast-right .overflow {
    min-width: 0;
    grid-column: 1;
    grid-row: 1;
    align-self: center;
    justify-self: end;
    margin-top: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    line-height: 1;
  }
}
@media (max-width: 520px) {
  .stage {
    padding-inline: 7px;
  }
  .event-card {
    width: min(96vw, 880px);
    min-height: 520px;
    padding: clamp(16px, 4vw, 28px);
  }
  .prize-surface {
    grid-template-columns: minmax(78px, 0.36fr) minmax(0, 1.64fr);
    gap: 8px;
  }
  .prize-label,
  .prize-value {
    padding: 14px 8px 16px;
  }
  .prize-label {
    font-size: clamp(28px, 8vw, 31px);
  }
  .timer-wrap {
    min-height: 132px;
    margin: 24px 0;
  }
  .join-panel {
    grid-template-columns: minmax(0, 1fr) minmax(185px, 1.25fr);
    gap: 6px;
  }
  .join-panel > * {
    padding: 10px 4px;
    font-size: 36px;
  }
}

/* ── 주문 카드 가독성 · 진행중 세로 접힘 수정 ───────────────────────────── */
/* 기존: order-current-status 가 position:absolute + right:10px 라 폭이 좁아지면
   글자가 세로로 접혔다. 절대위치를 풀고 이름과 같은 줄의 그리드 항목으로 만든다. */
@media (min-width: 721px) {
  .broadcast-right .order-current {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: 8px;
  }
  .broadcast-right .order-current-status {
    position: static;
    right: auto;
    grid-column: 2;
    grid-row: 1;
    justify-self: end;
    white-space: nowrap;
    font-weight: 900;
  }
  .broadcast-right .order-current[data-state="active"] .order-current-status {
    color: var(--hit-honor);
  }
  .broadcast-right .order-current strong {
    grid-column: 1;
    grid-row: 1;
    padding-right: 0;
  }
  .broadcast-right .order-current p {
    grid-column: 1 / -1;
    grid-row: 2;
    padding-right: 0;
    line-height: 1.2;
  }
}

/* ── 주문 알림창: HIT 박스와 같은 형태 + 상단 중앙 배치 ─────────────────── */
.order-alert {
  display: grid;
  gap: 6px;
  justify-items: center;
  text-align: center;
}
.order-alert-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0;
  color: var(--hit-honor);
  font-size: var(--broadcast-hit-title);
  line-height: 1.2;
  white-space: nowrap;
}
.order-alert .hit-mascot {
  width: clamp(34px, 3.8vw, 46px);
  height: clamp(36px, 4vw, 48px);
  flex: 0 0 auto;
  object-fit: contain;
}
#orderAlertName {
  min-width: 0;
  max-width: 100%;
  overflow-wrap: anywhere;
  font-size: clamp(26px, 3.4vw, 40px);
  font-weight: 900;
  line-height: 1.15;
}
#orderAlertProduct {
  min-width: 0;
  max-width: 100%;
  margin: 0;
  overflow-wrap: anywhere;
  font-size: clamp(20px, 2.6vw, 30px);
  font-weight: 800;
  line-height: 1.2;
}

/* ── 소스 분리: /overlay?side=left | right ──────────────────────────────── */
/* side 파라미터가 없으면 아무 규칙도 걸리지 않아 기존과 완전히 동일하다. */
:root.only-left .broadcast-right,
:root.only-right .broadcast-left {
  display: none;
}
:root.only-left .broadcast-grid,
:root.only-right .broadcast-grid {
  grid-template-columns: minmax(0, 1fr);
}

/* ── 알림창 마스코트·배지 보정 ──────────────────────────────────────────── */
/* .order-alert 는 .broadcast-grid 밖이라 .broadcast-right 한정 규칙이 안 닿는다.
   HIT 박스와 같아 보이려면 글로우와 좌우반전을 여기서 다시 준다.
   ::before 의 "NEW ORDER" 알약은 HIT 박스에 없는 요소라 숨긴다. */
.order-alert::before {
  display: none;
}
.order-alert .hit-mascot {
  filter: drop-shadow(0 0 8px var(--hit-honor-glow));
}
.order-alert .hit-mascot-mirror {
  transform: scaleX(-1);
}

/* ── 색상 프리셋 — ALMA SUPERLIORA 테마 이식 ────────────────────────────────
   출처: alma-gui-kiro-concurrency-fix/renderer.js 의 ALMA_THEMES (199-221행).
   네 이름 emerald·violet·arctic·solar 가 오버레이 enum 및 운영자 드롭다운과 일치한다.
   emerald 는 이 파일 :root 기본값이 이미 ALMA emerald 와 동일하므로 재정의하지 않는다
   (--order #1a2420, --order-raised #24332c, --order-line #2a3a32, --order-accent #34d399,
    --order-text #e6ede8, --order-muted #8ea89a 가 ALMA panel/raised/line/accent/text/text2 와 같다).
   overlay.js 가 상태의 motionPalette 를 :root 의 data-palette 로 건다.
   --card-bg 와 --accent 는 overlay.js 가 인라인으로 넣으므로 색상 선택기가 계속 우선한다.
   피카츄가 노란색이라 --hit-honor 금색은 네 테마 모두 유지한다. */

/* VIOLET NEBULA */
:root[data-palette="violet"] {
  --sl-panel: rgba(29, 23, 48, 0.94);
  --sl-raised: rgba(42, 33, 66, 0.96);
  --sl-line: rgba(196, 181, 253, 0.34);
  --sl-line-soft: rgba(196, 181, 253, 0.16);
  --sl-accent: #a78bfa;
  --sl-bright: #ddd6fe;
  --sl-text: #f4f0ff;
  --sl-muted: #a99bc2;
  --order: #1d1730;
  --order-raised: #2a2142;
  --order-line: #382d52;
  --order-accent: #a78bfa;
  --order-text: #f4f0ff;
  --order-muted: #a99bc2;
  --sl-header-band: linear-gradient(
    90deg,
    rgba(91, 33, 182, 0.96),
    rgba(124, 58, 237, 0.72) 62%,
    rgba(124, 58, 237, 0.12)
  );
  --event-header-band: linear-gradient(
    90deg,
    rgba(91, 33, 182, 0.95),
    rgba(167, 139, 250, 0.68) 62%,
    rgba(167, 139, 250, 0.1)
  );
  --event-aura-violet: rgba(124, 58, 237, 0.46);
  --event-aura-sky: rgba(221, 214, 254, 0.3);
  --alert-bg: linear-gradient(
    135deg,
    rgba(91, 33, 182, 0.98),
    rgba(20, 16, 31, 0.98) 58%,
    rgba(42, 33, 66, 0.98)
  );
}

/* ARCTIC SIGNAL */
:root[data-palette="arctic"] {
  --sl-panel: rgba(16, 35, 41, 0.94);
  --sl-raised: rgba(23, 52, 60, 0.96);
  --sl-line: rgba(103, 232, 249, 0.34);
  --sl-line-soft: rgba(103, 232, 249, 0.16);
  --sl-accent: #22d3ee;
  --sl-bright: #cffafe;
  --sl-text: #e9fbff;
  --sl-muted: #8db6bf;
  --order: #102329;
  --order-raised: #17343c;
  --order-line: #23444c;
  --order-accent: #22d3ee;
  --order-text: #e9fbff;
  --order-muted: #8db6bf;
  --sl-header-band: linear-gradient(
    90deg,
    rgba(14, 116, 144, 0.96),
    rgba(8, 145, 178, 0.72) 62%,
    rgba(8, 145, 178, 0.12)
  );
  --event-header-band: linear-gradient(
    90deg,
    rgba(14, 116, 144, 0.95),
    rgba(34, 211, 238, 0.68) 62%,
    rgba(34, 211, 238, 0.1)
  );
  --event-aura-violet: rgba(8, 145, 178, 0.42);
  --event-aura-sky: rgba(207, 250, 254, 0.32);
  --alert-bg: linear-gradient(
    135deg,
    rgba(14, 116, 144, 0.98),
    rgba(11, 23, 27, 0.98) 58%,
    rgba(23, 52, 60, 0.98)
  );
}

/* SOLAR AMBER */
:root[data-palette="solar"] {
  --sl-panel: rgba(36, 28, 17, 0.94);
  --sl-raised: rgba(52, 40, 22, 0.96);
  --sl-line: rgba(253, 230, 138, 0.34);
  --sl-line-soft: rgba(253, 230, 138, 0.16);
  --sl-accent: #fbbf24;
  --sl-bright: #fef3c7;
  --sl-text: #fff8e7;
  --sl-muted: #c8b78f;
  --order: #241c11;
  --order-raised: #342816;
  --order-line: #4a3820;
  --order-accent: #fbbf24;
  --order-text: #fff8e7;
  --order-muted: #c8b78f;
  --sl-header-band: linear-gradient(
    90deg,
    rgba(180, 83, 9, 0.96),
    rgba(217, 119, 6, 0.72) 62%,
    rgba(217, 119, 6, 0.12)
  );
  --event-header-band: linear-gradient(
    90deg,
    rgba(180, 83, 9, 0.95),
    rgba(249, 115, 22, 0.68) 62%,
    rgba(249, 115, 22, 0.1)
  );
  --event-aura-violet: rgba(217, 119, 6, 0.42);
  --event-aura-sky: rgba(254, 243, 199, 0.3);
  --alert-bg: linear-gradient(
    135deg,
    rgba(180, 83, 9, 0.98),
    rgba(24, 19, 12, 0.98) 58%,
    rgba(52, 40, 22, 0.98)
  );
}
/* ── 주문 박스 강조 (고객 04:03 요청) ──────────────────────────────────────
   HIT 카드는 잘 보이는데 주문 박스가 눈에 안 띈다는 요청.
   ORDER LIVE 를 HIT CARD 와 같은 급의 헤더 띠로 올리고, 주문이 들어오면 반짝인다. */
.broadcast-right .order-kicker {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 12px;
  border-radius: 12px;
  background: var(--sl-header-band);
  color: var(--hit-honor);
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.6);
}
/* 진행 중인 주문이 있으면 카드가 은은하게 맥동한다 */
body:not(.motion-reduced) .broadcast-right .order-current[data-state="active"] {
  animation: order-pulse 1.8s ease-in-out infinite alternate;
}
@keyframes order-pulse {
  from {
    border-color: var(--sl-line);
    box-shadow: 0 0 0 0 var(--hit-honor-glow);
  }
  to {
    border-color: var(--hit-honor);
    box-shadow: 0 0 22px 2px var(--hit-honor-glow);
  }
}
/* 주문자 이름도 진행 중일 때 금색으로 */
.broadcast-right .order-current[data-state="active"] strong {
  color: var(--hit-honor);
  text-shadow: 0 0 14px var(--hit-honor-glow);
}

/* ── HIT 카드 번호 매기기 (고객 04:03 요청) ────────────────────────────────
   원본이 클론과 함께 순환하므로 두 목록 각각에서 1 부터 다시 센다. */
.broadcast-right .hit-box ul {
  counter-reset: hit-rank;
}
.broadcast-right .hit-box li {
  counter-increment: hit-rank;
}

/* 알림창 배경을 테마에 연동한다. 기본값은 기존 초록과 동일해 emerald 는 픽셀 동일하다. */
:root {
  --alert-bg: linear-gradient(
    135deg,
    rgba(4, 120, 87, 0.98),
    rgba(20, 30, 26, 0.98) 58%,
    rgba(36, 51, 44, 0.98)
  );
}
.order-alert {
  background: var(--alert-bg);
}

/* ── HIT 줄: 카드명 왼쪽 · 이름 오른쪽으로 벌려 박스를 채운다 (고객 04:08 요청)
   overlay.js 의 fillHitRow 가 "사보망가,일로이안님" 또는 "사보망가 ㅡ 일로이안님" 을
   두 span 으로 나눈다. 구분자가 없으면 한 덩어리로 그대로 둔다. */
.broadcast-right .hit-box li {
  display: flex;
  align-items: baseline;
  gap: clamp(8px, 1vw, 14px);
  text-align: left;
}
.broadcast-right .hit-box li::before {
  flex: 0 0 auto;
}
.broadcast-right .hit-box li .hit-card-name {
  min-width: 0;
  margin-right: auto;
  overflow-wrap: anywhere;
}
.broadcast-right .hit-box li .hit-card-owner {
  flex: 0 0 auto;
  white-space: nowrap;
}

@media (min-width: 721px) {
  .broadcast-right .order-current {
    align-items: start;
    row-gap: 4px;
  }
  .broadcast-right .order-current strong,
  .broadcast-right .order-current .order-current-status {
    align-self: baseline;
  }
}

/* ── HIT 줄 가독성 — 타이머(00:00)와 같은 급으로 (고객 04:21 요청) ──────────
   흐르는 방식과 한 줄씩 보이는 동작은 그대로 두고, 글씨만 키우고 밝게 한다.
   번호는 참고 이미지처럼 동그란 배지로 만든다. */
.broadcast-right .hit-box li {
  font-size: clamp(26px, 3.2vw, 40px);
  font-weight: 950;
  color: var(--event-copy);
  text-shadow: var(--event-copy-shadow);
}
.broadcast-right .hit-box li::before {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0 0.45em;
  border-radius: 999px;
  color: #0b1410;
  background: var(--hit-honor);
  box-shadow: 0 0 14px var(--hit-honor-glow);
  content: counter(hit-rank);
  font-weight: 950;
  text-shadow: none;
}
.broadcast-right .hit-box li .hit-card-owner {
  color: var(--sl-bright);
  font-weight: 900;
}

/* 글씨를 키웠으니 행 높이도 같이 올린다.
   안 올리면 .hit-viewport 가 2줄 높이로 고정돼 아래 줄이 잘린다. */
:root {
  --hit-row-height: clamp(46px, 4.6vw, 62px);
}
/* 번호 배지가 줄 높이를 넘어 잘리지 않게 한다. */
.broadcast-right .hit-box li::before {
  line-height: 1;
}
.broadcast-right .hit-box li {
  line-height: 1.15;
}

/* ── 1·2·3위 금·은·동 강조 (고객 04:27 요청) ───────────────────────────────
   4위부터는 은은한 기본 배지로 두어 상위 셋이 도드라지게 한다. */
.broadcast-right .hit-box li:nth-child(1)::before {
  color: #4a3200;
  background: linear-gradient(145deg, #ffe680, #f2b705);
  box-shadow: 0 0 18px rgba(255, 216, 77, 0.6);
}
.broadcast-right .hit-box li:nth-child(2)::before {
  color: #2b3138;
  background: linear-gradient(145deg, #f2f5f8, #b9c3cd);
  box-shadow: 0 0 16px rgba(220, 230, 240, 0.5);
}
.broadcast-right .hit-box li:nth-child(3)::before {
  color: #3d1f08;
  background: linear-gradient(145deg, #e5a26a, #b46b32);
  box-shadow: 0 0 16px rgba(205, 139, 82, 0.5);
}

/* 줄이 baseline 정렬이라 고정 높이 배지가 눌린다. 배지만 가운데 정렬로 뺀다. */
.broadcast-right .hit-box li::before {
  align-self: center;
  box-sizing: content-box;
}

/* ── 이벤트 카드를 나머지 세 박스와 같은 색감으로 (고객 04:24 요청) ────────
   배경은 이미 --sl-panel 로 같았고, 테두리·오라·헤더 띠만 보라색으로 덮여 있었다.
   :root[data-palette] 는 테마 블록과 특이도가 같고 뒤에 오므로 테마를 따라간다. */
:root,
:root[data-palette] {
  --event-header-band: var(--sl-header-band);
  --event-aura-violet: color-mix(in srgb, var(--sl-accent) 42%, transparent);
  --event-aura-sky: color-mix(in srgb, var(--sl-bright) 30%, transparent);
}
.broadcast-left .event-card {
  border-color: var(--sl-line);
}
body:not(.motion-reduced) .broadcast-left .event-card {
  box-shadow: var(--sl-shadow);
}

/* ── 현재 주문 헤더를 HIT CARD 와 동일한 크기·색으로, 진행중 글씨는 제거 (04:49 요청) ──
   진행중은 잘 안 보인다는 요청이라 감춘다. 대기 상태의 "주문 대기중" 은 그대로 둔다. */
@media (min-width: 721px) {
  .broadcast-right .order-kicker {
    padding: 8px 12px;
    border-radius: 12px;
  }
}

/* 헤더를 키우면 1fr 1fr 로는 진행중 카드가 눌린다.
   2행을 auto 로 바꿔 내용만큼 늘어나게 하고, 남는 높이를 대기 목록이 가져가게 한다. */
@media (min-width: 721px) {
  .broadcast-right .order-box {
    grid-template-rows: auto auto minmax(0, 1fr);
  }
}

/* 색 반전 요청 (04:54) — 주문자명은 흰색, 상품명은 노란색. 헤더는 그대로 노란색. */
@media (min-width: 721px) {
  .broadcast-right .order-current[data-state="active"] strong {
    color: var(--event-copy);
    text-shadow: var(--event-copy-shadow);
  }
  .broadcast-right .order-current p {
    text-shadow: 0 2px 4px rgba(0, 0, 0, 0.7);
  }
}

/* ── 가독성 요청 묶음 (04:53~04:55) ────────────────────────────────────────
   주문링크·참여 명령어·참여 문구를 타이머(00:00)처럼 굵고 크게,
   HIT 번호 배지는 1~3 을 더 굵게, 4 이상은 흐리지 않게. */
.broadcast-left .broadcast-link strong,
.broadcast-left .broadcast-link span {
  font-weight: 950;
  text-shadow: var(--event-copy-shadow);
}
.broadcast-left .event-card .join-panel > * {
  font-weight: 950;
}
.broadcast-left .event-card #command,
.broadcast-left .event-card .join-copy {
  font-weight: 950;
  text-shadow: var(--event-copy-shadow);
}
/* 번호 배지 — 1~3 은 더 크고 굵게 */
.broadcast-right .hit-box li:nth-child(-n + 3)::before {
  letter-spacing: -0.02em;
}
/* 4 이상도 또렷하게 — 어두운 배경 대신 밝은 배지 */
.broadcast-right .hit-box li:nth-child(n + 4)::before {
  color: #0b1410;
  background: var(--sl-bright);
  box-shadow: 0 0 12px var(--sl-line-soft);
}

/* 명령어 글씨를 키우면서 !포케팩라이브 가 잘렸다. 명령어 칸을 넓히고 줄이지 않게 한다. */
.broadcast-left .event-card #command {
  min-width: 0;
}

:root[data-mascot-asset="pikachu-video"] .hit-mascot-static {
  display: none;
}
:root[data-mascot-asset="pikachu-video"] .hit-mascot-video {
  display: block;
}
@media (prefers-reduced-motion: reduce) {
  :root[data-mascot-asset="pikachu-video"] .hit-mascot-static {
    display: block;
  }
  :root[data-mascot-asset="pikachu-video"] .hit-mascot-video {
    display: none;
  }
}

/* ── 현재 진행중 머리띠를 HIT CARD 와 글씨체·크기까지 동일하게 (05:00 요청) ──
   기존 order-kicker 는 모노스페이스에 자간 0.13em 이라 달라 보였다. */
.broadcast-right .order-kicker {
  text-align: center;
  white-space: nowrap;
  border: 1px solid rgba(167, 243, 208, 0.26);
}

/* 포케팩라이브 라벨을 진하고 크게 (05:00 요청) */
.broadcast-left .event-card #statusLabel {
  color: var(--event-copy);
  font-weight: 950;
  letter-spacing: -0.01em;
  text-shadow: var(--event-copy-shadow);
}

/* ── 폰 시청 가독성 (05:03 실방송 확인) ────────────────────────────────────
   고객이 박스를 70~80% 로 줄여 쓰기 때문에 앞선 확대가 상쇄된다.
   축소 상태에서도 읽히도록 한 단계 더 키운다. */
:root {
  --broadcast-link-text: clamp(30px, 3.2vw, 40px);
}
.broadcast-left .event-card #statusLabel {
  font-size: clamp(26px, 2.8vw, 34px);
}
/* 상품명 */
@media (min-width: 721px) {
  .broadcast-right .order-current p {
    font-size: clamp(26px, 3vw, 36px);
  }
}
/* HIT 번호 배지 — 폰에서 보이도록 확대 */
.broadcast-right .hit-box li::before {
  font-size: 0.72em;
  min-width: 2em;
  height: 1.8em;
}
.broadcast-right .hit-box li:nth-child(-n + 3)::before {
  font-size: 0.78em;
  min-width: 2.1em;
  height: 1.85em;
}

/* ── 확대로 생긴 잘림 해소 (05:05) ─────────────────────────────────────────
   글씨는 키운 채로, 잘라내던 제약을 푼다. */
/* 주문링크: 88px 예약과 nowrap 을 풀어 폭을 다 쓰게 한다 */
.broadcast-left .broadcast-link span {
  max-width: 100%;
  overflow: visible;
  text-overflow: clip;
  white-space: nowrap;
}
.broadcast-left .broadcast-link {
  flex-wrap: wrap;
  justify-content: center;
}
/* 참여 명령어: 칸을 넓히고 살짝 낮춰 한 줄에 들어가게 */
:root {
  --broadcast-command-text: clamp(22px, 2.4vw, 28px);
}
/* 상품명: 한 줄 자르기 대신 두 줄까지 허용 */
@media (min-width: 721px) {
  .broadcast-right .order-current p {
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    overflow-wrap: anywhere;
  }
  .broadcast-right .order-current strong {
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
  }
}
/* HIT 카드명: 잘리기 전에 줄바꿈 */
.broadcast-right .hit-box li .hit-card-name {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}

/* ── 1·2·3 등은 줄 전체를 금·은·동으로 (05:06 요청) ────────────────────────
   지나가는 동안 등수를 바로 알아보게 숫자·카드이름·성명을 같은 색으로 묶는다. */
.broadcast-right .hit-box li:nth-child(1) {
  --medal: #ffd84d;
  --medal-glow: rgba(255, 216, 77, 0.55);
}
.broadcast-right .hit-box li:nth-child(2) {
  --medal: #e2e8f0;
  --medal-glow: rgba(226, 232, 240, 0.45);
}
.broadcast-right .hit-box li:nth-child(3) {
  --medal: #e5a26a;
  --medal-glow: rgba(229, 162, 106, 0.45);
}
.broadcast-right .hit-box li:nth-child(-n + 3) .hit-card-name,
.broadcast-right .hit-box li:nth-child(-n + 3) .hit-card-owner {
  color: var(--medal);
  text-shadow:
    0 2px 4px rgba(0, 0, 0, 0.75),
    0 0 14px var(--medal-glow);
}
.broadcast-right .hit-box li:nth-child(-n + 3)::before {
  color: #1b1405;
  background: var(--medal);
  box-shadow: 0 0 18px var(--medal-glow);
}

/* 명령어 칸을 넓혔더니 입력 시 참여 가 잘렸다. 두 칸을 균등하게 두고 둘 다 안 자르게 한다. */
.broadcast-left .join-panel {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}
.broadcast-left .event-card .join-panel > * {
  min-width: 0;
  overflow: visible;
}
.broadcast-left .event-card #command,
.broadcast-left .event-card .join-copy {
  overflow: visible;
  text-overflow: clip;
  white-space: nowrap;
}

/* ── 폰 실측 보정 (05:10) ──────────────────────────────────────────────────
   상품명이 두 줄이 되면 ×1 이 박스 밖으로 잘린다. 박스 높이를 늘린다.
   이벤트 카드 쪽 작은 글씨들도 폰에서 읽히게 키운다. */
.broadcast-left .event-card .prize-label,
.broadcast-left .event-card .count-row {
  font-size: clamp(20px, 2.2vw, 26px);
  font-weight: 950;
}
.broadcast-left .event-card #prize {
  font-size: clamp(30px, 3.4vw, 42px);
  font-weight: 950;
}

/* .order-current 의 overflow:hidden 이 두 줄째(×1)를 잘라낸다.
   박스 상한을 380px 로 올려뒀으니 카드가 내용만큼 늘어나도 안전하다. */
@media (min-width: 721px) {
  .broadcast-right .order-current {
    overflow: visible;
  }
}

/* HIT 박스를 3줄까지 보이게 (05:12 요청). 기존은 2줄 고정이었다. */
.hit-viewport {
  height: calc(var(--hit-row-height) * 3 + var(--hit-row-gap) * 2);
}

/* ── 상품 라벨 확대 + 참여 안내를 한 박스로 (05:34 요청) ────────────────────
   기존엔 명령어와 안내가 각각 박스였다. 하나로 합쳐 글씨를 키운다. */
.broadcast-left .event-card .prize-label {
  font-size: clamp(24px, 2.6vw, 32px);
  font-weight: 950;
}
.broadcast-left .join-panel {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.35em;
  padding: 10px 14px;
  border: 1px solid rgba(199, 210, 254, 0.18);
  border-radius: 14px;
  background: rgba(13, 22, 40, 0.86);
  box-shadow: inset 0 1px 0 rgb(255 255 255 / 7%);
}
.broadcast-left .event-card .join-panel > * {
  display: inline;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  white-space: nowrap;
}
.broadcast-left .event-card #command {
  color: var(--hit-honor);
  font-size: clamp(26px, 2.9vw, 34px);
  font-weight: 950;
}
.broadcast-left .event-card .join-copy {
  font-size: clamp(22px, 2.4vw, 28px);
  font-weight: 900;
}

/* ── 마스코트 기본값을 영상으로 (05:52 사장님 지시) ────────────────────────
   기존 기본은 정지 이미지였고 data-mascot-asset="pikachu-video" 일 때만 영상이었다.
   서버가 아직 mascotAsset 을 내보내지 않으므로 기본을 뒤집어 영상이 바로 나오게 한다.
   pikachu-static 을 명시하면 이미지로 돌아가고, 모션 최소 설정에서는 이미지로 폴백한다.
   영상은 muted·loop·playsinline 이라 소리가 나지 않는다. */
.hit-mascot-video {
  display: block;
}
.hit-mascot-static {
  display: none;
}
:root[data-mascot-asset="pikachu-static"] .hit-mascot-video {
  display: none;
}
:root[data-mascot-asset="pikachu-static"] .hit-mascot-static {
  display: block;
}
body.motion-reduced .hit-mascot-video {
  display: none;
}
body.motion-reduced .hit-mascot-static {
  display: block;
}
@media (prefers-reduced-motion: reduce) {
  .hit-mascot-video {
    display: none;
  }
  .hit-mascot-static {
    display: block;
  }
}

/* ── 추첨 룰렛 (05:56 요청) ────────────────────────────────────────────────
   이름이 90ms 마다 바뀔 때 시선이 잡히도록 살짝 흔들고 빛나게 한다.
   모션 최소 설정에서는 애니메이션 없이 이름만 바뀐다. */
.draw-view > strong.is-spinning {
  color: var(--hit-honor);
  text-shadow:
    0 2px 6px rgb(0 0 0 / 70%),
    0 0 22px var(--hit-honor-glow);
}
body:not(.motion-reduced) .draw-view > strong.is-spinning {
  animation: roulette-tick 0.18s ease-in-out infinite alternate;
}
@keyframes roulette-tick {
  from {
    transform: translateY(-2px) scale(0.99);
    opacity: 0.86;
  }
  to {
    transform: translateY(2px) scale(1.02);
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  .draw-view > strong.is-spinning {
    animation: none;
    transform: none;
  }
}

/* ── 포케팩라이브 라벨 옆 작은 효과 영상 (06:10 요청) ──────────────────────
   라벨 오른쪽에 작게 붙는 장식이다. 무음·반복이고 레이아웃을 밀지 않는다.
   모션 최소 설정에서는 숨긴다. */
.status-row .brand-clip {
  flex: 0 0 auto;
  vertical-align: middle;
}
body.motion-reduced .status-row .brand-clip {
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  .status-row .brand-clip {
    display: none;
  }
}

/* ── 추가 색상 프리셋 (2026-08-29) ───────────────────────────────────────
   console 은 SuperLiora CLI 의 dark 팔레트에서 가져왔다
   (primary #4FA8FF · glow #7DD3FC · particle #B784FF · gradient #00D5FF→#B784FF).
   나머지 넷은 고객이 파는 카드에 맞춘 것으로, 색과 분위기만 쓰고
   로고·캐릭터 그림·공식 서체는 쓰지 않는다. */

:root[data-palette="console"] {
  --sl-panel: rgba(17, 24, 39, 0.94);
  --sl-raised: rgba(24, 34, 51, 0.96);
  --sl-line: rgba(79, 168, 255, 0.34);
  --sl-line-soft: rgba(79, 168, 255, 0.16);
  --sl-accent: #4fa8ff;
  --sl-bright: #7dd3fc;
  --sl-text: #f5f5f5;
  --sl-muted: #8fa3bf;
  --order: #0b0f14;
  --order-raised: #182233;
  --order-line: #24334a;
  --order-accent: #4fa8ff;
  --order-text: #f5f5f5;
  --order-muted: #8fa3bf;
  --sl-header-band: linear-gradient(
    90deg,
    rgba(0, 213, 255, 0.96),
    rgba(79, 168, 255, 0.7) 58%,
    rgba(183, 132, 255, 0.12)
  );
  --event-header-band: linear-gradient(
    90deg,
    rgba(0, 213, 255, 0.95),
    rgba(125, 211, 252, 0.66) 60%,
    rgba(183, 132, 255, 0.1)
  );
  --event-aura-violet: rgba(183, 132, 255, 0.46);
  --event-aura-sky: rgba(125, 211, 252, 0.32);
  --alert-bg: linear-gradient(
    135deg,
    rgba(0, 213, 255, 0.96),
    rgba(11, 15, 20, 0.98) 56%,
    rgba(24, 34, 51, 0.98)
  );
}

:root[data-palette="pokeball"] {
  --sl-panel: rgba(22, 16, 17, 0.94);
  --sl-raised: rgba(38, 27, 28, 0.96);
  --sl-line: rgba(255, 122, 122, 0.36);
  --sl-line-soft: rgba(255, 122, 122, 0.16);
  --sl-accent: #ff4d4d;
  --sl-bright: #ffe9e9;
  --sl-text: #fff7f6;
  --sl-muted: #cfa6a6;
  --order: #16100f;
  --order-raised: #261b1c;
  --order-line: #3a2829;
  --order-accent: #ff4d4d;
  --order-text: #fff7f6;
  --order-muted: #cfa6a6;
  --sl-header-band: linear-gradient(
    90deg,
    rgba(198, 24, 24, 0.97),
    rgba(255, 77, 77, 0.66) 56%,
    rgba(255, 233, 233, 0.12)
  );
  --event-header-band: linear-gradient(
    90deg,
    rgba(198, 24, 24, 0.96),
    rgba(255, 122, 122, 0.62) 58%,
    rgba(255, 233, 233, 0.1)
  );
  --event-aura-violet: rgba(198, 24, 24, 0.44);
  --event-aura-sky: rgba(255, 233, 233, 0.3);
  --alert-bg: linear-gradient(
    135deg,
    rgba(198, 24, 24, 0.98),
    rgba(22, 16, 15, 0.98) 56%,
    rgba(38, 27, 28, 0.98)
  );
}

:root[data-palette="gymbadge"] {
  --sl-panel: rgba(13, 20, 38, 0.94);
  --sl-raised: rgba(22, 32, 56, 0.96);
  --sl-line: rgba(240, 200, 90, 0.36);
  --sl-line-soft: rgba(240, 200, 90, 0.16);
  --sl-accent: #f0c85a;
  --sl-bright: #ffe9a8;
  --sl-text: #fdf6e3;
  --sl-muted: #b3a67d;
  --order: #0d1426;
  --order-raised: #162038;
  --order-line: #23304f;
  --order-accent: #f0c85a;
  --order-text: #fdf6e3;
  --order-muted: #b3a67d;
  --sl-header-band: linear-gradient(
    90deg,
    rgba(146, 102, 10, 0.97),
    rgba(240, 200, 90, 0.66) 58%,
    rgba(255, 233, 168, 0.12)
  );
  --event-header-band: linear-gradient(
    90deg,
    rgba(146, 102, 10, 0.96),
    rgba(240, 200, 90, 0.62) 60%,
    rgba(255, 233, 168, 0.1)
  );
  --event-aura-violet: rgba(146, 102, 10, 0.44);
  --event-aura-sky: rgba(255, 233, 168, 0.3);
  --alert-bg: linear-gradient(
    135deg,
    rgba(146, 102, 10, 0.98),
    rgba(13, 20, 38, 0.98) 56%,
    rgba(22, 32, 56, 0.98)
  );
}

:root[data-palette="strawhat"] {
  --sl-panel: rgba(12, 32, 54, 0.94);
  --sl-raised: rgba(19, 48, 78, 0.96);
  --sl-line: rgba(247, 201, 72, 0.36);
  --sl-line-soft: rgba(247, 201, 72, 0.16);
  --sl-accent: #f7c948;
  --sl-bright: #ffe9a3;
  --sl-text: #fffaf0;
  --sl-muted: #a3bcd4;
  --order: #0c2036;
  --order-raised: #13304e;
  --order-line: #1d4368;
  --order-accent: #f7c948;
  --order-text: #fffaf0;
  --order-muted: #a3bcd4;
  --sl-header-band: linear-gradient(
    90deg,
    rgba(209, 56, 44, 0.97),
    rgba(247, 201, 72, 0.68) 56%,
    rgba(255, 250, 240, 0.12)
  );
  --event-header-band: linear-gradient(
    90deg,
    rgba(209, 56, 44, 0.96),
    rgba(247, 201, 72, 0.64) 58%,
    rgba(255, 233, 163, 0.1)
  );
  --event-aura-violet: rgba(209, 56, 44, 0.42);
  --event-aura-sky: rgba(247, 201, 72, 0.32);
  --alert-bg: linear-gradient(
    135deg,
    rgba(209, 56, 44, 0.98),
    rgba(12, 32, 54, 0.98) 56%,
    rgba(19, 48, 78, 0.98)
  );
}

:root[data-palette="jollyroger"] {
  --sl-panel: rgba(14, 14, 16, 0.95);
  --sl-raised: rgba(28, 28, 32, 0.96);
  --sl-line: rgba(238, 235, 225, 0.32);
  --sl-line-soft: rgba(238, 235, 225, 0.14);
  --sl-accent: #eeebe1;
  --sl-bright: #ffffff;
  --sl-text: #f6f4ee;
  --sl-muted: #9d9a92;
  --order: #0e0e10;
  --order-raised: #1c1c20;
  --order-line: #2c2c32;
  --order-accent: #d4342a;
  --order-text: #f6f4ee;
  --order-muted: #9d9a92;
  --sl-header-band: linear-gradient(
    90deg,
    rgba(212, 52, 42, 0.96),
    rgba(238, 235, 225, 0.6) 56%,
    rgba(238, 235, 225, 0.1)
  );
  --event-header-band: linear-gradient(
    90deg,
    rgba(14, 14, 16, 0.97),
    rgba(238, 235, 225, 0.55) 58%,
    rgba(238, 235, 225, 0.1)
  );
  --event-aura-violet: rgba(212, 52, 42, 0.4);
  --event-aura-sky: rgba(238, 235, 225, 0.3);
  --alert-bg: linear-gradient(
    135deg,
    rgba(212, 52, 42, 0.98),
    rgba(14, 14, 16, 0.98) 56%,
    rgba(28, 28, 32, 0.98)
  );
}

/* ── 주문 박스 라벨 키우고 굵게 (고객 2026-08-29 14:26·14:27 요청) ──────────
   "현재 진행중 / 주문 대기중 글씨를 좀 더 키워주세요", "주문대기중 글씨 진하게".
   두 글씨는 한 쌍으로 읽히므로 같은 크기 규칙을 쓰고, 상태 글씨만 더 굵게 둔다.
   앞선 규칙이 여러 겹 쌓여 있어 마지막에 명시적으로 덮는다. */

.broadcast-right .order-current[data-state="waiting"] .order-current-status {
  font-size: clamp(30px, 3.6vw, 44px);
  font-weight: 900;
  letter-spacing: -0.01em;
}

/* ── HIT 박스가 대기 목록 때문에 찌그러지지 않게 (고객 2026-08-29 14:39 요청) ──
   "대기목록 생기면 힛카드 박스가 저절로 줄어들어요".
   .hit-viewport 는 높이만 고정돼 있고 최소 높이가 없었다. 내용을 잘라내는 상자라
   최소 내용 크기가 0 으로 계산돼, 주문 박스가 대기 목록만큼 커지면 눌려 찌그러졌다.
   높이와 같은 값을 최소 높이로 못박고 수축도 막는다. */
.broadcast-right .hit-box {
  align-self: start;
}

/* ── 주문 글씨 대비 개선 (고객 2026-08-29 14:45 요청) ──────────────────────
   "대기자 이름이 안 보인다", "상품 이름을 진하게 하얀색으로".
   대기 줄은 overlay.js 에서 이름·상품을 각각의 span 으로 나눠 그린다.
   이름은 금색, 상품은 흰색 굵게, 수량은 기존 강조색을 유지한다. */
.order-waiting li {
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: baseline;
}
.order-waiting-name {
  flex: none;
  color: var(--hit-honor);
  font-weight: 900;
  white-space: nowrap;
}
.order-waiting-product {
  min-width: 0;
  overflow: hidden;
  color: #ffffff;
  font-weight: 800;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 현재 진행중의 상품 이름도 같은 급으로 (주문 완료 알림 박스와 맞춘다) */
.broadcast-right .order-current p {
  color: #ffffff;
  font-weight: 800;
}

/* ── HIT 목록은 최소 한 줄까지 (고객 2026-08-29 14:45 요청) ────────────────
   "대기자목록이 늘어나서 박스가 늘어나도 힛 카드 목록은 최소 1줄까지는 보이게".
   앞서 3줄을 최소로 못박았는데, 그러면 자리가 모자랄 때 화면 밖으로 밀려난다.
   원하는 3줄은 그대로 두되 최소는 한 줄로 낮춰, 줄어들더라도 사라지지는 않게 한다. */
.hit-viewport {
  min-height: var(--hit-row-height);
  flex-shrink: 1;
}

/* ── 주문 완료 알림 최종 위치 (고객 캡처의 빨간 동그라미, 2026-08-29 15:16) ──
   앞선 시도는 화면 왼쪽 끝에 붙어 모서리가 잘렸고 높이도 높았다.
   가장자리에서 띄우고 아래로 내려 동그라미 안쪽에 오게 한다.
   auto/0 을 섞으면 앞 블록과 충돌하므로 네 방향을 모두 여기서 확정한다. */
.order-alert {
  top: auto;
  right: auto;
  width: fit-content;
  margin-inline: 0;
}

/* ── "현재 진행중" 과 주문자 이름을 HIT CARD 제목과 동일하게 (고객 15:24 요청) ──
   "hit card 글씨랑 크기만 똑같게" — HIT CARD 제목은 h2 기본 굵기(700)에
   var(--broadcast-hit-title) 크기, 자간 기본, 글꼴 상속이다. 앞서 내가 34~44px 로
   키워둔 것이 오히려 더 컸다. 색은 요청에 없으므로 각자 그대로 둔다. */
.broadcast-right .order-kicker,
.broadcast-right .order-current strong {
  font-family: inherit;
  font-size: var(--broadcast-hit-title);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: normal;
}

/* ── 글씨 굵기·크기 정리 (고객 2026-08-29 15:27 요청) ──────────────────────
   "hitcard 글씨체는 좀 얇은 느낌이라" → HIT CARD 제목을 900 으로 두껍게 한다.
   크기는 같은 종류끼리 맞춘다 — "현재 진행중" 은 HIT CARD **제목**과,
   대기 목록의 주문자명은 HIT CARD **줄**과 같은 크기다. 머리글을 줄 크기에,
   줄을 머리글 크기에 맞추면 대기 목록이 커져 HIT 박스를 다시 밀어낸다. */
.broadcast-right .hit-box h2 {
  font-weight: 900;
}
.broadcast-right .order-kicker {
  font-size: var(--broadcast-hit-title);
  font-weight: 900;
}

/* ── 대기 목록 가독성 (고객 2026-08-29 15:28·15:30 요청) ────────────────────
   "폰으로 보면 가까이 봐야 보여서" — HIT 줄 크기보다 한 단계 키운다.
   수량 ×10 은 초록이라 배경에 묻혔다. 흰색 굵게로 바꾼다.
   박스가 커지면 HIT 뷰포트가 최소 한 줄까지만 줄어든다(위의 14:45 블록). */
.broadcast-right .order-waiting-name,
.broadcast-right .order-waiting-product {
  font-size: clamp(22px, 2.4vw, 30px);
}
.broadcast-right .order-waiting-name {
  font-weight: 900;
}
.broadcast-right .order-waiting-product {
  font-weight: 800;
}
.broadcast-right .order-waiting b {
  color: #ffffff;
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 900;
}

/* ── 추첨 속도 (고객 2026-08-29 15:33 요청) ────────────────────────────────
   이름은 45ms 마다 바뀌는데 깜빡임 효과가 0.18초 왕복(0.36초)이라 그쪽이 느리게 보였다.
   효과 주기를 이름 교체와 같은 급으로 맞춘다. */
body:not(.motion-reduced) .draw-view > strong.is-spinning {
  animation-duration: 0.09s;
}

/* ── 대기자가 늘어도 HIT 박스는 반드시 보이게 (고객 2026-08-29 15:37 요청) ──
   "대기자가 늘어나면서 힛카드 박스가 아예 안보여요".
   .hit-viewport 에 최소 높이를 준 것으로는 못 막는다 — 뷰포트가 아니라 **박스 자체가**
   아래로 밀려 화면 밖으로 나가기 때문이다. 주문 박스가 커지는 폭을 직접 묶는다.
   대기 줄은 넘치면 잘리고, 넘친 건수는 이미 "외 N건 대기 중" 으로 따로 표시된다. */
.broadcast-right .order-waiting {
  overflow: hidden;
}
.broadcast-right .order-box {
  overflow: hidden;
}
.broadcast-right .hit-box {
  min-height: 22vh;
}

/* ── 팬텀 클립: 투명 배경 · 조금 왼쪽 · 조금 크게 (고객 2026-08-29 요청) ────
   흰 배경은 CSS 로 못 지운다. colorkey 로 배경만 빼서 투명 APNG 로 다시 만들었고
   (팬텀의 흰 이빨은 남도록 임계값을 좁게 잡음), 요소도 video → img 로 바꿨다.
   "살짝만" 왼쪽이라 여백만 줄인다. 크기는 한 단계 키운다. */
.status-row .brand-clip {
  width: clamp(38px, 4vw, 54px);
  height: clamp(38px, 4vw, 54px);
  margin-left: 0.1em;
  border-radius: 0;
  object-fit: contain;
}

/* ── 대기 목록이 통째로 잘리던 문제 (고객 2026-08-29 17:2x 보고) ────────────
   HIT 박스를 지키려고 주문 박스에 max-height + overflow:hidden 을 걸었는데,
   현재 주문이 높이를 다 쓰면 그 아래 대기 목록이 0px 로 잘려 아예 안 보였다.
   대기 목록에 최소 높이를 줘서 한 줄은 반드시 남기고, 주문 박스 상한을 조금 올린다.
   HIT 박스 최소 높이(22vh)는 그대로 두어 밀려나지 않게 한다. */
.broadcast-right .order-waiting {
  min-height: calc(var(--broadcast-hit-row) * 2.4);
  max-height: 26vh;
}

/* ── 주문 완료 알림을 고객이 표시한 동그라미 자리로 (2026-08-29 17:2x 캡처) ──
   캡처에서 동그라미는 화면 세로 63~86% 구간, 가로 3~45% 구간에 있다.
   아래에서 16% 띄우고 왼쪽에서 5% 들어가면 그 안에 들어온다.
   앞선 값(bottom 6%)은 동그라미보다 더 아래였다. */
.order-alert {
  bottom: 16%;
  left: 5%;
  max-width: min(44vw, 600px);
}

/* ── 주문 완료 알림 전용 소스 / 알림 제외 소스 (고객 2026-08-29 요청) ────────
   장면마다 오버레이가 들어가는 틀이 달라 좌표를 코드로 맞추는 것이 반복 실패했다.
   고객이 OBS 에서 직접 끌어다 놓을 수 있도록 알림을 별도 브라우저 소스로 분리한다.

     ?only=alert  알림만 — 자기 캔버스 왼쪽 위에 붙여 소스 크기 = 알림 크기가 되게 한다
     ?hide=alert  기존 오버레이에서 알림만 제외

   색은 이미지에 구워 넣었으므로 filter 는 끈다. 필터를 겹치면 과채도가 된다. */
:root.only-alert .broadcast-grid {
  display: none;
}
:root.only-alert .order-alert {
  position: static;
  display: grid;
  max-width: none;
  margin: 0;
}
:root.only-alert body {
  padding: 0;
}
:root.hide-alert .order-alert {
  display: none;
}

.status-row .brand-clip {
  filter: none;
}

/* ── 주문자 이름 위의 작은 "진행중" 배지 제거 (고객 2026-08-29 요청) ────────
   같은 요소가 대기 상태에서는 "주문 대기중" 을 보여주므로 active 일 때만 숨긴다.
   앞서 미디어쿼리 안에 같은 규칙이 있었으나 조건이 안 맞아 적용되지 않았다.
   배지가 빠진 자리는 이름이 넓게 쓴다. */
.broadcast-right .order-current[data-state="active"] .order-current-status {
  display: none;
}
.broadcast-right .order-current[data-state="active"] strong {
  grid-column: 1 / -1;
}

/* ── 분할 소스에서는 알림을 빼고 전용 소스에만 띄운다 (고객 2026-08-29 요청) ──
   고객은 side=left / side=right 두 개의 브라우저 소스를 쓴다. 알림이 왼쪽 소스 안에
   들어 있으면 위치를 코드로 맞춰야 하고, 장면 틀이 달라 계속 어긋났다.
   이제 알림은 ?only=alert 전용 소스에서만 나오고 OBS 에서 직접 배치한다. */
:root.only-left .order-alert,
:root.only-right .order-alert {
  display: none;
}

/* ── 실제로 효과가 있는 한 곳만 고친다 (2026-08-29 CSS 감사 결과) ────────────
   오늘 이 파일 끝에 열댓 번 덧붙였는데, 아래 세 가지 때문에 대부분이 무효였다.

   1) .broadcast-right .order-box 는 907행에서 height/min-height/max-height 를
      모두 210px 로 못박고 있다. 이후 max-height 를 여섯 번 올렸지만 height 가
      이기므로 박스는 계속 210px 였고, 대기 목록이 들어갈 자리가 9.6px 밖에 없어
      화면에서 사라졌다. min/height 를 함께 올려야 실제로 커진다.
      세로 예산: 위아래 여백 151 + 박스 300 + 간격 20 + HIT 274 = 745px (69vh) — 넘치지 않는다.

   2) 990행 `.broadcast-right .order-waiting span` 이 특이도(0,2,1)로
      `.order-waiting-name`(0,2,0) 을 이겨서, 대기자 이름·상품 글씨 확대가
      적용된 적이 없다. 같은 특이도로 맞춰야 뒤에 쓴 값이 산다.

   3) 주문자 이름만 굵기 700 이라 옆의 헤더(900)보다 얇았다. */
.broadcast-right .order-box {
  height: 300px;
  min-height: 300px;
  max-height: 300px;
}
.broadcast-right .order-waiting span.order-waiting-name {
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 900;
  line-height: 1.15;
}
.broadcast-right .order-waiting span.order-waiting-product {
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 800;
  line-height: 1.15;
}
.broadcast-right .order-current strong {
  font-weight: 900;
}

/* ── 주문 완료 알림은 전용 소스에서만 나온다 (2026-08-29 최종) ──────────────
   알림 위치를 코드로 맞추려다 여러 번 실패했다. 장면 틀이 장면마다 다르고,
   고객이 쓰는 오버레이 주소도 여러 가지라 "어떤 주소에서 숨길지" 를 맞추는 방식은
   계속 어긋났다. 그래서 방향을 뒤집는다 — 기본은 숨김이고, ?only=alert 에서만 보인다.
   고객은 알림 전용 브라우저 소스를 하나 만들어 원하는 자리에 두면 되고,
   기존 오버레이 주소는 무엇이든 그대로 써도 중복되지 않는다. */
.order-alert {
  display: none;
}
:root.only-alert .order-alert {
  display: grid;
}

/* ── 주문 박스가 대기자 수에 따라 다시 늘어나게 (고객 2026-08-29 보고) ──────
   "원래 알아서 늘어났는데 갑자기 크기가 고정됐네요" — 내 잘못이다.
   대기 목록이 안 보이던 문제를 고치려고 height 를 300px 로 못박았는데,
   그게 내용에 따라 늘어나던 동작까지 막았다.

   이제 내용만큼 늘어나되 상한만 둔다. 상한 근거(1920x1080 계산):
   위아래 여백 151 + 주문박스 X + 간격 20 + HIT 274 ≤ 1080  →  X ≤ 634px ≈ 58vh.
   여유를 두어 56vh 로 잡으면 HIT 박스가 절대 밀려나지 않는다.
   대기 줄도 3등분 고정을 풀어 글씨 크기만큼 자연스럽게 잡히게 한다
   (3등분 때문에 줄 높이가 16px 이라 30px 글씨가 잘렸다). */
.broadcast-right .order-box {
  height: auto;
  min-height: 210px;
  max-height: 56vh;
}
.broadcast-right .order-waiting {
  grid-template-rows: none;
  grid-auto-rows: auto;
  min-height: 0;
  max-height: none;
}

/* 알림 단독 소스(?only=alert)에서 박스 가로폭이 내용 길이를 따라갔다. 짧은 주문 337px →
   긴 주문 1143px (1920x1080 실측), 그래서 알림이 뜰 때마다 왼쪽 가장자리가 403px 씩
   움직였고 고객이 "가로로 너무 길다"고 했다 (2026-08-29). 이제 소스 캔버스를 그대로
   채우고, 긴 상품명은 늘어나는 대신 줄바꿈으로 흘린다 — 폭은 프리즘 소스 크기로만 정해진다. */
:root.only-alert .order-alert {
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  margin-inline: 0;
}

:root.only-alert .order-alert strong,
:root.only-alert .order-alert p,
:root.only-alert .order-alert span {
  min-width: 0;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* 배송 안내 문구(#linkGuidance)를 잠깐 보이게 했다가 되돌렸다 — 고객이 원하지 않았다
   (2026-08-29: "박스 밑에 주문되면 실시간 개봉후에 배송됩니다 이게 갑자기 뜹니다 없애").
   원래대로 숨긴다. 운영자 페이지의 "링크 안내" 입력칸은 값이 저장되기는 하지만 화면에는
   나오지 않는다는 뜻이다. 다시 보이게 하려면 아래 display 를 block 으로 되돌리면 된다. */
.link-box small {
  display: none;
}

/* 알림 박스 가로폭에 600px 상한을 넣었다가 뺐다 — 고객 요청은 "이벤트 박스랑 같은
   크기" 였다 (2026-08-29). 이벤트 박스(.broadcast-item)는 자기 소스를 그대로 채우므로,
   알림도 같은 규칙(위 블록의 width:100%)만 따르게 둔다. 프리즘에서 알림 소스를 이벤트
   소스와 같은 크기로 잡으면 두 박스가 정확히 같은 크기가 된다. 내용 길이에 따라 폭이
   변하지 않는 것은 위 블록이 이미 보장한다. */

/* max-height: 56vh 가 세로가 짧은 소스에서 대기 목록을 통째로 잘라냈다. 1920x1080 에서는
   3줄이 다 보이는데 고객 소스(더 낮은 캔버스)에서는 1줄만 보였다 (2026-08-29 실측:
   280x471 에서 3줄 전부 박스 바닥 밖으로 밀려 overflow:hidden 에 잘림).
   원래대로 내용에 맞춰 늘어나게 둔다 — 줄 수는 overlay.js 의 WAITING_VISIBLE_LIMIT(10)
   가 이미 막고 있어서 무한정 자라지 않는다. */
.broadcast-right .order-box {
  max-height: none;
}

/* ── 소스 분리: /overlay?only=hit ──────────────────────────────────────────
   HIT CARD 전용 소스. 오른쪽 소스에서 주문 박스와 높이를 다투던 문제를 구조적으로
   없앤다 (2026-08-29). only=hit 가 없으면 아래 규칙은 하나도 걸리지 않는다. */
:root.only-hit .broadcast-left,
:root.only-hit .order-box,
:root.only-hit .order-alert {
  display: none;
}

:root.only-hit .broadcast-grid {
  grid-template-columns: minmax(0, 1fr);
}

:root.only-hit .broadcast-right {
  grid-template-rows: minmax(0, 1fr);
}

/* 전용 소스로 빼려다 되돌렸다 — 소스를 나누면 두 박스가 서로 크기를 주고받지 못하고,
   방송 PC 발열도 늘어난다는 고객 지적이 있었다 (2026-08-29). 한 소스에 그대로 둔다. */

/* 주문자 순번. 진행중인 주문이 1번이고 대기자가 2번부터 이어진다 — 고객 확인
   (2026-08-29): "현재진행중이랑 대기중 총 4명이 보일 텐데".

   동그라미 번호(①②③)로 만들었다가 "1. 2. 3. 으로 할게요! 일단은!" 이라 하셔서
   숫자+마침표로 되돌렸다. 동그라미로 다시 바꾸려면 @counter-style 을 쓰면 된다. */
.order-waiting {
  counter-reset: waitingrow 1;
}

.order-waiting li::before {
  content: counter(waitingrow) ".";
  counter-increment: waitingrow;
  margin-right: 8px;
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  opacity: 0.9;
}

#orderCurrentName::before {
  content: "1. ";
  font-variant-numeric: tabular-nums;
  font-weight: 800;
  opacity: 0.9;
}

/* HIT 목록 높이를 줄 높이의 배수(2줄)로 못 박았다가 되돌렸다 — 고객의 원래 화면은
   3줄이 보이는 것이었고, 맨 아래 줄이 조금 걸치는 것이 정상이었다 (2026-08-29 원본
   화면 캡처로 확인). 잘린 것처럼 보인 것을 결함으로 잘못 판단했다. */

/* 주문완료 알림을 이벤트 박스와 같은 크기로 맞춘다 — 고객 요청 (2026-08-29).
   이벤트 박스(#eventCard)와 링크 박스는 둘 다 뷰포트의 89.24% 폭에 좌우 여백이 같은
   가운데 정렬이다(1080 폭에서 x=53.5, 폭 963.8 실측). 알림에도 같은 비율을 준다.
   비율로 두면 알림 소스 크기가 이벤트 소스와 달라도 같은 비례로 보인다.
   내용 길이에 따라 폭이 변하지 않는 것은 위쪽 only-alert 블록이 이미 보장한다. */
:root.only-alert .order-alert {
  width: 89.24%;
  max-width: 89.24%;
  margin-inline: auto;
}

/* 대기 목록을 1줄 창으로 고정하고, 2명 이상이면 HIT CARD 와 똑같이 위로 순환시킨다 —
   고객 요청 (2026-08-29): "대기자칸 1줄 고정하고 2명 이상되면 힛카드처럼 위로",
   "밑에 힛카드랑 동일한 속도", "지그재그 느낌이 안 들게".

   @keyframes hit-cycle 을 그대로 재사용한다. 그 키프레임은 목록 두 벌을 이어붙인
   트랙을 -50% - 4px 만큼 옮기는 것이라, 트랙 간격도 HIT 과 같은 8px 이어야 한 바퀴가
   정확히 맞아떨어진다. 한 줄당 4초도 HIT_ROW_DURATION_MS 와 같은 값이다.

   이렇게 하면 대기자가 몇 명이든 주문 박스 높이가 변하지 않으므로, 아래 HIT CARD 를
   밀어내는 일 자체가 사라진다. */
.order-waiting-viewport {
  overflow: hidden;
  height: var(--waiting-row-height, 46px);
  mask-image: linear-gradient(to bottom, transparent, #000 12%, #000 88%, transparent);
}

.order-waiting-track {
  display: flex;
  flex-direction: column;
  gap: var(--hit-row-gap, 8px);
  transform: translateY(0);
  will-change: transform;
}

.order-waiting-track.is-cycling {
  animation: hit-cycle var(--waiting-cycle-duration) linear infinite;
}

.order-waiting-track .order-waiting {
  display: grid;
  grid-auto-rows: var(--waiting-row-height, 46px);
  gap: var(--hit-row-gap, 8px);
  max-height: none;
  min-height: 0;
}

.order-waiting-track .order-waiting li {
  height: var(--waiting-row-height, 46px);
  min-height: var(--waiting-row-height, 46px);
}

/* 추첨 화면 강조색 — 고객 요청 (2026-08-29 20:18): "추첨중 노란색 글씨로,
   밑에 당첨 상품도 노란색". 추첨/당첨 화면(#drawLabel 라벨, #winnerPrize 상품명)에만
   적용하고 다른 eyebrow 라벨은 건드리지 않는다. */
#drawLabel {
  color: #ffd54a;
}

#winnerPrize {
  color: #ffd54a;
}

/* 현재 진행중 제목 양옆 마스코트 — 고객 요청 (2026-08-29 20:14, 20:22): "현재 진행중
   사이드에 피카츄처럼 파이리/꼬북이". HIT CARD 제목의 피카츄와 같은 배치다.
   원본이 배경 있는 장면 GIF 라 얼굴 중심으로 잘라 동그란 배지로 쓴다.
   파이리 이미지가 오면 왼쪽을 파이리로 바꾼다. */
.order-kicker-mascot {
  display: inline-block;
  width: clamp(30px, 3vw, 42px);
  height: clamp(30px, 3vw, 42px);
  margin-right: 10px;
  vertical-align: middle;
  object-fit: cover;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgb(255 255 255 / 28%);
}

.order-kicker-mascot-right {
  margin-right: 0;
  margin-left: 10px;
}

/* 파이리는 흰 배경을 투명하게 뺀 전신 스프라이트다. 꼬북이 배지용 원형 자르기·테두리를
   그대로 쓰면 몸이 잘리므로 스프라이트용으로 되돌린다. (왼쪽=파이리, 오른쪽=꼬북이 —
   고객 요청 2026-08-29 20:14·20:22) */
.order-kicker-mascot-sprite {
  object-fit: contain;
  border-radius: 0;
  box-shadow: none;
}

/* 추첨 화면 꼬북이 — 고객 정정 (2026-08-29): "꼬북이는 이벤트 추첨할 때요".
   진행중 박스 양옆은 파이리로 통일하고, 꼬북이는 추첨 라벨(추첨중/WINNER) 양옆에 둔다.
   #drawLabel 은 overlay.js 의 setText 가 textContent 를 갈아끼우므로 이미지를 그 안에
   넣으면 지워진다 — 형제로 두고 줄 배치만 맞춘다. */
.draw-label-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.draw-mascot {
  width: clamp(34px, 3.4vw, 48px);
  height: clamp(34px, 3.4vw, 48px);
  object-fit: cover;
  border-radius: 50%;
  box-shadow: 0 0 0 2px rgb(255 255 255 / 28%);
}

/* 추첨 화면 최종 다듬기 — 고객 정정 (2026-08-29 20:19~20:24):
   "노란색 말고 하늘색", "추첨중이랑 상품이름 조금 더 키워주십시오",
   "꼬북이는 움직이는 걸로, 피카츄처럼 동그란 배경 없애고".
   꼬북이는 배경이 원래부터 투명한 애니메이션 스프라이트로 교체했으므로
   배지용 원형·테두리를 벗긴다. */
.draw-mascot-sprite {
  width: clamp(44px, 4.4vw, 64px);
  height: clamp(44px, 4.4vw, 64px);
  object-fit: contain;
  border-radius: 0;
  box-shadow: none;
  image-rendering: pixelated;
}

#drawLabel {
  color: #7ed6ff;
  font-size: clamp(30px, 3.2vw, 46px);
}

#winnerPrize {
  color: #7ed6ff;
  font-size: clamp(26px, 2.8vw, 40px);
}

/* 공격 리뷰 (2026-08-29) 정정 두 가지.

   1순위 — 대기 줄의 수량(×N)이 항상 잘렸다. 순번 ::before 가 실제 그리드 아이템이라
   3칸짜리 grid-template-columns 에서 수량이 둘째 줄로 밀렸고, 마퀴가 행 높이를 46px 로
   고정하면서 그 둘째 줄이 통째로 잘려 나갔다 (실측: scrollHeight 63px vs clientHeight
   44px, 수량 세로 32% 소실). 순번 칸을 하나 추가한다.

   3순위 — 힛 카드용 12% 페이드 마스크를 1줄 뷰포트에 그대로 복사해 와서, 유일한 줄의
   위아래 24% 가 상시 흐려졌다. 픽셀 고정으로 줄인다. */
.order-waiting-track .order-waiting li {
  grid-template-columns: auto auto minmax(0, 1fr) auto;
}

.order-waiting-viewport {
  mask-image: linear-gradient(to bottom, transparent, #000 4px, #000 calc(100% - 4px), transparent);
}

/* 힛 카드 끌어올리기 — 고객 요청 (2026-08-29 20:43): "힛카드를 좀 올리면 좋겠는데
   공간이 비어있어서". 대기 목록을 1줄로 고정하자 주문 박스 내용이 min-height(210px)보다
   작아져 빈 공간이 생겼고, 운영자 배율 0.9 로 박스가 칸 가운데 떠서 여백이 더 보였다.
   1080x900 실측: 힛 카드 꼭대기 305 → 272 (33px 상승), 바닥 여유 충분. */
.broadcast-right {
  grid-template-rows: auto auto;
  align-content: start;
  row-gap: 14px;
}

.broadcast-right .order-box {
  height: auto;
  min-height: 0;
}

.broadcast-right .hit-box {
  margin-top: -10px;
}

/* 2026-08-29 20:56~20:58 고객 요청 세 가지.

   1) "2. 3. 도 노란색 글씨로, 크기랑 글씨색 잘 보이게" — 순번을 노랗고 크게.

   2) "움직이는데 힛카드가 밑으로 내려간 것 같아요" — 캡처 분석 결과, 진행중 상품명이
   길어 2줄로 감기면서 주문 박스가 커졌고 힛 카드가 밀려 소스 바닥에서 잘렸다.
   진행중 상품명을 대기 줄과 같은 1줄 말줄임으로 고정해 박스 높이를 일정하게 만든다.

   3) "주문완료 박스가 아직 크네요" — 이벤트 박스 비율(89.24%)로 맞췄는데도 크다고
   하셔서 66% 로 줄인다. 더 조정 필요하면 이 숫자만 바꾸면 된다. */
.order-waiting li::before {
  font-size: 1.15em;
  color: #ffd54a;
}

#orderCurrentName::before {
  color: #ffd54a;
}

/* (삭제 01:40) nowrap+ellipsis 가 1520행대의 두 줄 표시 규칙(white-space:normal,
   아래 공간으로 줄바꿈 — 고객이 "원래 해주셨던" 그 동작)을 덮어 물품명이 한 줄로
   잘렸다. 어제 저녁 베이스라인부터 있던 자충돌 — 09 blame 판정, d9 적용. */

:root.only-alert .order-alert {
  width: 66%;
  max-width: 66%;
}

.order-waiting-viewport {
  height: auto;
  mask-image: none;
}

.order-waiting-track {
  animation: none;
}

/* 고객 (2026-08-29 21:08): "대기자 이름 글씨가 흐릿해요 위에는 빛나고 잘보이는데".
   진행중 이름과 같은 흰색·같은 광 처리로 맞춘다. */
.broadcast-right .order-waiting li {
  opacity: 1;
}

.broadcast-right .order-waiting span.order-waiting-name {
  color: #fff;
  text-shadow: 0 0 14px rgb(140 255 210 / 45%);
}

/* 대기 목록 순환은 폐기됐다. is-cycling 규칙(특이도 0,2,0)이 animation:none(0,1,0)을
   이기므로, 누가 상수를 다시 갈라도 순환이 조용히 살아나지 못하게 못을 박는다
   (공격 리뷰 2026-08-29 지적). */
.order-waiting-track,
.order-waiting-track.is-cycling {
  animation: none !important;
}

/* 고객 요청 (2026-08-29 22:52): "주문자 대기자도 이름 노란색으로, 2.3.4. 숫자가 너무
   흐릿해서 진하게 — 눈에 안 띄어서". 이름은 흰색에서 순번과 같은 노란색으로, 순번은
   반투명을 없애고 더 굵고 크게. */
.broadcast-right .order-waiting span.order-waiting-name {
  color: #ffd54a;
}

.order-waiting li::before {
  font-size: 1.3em;
  font-weight: 900;
  opacity: 1;
  text-shadow: 0 0 10px rgb(255 213 74 / 45%);
}

#orderCurrentName::before {
  font-weight: 900;
  opacity: 1;
}

/* 오른쪽 소스 0.85 배율 시도는 되돌렸다 — 방송 화면에서 길이가 크게 늘어나는
   부작용 (2026-08-29, 원인 조사 전 즉시 철회). */

/* 오른쪽 소스 전체 실축소 — 오른쪽 소스만! (2026-08-29 사장님 확정: 원래 크기에서
   가로·세로를 확 줄이고, 화면 크기는 고객이 소스 확대로 잡는다) */
:root.only-right {
  zoom: var(--right-safe-zoom);
}

/* 뱃지 최종 모양 — 고객 (2026-08-29 심야): "대기자 N명" 문구에, 참여자 라벨과 같은
   글씨체·색·크기(.count-row 계열: 900 굵기, clamp 크기, 카드 본문색). 주변 여백은
   글씨 높이에 맞춰 줄이고, 줄어든 만큼 힛 카드가 따라 올라온다(그리드 auto 행이라
   뱃지 높이 축소가 곧 힛 카드 상승이다). */
.broadcast-right .overflow {
  margin: 4px 0 0;
  padding: 0;
  font-size: clamp(19px, 2.2vw, 24px);
  font-weight: 900;
  line-height: 1.1;
  color: var(--event-copy, #eafff5);
  text-shadow: var(--event-copy-shadow, none);
}

/* 힛 카드 추가 상승 — 고객 (2026-08-29 심야): 뱃지 여백 축소에 이어 힛 카드 자체도
   더 올려달라. 행 간격 14→6px, 당김 -10→-16px: 합쳐서 약 14px 더 올라간다. */
.broadcast-right {
  row-gap: 6px;
}

.broadcast-right .hit-box {
  margin-top: -16px;
}

/* 추첨 글자 하늘색 재고정 — 고객 (2026-08-30 00시): "하늘색 요청드린거 아직 하얀색".
   운영자 카드 글자색 규칙(.broadcast-left .event-card :is(... .eyebrow, #winner,
   #winnerPrize ...))이 (1,2,0) 특이도로 나중에 들어와 라벨(eyebrow 클래스)까지 셋 다
   도로 희게 칠했다 — 하늘색이 한 번도 화면에 못 나온 원인. 같은 특이도로 맨 뒤에서
   다시 고정한다. 그림자는 카드 규칙 것을 그대로 쓴다. */
/* 정정(01:40, 고객 01:18): 당첨자 닉네임과 추첨 롤링 '참여자N'(같은 #winner 요소)은
   흰색이어야 한다 — 하늘색은 라벨(#drawLabel)·상품(#winnerPrize)만. */
.broadcast-left .event-card :is(#drawLabel, #winnerPrize) {
  color: #7ed6ff;
}
.broadcast-left .event-card #winner {
  color: #ffffff;
}

:root.only-left .broadcast-left .link-box {
  transform: translate(var(--offset-x, 0), calc(var(--offset-y, 0px) + 8px)) scale(var(--scale, 1));
}

/* ── 주문 대기중 글씨 흰색+글로우 (고객 2026-08-30 01시 요청) ──────────────
   "주문대기중 글씨도 좀 빛나게 하고 하얀색으로". 몬스터볼 장식의 흰 드롭섀도와
   톤을 맞춰 글자만 흰색·이중 글로우로 맨 뒤에서 고정한다. */
.broadcast-right .order-current[data-state="waiting"] .order-current-status {
  color: #ffffff;
  /* 글로우 절반 완화 — 고객 01:5x "밝기 낮춰주세요, 글씨가 뭉툭". 흰색은 유지. */
  text-shadow:
    0 0 3px rgba(255, 255, 255, 0.55),
    0 0 9px rgba(255, 255, 255, 0.25);
}

/* ── 물품명(상품 설명 줄)은 다시 크게 (고객 2026-08-30 01:12 "물품명이 안 보입니다") ──
   15:24 의 'HIT 제목과 동일' 요청은 머리글·주문자 이름 줄에 대한 것이었는데
   .order-current strong(상품 설명)까지 hit-title 크기로 줄어 있었다. 상품 줄만
   전용 변수 크기로 원복한다 (머리글·이름은 그대로 hit-title 유지). */
/* (철회 2026-08-30 01:30) strong 은 물품명이 아니라 주문자명이었다 — 잘못 짚어
   이름을 26px 로 줄였던 font-size 지정을 제거한다. 이름은 1986행대 hit-title
   (30~38px) 규칙으로 복귀, 물품명(#orderCurrentProduct)은 clamp(26px,3vw,36px)
   규칙이 이미 지배한다. */

.broadcast-right .order-current strong {
  font-size: var(--broadcast-hit-title);
}
.broadcast-right .order-current p {
  font-size: var(--broadcast-hit-title);
}

:root.only-right .broadcast-right {
  display: flex;
  flex-direction: column;
}

:root.only-right .broadcast-right .order-box {
  flex: 0 0 auto;
}

:root.only-right .broadcast-right .order-current[data-state="waiting"] .order-current-status {
  grid-column: 1 / -1;
  justify-self: start;
}

:root.only-right .broadcast-right .hit-box {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  min-height: 0;
  margin-top: 0;
}

:root.only-right .broadcast-right .hit-box h2 {
  flex: 0 0 auto;
}

:root.only-right .broadcast-right .hit-viewport {
  flex: 0 0 auto;
  height: calc(var(--hit-row-height) * 3 + var(--hit-row-gap) * 2);
  min-height: calc(var(--hit-row-height) * 3 + var(--hit-row-gap) * 2);
  mask-image: linear-gradient(to bottom, transparent, #000 8px, #000 calc(100% - 8px), transparent);
}

/* ── 체이싱 LED 테두리 — 테마 팔레트 4종 전용 (사장님 승인 발주, 2026-08-30) ───
   고객 2 오버레이(188-217행)의 링 효과 이식: conic-gradient 빛줄기가 2px 테두리
   링(마스크 xor)을 따라 7초에 한 바퀴 돈다. 기본 emerald(현재 방송 룩)는 불변 —
   아래 :is() 4종에서만 발동한다.

   의사요소 배치: 링크·힛 박스의 ::before 는 357행이 display:none 으로 비워 둔
   자리를 재활용하고(그래서 여기서 display:block 으로 되살린다), 주문 박스
   ::before 는 원래 미사용이다. event-card 는 ::before/::after 둘 다 오라가 점유
   중이라 제외한다 — 발주 재량 범위(새 DOM 요소는 렌더 경로 영향이 있어 안 만든다).

   성능: 애니메이션은 @property 로 등록한 --led-angle 각도 하나뿐이다(등록이
   없으면 각도가 보간되지 않아 링이 멈춘다). drop-shadow 는 원본과 같은 3px —
   고객 2 방송에서 부하 검증된 값. */
@property --led-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

@keyframes led-orbit {
  to {
    --led-angle: 360deg;
  }
}

/* 빛 색은 팔레트별 확정값(발주 지정): 몬스터볼 레드 / 체육관 골드 / 밀짚 골드 /
   해적 레드. 해적기는 --sl-accent 가 백색이라 --order-accent 의 레드를 쓴다. */
:root[data-palette="pokeball"] {
  --led-beam: #ff4d4d;
}

:root[data-palette="gymbadge"] {
  --led-beam: #f0c85a;
}

:root[data-palette="strawhat"] {
  --led-beam: #f7c948;
}

:root[data-palette="jollyroger"] {
  --led-beam: #d4342a;
}

/* 링의 inset:0 기준점 — 힛 박스는 이미 position:relative(120행), 나머지 둘만 세운다.
   팔레트 게이트 밖(emerald)에서는 position 도 건드리지 않는다. */
:root:is(
  [data-palette="pokeball"],
  [data-palette="gymbadge"],
  [data-palette="strawhat"],
  [data-palette="jollyroger"]
) :is(.broadcast-left .link-box, .broadcast-right .order-box) {
  position: relative;
}

:root:is(
    [data-palette="pokeball"],
    [data-palette="gymbadge"],
    [data-palette="strawhat"],
    [data-palette="jollyroger"]
  )
  :is(.broadcast-left .link-box, .broadcast-right .order-box, .broadcast-right .hit-box)::before {
  content: "";
  display: block;
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 2px;
  background: conic-gradient(
    from var(--led-angle),
    transparent 0deg 244deg,
    color-mix(in srgb, var(--led-beam) 18%, transparent) 260deg,
    color-mix(in srgb, var(--led-beam) 66%, transparent) 278deg,
    var(--led-beam) 292deg,
    #fff 300deg,
    var(--led-beam) 308deg,
    color-mix(in srgb, var(--led-beam) 48%, transparent) 324deg,
    transparent 342deg 360deg
  );
  filter: drop-shadow(0 0 3px var(--led-beam));
  pointer-events: none;
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  mask-composite: exclude;
  animation: led-orbit 7s linear infinite;
}
