/* LoreBoard — viewer.css
 * Page shell + per-surface layout for viewer.html.
 * The surface is written onto <html data-sb-surface="..."> by js/boot.js, and
 * onto the app container by render.js.
 */

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

body { overflow: hidden; }

/* ------------------------------------------------------------- overlay */
/* Everything outside the pill and the tray must let clicks through to the
 * Twitch player, so the page itself is inert and only the two interactive
 * roots opt back in. */

html[data-sb-surface="overlay"],
html[data-sb-surface="overlay"] body {
  background: transparent;
  pointer-events: none;
  overflow: hidden;
}

.sb-surface-overlay {
  position: fixed;
  top: 0; right: 0; bottom: 0; left: 0;
  pointer-events: none;
}

/* The pill anchors to one edge of the player, chosen in the CMS
 * (config.overlay.anchor). render.js puts .sb-anchor-<edge> on this element
 * and writes the safe-area offset into --sb-anchor-offset: 44px on top, to
 * clear Twitch's own top-corner UI, and 48px on bottom, to clear the control
 * bar. Right and left are vertically centered and need no offset.
 * The tray always opens inward, away from that edge. */
.sb-overlay-anchor {
  position: absolute;
  pointer-events: none;
  --sb-anchor-offset: 0px;
}

.sb-anchor-right { right: 0; top: 50%; transform: translateY(-50%); }
.sb-anchor-left  { left: 0;  top: 50%; transform: translateY(-50%); }
.sb-anchor-top {
  top: var(--sb-anchor-offset, 44px);
  left: 50%;
  transform: translateX(-50%);
}
.sb-anchor-bottom {
  bottom: var(--sb-anchor-offset, 48px);
  left: 50%;
  transform: translateX(-50%);
}

.sb-surface-overlay .sb-pill {
  pointer-events: auto;
  position: relative;
  z-index: 2;
}

/* Pill shape: the border facing the player edge is dropped so the pill reads
 * as attached to it. */
.sb-anchor-right .sb-pill {
  border-right: 0;
  border-radius: var(--sb-radius) 0 0 var(--sb-radius);
}
.sb-anchor-left .sb-pill {
  border-left: 0;
  border-radius: 0 var(--sb-radius) var(--sb-radius) 0;
}
.sb-anchor-top .sb-pill {
  border-top: 0;
  border-radius: 0 0 var(--sb-radius) var(--sb-radius);
}
.sb-anchor-bottom .sb-pill {
  border-bottom: 0;
  border-radius: var(--sb-radius) var(--sb-radius) 0 0;
}

/* Free placement (config.overlay.anchor === "custom"). The position itself —
 * left, top and the self-relative transform — is written inline by render.js
 * from overlay.x / overlay.y, because those are per-config numbers rather than
 * one of four fixed cases; see customPlacement() there. What is left for the
 * stylesheet is everything that does not depend on the numbers.
 *
 * The pill is not touching an edge here, so unlike the edge anchors it keeps
 * its border and its radius the whole way round. */
.sb-anchor-custom .sb-pill { border-radius: var(--sb-radius); }
.sb-anchor-custom[data-open="left"] .sb-chevron         { transform: rotate(0deg); }
.sb-anchor-custom[data-open="left"].is-open .sb-chevron { transform: rotate(180deg); }
.sb-anchor-custom[data-open="right"] .sb-chevron         { transform: rotate(180deg); }
.sb-anchor-custom[data-open="right"].is-open .sb-chevron { transform: rotate(0deg); }

/* The chevron always points the way the tray will open. */
.sb-anchor-left .sb-chevron            { transform: rotate(180deg); }
.sb-anchor-left.is-open .sb-chevron    { transform: rotate(0deg); }
.sb-anchor-top .sb-chevron             { transform: rotate(-90deg); }
.sb-anchor-top.is-open .sb-chevron     { transform: rotate(90deg); }
.sb-anchor-bottom .sb-chevron          { transform: rotate(90deg); }
.sb-anchor-bottom.is-open .sb-chevron  { transform: rotate(-90deg); }

.sb-surface-overlay .sb-tray {
  position: absolute;
  width: 40vw;
  min-width: 240px;
  max-width: 440px;
  max-height: 78vh;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s linear;
}

.sb-anchor-right .sb-tray {
  right: 100%;
  top: 50%;
  margin-right: 8px;
  transform: translateY(-50%) translateX(10px);
}
.sb-anchor-left .sb-tray {
  left: 100%;
  top: 50%;
  margin-left: 8px;
  transform: translateY(-50%) translateX(-10px);
}
.sb-anchor-top .sb-tray {
  top: 100%;
  left: 50%;
  margin-top: 8px;
  max-height: calc(100vh - var(--sb-anchor-offset, 44px) - 110px);
  transform: translateX(-50%) translateY(-10px);
}
.sb-anchor-bottom .sb-tray {
  bottom: 100%;
  left: 50%;
  margin-bottom: 8px;
  max-height: calc(100vh - var(--sb-anchor-offset, 48px) - 110px);
  transform: translateX(-50%) translateY(10px);
}

/* Custom: the tray unfolds toward whichever side of the player has more room
 * (data-open, set by render.js from x), and hangs from the top, the middle or
 * the bottom of the pill (data-tray-v, from y) so that a pill placed near an
 * edge does not open a tray off the player. */
