/* =========================================================================
   Obs Media Share - design system
   One stylesheet, no build step. Tokens first, then layout, then components.
   ========================================================================= */

:root {
  /* Surfaces */
  --bg: #0a0f14;
  --bg-glow: radial-gradient(1200px 600px at 12% -10%, #123040 0%, transparent 60%),
             radial-gradient(900px 500px at 100% 0%, #1a2436 0%, transparent 55%);
  --surface: #111a22;
  --surface-2: #16212b;
  --surface-3: #1d2b37;
  --border: #23323f;
  --border-strong: #31465a;

  /* Text */
  --text: #e9f1f6;
  --text-muted: #8ea3b2;
  --text-dim: #5f7486;

  /* Accents */
  --accent: #5ce6c4;
  --accent-ink: #052b24;
  --accent-soft: rgba(92, 230, 196, 0.12);
  --gold: #ffc861;
  --gold-soft: rgba(255, 200, 97, 0.12);
  --danger: #ff6b7a;
  --danger-soft: rgba(255, 107, 122, 0.12);
  --info: #6cb6ff;

  /* Shape */
  --r-sm: 8px;
  --r-md: 12px;
  --r-lg: 18px;
  --r-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 8px 24px -8px rgba(0, 0, 0, 0.6);
  --shadow-lg: 0 24px 60px -20px rgba(0, 0, 0, 0.75);

  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --sp: 4px;
  --header-h: 62px;

  color-scheme: dark;
}

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

html { -webkit-text-size-adjust: 100%; }

body {
  min-height: 100vh;
  background: var(--bg);
  background-image: var(--bg-glow);
  background-attachment: fixed;
  color: var(--text);
  font-family: "Maven Pro", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
svg { display: block; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}

.hidden { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Scrollbars ------------------------------------------------------------- */
* { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--border-strong);
  border-radius: var(--r-pill);
  border: 2px solid transparent;
  background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: #41607a; background-clip: padding-box; }

/* =========================================================================
   App shell
   ========================================================================= */
.app-header {
  position: sticky;
  top: 0;
  z-index: 60;
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 20px;
  background: rgba(10, 15, 20, 0.82);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--border);
}

.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand__mark {
  width: 30px; height: 30px;
  display: grid; place-items: center;
  border-radius: 9px;
  background: linear-gradient(145deg, var(--accent), #2ba98d);
  color: var(--accent-ink);
  box-shadow: 0 0 0 1px rgba(92, 230, 196, 0.25), 0 6px 18px -6px rgba(92, 230, 196, 0.6);
}
.brand__mark svg { width: 16px; height: 16px; fill: currentColor; }
.brand__name {
  font-weight: 800;
  letter-spacing: -0.02em;
  font-size: 15px;
  white-space: nowrap;
}
.brand__name span { color: var(--text-dim); font-weight: 600; }

.header-spacer { flex: 1; }

.header-links { display: flex; gap: 4px; }
.header-link {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 13px;
  border-radius: var(--r-pill);
  color: var(--text-muted);
  font-size: 13.5px; font-weight: 600;
  transition: background 0.16s var(--ease), color 0.16s var(--ease);
}
.header-link:hover { background: var(--surface-2); color: var(--text); text-decoration: none; }
.header-link[aria-current="page"] { background: var(--accent-soft); color: var(--accent); }
.header-link svg { width: 14px; height: 14px; fill: currentColor; }

/* Status pills ----------------------------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: 7px;
  height: 30px; padding: 0 12px;
  border-radius: var(--r-pill);
  border: 1px solid var(--border);
  background: var(--surface);
  font-size: 12.5px; font-weight: 600;
  color: var(--text-muted);
  white-space: nowrap;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease);
}
.pill__dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--text-dim);
  box-shadow: 0 0 0 0 currentColor;
}
.pill.is-online { color: var(--accent); border-color: rgba(92, 230, 196, 0.35); }
.pill.is-online .pill__dot { background: var(--accent); animation: pulse 2.4s var(--ease) infinite; }
.pill.is-offline { color: var(--danger); border-color: rgba(255, 107, 122, 0.3); }
.pill.is-offline .pill__dot { background: var(--danger); }
.pill.is-clickable { cursor: pointer; }
.pill svg { width: 12px; height: 12px; fill: currentColor; }
.pill [data-icon] { display: inline-flex; }
.pill.is-clickable:hover { border-color: var(--border-strong); color: var(--text); }

@keyframes pulse {
  0%   { box-shadow: 0 0 0 0 rgba(92, 230, 196, 0.5); }
  70%  { box-shadow: 0 0 0 6px rgba(92, 230, 196, 0); }
  100% { box-shadow: 0 0 0 0 rgba(92, 230, 196, 0); }
}

/* =========================================================================
   Layout
   ========================================================================= */
.layout {
  max-width: 1500px;
  margin: 0 auto;
  padding: 22px 20px 60px;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 20px;
  align-items: start;
}
.col { display: grid; gap: 20px; min-width: 0; }
.col--left { position: sticky; top: calc(var(--header-h) + 22px); }

@media (max-width: 1080px) {
  .layout { grid-template-columns: minmax(0, 1fr); }
  .col--left { position: static; }
}

/* =========================================================================
   Card / panel
   ========================================================================= */
.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}

.card__head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.025), transparent);
}
.card__title {
  display: flex; align-items: center; gap: 9px;
  font-size: 13px; font-weight: 800;
  letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-muted);
}
.card__title svg { width: 14px; height: 14px; fill: var(--accent); }
.card__count {
  display: inline-grid; place-items: center;
  min-width: 22px; height: 20px; padding: 0 7px;
  border-radius: var(--r-pill);
  background: var(--accent-soft); color: var(--accent);
  font-size: 11.5px; font-weight: 800; letter-spacing: 0;
}
.card__actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.card__body { padding: 16px 18px; }
.card__body--flush { padding: 0; }

