/* ============================================================================
   VERSUS — Shared component layer
   Linked into every page AFTER tokens.css and BEFORE the page's own CSS, so
   pages can still override. This is where de-duplicated primitives live
   (icons, buttons, toasts, overlays) as the design-system migration proceeds.
   ========================================================================== */

/* ── Icons (data-icon hydration target; see shared/icons.js) ─────────────── */
[data-icon] {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.vsi {
  width: 1em;
  height: 1em;
  flex: 0 0 auto;
  vertical-align: -0.125em;
  /* inherits color via currentColor; size via the host's font-size */
}
/* Icons sitting next to text in a button/label get a touch of breathing room */
button .vsi,
a .vsi,
label .vsi { pointer-events: none; }

/* ── Ghost button (de-duped from the 3 mode stylesheets — P0.1) ───────────────
   Canonical here; the lobby (index.css) keeps its own .btn-ghost variant that
   loads later and overrides this for that page only. */
.btn-ghost {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r);
  color: var(--muted);
  font-family: var(--font-body, 'Rajdhani', sans-serif);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: .08em;
  padding: 6px 13px;
  cursor: pointer;
  transition: all .15s;
  white-space: nowrap;
}
.btn-ghost:hover { border-color: var(--a2); color: var(--a2); }

/* ── Skeletons (loading placeholders; see gauntlet's ghost-cards) ─────────────
   Reusable shimmer bar. Size each instance via width/height (inline or a
   modifier). Generalises gauntlet's .ghost-line so the lobby viewer / any async
   surface can show a skeleton while data lazy-loads (P0.2 + P0.3). */
.skel {
  display: inline-block;
  border-radius: var(--r-xs);
  background: linear-gradient(90deg,
    rgba(255, 255, 255, .05) 0%,
    rgba(255, 255, 255, .10) 50%,
    rgba(255, 255, 255, .05) 100%);
  background-size: 200% 100%;
  animation: vs-skel-shimmer 1.6s ease-in-out infinite;
}
.skel-row td { opacity: .85; }
.skel-row .skel { animation-delay: calc(var(--skel-i, 0) * .12s); }
/* Skeleton set-card (lobby set grid, shown until renderSets replaces it). */
.skel-card { pointer-events: none; }
.skel-card .skel { display: block; margin-left: auto; margin-right: auto; animation-delay: calc(var(--skel-i, 0) * .1s); }
html.vs-reduced-motion .skel { animation: none; opacity: .6; }
@keyframes vs-skel-shimmer {
  0%, 100% { background-position: 200% 0; }
  50%      { background-position: -200% 0; }
}

/* ── X-tier pull flourish (wheel feel; see VSUtils.xPullFlourish) ──────────────
   A brief full-screen multiversal pulse on landing the rarest tier — shared by the
   spinner + auction wheels. Reduced-motion users get the global damp. */
.x-pull-burst {
  position: fixed; inset: 0; z-index: 9998; pointer-events: none;
  background: radial-gradient(circle at center,
    rgba(255, 60, 110, .30), rgba(255, 60, 110, .10) 42%, transparent 72%);
  animation: x-pull-burst .85s ease-out forwards;
}
@keyframes x-pull-burst {
  0%   { opacity: 0; transform: scale(.6); }
  18%  { opacity: 1; }
  100% { opacity: 0; transform: scale(1.3); }
}
