/* VS+ portal design tokens and primitives.
 *
 * One source of truth for surface, text, state, spacing, radius and type across the
 * developer and admin portals. Imported once from index.css.
 *
 * Rules this file holds to:
 *   1. Colour means state. Green, amber and red say live, needs-attention, broken.
 *      Blue means "this is an action". Nothing is coloured for decoration.
 *   2. Radius encodes hierarchy rather than being one flat number: 14px for the single
 *      raised surface on a screen, 10px for panels, 6px for controls.
 *   3. Spacing comes off an 8px scale. Half steps exist only for control padding.
 *   4. Sentence case. No tracked-out caps, no arrows glued onto link text.
 *
 * Everything here is inert until used: the custom properties sit on :root and the
 * primitives are all class-scoped behind a vsp- prefix, so importing this file cannot
 * change the play, advertiser or marketing surfaces that share the bundle.
 */

:root {
  /* ---- Surfaces. A blue-charcoal ground, deliberately lifted off black so panels
     separate by their own value instead of needing a border on everything. ---- */
  --vs-sunk: #0a1017;      /* below ground: the nav rail and page header recede */
  --vs-void: #0d141b;      /* page ground */
  --vs-deck: #16202b;      /* raised surface: panels and cards */
  --vs-deck-hi: #1d2836;   /* hover on a raised surface */
  --vs-rail: #26333f;      /* a border you are meant to see */
  --vs-rail-soft: #1b2734; /* a hairline inside a surface */

  /* ---- Text ---- */
  /* Every value below clears WCAG AA (4.5:1) against --vs-deck, the lightest surface any
     of them sits on. --vs-deck is the worst case; on --vs-void and --vs-sunk they are better. */
  --vs-chalk: #e7edf3;     /* primary, 13.9:1 on deck */
  --vs-dim: #8b9fae;       /* secondary, 6.0:1 on deck */
  --vs-faint: #7d93a4;     /* tertiary, 5.2:1 on deck */

  /* ---- State. Only these carry colour. ---- */
  --vs-on: #35d67f;        /* live, healthy, done: 8.7:1 */
  --vs-warn: #f5a524;      /* needs attention: 8.1:1 */
  --vs-fault: #ff6b6b;     /* broken, destructive: 5.9:1 */

  /* Action blue splits in two because one value cannot both read as text on a dark surface
     and carry white text on top of itself. --vs-act is the ink; --vs-act-fill is the fill. */
  --vs-act: #4a8cf7;       /* action as text, icon, border or focus ring: 5.0:1 on deck */
  --vs-act-fill: #2f6fe0;  /* action as a filled button: white on it is 4.7:1 */
  --vs-act-fill-hi: #2560cc; /* hover darkens rather than lightens, or white would fail */
  --vs-act-ink: #ffffff;

  /* A destructive confirmation is the one place red is a fill. Dark ink on it, because white on
     this red fails contrast, and hover lightens for the same reason. */
  --vs-fault-fill-hi: #ff8484;
  --vs-fault-ink: #26090b;

  --vs-on-wash: rgba(53, 214, 127, 0.1);
  --vs-warn-wash: rgba(245, 165, 36, 0.1);
  --vs-fault-wash: rgba(255, 107, 107, 0.1);
  --vs-act-wash: rgba(74, 140, 247, 0.1);

  /* ---- Radius. Hierarchy, not a single rule. ---- */
  --vs-r-sm: 6px;
  --vs-r-md: 10px;
  --vs-r-lg: 14px;
  --vs-r-pill: 999px;

  /* ---- Space, off an 8px scale ---- */
  --vs-s1: 0.25rem;
  --vs-s2: 0.5rem;
  --vs-s3: 0.75rem;
  --vs-s4: 1rem;
  --vs-s5: 1.5rem;
  --vs-s6: 2rem;
  --vs-s7: 3rem;

  /* ---- Type. Swapping in a webfont is one line here and nowhere else. ---- */
  --vs-font: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --vs-mono: ui-monospace, SFMono-Regular, "Cascadia Mono", Menlo, Consolas, monospace;

  /* ---- Shell metrics ---- */
  --vs-rail-w: 232px;

  --vs-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
}

/* A focus ring that stays visible on every surface: a dark spacer, then the action
   colour. Applied by primitives; reach for it directly on bespoke controls.
   Listed one by one rather than wrapped in :where(), which contributes no specificity and
   would lose `outline: none` to index.css `button:focus-visible`, stacking two rings. */
.vsp-focus:focus-visible,
.vsp-btn:focus-visible,
.vsp-select:focus-visible,
.vsp-seg-btn:focus-visible,
.vsp-menu-item:focus-visible,
.vsp-icon-btn:focus-visible,
.vsp-th-sort:focus-visible,
.vsp-count:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--vs-void), 0 0 0 4px var(--vs-act);
}

.vsp-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------- Buttons */

.vsp-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--vs-s2);
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck);
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 550;
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  white-space: nowrap;
}

/* colour is restated on every hover rule below. Without it the global `a:hover` wins on
   any Link that carries these classes and the label turns Vite-template indigo. */
.vsp-btn:hover:not(:disabled) {
  background: var(--vs-deck-hi);
  border-color: var(--vs-faint);
  color: var(--vs-chalk);
}

.vsp-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.vsp-btn--primary {
  background: var(--vs-act-fill);
  border-color: var(--vs-act-fill);
  color: var(--vs-act-ink);
}

.vsp-btn--primary:hover:not(:disabled) {
  background: var(--vs-act-fill-hi);
  border-color: var(--vs-act-fill-hi);
  color: var(--vs-act-ink);
}

.vsp-btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--vs-dim);
}

.vsp-btn--ghost:hover:not(:disabled) {
  background: var(--vs-deck-hi);
  border-color: transparent;
  color: var(--vs-chalk);
}

.vsp-btn--danger {
  color: var(--vs-fault);
  border-color: transparent;
  background: transparent;
}

.vsp-btn--danger:hover:not(:disabled) {
  background: var(--vs-fault-wash);
  border-color: transparent;
  color: var(--vs-fault);
}

.vsp-btn--sm {
  padding: 0.3rem 0.6rem;
  font-size: 0.8125rem;
}

/* Square button for a lone glyph. Needs an aria-label at the call site. */
.vsp-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck);
  color: var(--vs-dim);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.vsp-icon-btn:hover {
  background: var(--vs-deck-hi);
  border-color: var(--vs-faint);
  color: var(--vs-chalk);
}

/* ---------------------------------------------------------------- Badges and lamps */

.vsp-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.15rem 0.55rem;
  border-radius: var(--vs-r-pill);
  border: 1px solid var(--vs-rail);
  background: var(--vs-deck);
  color: var(--vs-dim);
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.5;
  white-space: nowrap;
}

.vsp-badge--ok {
  color: var(--vs-on);
  border-color: rgba(53, 214, 127, 0.35);
  background: var(--vs-on-wash);
}

.vsp-badge--warn {
  color: var(--vs-warn);
  border-color: rgba(245, 165, 36, 0.35);
  background: var(--vs-warn-wash);
}

.vsp-badge--fault {
  color: var(--vs-fault);
  border-color: rgba(255, 107, 107, 0.35);
  background: var(--vs-fault-wash);
}

/* The state dot. The only thing on a screen allowed to move on its own, and only
   when something really is live right now. */
.vsp-lamp {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.vsp-lamp--on {
  color: var(--vs-on);
  box-shadow: 0 0 0 0 rgba(53, 214, 127, 0.55);
  animation: vsp-pulse 2.4s ease-out infinite;
}

.vsp-lamp--warn { color: var(--vs-warn); }
.vsp-lamp--fault { color: var(--vs-fault); }
.vsp-lamp--idle { color: var(--vs-faint); }

@keyframes vsp-pulse {
  70% { box-shadow: 0 0 0 7px rgba(53, 214, 127, 0); }
  100% { box-shadow: 0 0 0 0 rgba(53, 214, 127, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .vsp-lamp--on { animation: none; }
}

/* ---------------------------------------------------------------- Panels */

.vsp-panel {
  background: var(--vs-deck);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  padding: var(--vs-s5);
  min-width: 0;
}

.vsp-panel-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--vs-s4);
  margin-bottom: var(--vs-s4);
  flex-wrap: wrap;
}

.vsp-panel-title {
  margin: 0;
  font-size: 0.9375rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--vs-chalk);
}

.vsp-panel-sub {
  margin: 0.2rem 0 0;
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

/* ---------------------------------------------------------------- Notices */

.vsp-notice {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  padding: var(--vs-s3) var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-inline-start: 3px solid var(--vs-act);
  border-radius: var(--vs-r-md);
  background: var(--vs-act-wash);
  font-size: 0.875rem;
  color: var(--vs-chalk);
}

.vsp-notice--warn {
  border-inline-start-color: var(--vs-warn);
  background: var(--vs-warn-wash);
}

.vsp-notice--fault {
  border-inline-start-color: var(--vs-fault);
  background: var(--vs-fault-wash);
}

.vsp-notice--ok {
  border-inline-start-color: var(--vs-on);
  background: var(--vs-on-wash);
}

/* ---------------------------------------------------------------- Selects */

/* color-scheme is what makes the native option list render dark on Windows and Linux.
   Without it the popup is white regardless of what the closed control looks like. */
.vsp-select {
  color-scheme: dark;
  appearance: none;
  padding-block: 0.4rem;
  padding-inline: 0.7rem 2rem;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-sm);
  background-color: var(--vs-deck);
  background-image: linear-gradient(45deg, transparent 50%, var(--vs-dim) 50%),
    linear-gradient(135deg, var(--vs-dim) 50%, transparent 50%);
  background-position: calc(100% - 15px) center, calc(100% - 10px) center;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.875rem;
  cursor: pointer;
  max-width: 100%;
}

/* background-position has no logical form, so the arrow is placed by hand in RTL. The
   padding above already flips on its own. */
[dir='rtl'] .vsp-select {
  background-position: 15px center, 10px center;
  background-image: linear-gradient(135deg, transparent 50%, var(--vs-dim) 50%),
    linear-gradient(45deg, var(--vs-dim) 50%, transparent 50%);
}

.vsp-select:hover {
  border-color: var(--vs-faint);
}

/* For a select that sits inside a section head next to a heading, not on its own. */
.vsp-select--sm {
  padding-block: 0.25rem;
  font-size: 0.8125rem;
  max-width: 11rem;
}

/* ---------------------------------------------------------------- Segmented control */

.vsp-seg {
  display: inline-flex;
  padding: 2px;
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-sm);
  background: var(--vs-void);
}

.vsp-seg-btn {
  padding: 0.25rem 0.7rem;
  border: none;
  border-radius: 4px;
  background: transparent;
  color: var(--vs-dim);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 550;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.vsp-seg-btn:hover {
  color: var(--vs-chalk);
}

.vsp-seg-btn[aria-pressed='true'] {
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
}

/* ---------------------------------------------------------------- Overflow menu */

.vsp-menu-wrap {
  position: relative;
}

.vsp-menu {
  position: absolute;
  inset-inline-end: 0;
  top: calc(100% + 6px);
  z-index: 40;
  min-width: 13rem;
  padding: var(--vs-s1);
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
}

.vsp-menu-item {
  display: block;
  width: 100%;
  padding: 0.5rem 0.65rem;
  border: none;
  border-radius: var(--vs-r-sm);
  background: transparent;
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.875rem;
  text-align: start;
  text-decoration: none;
  cursor: pointer;
}

.vsp-menu-item:hover:not(:disabled) {
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
}

.vsp-menu-item:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.vsp-menu-item--danger {
  color: var(--vs-fault);
}

.vsp-menu-item--danger:hover:not(:disabled) {
  background: var(--vs-fault-wash);
  color: var(--vs-fault);
}

.vsp-menu-note {
  padding: 0.35rem 0.65rem 0.5rem;
  margin: 0;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--vs-faint);
}

.vsp-menu-sep {
  height: 1px;
  margin: var(--vs-s1) 0;
  background: var(--vs-rail-soft);
  border: none;
}

/* ---------------------------------------------------------------- Tables */

.vsp-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
  font-variant-numeric: tabular-nums;
}

.vsp-table th,
.vsp-table td {
  padding: 0.55rem 0.75rem;
  text-align: start;
  border-bottom: 1px solid var(--vs-rail-soft);
}

.vsp-table thead th {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--vs-dim);
  border-bottom-color: var(--vs-rail);
}

.vsp-table tbody tr:last-child :is(th, td) {
  border-bottom: none;
}

.vsp-table tbody tr:hover {
  background: var(--vs-deck-hi);
}

/* Numbers right-align so digits stack in a column and the eye can compare down it. */
.vsp-table :is(th, td).vsp-num {
  text-align: end;
}

.vsp-table th[scope='row'] {
  font-weight: 550;
  color: var(--vs-chalk);
}

/* Horizontal overflow clips vertically as well, so leave room for a focus ring on
   anything interactive inside and pull the space back out of the layout. */
.vsp-scroll-x {
  overflow-x: auto;
  margin-inline: calc(var(--vs-s2) * -1);
  padding-inline: var(--vs-s2);
  margin-block: -4px;
  padding-block: 4px;
}

/* A sortable column head: a real <button> inside <th aria-sort>, so the header stays a
   header to a screen reader and the sort is reachable by keyboard. It reads as the header
   text, not as a button. Every box property the index.css button defaults touch is
   restated here, because those defaults would otherwise draw a grey pill in the thead.
   The chevron only shows on the active column; elsewhere it keeps its space so the label
   does not jump when the sort moves. */
.vsp-th-sort {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  margin: 0;
  padding: 0.1rem 0.2rem;
  margin-inline: -0.2rem;
  border: 1px solid transparent;
  border-radius: 4px;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: start;
  white-space: nowrap;
  cursor: pointer;
}

.vsp-th-sort:hover {
  background: transparent;
  border-color: transparent;
  color: var(--vs-chalk);
}

.vsp-th-sort-icon {
  flex: none;
  opacity: 0;
  transition: transform 0.15s, opacity 0.15s;
}

.vsp-th-sort:hover .vsp-th-sort-icon {
  opacity: 0.5;
}

.vsp-table th[aria-sort='ascending'],
.vsp-table th[aria-sort='descending'] {
  color: var(--vs-chalk);
}

th[aria-sort='ascending'] .vsp-th-sort-icon,
th[aria-sort='descending'] .vsp-th-sort-icon {
  opacity: 1;
}

th[aria-sort='ascending'] .vsp-th-sort-icon {
  transform: rotate(180deg);
}

.vsp-table :is(th, td).vsp-num .vsp-th-sort {
  flex-direction: row-reverse;
}

@media (prefers-reduced-motion: reduce) {
  .vsp-th-sort-icon { transition: none; }
}

/* ---------------------------------------------------------------- Pager */

/* Where the reader is on the left, the way to move on the right. The buttons are vsp-btn
   --sm; the pager only lays them out. */
.vsp-pager {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s2) var(--vs-s4);
  flex-wrap: wrap;
  font-size: 0.8125rem;
  color: var(--vs-dim);
  font-variant-numeric: tabular-nums;
}

.vsp-pager-status {
  margin: 0;
}

.vsp-pager-controls {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
}

.vsp-pager-page {
  padding-inline: var(--vs-s1);
  white-space: nowrap;
}

/* ---------------------------------------------------------------- Search */

/* A compact search box for a toolbar, sized to sit on one line with vsp-select--sm rather
   than the 44px form field. The glyph is decoration; the accessible name comes from a
   vsp-sr label at the call site. */
.vsp-search {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  min-width: 0;
}

.vsp-search-icon {
  position: absolute;
  inset-inline-start: 0.6rem;
  color: var(--vs-faint);
  pointer-events: none;
}

.vsp-search-input {
  width: 100%;
  min-height: 2rem;
  box-sizing: border-box;
  padding-block: 0.3rem;
  padding-inline: 2rem 0.7rem;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-sm);
  background: var(--vs-void);
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.8125rem;
  color-scheme: dark;
}

.vsp-search-input::placeholder {
  color: var(--vs-faint);
}

.vsp-search-input:hover {
  border-color: var(--vs-faint);
}

.vsp-search-input:focus {
  outline: none;
  border-color: var(--vs-act);
  box-shadow: 0 0 0 3px var(--vs-act-wash);
}

/* ---------------------------------------------------------------- Count chip */

/* A number with its label that doubles as a one-click filter. It is a toggle, so it takes
   aria-pressed, and the pressed state is drawn in action blue because choosing it is the
   action; the number itself never carries state colour. */
.vsp-count {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.15rem;
  min-width: 0;
  margin: 0;
  padding: var(--vs-s3) var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  color: var(--vs-chalk);
  font: inherit;
  text-align: start;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

.vsp-count:hover:not(:disabled) {
  background: var(--vs-deck-hi);
  border-color: var(--vs-faint);
  color: var(--vs-chalk);
}

.vsp-count[aria-pressed='true'] {
  border-color: var(--vs-act);
  background: var(--vs-act-wash);
}

.vsp-count[aria-pressed='true']:hover:not(:disabled) {
  background: var(--vs-act-wash);
  border-color: var(--vs-act);
  color: var(--vs-chalk);
}

/* Disabled only while there is nothing to count yet, so it stays at full strength rather
   than greying out a strip that is about to fill in. */
.vsp-count:disabled {
  cursor: default;
}

.vsp-count-value {
  font-size: 1.375rem;
  font-weight: 650;
  line-height: 1.15;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}

.vsp-count-label {
  font-size: 0.8125rem;
  font-weight: 550;
  color: var(--vs-dim);
}

.vsp-count-hint {
  font-size: 0.75rem;
  color: var(--vs-faint);
}

/* ---------------------------------------------------------------- Misc */

.vsp-code {
  font-family: var(--vs-mono);
  font-size: 0.8125rem;
  color: var(--vs-chalk);
}

.vsp-muted {
  color: var(--vs-dim);
}

.vsp-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--vs-s2);
  padding: var(--vs-s6) var(--vs-s4);
  text-align: center;
  color: var(--vs-dim);
  font-size: 0.875rem;
}

.vsp-empty-title {
  color: var(--vs-chalk);
  font-size: 0.9375rem;
  font-weight: 600;
}

/* ---------------------------------------------------------------- Forms
 *
 * One field shape for the whole portal. A control is 44px tall, sits on a surface one
 * step darker than the panel behind it so it reads as somewhere to type, and carries its
 * label above and its explanation below.
 */

.vsp-field {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.vsp-label {
  display: flex;
  /* Explicit: App.css sets `form label { flex-direction: column }` on the bare element,
     which a class that only declares `display: flex` does not override. */
  flex-direction: row;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8125rem;
  font-weight: 550;
  color: var(--vs-chalk);
}

.vsp-label-optional {
  font-weight: 400;
  color: var(--vs-faint);
}

.vsp-hint {
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--vs-dim);
  max-width: 66ch;
}

.vsp-error {
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.5;
  color: var(--vs-fault);
}

.vsp-input,
.vsp-textarea {
  width: 100%;
  min-height: 44px;
  padding: 0.55rem 0.75rem;
  box-sizing: border-box;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-sm);
  /* One step darker than the panel, not black. */
  background: var(--vs-void);
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.9375rem;
  color-scheme: dark;
}

.vsp-textarea {
  min-height: 8rem;
  font-family: var(--vs-mono);
  font-size: 0.8125rem;
  line-height: 1.6;
  resize: vertical;
}

.vsp-input::placeholder,
.vsp-textarea::placeholder {
  color: var(--vs-faint);
}

.vsp-input:hover,
.vsp-textarea:hover {
  border-color: var(--vs-faint);
}

.vsp-input:focus,
.vsp-textarea:focus {
  outline: none;
  border-color: var(--vs-act);
  box-shadow: 0 0 0 3px var(--vs-act-wash);
}

.vsp-input[aria-invalid='true'],
.vsp-textarea[aria-invalid='true'] {
  border-color: var(--vs-fault);
}

/* The select primitive already exists above; this matches its metrics to the inputs. */
.vsp-select--field {
  width: 100%;
  min-height: 44px;
  background-color: var(--vs-void);
  font-size: 0.9375rem;
}

/* Two fields that belong together, on one row until there is no room. */
.vsp-form-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--vs-s4);
}

@media (max-width: 560px) {
  .vsp-form-row {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ---- Toggle ---- */

.vsp-switch {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--vs-s3);
  cursor: pointer;
}

.vsp-switch input {
  appearance: none;
  flex: none;
  width: 38px;
  height: 22px;
  margin: 0;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-pill);
  background: var(--vs-void);
  cursor: pointer;
  position: relative;
  transition: background 0.15s, border-color 0.15s;
}

.vsp-switch input::after {
  content: '';
  position: absolute;
  top: 2px;
  inset-inline-start: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--vs-dim);
  transition: transform 0.15s, background 0.15s;
}

.vsp-switch input:checked {
  background: var(--vs-act-fill);
  border-color: var(--vs-act-fill);
}

.vsp-switch input:checked::after {
  background: #fff;
  transform: translateX(16px);
}

[dir='rtl'] .vsp-switch input:checked::after {
  transform: translateX(-16px);
}

.vsp-switch input:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--vs-deck), 0 0 0 4px var(--vs-act);
}

.vsp-switch-text {
  font-size: 0.875rem;
  font-weight: 550;
  color: var(--vs-chalk);
}

@media (prefers-reduced-motion: reduce) {
  .vsp-switch input,
  .vsp-switch input::after {
    transition: none;
  }
}

/* ---- Selection cards: a radio group that shows what each option means ---- */

.vsp-choices {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--vs-s2);
}

.vsp-choice {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: var(--vs-s3);
  padding: var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-void);
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}

.vsp-choice:hover {
  border-color: var(--vs-faint);
}

.vsp-choice input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.vsp-choice:has(input:checked) {
  border-color: var(--vs-act);
  background: var(--vs-act-wash);
}

.vsp-choice:has(input:focus-visible) {
  box-shadow: 0 0 0 2px var(--vs-deck), 0 0 0 4px var(--vs-act);
}

.vsp-choice-mark {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck-hi);
  color: var(--vs-dim);
}

.vsp-choice:has(input:checked) .vsp-choice-mark {
  background: var(--vs-act);
  color: var(--vs-act-ink);
}

.vsp-choice-body {
  min-width: 0;
}

.vsp-choice-title {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--vs-chalk);
}

.vsp-choice-why {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--vs-dim);
}

/* ---- Sticky action bar ---- */

.vsp-actionbar {
  position: sticky;
  bottom: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--vs-s2);
  padding: var(--vs-s3) var(--vs-s4);
  margin-top: var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.35);
  flex-wrap: wrap;
}

.vsp-actionbar-msg {
  margin: 0;
  margin-inline-end: auto;
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

.vsp-actionbar-msg--error {
  color: var(--vs-fault);
}

/* ================================================================ Admin page pattern
 *
 * The frame every admin page shares, top to bottom:
 *   1. breadcrumbs, on detail pages only
 *   2. a head: one h1 that matches the nav label, one line saying what the page is for, and
 *      at most one primary button
 *   3. notices
 *   4. optional summary chips (vsp-count), each applying one filter
 *   5. tabs, held in the URL
 *   6. panels, each a toolbar, a table and a pager
 * The React side lives in src/components/admin. Page stylesheets only lay these out.
 */

.vsp-page {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s5);
  min-width: 0;
  color: var(--vs-chalk);
  font-family: var(--vs-font);
}

/* A column of things inside a panel: toolbar, table, pager. */
.vsp-stack {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
  min-width: 0;
}

/* ---------------------------------------------------------------- Page head */

.vsp-page-head {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s3);
}

.vsp-page-head-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--vs-s3) var(--vs-s4);
  flex-wrap: wrap;
}

.vsp-page-head-text {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s1);
  min-width: 0;
}

.vsp-page-title-row {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  flex-wrap: wrap;
  min-width: 0;
}

.vsp-page-title {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 650;
  line-height: 1.2;
  letter-spacing: -0.02em;
  color: var(--vs-chalk);
  overflow-wrap: anywhere;
}

.vsp-page-sub {
  margin: 0;
  max-width: 72ch;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--vs-dim);
}

.vsp-page-actions {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------- Breadcrumbs */

.vsp-crumbs {
  display: flex;
  align-items: center;
  gap: var(--vs-s1);
  flex-wrap: wrap;
  color: var(--vs-faint);
  font-size: 0.8125rem;
}

.vsp-crumbs-item {
  display: inline-flex;
  align-items: center;
  gap: var(--vs-s1);
}

.vsp-crumb {
  color: var(--vs-dim);
  text-decoration: none;
  border-radius: 4px;
}

a.vsp-crumb:hover {
  color: var(--vs-chalk);
  text-decoration: underline;
}

.vsp-crumb[aria-current='page'] {
  color: var(--vs-chalk);
  font-weight: 550;
}

/* ---------------------------------------------------------------- Tabs */

/* A rule that runs the full content width, with the active tab sitting on it. Tabs are links,
   so each one has an address and the back button walks through them. */
.vsp-tabs-scroll {
  overflow-x: auto;
  border-bottom: 1px solid var(--vs-rail-soft);
  scrollbar-width: thin;
}

.vsp-tabs {
  display: flex;
  gap: var(--vs-s1);
  min-width: max-content;
}

.vsp-tab {
  display: inline-flex;
  align-items: center;
  gap: var(--vs-s2);
  padding: 0.55rem var(--vs-s3);
  border-bottom: 2px solid transparent;
  color: var(--vs-dim);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  transition: color 0.15s, border-color 0.15s;
}

.vsp-tab:hover {
  color: var(--vs-chalk);
}

/* The strip scrolls horizontally, and overflow clips vertically too, so an outset ring would be
   cut off at the top and bottom. This one sits inside the tab. */
.vsp-tab:focus-visible {
  outline: 2px solid var(--vs-act);
  outline-offset: -3px;
  border-radius: var(--vs-r-sm) var(--vs-r-sm) 0 0;
}

.vsp-tab[aria-current='page'],
.vsp-tab.vsp-tab--active {
  color: var(--vs-chalk);
  border-bottom-color: var(--vs-act);
}

/* How many things in a tab need staff. A number, not a state, so it stays neutral. */
.vsp-tab-count {
  min-width: 1.25rem;
  padding: 0 0.35rem;
  border-radius: var(--vs-r-pill);
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
  font-size: 0.6875rem;
  font-weight: 650;
  line-height: 1.25rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .vsp-tab { transition: none; }
}

/* ---------------------------------------------------------------- Toolbar */

/* Search and filters on the left, the result count and Clear on the right. Wraps to as many
   lines as it needs rather than squeezing controls. */
.vsp-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s2) var(--vs-s4);
  flex-wrap: wrap;
}

.vsp-toolbar-group {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
  min-width: 0;
}

.vsp-toolbar-group--grow {
  flex: 1 1 24rem;
}

.vsp-toolbar .vsp-search {
  flex: 1 1 14rem;
  max-width: 22rem;
}

.vsp-toolbar-count {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--vs-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ---------------------------------------------------------------- Summary chips */

/* Four across, two by two on narrow screens, so the chips never leave one stranded on its own row. A page with a
   different number of chips sets --vsp-summary-columns. */
.vsp-summary {
  display: grid;
  grid-template-columns: repeat(var(--vsp-summary-columns, 4), minmax(0, 1fr));
  gap: var(--vs-s3);
}

@media (max-width: 760px) {
  .vsp-summary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ---------------------------------------------------------------- Notices, continued */

/* The text beside a notice's icon, taking the room so a trailing Retry sits at the end. */
.vsp-notice-text {
  flex: 1;
  min-width: 0;
  line-height: 1.45;
}

.vsp-notice > svg {
  flex: none;
}

/* ---------------------------------------------------------------- Badges, continued */

/* Finished without effect: void, cancelled, declined, archived. Present, but nothing to do. */
.vsp-badge--quiet {
  color: var(--vs-faint);
  border-color: var(--vs-rail-soft);
  background: transparent;
}

/* ---------------------------------------------------------------- Dialog */

/* One confirmation shape for the whole portal, on a native <dialog> opened with showModal, so
   focus is trapped and returned by the browser. It names the action, the object and any amount.
   Cancel comes first, and a server refusal shows inside the dialog rather than behind it. */
.vsp-dialog {
  box-sizing: border-box;
  width: min(30rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem);
  max-height: calc(100dvh - 2rem);
  overflow: auto;
  padding: var(--vs-s5);
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-lg);
  background: var(--vs-deck);
  color: var(--vs-chalk);
  font-family: var(--vs-font);
  box-shadow: 0 16px 48px rgba(0, 0, 0, 0.6);
}

.vsp-dialog::backdrop {
  background: rgba(0, 0, 0, 0.6);
}

.vsp-dialog-title {
  margin: 0 0 var(--vs-s2);
  font-size: 1.0625rem;
  font-weight: 650;
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--vs-chalk);
  overflow-wrap: anywhere;
}

.vsp-dialog-form {
  display: block;
  max-width: none;
}

/* margin is reset because the class also goes on a single <p>. */
.vsp-dialog-body {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--vs-dim);
  overflow-wrap: anywhere;
}

.vsp-dialog-body p {
  margin: 0 0 var(--vs-s2);
}

.vsp-dialog-body > :last-child {
  margin-bottom: 0;
}

.vsp-dialog-body strong {
  color: var(--vs-chalk);
  font-weight: 600;
}

.vsp-dialog-fields {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
  margin-top: var(--vs-s4);
}

.vsp-dialog-error {
  margin-top: var(--vs-s4);
}

.vsp-dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--vs-s2);
  flex-wrap: wrap;
  margin-top: var(--vs-s5);
}

.vsp-btn--danger-fill {
  background: var(--vs-fault);
  border-color: var(--vs-fault);
  color: var(--vs-fault-ink);
  font-weight: 650;
}

.vsp-btn--danger-fill:hover:not(:disabled) {
  background: var(--vs-fault-fill-hi);
  border-color: var(--vs-fault-fill-hi);
  color: var(--vs-fault-ink);
}

/* ---------------------------------------------------------------- Forms, continued */

/* A textarea for words rather than code: a reason, a note, a reply. */
.vsp-textarea.vsp-textarea--prose {
  min-height: 5rem;
  font-family: inherit;
  font-size: 0.9375rem;
  line-height: 1.5;
}

.vsp-checkbox {
  display: flex;
  /* Restated: App.css sets `form label { flex-direction: column }` on the bare element. */
  flex-direction: row;
  align-items: flex-start;
  gap: var(--vs-s2);
  font-size: 0.875rem;
  color: var(--vs-chalk);
  cursor: pointer;
}

.vsp-checkbox input {
  flex: none;
  width: 1rem;
  height: 1rem;
  margin: 0.15rem 0 0;
  accent-color: var(--vs-act-fill);
  color-scheme: dark;
  cursor: pointer;
}

.vsp-checkbox input:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--vs-deck), 0 0 0 4px var(--vs-act);
}

/* Fields laid out in a responsive grid inside a panel or a dialog. */
.vsp-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--vs-s4);
  align-items: start;
}

.vsp-form-actions {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------- Tables, continued */

.vsp-table {
  transition: opacity 0.15s;
}

/* Reloading in place: the old rows stay readable but plainly out of date. */
.vsp-table.vsp-table--busy {
  opacity: 0.6;
}

/* The last column: one visible action, then a More menu if there are others. */
.vsp-table :is(th, td).vsp-actions-cell {
  width: 1%;
  text-align: end;
  white-space: nowrap;
}

.vsp-table-actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--vs-s1);
}

/* A second line under a cell's main value: an id, a date, a failure reason. */
.vsp-table-sub {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.75rem;
  color: var(--vs-faint);
}

/* A total row under a money column. */
.vsp-table tfoot :is(th, td) {
  border-top: 1px solid var(--vs-rail);
  border-bottom: none;
  font-weight: 600;
  color: var(--vs-chalk);
}

@media (prefers-reduced-motion: reduce) {
  .vsp-table { transition: none; }
}

/* ---------------------------------------------------------------- Key and value list */

.vsp-kv {
  display: grid;
  grid-template-columns: minmax(8rem, max-content) minmax(0, 1fr);
  gap: var(--vs-s2) var(--vs-s4);
  margin: 0;
  font-size: 0.875rem;
}

.vsp-kv dt {
  color: var(--vs-dim);
}

.vsp-kv dd {
  margin: 0;
  color: var(--vs-chalk);
  overflow-wrap: anywhere;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 560px) {
  .vsp-kv {
    grid-template-columns: minmax(0, 1fr);
    gap: 0.1rem;
  }

  .vsp-kv dd {
    margin-bottom: var(--vs-s2);
  }
}

/* ---------------------------------------------------------------- Thumbnail */

/* A small square image or its initials. The caller sets the size inline. */
.vsp-thumb {
  display: grid;
  place-items: center;
  flex: none;
  overflow: hidden;
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
  font-size: 0.6875rem;
  font-weight: 650;
}

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

/* ---------------------------------------------------------------- Toast */

/* A brief confirmation that needs no answer, such as "Copied". Anything staff must read belongs
   in a notice instead, because a toast disappears. */
.vsp-toast {
  position: fixed;
  inset-block-end: var(--vs-s5);
  inset-inline-start: 50%;
  transform: translateX(-50%);
  z-index: 70;
  margin: 0;
  padding: var(--vs-s2) var(--vs-s4);
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
  font-size: 0.8125rem;
  color: var(--vs-chalk);
  pointer-events: none;
}

[dir='rtl'] .vsp-toast {
  transform: translateX(50%);
}
/* Arabic: prefer fonts with full Arabic coverage; falls back to the system stack elsewhere. */
:root[lang="ar"],
:root[lang="ar"] body {
  font-family: "Segoe UI", Tahoma, "Noto Sans Arabic", "Noto Naskh Arabic", "Geeza Pro", system-ui, sans-serif;
}

:root {
  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;
  color-scheme: dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #000;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* :where() keeps these Vite starter defaults for elements nothing else styles, while
   giving them zero specificity so any class rule wins. Before this, `a:hover` at (0,1,1)
   beat `.vsp-btn` at (0,1,0) and turned button labels indigo on hover. */
/* Sixty-two links across the portal have no other text-decoration source, so this is
   what keeps them from being underlined. Nineteen depend on the colour. */
:where(a) {
  font-weight: 500;
  color: var(--vs-act);
  text-decoration: inherit;
}
:where(a:hover) {
  color: var(--vs-chalk);
}

body {
  margin: 0;
  min-width: 320px;
  min-height: 100vh;
  background: #000;
}

:where(h1) {
  font-size: 3.2em;
  line-height: 1.1;
}

:where(button) {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.25s;
}
/* 270 of 318 buttons declare no hover border of their own, so every one of them was
   flashing the Vite template indigo. */
:where(button:hover) {
  border-color: var(--vs-faint);
}

/* 275 of 318 buttons have no focus ring of their own, which is why the starter rule could
   not simply be deleted. This is the same ring the vsp- primitives draw, so keyboard
   focus is visible everywhere rather than only on the redesigned screens. The primitives
   set `outline: none` at higher specificity and draw their own, so nothing doubles up. */
:where(button:focus-visible) {
  outline: 2px solid var(--vs-act);
  outline-offset: 2px;
}

/* Portal is always dark; ignore light scheme so no white flash */
.adv-layout { min-height: 100vh; background: #0b0b12; color: #e8e8ef; }
.adv-bar { display: flex; align-items: center; gap: 1rem; padding: 0.6rem 1.25rem; background: #12121b; border-bottom: 1px solid #23232f; flex-wrap: wrap; }
.adv-logo, .adv-logo-link img { height: 28px; }
.adv-portal-tag { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: #b4a7ff; background: #241f4a; padding: 0.15rem 0.5rem; border-radius: 999px; }
.adv-account-select { background: #0e0e15; border: 1px solid #2a2a38; color: #e8e8ef; border-radius: 6px; padding: 0.35rem 0.5rem; }
.adv-account-name { font-weight: 600; }
.adv-nav { display: flex; gap: 0.25rem; margin-left: 1rem; flex-wrap: wrap; }
.adv-nav-link { color: #a8a8b8; text-decoration: none; padding: 0.4rem 0.7rem; border-radius: 6px; font-size: 0.92rem; }
.adv-nav-link--active, .adv-nav-link:hover { color: #fff; background: #1d1d2a; }
.adv-user { margin-left: auto; display: flex; align-items: center; gap: 0.75rem; }
.adv-balance { font-weight: 700; color: #9be7b4; }
.adv-user-name { color: #c8c8d4; font-size: 0.9rem; }
.adv-logout { background: none; border: 1px solid #2a2a38; color: #c8c8d4; border-radius: 6px; padding: 0.35rem 0.7rem; cursor: pointer; }
.adv-badge { font-size: 0.72rem; text-transform: uppercase; padding: 0.15rem 0.5rem; border-radius: 999px; }
.adv-badge--active { background: #16331f; color: #9be7b4; }
.adv-badge--pending { background: #33301a; color: #e7d79b; }
.adv-badge--suspended { background: #3a1620; color: #f3a7b6; }

.adv-main { padding: 1.5rem; max-width: 1100px; margin: 0 auto; }
.adv-muted { color: #8a8a98; }
.adv-error { background: #3a1620; border: 1px solid #a83a4f; color: #f3a7b6; padding: 0.6rem 0.8rem; border-radius: 6px; margin-bottom: 1rem; }
.adv-notice { background: #33301a; border: 1px solid #6b5e2e; color: #e7d79b; padding: 0.6rem 0.8rem; border-radius: 6px; margin-bottom: 1rem; }
.adv-onboard { max-width: 520px; margin: 3rem auto; text-align: center; }
.adv-onboard h1 { margin-bottom: 0.5rem; }

.adv-btn { display: inline-block; background: #6c5ce7; color: #fff; border: none; border-radius: 6px; padding: 0.55rem 1rem; cursor: pointer; text-decoration: none; font-size: 0.95rem; }
.adv-btn:disabled { opacity: 0.5; cursor: default; }
.adv-link-btn { background: none; border: none; color: #9b8cff; cursor: pointer; padding: 0.2rem 0.4rem; }

/* Cards / sections */
.adv-section { background: #14141d; border: 1px solid #23232f; border-radius: 10px; padding: 1.25rem; margin-bottom: 1.25rem; }
.adv-section h2 { margin: 0 0 0.75rem; font-size: 1.15rem; }
.adv-stat-row { display: flex; gap: 2rem; flex-wrap: wrap; }
.adv-stat { display: flex; flex-direction: column; }
.adv-stat-value { font-size: 1.8rem; font-weight: 700; }
.adv-stat-label { color: #9a9aa8; font-size: 0.85rem; }

.adv-table { width: 100%; border-collapse: collapse; }
.adv-table th, .adv-table td { text-align: left; padding: 0.55rem 0.6rem; border-bottom: 1px solid #23232f; font-size: 0.9rem; }
.adv-table th { color: #9a9aa8; }
.adv-num { text-align: right; }
.adv-empty { color: #8a8a98; font-style: italic; padding: 0.75rem 0; }

/* Forms */
.adv-form { max-width: 560px; }
.adv-fr { display: flex; flex-direction: column; gap: 0.3rem; margin-bottom: 0.8rem; }
.adv-fr label { font-size: 0.85rem; color: #c8c8d4; }
.adv-fr input, .adv-fr select, .adv-fr textarea { background: #0e0e15; border: 1px solid #2a2a38; color: #e8e8ef; border-radius: 6px; padding: 0.5rem; font-size: 0.9rem; }
.adv-form-actions { display: flex; gap: 0.75rem; align-items: center; margin-top: 0.5rem; }
.adv-form-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem; }
/* Developer portal login — centered, full-width dark background */

.dev-login {
  --vs-primary: #0066ff;
  --vs-primary-hover: #0052cc;
  --vs-primary-focus: rgba(0, 102, 255, 0.3);
  --vs-link: #3b82f6;
  --vs-text: #f1f5f9;
  --vs-text-muted: #94a3b8;
  --vs-border: #334155;

  position: fixed;
  inset: 0;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  box-sizing: border-box;
}

.dev-login-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 400px;
}

.dev-login-brand {
  text-align: center;
  margin-bottom: 1.75rem;
}

.dev-login-logo {
  max-width: 100px;
  height: auto;
  margin-bottom: 1rem;
}

.dev-login-title {
  margin: 0 0 0.5rem;
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-login-subtitle {
  margin: 0;
  font-size: 0.95rem;
  color: var(--vs-text-muted);
  font-weight: 400;
}

.dev-login-form-wrap {
  width: 100%;
}

.dev-login-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.dev-login-label {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--vs-text);
}

.dev-login-input {
  width: 100%;
  padding: 0.65rem 0.9rem;
  box-sizing: border-box;
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  font-size: 0.95rem;
  color: var(--vs-text);
  background: #111;
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.dev-login-input::placeholder {
  color: var(--vs-text-muted);
}

.dev-login-input:focus {
  border-color: var(--vs-primary);
  box-shadow: 0 0 0 2px var(--vs-primary-focus);
}

.dev-login-password-wrap {
  position: relative;
  display: block;
}

.dev-login-password-wrap .dev-login-input {
  padding-right: 2.5rem;
}

.dev-login-password-toggle {
  position: absolute;
  top: 50%;
  right: 10px;
  transform: translateY(-50%);
  padding: 4px;
  background: none;
  border: none;
  color: var(--vs-text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  line-height: 0;
}

.dev-login-password-toggle:hover {
  color: var(--vs-text);
}

.dev-login-error {
  margin: 0;
  font-size: 0.875rem;
  color: #f87171;
}

.dev-login-btn {
  width: 100%;
  padding: 0.75rem 1.25rem;
  margin-top: 0.25rem;
  background: var(--vs-primary);
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
}

.dev-login-btn:hover:not(:disabled) {
  background: var(--vs-primary-hover);
}

.dev-login-btn:disabled {
  opacity: 0.7;
  cursor: not-allowed;
}

.dev-login-footer {
  margin: 1.5rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--vs-border);
  text-align: center;
  font-size: 0.9rem;
  color: var(--vs-text-muted);
}

.dev-login-footer a {
  color: var(--vs-link);
  font-weight: 500;
  text-decoration: none;
}

.dev-login-footer a:hover {
  text-decoration: underline;
}
/* Gaming-themed login — for gamer app. See Login.tsx for developer portal. */

.gamer-login-screen {
  position: fixed;
  inset: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  box-sizing: border-box;
  overflow: auto;
}

.gamer-login-bg {
  position: absolute;
  inset: 0;
  background: url('/images/Login%20Background.png') center center / cover no-repeat;
  z-index: 0;
}

.gamer-login-overlay {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.75) 50%, rgba(0, 0, 0, 0.9) 100%);
  z-index: 1;
}

.gamer-login-content {
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: 380px;
  text-align: center;
}

.gamer-login-brand {
  margin-bottom: 2rem;
}

.gamer-login-logo {
  max-width: 140px;
  height: auto;
  display: block;
  margin: 0 auto 0.5rem;
}

.gamer-login-tagline {
  margin: 0;
  color: rgba(255, 255, 255, 0.95);
  font-size: 0.95rem;
  font-weight: 400;
}

.gamer-login-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  text-align: start;
}

.gamer-login-label {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  cursor: text;
}

.gamer-login-label-text {
  color: #fff;
  font-size: 0.9rem;
  font-weight: 500;
}

.gamer-login-input-wrap {
  position: relative;
  display: block;
}

.gamer-login-input {
  width: 100%;
  padding-block: 0.85rem;
  padding-inline: 1rem 3rem;
  box-sizing: border-box;
  background: rgba(40, 44, 52, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 10px;
  color: #fff;
  font-size: 1rem;
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.gamer-login-input::placeholder {
  color: rgba(255, 255, 255, 0.4);
}

.gamer-login-input:focus {
  border-color: rgba(100, 150, 255, 0.6);
  box-shadow: 0 0 0 2px rgba(100, 150, 255, 0.2);
}

.gamer-login-input-icon {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  inset-inline-end: 12px;
  color: rgba(255, 255, 255, 0.7);
  pointer-events: none;
  display: flex;
  align-items: center;
  gap: 6px;
}

.gamer-login-input-icon--right {
  pointer-events: auto;
}

.gamer-login-password-toggle {
  background: none;
  border: none;
  padding: 4px;
  cursor: pointer;
  color: inherit;
  display: flex;
  align-items: center;
  line-height: 0;
}

.gamer-login-password-toggle:hover {
  color: #fff;
}

.gamer-login-error {
  margin: 0;
  color: #ff6b6b;
  font-size: 0.9rem;
}

.gamer-login-btn {
  width: 100%;
  padding: 1rem 1.5rem;
  margin-top: 0.25rem;
  background: #3b82f6;
  color: #fff;
  border: none;
  border-radius: 10px;
  font-size: 1.05rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
}

.gamer-login-btn:hover:not(:disabled) {
  background: #2563eb;
}

.gamer-login-btn:disabled {
  opacity: 0.7;
  cursor: not-allowed;
}

.gamer-login-footer {
  margin: 1.5rem 0 0;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.95rem;
}

.gamer-login-footer a {
  color: #fff;
  font-weight: 500;
  text-decoration: none;
}

.gamer-login-footer a:hover {
  text-decoration: underline;
}

/* Language picker on the sign-in screen */
.gamer-login-lang { display: flex; justify-content: flex-end; gap: 6px; margin-bottom: 8px; }
.gamer-login-lang-btn { padding: 4px 10px; border-radius: 999px; border: 1px solid rgba(255,255,255,0.25); background: transparent; color: rgba(255,255,255,0.8); font-size: 0.8rem; cursor: pointer; }
.gamer-login-lang-btn--active { background: rgba(255,255,255,0.18); color: #fff; font-weight: 600; }
/* Password reset and email verification screens. They sit inside the existing sign-in frames
   (Login.css and LoginGamer.css); this file only adds what those screens did not need. */

.recovery-brand {
  margin-bottom: 1.5rem;
}

.recovery-title--player {
  margin: 1rem 0 0.4rem;
  font-size: 1.4rem;
  font-weight: 700;
  color: #fff;
}

.recovery-sub--player {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.82);
}

.recovery-label-text {
  display: block;
}

.recovery-message {
  margin: 0 0 1.25rem;
  font-size: 0.95rem;
  line-height: 1.55;
  text-align: start;
  overflow-wrap: anywhere;
}

.recovery-message p {
  margin: 0 0 0.6rem;
}

.recovery-message p:last-child {
  margin-bottom: 0;
}

.recovery-message--player {
  color: rgba(255, 255, 255, 0.9);
}

.recovery-message--portal {
  color: #cbd5e1;
}

.recovery-hint {
  margin: 0;
  font-size: 0.85rem;
}

.recovery-message--player.recovery-hint {
  color: rgba(255, 255, 255, 0.7);
}

.recovery-message--portal.recovery-hint {
  color: #94a3b8;
}

/* A Link styled as the frame's main button. Colour is restated on hover because the global
   a:hover rule in index.css would otherwise turn the label indigo against the blue fill. */
.recovery-button-link {
  display: block;
  box-sizing: border-box;
  text-align: center;
  text-decoration: none;
  color: #fff;
}

.recovery-button-link:hover,
.recovery-button-link:focus {
  color: #fff;
  text-decoration: none;
}

.recovery-secondary {
  display: block;
  width: 100%;
  margin-top: 0.75rem;
  padding: 0.7rem 1rem;
  box-sizing: border-box;
  border-radius: 10px;
  background: transparent;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 500;
  cursor: pointer;
}

.recovery-secondary--player {
  border: 1px solid rgba(255, 255, 255, 0.28);
  color: #fff;
}

.recovery-secondary--player:hover {
  border-color: rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
}

.recovery-secondary--portal {
  border: 1px solid #334155;
  border-radius: 8px;
  color: #e2e8f0;
}

.recovery-secondary--portal:hover {
  border-color: #64748b;
  background: #0f172a;
  color: #fff;
}

.recovery-button-link:focus-visible,
.recovery-secondary:focus-visible,
.recovery-forgot:focus-visible {
  outline: 2px solid #60a5fa;
  outline-offset: 2px;
}

/* The gamer sign-in screen draws its eye toggle inside an icon group; here it stands alone in the field. */
.recovery-toggle--player {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  inset-inline-end: 12px;
  color: rgba(255, 255, 255, 0.7);
}

/* "Forgot password?" under the password field on both sign-in screens. */
.recovery-forgot-row {
  display: flex;
  justify-content: flex-end;
  margin-top: -0.6rem;
}

.recovery-forgot {
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
}

.recovery-forgot:hover {
  text-decoration: underline;
}

.recovery-forgot--portal,
.recovery-forgot--portal:hover {
  color: #60a5fa;
}

.recovery-forgot--player,
.recovery-forgot--player:hover {
  color: #fff;
}
/* "Confirm your email address" notice. The portal look is the shared vsp-notice; the player look matches the
   play settings cards. */

.evn {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  margin-bottom: 1rem;
  box-sizing: border-box;
}

.evn-text {
  flex: 1 1 16rem;
  min-width: 0;
}

.evn-title {
  margin: 0 0 0.2rem;
  font-size: 0.95rem;
  font-weight: 600;
}

.evn-body {
  margin: 0;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

.evn--portal .evn-title {
  color: var(--vs-chalk);
}

.evn--portal .evn-body {
  color: var(--vs-dim);
}

.evn--player {
  padding: 1rem;
  border-radius: 12px;
  background: rgba(59, 130, 246, 0.12);
  border: 1px solid rgba(96, 165, 250, 0.35);
}

.evn--player .evn-title {
  color: #fff;
  font-size: 1rem;
}

.evn--player .evn-body {
  color: rgba(255, 255, 255, 0.82);
  font-size: 0.9rem;
}

.evn-btn--player {
  flex: none;
  padding: 0.6rem 1rem;
  border: 1px solid transparent;
  border-radius: 10px;
  background: #2f6fe0;
  color: #fff;
  font: inherit;
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}

.evn-btn--player:hover:not(:disabled) {
  background: #2560cc;
  border-color: transparent;
  color: #fff;
}

.evn-btn--player:disabled {
  opacity: 0.65;
  cursor: not-allowed;
}

.evn-btn--player:focus-visible {
  outline: 2px solid #93c5fd;
  outline-offset: 2px;
}

/* The settings column already spaces its children with a gap. */
.dev-settings > .evn {
  margin-bottom: 0;
}
.dev-pending-approval {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(145deg, #0f0f14 0%, #1a1a24 100%);
  padding: 1rem;
}

.dev-pending-approval-card {
  width: 100%;
  max-width: 400px;
  padding: 2rem;
  background: rgba(255, 255, 255, 0.06);
  border-radius: 16px;
  border: 1px solid rgba(255, 255, 255, 0.08);
  text-align: center;
}

.dev-pending-approval-logo {
  height: 48px;
  width: auto;
  margin-bottom: 1rem;
  object-fit: contain;
}

.dev-pending-approval-title {
  font-size: 1.25rem;
  font-weight: 700;
  color: #fff;
  margin: 0 0 0.75rem 0;
}

.dev-pending-approval-message {
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.75);
  margin: 0 0 1rem 0;
  line-height: 1.4;
}

.dev-pending-approval-user {
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.5);
  margin: 0 0 1.25rem 0;
}

.dev-pending-approval-logout {
  padding: 0.6rem 1.25rem;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: transparent;
  color: rgba(255, 255, 255, 0.9);
  font-size: 0.9rem;
  cursor: pointer;
}
.dev-pending-approval-logout:hover {
  background: rgba(255, 255, 255, 0.08);
}
/* The portal shell: a nav rail that recedes, and content that advances.
 *
 * The rail sits on the darkest surface in the product so it reads as chrome and the
 * work stays the brightest thing on screen. It collapses to an off-canvas drawer
 * below 1000px, where a single top bar takes over.
 */

.portal-shell {
  --portal-pad: 1.5rem;

  display: flex;
  min-height: 100vh;
  background: var(--vs-void);
  color: var(--vs-chalk);
  font-family: var(--vs-font);
}

.portal-skip {
  position: absolute;
  inset-inline-start: -9999px;
  top: 0;
  z-index: 60;
  padding: var(--vs-s2) var(--vs-s4);
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
  border-radius: 0 0 var(--vs-r-sm) 0;
  font-size: 0.875rem;
}

.portal-skip:focus {
  inset-inline-start: 0;
}

/* ---------------------------------------------------------------- Rail */

.portal-rail {
  position: sticky;
  top: 0;
  display: flex;
  flex-direction: column;
  flex: none;
  width: var(--vs-rail-w);
  height: 100vh;
  padding: var(--vs-s4) var(--vs-s3);
  box-sizing: border-box;
  background: var(--vs-sunk);
  border-inline-end: 1px solid var(--vs-rail-soft);
  overflow-y: auto;
  scrollbar-gutter: stable;
  scrollbar-width: thin;
}

.portal-rail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--vs-s2) var(--vs-s4);
}

.portal-rail-logo-link,
.portal-topbar-logo-link {
  display: inline-flex;
  align-items: center;
  border-radius: var(--vs-r-sm);
}

.portal-rail-logo {
  height: 30px;
  width: auto;
  display: block;
}

.portal-rail-close {
  display: none;
}

/* Quiet by design: a version you can check, not a status you have to read. */
.portal-rail-health {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.1rem var(--vs-s2);
  color: var(--vs-faint);
  font-size: 0.6875rem;
  font-weight: 550;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.portal-rail-health-lamp {
  color: var(--vs-on);
}

/* Both modifiers are single classes in another file, so they need the extra class here to
   outrank the green above. Without it the lamp reads healthy whatever the API says. */
.portal-rail-health-lamp.vsp-lamp--warn {
  color: var(--vs-warn);
}

.portal-rail-health-lamp.vsp-lamp--fault {
  color: var(--vs-fault);
}

/* ---------------------------------------------------------------- Studio */

.portal-studio {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  padding: var(--vs-s2);
  min-width: 0;
}

.portal-studio-mark {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
  font-size: 0.75rem;
  font-weight: 650;
  overflow: hidden;
}

.portal-studio-logo {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.portal-studio-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.portal-studio-name {
  font-size: 0.875rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.portal-studio-summary {
  font-size: 0.75rem;
  color: var(--vs-faint);
  font-variant-numeric: tabular-nums;
}

.portal-studio-switch {
  display: block;
  padding: 0 var(--vs-s2) var(--vs-s2);
}

.portal-studio-select {
  width: 100%;
  background-color: transparent;
}

/* ---------------------------------------------------------------- Nav */

.portal-nav {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
  padding: var(--vs-s3) 0;
  flex: 1;
}

.portal-nav-group {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

/* Sentence case and quiet. A group label is a wayfinding aid, not a heading. */
.portal-nav-group-label {
  margin: 0 0 var(--vs-s1);
  padding-inline-start: var(--vs-s2);
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--vs-faint);
}

.portal-nav-link {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  padding: 0.45rem var(--vs-s2);
  border-radius: var(--vs-r-sm);
  color: var(--vs-dim);
  font-size: 0.875rem;
  font-weight: 500;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}

.portal-nav-link:hover {
  background: var(--vs-deck);
  color: var(--vs-chalk);
}

.portal-nav-link:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--vs-sunk), 0 0 0 4px var(--vs-act);
}

.portal-nav-link--active {
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
}

.portal-nav-link--active svg {
  color: var(--vs-act);
}

.portal-nav-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.portal-nav-badge {
  flex: none;
  min-width: 1.15rem;
  padding: 0 0.3rem;
  border-radius: var(--vs-r-pill);
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
  font-size: 0.6875rem;
  font-weight: 650;
  line-height: 1.15rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- Account */

.portal-rail-foot {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  padding: var(--vs-s3) var(--vs-s2) var(--vs-s2);
  margin-top: auto;
  background: var(--vs-sunk);
  border-top: 1px solid var(--vs-rail-soft);
  min-width: 0;
}

.portal-account-mark {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 50%;
  background: var(--vs-deck-hi);
  font-size: 0.6875rem;
  font-weight: 650;
}

.portal-account-text {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.portal-account-name {
  font-size: 0.8125rem;
  font-weight: 550;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.portal-account-role {
  font-size: 0.75rem;
  color: var(--vs-faint);
}

.portal-logout {
  flex: none;
  border-color: transparent;
  background: transparent;
}

/* ---------------------------------------------------------------- Body */

.portal-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
}

.portal-topbar {
  display: none;
  align-items: center;
  gap: var(--vs-s3);
  padding: var(--vs-s3) var(--portal-pad);
  background: var(--vs-sunk);
  border-bottom: 1px solid var(--vs-rail-soft);
}

.portal-main {
  flex: 1;
  width: 100%;
  max-width: 1320px;
  margin: 0 auto;
  padding: var(--vs-s6) var(--portal-pad);
  box-sizing: border-box;
  min-width: 0;
}

.portal-scrim {
  display: none;
}

/* ---------------------------------------------------------------- Narrow */

@media (max-width: 1000px) {
  .portal-shell {
    display: block;
  }

  /* visibility, not just transform. A rail that is only translated off-screen still takes
     keyboard focus, so tabbing from the top bar walks through a menu nobody can see. */
  .portal-rail {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    z-index: 50;
    transform: translateX(-100%);
    visibility: hidden;
    transition: transform 0.2s ease, visibility 0s linear 0.2s;
    border-inline-end: 1px solid var(--vs-rail);
    /* The base rule's 100vh is the whole page on a phone, browser chrome included, so the
       drawer's own footer sits under it. dvh is the part you can actually see. */
    height: 100dvh;
    overscroll-behavior: contain;
  }

  [dir='rtl'] .portal-rail {
    transform: translateX(100%);
  }

  .portal-rail--open {
    transform: none;
    visibility: visible;
    transition: transform 0.2s ease, visibility 0s;
  }

  .portal-rail-close {
    display: inline-flex;
  }

  /* The close button takes this slot in the drawer. */
  .portal-rail-health {
    display: none;
  }

  .portal-topbar {
    display: flex;
  }

  .portal-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 45;
    background: rgba(0, 0, 0, 0.55);
  }

  .portal-main {
    padding-block: var(--vs-s5);
  }
}

@media (prefers-reduced-motion: reduce) {
  .portal-rail {
    transition: none;
  }
}
.banner-ad {
  flex-shrink: 0;
  width: 100%;
  min-height: 50px;
  max-height: 90px;
  background: rgba(255, 255, 255, 0.06);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.banner-ad--loading {
  min-height: 40px;
  font-size: 0.75rem;
  color: rgba(255, 255, 255, 0.4);
}

/* The sponsor image, scaled to fit the strip without cropping or stretching. */
.banner-ad-img {
  display: block;
  max-width: 100%;
  max-height: 90px;
  width: auto;
  height: auto;
  margin: 0 auto;
  object-fit: contain;
}

.banner-ad-html {
  width: 100%;
  max-height: 90px;
  overflow: hidden;
  padding: 0.25rem;
  font-size: 0.8rem;
  line-height: 1.3;
}
.banner-ad-html img {
  max-height: 80px;
  width: auto;
  display: block;
  margin: 0 auto;
}

.banner-ad-admob {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  padding: 0.5rem;
  color: rgba(255, 255, 255, 0.5);
  font-size: 0.8rem;
}

.banner-ad-admob-label {
  font-weight: 600;
  color: rgba(255, 255, 255, 0.7);
}

.banner-ad-admob-hint {
  font-size: 0.7rem;
  color: rgba(255, 255, 255, 0.4);
}
/* Mobile-first layout for Gamers / Players portal – constrained width on desktop */

.play-layout {
  min-height: 100vh;
  min-height: 100dvh;
  background: linear-gradient(180deg, #0f0f14 0%, #1a1a24 100%);
  color: #f1f5f9;
  display: flex;
  justify-content: center;
}

.play-layout-inner {
  width: 100%;
  max-width: 480px;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.06);
}

.play-layout-header {
  flex-shrink: 0;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0.75rem 1rem;
  padding-inline-start: max(1rem, env(safe-area-inset-left));
  padding-inline-end: max(1rem, env(safe-area-inset-right));
  padding-top: max(0.75rem, env(safe-area-inset-top));
  background: rgba(15, 15, 20, 0.95);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.play-layout-header-left {
  min-width: 0;
}

.play-layout-logo-link {
  display: flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
}

.play-layout-logo-link--center {
  grid-column: 2;
  justify-self: center;
}

.play-layout-logo {
  height: 28px;
  width: auto;
}

.play-layout-actions {
  grid-column: 3;
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.play-layout-dev-link {
  padding: 0.35rem 0.65rem;
  font-size: 0.8rem;
  font-weight: 500;
  color: #94a3b8;
  text-decoration: none;
  border: 1px solid rgba(148, 163, 184, 0.3);
  border-radius: 8px;
}

.play-layout-dev-link:hover {
  color: #e2e8f0;
  border-color: rgba(226, 232, 240, 0.4);
}

.play-layout-avatar-link {
  flex-shrink: 0;
  display: block;
  border-radius: 50%;
  overflow: hidden;
}
.play-layout-avatar {
  width: 32px;
  height: 32px;
  display: block;
  object-fit: cover;
}
.play-layout-avatar-placeholder {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.9rem;
  font-weight: 600;
  color: #94a3b8;
  background: rgba(255, 255, 255, 0.12);
}

.play-layout-main {
  flex: 1;
  overflow: auto;
  padding: 1rem;
  padding-bottom: 0.5rem;
}

.play-layout-bottom-nav {
  flex-shrink: 0;
  display: flex;
  justify-content: space-around;
  align-items: center;
  padding: 0.5rem 0;
  padding-bottom: max(0.5rem, env(safe-area-inset-bottom));
  background: rgba(15, 15, 20, 0.98);
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.play-layout-nav-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.25rem;
  padding: 0.4rem 0.5rem;
  font-size: 0.75rem;
  font-weight: 500;
  color: #98a1b5;
  text-decoration: none;
  border-radius: 8px;
}
.play-layout-nav-item:hover {
  color: #e2e8f0;
}
/* Matches NAV_ACTIVE in PlayLayout.tsx. Leans toward the blue in the mark without dropping to its
   luminance, which would fail contrast on this bar. */
.play-layout-nav-item--active {
  color: #5470ff !important;
}
.play-layout-nav-item--active .play-layout-nav-label {
  color: #5470ff;
  font-weight: 600;
}
.play-layout-nav-label {
  color: inherit;
  font-size: 0.7rem;
}

@media (min-width: 600px) {
  .play-layout-header {
    padding: 0.75rem 1.5rem;
  }
  .play-layout-main {
    padding: 1.5rem;
  }
}
/* Developer portal register — centered, full-width dark (matches Login) */

.dev-register {
  --vs-primary: #0066ff;
  --vs-primary-hover: #0052cc;
  --vs-primary-focus: rgba(0, 102, 255, 0.3);
  --vs-link: #3b82f6;
  --vs-text: #f1f5f9;
  --vs-text-muted: #94a3b8;
  --vs-border: #334155;

  position: fixed;
  inset: 0;
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2rem;
  box-sizing: border-box;
}

.dev-register-center {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: 400px;
}

.dev-register-brand {
  text-align: center;
  margin-bottom: 1.75rem;
}

.dev-register-logo {
  max-width: 100px;
  height: auto;
  margin-bottom: 1rem;
}

.dev-register-title {
  margin: 0 0 0.5rem;
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-register-subtitle {
  margin: 0;
  font-size: 0.95rem;
  color: var(--vs-text-muted);
  font-weight: 400;
}

.dev-register-form-wrap {
  width: 100%;
}

.dev-register-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.dev-register-label {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--vs-text);
}

.dev-register-optional {
  font-weight: 400;
  color: var(--vs-text-muted);
}

.dev-register-input {
  width: 100%;
  padding: 0.65rem 0.9rem;
  box-sizing: border-box;
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  font-size: 0.95rem;
  color: var(--vs-text);
  background: #111;
  outline: none;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.dev-register-input::placeholder {
  color: var(--vs-text-muted);
}

.dev-register-input:focus {
  border-color: var(--vs-primary);
  box-shadow: 0 0 0 2px var(--vs-primary-focus);
}

.dev-register-error {
  margin: 0;
  font-size: 0.875rem;
  color: #f87171;
}

.dev-register-btn {
  width: 100%;
  padding: 0.75rem 1.25rem;
  margin-top: 0.25rem;
  background: var(--vs-primary);
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
}

.dev-register-btn:hover:not(:disabled) {
  background: var(--vs-primary-hover);
}

.dev-register-btn:disabled {
  opacity: 0.7;
  cursor: not-allowed;
}

.dev-register-footer {
  margin: 1.5rem 0 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--vs-border);
  text-align: center;
  font-size: 0.9rem;
  color: var(--vs-text-muted);
}

.dev-register-footer a {
  color: var(--vs-link);
  font-weight: 500;
  text-decoration: none;
}

.dev-register-footer a:hover {
  text-decoration: underline;
}
.game-overview-series-sub {
  margin: 0 0 0.35rem;
  font-size: 0.85rem;
  color: var(--vs-dim, rgba(255, 255, 255, 0.55));
  line-height: 1.35;
}

.game-overview-series-y-hint {
  margin: 0 0 0.5rem;
  font-size: 0.75rem;
  color: var(--vs-faint, rgba(255, 255, 255, 0.45));
}

.game-overview-series-chart-wrap {
  width: 100%;
  max-width: 640px;
}

.game-overview-series-svg {
  width: 100%;
  height: auto;
  min-height: 240px;
  display: block;
}

.game-overview-series-x-svg-text {
  font-family: system-ui, -apple-system, Segoe UI, sans-serif;
}

.game-overview-series-muted,
.game-overview-series-error {
  margin: 0;
  font-size: 0.9rem;
  color: var(--vs-dim, rgba(255, 255, 255, 0.55));
}

.game-overview-series-error {
  color: var(--vs-fault, #f87171);
}
/* Developer dashboard.
 *
 * Rules this file holds to:
 *   1. Colour means state. Green, amber and red say a game is live, quiet or blocked.
 *      Blue means "you can click this". Nothing is coloured for decoration.
 *   2. One padding value for panels and one gap between sections, both from tokens.css.
 *      No section sets its own rhythm.
 *   3. Numbers are tabular and right-aligned so columns stay still while counts change.
 *   4. Sentence case everywhere. No tracked-out caps, no arrows glued to link text.
 *
 * Surface, text and state tokens come from src/styles/tokens.css so this screen and the
 * game screens cannot drift apart.
 */

.dev-dashboard {
  --vs-gap: 2rem;
  --dash-pad: var(--vs-s5);

  display: flex;
  flex-direction: column;
  gap: var(--vs-gap);
  color: var(--vs-chalk);
  font-family: var(--vs-font);
  font-variant-numeric: tabular-nums;
  min-width: 0;
}

.dev-dashboard :is(h1, h2, h3) {
  color: var(--vs-chalk);
  letter-spacing: -0.01em;
}

/* ---------------------------------------------------------------- Page head */

.dev-dashboard-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s4);
  flex-wrap: wrap;
}

.dev-dashboard-head h1 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 650;
  letter-spacing: -0.02em;
}

/* ---------------------------------------------------------------- Notices */

.dev-dashboard-notice {
  margin: 0;
  padding: 0.7rem 0.95rem;
  border-radius: var(--vs-r-md);
  border-inline-start: 3px solid var(--vs-act);
  background: var(--vs-act-wash);
  font-size: 0.9rem;
}

.dev-dashboard-notice--good {
  border-inline-start-color: var(--vs-on);
  background: var(--vs-on-wash);
}

.dev-dashboard-notice a {
  color: var(--vs-act);
}

.dev-dashboard-loading,
.dev-dashboard-empty,
.dev-dashboard-todo-clear {
  margin: 0;
  color: var(--vs-dim);
  font-size: 0.9rem;
}

.dev-dashboard-error {
  margin: 0;
  color: var(--vs-fault);
  font-size: 0.9rem;
}

.dev-dashboard-quiet-link {
  color: var(--vs-act);
  text-decoration: none;
  font-size: 0.875rem;
}

.dev-dashboard-quiet-link:hover {
  color: var(--vs-act);
  text-decoration: underline;
}

/* ---------------------------------------------------------------- Section heads */

.dev-dashboard-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vs-s4);
  margin-bottom: var(--vs-s4);
  flex-wrap: wrap;
}

.dev-dashboard-section-head h2 {
  margin: 0;
  font-size: 1rem;
  font-weight: 650;
}

.dev-dashboard-count {
  margin: 0;
  font-size: 0.85rem;
  color: var(--vs-dim);
}

.dev-dashboard-head-tools {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  flex-wrap: wrap;
}

.dev-dashboard-count strong {
  color: var(--vs-chalk);
  font-weight: 650;
}

/* ---------------------------------------------------------------- Panels */

.dev-dashboard-panel {
  padding: var(--dash-pad);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  min-width: 0;
}

/* ---------------------------------------------------------------- Empty states */

/* Compact by design. An empty panel should be short, not a large blank rectangle. */
.dev-dashboard-blank {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--vs-s2);
  padding: var(--vs-s5) var(--vs-s4);
  border: 1px dashed var(--vs-rail);
  border-radius: var(--vs-r-md);
  text-align: center;
  color: var(--vs-dim);
}

.dev-dashboard-blank svg {
  color: var(--vs-faint);
}

.dev-dashboard-blank p {
  margin: 0;
  font-size: 0.875rem;
  max-width: 44ch;
}

.dev-dashboard-blank-title {
  color: var(--vs-chalk);
  font-size: 0.9375rem;
  font-weight: 600;
}

.dev-dashboard-blank .vsp-btn {
  margin-top: var(--vs-s2);
}

.dev-dashboard-blank--chart {
  border-style: solid;
  border-color: var(--vs-rail-soft);
  background: var(--vs-void);
}

/* ---------------------------------------------------------------- Games grid */

.dev-dashboard-gamegrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(258px, 1fr));
  gap: var(--vs-s3);
  list-style: none;
  margin: 0;
  padding: 0;
}

.dev-dashboard-gamecard {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s3);
  padding: var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  min-width: 0;
  transition: border-color 0.15s ease;
}

.dev-dashboard-gamecard:hover {
  border-color: var(--vs-rail);
}

.dev-dashboard-gamecard-top {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  min-width: 0;
}

.dev-dashboard-gamecard-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
  font-size: 0.8125rem;
  font-weight: 650;
  overflow: hidden;
}

.dev-dashboard-gamecard-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.dev-dashboard-gamecard-id {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.dev-dashboard-gamecard-name {
  color: var(--vs-chalk);
  text-decoration: none;
  font-size: 0.9375rem;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dev-dashboard-gamecard-name:hover {
  color: var(--vs-chalk);
  text-decoration: underline;
}

.dev-dashboard-gamecard-state {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.8rem;
  color: var(--vs-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.dev-dashboard-lamp {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex: none;
  background: var(--vs-faint);
}

.dev-dashboard-gamecard--live .dev-dashboard-lamp {
  background: var(--vs-on);
  box-shadow: 0 0 0 3px rgba(53, 214, 127, 0.16);
}

.dev-dashboard-gamecard--quiet .dev-dashboard-lamp {
  background: var(--vs-warn);
}

.dev-dashboard-gamecard--blocked .dev-dashboard-lamp {
  background: var(--vs-fault);
}

.dev-dashboard-gamecard--blocked .dev-dashboard-gamecard-state {
  color: var(--vs-fault);
}

/* The only motion on the page, and it marks the one thing that is genuinely live. */
@media (prefers-reduced-motion: no-preference) {
  .dev-dashboard-gamecard--live .dev-dashboard-lamp {
    animation: dev-dashboard-pulse 2.6s ease-in-out infinite;
  }
}

@keyframes dev-dashboard-pulse {
  0%, 100% { box-shadow: 0 0 0 3px rgba(53, 214, 127, 0.16); }
  50% { box-shadow: 0 0 0 6px rgba(53, 214, 127, 0.05); }
}

.dev-dashboard-gamecard-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--vs-s2);
  margin: 0;
  padding: var(--vs-s3) 0 0;
  border-top: 1px solid var(--vs-rail-soft);
}

.dev-dashboard-gamecard-stats dt {
  font-size: 0.75rem;
  color: var(--vs-dim);
}

.dev-dashboard-gamecard-stats dd {
  margin: 0.1rem 0 0;
  font-size: 1.0625rem;
  font-weight: 600;
}

.dev-dashboard-gamecard-live {
  color: var(--vs-on);
}

.dev-dashboard-gamecard-action {
  align-self: flex-start;
  margin-top: auto;
}

/* ---------------------------------------------------------------- Two-column body */

.dev-dashboard-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 340px);
  gap: var(--vs-s4);
  /* start, not stretch: the shorter column must not be padded out to match the taller one. */
  align-items: start;
}

@media (max-width: 1000px) {
  .dev-dashboard-split {
    grid-template-columns: 1fr;
  }
}

/* ---------------------------------------------------------------- Fixture list */

.dev-dashboard-fixtures {
  list-style: none;
  margin: 0;
  padding: 0;
}

.dev-dashboard-fixture {
  display: grid;
  grid-template-columns: 68px minmax(0, 1fr) auto;
  gap: var(--vs-s3);
  align-items: baseline;
  padding: 0.65rem 0;
  border-bottom: 1px solid var(--vs-rail-soft);
}

.dev-dashboard-fixture:first-child {
  padding-top: 0;
}

.dev-dashboard-fixture:last-child {
  padding-bottom: 0;
  border-bottom: none;
}

.dev-dashboard-fixture-when {
  font-size: 0.82rem;
  color: var(--vs-dim);
  white-space: nowrap;
}

.dev-dashboard-fixture--live .dev-dashboard-fixture-when {
  color: var(--vs-on);
}

.dev-dashboard-fixture-main {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-width: 0;
}

.dev-dashboard-fixture-icon {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  flex: none;
  border-radius: 5px;
  background: var(--vs-deck-hi);
  color: var(--vs-dim);
  font-size: 0.625rem;
  font-weight: 650;
  overflow: hidden;
}

.dev-dashboard-fixture-icon img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.dev-dashboard-fixture-text {
  min-width: 0;
}

.dev-dashboard-fixture-name {
  display: block;
  color: var(--vs-chalk);
  text-decoration: none;
  font-size: 0.9375rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

.dev-dashboard-fixture-name:hover {
  color: var(--vs-chalk);
  text-decoration: underline;
}

.dev-dashboard-fixture-game {
  display: block;
  font-size: 0.8rem;
  color: var(--vs-dim);
}

.dev-dashboard-fixture-count {
  font-size: 0.875rem;
  color: var(--vs-dim);
  white-space: nowrap;
}

.dev-dashboard-fixture-count strong {
  color: var(--vs-chalk);
  font-weight: 650;
}

@media (max-width: 560px) {
  .dev-dashboard-fixture {
    grid-template-columns: 56px minmax(0, 1fr);
    row-gap: 0.25rem;
  }

  .dev-dashboard-fixture-count {
    grid-column: 2;
  }
}

/* ---------------------------------------------------------------- Needs you */

.dev-dashboard-todo {
  list-style: none;
  margin: 0;
  padding: 0;
}

.dev-dashboard-todo-item {
  padding: 0.65rem 0 0.65rem 0.8rem;
  border-inline-start: 2px solid var(--vs-rail);
}

.dev-dashboard-todo-item + .dev-dashboard-todo-item {
  margin-top: var(--vs-s2);
}

.dev-dashboard-todo-item--warn {
  border-inline-start-color: var(--vs-warn);
}

.dev-dashboard-todo-item--fault {
  border-inline-start-color: var(--vs-fault);
}

.dev-dashboard-todo-text {
  font-size: 0.875rem;
  line-height: 1.5;
}

.dev-dashboard-todo-action {
  display: inline-block;
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  color: var(--vs-act);
  text-decoration: none;
}

.dev-dashboard-todo-action:hover {
  color: var(--vs-act);
  text-decoration: underline;
}

.dev-dashboard-todo-toggle {
  margin-top: var(--vs-s3);
}

.dev-dashboard-todo-more {
  margin: var(--vs-s3) 0 0;
  padding-top: var(--vs-s3);
  border-top: 1px solid var(--vs-rail-soft);
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

/* ---------------------------------------------------------------- Get started */

/* Shown only while a step is outstanding, and gone for good once they are all done. */
.dev-dashboard-start {
  margin-bottom: var(--vs-s4);
  padding-bottom: var(--vs-s4);
  border-bottom: 1px solid var(--vs-rail-soft);
}

.dev-dashboard-start-title {
  margin: 0 0 var(--vs-s2);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--vs-dim);
}

.dev-dashboard-start-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.dev-dashboard-start-step {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  font-size: 0.875rem;
}

.dev-dashboard-start-mark {
  display: grid;
  place-items: center;
  width: 16px;
  height: 16px;
  flex: none;
  border: 1.5px solid var(--vs-rail);
  border-radius: 50%;
  color: var(--vs-void);
}

.dev-dashboard-start-step.is-done .dev-dashboard-start-mark {
  background: var(--vs-on);
  border-color: var(--vs-on);
}

.dev-dashboard-start-label {
  min-width: 0;
}

.dev-dashboard-start-step.is-done .dev-dashboard-start-label {
  color: var(--vs-dim);
}

a.dev-dashboard-start-link {
  color: var(--vs-act);
  text-decoration: none;
}

a.dev-dashboard-start-link:hover {
  color: var(--vs-act);
  text-decoration: underline;
}

/* ---------------------------------------------------------------- Player activity */

.dev-dashboard-chart-controls {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

.dev-dashboard-range-fixed {
  font-size: 0.8125rem;
  color: var(--vs-dim);
  padding-inline: var(--vs-s1);
}

/* Reads across the top of the panel, above the chart, rather than down a narrow column. */
.dev-dashboard-trend {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  gap: var(--vs-s3) var(--vs-s5);
  margin: 0 0 var(--vs-s4);
  padding-bottom: var(--vs-s4);
  border-bottom: 1px solid var(--vs-rail-soft);
}

.dev-dashboard-trend dt {
  font-size: 0.78rem;
  color: var(--vs-dim);
}

.dev-dashboard-trend dd {
  margin: 0.15rem 0 0;
  font-size: 1.125rem;
  font-weight: 650;
}

.dev-dashboard-trend-lead {
  font-size: 1.6rem !important;
  letter-spacing: -0.02em;
}

.dev-dashboard-trend-up { color: var(--vs-on); }
.dev-dashboard-trend-down { color: var(--vs-fault); }

.dev-dashboard-trend-when {
  display: block;
  font-size: 0.78rem;
  font-weight: 400;
  color: var(--vs-dim);
}

/* The chart scales with its container, axis labels included, so cap the reading width or
   the text grows with the box. Most of the panel, not all of it. */
.dev-dashboard-chart .game-overview-series-chart-wrap {
  max-width: 860px;
}

.dev-dashboard-chart .game-overview-series-svg {
  min-height: 260px;
}

/* ---------------------------------------------------------------- Revenue share */

.dev-dashboard-revenue {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: start;
  gap: var(--vs-s4);
  padding: var(--dash-pad);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
}

.dev-dashboard-revenue-icon {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck-hi);
  color: var(--vs-on);
}

.dev-dashboard-revenue-body {
  min-width: 0;
}

.dev-dashboard-revenue-body h2 {
  margin: 0 0 0.3rem;
  font-size: 1rem;
  font-weight: 650;
}

.dev-dashboard-revenue-blurb {
  margin: 0;
  font-size: 0.875rem;
  line-height: 1.5;
  color: var(--vs-dim);
  max-width: 62ch;
}

.dev-dashboard-revenue-figure {
  display: flex;
  align-items: baseline;
  gap: var(--vs-s3);
  margin: 0;
  flex-wrap: wrap;
}

.dev-dashboard-revenue-amount {
  font-size: 1.9rem;
  font-weight: 650;
  letter-spacing: -0.025em;
  line-height: 1.1;
}

.dev-dashboard-revenue-period {
  font-size: 0.85rem;
  color: var(--vs-dim);
}

.dev-dashboard-revenue-split {
  list-style: none;
  margin: var(--vs-s3) 0 0;
  padding: var(--vs-s3) 0 0;
  border-top: 1px solid var(--vs-rail-soft);
  max-width: 34rem;
}

.dev-dashboard-revenue-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  gap: var(--vs-s4);
  align-items: baseline;
  padding: 0.4rem 0;
  font-size: 0.875rem;
}

.dev-dashboard-revenue-impressions {
  color: var(--vs-dim);
  font-size: 0.85rem;
  text-align: end;
}

.dev-dashboard-revenue-action {
  white-space: nowrap;
}

@media (max-width: 720px) {
  .dev-dashboard-revenue {
    grid-template-columns: auto minmax(0, 1fr);
  }

  .dev-dashboard-revenue-action {
    grid-column: 1 / -1;
    justify-self: start;
  }
}
/* Staff games register.
 *
 * Built from the vsp- primitives in src/styles/tokens.css. This file only lays them out and
 * sets the few text weights the table needs; every colour comes from a token. Hover rules
 * restate colour because index.css still carries link and button defaults (see the comments
 * at the top of tokens.css).
 */

/* The page frame, head, notices, summary chips, dialog, thumbnails and toast are shared primitives
   (vsp-page, vsp-summary, vsp-dialog, vsp-thumb, vsp-toast). */

/* ---------------------------------------------------------------- Review queue */

.staff-games-queue-head {
  margin-bottom: var(--vs-s3);
}

/* Focus lands here when a link result is dismissed, so keyboard users stay in the queue. Like the
   result itself it is a landing spot, not a control, so it does not draw a ring. */
.staff-games-queue-title:focus {
  outline: none;
}

.staff-games-queue-clear {
  margin: 0;
  font-size: 0.875rem;
  color: var(--vs-dim);
}

.staff-games-queue-table {
  min-width: 640px;
}

/* Only the issue wraps. A game or studio name broken over three lines is harder to scan
   than a table that scrolls. */
.staff-games-queue-table :is(th, td) {
  vertical-align: middle;
  white-space: nowrap;
}

.staff-games-queue-table td.staff-games-queue-issue {
  width: 100%;
  min-width: 12rem;
  white-space: normal;
}

.staff-games-queue-studio {
  color: var(--vs-dim);
}

.staff-games-queue-action {
  text-align: end;
  white-space: nowrap;
}

.staff-games-queue-foot {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  flex-wrap: wrap;
  margin-top: var(--vs-s3);
}

.staff-games-queue-more {
  margin: 0;
  font-size: 0.8125rem;
}

/* The primary link and its quiet "Show games" or "View game" partner, kept on one line. */
.staff-games-queue-actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--vs-s1);
}

/* A long studio name would push the whole queue sideways, so the label stops at a width and
   the button's title carries the full name. The span is what can ellipsise: text directly in
   an inline-flex button cannot. */
.staff-games-link-btn-label {
  display: block;
  max-width: 14rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

.staff-games-link-outcome {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s2);
  margin-bottom: var(--vs-s3);
}

/* Focus is moved here after a link so it is not lost with the row. It is a landing spot, not a
   control, so it does not draw a ring. */
.staff-games-link-outcome:focus,
.staff-games-link-notice:focus {
  outline: none;
}

.staff-games-queue > .staff-games-link-notice {
  margin-bottom: var(--vs-s3);
}

/* Top aligned, because the skipped list makes the notice several lines tall. */
.staff-games-link-notice {
  align-items: flex-start;
}

.staff-games-link-notice > svg {
  flex: none;
  margin-top: 0.15em;
}

.staff-games-link-notice-body {
  flex: 1;
  min-width: 0;
  line-height: 1.45;
}

.staff-games-link-notice-head {
  margin: 0;
}

.staff-games-link-skipped {
  margin: var(--vs-s1) 0 0;
  padding-inline-start: 1.1rem;
}

.staff-games-link-skipped-name {
  font-weight: 600;
  overflow-wrap: anywhere;
}

.vsp-icon-btn.staff-games-link-dismiss {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  border-color: transparent;
  background: transparent;
}

/* ---------------------------------------------------------------- Toolbar */

.staff-games-register {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
}

.staff-games-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s2) var(--vs-s4);
  flex-wrap: wrap;
}

.staff-games-toolbar-scope,
.staff-games-toolbar-filters {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
  min-width: 0;
}

.staff-games-toolbar-scope {
  flex: 1 1 26rem;
}

.staff-games-search {
  flex: 1 1 14rem;
  max-width: 22rem;
}

/* Studio names run longer than the other options, so this select gets more room than the
   small select's default. */
.vsp-select.staff-games-studio-select {
  max-width: 16rem;
}

.staff-games-filter {
  display: flex;
  flex-direction: row;
}

.staff-games-empty-body {
  margin: 0;
}

/* ---------------------------------------------------------------- Table */

.staff-games-table {
  min-width: 960px;
}

.staff-games-table :is(th, td) {
  vertical-align: middle;
}

.staff-games-game-cell {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  min-width: 11rem;
}

.staff-games-stack {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  min-width: 0;
}

.staff-games-link {
  color: var(--vs-chalk);
  text-decoration: none;
}

.staff-games-link:hover {
  color: var(--vs-act);
  text-decoration: underline;
}

.staff-games-name {
  font-weight: 600;
}

.staff-games-sub {
  font-size: 0.75rem;
  font-weight: 400;
  color: var(--vs-faint);
}

.staff-games-dim {
  color: var(--vs-dim);
}

.staff-games-faint {
  color: var(--vs-faint);
}

.staff-games-warn {
  color: var(--vs-warn);
}

.staff-games-studio-name {
  color: var(--vs-chalk);
}

.staff-games-meta {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

/* Muted, not a badge: a studio taken from the creator is information, not a state. The dotted
   underline marks the title that explains the game is not linked to it yet. */
.staff-games-studio-inferred {
  color: var(--vs-dim);
  text-decoration: underline dotted;
  text-decoration-color: var(--vs-faint);
  text-underline-offset: 3px;
  cursor: help;
}

.staff-games-sdk {
  display: flex;
  align-items: flex-start;
  gap: var(--vs-s2);
  min-width: 8.5rem;
}

/* Pinned to the first line of text, so a label that wraps keeps its dot beside the words. */
.staff-games-sdk .vsp-lamp {
  margin-top: 0.5em;
}

/* Receiving over the last day is steady green. Only a game calling in right now pulses,
   which keeps the one moving thing on the screen meaningful. */
.vsp-lamp.staff-games-lamp-steady {
  animation: none;
  box-shadow: none;
}

.vsp-lamp.staff-games-lamp-off {
  opacity: 0.5;
}

.staff-games-attention {
  display: inline-flex;
  align-items: center;
  gap: var(--vs-s2);
  max-width: 16rem;
}

/* The full list is in the title; the badge only has to say enough to be recognised. */
.staff-games-attention-badge {
  min-width: 0;
  max-width: 13rem;
}

.staff-games-attention-label {
  overflow: hidden;
  text-overflow: ellipsis;
}

.staff-games-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--vs-s1);
}

.vsp-icon-btn.staff-games-more {
  width: 1.75rem;
  height: 1.75rem;
}

/* Placed by RegisterTable against the viewport, so it is not clipped by the table's
   horizontal scroll container. */
.vsp-menu.staff-games-menu {
  z-index: 60;
}

/* ActionLink adds an external mark after the label when the link leaves this host. */
.vsp-menu-item.staff-games-menu-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s2);
}
/* Create game — full Add Game form, dark theme */

.dev-create-game {
  --vs-primary: #0066ff;
  --vs-primary-hover: #0052cc;
  --vs-link: #3b82f6;
  --vs-bg: #000;
  --vs-card: #111;
  --vs-text: #f1f5f9;
  --vs-text-muted: #94a3b8;
  --vs-border: #334155;
}

.dev-create-game-back {
  color: var(--vs-link);
  text-decoration: none;
  font-size: 0.9rem;
  margin-bottom: 1.5rem;
  display: inline-block;
}

.dev-create-game-back:hover {
  text-decoration: underline;
}

.dev-create-game-blocked {
  margin: 0 0 1rem;
  padding: 0.75rem 1rem;
  border-radius: 8px;
  background: rgba(251, 191, 36, 0.12);
  border: 1px solid #b45309;
  color: #fcd34d;
  font-size: 0.9rem;
}

.dev-create-game-blocked a {
  color: var(--vs-link);
  font-weight: 600;
}

.dev-create-game-card {
  max-width: 560px;
  background: var(--vs-card);
  border: 1px solid var(--vs-border);
  border-radius: 12px;
  padding: 2rem;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
}

.dev-create-game-header {
  margin-bottom: 0.5rem;
}

.dev-create-game-icon {
  display: block;
  font-size: 1.5rem;
  margin-bottom: 0.25rem;
}

.dev-create-game-card h1 {
  margin: 0 0 0.25rem;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-create-game-subtitle {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: var(--vs-text-muted);
}

.dev-create-game-hint {
  margin: -0.35rem 0 0.5rem;
  font-size: 0.8rem;
  color: var(--vs-text-muted);
}

.dev-create-game-required-legend {
  margin: 0 0 1.25rem;
  font-size: 0.8rem;
  color: var(--vs-text-muted);
}

.dev-create-game-asterisk {
  color: #f87171;
}

.dev-create-game-section {
  margin-bottom: 1.75rem;
}

.dev-create-game-section h2 {
  margin: 0 0 1rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-create-game-label {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--vs-text);
  margin-bottom: 0.5rem;
}

.dev-create-game-input {
  width: 100%;
  padding: 0.65rem 0.9rem;
  box-sizing: border-box;
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  font-size: 0.95rem;
  color: var(--vs-text);
  background: var(--vs-bg);
  outline: none;
  margin-bottom: 1rem;
}

.dev-create-game-input:focus {
  border-color: var(--vs-primary);
  box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.3);
}

.dev-create-game-input::placeholder {
  color: var(--vs-text-muted);
}

.dev-create-game-field-error {
  display: block;
  font-size: 0.8rem;
  color: #f87171;
  margin-top: -0.5rem;
  margin-bottom: 1rem;
}

.dev-create-game-select {
  width: 100%;
  padding: 0.65rem 0.9rem;
  box-sizing: border-box;
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  font-size: 0.95rem;
  color: var(--vs-text);
  background: var(--vs-bg);
  outline: none;
  margin-bottom: 1rem;
  cursor: pointer;
}

.dev-create-game-select:focus {
  border-color: var(--vs-primary);
}

.dev-create-game-multiselect-row {
  display: flex;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.dev-create-game-multiselect-block {
  flex: 1;
  min-width: 0;
}

.dev-create-game-multiselect-list {
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  padding: 0.5rem;
  max-height: 140px;
  overflow-y: auto;
  background: var(--vs-bg);
}

.dev-create-game-checkbox-label {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.875rem;
  color: var(--vs-text);
  cursor: pointer;
  padding: 0.35rem 0;
}

.dev-create-game-checkbox-label input {
  accent-color: var(--vs-primary);
}

.dev-create-game-checkbox-label--block {
  margin-bottom: 0.5rem;
}

.dev-create-game-selected-display {
  padding: 0.65rem 0.9rem;
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  font-size: 0.9rem;
  color: var(--vs-text-muted);
  background: var(--vs-bg);
  min-height: 2.5rem;
}

.dev-create-game-coming-soon {
  font-size: 1.25rem;
  font-weight: 600;
  color: #c084fc;
  margin: 0.5rem 0 0;
}

.dev-create-game-link-row {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-bottom: 0.5rem;
}

.dev-create-game-link-input {
  flex: 1;
  margin-bottom: 0;
}

.dev-create-game-link-remove {
  padding: 0.5rem 0.75rem;
  font-size: 0.85rem;
  color: var(--vs-text-muted);
  background: transparent;
  border: 1px solid var(--vs-border);
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
}

.dev-create-game-link-remove:hover {
  color: #f87171;
  border-color: #f87171;
}

.dev-create-game-add-link {
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  color: var(--vs-primary);
  background: transparent;
  border: 1px dashed var(--vs-border);
  border-radius: 8px;
  cursor: pointer;
  margin-top: 0.25rem;
}

.dev-create-game-add-link:hover {
  border-color: var(--vs-primary);
  background: rgba(0, 102, 255, 0.08);
}

.dev-create-game-error {
  margin: 0 0 1rem;
  font-size: 0.875rem;
  color: #f87171;
}

.dev-create-game-btn {
  width: 100%;
  padding: 0.75rem 1.25rem;
  background: var(--vs-primary);
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
}

.dev-create-game-btn:hover:not(:disabled) {
  background: var(--vs-primary-hover);
}

.dev-create-game-btn:disabled {
  opacity: 0.7;
  cursor: not-allowed;
}
/* Game header and tab strip. The breadcrumb, tabs and delete dialog are the shared vsp-crumbs,
 * vsp-tabs and vsp-dialog primitives in styles/tokens.css; this file lays out the identity row.
 *
 * The header answers three questions before anything else on the page: which game,
 * is it approved, and what can I do to it. Everything else is a tab away.
 */

.game-shell {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.game-head {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
  margin-bottom: var(--vs-s6);
}

.game-head--bare {
  gap: var(--vs-s4);
}

/* ---------------------------------------------------------------- Identity row */

.game-head-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--vs-s4);
  flex-wrap: wrap;
}

.game-identity {
  display: flex;
  align-items: center;
  gap: var(--vs-s4);
  min-width: 0;
}

.game-icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  flex: none;
  border-radius: var(--vs-r-md);
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
  font-size: 1rem;
  font-weight: 650;
  overflow: hidden;
}

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

.game-identity-text {
  min-width: 0;
}

.game-name {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--vs-chalk);
}

.game-identity-meta {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  margin-top: 0.35rem;
  flex-wrap: wrap;
}

.game-slug {
  font-family: var(--vs-mono);
  font-size: 0.75rem;
}

.game-head-actions {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

.game-switch select {
  min-width: 11rem;
}

/* ---------------------------------------------------------------- Main */

.game-main {
  min-width: 0;
}

@media (max-width: 760px) {
  .game-head-actions {
    width: 100%;
  }

  .game-switch {
    flex: 1;
  }

  .game-switch select {
    width: 100%;
    min-width: 0;
  }
}
/* Game overview.
 *
 * One raised, coloured surface at the top says whether the game is working. Everything
 * below it sits on quieter panels in reading order. Numbers are tabular so a column of
 * digits stays still while it updates.
 */

.gov {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s6);
  font-variant-numeric: tabular-nums;
  min-width: 0;
}

.gov-flash {
  margin: 0;
}

.gov-loading {
  margin: 0;
  font-size: 0.875rem;
}

/* ---------------------------------------------------------------- Status */

.gov-status {
  padding: var(--vs-s5);
  border: 1px solid var(--vs-rail-soft);
  border-inline-start: 3px solid var(--vs-faint);
  border-radius: var(--vs-r-lg);
  background: var(--vs-deck);
}

.gov-status--ok {
  border-inline-start-color: var(--vs-on);
  background: linear-gradient(90deg, var(--vs-on-wash), transparent 55%), var(--vs-deck);
}

.gov-status--warn {
  border-inline-start-color: var(--vs-warn);
  background: linear-gradient(90deg, var(--vs-warn-wash), transparent 55%), var(--vs-deck);
}

.gov-status--fault {
  border-inline-start-color: var(--vs-fault);
  background: linear-gradient(90deg, var(--vs-fault-wash), transparent 55%), var(--vs-deck);
}

.gov-status-head {
  display: flex;
  align-items: flex-start;
  gap: var(--vs-s3);
}

.gov-status-head > .vsp-lamp {
  margin-top: 0.45rem;
}

.gov-status-text {
  flex: 1;
  min-width: 0;
}

.gov-status-title {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--vs-chalk);
}

.gov-status-detail {
  margin: 0.2rem 0 0;
  max-width: 68ch;
  font-size: 0.875rem;
  line-height: 1.55;
  color: var(--vs-dim);
}

.gov-status-actions {
  display: flex;
  gap: var(--vs-s2);
  flex: none;
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------- First-run steps */

/* One compact row rather than a four-column block. The per-step explanation moves to a
   title tooltip and to screen-reader text, so setup does not cost a quarter of the page. */
.gov-steps-wrap {
  display: flex;
  align-items: center;
  gap: var(--vs-s3) var(--vs-s4);
  flex-wrap: wrap;
  margin-top: var(--vs-s4);
  padding-top: var(--vs-s3);
  border-top: 1px solid var(--vs-rail-soft);
}

.gov-steps-count {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--vs-dim);
  white-space: nowrap;
}

.gov-steps-count strong {
  color: var(--vs-chalk);
  font-weight: 650;
}

.gov-steps {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vs-s2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.gov-step {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.2rem 0.6rem 0.2rem 0.35rem;
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-pill);
  background: var(--vs-void);
  font-size: 0.8125rem;
  white-space: nowrap;
}

.gov-step-mark {
  display: grid;
  place-items: center;
  width: 15px;
  height: 15px;
  flex: none;
  border: 1.5px solid var(--vs-rail);
  border-radius: 50%;
  color: var(--vs-void);
}

.gov-step--done .gov-step-mark {
  background: var(--vs-on);
  border-color: var(--vs-on);
}

.gov-step-label {
  color: var(--vs-chalk);
}

.gov-step--done .gov-step-label {
  color: var(--vs-dim);
}

/* ---------------------------------------------------------------- Metric cluster */

/* One instrument cluster split by hairlines, rather than four separate cards with four
   separate borders and four separate shadows. */
.gov-cluster {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  overflow: hidden;
}

.gov-cluster-msg {
  grid-column: 1 / -1;
  border-radius: 0;
  border-inline-start-width: 3px;
}

.gov-metric {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding: var(--vs-s4) var(--vs-s5);
  border-inline-start: 1px solid var(--vs-rail-soft);
  min-width: 0;
}

.gov-metric:first-child {
  border-inline-start: none;
}

.gov-metric-label {
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

.gov-metric-value {
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1.15;
  color: var(--vs-chalk);
}

.gov-metric-note {
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--vs-faint);
}

.gov-skeleton {
  display: inline-block;
  width: 3.5rem;
  height: 1.5rem;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--vs-deck-hi), var(--vs-rail), var(--vs-deck-hi));
  background-size: 200% 100%;
  animation: gov-shimmer 1.4s linear infinite;
  vertical-align: -0.2rem;
}

@keyframes gov-shimmer {
  to {
    background-position: -200% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .gov-skeleton {
    animation: none;
  }
}

@media (max-width: 900px) {
  .gov-cluster {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .gov-metric:nth-child(odd) {
    border-inline-start: none;
  }

  .gov-metric:nth-child(n + 3) {
    border-top: 1px solid var(--vs-rail-soft);
  }
}

@media (max-width: 520px) {
  .gov-cluster {
    grid-template-columns: minmax(0, 1fr);
  }

  .gov-metric {
    border-inline-start: none;
  }

  .gov-metric + .gov-metric {
    border-top: 1px solid var(--vs-rail-soft);
  }
}

/* ---------------------------------------------------------------- Split */

.gov-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 360px);
  gap: var(--vs-s5);
  align-items: start;
}

@media (max-width: 1100px) {
  .gov-split {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The chart scales with its container, labels included, so cap the reading width or the
   axis text grows with the box. */
.gov-activity .game-overview-series-chart-wrap {
  max-width: 720px;
}

/* Compact by design. An empty chart should leave a short panel, not a tall blank box. */
.gov-chart-blank {
  padding: var(--vs-s5) var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-void);
}

.gov-chart-blank svg {
  color: var(--vs-faint);
}

.gov-chart-blank p {
  margin: 0;
  max-width: 42ch;
}

.gov-chart-blank .vsp-btn {
  margin-top: var(--vs-s2);
}

/* ---------------------------------------------------------------- Health */

/* Label and value on one line in two columns. Stacked, these five counters stood taller
   than the whole chart beside them and left a gap under it. */
.gov-counters {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.3rem var(--vs-s4);
  margin: 0;
}

.gov-counters > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vs-s2);
  min-width: 0;
  padding: 0.15rem 0;
  border-bottom: 1px solid var(--vs-rail-soft);
}

.gov-counters dt {
  font-size: 0.75rem;
  color: var(--vs-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.gov-counters dd {
  margin: 0;
  flex: none;
  font-size: 0.9375rem;
  font-weight: 650;
  color: var(--vs-chalk);
  white-space: nowrap;
}

/* Webhooks reads as a sentence rather than a figure, so it takes the full row instead of
   squeezing its own label down to one letter. */
.gov-counters > div:last-child {
  grid-column: 1 / -1;
}

.gov-counter-bad {
  color: var(--vs-fault);
}

.gov-counter-warn {
  color: var(--vs-warn);
}

.gov-hourly {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 36px;
  margin-top: var(--vs-s4);
  padding-top: var(--vs-s2);
  border-bottom: 1px solid var(--vs-rail-soft);
}

.gov-hourly-bar {
  flex: 1;
  min-width: 2px;
  border-radius: 1px 1px 0 0;
  background: var(--vs-act);
  opacity: 0.75;
}

.gov-hourly-bar--err {
  background: var(--vs-fault);
  opacity: 1;
}

.gov-advice {
  list-style: none;
  margin: var(--vs-s4) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--vs-s2);
}

.gov-advice-item {
  display: flex;
  align-items: flex-start;
  gap: var(--vs-s2);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--vs-dim);
}

.gov-advice-item svg {
  flex: none;
  margin-top: 0.15rem;
}

.gov-advice-item--problem {
  color: var(--vs-chalk);
}

.gov-advice-item--problem svg {
  color: var(--vs-fault);
}

.gov-advice-item--warning svg {
  color: var(--vs-warn);
}

/* Neutral, not green. Green would claim the integration is working, and an info line is
   often exactly the opposite: nothing has happened yet. The status strip above is the one
   place that reports health. */
.gov-advice-item--info svg {
  color: var(--vs-faint);
}

/* ---------------------------------------------------------------- Expanders */

.gov-more {
  margin-top: var(--vs-s3);
}

.gov-more > summary {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.2rem 0;
  list-style: none;
  cursor: pointer;
  font-size: 0.8125rem;
  color: var(--vs-dim);
  border-radius: var(--vs-r-sm);
}

.gov-more > summary::-webkit-details-marker {
  display: none;
}

.gov-more > summary::before {
  content: "";
  width: 0;
  height: 0;
  flex: none;
  border-left: 4px solid currentColor;
  border-top: 3.5px solid transparent;
  border-bottom: 3.5px solid transparent;
  transition: transform 0.15s ease;
}

[dir="rtl"] .gov-more > summary::before {
  transform: scaleX(-1);
}

.gov-more[open] > summary::before {
  transform: rotate(90deg);
}

[dir="rtl"] .gov-more[open] > summary::before {
  transform: rotate(-90deg);
}

.gov-more > summary:hover {
  color: var(--vs-chalk);
}

.gov-more > summary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--vs-deck), 0 0 0 4px var(--vs-act);
}

.gov-more-body {
  margin: 0.3rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--vs-dim);
  max-width: 78ch;
}

@media (prefers-reduced-motion: reduce) {
  .gov-more > summary::before,
  .gov-creds-summary::after {
    transition: none;
  }
}

.gov-sdk-versions {
  list-style: none;
  margin: var(--vs-s2) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--vs-s2);
  font-size: 0.8125rem;
}

.gov-sdk-versions li {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

/* ---------------------------------------------------------------- Credentials */

.gov-creds-summary {
  display: flex;
  align-items: baseline;
  gap: var(--vs-s3);
  flex-wrap: wrap;
  list-style: none;
  cursor: pointer;
  border-radius: var(--vs-r-sm);
}

.gov-creds-summary::-webkit-details-marker {
  display: none;
}

.gov-creds-summary::after {
  content: "";
  width: 0;
  height: 0;
  margin-inline-start: auto;
  align-self: center;
  border-left: 4.5px solid var(--vs-dim);
  border-top: 4px solid transparent;
  border-bottom: 4px solid transparent;
  transition: transform 0.15s ease;
}

.gov-creds[open] .gov-creds-summary::after {
  transform: rotate(90deg);
}

.gov-creds-summary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--vs-deck), 0 0 0 4px var(--vs-act);
}

.gov-creds-hint {
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

.gov-creds[open] .gov-creds-hint {
  display: none;
}

.gov-creds-blurb {
  margin: var(--vs-s2) 0 var(--vs-s3);
  max-width: 78ch;
}

.gov-creds .gov-cred {
  display: grid;
  grid-template-columns: 8.5rem minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--vs-s3) var(--vs-s4);
  padding: var(--vs-s3) 0;
  border-top: 1px solid var(--vs-rail-soft);
}

.gov-cred-label {
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

.gov-cred-value {
  padding: 0.35rem var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-sm);
  background: var(--vs-void);
  overflow-x: auto;
  white-space: nowrap;
  min-width: 0;
}

.gov-cred-value--once {
  border-color: rgba(245, 165, 36, 0.45);
  background: var(--vs-warn-wash);
}

.gov-cred-actions {
  display: flex;
  gap: var(--vs-s2);
  justify-content: flex-end;
}

.gov-cred-restricted {
  grid-column: 2 / -1;
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--vs-faint);
  max-width: 70ch;
}

.gov-cred-restricted--urgent {
  color: var(--vs-warn);
}

.gov-cred-error {
  grid-column: 1 / -1;
}

@media (max-width: 760px) {
  .gov-creds .gov-cred {
    grid-template-columns: minmax(0, 1fr);
  }

  .gov-cred-actions {
    justify-content: flex-start;
  }

  .gov-cred-restricted,
  .gov-cred-error {
    grid-column: 1;
  }
}
/* Events, and the card shape that Recurring reuses.
 *
 * Both screens show the same object at different grain: Events foregrounds a single
 * tournament, Recurring foregrounds the schedule that makes them. The card frame,
 * spacing and footer are shared here so the two cannot drift; only the middle changes.
 */

.gev {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
  min-width: 0;
  font-variant-numeric: tabular-nums;
}

.gev-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s4);
  flex-wrap: wrap;
}

.gev-title {
  margin: 0;
  font-size: 1.125rem;
  font-weight: 650;
  letter-spacing: -0.01em;
}

.gev-tools {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

.gev-search {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0 0.6rem;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck);
  color: var(--vs-dim);
}

.gev-search:focus-within {
  border-color: var(--vs-act);
}

.gev-search input {
  width: 11rem;
  max-width: 40vw;
  padding: 0.4rem 0;
  border: none;
  background: transparent;
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.875rem;
}

.gev-search input::placeholder {
  color: var(--vs-faint);
}

.gev-search input:focus {
  outline: none;
}

/* ---------------------------------------------------------------- Filters */

.gev-filters {
  display: flex;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

.gev-filter {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.7rem;
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-pill);
  background: var(--vs-deck);
  color: var(--vs-dim);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 550;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.gev-filter:hover:not(:disabled) {
  border-color: var(--vs-faint);
  color: var(--vs-chalk);
}

.gev-filter:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.gev-filter[aria-pressed='true'] {
  background: var(--vs-deck-hi);
  border-color: var(--vs-faint);
  color: var(--vs-chalk);
}

.gev-filter:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--vs-void), 0 0 0 4px var(--vs-act);
}

.gev-filter-count {
  font-size: 0.75rem;
  color: var(--vs-faint);
  font-variant-numeric: tabular-nums;
}

.gev-filter[aria-pressed='true'] .gev-filter-count {
  color: var(--vs-dim);
}

.gev-msg {
  margin: 0;
  font-size: 0.9rem;
}

.gev-blank {
  border: 1px dashed var(--vs-rail);
  border-radius: var(--vs-r-md);
}

.gev-blank svg {
  color: var(--vs-faint);
}

.gev-blank p {
  margin: 0;
  max-width: 46ch;
}

.gev-blank .vsp-btn {
  margin-top: var(--vs-s2);
}

/* ---------------------------------------------------------------- Card grid */

.gev-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(290px, 1fr));
  gap: var(--vs-s3);
  list-style: none;
  margin: 0;
  padding: 0;
}

.gev-card {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s3);
  padding: var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  min-width: 0;
  transition: border-color 0.15s ease;
}

.gev-card:hover {
  border-color: var(--vs-rail);
}

/* Finished tournaments recede: a sunken surface and a dimmed mark, but the text keeps its
   own contrast so an ended event stays readable rather than merely faint. */
.gev-card--ended,
.gev-card--cancelled {
  background: var(--vs-void);
}

.gev-card--ended .gev-art,
.gev-card--cancelled .gev-art {
  opacity: 0.55;
}

.gev-card-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--vs-s2);
}

.gev-art {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  flex: none;
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck-hi);
  color: var(--vs-dim);
  overflow: hidden;
}

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

.gev-card-name {
  margin: 0;
  font-size: 1rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  line-height: 1.3;
}

.gev-card-name a {
  color: var(--vs-chalk);
  text-decoration: none;
}

.gev-card-name a:hover {
  color: var(--vs-chalk);
  text-decoration: underline;
}

.gev-card-mode {
  margin: -0.4rem 0 0;
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

.gev-card-facts {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin: 0;
  padding-top: var(--vs-s3);
  border-top: 1px solid var(--vs-rail-soft);
}

.gev-card-facts > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vs-s3);
  min-width: 0;
}

.gev-card-facts dt {
  font-size: 0.75rem;
  color: var(--vs-dim);
  flex: none;
}

.gev-card-facts dd {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--vs-chalk);
  text-align: end;
  min-width: 0;
}

.gev-card-rel {
  display: block;
  font-size: 0.75rem;
  color: var(--vs-warn);
}

.gev-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s2);
  margin-top: auto;
  padding-top: var(--vs-s2);
}

/* ---------------------------------------------------------------- List view */

.gev-row-name {
  color: var(--vs-chalk);
  text-decoration: none;
}

.gev-row-name:hover {
  color: var(--vs-chalk);
  text-decoration: underline;
}

.gev-row--past :is(th, td) {
  color: var(--vs-dim);
}

@media (max-width: 620px) {
  .gev-head {
    align-items: flex-start;
  }

  .gev-tools {
    width: 100%;
  }

  /* Sharing a row with the view toggle and Create event left this about 88px wide. */
  .gev-search {
    flex: 1 0 100%;
    order: -1;
  }

  .gev-search input {
    width: 100%;
    max-width: none;
  }
}
/* Game detail — same dark flair */

/* The local names stay so every rule below still resolves; they now read from
   src/styles/tokens.css instead of a private palette. The card was #111 and the
   surrounding shell is charcoal, which is why these tabs looked pasted in. */
.dev-game-detail {
  --vs-primary: var(--vs-act-fill);
  --vs-primary-hover: var(--vs-act-fill-hi);
  --vs-link: var(--vs-act);
  --vs-card: var(--vs-deck);
  --vs-text: var(--vs-chalk);
  --vs-text-muted: var(--vs-dim);
  --vs-border: var(--vs-rail);

  font-family: var(--vs-font);
}

.dev-game-detail-back {
  color: var(--vs-link);
  text-decoration: none;
  font-size: 0.9rem;
  margin-bottom: 1.5rem;
  display: inline-block;
}

.dev-game-detail-back:hover {
  text-decoration: underline;
}

.dev-game-detail-card {
  background: var(--vs-card);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  padding: var(--vs-s5);
}

.dev-game-detail-info {
  margin-bottom: 1.5rem;
}

.dev-game-detail-name {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-game-detail-status-row {
  margin-bottom: 1.25rem;
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.dev-game-detail-status {
  display: inline-block;
  padding: 0.25rem 0.5rem;
  border-radius: 6px;
  font-size: 0.8rem;
  font-weight: 500;
}
.dev-game-detail-status--pending {
  background: rgba(251, 191, 36, 0.2);
  color: var(--vs-warn);
}
.dev-game-detail-status--approved {
  background: rgba(74, 222, 128, 0.2);
  color: var(--vs-on);
}
.dev-game-detail-status--rejected {
  background: rgba(248, 113, 113, 0.2);
  color: var(--vs-fault);
}

.dev-game-detail-live-indicator {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.85rem;
  font-weight: 500;
}
.dev-game-detail-live-dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  flex-shrink: 0;
}
.dev-game-detail-live-indicator--live {
  color: var(--vs-on);
}
.dev-game-detail-live-indicator--live .dev-game-detail-live-dot {
  background: var(--vs-on);
}
.dev-game-detail-live-indicator--potential {
  color: var(--vs-warn);
}
.dev-game-detail-live-indicator--potential .dev-game-detail-live-dot {
  background: var(--vs-warn);
}
.dev-game-detail-live-indicator--issue {
  color: var(--vs-fault);
}
.dev-game-detail-live-indicator--issue .dev-game-detail-live-dot {
  background: var(--vs-fault);
}

.dev-game-detail-meta {
  display: grid;
  gap: 1rem;
  margin: 0;
}

.dev-game-detail-meta dt {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--vs-text-muted);
  margin-bottom: 0.25rem;
}

.dev-game-detail-meta dd {
  margin: 0;
  font-size: 0.95rem;
  color: var(--vs-text);
}

.dev-game-detail-meta code {
  font-size: 0.85em;
  color: var(--vs-text-muted);
}

.dev-game-detail-sdk {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.dev-game-detail-sdk-toggle,
.dev-game-detail-sdk-copy {
  padding: 0.25rem 0.6rem;
  font-size: 0.8rem;
  border-radius: 6px;
  border: 1px solid var(--vs-border);
  background: transparent;
  color: var(--vs-text-muted);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s;
}

.dev-game-detail-sdk-toggle:hover,
.dev-game-detail-sdk-copy:hover {
  color: var(--vs-text);
  border-color: var(--vs-text-muted);
}

.dev-game-detail-events {
  margin-top: 0;
}

.dev-game-detail-section-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 1.25rem;
}

.dev-game-detail-section-head h2 {
  margin: 0;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-game-detail-create-btn {
  display: inline-block;
  padding: 0.5rem 1rem;
  background: var(--vs-primary);
  color: #fff;
  border-radius: 8px;
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  transition: background 0.2s;
}

.dev-game-detail-create-btn:hover {
  background: var(--vs-primary-hover);
}

.dev-game-detail-empty {
  margin: 0;
  color: var(--vs-text-muted);
  font-size: 0.95rem;
}

.dev-game-detail-table {
  width: 100%;
  border-collapse: collapse;
}

.dev-game-detail-table th,
.dev-game-detail-table td {
  padding: 0.75rem 1rem;
  text-align: left;
  border-bottom: 1px solid var(--vs-border);
  color: var(--vs-text);
  font-size: 0.95rem;
}

.dev-game-detail-table th {
  font-weight: 600;
  color: var(--vs-text-muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.dev-game-detail-table tbody tr:last-child td {
  border-bottom: none;
}

.dev-game-detail-table tbody tr:hover td {
  background: rgba(255, 255, 255, 0.02);
}

.dev-game-detail-event-link {
  color: var(--vs-link);
  text-decoration: none;
}

.dev-game-detail-event-link:hover {
  text-decoration: underline;
}

.dev-game-detail-status {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border-radius: 6px;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
}

.dev-game-detail-status--pending {
  background: rgba(234, 179, 8, 0.2);
  color: #eab308;
}

.dev-game-detail-status--live {
  background: rgba(34, 197, 94, 0.2);
  color: #22c55e;
}

.dev-game-detail-status--ended {
  background: rgba(148, 163, 184, 0.2);
  color: var(--vs-dim);
}

.dev-game-detail-status--cancelled {
  background: rgba(248, 113, 113, 0.2);
  color: var(--vs-fault);
}

.dev-game-detail-table code {
  font-size: 0.85em;
  color: var(--vs-text-muted);
}

.dev-game-detail-muted {
  color: var(--vs-text-muted);
  font-size: 0.95rem;
  margin: 0;
}

.dev-game-detail-error {
  color: var(--vs-fault);
  font-size: 0.95rem;
  margin: 0;
}

.dev-game-detail-success {
  color: var(--vs-on);
  font-size: 0.9rem;
  font-weight: 500;
}

.dev-game-detail-stats {
  margin-top: 1.5rem;
}

.dev-game-detail-stats .dev-game-detail-create-btn {
  cursor: pointer;
  border: none;
}

.dev-game-detail-stats .dev-game-detail-create-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.dev-game-detail-stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
  gap: 1.5rem;
}

.dev-game-detail-stats-category {
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  padding: 1rem;
  background: rgba(255, 255, 255, 0.02);
}

.dev-game-detail-stats-cat-title {
  margin: 0 0 0.75rem;
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--vs-text-muted);
}

.dev-game-detail-stats-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.dev-game-detail-stats-item {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 0.5rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid rgba(51, 65, 85, 0.5);
  font-size: 0.9rem;
}

.dev-game-detail-stats-item:last-child {
  border-bottom: none;
}

.dev-game-detail-stats-item label {
  cursor: pointer;
  color: var(--vs-text);
  flex: 1;
}

.dev-game-detail-stats-item input[type="checkbox"] {
  margin-right: 0.5rem;
}

.dev-game-detail-stats-item code {
  font-size: 0.8em;
  color: var(--vs-text-muted);
}

.dev-game-detail-stats-desc {
  color: var(--vs-text-muted);
  font-size: 0.85em;
}

.dev-game-detail-stats-meta {
  font-size: 0.75rem;
  color: var(--vs-text-muted);
  white-space: nowrap;
}

.dev-game-detail-leaderboard-preview {
  margin-top: 1.5rem;
}

.dev-game-detail-lb-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  align-items: center;
}

.dev-game-detail-lb-select {
  padding: 0.5rem 0.75rem;
  font-size: 0.9rem;
  border-radius: 8px;
  border: 1px solid var(--vs-border);
  background: var(--vs-card);
  color: var(--vs-text);
  min-width: 12rem;
}

.dev-game-detail-lb-load {
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  border-radius: 8px;
  border: none;
  background: var(--vs-primary);
  color: #fff;
  cursor: pointer;
  font-weight: 500;
}

.dev-game-detail-lb-load:hover:not(:disabled) {
  background: var(--vs-primary-hover);
}

.dev-game-detail-lb-load:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.dev-game-detail-lb-table-wrap {
  margin-top: 1.25rem;
  overflow-x: auto;
}

.dev-game-detail-lb-table th,
.dev-game-detail-lb-table td {
  white-space: nowrap;
}

.dev-game-detail-lb-table td {
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: normal;
}

.dev-game-detail-analytics {
  margin-top: 1.5rem;
}

.dev-game-detail-summary {
  margin-bottom: 1.5rem;
}

.dev-game-detail-analytics-days {
  display: flex;
  gap: 0.5rem;
}

.dev-game-detail-analytics-day-btn {
  padding: 0.35rem 0.75rem;
  font-size: 0.85rem;
  border-radius: 6px;
  border: 1px solid var(--vs-border);
  background: transparent;
  color: var(--vs-text-muted);
  cursor: pointer;
}

.dev-game-detail-analytics-day-btn:hover {
  color: var(--vs-text);
  border-color: var(--vs-text-muted);
}

.dev-game-detail-analytics-day-btn--active {
  background: var(--vs-primary);
  border-color: var(--vs-primary);
  color: #fff;
}

.dev-game-detail-analytics-h3 {
  margin: 0 0 0.75rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-game-detail-funnel {
  margin-bottom: 1.5rem;
}

.dev-game-detail-funnel-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
  gap: 1rem;
}

.dev-game-detail-funnel-item {
  padding: 0.75rem 1rem;
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.02);
}

.dev-game-detail-funnel-label {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--vs-text-muted);
  margin-bottom: 0.25rem;
}

.dev-game-detail-funnel-value {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-game-detail-daily-totals {
  margin-bottom: 1.5rem;
}

.dev-game-detail-top-events {
  margin-top: 0.5rem;
}

.dev-game-detail-top-events .dev-game-detail-table {
  margin-top: 0.5rem;
}

/* Template creator: type + presets + JSON */
.dev-template-create-type {
  margin-bottom: 1.5rem;
}
.dev-template-create-type label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 500;
  color: var(--vs-text);
}
.dev-template-create-type-options {
  display: flex;
  gap: 0.75rem;
  flex-wrap: wrap;
}
.dev-template-create-type-options input {
  margin-right: 0.35rem;
}
.dev-template-create-row {
  display: grid;
  grid-template-columns: 200px minmax(32rem, 1fr);
  gap: 1.5rem;
  align-items: start;
}
@media (max-width: 720px) {
  .dev-template-create-row {
    grid-template-columns: 1fr;
  }
}
.dev-template-create-presets {
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  padding: 0.75rem;
  background: rgba(0, 0, 0, 0.2);
}
.dev-template-create-presets h4 {
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
  color: var(--vs-text-muted);
}
.dev-template-create-preset-btn {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.6rem;
  margin-bottom: 0.25rem;
  border: 1px solid var(--vs-border);
  border-radius: 6px;
  background: var(--vs-card);
  color: var(--vs-text);
  cursor: pointer;
  font-size: 0.9rem;
}
.dev-template-create-preset-btn:hover {
  background: rgba(255, 255, 255, 0.06);
  border-color: var(--vs-primary);
}
.dev-template-create-preset-btn.active {
  border-color: var(--vs-primary);
  background: rgba(0, 102, 255, 0.15);
  color: var(--vs-primary);
}
.dev-template-create-json-wrap {
  min-width: 0;
}
.dev-template-create-json-wrap label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: 500;
  color: var(--vs-text);
}
.dev-template-create-json-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}
.dev-template-create-json-wrap textarea {
  width: 100%;
  min-width: 32rem;
  min-height: 280px;
  font-family: monospace;
  font-size: 0.85rem;
  resize: vertical;
}

/* —— Game overview (mock-aligned dashboard) —— */
.dev-game-overview-flash {
  margin: 0 0 1rem;
  padding: 0.65rem 1rem;
  border-radius: 8px;
  background: rgba(34, 197, 94, 0.15);
  border: 1px solid rgba(34, 197, 94, 0.35);
  color: #86efac;
  font-size: 0.9rem;
}

.dev-game-overview-hero {
  margin-bottom: 1.5rem;
}

.dev-game-overview-hero-main {
  background: var(--vs-card);
  border: 1px solid var(--vs-border);
  border-radius: 12px;
  padding: 1.5rem 1.75rem;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
}

.dev-game-overview-top-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}

.dev-game-overview-brand {
  display: flex;
  align-items: flex-start;
  gap: 1.25rem;
  min-width: 0;
}

.dev-game-overview-icon-wrap {
  width: 96px;
  height: 96px;
  border-radius: 12px;
  border: 1px solid var(--vs-border);
  background: #0a0a0a;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.dev-game-overview-icon-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.dev-game-overview-icon-fallback {
  font-size: 1.75rem;
  font-weight: 700;
  letter-spacing: -0.04em;
  color: #fff;
  background: linear-gradient(145deg, #1e3a8a, #4f46e5);
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.dev-game-overview-headlines {
  min-width: 0;
}

.dev-game-overview-title {
  margin-top: 0;
}

.dev-game-overview-edit-btn {
  display: inline-block;
  padding: 0.55rem 1.15rem;
  background: var(--vs-primary);
  color: #fff !important;
  border-radius: 8px;
  text-decoration: none;
  font-size: 0.9rem;
  font-weight: 500;
  white-space: nowrap;
  transition: background 0.2s;
}

.dev-game-overview-edit-btn:hover {
  background: var(--vs-primary-hover);
}

.dev-game-overview-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}

.dev-game-overview-delete-btn {
  padding: 0.55rem 1rem;
  background: transparent;
  color: #f3a7b6;
  border: 1px solid rgba(168, 58, 79, 0.6);
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.2s;
}

.dev-game-overview-delete-btn:hover:not(:disabled) {
  background: rgba(168, 58, 79, 0.18);
}

.dev-game-overview-delete-btn:disabled {
  opacity: 0.5;
  cursor: default;
}

.dev-game-overview-meta {
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .dev-game-overview-meta {
    grid-template-columns: 1fr 1fr;
  }
}

.dev-game-overview-grid {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(300px, 1fr);
  gap: 1.25rem;
  align-items: start;
}

@media (max-width: 960px) {
  .dev-game-overview-grid {
    grid-template-columns: 1fr;
  }
}

.dev-game-overview-card {
  background: var(--vs-card);
  border: 1px solid var(--vs-border);
  border-radius: 12px;
  padding: 1.35rem 1.5rem;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25);
}

.dev-game-overview-card-title {
  margin: 0 0 1rem;
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-game-overview-stats-totals {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: var(--vs-text-muted);
}

.dev-game-overview-stats-totals strong {
  color: var(--vs-text);
  font-weight: 600;
  margin-left: 0.25rem;
}

.dev-game-overview-table-wrap {
  overflow-x: auto;
}

.dev-game-overview-stats-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.dev-game-overview-stats-table th,
.dev-game-overview-stats-table td {
  text-align: right;
  padding: 0.55rem 0.65rem;
  border-bottom: 1px solid #1e293b;
  color: var(--vs-text);
}

.dev-game-overview-stats-table thead th {
  text-align: right;
  color: var(--vs-text-muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.dev-game-overview-stats-table thead th:first-child,
.dev-game-overview-stats-table tbody th {
  text-align: left;
}

.dev-game-overview-stats-table tbody th {
  font-weight: 500;
  color: var(--vs-text-muted);
}

.dev-game-overview-sample-note {
  margin: 0.85rem 0 0;
  font-size: 0.75rem;
  color: #64748b;
  line-height: 1.35;
}

.dev-game-overview-performance-card .perf-preview {
  margin-top: -0.25rem;
}

.dev-game-overview-performance-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.5rem;
}

.dev-game-overview-performance-head .dev-game-overview-card-title {
  margin-bottom: 0;
}

.dev-game-overview-series-select-label {
  margin: 0;
}

.dev-game-overview-series-select {
  padding: 0.4rem 2rem 0.4rem 0.65rem;
  font-size: 0.8rem;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background: #fff;
  color: #0f172a;
  cursor: pointer;
  max-width: min(100%, 22rem);
}

.dev-game-overview-series-select option {
  color: #0f172a;
  background: #fff;
}

.dev-game-overview-series-title {
  margin: 0 0 0.35rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-game-overview-sdk-restricted {
  font-size: 0.85rem;
  color: var(--vs-text-muted);
  line-height: 1.45;
}

.dev-game-overview-metrics-error {
  margin: 0 0 0.75rem;
  font-size: 0.9rem;
  color: var(--vs-fault);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Integration health card */
.dev-game-overview-advice { list-style: none; padding: 0; margin: 0 0 12px; }
.dev-game-overview-advice li { padding: 8px 10px; border-radius: 6px; margin-bottom: 6px; font-size: 0.92rem; }
.dev-game-overview-advice-problem { background: rgba(220, 53, 69, 0.12); border-left: 3px solid var(--vs-fault); }
.dev-game-overview-advice-warning { background: rgba(255, 193, 7, 0.14); border-left: 3px solid #e0a800; }
.dev-game-overview-advice-info { background: rgba(13, 110, 253, 0.10); border-left: 3px solid #0d6efd; }
.dev-game-overview-hourly { display: flex; align-items: flex-end; gap: 3px; height: 44px; margin: 8px 0 12px; }
.dev-game-overview-hourly-bar { flex: 1; min-width: 4px; background: rgba(13, 110, 253, 0.35); border-radius: 2px 2px 0 0; position: relative; }
.dev-game-overview-hourly-err { position: absolute; left: 0; right: 0; bottom: 0; background: var(--vs-fault); border-radius: 0 0 2px 2px; }
.ges-desc {
  margin: 0 0 0.75rem;
  font-size: 0.92rem;
  opacity: 0.85;
  max-width: 70ch;
}

.ges-muted {
  opacity: 0.6;
  font-size: 0.88rem;
}

.ges-hint {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.78rem;
  opacity: 0.6;
}

.ges-notice {
  margin: 0.5rem 0;
  color: var(--vs-on);
}

.ges-error {
  margin: 0.5rem 0;
  color: var(--vs-fault);
}

.ges-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 0.85rem;
  margin-bottom: 0.85rem;
}

.ges-grid label,
.ges-template {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.9rem;
}

.ges-grid input,
.ges-grid select,
.ges-template textarea {
  padding: 0.5rem 0.6rem;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(255, 255, 255, 0.05);
  color: inherit;
  font: inherit;
}

.ges-template textarea {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.82rem;
  line-height: 1.45;
}

.ges-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.ges-btn {
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
  border: none;
  background: var(--vs-act);
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.ges-btn:disabled {
  opacity: 0.6;
  cursor: default;
}

.ges-btn--ghost {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: inherit;
  font-weight: 500;
}

.ges-preview {
  margin-top: 1rem;
  padding: 0.75rem 1rem;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.04);
}

.ges-preview h4 {
  margin: 0 0 0.4rem;
  font-size: 0.9rem;
}

.ges-preview ul {
  margin: 0;
  padding-inline-start: 1.1rem;
  font-size: 0.85rem;
  opacity: 0.85;
}

.ges-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.ges-table th,
.ges-table td {
  text-align: start;
  padding: 0.55rem 0.6rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  vertical-align: top;
}

.ges-table th {
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.6;
}

.ges-row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.ges-link {
  background: none;
  border: none;
  padding: 0;
  color: var(--vs-act);
  font: inherit;
  cursor: pointer;
}

.ges-link--danger {
  color: var(--vs-fault);
}

.ges-chip {
  display: inline-block;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  font-size: 0.75rem;
  background: rgba(255, 255, 255, 0.1);
}

.ges-chip--live {
  background: rgba(34, 197, 94, 0.22);
  color: var(--vs-on);
}

.ges-chip--pending {
  background: rgba(59, 130, 246, 0.22);
  color: #a9c9ff;
}

.ges-chip--paused {
  background: rgba(245, 158, 11, 0.22);
  color: #ffd479;
}

/* ------------------------------------------------------------------------------------
 * Schedule cards.
 *
 * Same frame as an event card (GameEvents.css) so the two screens read as one family.
 * What changes is the hierarchy: an event card foregrounds the tournament, a schedule
 * card foregrounds when the automation next fires, because that is the thing a developer
 * is actually checking.
 * ---------------------------------------------------------------------------------- */

.ges {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
  min-width: 0;
}

/* The page still carries legacy cards for the header and the create form; give them the
   spacing the shared container used to swallow. */
.ges > .dev-game-detail-card {
  margin: 0;
}

.ges-card {
  font-variant-numeric: tabular-nums;
}

/* ---- Next event: the strongest detail after the name ---- */

.ges-next {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-sm);
  background: var(--vs-void);
}

.ges-next-label {
  font-size: 0.75rem;
  color: var(--vs-dim);
}

.ges-next-when {
  font-size: 1.0625rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--vs-chalk);
}

.ges-next-rel {
  font-size: 0.78rem;
  color: var(--vs-warn);
}

.ges-next-none {
  font-size: 0.875rem;
  color: var(--vs-dim);
  line-height: 1.45;
}

.ges-current-link {
  color: var(--vs-act);
  text-decoration: none;
}

.ges-current-link:hover {
  color: var(--vs-act);
  text-decoration: underline;
}

/* ---- Footer: three labelled actions plus the destructive one behind an overflow ---- */

.ges-foot {
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: var(--vs-s2);
}

.ges-menu {
  margin-inline-start: auto;
}

.ges-msg {
  margin: 0;
  font-size: 0.9rem;
}

.ges-dst {
  margin: var(--vs-s3) 0 0;
  padding: var(--vs-s3);
  border-inline-start: 3px solid var(--vs-warn);
  border-radius: var(--vs-r-sm);
  background: var(--vs-warn-wash);
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--vs-chalk);
  max-width: 80ch;
}
.mm { color: var(--vs-chalk); }
.mm-back { color: var(--vs-act); text-decoration: none; font-size: 0.9rem; }
.mm h1 { font-size: 1.5rem; margin: 0.5rem 0 0.25rem; }
.mm-desc { color: var(--vs-dim); max-width: 62ch; margin: 0 0 1rem; }
.mm-error { background: #3a1620; border: 1px solid #a83a4f; color: var(--vs-fault); padding: 0.6rem 0.8rem; border-radius: 6px; margin-bottom: 1rem; }
.mm-empty { color: var(--vs-faint); font-style: italic; padding: 0.75rem 0; }

.mm-btn { background: var(--vs-act-fill); color: #fff; border: none; border-radius: 6px; padding: 0.5rem 0.9rem; cursor: pointer; font-size: 0.9rem; }
.mm-btn:disabled { opacity: 0.5; cursor: default; }
.mm-link-btn { background: none; border: none; color: var(--vs-act); cursor: pointer; padding: 0.2rem 0.4rem; font-size: 0.85rem; }
.mm-link-btn--danger { color: var(--vs-fault); }

.mm-table { width: 100%; border-collapse: collapse; margin-top: 1rem; }
.mm-table th, .mm-table td { text-align: left; padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--vs-rail-soft); font-size: 0.9rem; }
.mm-table th { color: #9a9aa8; }
.mm-row-actions { display: flex; gap: 0.4rem; justify-content: flex-end; }
.mm-badge { font-size: 0.72rem; text-transform: uppercase; padding: 0.15rem 0.5rem; border-radius: 999px; background: var(--vs-rail); color: var(--vs-dim); }
.mm-badge--premium { background: var(--vs-act-wash); color: var(--vs-act); }

.mm-form { background: #14141d; border: 1px solid var(--vs-rail); border-radius: 8px; padding: 1rem; margin-top: 1.25rem; max-width: 760px; }
.mm-form h3 { margin: 0 0 0.75rem; }
.mm-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0.75rem; }
.mm-fr { display: flex; flex-direction: column; gap: 0.3rem; }
.mm-fr label { font-size: 0.82rem; color: var(--vs-dim); }
.mm-fr input { background: var(--vs-void); border: 1px solid var(--vs-rail); color: var(--vs-chalk); border-radius: 6px; padding: 0.45rem; font-size: 0.9rem; }
.mm-premium-toggle { margin: 1rem 0 0.5rem; padding-top: 0.75rem; border-top: 1px solid var(--vs-rail-soft); }
.mm-premium { background: var(--vs-void); border: 1px solid var(--vs-act-wash); border-radius: 8px; padding: 0.75rem; }
.mm-form-actions { display: flex; gap: 0.75rem; align-items: center; margin-top: 1rem; }
.elo-ladder-callout {
  border-radius: 10px;
  padding: 0.85rem 1rem;
  margin: 0.75rem 0 1rem;
  border: 1px solid var(--vs-border, #334155);
  background: rgba(15, 23, 42, 0.6);
}

.elo-ladder-callout--detail {
  margin: 0 0 1.25rem;
  padding: 1rem 1.15rem;
}

.elo-ladder-callout--form {
  max-width: 100%;
}

.elo-ladder-callout--ladder {
  border-color: rgba(251, 191, 36, 0.45);
  background: rgba(120, 53, 15, 0.2);
}

.elo-ladder-callout--ranked {
  border-color: rgba(96, 165, 250, 0.5);
  background: rgba(30, 58, 138, 0.25);
}

.elo-ladder-callout__badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  margin-bottom: 0.45rem;
  color: var(--vs-text, #f1f5f9);
  opacity: 0.95;
}

.elo-ladder-callout__text {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.45;
  color: var(--vs-text-muted, #94a3b8);
}

.elo-ladder-callout__text strong {
  color: var(--vs-text, #f1f5f9);
  font-weight: 600;
}

.elo-ladder-mode-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.55rem;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  vertical-align: middle;
}

.elo-ladder-mode-badge--ladder {
  background: rgba(120, 53, 15, 0.45);
  color: #fcd34d;
  border: 1px solid rgba(251, 191, 36, 0.35);
}

.elo-ladder-mode-badge--ranked {
  background: rgba(30, 58, 138, 0.55);
  color: #93c5fd;
  border: 1px solid rgba(96, 165, 250, 0.4);
}
/* Create event — centered card, uses space well */

.dev-create-event {
  /* Local names kept so every rule below still resolves, but they now read from
     src/styles/tokens.css instead of a private palette. The field background in
     particular was pure black and the card was #111. */
  --vs-primary: var(--vs-act-fill);
  --vs-primary-hover: var(--vs-act-fill-hi);
  --vs-link: var(--vs-act);
  --vs-bg: var(--vs-void);
  --vs-card: var(--vs-deck);
  --vs-text: var(--vs-chalk);
  --vs-text-muted: var(--vs-dim);
  --vs-border: var(--vs-rail);

  width: 100%;
  box-sizing: border-box;
  font-family: var(--vs-font);
}

.dev-create-event-back {
  color: var(--vs-link);
  text-decoration: none;
  font-size: 0.9rem;
  margin-bottom: 1rem;
  display: inline-block;
}

.dev-create-event-back:hover {
  text-decoration: underline;
}

.dev-create-event-muted {
  color: var(--vs-text-muted);
  margin: 1rem 0;
}

.dev-create-event-hint {
  color: var(--vs-text-muted);
  margin: 0 0 1rem;
  font-size: 0.9rem;
}

/* Centered card: block + margin auto so it always centers in the main area */
.dev-create-event-card {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  background: var(--vs-card);
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-md);
  padding: var(--vs-s5);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
  box-sizing: border-box;
}

.dev-create-event-card h1 {
  margin: 0 0 1.5rem;
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-create-event-modes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1.75rem;
}

.dev-create-event-mode {
  padding: 0.5rem 1rem;
  font-size: 0.9rem;
  border-radius: 8px;
  border: 1px solid var(--vs-border);
  background: transparent;
  color: var(--vs-text-muted);
  cursor: pointer;
  transition: background 0.2s, color 0.2s, border-color 0.2s;
}

.dev-create-event-mode:hover {
  color: var(--vs-text);
  border-color: var(--vs-text-muted);
}

.dev-create-event-mode.active {
  background: var(--vs-primary);
  color: #fff;
  border-color: var(--vs-primary);
}

.dev-create-event-form {
  display: flex;
  flex-direction: column;
  gap: 0;
}

.dev-create-event-section {
  margin-bottom: 1.5rem;
}

.dev-create-event-section h2 {
  margin: 0 0 1rem;
  font-size: 1rem;
  font-weight: 600;
  color: var(--vs-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.dev-create-event-subsection {
  margin: 1rem 0 0.5rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--vs-text-muted);
}

.dev-create-event-label {
  display: block;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--vs-text);
  margin-bottom: 0.35rem;
  margin-top: 0.75rem;
}

.dev-create-event-label:first-of-type {
  margin-top: 0;
}

.dev-create-event-label-row {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.dev-create-event-label-text {
  font-weight: 500;
}

.dev-create-event-info-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.dev-create-event-info-wrap--inline {
  margin-left: 0.25rem;
}

.dev-create-event-info-icon {
  width: 1rem;
  height: 1rem;
  border-radius: 50%;
  border: 1px solid var(--vs-text-muted);
  color: var(--vs-text-muted);
  font-size: 0.65rem;
  font-weight: 600;
  font-style: normal;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: help;
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s;
}

.dev-create-event-info-icon:hover {
  color: var(--vs-text);
  border-color: var(--vs-text-muted);
}

.dev-create-event-tooltip {
  position: absolute;
  bottom: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-bottom: 6px;
  padding: 0.5rem 0.65rem;
  max-width: 280px;
  width: max-content;
  background: #1e293b;
  border: 1px solid var(--vs-border);
  border-radius: 6px;
  font-size: 0.8rem;
  color: var(--vs-text);
  line-height: 1.4;
  white-space: normal;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s, visibility 0.15s;
  pointer-events: none;
  z-index: 20;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}

.dev-create-event-info-wrap:hover .dev-create-event-tooltip {
  opacity: 1;
  visibility: visible;
}

.dev-create-event-input {
  width: 100%;
  min-height: 44px;
  padding: 0.55rem 0.75rem;
  box-sizing: border-box;
  border: 1px solid var(--vs-border);
  border-radius: var(--vs-r-sm);
  font-size: 0.9375rem;
  color: var(--vs-text);
  background: var(--vs-bg);
  outline: none;
  color-scheme: dark;
  transition: border-color 0.2s, box-shadow 0.2s;
}

.dev-create-event-input:hover {
  border-color: var(--vs-faint);
}

.dev-create-event-input:focus {
  border-color: var(--vs-act);
  box-shadow: 0 0 0 3px var(--vs-act-wash);
}

.dev-create-event-input::placeholder {
  color: var(--vs-text-muted);
}

select.dev-create-event-input {
  cursor: pointer;
  appearance: auto;
}

textarea.dev-create-event-input {
  resize: vertical;
  min-height: 80px;
  font-family: inherit;
}

.dev-create-event-check {
  display: flex;
  /* Explicit: App.css sets `form label { flex-direction: column }`, which stacked the
     checkbox above its own text and centred both. */
  flex-direction: row;
  align-items: center;
  gap: 0.5rem;
  margin-top: 1rem;
  font-size: 0.9rem;
  color: var(--vs-text);
  cursor: pointer;
}

.dev-create-event-check input {
  width: 1rem;
  height: 1rem;
  cursor: pointer;
}

.dev-create-event-error {
  margin: 1rem 0 0;
  font-size: 0.875rem;
  color: #f87171;
}

.dev-create-event-btn {
  width: 100%;
  padding: 0.75rem 1.25rem;
  margin-top: 0.5rem;
  background: var(--vs-primary);
  color: #fff;
  border: none;
  border-radius: 8px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.2s;
}

.dev-create-event-btn:hover:not(:disabled) {
  background: var(--vs-primary-hover);
}

.dev-create-event-btn:disabled {
  opacity: 0.7;
  cursor: not-allowed;
}

/* ELO: separate “Ladder vs Ranked” from optional tier JSON */
.dev-create-event-elo-tiers-panel {
  margin-top: 0.25rem;
  padding: 1rem 1.1rem 1.15rem;
  border-radius: 10px;
  border: 1px dashed var(--vs-border);
  background: rgba(15, 23, 42, 0.35);
}

.dev-create-event-elo-tiers-panel-title {
  margin: 0 0 0.35rem;
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--vs-text-muted);
}

.dev-create-event-elo-tiers-panel-hint {
  margin: 0 0 1rem;
  font-size: 0.85rem;
  line-height: 1.45;
  color: var(--vs-text-muted);
}

.dev-create-event-elo-tiers-panel-hint strong {
  color: var(--vs-text);
  font-weight: 600;
}

/* ------------------------------------------------------------------------------------
 * Create event, restructured.
 *
 * The form used to be one 360px column inside an 885px panel, so most of every row was
 * empty. It is now a form column beside a summary that reads back what is about to be
 * created, which both uses the space and catches mistakes before submitting.
 *
 * The format-specific blocks still use the .dev-create-event-* classes; they are styled
 * as panels here rather than rewritten, so no format-specific control moved.
 * ---------------------------------------------------------------------------------- */

.cev {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
  min-width: 0;
}

.cev-crumbs {
  display: flex;
  align-items: center;
  gap: var(--vs-s1);
  font-size: 0.8125rem;
  color: var(--vs-faint);
}

.cev-crumb {
  color: var(--vs-dim);
  text-decoration: none;
}

a.cev-crumb:hover {
  color: var(--vs-chalk);
}

.cev-crumb--here {
  color: var(--vs-chalk);
  font-weight: 550;
}

.cev-notice {
  margin: 0;
}

.cev-head h1 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 650;
  letter-spacing: -0.02em;
  color: var(--vs-chalk);
}

.cev-head-sub {
  margin: 0.25rem 0 0;
  font-size: 0.875rem;
  color: var(--vs-dim);
}

/* ---- Two columns: the form, and what it adds up to ---- */

.cev-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 330px);
  gap: var(--vs-s4);
  align-items: start;
}

@media (max-width: 1040px) {
  .cev-layout {
    grid-template-columns: minmax(0, 1fr);
  }
}

.cev-main,
.cev-form {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
  min-width: 0;
  /* App.css caps the bare `form` element at 360px, which is where the narrow column came
     from in the first place. */
  max-width: none;
}

.cev-panel,
.cev-main .dev-create-event-section {
  padding: var(--vs-s5);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--vs-s4);
}

/* The legacy blocks lay out label/control pairs as plain siblings; keep them readable
   without touching their markup. */
.cev-main .dev-create-event-section {
  gap: 0.35rem;
}

.cev-main .dev-create-event-section > h2 {
  margin: 0 0 var(--vs-s2);
  font-size: 1rem;
  font-weight: 650;
  color: var(--vs-chalk);
  text-transform: none;
  letter-spacing: -0.005em;
}

.cev-main .dev-create-event-section > .dev-create-event-label {
  margin-top: var(--vs-s3);
}

.cev-panel-head h2 {
  margin: 0;
  font-size: 1rem;
  font-weight: 650;
  color: var(--vs-chalk);
}

.cev-panel-sub {
  margin: 0.25rem 0 0;
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--vs-dim);
  max-width: 70ch;
}

/* ---- Format picker ---- */

.cev-variants {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  flex-wrap: wrap;
}

.cev-variants-label {
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

.cev-format-done {
  display: flex;
  justify-content: flex-end;
}

.cev-format-chosen {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
}

.cev-format-chosen-text {
  display: flex;
  align-items: baseline;
  gap: var(--vs-s2);
  flex: 1;
  min-width: 0;
  flex-wrap: wrap;
}

.cev-format-chosen-text strong {
  font-size: 0.9375rem;
  color: var(--vs-chalk);
}

.cev-format-chosen-variant {
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

/* ---- Guest toggle ---- */

.cev-toggle-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  align-items: flex-start;
}

/* ---- Prizes ---- */

.cev-prize-readout {
  padding: var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-sm);
  background: var(--vs-void);
}

.cev-prize-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.cev-prize-list li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vs-s3);
  font-size: 0.8125rem;
}

.cev-prize-place {
  color: var(--vs-dim);
}

.cev-adv > summary {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.2rem 0;
  list-style: none;
  cursor: pointer;
  font-size: 0.8125rem;
  color: var(--vs-dim);
  border-radius: var(--vs-r-sm);
}

.cev-adv > summary::-webkit-details-marker {
  display: none;
}

.cev-adv > summary::before {
  content: "";
  width: 0;
  height: 0;
  flex: none;
  border-left: 4px solid currentColor;
  border-top: 3.5px solid transparent;
  border-bottom: 3.5px solid transparent;
  transition: transform 0.15s ease;
}

.cev-adv[open] > summary::before {
  transform: rotate(90deg);
}

.cev-adv > summary:hover {
  color: var(--vs-chalk);
}

.cev-adv > summary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--vs-deck), 0 0 0 4px var(--vs-act);
}

.cev-adv > * + * {
  margin-top: var(--vs-s2);
}

/* ---- Summary ---- */

.cev-summary {
  min-width: 0;
}

.cev-summary-card {
  position: sticky;
  top: var(--vs-s4);
  display: flex;
  flex-direction: column;
  gap: var(--vs-s2);
  padding: var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  font-variant-numeric: tabular-nums;
}

.cev-summary-game {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  padding-bottom: var(--vs-s2);
  border-bottom: 1px solid var(--vs-rail-soft);
}

.cev-summary-icon {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck-hi);
  color: var(--vs-dim);
}

.cev-summary-gname {
  font-size: 0.8125rem;
  color: var(--vs-dim);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cev-summary-name {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--vs-chalk);
  overflow-wrap: anywhere;
}

.cev-summary-format {
  margin: -0.35rem 0 0;
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

.cev-summary-facts {
  margin: var(--vs-s2) 0 0;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.cev-summary-facts > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vs-s3);
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--vs-rail-soft);
}

.cev-summary-facts > div:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.cev-summary-facts dt {
  font-size: 0.75rem;
  color: var(--vs-dim);
  flex: none;
}

.cev-summary-facts dd {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--vs-chalk);
  text-align: end;
  min-width: 0;
  overflow-wrap: anywhere;
}

/* ---- Action bar ---- */

.cev-bar {
  margin-top: 0;
}

@media (prefers-reduced-motion: reduce) {
  .cev-adv > summary::before {
    transition: none;
  }
}

/* Three classes both event forms have always used with no rule behind them, so every
   "two fields on a row" in the promo and score-range blocks was quietly stacking. */
.dev-create-event-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--vs-s3);
}

@media (max-width: 560px) {
  .dev-create-event-row {
    grid-template-columns: minmax(0, 1fr);
  }
}

.dev-create-event-subsection-wrap {
  margin-top: var(--vs-s4);
  padding: var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-sm);
  background: var(--vs-void);
}

.dev-create-event-success {
  margin: var(--vs-s3) 0 0;
  font-size: 0.875rem;
  color: var(--vs-on);
}
/* Event detail — same dark style as GameDetail */

.dev-event-detail {
  --vs-primary: #0066ff;
  --vs-primary-hover: #0052cc;
  --vs-link: #3b82f6;
  --vs-card: #111;
  --vs-text: #f1f5f9;
  --vs-text-muted: #94a3b8;
  --vs-border: #334155;
  max-width: 900px;
  margin: 0 auto;
}

.dev-event-detail-back {
  color: var(--vs-link);
  text-decoration: none;
  font-size: 0.9rem;
  margin-bottom: 1.5rem;
  display: inline-block;
}

.dev-event-detail-back:hover {
  text-decoration: underline;
}

.dev-event-detail-card {
  background: var(--vs-card);
  border: 1px solid var(--vs-border);
  border-radius: 12px;
  padding: 2rem;
  margin-bottom: 1.5rem;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.3);
}

.dev-event-detail-info {
  margin-bottom: 1.5rem;
}

.dev-event-detail-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}

.dev-event-detail-head-right {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.dev-event-detail-btn {
  padding: 0.4rem 0.75rem;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 500;
  text-decoration: none;
  border: none;
  cursor: pointer;
  transition: background 0.2s, color 0.2s;
}

.dev-event-detail-btn-edit {
  background: var(--vs-primary, #0066ff);
  color: #fff;
}

.dev-event-detail-btn-edit:hover {
  background: var(--vs-primary-hover, #0052cc);
}

.dev-event-detail-btn-cancel {
  background: transparent;
  color: #f87171;
  border: 1px solid #f87171;
}

.dev-event-detail-btn-cancel:hover:not(:disabled) {
  background: rgba(248, 113, 113, 0.15);
}

.dev-event-detail-btn-cancel:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.dev-event-detail-btn-finalize {
  background: var(--vs-primary, #0066ff);
  color: #fff;
}

.dev-event-detail-btn-finalize:hover:not(:disabled) {
  background: var(--vs-primary-hover, #0052cc);
}

.dev-event-detail-btn-finalize:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.dev-event-detail-prizes-actions {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.dev-event-detail-prizes-actions .dev-event-detail-hint {
  font-size: 0.85rem;
  color: var(--vs-text-muted);
}

.dev-event-detail-success {
  color: #22c55e;
  font-size: 0.95rem;
  margin: 0.5rem 0 0;
}

.dev-event-detail-name {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-event-detail-status {
  display: inline-block;
  padding: 0.25rem 0.6rem;
  border-radius: 6px;
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
}

.dev-event-detail-status--pending {
  background: rgba(234, 179, 8, 0.2);
  color: #eab308;
}

.dev-event-detail-status--live {
  background: rgba(34, 197, 94, 0.2);
  color: #22c55e;
}

.dev-event-detail-status--ended {
  background: rgba(148, 163, 184, 0.2);
  color: #94a3b8;
}

.dev-event-detail-status--cancelled {
  background: rgba(248, 113, 113, 0.2);
  color: #f87171;
}

.dev-event-detail-participants-wrap {
  display: inline-flex;
  align-items: center;
  gap: 0.75rem;
}

.dev-event-detail-players-link {
  color: var(--vs-link);
  font-size: 0.9rem;
  text-decoration: none;
}

.dev-event-detail-players-link:hover {
  text-decoration: underline;
}

.dev-event-detail-meta {
  display: grid;
  gap: 0.75rem;
  margin: 0;
}

.dev-event-detail-meta-row dt {
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--vs-text-muted);
  margin-bottom: 0.2rem;
}

.dev-event-detail-meta-row dd {
  margin: 0;
  font-size: 0.95rem;
  color: var(--vs-text);
}

.dev-event-detail-meta code {
  font-size: 0.85em;
  color: var(--vs-text-muted);
}

.dev-event-detail-id-wrap {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.dev-event-detail-copy {
  padding: 0.25rem 0.6rem;
  font-size: 0.8rem;
  border-radius: 6px;
  border: 1px solid var(--vs-border);
  background: transparent;
  color: var(--vs-text-muted);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s;
}

.dev-event-detail-copy:hover {
  color: var(--vs-text);
  border-color: var(--vs-text-muted);
}

.dev-event-detail-section-title {
  margin: 0;
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-event-detail-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}

.dev-event-detail-mode-value {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.65rem;
}

.dev-event-detail-pre {
  margin: 0;
  font-size: 0.85rem;
  color: var(--vs-text-muted);
  white-space: pre-wrap;
  word-break: break-all;
  max-height: 8rem;
  overflow: auto;
}

.dev-event-detail-muted {
  color: var(--vs-text-muted);
  font-size: 0.95rem;
  margin: 0;
}

.dev-event-detail-error {
  color: #f87171;
  font-size: 0.95rem;
  margin: 0;
}

/* Brand-funded event banner */
.dev-event-sponsor {
  border: 1px solid rgba(255, 212, 121, 0.35);
}

.dev-event-sponsor-banner {
  width: 100%;
  max-height: 140px;
  object-fit: cover;
  border-radius: 8px;
  margin-bottom: 0.75rem;
}

.dev-event-sponsor-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.dev-event-sponsor-logo {
  width: 48px;
  height: 48px;
  border-radius: 8px;
  object-fit: cover;
}

.dev-event-sponsor-name {
  font-weight: 600;
  color: #ffd479;
}

.dev-event-sponsor-tagline {
  font-size: 0.9rem;
  opacity: 0.85;
}

.dev-event-sponsor-meta {
  font-size: 0.85rem;
  opacity: 0.7;
}
.dev-event-participants {
  --vs-link: #3b82f6;
  --vs-card: #111;
  --vs-text: #f1f5f9;
  --vs-text-muted: #94a3b8;
  --vs-border: #334155;
  max-width: 1200px;
  margin: 0 auto;
}

.dev-event-participants-back {
  color: var(--vs-link);
  text-decoration: none;
  font-size: 0.9rem;
  margin-bottom: 1rem;
  display: inline-block;
}

.dev-event-participants-back:hover {
  text-decoration: underline;
}

.dev-event-participants-title {
  margin: 0 0 1.25rem;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--vs-text);
}

.dev-event-participants-muted,
.dev-event-participants-error {
  margin: 0;
  font-size: 0.95rem;
}

.dev-event-participants-muted {
  color: var(--vs-text-muted);
}

.dev-event-participants-error {
  color: #f87171;
}

.dev-event-participants-card {
  background: var(--vs-card);
  border: 1px solid var(--vs-border);
  border-radius: 12px;
  padding: 1.5rem;
  overflow-x: auto;
}

.dev-event-participants-table {
  width: 100%;
  border-collapse: collapse;
}

.dev-event-participants-table th,
.dev-event-participants-table td {
  padding: 0.6rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid var(--vs-border);
  color: var(--vs-text);
  font-size: 0.9rem;
}

.dev-event-participants-table th {
  font-weight: 600;
  color: var(--vs-text-muted);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  white-space: nowrap;
}

.dev-event-participants-table tbody tr:last-child td {
  border-bottom: none;
}

.dev-event-participants-table tbody tr:hover td {
  background: rgba(255, 255, 255, 0.02);
}

.dev-event-participants-id {
  font-size: 0.8em;
  color: var(--vs-text-muted);
  word-break: break-all;
}

.dev-event-participants-table .dev-event-participants-view-link {
  color: var(--vs-link);
  text-decoration: none;
}

.dev-event-participants-table .dev-event-participants-view-link:hover {
  text-decoration: underline;
}
.pending-games-section {
  margin-top: 2rem;
}

.pending-games-section:first-of-type {
  margin-top: 0;
}

.pending-games-section-title {
  font-size: 1.15rem;
  font-weight: 600;
  margin: 0 0 0.5rem;
}

.pending-games-section-hint {
  margin-top: 0;
  margin-bottom: 0.75rem;
}

.pending-games-table-wrap {
  overflow-x: auto;
  max-width: 100%;
}

.pending-games-table--wide {
  min-width: 720px;
}

.pending-games-sub {
  font-size: 0.75rem;
  opacity: 0.85;
  margin-top: 0.15rem;
}

.pending-games {
  --vs-text: #f1f5f9;
  --vs-text-muted: #94a3b8;
  --vs-border: #334155;
  --vs-link: #3b82f6;
}

.pending-games-back-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.35rem 0.5rem;
  margin-bottom: 1rem;
}

.pending-games-back {
  color: var(--vs-link);
  text-decoration: none;
  font-size: 0.9rem;
  margin-bottom: 1rem;
  display: inline-block;
}

.pending-games-back-row .pending-games-back {
  margin-bottom: 0;
}

.pending-games-back:hover {
  text-decoration: underline;
}

.pending-games h1 {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
  color: var(--vs-text);
}

.pending-games-desc {
  margin: 0 0 1.5rem;
  font-size: 0.9rem;
  color: var(--vs-text-muted);
}

.pending-games-loading,
.pending-games-empty {
  color: var(--vs-text-muted);
}

.pending-games-error {
  color: #f87171;
  margin-bottom: 1rem;
}

.pending-games-table {
  width: 100%;
  border-collapse: collapse;
  border: 1px solid var(--vs-border);
  border-radius: 8px;
  overflow: hidden;
}

.pending-games-table th,
.pending-games-table td {
  padding: 0.75rem 1rem;
  text-align: left;
  border-bottom: 1px solid var(--vs-border);
}

.pending-games-table th {
  background: rgba(0, 0, 0, 0.2);
  font-weight: 600;
}

.pending-games-btn {
  padding: 0.4rem 0.75rem;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  margin-right: 0.5rem;
  border: none;
}

.pending-games-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.pending-games-btn--approve {
  background: #4ade80;
  color: #000;
}

.pending-games-btn--approve:hover:not(:disabled) {
  background: #22c55e;
}

.pending-games-btn--reject {
  background: rgba(248, 113, 113, 0.3);
  color: #f87171;
}

.pending-games-btn--reject:hover:not(:disabled) {
  background: rgba(248, 113, 113, 0.5);
}

.pending-games-action {
  padding: 0.45rem 0.9rem;
  border-radius: 6px;
  font-size: 0.85rem;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid var(--vs-border);
  background: rgba(59, 130, 246, 0.25);
  color: var(--vs-text);
}

.pending-games-action:hover:not(:disabled) {
  background: rgba(59, 130, 246, 0.4);
}

.pending-games-action:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.pending-games-input {
  padding: 0.4rem 0.6rem;
  border-radius: 6px;
  border: 1px solid var(--vs-border);
  background: rgba(0, 0, 0, 0.25);
  color: var(--vs-text);
}

.pending-games-linkish {
  background: none;
  border: none;
  color: var(--vs-link);
  cursor: pointer;
  font-size: inherit;
  text-decoration: underline;
  padding: 0;
}

.pending-games-th-icon {
  width: 3rem;
}

.pending-games-cell-icon {
  width: 3rem;
  vertical-align: middle;
}

.pending-games-icon {
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 8px;
  background: rgba(148, 163, 184, 0.15);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--vs-text-muted);
  overflow: hidden;
}

.pending-games-icon--img {
  padding: 0;
  background: #0f172a;
}

.pending-games-icon--img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Search, filters and sort for the directory. The controls are the shared vsp- primitives from tokens.css, the same ones
   the staff games register uses, so the two pages behave and look alike. */
.pending-games-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.6rem;
  margin: 0 0 0.9rem;
}

.pending-games-search {
  flex: 1 1 16rem;
  max-width: 24rem;
}

.pending-games-company-select {
  max-width: 16rem;
}

.pending-games-count {
  color: var(--vs-text-muted);
  font-size: 0.85rem;
  white-space: nowrap;
}

.pending-games-no-match {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.pending-games-no-match p {
  margin: 0;
}

.pending-games-faint {
  color: var(--vs-text-muted);
}

.pending-games-table th.pending-games-th-num,
.pending-games-table td.pending-games-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Company logo beside the name on the admin Companies page. Contained rather than cropped, so a wide wordmark or a
   square icon both show whole. The tile is dark with a hairline border, the same frame studios see when they upload a
   logo in Company setup, so a logo looks here the way its studio approved it. */
.pending-games-name-cell {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
}

.pending-games-logo {
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 8px;
  background: rgba(148, 163, 184, 0.15);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--vs-text-muted);
  overflow: hidden;
}

.pending-games-logo--img {
  background: var(--vs-void, #0d141b);
  border: 1px solid var(--vs-rail, #26333f);
  padding: 3px;
  box-sizing: border-box;
}

.pending-games-logo--img img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.company-setup-overview-intro {
  margin-bottom: 1.25rem;
  max-width: 52rem;
}

.company-setup-overview-intro a {
  color: var(--vs-act);
  text-decoration: underline;
}

.company-setup-overview-stats-wrap {
  max-width: 42rem;
}

.company-setup-overview-panel {
  margin-top: 0.5rem;
}

.company-setup {
  max-width: 56rem;
  padding: 1rem 1.25rem 2rem;
  color: var(--vs-chalk);
}

.company-setup-tabs {
  display: flex;
  gap: 0.35rem;
  margin-bottom: 1.25rem;
}

.company-setup-tab {
  padding: 0.45rem 1rem;
  border-radius: 8px;
  border: 1px solid var(--vs-rail);
  background: var(--vs-void);
  color: var(--vs-dim);
  font-size: 0.875rem;
  cursor: pointer;
}

.company-setup-tab--on {
  background: rgba(0, 102, 255, 0.2);
  border-color: var(--vs-act-fill);
  color: var(--vs-chalk);
}

.company-setup-panel {
  background: var(--vs-deck);
  border: 1px solid var(--vs-rail);
  border-radius: 12px;
  padding: 1.25rem 1.35rem;
  margin-bottom: 1rem;
}

.company-setup-subh {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
}

.company-setup-invite-dummy {
  margin-bottom: 1rem;
  padding: 0.5rem 1rem;
  border-radius: 8px;
  border: 1px dashed var(--vs-rail);
  background: transparent;
  color: var(--vs-faint);
  cursor: not-allowed;
  font-size: 0.875rem;
}

.company-setup-team-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.company-setup-team-table th,
.company-setup-team-table td {
  text-align: left;
  padding: 0.6rem 0.5rem;
  border-bottom: 1px solid var(--vs-deck);
  color: var(--vs-chalk);
}

.company-setup-team-table th {
  color: var(--vs-faint);
  font-size: 0.75rem;
  text-transform: uppercase;
}

.company-setup-pill {
  display: inline-block;
  padding: 0.15rem 0.45rem;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
}

.company-setup-pill--ok {
  background: rgba(34, 197, 94, 0.2);
  color: var(--vs-on);
}

.company-setup-brand-row {
  display: flex;
  gap: 1rem;
  align-items: center;
  margin-bottom: 1rem;
}

.company-setup-logo-frame {
  flex-shrink: 0;
  width: 88px;
  height: 72px;
  border-radius: 10px;
  border: 1px solid var(--vs-rail);
  background: var(--vs-void);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem;
  box-sizing: border-box;
}

.company-setup-logo-frame--initials {
  background: linear-gradient(135deg, var(--vs-act-fill-hi), var(--vs-act));
  border-color: var(--vs-rail);
}

.company-setup-logo-initials {
  font-size: 1.35rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  color: #fff;
  line-height: 1;
}

.company-setup-logo-preview {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  border-radius: 6px;
  object-fit: contain;
  border: none;
}

.company-setup-brand-name {
  margin: 0 0 0.25rem;
}

.company-setup-dl {
  margin: 0;
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: 0.35rem 1rem;
  font-size: 0.875rem;
}

.company-setup-dl dt {
  color: var(--vs-faint);
  margin: 0;
}

.company-setup-dl dd {
  margin: 0;
  color: var(--vs-chalk);
}

.company-setup-activity-panel {
  max-width: none;
}

.company-setup-activity-scroll {
  overflow-x: auto;
  margin-top: 1rem;
}

.company-setup-activity-table {
  width: 100%;
  min-width: 640px;
  border-collapse: collapse;
  font-size: 0.875rem;
}

.company-setup-activity-table th,
.company-setup-activity-table td {
  text-align: left;
  padding: 0.65rem 0.75rem;
  border-bottom: 1px solid var(--vs-deck);
  vertical-align: top;
}

.company-setup-activity-table th {
  color: var(--vs-faint);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.company-setup-activity-link {
  color: var(--vs-act);
  text-decoration: none;
  font-weight: 500;
}

.company-setup-activity-link:hover {
  text-decoration: underline;
}

.company-setup-activity-status {
  display: inline-block;
  padding: 0.2rem 0.45rem;
  border-radius: 6px;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
}

.company-setup-activity-status--live {
  background: rgba(34, 197, 94, 0.2);
  color: var(--vs-on);
}

.company-setup-activity-status--pending {
  background: rgba(234, 179, 8, 0.2);
  color: var(--vs-warn);
}

.company-setup-activity-status--ended,
.company-setup-activity-status--cancelled {
  background: rgba(148, 163, 184, 0.2);
  color: var(--vs-dim);
}

.company-setup-activity-time {
  display: block;
  color: var(--vs-chalk);
  font-size: 0.8rem;
}

.company-setup-activity-rel {
  display: block;
  color: var(--vs-faint);
  font-size: 0.72rem;
  margin-top: 0.15rem;
}

.company-setup-activity-open {
  color: var(--vs-act);
  text-decoration: none;
  font-weight: 500;
  font-size: 0.85rem;
}

.company-setup-activity-open:hover {
  text-decoration: underline;
}

.company-setup-activity-badge {
  display: inline-block;
  font-size: 0.7rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.2rem 0.45rem;
  border-radius: 6px;
  background: rgba(59, 130, 246, 0.25);
  color: var(--vs-act);
}

.company-setup-activity-row--announcement td {
  vertical-align: top;
}

.company-setup-activity-news-title {
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.company-setup-activity-news-body {
  margin: 0;
  font-size: 0.8rem;
  color: var(--vs-dim);
  white-space: pre-wrap;
  word-break: break-word;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  max-width: 420px;
}

.company-setup-back {
  color: var(--vs-act);
  text-decoration: none;
  font-size: 0.9rem;
  display: inline-block;
  margin-bottom: 1rem;
}

.company-setup-back:hover {
  text-decoration: underline;
}

.company-setup h1 {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
}

.company-setup-desc,
.company-setup-muted {
  color: var(--vs-dim);
  font-size: 0.9rem;
  margin: 0 0 1rem;
}

.company-setup-error {
  color: var(--vs-fault);
  margin-bottom: 1rem;
}

.company-setup-reject {
  background: rgba(248, 113, 113, 0.12);
  border: 1px solid var(--vs-fault);
  border-radius: 8px;
  padding: 0.75rem 1rem;
  margin-bottom: 1rem;
  font-size: 0.9rem;
}

.company-setup-form {
  display: flex;
  flex-direction: column;
  gap: 0.85rem;
}

.company-setup-form label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.85rem;
  color: var(--vs-chalk);
}

.company-setup-form input {
  padding: 0.5rem 0.65rem;
  border-radius: 6px;
  border: 1px solid var(--vs-rail);
  background: var(--vs-void);
  color: var(--vs-chalk);
}

.company-setup-submit {
  margin-top: 0.5rem;
  padding: 0.6rem 1rem;
  border-radius: 8px;
  border: none;
  background: var(--vs-act-fill);
  color: #fff;
  font-weight: 600;
  cursor: pointer;
}

.company-setup-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.dev-settings {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s5);
  max-width: 46rem;
  min-width: 0;
  color: var(--vs-chalk);
  font-family: var(--vs-font);
}

.dev-settings-head h1 {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 650;
  letter-spacing: -0.02em;
}

.dev-settings-sub {
  margin: 0.3rem 0 0;
  font-size: 0.875rem;
  color: var(--vs-dim);
}

.dev-settings-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  max-width: 32rem;
}

.dev-settings-label {
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

.dev-settings-select {
  width: 100%;
}

.dev-settings-preview {
  margin: var(--vs-s4) 0 0;
  font-size: 0.875rem;
  color: var(--vs-dim);
}

.dev-settings-preview strong {
  color: var(--vs-chalk);
  font-weight: 650;
  font-variant-numeric: tabular-nums;
}

.dev-settings-note {
  margin-top: var(--vs-s4);
  align-items: flex-start;
  line-height: 1.55;
}

.dev-settings-note svg {
  flex: none;
  margin-top: 0.15rem;
  color: var(--vs-warn);
}

.dev-settings-fine {
  margin: var(--vs-s4) 0 0;
  padding-top: var(--vs-s4);
  border-top: 1px solid var(--vs-rail-soft);
  font-size: 0.8125rem;
  line-height: 1.55;
  color: var(--vs-faint);
  max-width: 72ch;
}
.live-ops {
  color: #f1f5f9;
  max-width: 1100px;
  margin: 0 auto;
}

.live-ops-back {
  color: #3b82f6;
  text-decoration: none;
  font-size: 0.9rem;
  display: inline-block;
  margin-bottom: 1rem;
}

.live-ops-back:hover {
  text-decoration: underline;
}

.live-ops-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  margin-bottom: 1.25rem;
}

.live-ops h1 {
  margin: 0 0 0.35rem;
  font-size: 1.5rem;
}

.live-ops-desc {
  margin: 0;
  color: #94a3b8;
  font-size: 0.9rem;
}

.live-ops-filters {
  display: flex;
  gap: 0.35rem;
}

.live-ops-filter {
  padding: 0.4rem 0.85rem;
  border-radius: 8px;
  border: 1px solid #334155;
  background: #0f172a;
  color: #94a3b8;
  font-size: 0.85rem;
  cursor: pointer;
}

.live-ops-filter--on {
  background: #1d4ed8;
  border-color: #2563eb;
  color: #fff;
}

.live-ops-muted {
  color: #94a3b8;
}

.live-ops-card {
  background: #111;
  border: 1px solid #334155;
  border-radius: 12px;
  overflow: hidden;
}

.live-ops-table {
  width: 100%;
  border-collapse: collapse;
}

.live-ops-table th,
.live-ops-table td {
  padding: 0.75rem 1rem;
  text-align: left;
  border-bottom: 1px solid #1e293b;
  font-size: 0.9rem;
}

.live-ops-table th {
  color: #64748b;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.live-ops-link {
  color: #3b82f6;
  text-decoration: none;
  font-weight: 500;
}

.live-ops-link:hover {
  text-decoration: underline;
}

.live-ops-status {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border-radius: 6px;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
}

.live-ops-status--live {
  background: rgba(34, 197, 94, 0.2);
  color: #22c55e;
}

.live-ops-status--pending {
  background: rgba(234, 179, 8, 0.2);
  color: #eab308;
}

.live-ops-status--ended,
.live-ops-status--cancelled {
  background: rgba(148, 163, 184, 0.2);
  color: #94a3b8;
}

.live-ops-manage {
  color: #3b82f6;
  text-decoration: none;
  font-weight: 500;
}

.live-ops-empty {
  color: #64748b;
  padding: 2rem 1rem !important;
}
.analytics-hub {
  color: var(--vs-chalk);
  max-width: 1100px;
  margin: 0 auto;
}

.analytics-hub-back {
  color: var(--vs-act);
  text-decoration: none;
  font-size: 0.9rem;
  display: inline-block;
  margin-bottom: 1rem;
}

.analytics-hub-back:hover {
  text-decoration: underline;
}

.analytics-hub h1 {
  margin: 0 0 0.35rem;
  font-size: 1.5rem;
}

.analytics-hub-desc {
  margin: 0 0 0.75rem;
  color: var(--vs-dim);
  font-size: 0.9rem;
  max-width: 36rem;
}

.analytics-hub-studio {
  margin: 0 0 1.25rem;
  font-size: 0.9rem;
  color: var(--vs-chalk);
}

.analytics-hub-muted {
  color: var(--vs-faint);
  font-size: 0.9rem;
}

.analytics-hub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1rem;
  margin-bottom: 2rem;
}

.analytics-hub-card {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 1.1rem 1.25rem;
  background: var(--vs-deck);
  border: 1px solid var(--vs-rail);
  border-radius: 12px;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s, background 0.15s;
}

.analytics-hub-card:hover {
  border-color: var(--vs-act-fill);
  background: var(--vs-void);
}

.analytics-hub-card-title {
  font-weight: 600;
  font-size: 1rem;
}

.analytics-hub-card-meta {
  font-size: 0.8rem;
  color: var(--vs-faint);
}

.analytics-hub-card-cta {
  margin-top: 0.35rem;
  font-size: 0.85rem;
  color: var(--vs-act);
  font-weight: 500;
}

.analytics-hub-modular {
  padding: 1.25rem;
  border-radius: 12px;
  border: 1px dashed var(--vs-rail);
  background: rgba(15, 23, 42, 0.5);
}

.analytics-hub-modular h2 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  color: var(--vs-chalk);
}

.analytics-hub-reports {
  margin-bottom: 2rem;
  padding: 1.25rem;
  border-radius: 12px;
  border: 1px solid var(--vs-rail);
  background: var(--vs-void);
}

.analytics-hub-reports h2 {
  margin: 0 0 0.35rem;
  font-size: 1.1rem;
  color: var(--vs-chalk);
}

.analytics-hub-reports-hint {
  margin: 0 0 1rem;
  font-size: 0.85rem;
}

.analytics-hub-fieldset {
  border: 1px solid var(--vs-rail);
  border-radius: 10px;
  padding: 0.85rem 1rem 1rem;
  margin: 0 0 1rem;
  background: rgba(15, 23, 42, 0.4);
}

.analytics-hub-legend {
  padding: 0 0.35rem;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--vs-chalk);
}

.analytics-hub-check {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  font-size: 0.85rem;
  color: var(--vs-chalk);
  cursor: pointer;
}

.analytics-hub-check:last-of-type {
  margin-bottom: 0;
}

.analytics-hub-check input {
  margin-top: 0.2rem;
  flex-shrink: 0;
}

.analytics-hub-check-sub {
  margin-left: 1.5rem;
  margin-top: -0.15rem;
  margin-bottom: 0.65rem;
  font-size: 0.8rem;
  color: var(--vs-dim);
}

.analytics-hub-check code {
  font-size: 0.78em;
  background: var(--vs-deck);
  padding: 0.05rem 0.3rem;
  border-radius: 4px;
  color: var(--vs-act);
}

.analytics-hub-csv-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
  margin-bottom: 1rem;
  padding: 0.65rem 0.85rem;
  border-radius: 8px;
  background: rgba(30, 41, 59, 0.5);
  border: 1px solid var(--vs-rail);
}

.analytics-hub-csv-label {
  font-size: 0.8rem;
  color: var(--vs-dim);
  font-weight: 500;
}

.analytics-hub-csv-btns {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.analytics-hub-btn.small {
  padding: 0.35rem 0.65rem;
  font-size: 0.8rem;
}

.analytics-hub-preview-block {
  margin-top: 1.25rem;
}

.analytics-hub-preview-title {
  margin: 0 0 0.35rem;
  font-size: 0.95rem;
  color: var(--vs-chalk);
}

.analytics-hub-preview-meta {
  margin: 0 0 0.5rem;
  font-size: 0.75rem;
}

.analytics-hub-preview-meta code {
  background: var(--vs-deck);
  padding: 0.1rem 0.35rem;
  border-radius: 4px;
  color: var(--vs-act);
}

.analytics-hub-form {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.75rem 1rem;
  margin-bottom: 1rem;
}

.analytics-hub-field {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.8rem;
  color: var(--vs-dim);
}

.analytics-hub-field span:first-child {
  font-weight: 500;
}

.analytics-hub-select,
.analytics-hub-input {
  padding: 0.45rem 0.6rem;
  border-radius: 8px;
  border: 1px solid var(--vs-rail);
  background: var(--vs-void);
  color: var(--vs-chalk);
  font-size: 0.9rem;
}

.analytics-hub-input-narrow {
  max-width: 6rem;
}

.analytics-hub-select option {
  background: var(--vs-void);
  color: var(--vs-chalk);
}

.analytics-hub-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.analytics-hub-btn {
  padding: 0.5rem 1rem;
  border-radius: 8px;
  border: 1px solid var(--vs-rail);
  background: var(--vs-deck);
  color: var(--vs-chalk);
  font-size: 0.9rem;
  cursor: pointer;
}

.analytics-hub-btn:hover:not(:disabled) {
  background: var(--vs-rail);
}

.analytics-hub-btn.primary {
  background: var(--vs-act-fill-hi);
  border-color: var(--vs-act-fill);
  color: #fff;
}

.analytics-hub-btn.primary:hover:not(:disabled) {
  background: var(--vs-act-fill);
}

.analytics-hub-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.analytics-hub-error {
  color: var(--vs-fault);
  font-size: 0.9rem;
  margin: 0 0 0.75rem;
}

.analytics-hub-table-wrap {
  overflow-x: auto;
  border-radius: 8px;
  border: 1px solid var(--vs-rail);
}

.analytics-hub-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}

.analytics-hub-table th,
.analytics-hub-table td {
  padding: 0.45rem 0.6rem;
  text-align: left;
  border-bottom: 1px solid var(--vs-deck);
}

.analytics-hub-table th {
  background: var(--vs-deck);
  color: var(--vs-dim);
  font-weight: 600;
  white-space: nowrap;
}

.analytics-hub-table td {
  color: var(--vs-chalk);
}

.analytics-hub-table tr:last-child td {
  border-bottom: none;
}

/* ---- Staff: platform player activity ---- */

.analytics-hub-platform {
  margin-bottom: 2rem;
}

.analytics-hub-platform-controls {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

.analytics-hub-platform-control {
  display: flex;
  flex-direction: row;
}

.analytics-hub-platform-range {
  font-size: 0.8125rem;
  color: var(--vs-dim);
  padding-inline: var(--vs-s1);
}

/* The series subtitle comes from the studio endpoint and says "across all studio games",
   which is wrong at platform scope. The panel's own subtitle says it correctly, so the
   chart's copy is hidden here rather than shown twice with two different meanings. */
.analytics-hub-platform-chart .game-overview-series-sub {
  display: none;
}

/* The chart scales with its container, axis labels included, so cap the reading width or
   the text grows with the box. */
.analytics-hub-platform-chart .game-overview-series-chart-wrap {
  max-width: 860px;
}

.analytics-hub-platform-chart .game-overview-series-svg {
  min-height: 260px;
}
.admin-users {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 1rem 2rem;
  color: #e2e8f0;
}

.admin-users-back {
  color: #3b82f6;
  text-decoration: none;
  font-size: 0.9rem;
  display: inline-block;
  margin-bottom: 1rem;
}

.admin-users h1 {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
}

.admin-users-desc {
  color: #94a3b8;
  font-size: 0.9rem;
  margin: 0 0 1.25rem;
  max-width: 40rem;
}

.admin-users-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem;
  margin-bottom: 1rem;
}

.admin-users-search-label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.8rem;
  color: #94a3b8;
}

.admin-users-search {
  min-width: 220px;
  padding: 0.45rem 0.65rem;
  border-radius: 8px;
  border: 1px solid #475569;
  background: #0f172a;
  color: #f1f5f9;
}

.admin-users-count {
  font-size: 0.85rem;
  color: #64748b;
}

.admin-users-muted {
  color: #64748b;
  font-size: 0.9rem;
}

.admin-users-error {
  color: #f87171;
}

.admin-users-table-wrap {
  overflow-x: auto;
  border: 1px solid #334155;
  border-radius: 10px;
}

.admin-users-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.admin-users-table th,
.admin-users-table td {
  padding: 0.5rem 0.65rem;
  text-align: left;
  border-bottom: 1px solid #1e293b;
}

.admin-users-table th {
  background: #111827;
  color: #94a3b8;
  font-weight: 600;
}

.admin-users-row-banned td {
  opacity: 0.85;
  background: rgba(127, 29, 29, 0.15);
}

.admin-users-pill {
  margin-left: 0.35rem;
  font-size: 0.65rem;
  text-transform: uppercase;
  padding: 0.1rem 0.35rem;
  border-radius: 4px;
  background: #334155;
  color: #cbd5e1;
}

.admin-users-link {
  margin-left: 0.5rem;
  background: none;
  border: none;
  color: #3b82f6;
  cursor: pointer;
  font-size: inherit;
  padding: 0;
  text-decoration: underline;
}

.admin-users-input {
  padding: 0.25rem 0.4rem;
  margin-right: 0.35rem;
  border-radius: 6px;
  border: 1px solid #475569;
  background: #0f172a;
  color: #f1f5f9;
  max-width: 180px;
}

.admin-users-select {
  padding: 0.25rem 0.35rem;
  border-radius: 6px;
  border: 1px solid #475569;
  background: #0f172a;
  color: #e2e8f0;
  font-size: 0.8rem;
}

.admin-users-btn {
  padding: 0.35rem 0.65rem;
  border-radius: 6px;
  border: 1px solid #475569;
  background: #1e293b;
  color: #e2e8f0;
  font-size: 0.8rem;
  cursor: pointer;
}

.admin-users-btn.danger {
  border-color: #991b1b;
  background: #7f1d1d;
  color: #fecaca;
}

.admin-users-btn.ghost {
  background: transparent;
  border: none;
  color: #94a3b8;
}

.admin-users-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.admin-users-pager {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 1rem;
}

.admin-users-player-id {
  max-width: 200px;
  vertical-align: top;
}

.admin-users-player-id code {
  display: block;
  font-size: 0.72rem;
  line-height: 1.35;
  word-break: break-all;
  color: #cbd5e1;
  background: #0f172a;
  padding: 0.2rem 0.35rem;
  border-radius: 4px;
}
.play-profile {
  padding: 0.5rem 0 1.5rem;
}

.play-profile-photo-error {
  color: #f87171;
  font-size: 0.875rem;
  margin: 0 0 0.75rem;
  max-width: 20rem;
}

.play-profile-photo-wrap {
  display: flex;
  justify-content: center;
  margin-bottom: 1rem;
}

.play-profile-photo-btn {
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  border-radius: 50%;
  overflow: hidden;
  display: block;
}
.play-profile-photo,
.play-profile-photo-placeholder {
  width: 120px;
  height: 120px;
  display: block;
  border-radius: 50%;
  object-fit: cover;
}
.play-profile-photo-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.5rem;
  font-weight: 600;
  color: #94a3b8;
  background: rgba(255, 255, 255, 0.1);
}
.play-profile-photo-input {
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0;
  pointer-events: none;
}

.play-profile-info {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-rows: auto auto;
  gap: 0.25rem 1rem;
  align-items: baseline;
  margin-bottom: 1.5rem;
}
.play-profile-name {
  margin: 0;
  font-size: 1.35rem;
  font-weight: 600;
  color: #fff;
  grid-column: 1;
  grid-row: 1;
}
.play-profile-location-row {
  grid-column: 1;
  grid-row: 2;
  display: flex;
  align-items: center;
  gap: 0.35rem;
}
.play-profile-pin {
  color: #94a3b8;
  flex-shrink: 0;
}
.play-profile-location-btn,
.play-profile-location-input {
  font-size: 0.9rem;
  color: #94a3b8;
  background: none;
  border: none;
  padding: 0;
  text-align: start;
  cursor: pointer;
}
.play-profile-location-btn:hover {
  color: #cbd5e1;
}
.play-profile-location-input {
  flex: 1;
  min-width: 0;
  color: #e2e8f0;
  cursor: text;
  outline: none;
  border-bottom: 1px solid rgba(255, 255, 255, 0.2);
}
.play-profile-location-input::placeholder {
  color: #64748b;
}
.play-profile-friends {
  grid-column: 2;
  grid-row: 1 / 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.play-profile-friends-num {
  font-size: 1.5rem;
  font-weight: 700;
  color: #fff;
  line-height: 1.2;
}
.play-profile-friends-label {
  font-size: 0.8rem;
  color: #94a3b8;
}

.play-profile-games-title {
  margin: 0 0 0.75rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: #cbd5e1;
}
.play-profile-games-empty {
  margin: 0;
  font-size: 0.9rem;
  color: #64748b;
}
.play-profile-games-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}
.play-profile-game-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  min-width: 72px;
  text-decoration: none;
  color: inherit;
}
.play-profile-game-card:hover .play-profile-game-name {
  color: #e2e8f0;
}
.play-profile-game-thumb {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  object-fit: cover;
  border: 1px solid rgba(255, 255, 255, 0.1);
  background: rgba(0, 0, 0, 0.2);
}
.play-profile-game-icon {
  width: 56px;
  height: 56px;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 255, 255, 0.06) 100%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.25rem;
  font-weight: 700;
  color: #e2e8f0;
}
.play-profile-game-name {
  font-size: 0.75rem;
  color: #94a3b8;
  text-align: center;
  max-width: 72px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.admin-user-play-profile {
  max-width: 720px;
  margin: 0 auto;
  padding: 1rem 1.25rem 2rem;
}

.admin-user-play-profile-back {
  display: inline-block;
  margin-bottom: 1rem;
  color: var(--portal-muted, #94a3b8);
  text-decoration: none;
  font-size: 0.9rem;
}

.admin-user-play-profile-back:hover {
  color: var(--portal-text, #e2e8f0);
}

.admin-user-play-profile-banner {
  font-size: 0.85rem;
  color: var(--portal-muted, #94a3b8);
  margin: 0 0 1rem;
  padding: 0.6rem 0.75rem;
  background: rgba(59, 130, 246, 0.12);
  border-radius: 8px;
  border: 1px solid rgba(59, 130, 246, 0.25);
}

.admin-user-play-profile-meta {
  margin: -0.25rem 0 0.75rem;
  font-size: 0.95rem;
  color: var(--portal-muted, #94a3b8);
}

.admin-user-play-profile-photo-readonly {
  display: inline-flex;
}

.admin-user-play-profile-id-row {
  align-items: flex-start;
  flex-wrap: wrap;
  gap: 0.35rem 0.5rem;
}

.admin-user-play-profile-id {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 0.8rem;
  word-break: break-all;
  color: var(--portal-text, #e2e8f0);
}

.admin-user-play-profile-copy {
  flex-shrink: 0;
}

.admin-user-play-profile-game-stats {
  display: block;
  font-size: 0.75rem;
  color: var(--portal-muted, #94a3b8);
  margin-top: 0.25rem;
}

/* Scoped to this page. Unscoped, it also restyled the game cards on players' own profile page on play.vs.plus, because
   the portal is one bundle and its CSS applies on every host. */
.admin-user-play-profile .play-profile-game-card {
  flex-direction: column;
  align-items: flex-start;
}
.play-content-admin {
  padding: 1.5rem;
  max-width: 840px;
  color-scheme: dark;
}

.play-content-admin-back {
  display: inline-block;
  margin-bottom: 1rem;
  color: rgba(255, 255, 255, 0.7);
  text-decoration: none;
  font-size: 0.9rem;
}
.play-content-admin-back:hover {
  color: #fff;
}

.play-content-admin h1 {
  font-size: 1.5rem;
  margin: 0 0 0.5rem;
  color: #fff;
}

.play-content-admin-desc {
  color: rgba(255, 255, 255, 0.6);
  margin: 0 0 1.25rem;
  font-size: 0.9rem;
}

.play-content-admin-error {
  color: #f87171;
  margin: 0 0 1rem;
}

.play-content-admin-section {
  margin-bottom: 2rem;
}

.play-content-admin-section h2 {
  font-size: 1.1rem;
  margin: 0 0 0.75rem;
  color: #e2e8f0;
}

.play-content-admin-btn-add {
  margin-bottom: 0.75rem;
  padding: 0.5rem 0.75rem;
  font-size: 0.9rem;
  background: #22c55e;
  color: #fff;
  border: none;
  border-radius: 8px;
  cursor: pointer;
}
.play-content-admin-btn-add:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.play-content-admin-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.play-content-admin-item {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 0.75rem;
  margin-bottom: 0.75rem;
  background: rgba(255, 255, 255, 0.04);
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.play-content-admin-item-fields {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem;
}

@media (min-width: 640px) {
  .play-content-admin-item-fields {
    grid-template-columns: 1fr 1fr;
  }
  .play-content-admin-item-fields .play-content-admin-input--num {
    grid-column: span 1;
    max-width: 5rem;
  }
}

.play-content-admin-input {
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(255, 255, 255, 0.06);
  color: #f1f5f9;
  font-size: 0.9rem;
}
.play-content-admin-input--num {
  width: 100%;
  max-width: 5rem;
}

.play-content-admin-icon-block {
  padding: 0.65rem 0.75rem;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.06);
}

.play-content-admin-icon-label {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #94a3b8;
  margin-bottom: 0.5rem;
}

.play-content-admin-icon-modes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  margin-bottom: 0.5rem;
}

.play-content-admin-radio {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: 0.85rem;
  color: #e2e8f0;
  cursor: pointer;
}

.play-content-admin-custom-icon {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
  margin-top: 0.35rem;
}

.play-content-admin-custom-icon .play-content-admin-input {
  flex: 1 1 200px;
  min-width: 0;
}

.play-content-admin-file {
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0;
  pointer-events: none;
}

.play-content-admin-btn-upload {
  padding: 0.45rem 0.65rem;
  font-size: 0.85rem;
  border-radius: 6px;
  border: 1px solid rgba(148, 163, 184, 0.4);
  background: rgba(255, 255, 255, 0.08);
  color: #e2e8f0;
  cursor: pointer;
}
.play-content-admin-btn-upload:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.play-content-admin-select {
  margin-top: 0.35rem;
  width: 100%;
  max-width: 420px;
  padding: 0.5rem 0.6rem;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.2);
  background-color: #0f172a;
  color: #f8fafc;
  font-size: 0.9rem;
}

.play-content-admin-select option,
.play-content-admin-select optgroup {
  background-color: #1e293b;
  color: #f8fafc;
}

.play-content-admin-icon-preview {
  display: block;
  margin-top: 0.5rem;
  width: 56px;
  height: 56px;
  border-radius: 8px;
  object-fit: cover;
  border: 1px solid rgba(255, 255, 255, 0.12);
}

.play-content-admin-item-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.play-content-admin-btn {
  padding: 0.4rem 0.75rem;
  font-size: 0.85rem;
  border-radius: 6px;
  border: none;
  cursor: pointer;
}
.play-content-admin-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.play-content-admin-btn--save {
  background: #3b82f6;
  color: #fff;
}
.play-content-admin-btn--del {
  background: transparent;
  color: #f87171;
  border: 1px solid rgba(248, 113, 113, 0.4);
}

.play-content-admin-btn--edit {
  background: rgba(255, 255, 255, 0.1);
  color: #e2e8f0;
  border: 1px solid rgba(148, 163, 184, 0.35);
}

.play-content-admin-item--saved {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
}

.play-content-admin-saved-main {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  flex: 1 1 200px;
  min-width: 0;
}

.play-content-admin-saved-text {
  min-width: 0;
}

.play-content-admin-saved-text strong {
  display: block;
  font-size: 0.95rem;
  color: #f1f5f9;
  margin-bottom: 0.15rem;
}

.play-content-admin-saved-meta {
  margin: 0;
  font-size: 0.8rem;
  color: #94a3b8;
  word-break: break-word;
}

.play-content-admin-saved-order {
  font-size: 0.75rem;
  color: #64748b;
  margin-top: 0.25rem;
}

.play-content-admin-saved-label {
  color: #64748b;
  margin-right: 0.25rem;
}

.play-content-admin-icon-preview--saved {
  margin-top: 0;
  flex-shrink: 0;
}
.gs { color: var(--vs-chalk); }
.gs-head { margin-bottom: 1rem; }
.gs-title { font-size: 1.6rem; margin: 0 0 0.25rem; }
.gs-sub { color: var(--vs-dim); margin: 0; }

.gs-tabs { display: flex; gap: 0.5rem; flex-wrap: wrap; border-bottom: 1px solid var(--vs-rail); margin-bottom: 1rem; }
.gs-tab {
  background: none; border: none; color: var(--vs-dim); padding: 0.5rem 0.9rem; cursor: pointer;
  border-bottom: 2px solid transparent; font-size: 0.95rem;
}
.gs-tab--active { color: #fff; border-bottom-color: var(--vs-act-fill); }

.gs-section { margin-bottom: 1.5rem; }
.gs-desc { color: var(--vs-dim); margin: 0 0 1rem; max-width: 60ch; }
.gs-muted { color: var(--vs-faint); }
.gs-empty { color: var(--vs-faint); font-style: italic; padding: 1rem 0; }
.gs-notice { background: #16331f; border: 1px solid #2e7d4f; color: var(--vs-on); padding: 0.6rem 0.8rem; border-radius: 6px; margin-bottom: 1rem; }
.gs-error { background: #3a1620; border: 1px solid #a83a4f; color: var(--vs-fault); padding: 0.6rem 0.8rem; border-radius: 6px; margin-bottom: 1rem; }

/* Marketplace cards */
.gs-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1rem; }
.gs-card { background: #16161f; border: 1px solid var(--vs-rail); border-radius: 10px; overflow: hidden; display: flex; flex-direction: column; }
.gs-card-media { aspect-ratio: 16 / 9; background: var(--vs-void); display: flex; align-items: center; justify-content: center; overflow: hidden; }
.gs-card-media img { width: 100%; height: 100%; object-fit: cover; }
.gs-card-noimg { color: #55556a; font-size: 0.85rem; }
.gs-card-body { padding: 0.85rem; display: flex; flex-direction: column; gap: 0.4rem; flex: 1; }
.gs-card-top { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; }
.gs-card-name { font-weight: 600; }
.gs-card-cat { font-size: 0.7rem; text-transform: uppercase; color: var(--vs-act); background: var(--vs-act-wash); padding: 0.15rem 0.45rem; border-radius: 999px; }
.gs-card-adv { color: var(--vs-dim); font-size: 0.85rem; margin: 0; }
.gs-card-desc { color: var(--vs-faint); font-size: 0.82rem; margin: 0; }
.gs-card-meta { display: flex; justify-content: space-between; font-size: 0.8rem; color: var(--vs-dim); margin-top: auto; padding-top: 0.5rem; }

/* Buttons */
.gs-btn {
  background: var(--vs-act-fill); color: #fff; border: none; border-radius: 6px; padding: 0.5rem 0.9rem;
  cursor: pointer; font-size: 0.9rem; align-self: flex-start;
}
.gs-btn:disabled { opacity: 0.5; cursor: default; }
.gs-link-btn { background: none; border: none; color: var(--vs-act); cursor: pointer; padding: 0.2rem 0.4rem; font-size: 0.85rem; }
.gs-link-btn--danger { color: var(--vs-fault); }

/* Tables */
.gs-table { width: 100%; border-collapse: collapse; margin-top: 0.5rem; }
.gs-table th, .gs-table td { text-align: left; padding: 0.55rem 0.6rem; border-bottom: 1px solid var(--vs-rail-soft); font-size: 0.9rem; }
.gs-table th { color: #9a9aa8; font-weight: 600; }
.gs-num { text-align: right; }
.gs-row-actions { display: flex; gap: 0.3rem; justify-content: flex-end; }

/* Status badges */
.gs-badge { font-size: 0.72rem; text-transform: uppercase; padding: 0.15rem 0.5rem; border-radius: 999px; white-space: nowrap; }
.gs-badge--active { background: #16331f; color: var(--vs-on); }
.gs-badge--pending-review { background: #33301a; color: #e7d79b; }
.gs-badge--paused { background: var(--vs-rail); color: var(--vs-dim); }
.gs-badge--declined, .gs-badge--rejected { background: #3a1620; color: var(--vs-fault); }
.gs-badge--disabled { background: var(--vs-rail); color: var(--vs-faint); }

/* Summary */
.gs-summary { display: flex; gap: 2rem; margin-bottom: 1rem; }
.gs-summary-item { display: flex; flex-direction: column; }
.gs-summary-value { font-size: 1.8rem; font-weight: 700; }
.gs-summary-label { color: #9a9aa8; font-size: 0.85rem; }

/* Forms */
.gs-form { background: #14141d; border: 1px solid var(--vs-rail); border-radius: 8px; padding: 1rem; margin: 1rem 0; max-width: 560px; }
.gs-form-row { display: flex; flex-direction: column; gap: 0.3rem; margin-bottom: 0.8rem; }
.gs-form-row label { font-size: 0.85rem; color: var(--vs-dim); }
.gs-form-row input[type="text"], .gs-form-row input[type="number"], .gs-form-row select, .gs-form-row textarea {
  background: var(--vs-void); border: 1px solid var(--vs-rail); color: var(--vs-chalk); border-radius: 6px; padding: 0.5rem; font-size: 0.9rem;
}
.gs-form-row--inline { flex-direction: row; gap: 1rem; }
.gs-form-row--inline > div { display: flex; flex-direction: column; gap: 0.3rem; flex: 1; }
.gs-form-actions { display: flex; gap: 0.75rem; align-items: center; margin-top: 0.5rem; }

/* Modal */
.gs-modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: center; z-index: 1000; }
.gs-modal { background: #16161f; border: 1px solid var(--vs-rail); border-radius: 10px; padding: 1.5rem; width: 90%; max-width: 420px; }
.gs-modal h3 { margin: 0 0 0.5rem; }

/* House campaigns: VS+'s own, and they pay studios nothing. Neutral, so it reads as a fact rather than a warning. */
.gs-badge--house { background: var(--vs-rail); color: var(--vs-chalk); text-transform: none; margin-right: 0.35rem; }

/* A hint under a field, such as the platform default share. */
.gs-hint { display: block; font-size: 0.8rem; color: var(--vs-faint); margin: 0 0 0.8rem; max-width: 60ch; }
.gs-form-row .gs-hint { margin: 0; }

/* Where the game's default share stands with VS+. The colour follows the state, and the words always say it too. */
.gs-share { border: 1px solid var(--vs-rail); background: var(--vs-deck); color: var(--vs-dim); padding: 0.6rem 0.8rem; border-radius: var(--vs-r-sm); margin: 0 0 0.8rem; font-size: 0.875rem; }
.gs-share strong { color: var(--vs-chalk); }
.gs-share--warn { border-color: var(--vs-warn); background: var(--vs-warn-wash); }
.gs-share--ok { border-color: var(--vs-on); background: var(--vs-on-wash); }
.gs-share--fault { border-color: var(--vs-fault); background: var(--vs-fault-wash); }
.ad-reporting {
  padding: 1.5rem;
  max-width: 900px;
}

.ad-reporting-back {
  display: inline-block;
  margin-bottom: 1rem;
  color: var(--vs-dim);
  text-decoration: none;
  font-size: 0.9rem;
}
.ad-reporting-back:hover {
  color: #fff;
}

.ad-reporting-title {
  font-size: 1.5rem;
  margin: 0 0 0.5rem;
  color: #fff;
}

.ad-reporting-desc {
  color: var(--vs-dim);
  margin: 0 0 1rem;
  font-size: 0.9rem;
}

.ad-reporting-info-block {
  background: var(--vs-deck);
  border: 1px solid var(--vs-rail-soft);
  border-radius: 12px;
  padding: 1.25rem;
}

.ad-reporting-list {
  margin: 0.75rem 0 1rem 1.25rem;
  padding: 0;
  color: var(--vs-chalk);
  font-size: 0.9rem;
  line-height: 1.6;
}

.ad-reporting-list li {
  margin-bottom: 0.5rem;
}

.ad-reporting-list code {
  font-size: 0.85em;
  background: var(--vs-rail-soft);
  padding: 0.15rem 0.35rem;
  border-radius: 4px;
}

.ad-reporting-muted {
  color: var(--vs-faint);
  font-size: 0.85rem;
  margin: 0;
}

.ad-reporting-h3 {
  font-size: 1rem;
  margin: 1.25rem 0 0.5rem;
  color: var(--vs-chalk);
}

.ad-reporting-sdk-test {
  margin-top: 1rem;
}

.ad-reporting-sdk-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 1rem;
}

.ad-reporting-sdk-label {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--vs-dim);
}

.ad-reporting-sdk-select {
  padding: 0.4rem 0.75rem;
  font-size: 0.9rem;
  border-radius: 8px;
  border: 1px solid var(--vs-rail);
  background: var(--vs-rail-soft);
  color: #fff;
  min-width: 12rem;
}

.ad-reporting-sdk-btn {
  padding: 0.4rem 0.75rem;
  font-size: 0.9rem;
  border-radius: 8px;
  border: none;
  background: var(--vs-act-fill);
  color: #fff;
  cursor: pointer;
  font-weight: 500;
}

.ad-reporting-sdk-btn:hover:not(:disabled) {
  background: var(--vs-act-fill-hi);
}

.ad-reporting-sdk-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.ad-reporting-sdk-result {
  margin-top: 1rem;
  padding: 1rem;
  background: var(--vs-void);
  border-radius: 8px;
  border: 1px solid var(--vs-rail-soft);
}

.ad-reporting-sdk-pre {
  margin: 0 0 1rem;
  font-size: 0.8rem;
  color: var(--vs-chalk);
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
}

.ad-reporting-error {
  color: var(--vs-fault);
  margin: 0 0 1rem;
}

.ad-reporting-forbidden {
  color: var(--vs-dim);
  margin: 0;
  font-size: 1rem;
}

.ad-reporting-presets {
  margin-bottom: 1.25rem;
  display: flex;
  gap: 0.5rem;
}

.ad-reporting-preset {
  padding: 0.4rem 0.75rem;
  font-size: 0.85rem;
  border-radius: 6px;
  border: 1px solid var(--vs-rail);
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
  cursor: pointer;
}
.ad-reporting-preset:hover {
  background: var(--vs-rail-soft);
}
.ad-reporting-preset.active {
  background: var(--vs-act);
  border-color: var(--vs-act);
  color: #fff;
}

.ad-reporting-section {
  margin-bottom: 2rem;
}

.ad-reporting-section h2 {
  font-size: 1.1rem;
  margin: 0 0 0.75rem;
  color: var(--vs-chalk);
}

.ad-reporting-summary {
  display: flex;
  gap: 2rem;
  margin-bottom: 0.5rem;
}

.ad-reporting-summary-item {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.ad-reporting-summary-value {
  font-size: 1.5rem;
  font-weight: 600;
  color: #fff;
}

.ad-reporting-summary-label {
  font-size: 0.85rem;
  color: var(--vs-dim);
}

.ad-reporting-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9rem;
}

.ad-reporting-table th,
.ad-reporting-table td {
  padding: 0.5rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid var(--vs-rail-soft);
}

.ad-reporting-table th {
  color: var(--vs-dim);
  font-weight: 500;
}

.ad-reporting-table td {
  color: var(--vs-chalk);
}

.ad-reporting-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.ad-reporting-empty {
  color: var(--vs-faint);
  font-size: 0.9rem;
  margin: 0;
}

.ad-reporting-sponsor-actions {
  margin-bottom: 1rem;
}

.ad-reporting-link-btn {
  background: none;
  border: none;
  color: var(--vs-act);
  cursor: pointer;
  font-size: 0.9rem;
  padding: 0;
  text-decoration: underline;
}
.ad-reporting-link-btn:hover {
  color: var(--vs-act);
}

.ad-reporting-form {
  margin-top: 1rem;
  padding: 1.25rem;
  background: var(--vs-void);
  border-radius: 8px;
  border: 1px solid var(--vs-rail-soft);
}

.ad-reporting-form h4 {
  margin: 0 0 1rem;
  font-size: 1rem;
  color: var(--vs-chalk);
}

.ad-reporting-form-row {
  margin-bottom: 0.75rem;
}

.ad-reporting-form-row label {
  display: block;
  font-size: 0.85rem;
  color: var(--vs-dim);
  margin-bottom: 0.25rem;
}

.ad-reporting-form-row input[type="text"],
.ad-reporting-form-row input[type="url"],
.ad-reporting-form-row input[type="number"],
.ad-reporting-form-row input[type="datetime-local"],
.ad-reporting-form-row textarea {
  width: 100%;
  max-width: 400px;
  padding: 0.4rem 0.6rem;
  font-size: 0.9rem;
  border-radius: 6px;
  border: 1px solid var(--vs-rail);
  background: var(--vs-rail-soft);
  color: #fff;
}

.ad-reporting-form-actions {
  display: flex;
  gap: 0.75rem;
  margin-top: 1rem;
}
/* Sponsored admin page.
 *
 * Built from the vsp- primitives in src/styles/tokens.css. This file only lays them out: every
 * colour comes from the primitives and tokens.
 */

/* A field that takes the whole row of a vsp-form-grid, such as a description. */
.sponsored-span-all {
  grid-column: 1 / -1;
}

/* The editor panels scroll into view when they open; leave a little room above the heading. */
.sponsored-editor {
  scroll-margin-top: var(--vs-s4);
}

/* Focus lands on the editor heading when it opens, so keyboard users start at the top of the
   form. It is a landing spot, not a control, so it does not draw a ring. */
.sponsored-editor-title:focus {
  outline: none;
}

.sponsored-subhead {
  margin: 0;
  font-size: 0.875rem;
  font-weight: 600;
}

/* A house campaign's badge sits in the line under its name, with the reason beside it. */
.sponsored-house > .vsp-badge {
  margin-right: var(--vs-s1);
}

/* ---------------------------------------------------------------- Targeting */

.sponsored-targeting > summary {
  width: fit-content;
  padding-block: var(--vs-s1);
  border-radius: var(--vs-r-sm);
  font-size: 0.875rem;
  font-weight: 550;
  cursor: pointer;
}

.sponsored-targeting[open] > summary {
  margin-bottom: var(--vs-s3);
}

/* ---------------------------------------------------------------- Creatives */

/* The creatives table sits inside the editor panel, so its rows are few and short. */
.sponsored-creatives :is(th, td) {
  vertical-align: middle;
  white-space: nowrap;
}

/* A long asset URL is cut short in the cell; the full address is in its title and the link. */
.sponsored-asset-link {
  display: inline-block;
  max-width: 22rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

.sponsored-creative-add {
  display: grid;
  grid-template-columns: minmax(12rem, 1fr) minmax(5rem, 7rem) minmax(5rem, 7rem) auto;
  gap: var(--vs-s3);
  align-items: end;
}

/* The button lines up with the 44px inputs beside it. */
.sponsored-creative-add > .vsp-btn {
  min-height: 44px;
}

@media (max-width: 760px) {
  .sponsored-creative-add {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .sponsored-creative-add > :first-child {
    grid-column: 1 / -1;
  }
}

/* ---------------------------------------------------------------- Creatives preview in the approve dialog */

.sponsored-preview {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vs-s3);
  margin: 0 0 var(--vs-s2);
  padding: 0;
  list-style: none;
}

.sponsored-preview-link {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s1);
  font-size: 0.75rem;
  color: var(--vs-dim);
  text-decoration: none;
}

.sponsored-preview-link:hover {
  color: var(--vs-chalk);
}

.sponsored-preview-img {
  display: block;
  width: 9rem;
  height: 5rem;
  object-fit: contain;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-sm);
  background: var(--vs-void);
}
/* Layout only. Colours, type and spacing tokens come from styles/tokens.css. */

/* The checkbox sits in a column, which would stretch its label across the panel and make the empty space beside the
   text toggle it. */
.admin-payouts-checkbox {
  align-self: flex-start;
}

/* ---- Studio picker: the search box and its Clear button on one line, with the matches listed under the box. */

.admin-payouts-picker {
  display: flex;
  align-items: center;
  gap: var(--vs-s2);
}

.admin-payouts-picker-box {
  flex: 1;
  min-width: 0;
}

/* The shared menu opens from the end of the button that owns it. A list of matches spans the box instead, and scrolls
   rather than running off the page. */
.admin-payouts-picker-menu {
  inset-inline: 0;
  min-width: 0;
  max-height: 18rem;
  overflow-y: auto;
}

.admin-payouts-picker-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The match the arrow keys are on. The menu primitive only draws hover, and focus stays in the box, so without this a
   keyboard user cannot see which studio Enter will choose. Same surface as the primitive's hover. */
.admin-payouts-picker-option[aria-selected='true'] {
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
}
.billing-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
  gap: 1rem;
  margin-bottom: 1rem;
}

.billing-card h2 {
  margin-top: 0;
}

.billing-card h3 {
  margin: 0.75rem 0 0.25rem;
  font-size: 1rem;
}

.billing-option {
  padding: 0.75rem 0;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.billing-option p {
  margin: 0.25rem 0 0.5rem;
  font-size: 0.92rem;
  opacity: 0.85;
}

.billing-status {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.billing-card .gs-btn + .gs-btn {
  margin-inline-start: 0.5rem;
}

.billing-detail .gs-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.billing .gs-btn--secondary {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.25);
}
/* Support tickets, shared by the developer portal (Support.tsx), the player portal (PlaySupport.tsx) and the admin
   console (AdminSupportTickets.tsx). Every portal is dark.

   This file used to read light-theme variables (--card-bg, --text, --border, --primary) that nothing defines, so it
   always fell back to its light defaults: near-white reply bubbles and forms under the dark theme's light text, dark
   text on the dark page, and near-white rows on hover. Replies were unreadable in all three portals. It now uses the
   design tokens from styles/tokens.css, which are defined on :root for every host.

   Hover rules restate colour and border-colour because index.css still carries Vite defaults (a:hover, button:hover)
   that outrank a bare class. */

.support-page {
  max-width: 640px;
  margin: 0 auto;
  padding: 1rem;
}
.support-back {
  display: inline-block;
  margin-bottom: 1rem;
  color: var(--vs-dim);
  text-decoration: none;
}
.support-back:hover {
  color: var(--vs-chalk);
  text-decoration: underline;
}
.support-page h1 {
  font-size: 1.5rem;
  margin-bottom: 0.25rem;
}
.support-desc,
.support-loading,
.support-empty {
  color: var(--vs-dim);
  margin-bottom: 1rem;
}
.support-admin-link {
  margin-bottom: 1rem;
}
.support-admin-link a {
  color: var(--vs-act);
  text-decoration: none;
  font-weight: 500;
}
.support-admin-link a:hover {
  color: var(--vs-act);
  text-decoration: underline;
}
.support-error {
  color: var(--vs-fault);
  margin-bottom: 0.5rem;
}
.support-btn {
  padding: 0.5rem 1rem;
  border-radius: var(--vs-r-sm);
  border: 1px solid var(--vs-act-fill);
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
  cursor: pointer;
  font-size: 0.9375rem;
}
.support-btn:hover:not(:disabled) {
  background: var(--vs-act-fill-hi);
  border-color: var(--vs-act-fill-hi);
  color: var(--vs-act-ink);
}
.support-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}
.support-btn--new {
  margin-bottom: 1.5rem;
}
.support-btn--secondary {
  background: transparent;
  border-color: var(--vs-rail);
  color: var(--vs-chalk);
  margin-inline-start: 0.5rem;
}
.support-btn--secondary:hover:not(:disabled) {
  background: var(--vs-deck-hi);
  border-color: var(--vs-faint);
  color: var(--vs-chalk);
}
.support-form {
  background: var(--vs-deck);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  padding: 1.25rem;
  margin-bottom: 1.5rem;
  color: var(--vs-chalk);
}
.support-form h2 {
  font-size: 1.125rem;
  margin-bottom: 1rem;
}
.support-form label {
  display: block;
  margin-bottom: 0.75rem;
  font-size: 0.875rem;
  color: var(--vs-dim);
}
.support-input,
.support-reply-input {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin-top: 0.25rem;
  padding: 0.5rem;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-sm);
  background: var(--vs-void);
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.9375rem;
}
.support-input::placeholder,
.support-reply-input::placeholder {
  color: var(--vs-faint);
}
.support-input:focus,
.support-reply-input:focus {
  outline: 2px solid var(--vs-act);
  outline-offset: 1px;
  border-color: var(--vs-act);
}
.support-form-actions {
  margin-top: 1rem;
}
.support-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.support-list-item {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  margin-bottom: 0.5rem;
  text-decoration: none;
  color: inherit;
}
.support-list-item:hover {
  background: var(--vs-deck-hi);
  border-color: var(--vs-rail);
  color: inherit;
}
.support-list-subject {
  flex: 1;
  font-weight: 500;
}
.support-list-date {
  font-size: 0.875rem;
  color: var(--vs-dim);
}
.support-badge {
  display: inline-block;
  padding: 0.2rem 0.5rem;
  border-radius: 4px;
  font-size: 0.75rem;
  background: var(--vs-rail-soft);
  color: var(--vs-chalk);
}
.support-badge--status {
  text-transform: capitalize;
}
.support-badge--staff {
  background: var(--vs-act-wash);
  color: var(--vs-act);
}
.support-detail {
  margin-top: 1rem;
}
.support-detail-subject {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
}
.support-detail-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 1rem;
  font-size: 0.875rem;
  color: var(--vs-dim);
}
.support-detail-date {
  margin-inline-start: auto;
}
.support-detail-description {
  white-space: pre-wrap;
  margin-bottom: 1.5rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--vs-rail-soft);
}
.support-replies {
  margin-bottom: 1rem;
}
.support-reply {
  padding: 0.75rem;
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  border: 1px solid var(--vs-rail-soft);
  color: var(--vs-chalk);
  margin-bottom: 0.5rem;
}
.support-reply--staff {
  background: var(--vs-act-wash);
  border-inline-start: 3px solid var(--vs-act);
}
.support-reply-meta {
  font-size: 0.8125rem;
  color: var(--vs-dim);
  margin-bottom: 0.25rem;
}
.support-reply-body {
  margin: 0;
  white-space: pre-wrap;
}
.support-reply-form {
  margin-top: 1rem;
}
.support-reply-input {
  margin-bottom: 0.5rem;
  resize: vertical;
}
.doc-layout {
  display: grid;
  grid-template-columns: minmax(200px, 240px) 1fr;
  gap: 1.5rem;
  align-items: start;
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 1rem 2rem;
}

@media (max-width: 768px) {
  .doc-layout {
    grid-template-columns: 1fr;
  }
  .doc-layout__subnav {
    position: static;
  }
}

.doc-layout__subnav {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.35rem;
  padding: 0.75rem 0.85rem;
  border: 1px solid #1e293b;
  border-radius: 10px;
  background: #0b1020;
}

.doc-layout__group {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
  padding-bottom: 0.5rem;
  margin-bottom: 0.35rem;
  border-bottom: 1px solid rgba(148, 163, 184, 0.15);
}

.doc-layout__group:last-of-type {
  border-bottom: none;
  margin-bottom: 0;
  padding-bottom: 0;
}

.doc-layout__group-label {
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: #64748b;
  padding: 0.25rem 0.5rem 0.15rem;
}

.doc-layout__sub {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  padding-left: 0.65rem;
  border-left: 2px solid rgba(0, 102, 255, 0.35);
  margin-left: 0.35rem;
}

.doc-layout__link {
  padding: 0.35rem 0.65rem;
  border-radius: 6px;
  font-size: 0.88rem;
  color: #94a3b8;
  text-decoration: none;
  transition: color 0.15s, background 0.15s;
}

.doc-layout__link--hub {
  font-size: 0.82rem;
  color: #64748b;
  margin-top: 0.25rem;
}

.doc-layout__link:hover {
  color: #e2e8f0;
  background: rgba(255, 255, 255, 0.06);
}

.doc-layout__link--active {
  color: #f1f5f9 !important;
  background: rgba(0, 102, 255, 0.22);
}

.doc-layout__link--external::after {
  content: ' ↗';
  font-size: 0.75em;
  opacity: 0.75;
}
.docs-page {
  color: var(--vs-chalk);
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.docs-hero {
  border: 1px solid var(--vs-deck);
  background: linear-gradient(180deg, var(--vs-void) 0%, var(--vs-void) 100%);
  border-radius: 14px;
  padding: 1.25rem 1.25rem 1rem;
}

.docs-hero h1 {
  margin: 0 0 0.5rem;
  font-size: 1.7rem;
  color: var(--vs-chalk);
}

.docs-hero p {
  margin: 0;
  color: var(--vs-dim);
  max-width: 70ch;
}

.docs-hero-extra {
  margin-top: 0.75rem !important;
}

.docs-inline-link {
  color: var(--vs-act);
  text-decoration: none;
  font-size: 0.9rem;
}

.docs-inline-link:hover {
  text-decoration: underline;
}

.docs-section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.docs-total-time {
  font-size: 0.8rem;
  color: var(--vs-faint);
  border: 1px solid var(--vs-rail);
  border-radius: 999px;
  padding: 0.2rem 0.55rem;
}

.docs-lead {
  margin: 0 0 1rem;
  color: var(--vs-dim);
  font-size: 0.92rem;
  line-height: 1.45;
  max-width: 70ch;
}

.docs-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.docs-step {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.75rem 1rem;
  align-items: stretch;
}

.docs-step-num {
  width: 2rem;
  height: 2rem;
  border-radius: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 0.95rem;
  color: var(--vs-act);
  background: rgba(37, 99, 235, 0.25);
  border: 1px solid var(--vs-act-fill-hi);
  flex-shrink: 0;
}

.docs-step-body {
  display: block;
  text-decoration: none;
  border: 1px solid var(--vs-deck);
  background: var(--vs-void);
  border-radius: 12px;
  padding: 0.85rem 1rem;
  transition: border-color 0.16s ease, transform 0.16s ease;
}

.docs-step-body:hover {
  border-color: var(--vs-act);
  transform: translateY(-1px);
}

.docs-step-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.35rem;
}

.docs-step-top h3 {
  margin: 0;
  color: var(--vs-chalk);
  font-size: 1rem;
  line-height: 1.35;
}

.docs-step-time {
  flex-shrink: 0;
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--vs-dim);
  border: 1px solid var(--vs-rail);
  border-radius: 999px;
  padding: 0.15rem 0.45rem;
}

.docs-step-body p {
  margin: 0;
  color: var(--vs-dim);
  font-size: 0.9rem;
  line-height: 1.45;
}

.docs-section h2 {
  margin: 0 0 0.75rem;
  color: var(--vs-chalk);
  font-size: 1.15rem;
}

.docs-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 0.9rem;
}

.docs-card {
  display: block;
  text-decoration: none;
  border: 1px solid var(--vs-deck);
  background: var(--vs-void);
  border-radius: 12px;
  padding: 0.9rem;
  transition: border-color 0.16s ease, transform 0.16s ease;
}

.docs-card:hover {
  border-color: var(--vs-act);
  transform: translateY(-1px);
}

.docs-card h3 {
  margin: 0.45rem 0;
  color: var(--vs-chalk);
  font-size: 1rem;
}

.docs-card p {
  margin: 0;
  color: var(--vs-dim);
  font-size: 0.9rem;
  line-height: 1.45;
}

.docs-tag {
  display: inline-flex;
  align-items: center;
  font-size: 0.72rem;
  padding: 0.18rem 0.42rem;
  border-radius: 999px;
  border: 1px solid var(--vs-rail);
  color: var(--vs-act);
  background: rgba(59, 130, 246, 0.15);
}

.docs-faq {
  display: grid;
  gap: 0.7rem;
}

.docs-faq-item {
  border: 1px solid var(--vs-deck);
  border-radius: 12px;
  background: var(--vs-void);
  padding: 0.9rem;
}

.docs-faq-item h3 {
  margin: 0 0 0.45rem;
  color: var(--vs-chalk);
  font-size: 0.98rem;
}

.docs-faq-item p {
  margin: 0;
  color: var(--vs-dim);
  line-height: 1.45;
  font-size: 0.9rem;
}

.docs-back {
  display: inline-block;
  margin-bottom: 0.25rem;
  color: var(--vs-act);
  text-decoration: none;
  font-size: 0.9rem;
}

.docs-back:hover {
  text-decoration: underline;
}

.docs-table-wrap {
  overflow-x: auto;
  margin: 0.75rem 0 0;
  border: 1px solid var(--vs-deck);
  border-radius: 12px;
}

.docs-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.88rem;
  color: var(--vs-chalk);
}

.docs-table th,
.docs-table td {
  border: 1px solid var(--vs-rail);
  padding: 0.5rem 0.65rem;
  text-align: left;
  vertical-align: top;
}

.docs-table thead th {
  color: var(--vs-chalk);
  background: var(--vs-void);
  font-weight: 600;
}

.docs-table tbody th[scope='row'] {
  color: var(--vs-chalk);
  background: var(--vs-void);
  font-weight: 600;
  white-space: nowrap;
}

.docs-table code {
  font-size: 0.9em;
  color: var(--vs-act);
}
.doc-sdk-page__list {
  margin: 0;
  padding-left: 1.25rem;
  color: #cbd5e1;
  line-height: 1.6;
}

.doc-sdk-page__list a {
  color: #93c5fd;
}

.doc-sdk-page__para {
  margin: 0;
  color: #94a3b8;
  line-height: 1.55;
  max-width: 72ch;
}

.doc-sdk-page__para code {
  font-size: 0.88em;
  color: #fde68a;
}
.tt-page {
  color: #e2e8f0;
  max-width: 960px;
}

.tt-back {
  display: inline-block;
  margin-bottom: 1rem;
  color: #93c5fd;
  text-decoration: none;
  font-size: 0.9rem;
}

.tt-back:hover {
  text-decoration: underline;
}

.tt-hero {
  border: 1px solid #1e293b;
  background: linear-gradient(180deg, #0b1220 0%, #0a0f18 100%);
  border-radius: 14px;
  padding: 1.25rem 1.25rem 1rem;
  margin-bottom: 1.5rem;
}

.tt-hero h1 {
  margin: 0 0 0.5rem;
  font-size: 1.7rem;
  color: #f8fafc;
}

.tt-hero p {
  margin: 0;
  color: #94a3b8;
  line-height: 1.5;
  max-width: 72ch;
}

.tt-section {
  margin-bottom: 1.75rem;
}

.tt-section h2 {
  margin: 0 0 0.75rem;
  color: #f8fafc;
  font-size: 1.15rem;
}

.tt-choose {
  margin: 0;
  padding-left: 1.25rem;
  color: #cbd5e1;
  line-height: 1.55;
}

.tt-choose li {
  margin-bottom: 0.5rem;
}

.tt-table-wrap {
  overflow-x: auto;
  border: 1px solid #1e293b;
  border-radius: 12px;
  background: #0b1020;
}

.tt-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.tt-table th,
.tt-table td {
  text-align: left;
  padding: 0.65rem 0.75rem;
  border-bottom: 1px solid #1e293b;
  vertical-align: top;
}

.tt-table th {
  color: #94a3b8;
  font-weight: 600;
  white-space: nowrap;
}

.tt-table tr:last-child td {
  border-bottom: none;
}

.tt-code {
  font-size: 0.8rem;
  color: #fde68a;
  white-space: nowrap;
}

.tt-card {
  border: 1px solid #1e293b;
  border-radius: 12px;
  background: #0b1020;
  padding: 1rem 1.1rem;
  margin-bottom: 0.75rem;
}

.tt-card h3 {
  margin: 0 0 0.5rem;
  color: #f1f5f9;
  font-size: 1rem;
}

.tt-card p {
  margin: 0;
  color: #94a3b8;
  line-height: 1.5;
  font-size: 0.9rem;
}

.tt-note {
  margin-top: 0.65rem !important;
  padding-top: 0.65rem;
  border-top: 1px dashed #334155;
  font-size: 0.85rem !important;
  color: #cbd5e1 !important;
}

.tt-section--muted p {
  color: #94a3b8;
  font-size: 0.9rem;
  line-height: 1.5;
}

.tt-section--muted a {
  color: #93c5fd;
}
.sdk-engine-layout {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.sdk-engine-nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.65rem 1rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid #1e293b;
  border-radius: 10px;
  background: #0b1020;
}

.sdk-engine-nav__title {
  font-weight: 700;
  color: #f8fafc;
  font-size: 0.95rem;
  margin-right: 0.25rem;
}

.sdk-engine-nav__links {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 0.35rem;
}

.sdk-engine-nav__a {
  padding: 0.3rem 0.65rem;
  border-radius: 6px;
  font-size: 0.85rem;
  color: #94a3b8;
  text-decoration: none;
}

.sdk-engine-nav__a:hover {
  color: #e2e8f0;
  background: rgba(255, 255, 255, 0.06);
}

.sdk-engine-nav__a--active {
  color: #f1f5f9 !important;
  background: rgba(0, 102, 255, 0.22);
}
.sdk-engine-page {
  color: #e2e8f0;
}

.sdk-engine-page__h1 {
  margin: 0 0 0.5rem;
  font-size: 1.5rem;
  color: #f8fafc;
}

.sdk-engine-page__lead {
  margin: 0 0 1.25rem;
  color: #94a3b8;
  line-height: 1.5;
  max-width: 65ch;
}

.sdk-engine-page__lead strong {
  color: #e2e8f0;
}

.sdk-engine-page__muted {
  color: #64748b;
}

.sdk-engine-page__section {
  margin-bottom: 1.5rem;
}

.sdk-engine-page__section h2 {
  margin: 0 0 0.5rem;
  font-size: 1.05rem;
  color: #f1f5f9;
}

.sdk-engine-page__ol {
  margin: 0 0 0.75rem;
  padding-left: 1.25rem;
  color: #94a3b8;
}

.sdk-engine-page__ul {
  margin: 0 0 1rem;
  padding-left: 1.25rem;
  color: #cbd5e1;
  line-height: 1.55;
}

.sdk-engine-page__para {
  margin: 0;
  color: #94a3b8;
  line-height: 1.55;
  max-width: 72ch;
}

.sdk-engine-page__para a {
  color: #93c5fd;
}

.sdk-engine-page__para code,
.sdk-engine-page__ol code {
  font-size: 0.88em;
  color: #fde68a;
}

.sdk-engine-page__pre {
  margin: 0 0 1rem;
  padding: 0.85rem 1rem;
  border-radius: 8px;
  border: 1px solid #334155;
  background: #0f172a;
  color: #cbd5e1;
  font-size: 0.82rem;
  overflow-x: auto;
}

.sdk-engine-page__cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 0.75rem;
}

.sdk-engine-page__cards--dim .sdk-engine-card:not(:hover) {
  opacity: 0.85;
}

.sdk-engine-card {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  padding: 0.9rem 1rem;
  border-radius: 12px;
  border: 1px solid #1e293b;
  background: #0b1020;
  text-decoration: none;
  color: inherit;
  transition: border-color 0.15s, transform 0.15s;
}

.sdk-engine-card:hover {
  border-color: #3b82f6;
  transform: translateY(-1px);
}

.sdk-engine-card--static {
  cursor: default;
  opacity: 0.7;
}

.sdk-engine-card--static:hover {
  transform: none;
  border-color: #1e293b;
}

.sdk-engine-card__t {
  font-weight: 700;
  color: #f8fafc;
  font-size: 0.95rem;
}

.sdk-engine-card__d {
  font-size: 0.82rem;
  color: #94a3b8;
  line-height: 1.4;
}

.sdk-changelog__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.sdk-changelog__item {
  border: 1px solid #1e293b;
  border-radius: 12px;
  padding: 1rem 1.1rem;
  background: #0b1020;
}

.sdk-changelog__meta {
  font-size: 0.78rem;
  color: #64748b;
  margin-bottom: 0.35rem;
}

.sdk-changelog__subject {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  color: #f1f5f9;
}

.sdk-changelog__notes {
  margin: 0;
  color: #94a3b8;
  font-size: 0.9rem;
  line-height: 1.5;
  white-space: pre-wrap;
}

.sdk-changelog__empty {
  color: #64748b;
  font-size: 0.9rem;
}

.sdk-changelog__err {
  color: #f87171;
  font-size: 0.9rem;
}
.sdks-page {
  color: #e2e8f0;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
}

.sdks-hero {
  border: 1px solid #1e293b;
  background: linear-gradient(180deg, #0b1220 0%, #0a0f18 100%);
  border-radius: 14px;
  padding: 1.25rem 1.25rem 1rem;
}

.sdks-hero h1 {
  margin: 0 0 0.5rem;
  font-size: 1.7rem;
  color: #f8fafc;
}

.sdks-hero p {
  margin: 0;
  color: #94a3b8;
  max-width: 72ch;
  line-height: 1.5;
}

.sdks-section__title {
  margin: 0 0 0.85rem;
  color: #f8fafc;
  font-size: 1.15rem;
  font-weight: 600;
}

.sdks-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

@media (max-width: 1100px) {
  .sdks-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 640px) {
  .sdks-grid {
    grid-template-columns: 1fr;
  }
}

.sdk-box {
  position: relative;
  border: 1px solid #1e293b;
  background: #0b1020;
  border-radius: 14px;
  padding: 1rem 1rem 1rem 0.85rem;
  min-height: 140px;
}

.sdk-box__badge {
  position: absolute;
  top: 0.65rem;
  right: 0.65rem;
  z-index: 1;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  border-radius: 6px;
  padding: 0.2rem 0.45rem;
  line-height: 1.2;
}

.sdk-box__badge--beta {
  color: #bfdbfe;
  border: 1px solid #2563eb;
  background: rgba(37, 99, 235, 0.28);
}

.sdk-box__badge--coming-soon {
  color: #cbd5e1;
  border: 1px solid #475569;
  background: rgba(51, 65, 85, 0.45);
}

.sdk-box__row {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding-right: 4.5rem;
}

.sdk-box__logo-wrap {
  flex-shrink: 0;
  width: 72px;
  height: 72px;
  border-radius: 12px;
  background: #0f172a;
  border: 1px solid #1e293b;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.sdk-box__logo {
  width: 56px;
  height: 56px;
  object-fit: contain;
}

.sdk-box__body {
  min-width: 0;
  flex: 1;
}

.sdk-box__title {
  margin: 0 0 0.35rem;
  font-size: 1.05rem;
  font-weight: 700;
  color: #f8fafc;
}

.sdk-box__version {
  margin: 0 0 0.5rem;
  font-size: 0.82rem;
  color: #94a3b8;
}

.sdk-box__version-num {
  color: #cbd5e1;
  font-weight: 600;
}

.sdk-box__links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.28rem;
}

.sdk-box__link {
  font-size: 0.9rem;
  color: #60a5fa;
  text-decoration: none;
  width: fit-content;
}

.sdk-box__link:hover {
  text-decoration: underline;
}

.sdk-box__link--disabled {
  color: #64748b !important;
  cursor: not-allowed;
  pointer-events: none;
  user-select: none;
}

.sdk-box__link--disabled:hover {
  text-decoration: none;
}
/* Admin ticket desk. Like Support.css, this read light-theme variables nothing defines and fell back to light colours
   on the dark console; it now uses the design tokens from styles/tokens.css. */
.admin-support {
  max-width: 900px;
  margin: 0 auto;
  padding: 1rem;
}
.admin-support-back {
  display: inline-block;
  margin-bottom: 1rem;
  color: var(--vs-dim);
  text-decoration: none;
}
.admin-support-back:hover {
  color: var(--vs-chalk);
  text-decoration: underline;
}
.admin-support h1 {
  font-size: 1.5rem;
  margin-bottom: 0.25rem;
}
.admin-support-desc {
  color: var(--vs-dim);
  margin-bottom: 1rem;
}
.admin-support-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  margin-bottom: 1rem;
}
.admin-support-filters label {
  display: flex;
  flex-direction: column;
  font-size: 0.875rem;
  color: var(--vs-dim);
}
.admin-support-select {
  margin-top: 0.25rem;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck);
  color: var(--vs-chalk);
  color-scheme: dark;
  font: inherit;
  font-size: 0.9375rem;
  min-width: 120px;
}
.admin-support-table-wrap {
  overflow-x: auto;
}
.admin-support-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}
.admin-support-table th,
.admin-support-table td {
  padding: 0.5rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid var(--vs-rail-soft);
}
.admin-support-table th {
  font-weight: 600;
  color: var(--vs-dim);
}
.admin-support-link {
  color: var(--vs-act);
  text-decoration: none;
}
.admin-support-link:hover {
  color: var(--vs-act);
  text-decoration: underline;
}
.admin-support-detail {
  margin-top: 1rem;
}
.admin-support-meta-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  font-size: 0.875rem;
}
.admin-support-date {
  margin-left: auto;
  color: var(--vs-dim);
}
.admin-support-subject {
  font-size: 1.25rem;
  margin-bottom: 0.5rem;
}
.admin-support-description {
  white-space: pre-wrap;
  margin-bottom: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--vs-rail-soft);
}
.admin-support-controls {
  display: flex;
  gap: 1rem;
  margin-bottom: 1rem;
}
.admin-support-controls label {
  display: flex;
  flex-direction: column;
  font-size: 0.875rem;
  color: var(--vs-dim);
}
/**
 * Chat reports.
 *
 * A list of cards rather than a table, because the thing being judged is a sentence somebody wrote and a table
 * cell is the wrong shape for it. The message is the loudest thing in each card: everything else is who, where
 * and when, which only matter once you have read it.
 *
 * The conversation opens inside the card instead of on another page, so a decision is made where the evidence is
 * rather than after a navigation that loses the queue.
 */

.acr-muted {
  color: var(--vs-faint);
  font-size: 0.875rem;
}

.acr-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--vs-s3);
}

.acr-item {
  padding: var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
}

.acr-item-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s3);
  flex-wrap: wrap;
  margin-bottom: var(--vs-s3);
}

.acr-badges {
  display: inline-flex;
  align-items: center;
  gap: var(--vs-s2);
  flex-wrap: wrap;
}

.acr-when {
  font-size: 0.75rem;
  color: var(--vs-faint);
  font-variant-numeric: tabular-nums;
}

/* The reported words. Quoted by the indent and the rule, not by quote marks, which would read as part of them. */
.acr-body {
  margin: 0 0 var(--vs-s3);
  padding-inline-start: var(--vs-s3);
  border-inline-start: 2px solid var(--vs-rail);
  color: var(--vs-chalk);
  font-size: 0.9375rem;
  line-height: 1.5;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.acr-removed {
  color: var(--vs-faint);
  font-style: italic;
}

.acr-meta {
  margin: 0 0 var(--vs-s2);
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

/* What the reporter said in their own words, which is not the same kind of thing as the message. */
.acr-note {
  margin: 0 0 var(--vs-s3);
  font-size: 0.8125rem;
  color: var(--vs-dim);
  font-style: italic;
}

.acr-context {
  margin-top: var(--vs-s4);
  padding-top: var(--vs-s3);
  border-top: 1px solid var(--vs-rail-soft);
}

.acr-context-head {
  margin: 0 0 var(--vs-s2);
  font-size: 0.75rem;
  color: var(--vs-faint);
}

.acr-line {
  display: flex;
  gap: var(--vs-s3);
  margin: 0 0 2px;
  padding: 0.25rem var(--vs-s2);
  border-radius: var(--vs-r-sm);
  font-size: 0.8125rem;
  line-height: 1.45;
}

/* The one being judged, marked so the eye finds it without counting lines. */
.acr-line--reported {
  background: var(--vs-deck-hi);
}

.acr-line-who {
  flex: none;
  width: 8rem;
  color: var(--vs-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.acr-line-body {
  flex: 1;
  min-width: 0;
  color: var(--vs-chalk);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.acr-line-gone {
  flex: none;
  color: var(--vs-faint);
  font-style: italic;
}
/**
 * Ops keys.
 *
 * The one-time reveal is the only loud thing on the page: it is the moment staff can lose the key for good. Everything
 * else is a quiet list.
 */

.aok-reveal {
  border-color: var(--vs-warn);
  margin-bottom: var(--vs-s5);
}

.aok-reveal-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--vs-s2);
}

.aok-reveal-key {
  flex: 1 1 22rem;
  min-width: 0;
  padding: var(--vs-s2) var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  overflow-wrap: anywhere;
  user-select: all;
}

.aok-section {
  margin-top: var(--vs-s5);
}

.aok-section-title {
  margin: 0 0 var(--vs-s3);
  font-size: 1rem;
  font-weight: 600;
}

.aok-studios {
  list-style: none;
  margin: 0 0 var(--vs-s3);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--vs-s2);
}

.aok-studios li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--vs-s1) var(--vs-s2);
}

.aok-id {
  font-size: 0.75rem;
  color: var(--vs-faint);
  overflow-wrap: anywhere;
}
/**
 * Ad networks.
 *
 * Money pages are read column by column, so every amount is right-aligned in tabular figures and the network's own
 * ids sit in the mono face, where a transposed character is easier to spot. An app no game claims is tinted on
 * every table it appears in: its money goes to VS+ rather than a studio, and that should never be a surprise.
 */

.aan-network .vsp-select {
  min-width: 11rem;
}

.aan-panel {
  margin-bottom: var(--vs-s5);
}

.aan-section {
  margin-top: var(--vs-s5);
}

.aan-section-title {
  margin: 0 0 var(--vs-s3);
  font-size: 1rem;
  font-weight: 600;
}

.aan-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vs-s3);
  margin-bottom: var(--vs-s4);
}

.aan-inline-field {
  max-width: 14rem;
}

/* Doubled with the table class: the shared table styles set cell alignment and outrank a bare class. */
.aan-table th.aan-num,
.aan-table td.aan-num,
.aan-num {
  text-align: end;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.aan-negative {
  color: var(--vs-fault);
}

.aan-id {
  font-family: var(--vs-mono);
  font-size: 0.8125rem;
  overflow-wrap: anywhere;
}

.aan-table .vsp-table-sub {
  display: block;
}

.aan-table td .vsp-table-sub {
  font-family: var(--vs-mono);
  font-size: 0.75rem;
}

.aan-row-unlinked td {
  background: var(--vs-warn-wash);
}

.aan-preview {
  margin-top: var(--vs-s5);
  padding-top: var(--vs-s4);
  border-top: 1px solid var(--vs-rail-soft);
  display: flex;
  flex-direction: column;
  gap: var(--vs-s3);
}

.aan-totals {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: var(--vs-s3);
  margin: 0;
}

.aan-totals div {
  padding: var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-md);
}

.aan-totals dt {
  color: var(--vs-faint);
  font-size: 0.8125rem;
}

.aan-totals dd {
  margin: var(--vs-s1) 0 0;
  font-size: 1.125rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.aan-paste {
  font-family: var(--vs-mono);
  font-size: 0.8125rem;
}
/**
 * Play home — mobile first.
 *
 * The page chrome gets out of the way so that faces and game art carry the personality: no outer
 * panel around each section, headings sitting directly on the page ground, and saturated blue kept
 * for actions alone. Every list is a horizontal rail that bleeds to the screen edge and shows part
 * of the next card, which is what tells a thumb there is more to the right.
 *
 * Hover colours and borders are restated rather than inherited: index.css still carries Vite's
 * starter rules for bare `a` and `button`, and an `a:hover` there outranks a bare class here.
 *
 * Written with logical properties throughout, because this portal ships in Arabic and the whole
 * layout mirrors.
 */

/* The gutter the layout already applies to <main>, so rails can cancel it and bleed. */
.ph {
  --ph-gutter: 1rem;
  --ph-ink: #eef3f8;
  --ph-ink-2: #a8b9c9; /* lifted from the old #94a3b8: secondary text was too dim to scan */
  --ph-ink-3: #7f93a5;
  --ph-surface: #1b1b26;
  --ph-surface-hi: #24242f;
  --ph-hairline: rgba(255, 255, 255, 0.09);
  --ph-live: #22c55e;
  --ph-act: #2563eb;
  --ph-act-hi: #1d4ed8;

  padding-block: 0.25rem 1.5rem;
}

/* ---- header ------------------------------------------------------------------------------ */

/* One line, not a title plus a tagline paragraph. The sections say what the page is. */
.ph-greeting {
  margin: 0 0 1.35rem;
  font-size: 1.15rem;
  font-weight: 650;
  line-height: 1.25;
  color: var(--ph-ink);
}

/* ---- section scaffolding ----------------------------------------------------------------- */

.ph-section {
  margin-bottom: 1.75rem;
}
.ph-section:last-child {
  margin-bottom: 0;
}

.ph-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.7rem;
}

.ph-head h2 {
  margin: 0;
  font-size: 1.02rem;
  font-weight: 650;
  letter-spacing: -0.01em;
  color: var(--ph-ink);
}

.ph-subhead {
  margin: 1.1rem 0 0.6rem;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--ph-ink-2);
}

/* A text link, not a filled button: "see all" is never the thing you most want someone to do. */
.ph-link,
.ph-link:visited {
  flex: none;
  font-size: 0.85rem;
  font-weight: 550;
  color: #7fb0ff;
  text-decoration: none;
  background: none;
}
.ph-link:hover,
.ph-link:focus-visible {
  color: #a9caff;
  text-decoration: underline;
}

.ph-muted {
  margin: 0;
  font-size: 0.88rem;
  color: var(--ph-ink-3);
}

/* ---- empty states ------------------------------------------------------------------------ */

/* Compact by design. Sparse content stretched to fill a screen reads as a broken page. */
.ph-empty {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.85rem 0.9rem;
  border: 1px dashed var(--ph-hairline);
  border-radius: 12px;
}
.ph-empty p {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.35;
  color: var(--ph-ink-2);
}

/* ---- rails ------------------------------------------------------------------------------- */

.ph-rail {
  display: flex;
  gap: 0.7rem;
  margin: 0;
  padding: 0.15rem 0 0.3rem;
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;

  /* Bleed past the page gutter so a card can sit against the screen edge. */
  margin-inline: calc(var(--ph-gutter) * -1);
  padding-inline: var(--ph-gutter);
  scroll-padding-inline-start: var(--ph-gutter);
}
.ph-rail::-webkit-scrollbar {
  display: none;
}
.ph-rail > li {
  scroll-snap-align: start;
}

/* The arrows sit against the page gutter, so they overlap the edge of a card rather than the
   middle of one. Only rendered for a hovering fine pointer, so they never steal space on a phone. */
.ph-rail-wrap {
  position: relative;
}

.ph-rail-btn {
  position: absolute;
  inset-block-start: 50%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--ph-hairline);
  background: rgba(13, 13, 18, 0.86);
  color: var(--ph-ink);
  cursor: pointer;
  opacity: 0.72;
  z-index: 2;
}
.ph-rail-btn:hover {
  opacity: 1;
  background: rgba(13, 13, 18, 0.96);
  border-color: rgba(255, 255, 255, 0.24);
  color: var(--ph-ink);
}
.ph-rail-btn:disabled {
  opacity: 0.22;
  cursor: default;
}
/* Centred is right for the friends rail, which is one row of faces. On the taller rails it lands
   squarely on the card title, so those anchor to the artwork band instead. Both the 16:9 event art
   and the square cover sit within a few pixels of this line across the 375 to 480px the page spans,
   and the page is capped at 480, so a fixed offset tracks them closely enough. */
.ph-rail-wrap:has(.ph-rail--events) .ph-rail-btn,
.ph-rail-wrap:has(.ph-rail--discover) .ph-rail-btn {
  inset-block-start: 5.1rem;
  transform: none;
}

.ph-rail-btn--prev {
  inset-inline-start: -0.4rem;
}
.ph-rail-btn--next {
  inset-inline-end: -0.4rem;
}

/* Mirrored automatically: the glyphs point along the reading direction. */
[dir='rtl'] .ph-rail-btn svg {
  transform: scaleX(-1);
}

/* ---- 1. friends -------------------------------------------------------------------------- */

.ph-friend {
  flex: none;
  width: 4.75rem;
}

.ph-friend-tap,
.ph-friend-tap:visited {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0.2rem 0;
  color: var(--ph-ink);
  text-decoration: none;
  background: none;
}
.ph-friend-tap:hover,
.ph-friend-tap:focus-visible {
  color: var(--ph-ink);
  text-decoration: none;
}
.ph-friend-tap:hover .ph-avatar {
  border-color: rgba(255, 255, 255, 0.35);
}

.ph-avatar-wrap {
  position: relative;
  display: block;
  line-height: 0;
}

.ph-avatar {
  display: block;
  width: 3.25rem;
  height: 3.25rem;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--ph-hairline);
  background: var(--ph-surface-hi);
}

.ph-avatar--initials {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  font-weight: 650;
  line-height: 1;
  color: var(--ph-ink-2);
}

/* Green means one specific, provable thing: this person is in a game right now. */
.ph-dot {
  position: absolute;
  inset-block-end: 1px;
  inset-inline-end: 1px;
  width: 0.7rem;
  height: 0.7rem;
  border-radius: 50%;
  background: var(--ph-live);
  border: 2px solid #15151d; /* punches back to the page ground so the dot reads as a cut-out */
}

.ph-friend-name {
  max-width: 100%;
  font-size: 0.76rem;
  font-weight: 550;
  line-height: 1.2;
  text-align: center;
  color: var(--ph-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ph-friend-game {
  max-width: 100%;
  font-size: 0.7rem;
  line-height: 1.2;
  text-align: center;
  color: var(--ph-ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- 2. events --------------------------------------------------------------------------- */

/* 80% leaves a deliberate sliver of the next card visible. */
.ph-event {
  flex: none;
  width: 80%;
  max-width: 20rem;
  border: 1px solid var(--ph-hairline);
  border-radius: 14px;
  background: var(--ph-surface);
  overflow: hidden;
}

.ph-event-art {
  position: relative;
  aspect-ratio: 16 / 9;
  background: var(--ph-surface-hi);
}
.ph-event-art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ph-event-art-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 1.6rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.22);
}

.ph-live-badge {
  position: absolute;
  inset-block-start: 0.5rem;
  inset-inline-start: 0.5rem;
  padding: 0.15rem 0.45rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  color: #04220f;
  background: var(--ph-live);
}

.ph-event-body {
  padding: 0.8rem 0.85rem 0.9rem;
}

.ph-event-name {
  margin: 0 0 0.35rem;
  font-size: 0.98rem;
  font-weight: 650;
  line-height: 1.25;
  color: var(--ph-ink);
}

.ph-event-game {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0 0 0.3rem;
  font-size: 0.8rem;
  color: var(--ph-ink-2);
}
.ph-event-game-icon {
  width: 1.1rem;
  height: 1.1rem;
  border-radius: 4px;
  object-fit: cover;
  flex: none;
}

.ph-event-when {
  margin: 0 0 0.5rem;
  font-size: 0.85rem;
  font-weight: 550;
  color: var(--ph-ink);
}

.ph-event-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0 0 0.55rem;
}

.ph-chip {
  padding: 0.16rem 0.5rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 550;
  color: var(--ph-ink-2);
  background: rgba(255, 255, 255, 0.07);
}
.ph-chip--prize {
  color: #ffd79a;
  background: rgba(245, 165, 36, 0.14);
}

.ph-event-sponsor {
  margin: 0 0 0.65rem;
  font-size: 0.72rem;
  color: var(--ph-ink-3);
}

/* ---- 3. discovery ------------------------------------------------------------------------ */

/* Narrower than an event card: two and a bit fit, so the row reads as a browse strip. */
.ph-discover {
  flex: none;
  width: 42%;
  max-width: 10.5rem;
}

.ph-discover-tap,
.ph-discover-tap:visited {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  color: var(--ph-ink);
  text-decoration: none;
  background: none;
}
.ph-discover-tap:hover,
.ph-discover-tap:focus-visible {
  color: var(--ph-ink);
  text-decoration: none;
}
.ph-discover-tap:hover .ph-cover {
  border-color: rgba(255, 255, 255, 0.3);
}

.ph-cover {
  display: block;
  aspect-ratio: 1 / 1;
  border-radius: 12px;
  border: 1px solid var(--ph-hairline);
  background: var(--ph-surface-hi);
  overflow: hidden;
}
.ph-cover img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ph-cover-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 1.5rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.22);
}

.ph-discover-title {
  font-size: 0.83rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--ph-ink);
}

.ph-discover-sub {
  font-size: 0.75rem;
  line-height: 1.3;
  color: var(--ph-ink-2);
}

/* ---- buttons ----------------------------------------------------------------------------- */

.ph-btn,
.ph-btn:visited {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 2.25rem;
  padding: 0.4rem 0.9rem;
  border-radius: 9px;
  border: 1px solid transparent;
  font-size: 0.84rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

/* Solid blue is reserved for the action the card exists to offer. */
.ph-btn--primary,
.ph-btn--primary:visited {
  width: 100%;
  color: #fff;
  background: var(--ph-act);
  border-color: var(--ph-act);
}
.ph-btn--primary:hover,
.ph-btn--primary:focus-visible {
  color: #fff;
  background: var(--ph-act-hi);
  border-color: var(--ph-act-hi);
  text-decoration: none;
}

.ph-btn--quiet,
.ph-btn--quiet:visited {
  flex: none;
  color: var(--ph-ink);
  background: rgba(255, 255, 255, 0.07);
  border-color: var(--ph-hairline);
}
.ph-btn--quiet:hover,
.ph-btn--quiet:focus-visible {
  color: var(--ph-ink);
  background: rgba(255, 255, 255, 0.12);
  text-decoration: none;
}

/* ---- shared ------------------------------------------------------------------------------ */

.ph a:focus-visible,
.ph button:focus-visible {
  outline: 2px solid #7fb0ff;
  outline-offset: 2px;
}

@media (min-width: 480px) {
  .ph {
    --ph-gutter: 1.5rem;
  }
  .ph-event {
    width: 72%;
  }
}
.play-support.support-page {
  padding-bottom: 4rem;
}
/**
 * The player's games grid.
 *
 * Two columns on a phone. Four made each card about 70px wide, which is narrower than most game
 * names and left the artwork, the only thing that tells cards apart at a glance, smaller than the
 * text under it.
 *
 * Shares the home page's palette deliberately: same charcoal surfaces, same hairlines, same blue
 * kept for actions, so moving between tabs does not feel like moving between apps.
 */

.pg {
  --pg-ink: #eef3f8;
  --pg-ink-2: #a8b9c9;
  --pg-ink-3: #7f93a5;
  --pg-surface: #1b1b26;
  --pg-surface-hi: #24242f;
  --pg-hairline: rgba(255, 255, 255, 0.09);
  --pg-ok: #35d67f;
  --pg-act: #2563eb;

  padding-block: 0.25rem 1.5rem;
}

/* ---- header ------------------------------------------------------------------------------ */

.pg-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

.pg-title {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 650;
  color: var(--pg-ink);
}

.pg-add,
.pg-add:visited {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 2.25rem;
  padding: 0.4rem 0.85rem;
  border-radius: 9px;
  border: 1px solid var(--pg-act);
  background: var(--pg-act);
  color: #fff;
  font-size: 0.84rem;
  font-weight: 600;
  text-decoration: none;
}
.pg-add:hover,
.pg-add:focus-visible {
  background: #1d4ed8;
  border-color: #1d4ed8;
  color: #fff;
  text-decoration: none;
}

/* ---- search and sort --------------------------------------------------------------------- */

.pg-controls {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1rem;
}

.pg-search {
  width: 100%;
  min-height: 2.4rem;
  padding: 0.45rem 0.7rem;
  border-radius: 10px;
  border: 1px solid var(--pg-hairline);
  background: var(--pg-surface);
  color: var(--pg-ink);
  font-size: 0.9rem;
}
.pg-search::placeholder {
  color: var(--pg-ink-3);
}
.pg-search:focus-visible {
  outline: 2px solid #7fb0ff;
  outline-offset: 1px;
  border-color: transparent;
}

.pg-sort {
  display: flex;
  gap: 0.35rem;
}

.pg-sort-btn {
  padding: 0.3rem 0.7rem;
  border-radius: 999px;
  border: 1px solid var(--pg-hairline);
  background: transparent;
  color: var(--pg-ink-2);
  font-size: 0.78rem;
  font-weight: 550;
  cursor: pointer;
}
.pg-sort-btn:hover {
  color: var(--pg-ink);
  background: rgba(255, 255, 255, 0.06);
}
/* Selected state carries weight as well as colour, so it does not rely on colour alone. */
.pg-sort-btn--on {
  color: var(--pg-ink);
  font-weight: 650;
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.2);
}

/* View toggle. Icon-only, because the two shapes say it faster than two words would, with the
   words kept for screen readers and as the tooltip. */
.pg-toggle {
  display: flex;
  gap: 0.25rem;
}

.pg-toggle-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.1rem;
  height: 2.1rem;
  padding: 0;
  border-radius: 9px;
  border: 1px solid var(--pg-hairline);
  background: transparent;
  color: var(--pg-ink-3);
  cursor: pointer;
}
.pg-toggle-btn:hover {
  color: var(--pg-ink);
  background: rgba(255, 255, 255, 0.06);
}
.pg-toggle-btn--on {
  color: var(--pg-ink);
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.2);
}

.pg-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---- grid -------------------------------------------------------------------------------- */

.pg-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0.85rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The grid stretches the item, but the card inside it has to fill that height too, or a two-line
   name on one card leaves its neighbour short and the badges stop lining up across the row. */
.pg-item {
  display: flex;
  min-width: 0;
}
.pg-card {
  flex: 1;
}

.pg-card,
.pg-card:visited {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.4rem;
  padding: 0.6rem;
  border-radius: 14px;
  border: 1px solid var(--pg-hairline);
  background: var(--pg-surface);
  color: var(--pg-ink);
  text-decoration: none;
}
.pg-card:hover,
.pg-card:focus-visible {
  background: var(--pg-surface-hi);
  border-color: rgba(255, 255, 255, 0.16);
  color: var(--pg-ink);
  text-decoration: none;
}
/* The whole card is the target, so it needs to acknowledge a press. */
.pg-card:active {
  transform: scale(0.985);
  background: #191922;
}
.pg-card:focus-visible {
  outline: 2px solid #7fb0ff;
  outline-offset: 2px;
}

/* One square frame for every game, whatever shape its logo is. Contain keeps a wordmark readable
   where cover would slice the ends off it; the tinted ground stops a transparent logo floating. */
.pg-art {
  display: block;
  aspect-ratio: 1 / 1;
  border-radius: 10px;
  background: radial-gradient(circle at 50% 40%, #2b2b3a 0%, #1f1f2b 70%);
  overflow: hidden;
}
.pg-art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 0.45rem;
  box-sizing: border-box;
}
.pg-art-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 1.9rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.24);
}

/* Two lines of room. A name is the thing a player is looking for, so it gets the space before the
   badge does, and only truncates after actually running out of it. */
.pg-name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--pg-ink);
}

.pg-text {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
}

.pg-platform {
  font-size: 0.72rem;
  line-height: 1.2;
  color: var(--pg-ink-3);
}

/* ---- list view ----------------------------------------------------------------------------- */

/* Same markup as the grid, laid out along the row instead of down the card. Artwork shrinks to a
   thumbnail because in a list the name is what you are scanning, not the picture. */
.pg-grid--list {
  grid-template-columns: 1fr;
  gap: 0.5rem;
}

.pg-grid--list .pg-card {
  flex-direction: row;
  align-items: center;
  gap: 0.7rem;
  padding: 0.5rem 0.6rem;
}

.pg-grid--list .pg-art {
  flex: none;
  width: 3.2rem;
  aspect-ratio: 1 / 1;
  border-radius: 8px;
}
.pg-grid--list .pg-art img {
  padding: 0.2rem;
}
.pg-grid--list .pg-art-fallback {
  font-size: 1.1rem;
}

.pg-grid--list .pg-text {
  flex: 1;
  min-width: 0;
}

/* One line here: the row is as wide as the screen, so a name that does not fit in one is rare, and
   two-line rows would make the list harder to scan than the grid it is an alternative to. */
.pg-grid--list .pg-name {
  -webkit-line-clamp: 1;
  line-clamp: 1;
  font-size: 0.88rem;
}

.pg-grid--list .pg-badge {
  flex: none;
  align-self: center;
  margin-top: 0;
}

/* ---- status ------------------------------------------------------------------------------ */

.pg-badge {
  align-self: flex-start;
  margin-top: auto;
  padding: 0.12rem 0.45rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-weight: 600;
  line-height: 1.45;
}
.pg-badge--ok {
  color: #9ff0c4;
  background: rgba(53, 214, 127, 0.13);
}

/* The tick lives here rather than in the translated string: it is the same mark in every
   language, and keeping it out of the copy stops it being dropped or doubled by a translator. */
.pg-badge--ok::before {
  content: '\2713\00a0';
}
.pg-badge--todo {
  color: #b9d3ff;
  background: rgba(37, 99, 235, 0.18);
}
/* Nothing to do, said out loud. This used to be an empty gap, which reads as missing information. */
.pg-badge--none {
  padding-inline: 0;
  color: var(--pg-ink-3);
  background: none;
  font-weight: 500;
}

/* ---- messages ---------------------------------------------------------------------------- */

.pg-muted {
  margin: 0.25rem 0 0;
  font-size: 0.88rem;
  color: var(--pg-ink-3);
}

.pg-error {
  margin: 0.25rem 0 0.75rem;
  font-size: 0.88rem;
  color: #ff9b9b;
}

@media (min-width: 420px) {
  .pg-controls {
    flex-direction: row;
    align-items: center;
  }
  .pg-search {
    flex: 1;
  }
  .pg-sort {
    flex: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pg-card:active {
    transform: none;
  }
}
/**
 * The event card, wherever it appears.
 *
 * Same charcoal surface and hairline as every other card in the play portal. The only card that
 * carries an accent is a live one, because that is the only one where being noticed is the point.
 */

.pev {
  padding: 0.75rem 0.8rem;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: #1b1b26;
}

.pev--live {
  border-color: rgba(53, 214, 127, 0.35);
}

/* Still readable, clearly over. Hiding ended events entirely would leave a player wondering where
   the thing they played last week went. */
.pev--ended {
  opacity: 0.72;
}

.pev-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.6rem;
}

.pev-name {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 650;
  line-height: 1.25;
  color: #eef3f8;
}

.pev-state {
  flex: none;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1.5;
}
.pev-state--live {
  color: #04220f;
  background: #35d67f;
}
.pev-state--upcoming {
  color: #b9d3ff;
  background: rgba(37, 99, 235, 0.22);
}
.pev-state--ended {
  color: #7f93a5;
  background: rgba(255, 255, 255, 0.07);
}

.pev-game {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.4rem 0 0;
  font-size: 0.79rem;
  color: #a8b9c9;
}
.pev-game-icon {
  flex: none;
  width: 1.05rem;
  height: 1.05rem;
  border-radius: 4px;
  object-fit: cover;
}

.pev-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin: 0.45rem 0 0;
}

.pev-chip {
  padding: 0.14rem 0.45rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 550;
  color: #a8b9c9;
  background: rgba(255, 255, 255, 0.07);
}

.pev-when {
  font-size: 0.78rem;
  color: #a8b9c9;
}

.pev-sponsor {
  margin: 0.35rem 0 0;
  font-size: 0.72rem;
  color: #7f93a5;
}
/**
 * The events page shell. The cards themselves are PlayEventCard, shared with the game page.
 */

.pe {
  padding-block: 0.25rem 1.5rem;
}

.pe-back,
.pe-back:visited {
  display: inline-block;
  margin-bottom: 0.75rem;
  font-size: 0.85rem;
  font-weight: 550;
  color: #7fb0ff;
  text-decoration: none;
  background: none;
}
.pe-back:hover,
.pe-back:focus-visible {
  color: #a9caff;
  text-decoration: underline;
}

.pe-title {
  margin: 0 0 1.1rem;
  font-size: 1.15rem;
  font-weight: 650;
  color: #eef3f8;
}

.pe-group {
  margin-bottom: 1.5rem;
}
.pe-group:last-child {
  margin-bottom: 0;
}

.pe-group-title {
  margin: 0 0 0.6rem;
  font-size: 0.88rem;
  font-weight: 650;
  color: #a8b9c9;
}

.pe-list {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pe-muted {
  margin: 0;
  font-size: 0.88rem;
  color: #7f93a5;
}

.pe-error {
  margin: 0 0 0.75rem;
  font-size: 0.88rem;
  color: #ff9b9b;
}

/* Compact, with one thing to do. Not a full-height illustration for a state that resolves itself
   the moment the player adds a game. */
.pe-empty {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.85rem 0.9rem;
  border: 1px dashed rgba(255, 255, 255, 0.09);
  border-radius: 12px;
}
.pe-empty p {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.35;
  color: #a8b9c9;
}

.pe-btn,
.pe-btn:visited {
  flex: none;
  display: inline-flex;
  align-items: center;
  min-height: 2.25rem;
  padding: 0.4rem 0.85rem;
  border-radius: 9px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: rgba(255, 255, 255, 0.07);
  color: #eef3f8;
  font-size: 0.84rem;
  font-weight: 600;
  text-decoration: none;
}
.pe-btn:hover,
.pe-btn:focus-visible {
  background: rgba(255, 255, 255, 0.12);
  color: #eef3f8;
  text-decoration: none;
}

.pe a:focus-visible {
  outline: 2px solid #7fb0ff;
  outline-offset: 2px;
}
.play-games {
  padding: 0.5rem 0 1.5rem;
}

.play-games-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  margin-bottom: 0.75rem;
}

.play-games-title {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
  color: #f1f5f9;
}

.play-games-add-btn {
  flex-shrink: 0;
  padding: 0.45rem 0.9rem;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
  color: #e0f2fe;
  background: rgba(59, 130, 246, 0.35);
  border: 1px solid rgba(96, 165, 250, 0.45);
}
.play-games-add-btn:hover {
  background: rgba(59, 130, 246, 0.5);
}

.play-games h1 {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
  color: #f1f5f9;
}

.play-games-desc {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: #94a3b8;
}

.play-games-error {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: #f87171;
}

.play-games-muted {
  margin: 0;
  font-size: 0.9rem;
  color: #64748b;
}

.play-games-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.play-games-box {
  padding: 1.25rem;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.play-games-game-name {
  margin: 0 0 0.75rem;
  font-size: 1.1rem;
  font-weight: 600;
  color: #e2e8f0;
}

.play-games-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  margin-bottom: 1rem;
  font-size: 0.9rem;
  color: #94a3b8;
}

.play-games-events h3 {
  margin: 0 0 0.5rem;
  font-size: 0.95rem;
  font-weight: 600;
  color: #cbd5e1;
}

.play-games-events ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.play-games-events li {
  padding: 0.5rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 0.9rem;
}
.play-games-events li:last-child {
  border-bottom: none;
}

.play-games-events strong {
  display: block;
  color: #e2e8f0;
  margin-bottom: 0.2rem;
}

.play-games-event-meta {
  font-size: 0.8rem;
  color: #94a3b8;
}

.play-games-back {
  display: inline-block;
  margin-bottom: 1rem;
  font-size: 0.9rem;
  color: #60a5fa;
  text-decoration: none;
}
.play-games-back:hover {
  text-decoration: underline;
}

.play-games-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.75rem;
}

@media (max-width: 900px) {
  .play-games-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 400px) {
  .play-games-grid {
    grid-template-columns: 1fr;
  }
}

.play-games-card {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  padding: 0.75rem;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  text-decoration: none;
  color: inherit;
  transition: background 0.15s ease, border-color 0.15s ease;
  min-height: 120px;
}
.play-games-card:hover {
  background: rgba(255, 255, 255, 0.07);
  border-color: rgba(96, 165, 250, 0.35);
}

.play-games-card-icon-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  max-height: 72px;
  margin: 0 auto 0.5rem;
  width: 100%;
}

.play-games-card-icon {
  max-width: 100%;
  max-height: 72px;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 8px;
}

.play-games-card-icon-placeholder {
  width: 64px;
  height: 64px;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.35), rgba(139, 92, 246, 0.35));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.5rem;
  font-weight: 700;
  color: #e2e8f0;
}

.play-games-card-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
  text-align: center;
}

.play-games-card-name {
  font-size: 0.85rem;
  font-weight: 600;
  color: #e2e8f0;
  line-height: 1.25;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.play-games-card-badge {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.15rem 0.4rem;
  border-radius: 4px;
}
.play-games-card-badge--ok {
  background: rgba(34, 197, 94, 0.2);
  color: #86efac;
}
.play-games-card-badge--warn {
  background: rgba(251, 191, 36, 0.15);
  color: #fcd34d;
}

/* Game detail */
.play-game-detail-header {
  display: flex;
  gap: 1rem;
  align-items: center;
  margin-bottom: 1.25rem;
}

.play-game-detail-icon-wrap {
  flex-shrink: 0;
}

.play-game-detail-icon {
  width: 80px;
  height: 80px;
  object-fit: contain;
  border-radius: 12px;
  background: rgba(0, 0, 0, 0.2);
}

.play-game-detail-icon-placeholder {
  width: 80px;
  height: 80px;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(59, 130, 246, 0.35), rgba(139, 92, 246, 0.35));
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  font-weight: 700;
  color: #e2e8f0;
}

.play-game-detail-title {
  margin: 0;
  font-size: 1.35rem;
  color: #f1f5f9;
}

.play-game-detail-section {
  margin-bottom: 1.5rem;
  padding: 1rem;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.play-game-detail-h2 {
  margin: 0 0 0.75rem;
  font-size: 1rem;
  font-weight: 600;
  color: #cbd5e1;
}

.play-game-detail-status {
  margin: 0 0 0.75rem;
  font-size: 0.95rem;
}
.play-game-detail-status--ok {
  color: #86efac;
}
.play-game-detail-status--warn {
  color: #fcd34d;
}

.play-game-detail-btn {
  padding: 0.5rem 1rem;
  border-radius: 8px;
  border: 1px solid rgba(96, 165, 250, 0.5);
  background: rgba(59, 130, 246, 0.25);
  color: #93c5fd;
  font-size: 0.9rem;
  cursor: pointer;
}
.play-game-detail-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.play-game-detail-btn--danger {
  border-color: rgba(248, 113, 113, 0.45);
  background: rgba(239, 68, 68, 0.15);
  color: #fca5a5;
}

.play-game-detail-danger-zone {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.play-game-detail-footnote {
  margin: 0.5rem 0 0;
  font-size: 0.8rem;
}

.play-game-detail-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  font-size: 0.9rem;
  color: #94a3b8;
}

.play-game-detail-event-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.play-game-detail-event {
  padding: 0.5rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 0.9rem;
}
.play-game-detail-event:last-child {
  border-bottom: none;
}
.play-game-detail-event strong {
  display: block;
  color: #e2e8f0;
  margin-bottom: 0.2rem;
}

/* Add games */
.play-add-games-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.play-add-games-row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

.play-add-games-icon-wrap {
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.play-add-games-icon {
  max-width: 48px;
  max-height: 48px;
  border-radius: 8px;
  object-fit: contain;
}

.play-add-games-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.play-add-games-name {
  font-weight: 600;
  color: #e2e8f0;
}

.play-add-games-btn {
  flex-shrink: 0;
  padding: 0.4rem 0.85rem;
  border-radius: 8px;
  border: 1px solid rgba(96, 165, 250, 0.45);
  background: rgba(59, 130, 246, 0.25);
  color: #93c5fd;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
}
.play-add-games-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Sponsored event: brand line under the event meta. */
.play-games-event-sponsor {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  margin-top: 0.2rem;
  font-size: 0.8rem;
  color: #ffd479;
}

.play-games-event-sponsor-logo {
  width: 16px;
  height: 16px;
  border-radius: 4px;
  object-fit: cover;
}
.share-card-block {
  margin: 0.75rem 0 0.25rem;
}

.share-card-btn {
  padding: 0.6rem 1.1rem;
  border-radius: 999px;
  border: none;
  background: #3b82f6;
  color: #fff;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.share-card-btn:disabled {
  opacity: 0.6;
  cursor: default;
}

.share-card-btn--ghost {
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.25);
  color: inherit;
  font-weight: 500;
}

.share-card-msg {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.7);
  word-break: break-all;
}

.share-card-preview {
  margin-top: 0.75rem;
}

.share-card-preview img {
  width: 100%;
  border-radius: 12px;
  display: block;
}

.share-card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 0.6rem;
}

/* Compact trigger: secondary to the thing it shares, so it reads as a control rather than the point
   of the section. */
.share-card-block--compact {
  display: inline-flex;
}

.share-card-btn--compact {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.28rem 0.6rem;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: transparent;
  color: #a8b9c9;
  font-size: 0.78rem;
  font-weight: 550;
}
.share-card-btn--compact:hover:not(:disabled) {
  color: #eef3f8;
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.24);
}
/**
 * One game's page.
 *
 * Same charcoal surfaces, spacing and controls as the rest of the play portal, with the game's own
 * artwork supplying the only colour that changes between pages. That is the whole trick here: the
 * banner is built from the game's icon rather than from a per-game theme, so every game gets its own
 * character without anyone having to author a cover for it.
 */

.gd {
  --gd-ink: #eef3f8;
  --gd-ink-2: #a8b9c9;
  --gd-ink-3: #7f93a5;
  --gd-surface: #1b1b26;
  --gd-surface-hi: #24242f;
  --gd-hairline: rgba(255, 255, 255, 0.09);
  --gd-live: #35d67f;
  --gd-act: #2563eb;

  padding-block: 0.25rem 1.5rem;
}

.gd-back,
.gd-back:visited {
  display: inline-block;
  margin-bottom: 0.75rem;
  font-size: 0.85rem;
  font-weight: 550;
  color: #7fb0ff;
  text-decoration: none;
}
.gd-back:hover,
.gd-back:focus-visible {
  color: #a9caff;
  text-decoration: underline;
}

/* ---- banner ------------------------------------------------------------------------------- */

.gd-banner {
  position: relative;
  margin-bottom: 1.5rem;
  border-radius: 14px;
  border: 1px solid var(--gd-hairline);
  background: var(--gd-surface);
  overflow: hidden;
  isolation: isolate;
}

/* The game's own icon, blown up and thrown out of focus. Enough of its colour survives to make the
   page feel like that game; none of its detail survives to compete with the text. */
.gd-banner-wash {
  position: absolute;
  inset: -30%;
  width: 160%;
  height: 160%;
  object-fit: cover;
  filter: blur(28px) saturate(1.3) brightness(0.55);
  opacity: 0.85;
  z-index: -1;
}
/* A fade over the wash, so text contrast does not depend on which game this is. */
.gd-banner::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(12, 12, 17, 0.35) 0%, rgba(12, 12, 17, 0.88) 100%);
  z-index: -1;
}

.gd-banner-inner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.9rem;
}

.gd-banner-icon {
  flex: none;
  display: block;
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(10, 10, 15, 0.5);
  overflow: hidden;
}
.gd-banner-icon img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 0.25rem;
  box-sizing: border-box;
}
.gd-banner-icon-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 1.2rem;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.4);
}

.gd-banner-text {
  min-width: 0;
}

.gd-banner-title {
  margin: 0 0 0.2rem;
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.2;
  color: #fff;
}

/* This line replaced the game's slug, which was an internal identifier and meant nothing to a
   player. It carries the platform and the account they are actually playing as. */
.gd-banner-sub {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.3;
}

.gd-banner-platform {
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.14);
  color: #e6edf4;
  font-weight: 600;
}

.gd-banner-account {
  color: #cdd9e4;
}
.gd-banner-account--todo {
  color: #ffd79a;
}

/* ---- sections ----------------------------------------------------------------------------- */

.gd-section {
  margin-bottom: 1.6rem;
}
.gd-section:last-child {
  margin-bottom: 0;
}

.gd-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  margin-bottom: 0.65rem;
}

.gd-h2 {
  margin: 0 0 0.65rem;
  font-size: 1rem;
  font-weight: 650;
  color: var(--gd-ink);
}
.gd-section-head .gd-h2 {
  margin: 0;
}

.gd-muted {
  margin: 0 0 0.5rem;
  font-size: 0.88rem;
  line-height: 1.4;
  color: var(--gd-ink-3);
}
.gd-muted:last-child {
  margin-bottom: 0;
}

.gd-error {
  margin: 0 0 0.75rem;
  font-size: 0.88rem;
  color: #ff9b9b;
}

/* ---- stat tiles ---------------------------------------------------------------------------- */

/* The number leads and the label explains it, which is the opposite of the sentence this replaced
   ("Matches: 4 Wins: 2 Kills: 0"), where the labels were the loudest part. */
.gd-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(4.5rem, 1fr));
  gap: 0.5rem;
}

.gd-tile {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  padding: 0.7rem 0.6rem;
  border-radius: 12px;
  border: 1px solid var(--gd-hairline);
  background: var(--gd-surface);
}

.gd-tile-value {
  font-size: 1.4rem;
  font-weight: 700;
  line-height: 1.1;
  color: var(--gd-ink);
  font-variant-numeric: tabular-nums;
}

.gd-tile-label {
  font-size: 0.72rem;
  line-height: 1.25;
  color: var(--gd-ink-2);
}

.gd-stat-rest {
  margin: 0.6rem 0 0;
}

.gd-stat-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.gd-stat-row:last-child {
  border-bottom: none;
}
.gd-stat-row dt {
  font-size: 0.83rem;
  color: var(--gd-ink-2);
}
.gd-stat-row dd {
  margin: 0;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--gd-ink);
  font-variant-numeric: tabular-nums;
}

/* ---- events -------------------------------------------------------------------------------- */

.gd-events {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.gd-event {
  padding: 0.75rem 0.8rem;
  border-radius: 12px;
  border: 1px solid var(--gd-hairline);
  background: var(--gd-surface);
}
/* A live event is the only one worth pulling the eye, so it is the only one with an accent. */
.gd-event--live {
  border-color: rgba(53, 214, 127, 0.35);
}
.gd-event--ended {
  opacity: 0.72;
}

.gd-event-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.6rem;
}

.gd-event-name {
  margin: 0;
  font-size: 0.92rem;
  font-weight: 650;
  line-height: 1.25;
  color: var(--gd-ink);
}

.gd-state {
  flex: none;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  line-height: 1.5;
}
.gd-state--live {
  color: #04220f;
  background: var(--gd-live);
}
.gd-state--upcoming {
  color: #b9d3ff;
  background: rgba(37, 99, 235, 0.22);
}
.gd-state--ended {
  color: var(--gd-ink-3);
  background: rgba(255, 255, 255, 0.07);
}

.gd-event-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin: 0.45rem 0 0;
}

.gd-chip {
  padding: 0.14rem 0.45rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 550;
  color: var(--gd-ink-2);
  background: rgba(255, 255, 255, 0.07);
}

.gd-event-when {
  font-size: 0.78rem;
  color: var(--gd-ink-2);
}

.gd-event-sponsor {
  margin: 0.35rem 0 0;
  font-size: 0.72rem;
  color: var(--gd-ink-3);
}

/* ---- friends -------------------------------------------------------------------------------- */

.gd-friends {
  display: flex;
  gap: 0.7rem;
  margin: 0;
  padding: 0.1rem 0 0.2rem;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
}
.gd-friends::-webkit-scrollbar {
  display: none;
}

.gd-friend {
  flex: none;
  width: 4rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
}

.gd-friend-avatar-wrap {
  position: relative;
  display: block;
  line-height: 0;
}

.gd-friend-avatar {
  display: block;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid var(--gd-hairline);
  background: var(--gd-surface-hi);
}
.gd-friend-avatar--initials {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  font-weight: 650;
  line-height: 1;
  color: var(--gd-ink-2);
}

/* Green means the one thing the platform can actually prove: they are in this game right now. */
.gd-friend-dot {
  position: absolute;
  inset-block-end: 0;
  inset-inline-end: 0;
  width: 0.65rem;
  height: 0.65rem;
  border-radius: 50%;
  background: var(--gd-live);
  border: 2px solid #15151d;
}

.gd-friend-name {
  max-width: 100%;
  font-size: 0.72rem;
  line-height: 1.2;
  text-align: center;
  color: var(--gd-ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ---- buttons -------------------------------------------------------------------------------- */

.gd-btn {
  min-height: 2.25rem;
  padding: 0.4rem 0.9rem;
  border-radius: 9px;
  border: 1px solid var(--gd-hairline);
  background: rgba(255, 255, 255, 0.07);
  color: var(--gd-ink);
  font-size: 0.84rem;
  font-weight: 600;
  cursor: pointer;
}
.gd-btn:disabled {
  opacity: 0.5;
  cursor: default;
}
.gd-btn--danger {
  color: #ffb4b4;
  border-color: rgba(255, 107, 107, 0.35);
  background: rgba(255, 107, 107, 0.1);
}
.gd-btn--danger:hover:not(:disabled) {
  background: rgba(255, 107, 107, 0.18);
  color: #ffd0d0;
}

.gd-disconnect {
  margin-top: 0.25rem;
}

.gd-footnote {
  margin-top: 0.4rem;
  font-size: 0.76rem;
}

.gd a:focus-visible,
.gd button:focus-visible {
  outline: 2px solid #7fb0ff;
  outline-offset: 2px;
}
/* A sheet over the page. Bottom-anchored on a phone, a centred panel once there is room. */

.sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: rgba(4, 8, 12, 0.66);
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 0;
}

.sheet {
  width: 100%;
  max-width: 34rem;
  max-height: 88vh;
  overflow-y: auto;
  background: var(--vs-deck);
  color: var(--vs-chalk);
  border: 1px solid var(--vs-rail);
  border-bottom: 0;
  border-radius: var(--vs-r-lg) var(--vs-r-lg) 0 0;
  box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.5);
  animation: sheet-rise 180ms ease-out;
}

/* Motion here reports what just happened, so it goes when someone has asked for less of it. */
@media (prefers-reduced-motion: reduce) {
  .sheet {
    animation: none;
  }
}

@keyframes sheet-rise {
  from {
    transform: translateY(12px);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s3);
  padding: var(--vs-s4) var(--vs-s4) var(--vs-s3);
  border-bottom: 1px solid var(--vs-rail-soft);
}

.sheet-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--vs-chalk);
}

/* Same reason as the row icons: an SVG in a flex button shrinks unless told not to. */
.sheet-close svg {
  flex: none;
}

.sheet-close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--vs-r-md);
  border: 1px solid transparent;
  background: transparent;
  color: var(--vs-dim);
  cursor: pointer;
}

.sheet-close:hover {
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
  border-color: var(--vs-rail);
}

.sheet-close:focus-visible,
.sheet:focus-visible {
  outline: 2px solid var(--vs-act);
  outline-offset: 2px;
}

.sheet-body {
  padding: var(--vs-s4);
}

@media (min-width: 40rem) {
  .sheet-scrim {
    align-items: center;
    padding: var(--vs-s4);
  }

  .sheet {
    border-bottom: 1px solid var(--vs-rail);
    border-radius: var(--vs-r-lg);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  }
}
/**
 * Friends.
 *
 * A quiet list with one loud thing in it: the green mark on somebody who is in a game right now,
 * which is the only fact on this page that changes what you do next. Everything else stays flat so
 * that mark is the thing the eye lands on.
 *
 * Rows are separated by a hairline rather than boxed as cards. Fifty people in fifty boxes reads as
 * fifty objects; the same fifty in one column reads as a list of people, which is what it is.
 */

.pf {
  padding: var(--vs-s4);
  max-width: 44rem;
}

/* ---------- head ---------- */

.pf-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--vs-s4);
  margin-bottom: var(--vs-s4);
}

.pf-title {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 650;
  color: var(--vs-chalk);
}

.pf-desc {
  margin: var(--vs-s1) 0 0;
  color: var(--vs-dim);
  font-size: 0.875rem;
  max-width: 42ch;
}

.pf-add {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--vs-s2);
  min-height: 40px;
  padding: 0 var(--vs-s3);
  border-radius: var(--vs-r-pill);
  border: 1px solid var(--vs-act);
  background: var(--vs-act-wash);
  color: var(--vs-act);
  font: inherit;
  font-size: 0.875rem;
  font-weight: 600;
  cursor: pointer;
}

.pf-add:hover {
  background: var(--vs-act);
  border-color: var(--vs-act);
  color: var(--vs-act-ink);
}

.pf-add--inline {
  margin-top: var(--vs-s3);
}

/* ---------- filters ---------- */

.pf-filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--vs-s2);
  margin-bottom: var(--vs-s3);
}

.pf-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--vs-s2);
  min-height: 36px;
  padding: 0 var(--vs-s3);
  border-radius: var(--vs-r-pill);
  border: 1px solid var(--vs-rail);
  background: transparent;
  color: var(--vs-dim);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}

.pf-pill:hover {
  background: var(--vs-deck);
  color: var(--vs-chalk);
  border-color: var(--vs-rail);
}

.pf-pill--on {
  background: var(--vs-deck);
  border-color: var(--vs-act);
  color: var(--vs-chalk);
}

.pf-pill-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.375rem;
  height: 1.375rem;
  padding: 0 0.375rem;
  border-radius: var(--vs-r-pill);
  background: var(--vs-rail-soft);
  color: var(--vs-faint);
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
}

.pf-pill--on .pf-pill-count {
  background: var(--vs-act-wash);
  color: var(--vs-act);
}

/* Requests waiting on you are the one count worth colouring. */
.pf-pill-count--due {
  background: var(--vs-act);
  color: var(--vs-act-ink);
}

/* ---------- search ---------- */

.pf-search {
  display: block;
  margin-bottom: var(--vs-s4);
}

.pf-search-label {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.pf-search-input {
  width: 100%;
  min-height: 42px;
  padding: 0 var(--vs-s3);
  border-radius: var(--vs-r-md);
  border: 1px solid var(--vs-rail);
  background: var(--vs-deck);
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.9375rem;
}

.pf-search-input::placeholder {
  color: var(--vs-faint);
}

/* ---------- list ---------- */

.pf-note {
  margin: 0 0 var(--vs-s2);
  color: var(--vs-faint);
  font-size: 0.8125rem;
}

.pf-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.pf-row {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  min-height: 68px;
  padding: var(--vs-s2) 0;
  border-bottom: 1px solid var(--vs-rail-soft);
}

.pf-row:last-child {
  border-bottom: 0;
}

.pf-avatar-wrap {
  position: relative;
  flex: none;
  width: 52px;
  height: 52px;
}

.pf-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--vs-deck-hi);
  border: 1px solid var(--vs-rail);
  color: var(--vs-dim);
  font-size: 1rem;
  font-weight: 600;
}

/* Ringed in the page ground so it reads as sitting on top of the picture, not inside it.
   Logical inset, or it stays on the same physical corner in Arabic while the row mirrors around
   it, and the dashboard shows the identical badge on the opposite corner of the same avatar. */
.pf-dot {
  position: absolute;
  inset-inline-end: 0;
  inset-block-end: 2px;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  border: 2px solid var(--vs-void);
  background: var(--vs-rail);
}

/* In a game and online share the green. Which of the two it is gets said in words underneath,
   where naming the game tells somebody far more than a second colour could. */
.pf-dot--ingame,
.pf-dot--online {
  background: var(--vs-on);
}

/* Away is a hollow ring rather than a filled grey circle: filled reads as another state with its
   own colour, hollow reads as the absence of one. It also survives being looked at by somebody who
   cannot tell the green from the grey. */
.pf-dot--offline {
  background: var(--vs-void);
  box-shadow: inset 0 0 0 2px var(--vs-rail);
}

.pf-identity {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pf-name {
  color: var(--vs-chalk);
  font-size: 0.9375rem;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pf-activity {
  color: var(--vs-dim);
  font-size: 0.8125rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Quieter than "Online", because a list of absent people should not be the loudest thing here. */
.pf-activity--away {
  color: var(--vs-faint);
}

.pf-activity--link {
  color: var(--vs-act);
  text-decoration: none;
}

.pf-activity--link:hover {
  text-decoration: underline;
}

/* ---------- row actions ---------- */

/**
 * Icons inside a flex button must be told not to shrink.
 *
 * An SVG is a flex item like any other, and its flex base size is not simply its width attribute,
 * so these were being squashed to about a quarter of their width while keeping their full height.
 * On screen that is not a small icon, it is a speck: the message glyph read as a dot and the
 * overflow menu as a thin smear. The button around it was the right size throughout, which is what
 * made it easy to miss when measuring the button rather than what is drawn inside it.
 */
.pf-add svg,
.pf-msg svg,
.pf-more svg,
.pf-empty-art {
  flex: none;
}

.pf-msg,
.pf-more {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: var(--vs-r-md);
  border: 1px solid transparent;
  background: transparent;
  color: var(--vs-dim);
  cursor: pointer;
}

.pf-more:hover:not(:disabled) {
  background: var(--vs-deck-hi);
  border-color: var(--vs-rail);
  color: var(--vs-chalk);
}

/**
 * Messaging is the main action on this row and it does not exist yet, so the slot is held rather
 * than hidden. The first attempt coloured it --vs-rail, which measured 1.6:1 against the page and
 * was invisible on screen: the row read as having no main action at all, which is the opposite of
 * what this page is for. Visible enough to be understood as the place messages will live, quiet
 * enough not to be mistaken for something that works today.
 */
.pf-msg:disabled {
  color: var(--vs-faint);
  border-color: var(--vs-rail-soft);
  opacity: 0.75;
  cursor: not-allowed;
}

.pf-more:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.pf-more-wrap {
  position: relative;
  flex: none;
}

.pf-menu {
  position: absolute;
  inset-inline-end: 0;
  top: calc(100% + 4px);
  z-index: 20;
  min-width: 11rem;
  padding: var(--vs-s1);
  border-radius: var(--vs-r-md);
  border: 1px solid var(--vs-rail);
  background: var(--vs-deck);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45);
}

.pf-menu-item {
  display: block;
  width: 100%;
  min-height: 40px;
  padding: 0 var(--vs-s3);
  border: 0;
  border-radius: var(--vs-r-sm);
  background: transparent;
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.875rem;
  text-align: start;
  cursor: pointer;
}

.pf-menu-item:hover {
  background: var(--vs-deck-hi);
}

.pf-menu-item--danger {
  color: var(--vs-fault);
}

.pf-menu-item--danger:hover {
  background: var(--vs-fault-wash);
  color: var(--vs-fault);
}

/* ---------- requests ---------- */

.pf-section {
  margin-bottom: var(--vs-s5);
}

.pf-section-title {
  margin: 0 0 var(--vs-s2);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--vs-dim);
}

.pf-row--request {
  min-height: 60px;
}

.pf-req-actions {
  display: flex;
  gap: var(--vs-s2);
  flex: none;
}

/* ---------- buttons ---------- */

/* 44px, matching the icon buttons on the same row. Accept and Decline sit next to each other and
   carry opposite consequences, so they are the last controls here that should be small. */
.pf-btn {
  min-height: 44px;
  padding: 0 var(--vs-s3);
  border-radius: var(--vs-r-md);
  border: 1px solid var(--vs-rail);
  background: transparent;
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.8125rem;
  font-weight: 600;
  cursor: pointer;
}

.pf-btn:hover:not(:disabled) {
  background: var(--vs-deck-hi);
  border-color: var(--vs-rail);
  color: var(--vs-chalk);
}

.pf-btn--primary {
  background: var(--vs-act-fill);
  border-color: var(--vs-act-fill);
  color: var(--vs-act-ink);
}

.pf-btn--primary:hover:not(:disabled) {
  background: var(--vs-act-fill-hi);
  border-color: var(--vs-act-fill-hi);
  color: var(--vs-act-ink);
}

.pf-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* ---------- states ---------- */

.pf-muted {
  color: var(--vs-dim);
  font-size: 0.9375rem;
}

.pf-empty-filter {
  padding: var(--vs-s5) 0;
}

.pf-error {
  margin: 0 0 var(--vs-s3);
  color: var(--vs-fault);
  font-size: 0.875rem;
}

.pf-sent {
  margin: 0 0 var(--vs-s3);
  color: var(--vs-on);
  font-size: 0.875rem;
}

.pf-empty {
  padding: var(--vs-s6) 0;
  text-align: center;
}

.pf-empty-art {
  color: var(--vs-rail);
  margin-bottom: var(--vs-s3);
}

.pf-empty-line {
  margin: 0;
  color: var(--vs-chalk);
  font-size: 1rem;
  font-weight: 600;
}

/* ---------- add form ---------- */

.pf-addform-label {
  display: block;
  margin-bottom: var(--vs-s2);
  color: var(--vs-chalk);
  font-size: 0.875rem;
  font-weight: 600;
}

.pf-addform-input {
  width: 100%;
  min-height: 44px;
  padding: 0 var(--vs-s3);
  border-radius: var(--vs-r-md);
  border: 1px solid var(--vs-rail);
  background: var(--vs-void);
  color: var(--vs-chalk);
  font: inherit;
  font-size: 0.9375rem;
}

.pf-addform-input::placeholder {
  color: var(--vs-faint);
}

.pf-addform-hint {
  margin: var(--vs-s2) 0 var(--vs-s4);
  color: var(--vs-faint);
  font-size: 0.8125rem;
}

.pf-addform-send {
  width: 100%;
  min-height: 44px;
}

/* ---------- focus ---------- */

.pf-add:focus-visible,
.pf-pill:focus-visible,
.pf-search-input:focus-visible,
.pf-msg:focus-visible,
.pf-more:focus-visible,
.pf-menu-item:focus-visible,
.pf-btn:focus-visible,
.pf-addform-input:focus-visible,
.pf-activity--link:focus-visible {
  outline: 2px solid var(--vs-act);
  outline-offset: 2px;
}

@media (max-width: 30rem) {
  .pf-head {
    flex-direction: column;
    align-items: stretch;
  }

  .pf-add {
    justify-content: center;
  }

  .pf-row--request {
    flex-wrap: wrap;
  }

  .pf-req-actions {
    width: 100%;
    padding-inline-start: calc(52px + var(--vs-s3));
  }
}

/* Reached from Chats now rather than from the bottom bar, so it needs a way back the bar no longer gives it. */
.pf-back {
  display: inline-block;
  margin-bottom: var(--vs-s3);
  color: var(--vs-dim);
  font-size: 0.875rem;
  text-decoration: none;
}

.pf-back:hover {
  color: var(--vs-chalk);
}
/**
 * Chats: the list, and one conversation.
 *
 * The list follows Friends: a column of people separated by hairlines, not a stack of cards. The only loud thing
 * is the unread count, because it is the only fact on the screen that changes which row you open.
 *
 * The thread is the one place in this app where the content is the interface, so it takes the whole column and
 * the chrome around it stays quiet. Bubbles are asymmetric on purpose: yours are filled and sit to the end of the
 * line, theirs are a flat surface at the start of it. That is enough to tell them apart without a colour per
 * person, which stops meaning anything past three people in a room.
 *
 * Everything reads inline-start and inline-end rather than left and right, because this portal renders in Arabic
 * with the whole layout mirrored, and a conversation that mirrors its own direction is the point.
 */

.pc {
  padding: var(--vs-s4);
  max-width: 44rem;
}

.pc-title {
  margin: 0 0 var(--vs-s4);
  font-size: 1.5rem;
  font-weight: 650;
  color: var(--vs-chalk);
}

.pc-muted {
  color: var(--vs-faint);
  font-size: 0.875rem;
}

.pc-error {
  color: var(--vs-fault);
  font-size: 0.875rem;
}

/* ---------- empty ---------- */

.pc-empty {
  padding: var(--vs-s6) 0;
}

.pc-empty-title {
  margin: 0 0 var(--vs-s2);
  font-size: 1rem;
  font-weight: 600;
  color: var(--vs-chalk);
}

.pc-empty-link {
  display: inline-block;
  margin-top: var(--vs-s4);
  color: var(--vs-act);
  font-size: 0.9375rem;
  font-weight: 550;
  text-decoration: none;
}

.pc-empty-link:hover {
  color: var(--vs-act);
  text-decoration: underline;
}

/* ---------- list ---------- */

.pc-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.pc-list li + li .pc-row {
  border-top: 1px solid var(--vs-rail-soft);
}

.pc-row {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  padding: var(--vs-s3) var(--vs-s2);
  color: var(--vs-chalk);
  text-decoration: none;
  min-width: 0;
}

.pc-row:hover {
  background: var(--vs-deck);
  color: var(--vs-chalk);
}

.pc-avatar {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  flex: none;
  border-radius: 50%;
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
  font-size: 0.875rem;
  font-weight: 650;
  overflow: hidden;
}

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

.pc-row-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
  min-width: 0;
}

.pc-row-top,
.pc-row-bottom {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--vs-s3);
  min-width: 0;
}

.pc-row-name {
  font-size: 0.9375rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pc-row-when {
  flex: none;
  font-size: 0.75rem;
  color: var(--vs-faint);
  font-variant-numeric: tabular-nums;
}

.pc-row-preview {
  font-size: 0.875rem;
  color: var(--vs-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pc-unread {
  flex: none;
  min-width: 1.25rem;
  padding: 0 0.35rem;
  border-radius: var(--vs-r-pill);
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1.25rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ---------- thread ---------- */

.pct {
  display: flex;
  flex-direction: column;
  /* The composer sits at the bottom of the visible area, not the bottom of the document. dvh so the phone's
     address bar collapsing does not leave it floating. */
  height: calc(100dvh - 8.5rem);
  min-height: 20rem;
}

.pct-head {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  padding: var(--vs-s3) var(--vs-s4);
  border-bottom: 1px solid var(--vs-rail-soft);
  flex: none;
}

.pct-back {
  color: var(--vs-dim);
  font-size: 1.25rem;
  text-decoration: none;
  line-height: 1;
}

.pct-back:hover {
  color: var(--vs-chalk);
}

.pct-head-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.pct-head-name {
  font-size: 0.9375rem;
  font-weight: 650;
  color: var(--vs-chalk);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pct-head-sub {
  font-size: 0.75rem;
  color: var(--vs-faint);
}

.pct-list {
  flex: 1;
  overflow-y: auto;
  padding: var(--vs-s4);
  display: flex;
  flex-direction: column;
  gap: var(--vs-s2);
  overscroll-behavior: contain;
}

.pct-centre {
  text-align: center;
  margin: auto 0;
}

.pct-more {
  align-self: center;
  margin-bottom: var(--vs-s3);
  padding: 0.3rem var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-pill);
  background: transparent;
  color: var(--vs-dim);
  font-size: 0.8125rem;
  font-family: inherit;
  cursor: pointer;
}

.pct-more:hover:not(:disabled) {
  color: var(--vs-chalk);
  border-color: var(--vs-rail);
  background: transparent;
}

.pct-day {
  margin: var(--vs-s3) 0;
  text-align: center;
  font-size: 0.75rem;
  color: var(--vs-faint);
}

.pct-msg {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  max-width: 82%;
}

.pct-msg--mine {
  align-self: flex-end;
  align-items: flex-end;
}

.pct-msg-sender {
  display: inline-flex;
  align-items: center;
  gap: var(--vs-s2);
  margin-top: var(--vs-s2);
  font-size: 0.75rem;
  color: var(--vs-faint);
}

.pct-msg-avatar {
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
  flex: none;
  border-radius: 50%;
  background: var(--vs-deck-hi);
  color: var(--vs-dim);
  font-size: 0.5625rem;
  font-weight: 650;
  overflow: hidden;
}

.pct-msg-avatar-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pct-bubble {
  display: inline-block;
  padding: 0.45rem 0.7rem;
  border-radius: var(--vs-r-md);
  background: var(--vs-deck);
  color: var(--vs-chalk);
  font-size: 0.9375rem;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.pct-msg--mine .pct-bubble {
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
}

.pct-bubble--gone {
  background: transparent;
  border: 1px dashed var(--vs-rail-soft);
  color: var(--vs-faint);
  font-style: italic;
}

.pct-msg--mine .pct-bubble--gone {
  background: transparent;
  color: var(--vs-faint);
}

.pct-time {
  display: inline-block;
  margin-inline-start: var(--vs-s3);
  font-size: 0.625rem;
  opacity: 0.65;
  font-variant-numeric: tabular-nums;
  vertical-align: baseline;
}

.pct-error {
  margin: 0;
  padding: var(--vs-s2) var(--vs-s4);
  color: var(--vs-fault);
  font-size: 0.8125rem;
}

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

.pct-composer {
  display: flex;
  gap: var(--vs-s2);
  padding: var(--vs-s3) var(--vs-s4);
  border-top: 1px solid var(--vs-rail-soft);
  flex: none;
  /* App.css styles every bare form as a 360px column. A class outranks that rule, but only for the
     properties it restates, so direction and width are restated here or the composer stacks. */
  flex-direction: row;
  max-width: none;
  width: auto;
  align-items: center;
}

.pct-input {
  flex: 1;
  min-width: 0;
  padding: 0.55rem var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-pill);
  background: var(--vs-sunk);
  color: var(--vs-chalk);
  font-size: 0.9375rem;
  font-family: inherit;
}

.pct-input:focus {
  outline: none;
  border-color: var(--vs-act);
}

.pct-send {
  flex: none;
  padding: 0.5rem var(--vs-s4);
  border: none;
  border-radius: var(--vs-r-pill);
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
  font-size: 0.875rem;
  font-weight: 650;
  font-family: inherit;
  cursor: pointer;
}

.pct-send:disabled {
  opacity: 0.5;
  cursor: default;
}

.pct-readonly {
  margin: 0;
  padding: var(--vs-s4);
  border-top: 1px solid var(--vs-rail-soft);
  color: var(--vs-faint);
  font-size: 0.8125rem;
  text-align: center;
}

/* ---------- report and block ---------- */

/*
 * The way to report or block sits on the message, not in a settings screen. It is quiet until you look for it,
 * because a flag on every line would read as an accusation waiting to happen, and it is always present rather
 * than appearing on hover, because a control that needs a mouse does not exist on a phone.
 */
.pct-flag {
  align-self: flex-start;
  margin-top: 2px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--vs-faint);
  font-size: 0.6875rem;
  font-family: inherit;
  cursor: pointer;
  text-decoration: underline;
}

.pct-flag:hover {
  color: var(--vs-dim);
  background: transparent;
}

.pct-done {
  margin: 0;
  padding: var(--vs-s2) var(--vs-s4);
  color: var(--vs-on);
  font-size: 0.8125rem;
}

/* A sheet from the bottom, where a thumb is, rather than a dialog in the middle of a phone screen. */
.pct-sheet {
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: var(--vs-s2);
  padding: var(--vs-s4) var(--vs-s4) var(--vs-s6);
  background: var(--vs-sunk);
  border-top: 1px solid var(--vs-rail);
  border-radius: var(--vs-r-md) var(--vs-r-md) 0 0;
}

.pct-sheet-title {
  margin: 0 0 var(--vs-s2);
  font-size: 0.9375rem;
  font-weight: 650;
  color: var(--vs-chalk);
}

.pct-sheet-label {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s2);
  font-size: 0.8125rem;
  color: var(--vs-dim);
}

.pct-sheet-select {
  padding: 0.5rem var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck);
  color: var(--vs-chalk);
  font-size: 0.9375rem;
  font-family: inherit;
}

.pct-sheet-btn {
  padding: 0.6rem var(--vs-s4);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-sm);
  background: var(--vs-deck);
  color: var(--vs-chalk);
  font-size: 0.9375rem;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
}

.pct-sheet-btn:hover:not(:disabled) {
  background: var(--vs-deck-hi);
  color: var(--vs-chalk);
}

.pct-sheet-btn--danger {
  border-color: transparent;
  background: var(--vs-fault);
  color: var(--vs-fault-ink);
}

.pct-sheet-btn--danger:hover:not(:disabled) {
  background: var(--vs-fault-fill-hi);
  color: var(--vs-fault-ink);
}

.pct-sheet-btn--quiet {
  border-color: transparent;
  background: transparent;
  color: var(--vs-dim);
}

.pct-sheet-btn--quiet:hover:not(:disabled) {
  background: transparent;
  color: var(--vs-chalk);
}

.pct-sheet-btn:disabled {
  opacity: 0.6;
  cursor: default;
}

/* What blocking actually does, said before it is done rather than after. */
.pct-sheet-note {
  margin: var(--vs-s2) 0 0;
  font-size: 0.75rem;
  line-height: 1.45;
  color: var(--vs-faint);
}

/* ---------- head and requests ---------- */

/*
 * Chats absorbed Friends, so the title shares its line with the way in to people. It is a labelled pill rather
 * than a bare icon: "a person shape in the corner" is only obvious once you already know what it does.
 */
.pc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--vs-s3);
  margin-bottom: var(--vs-s4);
}

.pc-head .pc-title {
  margin: 0;
}

.pc-new {
  display: inline-flex;
  align-items: center;
  gap: var(--vs-s2);
  flex: none;
  padding: 0.35rem var(--vs-s3);
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-pill);
  background: transparent;
  color: var(--vs-dim);
  font-size: 0.8125rem;
  font-weight: 550;
  text-decoration: none;
}

.pc-new:hover {
  background: var(--vs-deck);
  color: var(--vs-chalk);
}

/*
 * The only thing on this screen waiting on the reader, so it is the only thing louder than a conversation. It
 * sits above the list rather than in it, because it is not a conversation and a row that looked like one would
 * be opened expecting messages.
 */
.pc-requests {
  display: flex;
  align-items: center;
  gap: var(--vs-s3);
  margin-bottom: var(--vs-s4);
  padding: var(--vs-s3);
  border: 1px solid var(--vs-act);
  border-radius: var(--vs-r-md);
  background: var(--vs-act-wash);
  color: var(--vs-chalk);
  font-size: 0.875rem;
  text-decoration: none;
}

.pc-requests:hover {
  color: var(--vs-chalk);
  background: var(--vs-act-wash);
  filter: brightness(1.15);
}

.pc-requests-count {
  display: grid;
  place-items: center;
  min-width: 1.5rem;
  height: 1.5rem;
  flex: none;
  padding: 0 0.35rem;
  border-radius: var(--vs-r-pill);
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
  font-size: 0.75rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/**
 * A roster row: face, name, role. Same charcoal surface as every other card in the play portal.
 */

.mr {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  padding: 0.5rem 0.6rem;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: #1b1b26;
}

.mr-avatar-wrap {
  flex: none;
  line-height: 0;
}

.mr-avatar {
  display: block;
  width: 2.4rem;
  height: 2.4rem;
  border-radius: 50%;
  object-fit: cover;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: #24242f;
}

.mr-avatar--initials {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  font-weight: 650;
  line-height: 1;
  color: #a8b9c9;
}

/* An account that cannot be read is dimmer than one that simply has no picture, so the two states
   are distinguishable at a glance. */
.mr-avatar--gone {
  color: #5d6b78;
  border-style: dashed;
}

.mr-text {
  flex: 1;
  min-width: 0;
}

.mr-name {
  display: flex;
  align-items: baseline;
  gap: 0.4rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: #eef3f8;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.mr-name--gone {
  font-weight: 500;
  font-style: italic;
  color: #7f93a5;
}

.mr-you {
  flex: none;
  padding: 0.05rem 0.35rem;
  border-radius: 999px;
  font-size: 0.66rem;
  font-weight: 700;
  font-style: normal;
  color: #cdd9e4;
  background: rgba(255, 255, 255, 0.1);
}

.mr-role {
  flex: none;
  padding: 0.1rem 0.45rem;
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 650;
  line-height: 1.5;
}
/* Only the owner gets a colour. Three coloured badges in one list is noise, and the role that
   actually changes what someone can do is the one worth marking. */
.mr-role--owner {
  color: #ffd79a;
  background: rgba(245, 165, 36, 0.16);
}
.mr-role--officer {
  color: #b9d3ff;
  background: rgba(37, 99, 235, 0.18);
}
.mr-role--member {
  color: #a8b9c9;
  background: rgba(255, 255, 255, 0.07);
}

.mr-action {
  flex: none;
  display: flex;
  align-items: center;
}
/**
 * The way into a team's or guild's conversation.
 *
 * This replaced the placeholder that held the slot while chat was being built, and it keeps that panel's shape so
 * the page around it does not shift. What changes is the register: the dashed border and the dimmed everything
 * said "a room being built", and a door into a real conversation should not look provisional. Solid edge, live
 * button, one accent.
 */

.ce {
  padding: 0.85rem 0.9rem 0.9rem;
  border-radius: 14px;
  border: 1px solid var(--vs-rail-soft);
  background: var(--vs-deck);
}

.ce-title {
  margin: 0 0 0.3rem;
  font-size: 1rem;
  font-weight: 650;
  color: var(--vs-chalk);
}

.ce-desc {
  margin: 0 0 0.75rem;
  font-size: 0.83rem;
  line-height: 1.4;
  color: var(--vs-dim);
}

.ce-open {
  width: 100%;
  min-height: 2.25rem;
  padding: 0.4rem 0.9rem;
  border-radius: 9px;
  border: none;
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
  font-size: 0.84rem;
  font-weight: 650;
  font-family: inherit;
  cursor: pointer;
}

.ce-open:hover:not(:disabled) {
  background: var(--vs-act-fill);
  color: var(--vs-act-ink);
  filter: brightness(1.08);
}

.ce-open:disabled {
  opacity: 0.6;
  cursor: default;
}

.ce-error {
  margin: 0.5rem 0 0;
  font-size: 0.8rem;
  color: var(--vs-fault);
}
.play-tg {
  padding: 0.5rem 0 1.5rem;
}

.play-tg h1 {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
  color: #f1f5f9;
}

.play-tg-desc {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: #94a3b8;
}

.play-tg-tabs {
  display: flex;
  gap: 0.25rem;
  margin-bottom: 1rem;
}

.play-tg-tab {
  padding: 0.5rem 1rem;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(255, 255, 255, 0.06);
  color: #94a3b8;
  font-size: 0.95rem;
  cursor: pointer;
}

.play-tg-tab--active {
  background: #2563eb;
  color: #fff;
  border-color: #2563eb;
}

.play-tg-error {
  margin: 0 0 1rem;
  font-size: 0.9rem;
  color: #f87171;
}

.play-tg-muted {
  margin: 0;
  font-size: 0.9rem;
  color: #64748b;
}

.play-tg-section {
  margin-bottom: 1.25rem;
}

.play-tg-section-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
}

.play-tg-section h2 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  font-weight: 600;
  color: #e2e8f0;
}

.play-tg-section-header h2 {
  margin: 0;
}

.play-tg-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.play-tg-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  font-size: 0.95rem;
  color: #e2e8f0;
}

.play-tg-item--clickable .play-tg-item-btn {
  width: 100%;
  text-align: start;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.play-tg-tag {
  margin-inline-start: 0.25rem;
  font-size: 0.85rem;
  color: #94a3b8;
}

.play-tg-meta {
  font-size: 0.85rem;
  color: #94a3b8;
}

.play-tg-item-actions {
  display: flex;
  gap: 0.5rem;
}

.play-tg-btn {
  padding: 0.5rem 0.75rem;
  border-radius: 8px;
  border: none;
  font-size: 0.9rem;
  font-weight: 500;
  cursor: pointer;
}

.play-tg-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.play-tg-btn--primary {
  background: #2563eb;
  color: #fff;
}

.play-tg-btn--primary:hover:not(:disabled) {
  background: #1d4ed8;
}

.play-tg-btn--secondary {
  background: transparent;
  color: #94a3b8;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.play-tg-btn--accept {
  background: #2563eb;
  color: #fff;
}

.play-tg-btn--decline {
  background: transparent;
  color: #94a3b8;
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.play-tg-btn--danger {
  background: transparent;
  color: #f87171;
  border: 1px solid rgba(248, 113, 113, 0.4);
}

.play-tg-btn--danger:hover:not(:disabled) {
  background: rgba(248, 113, 113, 0.15);
}

.play-tg-invites {
  margin-bottom: 1.25rem;
}

.play-tg-invites h2 {
  margin: 0 0 0.5rem;
  font-size: 1rem;
  font-weight: 600;
  color: #e2e8f0;
}

.play-tg-create {
  margin-bottom: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.play-tg-input {
  padding: 0.6rem 0.75rem;
  border-radius: 8px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(255, 255, 255, 0.06);
  color: #f1f5f9;
  font-size: 0.95rem;
}

.play-tg-textarea {
  resize: vertical;
  min-height: 60px;
}

.play-tg-create-actions {
  display: flex;
  gap: 0.5rem;
}

/* Guild detail */
.play-tg-detail {
  padding: 0.5rem 0 1.5rem;
}

.play-tg-back {
  background: none;
  border: none;
  color: #94a3b8;
  font-size: 0.9rem;
  cursor: pointer;
  margin-bottom: 1rem;
  padding: 0;
}

.play-tg-back:hover {
  color: #e2e8f0;
}

.play-tg-detail h1 {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
  color: #f1f5f9;
}

.play-tg-detail-desc {
  margin: 0 0 0.5rem;
  font-size: 0.9rem;
  color: #94a3b8;
}

.play-tg-detail-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1rem;
  margin-top: 1rem;
}

.play-tg-inline-form {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  align-items: center;
}

.play-tg-inline-form .play-tg-input {
  flex: 1;
  min-width: 180px;
}

.play-tg-item--row {
  gap: 0.75rem;
}

.play-tg-select-inline {
  padding: 0.25rem 0.5rem;
  border-radius: 6px;
  border: 1px solid rgba(255, 255, 255, 0.15);
  background: rgba(255, 255, 255, 0.06);
  color: #e2e8f0;
  font-size: 0.85rem;
}

.play-tg-btn--sm {
  padding: 0.25rem 0.5rem;
  font-size: 0.85rem;
}

.play-tg-label {
  font-size: 0.9rem;
  color: #94a3b8;
  margin-bottom: 0.25rem;
  display: block;
}

/* ---- roster and the detail header ---------------------------------------------------------- */

/* Rows are MemberRow, which brings its own styling. This is only the stack they sit in. */
.play-tg-roster {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Manage sits beside the team's name rather than above the roster, so the settings it opens read
   as something you go and get rather than as part of the page. */
.play-tg-detail-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.75rem;
}
.play-tg-detail-head h1 {
  margin-bottom: 0.15rem;
}
.play-tg-detail-head .play-tg-btn {
  flex: none;
}

/* Field and action on one line, wrapping to two when the field would be too narrow to read an
   address in. Stretch rather than centre: a centred column of controls inside a left-aligned page
   reads as a mistake, which is what it looked like. */
.play-tg-invite {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  gap: 0.5rem;
}
.play-tg-invite .play-tg-input {
  flex: 1 1 11rem;
  min-width: 0;
  margin: 0;
}
.play-tg-invite .play-tg-btn {
  flex: 0 0 auto;
}

/* Confirmation of something that worked, so it is green rather than the error red beside it. */
.play-tg-note {
  margin: 0.5rem 0 0;
  font-size: 0.83rem;
  color: #9ff0c4;
}

/* How many of a quota are used, next to the button it governs. */
.play-tg-quota {
  margin: -0.35rem 0 0.75rem;
  font-size: 0.78rem;
  color: #7f93a5;
}
.play-tg-quota--full {
  color: #ffd79a;
}

/* ---- team cards ----------------------------------------------------------------------------- */

/* The list was a name and a role on one line, which made every team look identical and gave the
   badge, the game and the people no room at all. Full-width cards instead, badge leading. */
.tc-item {
  list-style: none;
}

.tc {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  width: 100%;
  padding: 0.7rem;
  border-radius: 14px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: #1b1b26;
  color: #eef3f8;
  font: inherit;
  text-align: start;
  cursor: pointer;
}
.tc:hover:not(:disabled) {
  background: #24242f;
  border-color: rgba(255, 255, 255, 0.16);
}
.tc:active:not(:disabled) {
  transform: scale(0.99);
}
.tc:focus-visible {
  outline: 2px solid #7fb0ff;
  outline-offset: 2px;
}
.tc:disabled {
  opacity: 0.6;
  cursor: default;
}

.tc-badge {
  flex: none;
  display: block;
  width: 3.75rem;
  height: 3.75rem;
  border-radius: 12px;
  border: 1px solid rgba(255, 255, 255, 0.09);
  background: radial-gradient(circle at 50% 40%, #2b2b3a 0%, #1f1f2b 70%);
  overflow: hidden;
}
.tc-badge img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 0.3rem;
  box-sizing: border-box;
}
.tc-badge-fallback {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: rgba(255, 255, 255, 0.32);
}

.tc-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.18rem;
}

.tc-title {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
  min-width: 0;
}

.tc-name {
  font-size: 0.95rem;
  font-weight: 650;
  line-height: 1.2;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* The tag is an abbreviation of the name beside it, so it is a quiet label rather than a second
   title competing with the first. */
.tc-tag {
  flex: none;
  padding: 0.02rem 0.3rem;
  border-radius: 5px;
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: #a8b9c9;
  background: rgba(255, 255, 255, 0.08);
}

.tc-game {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.76rem;
  color: #a8b9c9;
  min-width: 0;
}
.tc-game-icon {
  flex: none;
  width: 0.9rem;
  height: 0.9rem;
  border-radius: 3px;
  object-fit: cover;
}
.tc-game span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tc-people {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.12rem;
}

/* Overlapped, so four faces cost the width of about two. */
.tc-faces {
  display: flex;
}
.tc-face {
  display: block;
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 50%;
  overflow: hidden;
  border: 2px solid #1b1b26;
  background: #2b2b3a;
  margin-inline-start: -0.45rem;
}
.tc-face:first-child {
  margin-inline-start: 0;
}
.tc-face img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.tc-face-initials {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 0.55rem;
  font-weight: 700;
  color: #8ea0b0;
}
.tc:hover:not(:disabled) .tc-face {
  border-color: #24242f;
}

.tc-count {
  font-size: 0.72rem;
  color: #7f93a5;
}

.tc-owner {
  flex: none;
  align-self: flex-start;
  padding: 0.1rem 0.4rem;
  border-radius: 999px;
  font-size: 0.66rem;
  font-weight: 650;
  color: #ffd79a;
  background: rgba(245, 165, 36, 0.16);
}

@media (prefers-reduced-motion: reduce) {
  .tc:active:not(:disabled) {
    transform: none;
  }
}
.play-settings {
  padding: 0.5rem 0 1.5rem;
}

.play-settings-title {
  margin: 0 0 1.25rem;
  font-size: 1.5rem;
  font-weight: 700;
  color: #fff;
}

.play-settings-cards {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

.play-settings-card {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: 88px;
  padding: 1rem 1rem;
  background: rgba(255, 255, 255, 0.06);
  border: none;
  border-radius: 12px;
  color: inherit;
  font: inherit;
  text-align: start;
  text-decoration: none;
  cursor: pointer;
  gap: 0.75rem;
  box-sizing: border-box;
}
.play-settings-card:hover {
  background: rgba(255, 255, 255, 0.09);
}

.play-settings-card--profile {
  padding: 1rem;
}

.play-settings-avatar {
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  overflow: hidden;
  background: rgba(255, 255, 255, 0.1);
}
.play-settings-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.play-settings-avatar-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  font-size: 1.25rem;
  font-weight: 600;
  color: #94a3b8;
}

.play-settings-card-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}

.play-settings-card-title {
  font-size: 1rem;
  font-weight: 600;
  color: #fff;
}

.play-settings-card-sub {
  font-size: 0.875rem;
  color: rgba(255, 255, 255, 0.7);
}

.play-settings-chevron {
  flex-shrink: 0;
  font-size: 1.25rem;
  color: rgba(255, 255, 255, 0.5);
}

.play-settings-logout {
  display: block;
  width: 100%;
  padding: 1rem 1.5rem;
  font-size: 1rem;
  font-weight: 600;
  color: #1e293b;
  background: rgba(255, 255, 255, 0.85);
  border: none;
  border-radius: 12px;
  cursor: pointer;
}
.play-settings-logout:hover {
  background: rgba(255, 255, 255, 0.95);
}

/* Language picker */
.play-settings-lang-list { display: flex; gap: 8px; padding: 4px 2px 10px; }
.play-settings-lang-option { flex: 1; padding: 10px 12px; border-radius: 10px; border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.04); color: inherit; font-size: 0.95rem; cursor: pointer; }
.play-settings-lang-option--active { border-color: #2563eb; background: rgba(37, 99, 235, 0.18); font-weight: 600; }
/* Chevrons and arrows are supplied per language (› / ‹, ← / →), so nothing needs mirroring here. */
.play-linked {
  max-width: 32rem;
  margin: 0 auto;
  padding: 1rem 1.25rem 2rem;
}

.play-linked-back {
  display: inline-block;
  margin-bottom: 1rem;
  color: var(--play-text-muted, #8b93a7);
  text-decoration: none;
  font-size: 0.9rem;
}

.play-linked-back:hover {
  color: var(--play-text, #e8eaef);
}

.play-linked-title {
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0 0 0.5rem;
}

.play-linked-desc {
  color: var(--play-text-muted, #8b93a7);
  font-size: 0.9rem;
  line-height: 1.45;
  margin: 0 0 1.25rem;
}

.play-linked-muted {
  color: var(--play-text-muted, #8b93a7);
}

.play-linked-banner {
  padding: 0.65rem 0.85rem;
  border-radius: 8px;
  font-size: 0.9rem;
  margin: 0 0 1rem;
}

.play-linked-banner--ok {
  background: rgba(46, 160, 90, 0.15);
  color: #7dcea0;
}

.play-linked-banner--err {
  background: rgba(200, 80, 80, 0.15);
  color: #f5a9a9;
}

.play-linked-card {
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
  padding: 1rem 1.1rem;
  background: rgba(0, 0, 0, 0.2);
}

.play-linked-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
}

.play-linked-provider {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  min-width: 0;
}

.play-linked-provider-icon {
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  object-fit: contain;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.06);
}

.play-linked-card-head h2 {
  margin: 0;
  font-size: 1.1rem;
}

.play-linked-badge {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--play-text-muted, #8b93a7);
}

.play-linked-badge--on {
  color: #7dcea0;
}

.play-linked-meta {
  margin: 0.5rem 0 0;
  font-size: 0.85rem;
  color: var(--play-text-muted, #8b93a7);
}

.play-linked-meta code {
  font-size: 0.85em;
  color: var(--play-text, #e8eaef);
}

.play-linked-actions {
  margin-top: 1rem;
}

.play-linked-btn {
  border: none;
  border-radius: 8px;
  padding: 0.55rem 1rem;
  font-size: 0.9rem;
  cursor: pointer;
}

.play-linked-btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.play-linked-btn--primary {
  background: #3d6ee8;
  color: #fff;
}

.play-linked-btn--secondary {
  background: rgba(255, 255, 255, 0.08);
  color: var(--play-text, #e8eaef);
}
.play-privacy {
  max-width: 32rem;
  margin: 0 auto;
  padding: 1rem 1.25rem 2rem;
}

.play-privacy-back {
  display: inline-block;
  margin-bottom: 1rem;
  color: var(--play-text-muted, #8b93a7);
  text-decoration: none;
  font-size: 0.9rem;
}

.play-privacy-back:hover {
  color: var(--play-text, #e8eaef);
}

.play-privacy-title {
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0 0 0.5rem;
}

.play-privacy-desc {
  color: var(--play-text-muted, #8b93a7);
  margin: 0 0 1.5rem;
  line-height: 1.5;
}

.play-privacy-section {
  border: 1px solid var(--play-border, #262b38);
  border-radius: 12px;
  padding: 1.125rem;
  margin-bottom: 1rem;
}

/* The destructive half is marked by a warm border rather than a filled panel, so the page does not
   read as an alert before the person has chosen anything. */
.play-privacy-section--danger {
  border-color: #6b3a3a;
}

.play-privacy-heading {
  font-size: 1.05rem;
  font-weight: 650;
  margin: 0 0 0.35rem;
}

.play-privacy-sub {
  color: var(--play-text-muted, #8b93a7);
  margin: 0 0 0.875rem;
  line-height: 1.5;
  font-size: 0.925rem;
}

.play-privacy-notes {
  margin: 0 0 1rem;
  padding-left: 1.1rem;
  color: var(--play-text-muted, #8b93a7);
  font-size: 0.875rem;
  line-height: 1.6;
}

.play-privacy-notes li {
  margin-bottom: 0.4rem;
}

.play-privacy-blockers {
  background: rgba(245, 165, 36, 0.08);
  border: 1px solid rgba(245, 165, 36, 0.35);
  border-radius: 10px;
  padding: 0.875rem 1rem;
  font-size: 0.9rem;
  line-height: 1.55;
}

.play-privacy-blockers-lead {
  margin: 0 0 0.5rem;
  font-weight: 600;
}

.play-privacy-blockers ul {
  margin: 0;
  padding-left: 1.1rem;
  color: var(--play-text-muted, #8b93a7);
}

.play-privacy-btn {
  appearance: none;
  border: 1px solid var(--play-border, #262b38);
  background: var(--play-surface-2, #1a1f2b);
  color: var(--play-text, #e8eaef);
  border-radius: 8px;
  padding: 0.6rem 1rem;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.play-privacy-btn:hover:not(:disabled) {
  border-color: var(--play-text-muted, #8b93a7);
}

.play-privacy-btn:focus-visible {
  outline: 2px solid #4a8cf7;
  outline-offset: 2px;
}

.play-privacy-btn:disabled {
  opacity: 0.55;
  cursor: default;
}

.play-privacy-btn--danger {
  border-color: #8a4444;
  color: #ff9b9b;
}

.play-privacy-btn--danger:hover:not(:disabled) {
  border-color: #b25a5a;
}

.play-privacy-btn--quiet {
  color: var(--play-text-muted, #8b93a7);
}

.play-privacy-confirm {
  margin-top: 1rem;
}

.play-privacy-label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.play-privacy-input {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--play-border, #262b38);
  background: var(--play-surface, #12161f);
  color: var(--play-text, #e8eaef);
  border-radius: 8px;
  padding: 0.55rem 0.7rem;
  font: inherit;
  margin-bottom: 0.875rem;
}

.play-privacy-input:focus-visible {
  outline: 2px solid #4a8cf7;
  outline-offset: 1px;
}

.play-privacy-confirm-actions {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.play-privacy-error {
  color: #ff9b9b;
  font-size: 0.9rem;
  margin: 0.75rem 0 0;
  line-height: 1.5;
}
/* The portal layout supplies the page padding and the background. */
.super-changelog {
  max-width: 720px;
  color: #e2e8f0;
}

.super-changelog__title {
  margin: 0 0 0.35rem;
  font-size: 1.5rem;
  color: #f8fafc;
}

.super-changelog__sub {
  margin: 0 0 1.5rem;
  color: #94a3b8;
  font-size: 0.9rem;
  line-height: 1.45;
}

.super-changelog__sub code {
  color: #fde68a;
  font-size: 0.85em;
}

.super-changelog__form {
  border: 1px solid #1e293b;
  border-radius: 12px;
  padding: 1rem 1.1rem;
  background: #0b1020;
  margin-bottom: 2rem;
}

.super-changelog__h2 {
  margin: 0 0 0.75rem;
  font-size: 1.05rem;
  color: #f1f5f9;
}

.super-changelog__label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  margin-bottom: 0.75rem;
  font-size: 0.85rem;
  color: #94a3b8;
}

.super-changelog__input,
.super-changelog__textarea {
  padding: 0.45rem 0.55rem;
  border-radius: 6px;
  border: 1px solid #334155;
  background: #0f172a;
  color: #f1f5f9;
  font-size: 0.9rem;
}

.super-changelog__input--narrow {
  max-width: 200px;
}

.super-changelog__textarea {
  resize: vertical;
  min-height: 100px;
  font-family: inherit;
}

.super-changelog__btn {
  margin-top: 0.25rem;
  padding: 0.45rem 1rem;
  border-radius: 6px;
  border: 1px solid #2563eb;
  background: rgba(37, 99, 235, 0.35);
  color: #bfdbfe;
  font-weight: 600;
  cursor: pointer;
}

.super-changelog__btn:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.super-changelog__err {
  color: #f87171;
  font-size: 0.88rem;
  margin: 0 0 0.5rem;
}

.super-changelog__list-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 0.75rem;
}

.super-changelog__filter {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.85rem;
  color: #94a3b8;
}

.super-changelog__muted {
  color: #64748b;
  font-size: 0.9rem;
}

.super-changelog__ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
}

.super-changelog__li {
  border: 1px solid #1e293b;
  border-radius: 10px;
  padding: 0.75rem 0.9rem;
  background: #0b1020;
}

.super-changelog__li-top {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 0.35rem;
}

.super-changelog__badge {
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  padding: 0.12rem 0.4rem;
  border-radius: 4px;
  background: rgba(59, 130, 246, 0.2);
  color: #93c5fd;
  border: 1px solid #1d4ed8;
}

.super-changelog__date {
  font-size: 0.78rem;
  color: #64748b;
  flex: 1;
}

.super-changelog__del {
  margin-left: auto;
  font-size: 0.78rem;
  padding: 0.2rem 0.45rem;
  border-radius: 4px;
  border: 1px solid #7f1d1d;
  background: rgba(127, 29, 29, 0.35);
  color: #fecaca;
  cursor: pointer;
}

.super-changelog__subj {
  font-weight: 600;
  color: #f8fafc;
  margin-bottom: 0.35rem;
}

.super-changelog__notes {
  margin: 0;
  white-space: pre-wrap;
  font-family: inherit;
  font-size: 0.85rem;
  color: #94a3b8;
  line-height: 1.45;
}
/* The portal layout supplies the page padding and the background. */
.super-hosted {
  max-width: 720px;
  color: #e2e8f0;
}

.super-hosted__title {
  margin: 0 0 0.35rem;
  font-size: 1.5rem;
  color: #f8fafc;
}

.super-hosted__sub {
  margin: 0 0 0.75rem;
  color: #94a3b8;
  font-size: 0.9rem;
  line-height: 1.45;
}

.super-hosted__sub a {
  color: #93c5fd;
}

.super-hosted__sub code,
.super-hosted__api code {
  color: #fde68a;
  font-size: 0.85em;
}

.super-hosted__api {
  margin: 0 0 1.25rem;
  font-size: 0.8rem;
  color: #64748b;
  word-break: break-all;
}

.super-hosted__upload {
  margin-bottom: 1rem;
}

.super-hosted__upload-label {
  position: relative;
  display: inline-block;
  padding: 0.5rem 1rem;
  background: #1e3a5f;
  color: #e2e8f0;
  border-radius: 8px;
  cursor: pointer;
  font-size: 0.9rem;
}

.super-hosted__upload-label:hover {
  background: #2563a8;
}

.super-hosted__file {
  position: absolute;
  width: 0;
  height: 0;
  opacity: 0;
  pointer-events: none;
}

.super-hosted__err {
  color: #fca5a5;
  font-size: 0.9rem;
}

.super-hosted__ok {
  color: #86efac;
  font-size: 0.85rem;
}

.super-hosted__muted {
  color: #64748b;
  font-size: 0.9rem;
}

.super-hosted__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.super-hosted__row {
  display: flex;
  gap: 1rem;
  padding: 1rem;
  background: rgba(0, 0, 0, 0.25);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 12px;
}

.super-hosted__thumb-wrap {
  flex-shrink: 0;
  width: 88px;
  height: 88px;
  border-radius: 8px;
  overflow: hidden;
  background: #0b1020;
  display: flex;
  align-items: center;
  justify-content: center;
}

.super-hosted__thumb {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.super-hosted__meta {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.super-hosted__name {
  font-size: 0.8rem;
  color: #cbd5e1;
  word-break: break-all;
}

.super-hosted__meta2 {
  font-size: 0.75rem;
  color: #64748b;
}

.super-hosted__input {
  width: 100%;
  box-sizing: border-box;
  padding: 0.4rem 0.5rem;
  font-size: 0.75rem;
  border-radius: 6px;
  border: 1px solid #334155;
  background: #0f172a;
  color: #e2e8f0;
}

.super-hosted__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.super-hosted__btn {
  padding: 0.35rem 0.65rem;
  font-size: 0.8rem;
  border-radius: 6px;
  border: 1px solid #475569;
  background: #1e293b;
  color: #e2e8f0;
  cursor: pointer;
}

.super-hosted__btn:hover {
  background: #334155;
}

.super-hosted__btn--danger {
  border-color: #7f1d1d;
  color: #fecaca;
  background: #450a0a;
}

.super-hosted__btn--danger:hover {
  background: #7f1d1d;
}
/* Layout only. Colours and every control come from src/styles/tokens.css. */

/* Restated because App.css gives a bare form a 360px column for the sign-in pages. */
.admin-audit-log-filters {
  display: block;
  max-width: none;
}

.admin-audit-log-table td {
  vertical-align: top;
}

.admin-audit-log-when {
  white-space: nowrap;
}

/* Emails and ids have no spaces, and would otherwise push the summary off the side. */
.admin-audit-log-wrap {
  overflow-wrap: anywhere;
}

.admin-audit-log-summary {
  min-width: 16rem;
}

.admin-audit-log-details {
  display: flex;
  flex-direction: column;
  gap: var(--vs-s3);
  padding-block: var(--vs-s2);
}

.admin-audit-log-json {
  margin: 0;
  padding: var(--vs-s3);
  max-height: 24rem;
  overflow: auto;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  border: 1px solid var(--vs-rail-soft);
  border-radius: var(--vs-r-sm);
  background: var(--vs-void);
}

.admin-audit-log-none {
  margin: 0;
  font-size: 0.875rem;
}
.admin-search {
  max-width: 720px;
  margin: 0 auto;
  padding: 0 1rem 2rem;
  color: #e2e8f0;
}

.admin-search h1 {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
}

.admin-search-desc {
  color: #94a3b8;
  font-size: 0.9rem;
  margin: 0 0 1rem;
}

.admin-search-input {
  width: 100%;
  max-width: 480px;
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  border: 1px solid #475569;
  background: #0f172a;
  color: #f1f5f9;
  margin-bottom: 1rem;
}

.admin-search-muted {
  color: #64748b;
  font-size: 0.9rem;
}

.admin-search-error {
  color: #f87171;
}

.admin-search-section {
  margin-bottom: 1.5rem;
}

.admin-search-section h2 {
  font-size: 1rem;
  color: #94a3b8;
  margin: 0 0 0.5rem;
}

.admin-search-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.admin-search-list li {
  padding: 0.45rem 0;
  border-bottom: 1px solid #1e293b;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
}

.admin-search-link {
  color: #3b82f6;
  text-decoration: none;
}

.admin-search-link:hover {
  text-decoration: underline;
}

.admin-search-sub {
  color: #64748b;
  font-size: 0.85rem;
}

.admin-search-strong {
  font-weight: 600;
}

.admin-search-id {
  font-size: 0.7rem;
  color: #64748b;
  word-break: break-all;
}

.admin-search-pill {
  font-size: 0.7rem;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  background: #334155;
  text-transform: capitalize;
}

.admin-search-pill--approved {
  background: rgba(34, 197, 94, 0.2);
  color: #86efac;
}

.admin-search-pill--pending {
  background: rgba(234, 179, 8, 0.2);
  color: #fde047;
}

.admin-search-pill--rejected {
  background: rgba(239, 68, 68, 0.2);
  color: #fca5a5;
}
.admin-newsletter {
  max-width: 720px;
  margin: 0 auto;
  padding: 0 1rem 2rem;
  color: #e2e8f0;
}

.admin-newsletter h1 {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
}

.admin-newsletter h2 {
  font-size: 1rem;
  color: #94a3b8;
  margin: 2rem 0 0.75rem;
}

.admin-newsletter-desc {
  color: #94a3b8;
  font-size: 0.9rem;
  margin: 0 0 1.25rem;
  line-height: 1.5;
}

.admin-newsletter-form {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.admin-newsletter-label {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.85rem;
  color: #94a3b8;
}

.admin-newsletter-input,
.admin-newsletter-textarea {
  padding: 0.55rem 0.75rem;
  border-radius: 8px;
  border: 1px solid #475569;
  background: #0f172a;
  color: #f1f5f9;
  font-family: inherit;
}

.admin-newsletter-textarea {
  resize: vertical;
  min-height: 180px;
}

.admin-newsletter-submit {
  align-self: flex-start;
  padding: 0.55rem 1.25rem;
  border-radius: 8px;
  border: none;
  background: #2563eb;
  color: white;
  font-weight: 600;
  cursor: pointer;
}

.admin-newsletter-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.admin-newsletter-success {
  color: #86efac;
  margin-top: 1rem;
}

.admin-newsletter-error {
  color: #f87171;
  margin-top: 1rem;
}

.admin-newsletter-muted {
  color: #64748b;
}

.admin-newsletter-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.admin-newsletter-list li {
  padding: 1rem 0;
  border-bottom: 1px solid #334155;
}

.admin-newsletter-item-title {
  font-weight: 600;
  margin-bottom: 0.25rem;
}

.admin-newsletter-item-meta {
  font-size: 0.8rem;
  color: #64748b;
  margin-bottom: 0.5rem;
}

.admin-newsletter-item-body {
  white-space: pre-wrap;
  word-break: break-word;
  font-size: 0.85rem;
  color: #cbd5e1;
  margin: 0;
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
}
.admin-oauth-hub {
  max-width: 640px;
  margin: 0 auto;
  padding: 1rem 1.25rem 2rem;
}

.admin-oauth-hub--wide {
  max-width: 960px;
}

.admin-oauth-hub-summary {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-bottom: 1.25rem;
}

@media (max-width: 520px) {
  .admin-oauth-hub-summary {
    grid-template-columns: 1fr;
  }
}

.admin-oauth-hub-back {
  display: inline-block;
  margin-bottom: 1rem;
  color: #94a3b8;
  text-decoration: none;
  font-size: 0.9rem;
}

.admin-oauth-hub-back:hover {
  color: #e2e8f0;
}

.admin-oauth-hub-title {
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0 0 0.5rem;
  color: #fff;
}

.admin-oauth-hub-desc {
  color: #94a3b8;
  font-size: 0.9rem;
  line-height: 1.45;
  margin: 0 0 1.5rem;
}

.admin-oauth-hub-muted {
  color: #94a3b8;
}

.admin-oauth-hub-error {
  color: #f87171;
}

.admin-oauth-hub-cards {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.admin-oauth-hub-card {
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.1rem;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  text-decoration: none;
  color: inherit;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.admin-oauth-hub-card:hover {
  background: rgba(255, 255, 255, 0.09);
  border-color: rgba(255, 255, 255, 0.14);
}

.admin-oauth-hub-card-main {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  flex: 1;
  min-width: 0;
}

.admin-oauth-hub-card-icon {
  flex-shrink: 0;
  border-radius: 10px;
  background: rgba(0, 0, 0, 0.25);
  object-fit: contain;
}

.admin-oauth-hub-card-text {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}

.admin-oauth-hub-card-title {
  font-size: 1.05rem;
  font-weight: 600;
  color: #fff;
}

.admin-oauth-hub-card-count {
  font-size: 0.85rem;
  color: #94a3b8;
}

.admin-oauth-hub-card-status {
  flex-shrink: 0;
  font-size: 0.75rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.35rem 0.55rem;
  border-radius: 6px;
}

.admin-oauth-hub-card-status--live {
  color: #86efac;
  background: rgba(34, 197, 94, 0.15);
}

.admin-oauth-hub-card-status--off {
  color: #fcd34d;
  background: rgba(245, 158, 11, 0.12);
}

.admin-oauth-hub-card-chevron {
  flex-shrink: 0;
  font-size: 1.25rem;
  color: #64748b;
}

.admin-oauth-hub-foot {
  margin: 1.5rem 0 0;
  font-size: 0.9rem;
}

.admin-oauth-hub-foot a {
  color: #7dd3fc;
}

.admin-oauth-detail-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.admin-oauth-detail-stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.75rem;
  margin-bottom: 1.5rem;
}

.admin-oauth-detail-stats--wide {
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
}

@media (max-width: 520px) {
  .admin-oauth-detail-stats {
    grid-template-columns: 1fr;
  }
}

.admin-oauth-detail-stat {
  padding: 0.85rem 1rem;
  background: rgba(0, 0, 0, 0.22);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.admin-oauth-detail-stat-label {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #94a3b8;
  margin-bottom: 0.35rem;
}

.admin-oauth-detail-stat-value {
  font-size: 1.35rem;
  font-weight: 700;
  color: #f1f5f9;
}

.admin-oauth-detail-stat-value--sm {
  font-size: 0.85rem;
  font-weight: 600;
}

.admin-oauth-analytics-section {
  margin-bottom: 1.75rem;
}

.admin-oauth-analytics-heading {
  font-size: 1.1rem;
  font-weight: 600;
  color: #e2e8f0;
  margin: 0 0 0.5rem;
}

.admin-oauth-analytics-note {
  margin-top: 0.5rem;
  font-size: 0.8rem;
}

.admin-oauth-coverage-list {
  margin: 0;
  padding-left: 1.25rem;
  color: #cbd5e1;
  font-size: 0.9rem;
  line-height: 1.6;
}

.admin-oauth-chart {
  display: flex;
  align-items: flex-end;
  gap: 3px;
  height: 120px;
  padding: 0.5rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.admin-oauth-chart-bar-wrap {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  height: 100%;
  min-width: 0;
}

.admin-oauth-chart-bar {
  width: 100%;
  max-width: 14px;
  background: linear-gradient(180deg, #38bdf8, #2563eb);
  border-radius: 3px 3px 0 0;
  min-height: 4px;
}

.admin-oauth-chart-bar-count {
  font-size: 0.6rem;
  color: #94a3b8;
  margin-top: 2px;
}

.admin-oauth-chart-labels {
  display: flex;
  justify-content: space-between;
  font-size: 0.75rem;
  color: #64748b;
  margin-top: 0.35rem;
}

.admin-oauth-breakdown-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
  margin-bottom: 1.5rem;
}

.admin-oauth-breakdown {
  padding: 0.75rem;
  background: rgba(0, 0, 0, 0.2);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
}

.admin-oauth-breakdown-title {
  font-size: 0.85rem;
  font-weight: 600;
  color: #cbd5e1;
  margin: 0 0 0.5rem;
}

.admin-oauth-breakdown-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.admin-oauth-breakdown-table th,
.admin-oauth-breakdown-table td {
  text-align: left;
  padding: 0.35rem 0.25rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  color: #e2e8f0;
}

.admin-oauth-breakdown-table th {
  color: #94a3b8;
  font-weight: 500;
  font-size: 0.75rem;
}

.admin-oauth-detail-config {
  margin-bottom: 1.25rem;
  padding: 1rem;
  border-radius: 10px;
  border: 1px solid rgba(245, 158, 11, 0.25);
  background: rgba(245, 158, 11, 0.06);
}

.admin-oauth-detail-checklist {
  margin: 0 0 0.75rem;
  padding-left: 1.25rem;
  color: #cbd5e1;
  font-size: 0.9rem;
}

.admin-oauth-detail-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
}

.admin-oauth-detail-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.65rem 1.1rem;
  border-radius: 8px;
  font-size: 0.9rem;
  font-weight: 600;
  text-decoration: none;
}

.admin-oauth-detail-btn--primary {
  background: #2563eb;
  color: #fff;
}

.admin-oauth-detail-btn--primary:hover {
  background: #1d4ed8;
  color: #fff;
}
/**
 * Product pictures for the marketing page.
 *
 * These borrow the real portals' vocabulary on purpose: the same near-black panels, the same hairline
 * borders, the same green for live and blue for action. Someone who signs up should feel they have
 * seen this before.
 *
 * Local variables rather than the portal's tokens, because the marketing page is its own island with
 * its own hardcoded palette and pulling in the app's token layer here would couple the two.
 */

.lv,
.lv-phone,
.lv-mini {
  --lv-panel: #12161f;
  --lv-panel-hi: #171d28;
  --lv-line: rgba(255, 255, 255, 0.09);
  --lv-ink: #e8eef5;
  --lv-dim: #9aabbc;
  --lv-faint: #6b7d8f;
  --lv-blue: #2563eb;
  --lv-blue-soft: #6f9bf5;
  --lv-live: #35d67f;
}

.lv {
  background: var(--lv-panel);
  border: 1px solid var(--lv-line);
  border-radius: 14px;
  padding: 0.85rem;
  color: var(--lv-ink);
  font-size: 0.78rem;
  line-height: 1.35;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.45);
}

.lv-chrome {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  padding-bottom: 0.7rem;
  margin-bottom: 0.7rem;
  border-bottom: 1px solid var(--lv-line);
}

.lv-chrome-title {
  font-weight: 700;
  font-size: 0.95rem;
}

.lv-chrome-meta {
  color: var(--lv-faint);
  font-size: 0.72rem;
}

/* Initials stand-in, as used wherever a game or player has no picture. */
.lv-tile {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--lv-panel-hi);
  border: 1px solid var(--lv-line);
  color: var(--lv-dim);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.lv-tile--a { background: #1d2b3f; color: #8fb6ef; }
.lv-tile--b { background: #2b1f2e; color: #d79ad2; }
.lv-tile--c { background: #16302b; color: #78d3b2; }

.lv-live-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--lv-live);
  margin-inline-end: 5px;
}

/* ---------- dashboard ---------- */

.lv-dash-games {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.5rem;
  margin-bottom: 0.85rem;
}

.lv-dash-game {
  background: var(--lv-panel-hi);
  border: 1px solid var(--lv-line);
  border-radius: 10px;
  padding: 0.6rem;
}

.lv-dash-game-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.55rem;
}

.lv-dash-game-name {
  display: block;
  font-weight: 650;
  font-size: 0.76rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lv-dash-game-state {
  display: block;
  color: var(--lv-faint);
  font-size: 0.66rem;
}

.lv-dash-game-stat {
  display: flex;
  align-items: baseline;
  gap: 0.3rem;
}

.lv-dash-game-n {
  color: var(--lv-live);
  font-weight: 700;
  font-size: 1.05rem;
}

.lv-dash-game-k {
  color: var(--lv-faint);
  font-size: 0.68rem;
}

.lv-dash-section {
  display: block;
  font-weight: 650;
  margin-bottom: 0.45rem;
}

.lv-dash-running ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.lv-dash-running li {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.4rem 0;
  border-bottom: 1px solid var(--lv-line);
}

.lv-dash-running li:last-child {
  border-bottom: 0;
}

.lv-when {
  flex: none;
  width: 2.4rem;
  color: var(--lv-faint);
  font-size: 0.68rem;
}

.lv-when--live {
  color: var(--lv-live);
  font-weight: 650;
}

.lv-run-name {
  min-width: 0;
  font-size: 0.74rem;
  font-weight: 600;
}

.lv-run-name small {
  display: block;
  color: var(--lv-faint);
  font-weight: 400;
  font-size: 0.66rem;
}

/* ---------- phone ---------- */

.lv-phone {
  width: 260px;
  max-width: 100%;
  border-radius: 30px;
  padding: 8px;
  background: #05070b;
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.6);
}

.lv-phone-screen {
  background: #0b0f16;
  border-radius: 23px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  min-height: 460px;
  color: var(--lv-ink);
}

.lv-phone-top {
  display: flex;
  justify-content: center;
  padding: 0.65rem 0 0.5rem;
  border-bottom: 1px solid var(--lv-line);
}

.lv-phone-brand {
  font-weight: 800;
  font-size: 0.85rem;
  letter-spacing: 0.02em;
}

.lv-phone-body {
  flex: 1 1 auto;
  padding: 0.8rem 0.75rem;
}

.lv-phone-h {
  margin: 0 0 0.6rem;
  font-size: 1.05rem;
  font-weight: 700;
}

.lv-pills {
  display: flex;
  gap: 0.35rem;
  margin-bottom: 0.75rem;
}

.lv-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.25rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--lv-line);
  color: var(--lv-dim);
  font-size: 0.63rem;
  font-weight: 600;
}

.lv-pill i {
  font-style: normal;
  padding: 0 0.3rem;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.07);
  font-size: 0.6rem;
}

.lv-pill--on {
  border-color: var(--lv-blue);
  color: var(--lv-ink);
  background: rgba(37, 99, 235, 0.14);
}

.lv-friends {
  list-style: none;
  margin: 0;
  padding: 0;
}

.lv-friends li {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.45rem 0;
  border-bottom: 1px solid var(--lv-line);
}

.lv-friends li:last-child {
  border-bottom: 0;
}

.lv-avatar-wrap {
  position: relative;
  flex: none;
  line-height: 0;
}

.lv-avatar-wrap .lv-tile {
  width: 30px;
  height: 30px;
  border-radius: 50%;
}

.lv-dot {
  position: absolute;
  inset-inline-end: -1px;
  inset-block-end: -1px;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  border: 2px solid #0b0f16;
}

.lv-dot--ingame,
.lv-dot--online {
  background: var(--lv-live);
}

.lv-dot--offline {
  background: #0b0f16;
  box-shadow: inset 0 0 0 2px #2c3947;
}

.lv-friend-text {
  min-width: 0;
}

.lv-friend-text b {
  display: block;
  font-size: 0.75rem;
  font-weight: 650;
}

.lv-friend-text small {
  display: block;
  color: var(--lv-faint);
  font-size: 0.66rem;
}

.lv-friend-game {
  color: var(--lv-blue-soft) !important;
}

.lv-phone-nav {
  display: flex;
  justify-content: space-between;
  padding: 0.55rem 0.75rem 0.7rem;
  border-top: 1px solid var(--lv-line);
  color: var(--lv-faint);
  font-size: 0.6rem;
}

.lv-phone-nav-on {
  color: var(--lv-blue-soft);
  font-weight: 700;
}

/* ---------- player profile card ---------- */

.lv-card {
  width: 250px;
  max-width: 100%;
}

.lv-card-head {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 0.75rem;
}

.lv-card-avatar {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: #1d2b3f;
  border: 1px solid var(--lv-line);
  color: #8fb6ef;
  font-size: 0.72rem;
  font-weight: 700;
}

.lv-card-name {
  display: block;
  font-weight: 650;
  font-size: 0.82rem;
}

.lv-card-sub {
  display: block;
  color: var(--lv-faint);
  font-size: 0.68rem;
}

.lv-card-rank {
  margin-inline-start: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 1px solid var(--lv-blue);
  background: rgba(37, 99, 235, 0.18);
  color: #cfe0ff;
  font-size: 0.68rem;
  font-weight: 700;
}

.lv-card-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.4rem;
  margin-bottom: 0.7rem;
}

.lv-card-stats > span {
  padding: 0.45rem 0.3rem;
  border-radius: 8px;
  background: var(--lv-panel-hi);
  border: 1px solid var(--lv-line);
  text-align: center;
}

.lv-card-stats b {
  display: block;
  font-size: 0.85rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.lv-card-stats small {
  display: block;
  color: var(--lv-faint);
  font-size: 0.6rem;
}

.lv-card-games {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--lv-line);
}

.lv-card-games-k {
  margin-inline-start: auto;
  color: var(--lv-faint);
  font-size: 0.66rem;
}

/* ---------- format miniatures ---------- */

.lv-mini {
  min-height: 104px;
  padding: 0.7rem;
  border-radius: 10px;
  background: #0e131b;
  border: 1px solid var(--lv-line);
  color: var(--lv-ink);
  font-size: 0.72rem;
}

.lv-mini--center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
}

.lv-mini-row {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.28rem 0;
}

.lv-mini-row--slim {
  padding: 0.2rem 0;
}

.lv-mini-row--top .lv-mini-val {
  color: var(--lv-live);
}

.lv-mini-pos {
  flex: none;
  width: 1rem;
  color: var(--lv-faint);
  font-weight: 700;
  font-size: 0.68rem;
}

.lv-mini .lv-tile {
  width: 20px;
  height: 20px;
  border-radius: 5px;
  font-size: 0.55rem;
}

.lv-mini-name {
  flex: 1 1 auto;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.lv-mini-val {
  flex: none;
  font-variant-numeric: tabular-nums;
  font-weight: 650;
}

.lv-mini-bar {
  flex: 2 1 auto;
  height: 5px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
}

.lv-mini-bar i {
  display: block;
  height: 100%;
  background: var(--lv-blue-soft);
}

.lv-badges {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.lv-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 8px;
  border: 1px solid var(--lv-line);
  color: var(--lv-faint);
  font-size: 0.65rem;
  font-weight: 700;
}

.lv-badge--past {
  opacity: 0.45;
}

.lv-badge--now {
  border-color: var(--lv-blue);
  background: rgba(37, 99, 235, 0.18);
  color: #cfe0ff;
}

.lv-lp {
  width: 100%;
}

.lv-lp-bar {
  height: 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.08);
  overflow: hidden;
  margin-bottom: 0.35rem;
}

.lv-lp-bar i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--lv-blue), var(--lv-blue-soft));
}

.lv-lp-text {
  display: block;
  text-align: center;
  color: var(--lv-faint);
  font-size: 0.66rem;
}

.lv-place {
  display: flex;
  align-items: baseline;
  gap: 0.35rem;
}

.lv-place-n {
  font-size: 1.7rem;
  font-weight: 800;
  color: var(--lv-live);
  line-height: 1;
}

.lv-place-k {
  color: var(--lv-faint);
  font-size: 0.7rem;
}

.lv-br-stats {
  display: flex;
  gap: 1rem;
  color: var(--lv-faint);
  font-size: 0.68rem;
}

.lv-br-stats b {
  color: var(--lv-ink);
}

.lv-bracket {
  width: 100%;
  max-width: 170px;
  height: auto;
  color: var(--lv-blue-soft);
}

.lv-bracket-win {
  fill: rgba(53, 214, 127, 0.22);
  stroke: var(--lv-live);
  stroke-width: 1.2;
}

.lv-table-head,
.lv-table-row {
  display: grid;
  grid-template-columns: 1fr 1.4rem 1.4rem 1.4rem 2rem;
  gap: 0.2rem;
  align-items: center;
  padding: 0.24rem 0;
}

.lv-table-head {
  color: var(--lv-faint);
  font-size: 0.62rem;
  border-bottom: 1px solid var(--lv-line);
  margin-bottom: 0.15rem;
}

.lv-table-head span:not(:first-child),
.lv-table-row span:not(:first-child) {
  text-align: end;
  font-variant-numeric: tabular-nums;
}

.lv-table-row--top .lv-table-pts {
  color: var(--lv-live);
  font-weight: 700;
}

/* ---------- event setup ---------- */

.lv-setup {
  max-width: 340px;
}

.lv-field {
  margin-bottom: 0.6rem;
}

.lv-field--split {
  display: flex;
  gap: 0.5rem;
}

.lv-field--split > span {
  flex: 1 1 0;
}

.lv-label {
  display: block;
  color: var(--lv-faint);
  font-size: 0.66rem;
  margin-bottom: 0.2rem;
}

.lv-input {
  display: block;
  padding: 0.35rem 0.5rem;
  border-radius: 7px;
  background: #0a0e14;
  border: 1px solid var(--lv-line);
  font-size: 0.73rem;
}

.lv-choices {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
}

.lv-choice {
  padding: 0.25rem 0.5rem;
  border-radius: 999px;
  border: 1px solid var(--lv-line);
  color: var(--lv-dim);
  font-size: 0.66rem;
}

.lv-choice--on {
  border-color: var(--lv-blue);
  background: rgba(37, 99, 235, 0.18);
  color: #cfe0ff;
  font-weight: 600;
}

.lv-cta {
  display: block;
  margin-top: 0.75rem;
  padding: 0.45rem;
  border-radius: 8px;
  background: var(--lv-blue);
  color: #fff;
  text-align: center;
  font-size: 0.75rem;
  font-weight: 650;
}

@media (max-width: 520px) {
  .lv-dash-games {
    grid-template-columns: 1fr;
  }

  .lv-dash-games .lv-dash-game:nth-child(3) {
    display: none;
  }
}
/* Marketing home for www.vs.plus */

.landing {
  min-height: 100vh;
  background: #0a0a0f;
  color: #e2e8f0;
  font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
}

/* One place for the page's colours, so contrast is a decision rather than a scatter of literals. */
.landing {
  --landing-ground: #0a0a0f;
  --landing-ink: #eef3f8;
  --landing-body: #a9bacb;   /* body text; the old #94a3b8 read as a caption everywhere */
  --landing-faint: #7c8ea1;  /* genuine asides only */
  --landing-line: rgba(255, 255, 255, 0.08);
  --landing-blue: #2563eb;
  --landing-blue-soft: #6f9bf5;
  --landing-radius: 14px;
}

.landing-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: rgba(10, 10, 15, 0.9);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(8px);
}

.landing-header-inner {
  max-width: 1200px;
  margin: 0 auto;
  padding: 1rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.landing-logo {
  display: flex;
  align-items: center;
  text-decoration: none;
}

.landing-logo-img {
  height: 32px;
  width: auto;
  display: block;
}

.landing-nav {
  display: flex;
  align-items: center;
  gap: 1.5rem;
}

.landing-nav a,
.landing-nav .landing-nav-cta {
  color: var(--landing-body);
  text-decoration: none;
  font-size: 0.95rem;
  font-weight: 500;
  transition: color 0.15s;
}

.landing-nav a:hover {
  color: #e2e8f0;
}

.landing-nav-login {
  color: var(--landing-ink) !important;
}

.landing-nav-cta {
  padding: 0.5rem 1rem !important;
  background: #2563eb !important;
  color: #fff !important;
  border-radius: 8px;
}

.landing-nav-cta:hover {
  background: #1d4ed8 !important;
  color: #fff !important;
}

/* Hero */
.landing-hero {
  padding: 5rem 1.5rem 6rem;
  text-align: center;
}

.landing-hero-inner {
  max-width: 720px;
  margin: 0 auto;
}

.landing-hero-title {
  font-size: clamp(2rem, 5vw, 3.25rem);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.03em;
  color: #fff;
  margin: 0 0 1.25rem;
}

.landing-hero-sub {
  font-size: 1.2rem;
  line-height: 1.6;
  color: var(--landing-body);
  margin: 0 0 2rem;
}

.landing-hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
}

.landing-btn {
  display: inline-block;
  padding: 0.85rem 1.75rem;
  font-size: 1rem;
  font-weight: 600;
  border-radius: 10px;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
  border: none;
  cursor: pointer;
}

.landing-btn-primary {
  background: #2563eb;
  color: #fff;
}

.landing-btn-primary:hover {
  background: #1d4ed8;
  color: #fff;
}

.landing-btn-secondary {
  background: rgba(255, 255, 255, 0.08);
  color: #e2e8f0;
  border: 1px solid rgba(255, 255, 255, 0.15);
}

.landing-btn-secondary:hover {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
}

.landing-btn--large {
  padding: 1rem 2rem;
  font-size: 1.05rem;
}

/* Sections */
.landing-section {
  padding: 4rem 1.5rem;
}

.landing-section--dark {
  background: rgba(255, 255, 255, 0.02);
  border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.landing-section-inner {
  max-width: 1100px;
  margin: 0 auto;
}

.landing-section-title {
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  font-weight: 700;
  color: #fff;
  margin: 0 0 0.75rem;
  text-align: center;
}

.landing-section-lead {
  font-size: 1.1rem;
  color: var(--landing-body);
  text-align: center;
  max-width: 560px;
  margin: 0 auto 3rem;
  line-height: 1.6;
}

/* Feature cards */
.landing-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.5rem;
}

.landing-card {
  padding: 1.5rem;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
}

.landing-card h3 {
  font-size: 1.1rem;
  font-weight: 600;
  color: #e2e8f0;
  margin: 0 0 0.5rem;
}

.landing-card p {
  font-size: 0.95rem;
  color: var(--landing-body);
  margin: 0;
  line-height: 1.5;
}

/* ---------- hero ---------- */

/* Copy and product side by side once there is room, stacked on a phone. The art is the point of
   the hero now, so it gets the larger share of the row. */
.landing-hero-inner {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
  gap: 3rem;
  align-items: center;
  max-width: 1200px;
  margin: 0 auto;
  text-align: start;
}

.landing-hero-copy .landing-hero-title,
.landing-hero-copy .landing-hero-sub {
  text-align: start;
  margin-inline: 0;
}

.landing-hero-art {
  position: relative;
  min-width: 0;
}

.landing-hero-art-main {
  max-width: 560px;
}

/* The phone overlaps the dashboard's lower corner: two screens, one composition, rather than two
   pictures side by side. */
.landing-hero-art-float {
  position: absolute;
  inset-inline-end: -12px;
  inset-block-end: -56px;
  transform: scale(0.74);
  transform-origin: bottom right;
}

/* ---------- format cards ---------- */

.landing-formats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.25rem;
  text-align: start;
}

.landing-format {
  padding: 1rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--landing-line);
  border-radius: var(--landing-radius);
}

.landing-format-art {
  margin-bottom: 0.9rem;
}

.landing-format h3 {
  margin: 0 0 0.35rem;
  font-size: 1.02rem;
  font-weight: 650;
  color: var(--landing-ink);
}

.landing-format p {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--landing-body);
}

/* ---------- split sections ---------- */

.landing-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 3.5rem;
  align-items: center;
}

.landing-split--reverse .landing-split-copy {
  order: 2;
}

.landing-split-art {
  display: flex;
  justify-content: center;
  min-width: 0;
}

.landing-split-art--phone {
  justify-content: center;
}

.landing-section-title--left,
.landing-section-lead--left {
  text-align: start;
  margin-inline: 0;
}

.landing-section-lead--left {
  margin-bottom: 2rem;
  max-width: 46ch;
}

/* ---------- steps ---------- */

.landing-steps {
  list-style: none;
  margin: 0 0 1.75rem;
  padding: 0;
  display: grid;
  gap: 1.4rem;
  text-align: start;
}

.landing-step {
  display: flex;
  align-items: flex-start;
  gap: 0.9rem;
}

.landing-step-n {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border-radius: 999px;
  border: 1px solid rgba(37, 99, 235, 0.65);
  color: var(--landing-blue-soft);
  font-size: 0.9rem;
  font-weight: 700;
}

.landing-step h3 {
  margin: 0.15rem 0 0.2rem;
  font-size: 1rem;
  font-weight: 650;
  color: var(--landing-ink);
}

.landing-step p {
  margin: 0;
  font-size: 0.95rem;
  color: var(--landing-body);
  line-height: 1.55;
}

/* ---------- player benefits ---------- */

.landing-benefits {
  margin: 0 0 1.25rem;
  display: grid;
  gap: 1.25rem;
  text-align: start;
}

.landing-benefit {
  border-left: 2px solid rgba(37, 99, 235, 0.55);
  padding-left: 1.1rem;
}

.landing-benefit dt {
  font-size: 1rem;
  font-weight: 650;
  color: var(--landing-ink);
  margin-bottom: 0.3rem;
}

.landing-benefit dd {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--landing-body);
}

/* ---------- trust ---------- */

/* One raised panel split into three, rather than three separate cards: these are facets of a single
   promise and should read as one object. */
.landing-trust {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--landing-line);
  border-radius: var(--landing-radius);
  overflow: hidden;
  text-align: start;
}

.landing-trust-item {
  padding: 1.5rem;
  border-inline-start: 1px solid var(--landing-line);
}

.landing-trust-item:first-child {
  border-inline-start: 0;
}

.landing-trust-item h3 {
  margin: 0 0 0.45rem;
  font-size: 1rem;
  font-weight: 650;
  color: var(--landing-ink);
}

.landing-trust-item p {
  margin: 0;
  font-size: 0.93rem;
  line-height: 1.6;
  color: var(--landing-body);
}

/* ---------- shared bits ---------- */

.landing-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}

.landing-note {
  margin: 2.5rem auto 0;
  max-width: 620px;
  text-align: center;
  font-size: 0.9rem;
  color: var(--landing-faint);
}

.landing-note--left {
  margin-inline: 0;
  text-align: start;
}

.landing-inline-link {
  color: var(--landing-blue-soft);
  font-size: 0.93rem;
  font-weight: 600;
  text-decoration: none;
}

.landing-inline-link:hover {
  text-decoration: underline;
}

/* ---------- built with VS+ ---------- */

.landing-built {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1rem;
}

.landing-built-item {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  padding: 1rem;
  border-radius: var(--landing-radius);
  border: 1px solid var(--landing-line);
  background: rgba(255, 255, 255, 0.03);
  color: inherit;
  text-decoration: none;
}

a.landing-built-item:hover {
  border-color: rgba(37, 99, 235, 0.55);
  background: rgba(37, 99, 235, 0.08);
}

.landing-built-tile {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 11px;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--landing-line);
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--landing-body);
}

.landing-built-text b {
  display: block;
  font-size: 0.98rem;
  font-weight: 650;
  color: var(--landing-ink);
}

.landing-built-text small {
  display: block;
  font-size: 0.88rem;
  color: var(--landing-body);
}

/* ---------- closing call to action ---------- */

.landing-section--cta {
  padding: 4rem 1.5rem 5rem;
}

/* Raised and bordered, so the last thing on the page is an object to act on rather than one more
   heading floating on the same black as everything above it. */
.landing-cta-panel {
  padding: 3rem 2rem;
  border-radius: 20px;
  border: 1px solid rgba(37, 99, 235, 0.35);
  background:
    radial-gradient(120% 140% at 50% 0%, rgba(37, 99, 235, 0.18), transparent 60%),
    rgba(255, 255, 255, 0.03);
  text-align: center;
}

.landing-cta-title {
  margin: 0 0 0.6rem;
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  font-weight: 700;
  color: #fff;
}

.landing-cta-sub {
  margin: 0 auto 2rem;
  max-width: 44ch;
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--landing-body);
}

.landing-cta-panel .landing-actions {
  justify-content: center;
}

/* Footer */
.landing-footer {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  padding: 2rem 1.5rem;
  background: rgba(0, 0, 0, 0.2);
}

.landing-footer-inner {
  max-width: 1100px;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.landing-footer-brand {
  display: flex;
  align-items: center;
}

.landing-footer-logo-img {
  height: 24px;
  width: auto;
  display: block;
  opacity: 0.9;
}

.landing-footer-nav {
  display: flex;
  gap: 1.5rem;
}

.landing-footer-nav a {
  color: var(--landing-body);
  text-decoration: none;
  font-size: 0.9rem;
}

.landing-footer-nav a:hover {
  color: #e2e8f0;
}

.landing-footer-copy {
  font-size: 0.85rem;
  color: #64748b;
  margin: 0;
}

@media (max-width: 640px) {
  .landing-nav {
    gap: 0.75rem;
  }
  .landing-nav a:not(.landing-nav-login):not(.landing-nav-cta) {
    display: none;
  }
  .landing-hero {
    padding: 3rem 1rem 4rem;
  }
  .landing-footer-inner {
    flex-direction: column;
    text-align: center;
  }
}

@media (max-width: 1000px) {
  .landing-hero-inner,
  .landing-split {
    grid-template-columns: minmax(0, 1fr);
    gap: 2.5rem;
  }

  .landing-hero-copy .landing-hero-title,
  .landing-hero-copy .landing-hero-sub,
  .landing-section-title--left,
  .landing-section-lead--left {
    text-align: center;
    margin-inline: auto;
  }

  .landing-hero-copy .landing-actions,
  .landing-split-copy .landing-actions {
    justify-content: center;
  }

  /* Side by side instead of stacked: the overlap needs width it no longer has. */
  .landing-hero-art-float {
    position: static;
    transform: none;
    display: flex;
    justify-content: center;
    margin-top: 2rem;
  }

  .landing-hero-art-main {
    max-width: none;
    margin-inline: auto;
  }

  .landing-split--reverse .landing-split-copy {
    order: 0;
  }

  .landing-benefit {
    text-align: start;
  }

  .landing-note--left {
    text-align: center;
  }
}

@media (max-width: 640px) {
  .landing-trust-item {
    border-inline-start: 0;
    border-top: 1px solid var(--landing-line);
  }

  .landing-trust-item:first-child {
    border-top: 0;
  }

  .landing-cta-panel {
    padding: 2rem 1.25rem;
  }
}
/* Shared layout for Privacy Policy and Terms of Service */

.legal-doc {
  min-height: 100vh;
  background: #0a0a0f;
  color: #e2e8f0;
  font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
  line-height: 1.6;
}

.legal-doc-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: rgba(10, 10, 15, 0.92);
  border-bottom: 1px solid rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(8px);
}

.legal-doc-header-inner {
  max-width: 720px;
  margin: 0 auto;
  padding: 0.875rem 1.25rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}

.legal-doc-home {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  color: #e2e8f0;
  text-decoration: none;
  font-weight: 600;
  font-size: 0.95rem;
}

.legal-doc-home img {
  height: 28px;
  width: auto;
}

.legal-doc-nav {
  display: flex;
  gap: 1rem;
  font-size: 0.875rem;
}

.legal-doc-nav a {
  color: #94a3b8;
  text-decoration: none;
}

.legal-doc-nav a:hover {
  color: #e2e8f0;
}

.legal-doc-main {
  max-width: 720px;
  margin: 0 auto;
  padding: 2rem 1.25rem 4rem;
}

.legal-doc-main h1 {
  font-size: 1.75rem;
  font-weight: 700;
  margin: 0 0 0.5rem;
  color: #fff;
}

.legal-doc-updated {
  font-size: 0.875rem;
  color: #94a3b8;
  margin: 0 0 2rem;
}

.legal-doc-main h2 {
  font-size: 1.125rem;
  font-weight: 600;
  margin: 2rem 0 0.75rem;
  color: #f1f5f9;
}

.legal-doc-main h2:first-of-type {
  margin-top: 1.5rem;
}

.legal-doc-main p {
  margin: 0 0 1rem;
  color: #cbd5e1;
  font-size: 0.95rem;
}

.legal-doc-main ul {
  margin: 0 0 1rem;
  padding-left: 1.25rem;
  color: #cbd5e1;
  font-size: 0.95rem;
}

.legal-doc-main li {
  margin-bottom: 0.35rem;
}

.legal-doc-main a {
  color: #7dd3fc;
}

.legal-doc-note {
  font-size: 0.875rem;
  color: #94a3b8;
  border-left: 3px solid rgba(125, 211, 252, 0.4);
  padding-left: 1rem;
  margin: 1.5rem 0;
}

.legal-doc-contact {
  font-size: 0.95rem;
}

.legal-doc-contact strong {
  color: #e2e8f0;
}
#root {
  width: 100%;
  min-height: 100vh;
  display: block;
}


/* Zero specificity, same declarations. The login and register pages still get their
   360px column; a page that sets its own width or label direction now wins instead of
   silently losing to a bare element selector. */
:where(form) {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  max-width: 360px;
}

:where(form input) {
  padding: 0.5rem 0.75rem;
  border-radius: 6px;
  border: 1px solid #444;
  font-size: 1rem;
}

:where(form label) {
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