/* =========================================================================
   Buttons
   ========================================================================= */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  height: 36px; padding: 0 15px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
  color: var(--text);
  font-size: 13.5px; font-weight: 700;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.16s var(--ease), border-color 0.16s var(--ease),
              transform 0.08s var(--ease), opacity 0.16s var(--ease);
}
.btn:hover:not(:disabled) { background: var(--surface-3); border-color: var(--border-strong); }
.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: 0.45; cursor: not-allowed; }
.btn svg { width: 14px; height: 14px; fill: currentColor; }

.btn--primary {
  background: linear-gradient(145deg, var(--accent), #35c2a2);
  border-color: transparent;
  color: var(--accent-ink);
  box-shadow: 0 6px 18px -8px rgba(92, 230, 196, 0.8);
}
.btn--primary:hover:not(:disabled) { filter: brightness(1.08); background: var(--accent); }
.btn--ghost { background: transparent; border-color: transparent; color: var(--text-muted); }
.btn--ghost:hover:not(:disabled) { background: var(--surface-2); color: var(--text); }
.btn--danger { color: var(--danger); }
.btn--danger:hover:not(:disabled) { background: var(--danger-soft); border-color: rgba(255, 107, 122, 0.4); }
.btn--sm { height: 30px; padding: 0 11px; font-size: 12.5px; border-radius: var(--r-sm); }
.btn--icon { width: 34px; height: 34px; padding: 0; }
.btn--icon.btn--sm { width: 28px; height: 28px; }

/* =========================================================================
   Now playing
   ========================================================================= */
.stage {
  position: relative;
  aspect-ratio: 16 / 9;
  background: #000;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}
.stage__frame,
.stage__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border: 0; background: #000;
}
.stage__video { object-fit: contain; }

.stage__empty {
  position: absolute; inset: 0;
  z-index: 3;
  display: grid; place-content: center; justify-items: center; gap: 10px;
  background:
    repeating-linear-gradient(45deg, #0c1318 0 12px, #0e1620 12px 24px);
  color: var(--text-dim);
  text-align: center; padding: 20px;
}
.stage__empty svg { width: 34px; height: 34px; fill: currentColor; opacity: 0.55; }
.stage__empty strong { color: var(--text-muted); font-size: 14px; font-weight: 700; }
.stage__empty span { font-size: 12.5px; max-width: 34ch; }

.stage__badge {
  position: absolute; top: 12px; left: 12px; z-index: 3;
  display: inline-flex; align-items: center; gap: 7px;
  height: 26px; padding: 0 11px;
  border-radius: var(--r-pill);
  background: rgba(10, 15, 20, 0.78);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  font-size: 11.5px; font-weight: 800;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--accent);
}
.stage__badge .pill__dot { background: var(--accent); animation: pulse 2.4s var(--ease) infinite; }
.stage__badge--donation { color: var(--gold); }
.stage__badge--donation .pill__dot { background: var(--gold); }

.stage__spinner {
  position: absolute; inset: 0; z-index: 5;
  display: grid; place-items: center;
  background: rgba(8, 12, 16, 0.72);
  backdrop-filter: blur(3px);
}

/* Shown when the platform refuses to play something (embed blocked, private,
   removed). The old build left a dead black rectangle with no explanation. */
.stage__error {
  position: absolute; inset: 0; z-index: 4;
  display: grid; place-content: center; justify-items: center; gap: 10px;
  padding: 24px; text-align: center;
  background: #080c10;
  color: var(--text-muted);
}
.stage__error svg { width: 30px; height: 30px; fill: var(--danger); }
.stage__error strong { color: var(--text); font-size: 15px; }
.stage__error span { font-size: 13px; max-width: 42ch; }

/* Transparent click-catcher over the embed. Keeps the operator on our
   controls instead of YouTube's, which would desync the OBS view. */
.stage__shield {
  position: absolute; inset: 0; z-index: 2;
  border: 0; padding: 0;
  background: transparent;
  cursor: pointer;
  appearance: none;
}
.stage__shield:focus-visible { outline-offset: -3px; }

.spinner {
  width: 30px; height: 30px;
  border-radius: 50%;
  border: 3px solid rgba(92, 230, 196, 0.2);
  border-top-color: var(--accent);
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Meta ------------------------------------------------------------------- */
.now-meta { padding: 15px 18px 6px; display: grid; gap: 5px; min-width: 0; }
.now-meta__title {
  font-size: 17px; font-weight: 800; letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.now-meta__title:empty::before { content: "Nothing playing"; color: var(--text-dim); }
.now-meta__sub {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  font-size: 12.5px; color: var(--text-muted);
}
.now-meta__sub a { color: var(--text-muted); text-decoration: underline; text-underline-offset: 2px; }
.now-meta__sub a:hover { color: var(--accent); }

/* Transport -------------------------------------------------------------- */
.transport { padding: 10px 18px 18px; display: grid; gap: 12px; }

.scrubber { display: flex; align-items: center; gap: 12px; }
.scrubber__time {
  font-variant-numeric: tabular-nums;
  font-size: 12px; font-weight: 700; color: var(--text-muted);
  min-width: 42px; text-align: center;
}

.range {
  -webkit-appearance: none; appearance: none;
  flex: 1; height: 18px; background: transparent; cursor: pointer;
}
.range::-webkit-slider-runnable-track {
  height: 6px; border-radius: var(--r-pill);
  background: linear-gradient(to right, var(--accent) var(--progress, 0%), var(--surface-3) var(--progress, 0%));
}
.range::-moz-range-track {
  height: 6px; border-radius: var(--r-pill);
  background: linear-gradient(to right, var(--accent) var(--progress, 0%), var(--surface-3) var(--progress, 0%));
}
.range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px; margin-top: -4px;
  border-radius: 50%; background: var(--text); border: 0;
  box-shadow: 0 0 0 3px rgba(92, 230, 196, 0.25);
  transition: transform 0.12s var(--ease);
}
.range::-moz-range-thumb {
  width: 14px; height: 14px; border: 0;
  border-radius: 50%; background: var(--text);
  box-shadow: 0 0 0 3px rgba(92, 230, 196, 0.25);
}
.range:hover::-webkit-slider-thumb { transform: scale(1.18); }
.range:disabled { opacity: 0.4; cursor: default; }

.controls { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; row-gap: 12px; }
.controls__group { display: flex; align-items: center; gap: 6px; flex: none; }
.controls__spacer { flex: 1 1 auto; }

.ctrl {
  display: grid; place-items: center;
  width: 38px; height: 38px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
  color: var(--text);
  cursor: pointer;
  transition: background 0.16s var(--ease), border-color 0.16s var(--ease),
              transform 0.08s var(--ease);
}
.ctrl:hover:not(:disabled) { background: var(--surface-3); border-color: var(--border-strong); }
.ctrl:active:not(:disabled) { transform: scale(0.94); }
.ctrl:disabled { opacity: 0.4; cursor: not-allowed; }
.ctrl svg { width: 15px; height: 15px; fill: currentColor; }

.ctrl--play {
  width: 46px; height: 46px;
  border-radius: 50%;
  background: linear-gradient(145deg, var(--accent), #35c2a2);
  border-color: transparent;
  color: var(--accent-ink);
  box-shadow: 0 8px 22px -8px rgba(92, 230, 196, 0.85);
}
/* Hover keeps exactly the same paint as the resting button: the generic
   .ctrl hover above would otherwise turn it dark, and brightening it read as
   a flash every time the pointer crossed it. */
.ctrl--play:hover:not(:disabled) {
  background: linear-gradient(145deg, var(--accent), #35c2a2);
  border-color: transparent;
  filter: none;
}
.ctrl--play svg { width: 17px; height: 17px; }

/* The volume group and the autoplay switch used to share one flex row with
   nothing but a gap between them. A range input's width, and how far its
   thumb hangs past the end of the track, differ per browser (Firefox and
   Safari size it differently from Chrome), so at full volume the thumb could
   land on the autoplay switch. Both now have fixed sizes, the slider keeps
   its thumb's overhang inside its own box, and the switch sits behind a
   divider with its own padding, so they cannot meet in any browser. */
.volume {
  display: flex; align-items: center; gap: 10px;
  flex: none;
}
.volume .range {
  flex: none;
  width: 96px; min-width: 0; height: 16px;
  /* Room for the 14px thumb and its 3px ring at either end. */
  margin: 0 10px 0 4px;
}

/* Switch ----------------------------------------------------------------- */
.switch {
  position: relative; flex: none;
  display: inline-flex; align-items: center; gap: 9px;
  padding-left: 16px;
  border-left: 1px solid var(--border);
  cursor: pointer; user-select: none;
  font-size: 13px; font-weight: 700; color: var(--text-muted);
}
.switch input { position: absolute; opacity: 0; pointer-events: none; }
.switch__track {
  position: relative;
  width: 38px; height: 21px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
  border: 1px solid var(--border);
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease);
}
.switch__track::after {
  content: ""; position: absolute;
  top: 2px; left: 2px;
  width: 15px; height: 15px;
  border-radius: 50%; background: var(--text-dim);
  transition: transform 0.2s var(--ease), background 0.2s var(--ease);
}
.switch input:checked + .switch__track { background: var(--accent-soft); border-color: var(--accent); }
.switch input:checked + .switch__track::after { transform: translateX(17px); background: var(--accent); }
.switch input:focus-visible + .switch__track { outline: 2px solid var(--accent); outline-offset: 2px; }
.switch:has(input:checked) { color: var(--text); }

/* =========================================================================
   Stats strip
   ========================================================================= */
.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
  gap: 1px;
  background: var(--border);
  border-bottom: 1px solid var(--border);
}
.stat { background: var(--surface); padding: 12px 18px; display: grid; gap: 3px; }
.stat__label {
  font-size: 10.5px; font-weight: 800;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: var(--text-dim);
}
.stat__value {
  font-size: 18px; font-weight: 800; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.stat__value--accent { color: var(--accent); }
/* For stats holding a title rather than a number - never let one long video
   name blow the strip out to six lines. */
.stat__value--text {
  font-size: 13px; font-weight: 700; line-height: 1.35;
  letter-spacing: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere;
}
.stat__value--gold { color: var(--gold); }

/* =========================================================================
   Media list
   ========================================================================= */
.list {
  display: grid;
  gap: 8px;
  padding: 14px;
  max-height: 460px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
/* The review list is the only thing that scrolls on that page: the page
   itself staying put is what lets the wheel reach the list while the pointer
   is over a video preview. */
.list--tall { max-height: calc(100vh - var(--header-h) - 190px); }
.list:empty { padding: 0; }

.row {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 11px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--surface-2);
  transition: border-color 0.16s var(--ease), background 0.16s var(--ease),
              transform 0.16s var(--ease);
  animation: rowIn 0.24s var(--ease) both;
}
.row:hover { border-color: var(--border-strong); background: var(--surface-3); }
.row.is-dragging { opacity: 0.45; }
.row.is-ghost { border-style: dashed; border-color: var(--accent); background: var(--accent-soft); }

@keyframes rowIn {
  from { opacity: 0; transform: translateY(-5px); }
  to   { opacity: 1; transform: none; }
}

.row__grip {
  flex: none;
  display: grid; place-items: center;
  width: 20px; height: 26px;
  color: var(--text-dim);
  cursor: grab;
  border-radius: var(--r-sm);
  transition: color 0.16s var(--ease);
}
.row__grip:hover { color: var(--text-muted); }
.row__grip:active { cursor: grabbing; }
.row__grip svg { width: 11px; height: 11px; fill: currentColor; }

.row__index {
  flex: none;
  display: grid; place-items: center;
  width: 22px; height: 22px;
  border-radius: 6px;
  background: var(--surface);
  color: var(--text-dim);
  font-size: 11px; font-weight: 800;
  font-variant-numeric: tabular-nums;
}

.row__thumb {
  flex: none;
  width: 64px; height: 36px;
  border-radius: 6px;
  background: #000 center/cover no-repeat;
  border: 1px solid var(--border);
  position: relative;
  overflow: hidden;
}
.row__thumb::after {
  content: attr(data-platform);
  position: absolute; bottom: 2px; right: 3px;
  font-size: 8.5px; font-weight: 800; letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #fff;
  text-shadow: 0 1px 3px #000;
}

.row__main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.row__title {
  font-size: 13.5px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.row__sub {
  display: flex; align-items: center; gap: 7px; flex-wrap: wrap;
  font-size: 11.5px; color: var(--text-dim);
}
.row__sub .dot { opacity: 0.5; }

.row__actions { flex: none; display: flex; align-items: center; gap: 4px; }

.tag {
  display: inline-flex; align-items: center; gap: 4px;
  height: 18px; padding: 0 7px;
  border-radius: var(--r-pill);
  background: var(--surface);
  border: 1px solid var(--border);
  font-size: 10.5px; font-weight: 800;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--text-dim);
}
.tag--gold { color: var(--gold); border-color: rgba(255, 200, 97, 0.3); background: var(--gold-soft); }
.tag--accent { color: var(--accent); border-color: rgba(92, 230, 196, 0.3); background: var(--accent-soft); }

/* Empty state ------------------------------------------------------------ */
.empty {
  display: grid; place-items: center; gap: 9px;
  padding: 44px 24px;
  text-align: center;
  color: var(--text-dim);
}
.empty svg { width: 30px; height: 30px; fill: currentColor; opacity: 0.4; }
.empty strong { font-size: 13.5px; font-weight: 700; color: var(--text-muted); }
.empty span { font-size: 12.5px; max-width: 38ch; }

/* =========================================================================
   Forms
   ========================================================================= */
.field { display: grid; gap: 6px; min-width: 0; }
.field__label {
  font-size: 11.5px; font-weight: 800;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--text-dim);
}
.field__hint { font-size: 11.5px; color: var(--text-dim); }

.input {
  width: 100%; height: 38px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  background: var(--bg);
  color: var(--text);
  transition: border-color 0.16s var(--ease), box-shadow 0.16s var(--ease);
}
.input::placeholder { color: var(--text-dim); }
.input:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.input:disabled { opacity: 0.5; cursor: not-allowed; }

.add-form { display: grid; gap: 12px; }
.add-form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.add-form__actions { display: flex; gap: 8px; justify-content: flex-end; }

/* Import / export of the whole queue: a separate job from adding one link,
   so it sits below its own rule rather than inside the form. */
.transfer {
  display: grid; gap: 8px;
  margin-top: 16px; padding-top: 16px;
  border-top: 1px solid var(--border);
}
.transfer__row { display: flex; gap: 8px; flex-wrap: wrap; }

@media (max-width: 480px) {
  .add-form__row { grid-template-columns: 1fr; }
  .transfer__row > .btn { flex: 1; }
}

/* =========================================================================
   Modal
   ========================================================================= */
.overlay {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center;
  padding: 20px;
  background: rgba(5, 8, 11, 0.72);
  backdrop-filter: blur(6px);
  animation: fade 0.18s var(--ease);
}
.overlay[hidden] { display: none; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

.modal {
  width: min(520px, 100%);
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  animation: modalIn 0.22s var(--ease);
  max-height: 100%;
  overflow-y: auto;
}
@keyframes modalIn {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: none; }
}
.modal__head {
  display: flex; align-items: center; gap: 12px;
  padding: 16px 18px;
  border-bottom: 1px solid var(--border);
}
.modal__title { font-size: 15px; font-weight: 800; }
.modal__body { padding: 18px; }

/* =========================================================================
   Toasts
   ========================================================================= */
.toasts {
  position: fixed;
  bottom: 18px; right: 18px; z-index: 120;
  display: grid; gap: 9px;
  width: min(360px, calc(100vw - 36px));
  pointer-events: none;
}
.toast {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 13px;
  border: 1px solid var(--border-strong);
  border-left-width: 3px;
  border-radius: var(--r-md);
  background: var(--surface-2);
  box-shadow: var(--shadow-lg);
  font-size: 13px;
  pointer-events: auto;
  animation: toastIn 0.24s var(--ease);
}
.toast.is-leaving { animation: toastOut 0.2s var(--ease) forwards; }
.toast__icon { flex: none; width: 16px; height: 16px; margin-top: 1px; }
.toast__icon svg { width: 16px; height: 16px; fill: currentColor; }
.toast__text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.toast--success { border-left-color: var(--accent); color: var(--text); }
.toast--success .toast__icon { color: var(--accent); }
.toast--error { border-left-color: var(--danger); }
.toast--error .toast__icon { color: var(--danger); }
.toast--info { border-left-color: var(--info); }
.toast--info .toast__icon { color: var(--info); }

@keyframes toastIn { from { opacity: 0; transform: translateX(22px); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateX(22px); } }

/* =========================================================================
   Review page
   ========================================================================= */
.review-layout {
  max-width: 1080px;
  margin: 0 auto;
  padding: 22px 20px 60px;
  display: grid; gap: 20px;
}

.donation {
  display: grid;
  /* The preview has to be big enough to use: at 232px YouTube's play button
     covered most of it and the scrubber was too small to grab. */
  grid-template-columns: auto minmax(360px, 480px) minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 13px;
  border: 1px solid var(--border);
  border-left: 3px solid var(--gold);
  border-radius: var(--r-md);
  background: var(--surface-2);
  animation: rowIn 0.24s var(--ease) both;
  transition: border-color 0.16s var(--ease), opacity 0.2s var(--ease),
              transform 0.2s var(--ease);
}
.donation:hover { border-color: var(--border-strong); border-left-color: var(--gold); }
.donation.is-resolving { opacity: 0; transform: scale(0.97); }

.donation__preview {
  aspect-ratio: 16 / 9;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: #000;
  border: 1px solid var(--border);
}
.donation__preview { position: relative; }
.donation__preview iframe,
.donation__preview video { width: 100%; height: 100%; border: 0; display: block; }

/* See review.js `shield`. */
.donation__shield {
  position: absolute; inset: 0;
  border: 0; padding: 0;
  background: transparent;
  cursor: pointer;
  appearance: none;
}
.donation__preview.is-live .donation__shield { display: none; }

.donation__main { display: grid; gap: 6px; min-width: 0; }
.donation__title {
  font-size: 15px; font-weight: 800; letter-spacing: -0.01em;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.donation__meta { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-size: 12px; color: var(--text-muted); }
.donation__price { color: var(--gold); font-weight: 800; }
.donation__actions { display: grid; gap: 8px; }

.btn--approve {
  background: var(--accent-soft);
  border-color: rgba(92, 230, 196, 0.35);
  color: var(--accent);
}
.btn--approve:hover:not(:disabled) { background: var(--accent); color: var(--accent-ink); border-color: transparent; }
.btn--deny { background: var(--danger-soft); border-color: rgba(255, 107, 122, 0.3); color: var(--danger); }
.btn--deny:hover:not(:disabled) { background: var(--danger); color: #2a0409; border-color: transparent; }

@media (max-width: 1000px) {
  .donation { grid-template-columns: auto minmax(0, 1fr); grid-template-areas: "grip main" "preview preview" "actions actions"; }
  .donation__grip { grid-area: grip; }
  .donation__preview { grid-area: preview; }
  .donation__main { grid-area: main; }
  .donation__actions { grid-area: actions; grid-auto-flow: column; }
}

/* =========================================================================
   OBS view page
   ========================================================================= */
body.view-page {
  background: transparent;
  background-image: none;
  overflow: hidden;
}
.view-stage {
  position: fixed; inset: 0;
  overflow: hidden;
  background: #000;
  font-family: "Maven Pro", system-ui, sans-serif;
}
/* Nothing on air: a fully transparent page, so the OBS scene shows through
   instead of a black rectangle or the last video's thumbnail. */
.view-stage.is-idle { background: transparent; }
.view-stage.is-idle > .view-curtain,
.view-stage.is-idle > iframe,
.view-stage.is-idle > video { display: none; }

/* Waiting for a downloaded clip to load and start (view.js
   waitTransparently): see-through, so the scene behind the browser source
   shows instead of a black rectangle. The video is invisible rather than
   display:none, so it goes on buffering. */
.view-stage.is-waiting { background: transparent; }
.view-stage.is-waiting > .view-curtain { opacity: 0; }
.view-stage.is-waiting > video { opacity: 0; }

.view-stage > iframe,
.view-stage > .stage__frame,
.view-stage > video {
  position: absolute; inset: 0;
  width: 100%; height: 100%; border: 0;
  /* Never let the player see a pointer. Hovering a YouTube embed is what
     summons its title bar, its share button and its suggested-video strip,
     and none of that may reach the stream. */
  pointer-events: none;
}
/* The embed is taller than the stage by --yt-crop at each end, so YouTube's
   title bar (top) and its copy-link / "More videos" / logo row (bottom) land
   outside the stage and are cut off. Set from view.js (`/view?crop=`). */
.view-stage > iframe,
.view-stage > .stage__frame {
  top: calc(-1 * var(--yt-crop, 0px));
  bottom: auto;
  height: calc(100% + 2 * var(--yt-crop, 0px));
}

.view-stage > video { object-fit: contain; background: #000; }

/* Curtain ---------------------------------------------------------------- */
.view-curtain {
  position: absolute; inset: 0; z-index: 5;
  background: #000;
  opacity: 0;
  pointer-events: none;
}
.view-curtain.is-up { opacity: 1; }

/* Thumbnail while a video waits to play. Above the curtain, below the card. */
.view-poster {
  position: absolute; inset: 0; z-index: 5;
  width: 100%; height: 100%;
  object-fit: contain;
  background: #000;
  pointer-events: none;
}
.view-poster[hidden] { display: none; }

.view-sound {
  position: absolute; left: 50%; bottom: 36px; z-index: 7;
  transform: translateX(-50%);
  padding: 12px 20px;
  border: 0; border-radius: var(--r-pill);
  background: rgba(8, 12, 16, 0.82);
  color: #fff;
  font: 700 15px "Maven Pro", system-ui, sans-serif;
  cursor: pointer;
}
.view-sound[hidden] { display: none; }
/* The photo covers the person icon. It needs no fade of its own: the card
   waits for it and then fades in whole (view.js showCard). */
.view-card__photo {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  border-radius: 50%;
  object-fit: cover;
  display: block;
}

/* Now-playing card ------------------------------------------------------- */
.view-card {
  position: absolute; top: 26px; left: 26px; z-index: 6;
  display: flex; align-items: center; gap: 13px;
  max-width: min(520px, 55vw);
  padding: 11px 18px 11px 12px;
  border-radius: var(--r-pill);
  background: rgba(8, 12, 16, 0.72);
  box-shadow: 0 10px 34px -12px rgba(0, 0, 0, 0.9);
  color: #fff;
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
}
/* The transition lives on the shown state, not on the card, so it only plays
   on the way in. Going out - the video ended, was skipped, or the stage went
   idle - the card is simply gone, with no fade trailing over the next video. */
.view-card.is-shown {
  opacity: 1;
  transform: none;
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.view-card[hidden] { display: none; }

.view-card__avatar {
  position: relative;
  flex: none;
  display: grid; place-items: center;
  overflow: hidden;
  width: 38px; height: 38px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
}
.view-card__avatar svg { width: 17px; height: 17px; fill: #fff; opacity: 0.9; }
.view-card__avatar.has-photo svg { opacity: 0; }

.view-card__text { display: grid; gap: 1px; min-width: 0; }
.view-card__title {
  font-size: 17px; font-weight: 800; line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
}
.view-card__channel {
  font-size: 13px; font-weight: 600;
  color: rgba(255, 255, 255, 0.72);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.view-card__channel[hidden] { display: none; }
.view-card__title[hidden] { display: none; }

/* =========================================================================
   Login
   ========================================================================= */
body.login-page { display: grid; place-items: center; min-height: 100vh; }

.login {
  width: 100%;
  padding: 24px;
  display: grid;
  place-items: center;
}

.login__card {
  width: min(400px, 100%);
  display: grid;
  gap: 14px;
  padding: 30px 28px 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
}

.login__brand {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 4px;
}

.login__title {
  font-size: 22px; font-weight: 800; letter-spacing: -0.02em;
  margin-top: 6px;
}
.login__hint { font-size: 13px; color: var(--text-muted); margin-top: -10px; }

.login__error {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 10px 12px;
  border: 1px solid rgba(255, 107, 122, 0.35);
  border-left-width: 3px;
  border-radius: var(--r-md);
  background: var(--danger-soft);
  font-size: 13px;
}
.login__error svg { flex: none; width: 15px; height: 15px; margin-top: 2px; fill: var(--danger); }

.login__submit { width: 100%; height: 40px; margin-top: 4px; }

.login__foot {
  font-size: 11.5px; color: var(--text-dim);
  text-align: center; line-height: 1.5;
}
.login__foot code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px;
  padding: 1px 4px;
  border-radius: 4px;
  background: var(--surface-3);
  color: var(--text-muted);
}
