/* UI base - the shared layer under both surfaces (docs/ui.md section 10).
   Loaded FIRST by the site and the Mini App, so each surface's own stylesheet
   can still override it. Everything here is low-specificity (:where) on
   purpose: a component's own rule always wins, and a rule that needs the
   default switched off says so with the .fill / .hit-none opt-outs.

   Four things live here, because they were being re-decided per component:
   1. spacing + size tokens         (no more 0.35rem / 0.4rem / 0.45rem drift)
   2. control width cap             (a field never stretches across a monitor)
   3. empty / notice blocks         (centred by the system, not by margin hacks)
   4. touch hit areas               (44px target without changing the layout) */

#stats-table-coverage:empty { display: none; }
.stats-table tbody td.stats-metric-pending {
  color: var(--text-dim);
  filter: grayscale(1);
  --accent: var(--text-dim);
}
.stats-completeness-info { display: inline-block; position: relative; vertical-align: middle; }
.stats-info-button {
  width: var(--tap-min); height: var(--tap-min); padding: 0;
  color: var(--text-dim); background: transparent; border: 0;
  font: inherit; font-weight: 600; cursor: pointer;
}
.stats-info-glyph { display: inline-flex; align-items: center; justify-content: center;
  width: 1.25em; height: 1.25em; border: 1px solid currentColor; border-radius: 50%; }
.stats-info-tooltip {
  visibility: hidden; position: absolute; z-index: 100;
  bottom: calc(100% + var(--space-2)); left: 0;
  width: min(18rem, calc(100vw - 2rem)); padding: var(--space-3);
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface-alt, var(--bg)); color: var(--text); line-height: 1.5;
  box-shadow: 0 var(--space-2) var(--space-5) color-mix(in srgb, var(--accent) 12%, transparent);
  pointer-events: none;
}
.stats-info-button:hover + .stats-info-tooltip,
.stats-info-button:focus-visible + .stats-info-tooltip,
.stats-info-button[aria-expanded="true"] + .stats-info-tooltip { visibility: visible; }
.stats-info-button[data-tooltip-dismissed="true"] + .stats-info-tooltip { visibility: hidden; }

:root {
  /* Spacing scale - gaps, paddings and margins pick from these. */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2.5rem;

  /* One cap for every single-line field, select and action button. */
  --control-max: 28rem;
  /* Reading width for prose / empty states. */
  --prose-max: 40rem;
  /* Minimum touch target on a coarse pointer (Apple HIG 44, Material 48). */
  --tap-min: 44px;
  --control-h: 40px;

  /* Type scale - integer pixels on a 16px root, ~1.07-1.17 steps. Body copy
     and data live on --fs-sm..--fs-body; --fs-2xs is the legibility floor
     (11px: nothing readable is set smaller). Sizes outside the scale are bugs,
     not styles. Display sizes (headings, hero numerals) use clamp() separately. */
  --fs-2xs: 0.6875rem;  /* 11  badges, captions */
  --fs-xs: 0.75rem;     /* 12  secondary labels */
  --fs-sm: 0.8125rem;   /* 13  dense table / row text */
  --fs-md: 0.875rem;    /* 14  controls, default row text */
  --fs-body: 0.9375rem; /* 15  prose, card text */
  --fs-base: 1rem;      /* 16  inputs on iOS (never smaller: avoids zoom-on-focus) */
  --fs-lg: 1.125rem;    /* 18  section subtitles */
  --lh-tight: 1.2;
  --lh-body: 1.5;
  --lh-prose: 1.65;

  /* Safe areas, named once so Telegram's contentSafeAreaInset can extend them. */
  --safe-top: env(safe-area-inset-top, 0px);
  --safe-right: env(safe-area-inset-right, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
  --safe-left: env(safe-area-inset-left, 0px);
}

/* 2. Control width: width:100% stays the way a control fills a narrow phone;
   the cap only bites once the container is wider than a field needs. */
:where(input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=file]):not([type=hidden]),
       select,
       .secondary-btn,
       .primary-btn) {
  max-width: var(--control-max);
}
:where(.fill) { max-width: none; }

/* 3. Empty / notice block: always the full row, centred as a block AND as text.
   Fixes the old pattern where a text-align:center paragraph sat in a grid cell
   or flex row and looked "a bit left of centre". */
:where(.empty-state, .picker-empty, .online-card-empty) {
  grid-column: 1 / -1;
  width: 100%;
  max-width: var(--prose-max);
  margin-inline: auto;
  text-align: center;
}
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-5) var(--space-4);
  color: var(--text-dim, #888);
}

/* 4. Touch hit areas. The VISIBLE control keeps its compact size; an invisible
   ::after grows the tappable box to --tap-min. Only on a coarse pointer, so
   desktop density is untouched. Add a control to the list instead of
   enlarging it. Controls that are already positioned (absolute/fixed/sticky)
   are listed second: they must not be switched to position: relative. */
@media (pointer: coarse) {
  :where(.club-logo-toggle, .picker-pos, .picker-pos-clear, .col-sort-btn, .link-btn,
         .predict-rank-x, .tab-btn, .hit) {
    position: relative;
  }
  :where(.club-logo-toggle, .picker-pos, .picker-pos-clear, .col-sort-btn, .link-btn,
         .predict-rank-x, .picker-hint-btn, .logout-icon-btn, .tab-btn, .hit)::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    width: max(100%, var(--tap-min));
    height: max(100%, var(--tap-min));
    transform: translate(-50%, -50%);
  }
  /* Buttons that are pills / actions: a 40px body (the 44px hit area is the ::after above). */
  :where(.secondary-btn, .primary-btn, .tab-btn, .toplevel-btn, .nav-btn, .format-btn) {
    min-height: var(--control-h);
  }
  /* iOS Safari zooms the whole page when a field under 16px takes focus, and never
     zooms back. A coarse pointer therefore never gets a smaller field font -
     !important is deliberate: this must beat every #id rule that sized a field. */
  input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=hidden]),
  select, textarea {
    font-size: var(--fs-base) !important;
  }
  /* Replaced elements cannot take ::after: give fields a real minimum height. */
  :where(input:not([type=checkbox]):not([type=radio]):not([type=range]):not([type=hidden]), select) {
    min-height: var(--control-h);
  }
}

/* 5. Grids whose tracks are capped (minmax(a, b) with b < 1fr) leave the rest of the
   row empty; centre the track set so the group - and an .empty-state spanning it -
   sits on the page's centre line instead of hugging the left edge. */
:where(.online-grid, .manager-rooms-list, .mgr-bracket, .mgr-tool-grid) {
  justify-content: center;
}

/* Access colors are shared by Statistics and profile tables. */
.stats-table th[data-stats-access="pro"], .pd-table th[data-stats-access="pro"] { background: #164a51; color: #b9f5ed; }
.stats-table th[data-stats-access="sigma"], .pd-table th[data-stats-access="sigma"] { background: #49305f; color: #edd6ff; }
