/* perf — global performance & app-shell CSS (loaded last).
 * Base rules use :where() (zero specificity) so any component rule still wins.
 * Flags set on <html> by /js/perf.js (and an inline head script before first paint):
 *   data-quality="high|low"   adaptive effects budget -> [data-quality="low"] .x { drop heavy effects }
 *   data-motion="reduce"      OS reduced-motion is on
 *   data-hover="hover|none"   real hover-capable pointer vs touch
 *   data-hidden               tab hidden: CSS animations paused
 * Hover rules belong inside  @media (hover: hover) and (pointer: fine) { ... }  so taps never stick.
 */

/* ------------------------------------------------------------ app shell */
:where(html) {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  overscroll-behavior: none;            /* no pull-to-refresh / rubber-band on the table */
  touch-action: manipulation;           /* no double-tap zoom delay anywhere */
}
:where(body) {
  overscroll-behavior: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;          /* no long-press callout on cards and signs */
}
:where(button, a, input, select, textarea, label, summary, [role="button"]) {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}
/* Text fields stay selectable even though the app disables selection globally. */
:where(input, textarea, [contenteditable="true"]) {
  -webkit-user-select: text;
  user-select: text;
  -webkit-touch-callout: default;
}
:where(img, svg, canvas) { -webkit-user-drag: none; }

/* Safe-area tokens for the side insets (style.css already defines --safe-top / --safe-bottom). */
:where(:root) {
  --safe-left: env(safe-area-inset-left, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
}

/* Scroll containers: contain scroll chaining so flicking a list never drags the page. */
:where(.lobby-body, .sheet-body, .chat-list, .modal-card) {
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* ------------------------------------------------------------ containment */
/* Hidden screens/sheets/modals skip style, layout and paint (also if hidden without display:none). */
:where(.screen.hidden, .sheet.hidden, .modal-root.hidden) { content-visibility: hidden; }
/* Gesture canvas: fully contained, its repaints never invalidate the table. */
:where(#gestureCanvas) { contain: strict; }

/* ------------------------------------------------------------ hidden tab */
:root[data-hidden] *,
:root[data-hidden] *::before,
:root[data-hidden] *::after { animation-play-state: paused !important; }

/* ------------------------------------------------------------ low quality */
/* Generic, safe reductions; component owners add their own [data-quality="low"] rules. */
:root[data-quality="low"] .modal-backdrop { -webkit-backdrop-filter: none; backdrop-filter: none; }

/* ------------------------------------------------------------ reduced motion */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}

/* New-deploy pill (js/update.js), shown mid-game only */
.update-pill{position:fixed;left:50%;top:calc(env(safe-area-inset-top,0px) + 10px);transform:translateX(-50%);z-index:120;
  padding:8px 14px;border:0;border-radius:999px;background:#1f6f78;color:#fff;font:600 13px/1.2 Fredoka,system-ui,sans-serif;
  box-shadow:0 6px 18px rgba(0,0,0,.25);cursor:pointer;animation:updPill .35s ease-out both}
@keyframes updPill{from{opacity:0;transform:translate(-50%,-8px)}to{opacity:1;transform:translate(-50%,0)}}
@media (prefers-reduced-motion:reduce){.update-pill{animation:none}}