.sb-anchor-custom[data-open="right"] .sb-tray { left: 100%; margin-left: 8px; }
.sb-anchor-custom[data-open="left"] .sb-tray  { right: 100%; margin-right: 8px; }
.sb-anchor-custom[data-tray-v="top"] .sb-tray    { top: 0; max-height: 78vh; }
.sb-anchor-custom[data-tray-v="bottom"] .sb-tray { bottom: 0; max-height: 78vh; }
.sb-anchor-custom[data-tray-v="mid"] .sb-tray    { top: 50%; }

.sb-anchor-custom[data-open="right"][data-tray-v="top"] .sb-tray,
.sb-anchor-custom[data-open="right"][data-tray-v="bottom"] .sb-tray { transform: translateX(-10px); }
.sb-anchor-custom[data-open="left"][data-tray-v="top"] .sb-tray,
.sb-anchor-custom[data-open="left"][data-tray-v="bottom"] .sb-tray  { transform: translateX(10px); }
.sb-anchor-custom[data-open="right"][data-tray-v="mid"] .sb-tray { transform: translateY(-50%) translateX(-10px); }
.sb-anchor-custom[data-open="left"][data-tray-v="mid"] .sb-tray  { transform: translateY(-50%) translateX(10px); }

.sb-anchor-right.is-open .sb-tray,
.sb-anchor-left.is-open .sb-tray {
  transform: translateY(-50%) translateX(0);
}
.sb-anchor-top.is-open .sb-tray,
.sb-anchor-bottom.is-open .sb-tray {
  transform: translateX(-50%) translateY(0);
}
.sb-anchor-custom.is-open[data-tray-v="top"] .sb-tray,
.sb-anchor-custom.is-open[data-tray-v="bottom"] .sb-tray { transform: translateX(0); }
.sb-anchor-custom.is-open[data-tray-v="mid"] .sb-tray { transform: translateY(-50%) translateX(0); }

.sb-overlay-anchor.is-open .sb-tray {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
}

/* Twitch guidance: hide the extension when the player is too small for it
 * to be usable, rather than covering the video with a stub. */
.sb-surface-overlay[data-sb-too-small="1"] .sb-overlay-anchor { display: none; }

@media (prefers-reduced-motion: reduce) {
  .sb-surface-overlay .sb-tray { transition: none; }
}

/* Local preview only: ?mock=1 paints a backdrop so the transparent overlay
 * is visible in a plain browser. Twitch never sets this attribute. */
html[data-sb-surface="overlay"][data-sb-mock="1"] body {
  background:
    linear-gradient(135deg, rgba(255, 255, 255, 0.04) 25%, transparent 25%) -20px 0/40px 40px,
    linear-gradient(225deg, rgba(255, 255, 255, 0.04) 25%, transparent 25%) -20px 0/40px 40px,
    #101014;
}

/* ----------------------------------------------------------- component */

.sb-surface-component {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  display: flex;
  padding: 8px;
}

.sb-surface-component .sb-tray {
  flex: 1 1 auto;
  width: 100%;
  height: 100%;
  max-height: 100%;
}

/* --------------------------------------------------------------- panel */
/* Twitch panel viewport is 318 x 496. Single column, whole panel scrolls. */

.sb-surface-panel {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
}

.sb-surface-panel .sb-tray {
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: var(--sb-bg);
}

.sb-surface-panel .sb-grid { grid-template-columns: minmax(0, 1fr) !important; }
.sb-surface-panel .sb-block[data-size] { grid-column: auto; }

/* -------------------------------------------------------------- mobile */
/* Renders inside the mobile app's chat-area viewport, portrait and
 * landscape. Touch targets are 44px, single column. */

.sb-surface-mobile {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  --sb-touch: 44px;
  --sb-pad: 14px;
  --sb-gap: 12px;
  font-size: 15px;
}

.sb-surface-mobile .sb-tray {
  width: 100%;
  height: 100%;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: var(--sb-bg);
}

.sb-surface-mobile .sb-grid { grid-template-columns: minmax(0, 1fr) !important; }
.sb-surface-mobile .sb-block[data-size] { grid-column: auto; }
.sb-surface-mobile .sb-tab { padding: 0 14px; font-size: 14px; }
.sb-surface-mobile .sb-rt-p { font-size: 16.5px; }
.sb-surface-mobile .sb-block-title { font-size: 16px; }
.sb-surface-mobile .sb-rt-p,
.sb-surface-mobile .sb-link-label { font-size: 15px; }

@media (orientation: landscape) and (max-height: 420px) {
  .sb-surface-mobile { --sb-gap: 8px; --sb-pad: 10px; }
  .sb-surface-mobile .sb-tabs { padding-top: 4px; }
}

/* ------------------------------------------------------------ boot fail */

.sb-boot-error {
  position: absolute;
  top: 8px; left: 8px; right: 8px;
  padding: 10px 12px;
  font: 13px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: #efeff1;
  background: rgba(20, 20, 24, 0.94);
  border: 1px solid rgba(239, 239, 241, 0.24);
  border-radius: 8px;
  pointer-events: auto;
}
