/* css/vip.css — /vip, the VIP board.
 *
 * Prefix `vip-` (DESIGN.md §4 registry). Every colour comes from a token
 * defined in css/base.css — no literals, no page-local palette. ⚠ A var() for a
 * token that does not exist NEVER errors: with a fallback it silently ignores
 * light, without one the whole declaration is dropped (DESIGN.md §2, "phantom
 * tokens"). The tokens used here are: --bg-1/2/3, --glass-bg(-2),
 * --glass-border(-2), --border-1/2, --text-1/2/3, --accent(+ -border),
 * --amber(+ -glow/-border), --red(+ -glow/-border), --blue, --font-data,
 * --blur-md.
 *
 * The VIP tier badge reuses the player modal's amber pair on purpose: a reader
 * who has seen the gold "VIP 18" pill on a player card must meet the same pill
 * here. One meaning, one colour, site-wide.
 */

.vip-wrap { max-width: 1180px; margin: 0 auto; padding: 18px 14px 40px; display: flex; flex-direction: column; gap: 16px;
  /* ⚠ `min-width: 0` — .vip-wrap is a FLEX ITEM of .app-content, so it defaults to
     `min-width: auto` and grows to its widest content instead of the viewport. Measured
     2026-09-08: the charts' scrolling column strip made it 669px inside a 430px viewport,
     and because `body.page-vip` sets `overflow-x: clip` the page did not scroll — it CLIPPED,
     which is worse. Any child that wants to scroll sideways needs this to be here. */
  min-width: 0;
  /* ...and `width: 100%` is the half that actually fixes it. `.vip-wrap` has `margin: 0 auto`,
     which are AUTO CROSS-AXIS MARGINS in this column flex container — that disables `stretch`,
     so the box falls back to fit-content and takes its MIN-CONTENT width (669px) from the
     widest descendant. A definite width stops intrinsic sizing driving the page. */
  width: 100%;
}

/* The page's one heading, and its only h1 — which a crawler needs, since /vip is
   indexable and the header block that used to carry one is gone. */
.vip-title { font-size: clamp(24px, 5vw, 34px); line-height: 1.1; margin: 0; text-wrap: balance; }

/* ── controls ─────────────────────────────────────────────────── */
.vip-controls { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; justify-content: space-between; }
.vip-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.vip-tab { font: inherit; font-size: 12.5px; cursor: pointer; background: var(--bg-2); color: var(--text-2);
           border: 1px solid var(--border-2); border-radius: 999px; padding: 6px 13px; }
.vip-tab[aria-selected="true"] { background: var(--bg-3); color: var(--accent); border-color: var(--accent-border); font-weight: 700; }
.vip-pickers { display: flex; flex-wrap: wrap; gap: 8px; }
/* ⚠ REQUIRED, not tidy: `hidden` is a UA-stylesheet rule and loses to any class that sets
   display, so without this the Charts tab would leave the board's pickers on screen above a
   view they do not scope (CLAUDE.md, 2026-08-22 — 12 call sites shipped broken that way). */
.vip-pickers[hidden] { display: none; }
.vip-ctl { display: flex; flex-direction: column; gap: 3px; }
.vip-ctl-label { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); }
.vip-input { font: inherit; font-size: 13px; color: var(--text-1); background: var(--bg-2);
             border: 1px solid var(--border-2); border-radius: 9px; padding: 7px 10px; min-width: 190px; }
.vip-input:focus-visible, .vip-tab:focus-visible, .vip-card:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; }
.vip-count { font-family: var(--font-data); font-size: 11.5px; color: var(--text-3); }

/* ── the board: PLAYER-PROFILE CARDS ─────────────────────────────────────────
 * Owner reference, 2026-09-05: an esports player-profile card. Four things carry
 * that look and each is doing a job, not decoration:
 *   · the portrait is FULL-BLEED down the left edge — no padding, no radius on
 *     that side — so the face is the card's anchor rather than an avatar chip;
 *   · every figure is a SMALL UPPERCASE LABEL ABOVE A BIG VALUE, because the
 *     label is read once and the number is what the eye returns to;
 *   · a tier stripe runs under the portrait, so VIP 18 reads as gold across the
 *     whole grid without hunting for a pill;
 *   · corners are nearly square and the panel carries a faint diagonal — the
 *     angular, broadcast-graphic feel the reference gets from its chevrons.
 *
 * ⚠ This is a PAGE-LEVEL treatment that departs from the site's soft glass
 * cards, which DESIGN.md §2.4 allows as long as it says so at the same weight —
 * every colour is still a base.css token, so both themes follow with nothing
 * wired up.
 */
.vip-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(292px, 1fr)); gap: 10px; }
.vip-card { position: relative; display: grid; grid-template-columns: 96px 1fr; align-items: stretch;
            text-align: left; width: 100%; font: inherit; cursor: pointer; padding: 0; overflow: hidden;
            background: var(--glass-bg-2); backdrop-filter: blur(var(--blur-md));
            border: 1px solid var(--glass-border-2); border-radius: 4px; }
.vip-card:hover { border-color: var(--accent-border); }

/* The portrait column. min-height carries the card: the image stretches to
   whatever the panel needs, so a long name never leaves a gap beside it. */
.vip-card-media { position: relative; min-height: 118px; background: var(--bg-3); overflow: hidden; }
.vip-face { width: 100%; height: 100%; object-fit: cover; display: block; }
.vip-face-none { width: 100%; height: 100%; display: grid; place-items: center;
                 font-family: var(--font-data); font-size: 26px; color: var(--text-3); }
/* The tier stripe, under the portrait — the reference's red bar. */
.vip-card-media::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: var(--text-3); }
.vip-tier-18 .vip-card-media::after { background: var(--amber); }

.vip-card-body { position: relative; display: flex; flex-direction: column; gap: 1px; padding: 11px 12px 10px; min-width: 0; }
/* The faint diagonal the reference gets from its chevron watermark. Kept very
   low contrast: it is texture, not a second surface. */
.vip-card-body::before { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(115deg, transparent 52%, var(--glass-shine) 52%, transparent 76%); opacity: .5; }
.vip-card-eyebrow { font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; font-weight: 700; color: var(--text-3); }
.vip-tier-18 .vip-card-eyebrow { color: var(--amber); }
.vip-name { font-size: 17px; font-weight: 700; line-height: 1.15; color: var(--text-1);
            white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vip-sub { font-size: 11px; color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Label over value, three across. */
.vip-card-figs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 9px; }
.vip-fig { display: flex; flex-direction: column; gap: 0; min-width: 0; }
.vip-fig i { font-style: normal; font-size: 8.5px; letter-spacing: .09em; text-transform: uppercase; color: var(--text-3);
             white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.vip-fig b { font-family: var(--font-data); font-size: 15px; font-weight: 500; color: var(--text-1);
             white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* The sort position, small and cornered — context for the current sort, not an
   identity. A player is not "number 47". */
.vip-card-rank { position: absolute; top: 8px; right: 10px; font-family: var(--font-data);
                 font-size: 9.5px; color: var(--text-3); }

.vip-center { text-align: center; color: var(--text-3); padding: 26px 12px; }
.vip-foot { font-size: 11.5px; color: var(--text-3); border-top: 1px solid var(--border-1); padding-top: 12px; display: flex; flex-direction: column; gap: 6px; }

/* ── The VIP card modal (/vip's own, replacing the shared player modal) ──────
 * ⚠ z-index 500 is the site's MODAL LAYER; the bottom nav is 400. Anything lower
 * and the nav renders over the sheet and eats its last row.
 * ⚠ Visibility is the `.is-open` CLASS, never the `hidden` attribute — `hidden`
 * is a UA rule and loses to a class that sets display (CLAUDE.md, 2026-08-22).
 */
.vip-modal { position: fixed; inset: 0; z-index: 500; display: none; }
.vip-modal.is-open { display: grid; place-items: center; padding: 16px; }
/* ⚠ THE BLUR BELONGS ON THE BACKDROP, NOT ON THE SHEET. /killers proved this
   shape: dim + blur the page behind hard, then put a nearly-opaque sheet on top.
   The first version blurred only 2px and leaned on a 62%-opaque sheet, and on a
   phone the board read straight through the text — legible in the diff, illegible
   on the screen. */
.vip-modal-back { position: absolute; inset: 0; background: rgba(0, 0, 0, .66); backdrop-filter: blur(12px); }
/* CLAY + GLASS, not a flat panel (owner, 2026-09-05). The tokens carry the
   material: frosted glass over near-black in dark, the cool clay surface in
   light. ⚠ backdrop-filter needs the surface to stay TRANSLUCENT; a solid
   background here makes the blur invisible and the sheet reads as a slab. */
.vip-modal-sheet { position: relative; width: min(520px, 100%); max-height: 86vh; overflow: auto;
                   /* --glass-bg-2, not --glass-bg: 0.72 in dark and 0.93 in light against
                      0.65/0.62. Still translucent, still glass — but text wins over what is
                      behind it, which a card full of numbers has to. */
                   background: var(--glass-bg-2); backdrop-filter: blur(var(--blur-lg));
                   border: 1px solid var(--glass-border); border-radius: 18px;
                   box-shadow: 0 24px 70px -30px rgba(0, 0, 0, .8);
                   padding: 18px 18px 16px; display: flex; flex-direction: column; gap: 14px; }
:root[data-theme="light"] .vip-modal-sheet { border-radius: 24px; box-shadow: 0 30px 80px -34px rgba(31, 41, 61, .45); }
:root[data-theme="light"] .vip-modal-back { background: rgba(31, 41, 61, .38); }
.vip-modal-x { position: absolute; top: 8px; right: 10px; font: inherit; font-size: 20px; line-height: 1;
               background: none; border: 0; color: var(--text-3); cursor: pointer; padding: 4px 8px; }
.vip-modal-x:hover { color: var(--text-1); }
.vip-modal-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.vip-modal-head { display: flex; align-items: center; gap: 12px; padding-right: 28px; }
.vip-modal-face { width: 54px; height: 54px; border-radius: 12px; flex: 0 0 auto; object-fit: cover;
                  background: var(--bg-3); border: 1px solid var(--border-2); display: grid; place-items: center;
                  font-family: var(--font-data); font-size: 20px; color: var(--text-3); }
.vip-modal-id { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.vip-modal-name { font-size: 19px; font-weight: 700; color: var(--text-1); overflow-wrap: anywhere; }
.vip-modal-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px 16px; margin: 0; }
.vip-modal-grid dt { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); }
/* Monospace is for FIGURES — it lines digits up. On prose it reads as code and
   wraps badly ("still on their first warzone" set in mono, three words a line). */
.vip-modal-grid dd { margin: 2px 0 0; font-size: 14px; line-height: 1.35; color: var(--text-1); }
.vip-modal-grid dd.is-num { font-family: var(--font-data); }
.vip-modal-link { font-size: 13px; color: var(--accent); text-decoration: none; }
.vip-modal-link:hover { text-decoration: underline; }
.vip-modal .vip-pill { display: inline-flex; align-items: center; gap: 4px; border-radius: 999px; padding: 2px 8px;
                       font-size: 11px; font-weight: 700; white-space: nowrap; border: 1px solid transparent;
                       font-family: var(--font-data); }
.vip-modal .vip-pills { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
/* The pill variants live HERE now: the cards carry their tier as an eyebrow and a
   stripe, so the modal is the only place a pill is still rendered. Gold for 18 is
   the same amber pair the player modal's VIP badge uses — one meaning, one colour,
   site-wide. */
.vip-modal .vip-pill-18 { background: var(--amber-glow); color: var(--amber); border-color: var(--amber-border); }
.vip-modal .vip-pill-17 { background: var(--bg-3); color: var(--text-2); border-color: var(--border-2); }
.vip-modal .vip-pill-live { background: var(--bg-3); color: var(--text-2); border-color: var(--border-2); }
body.vip-modal-open { overflow: hidden; }

@media (max-width: 560px) {
  /* One card a row on a phone. The portrait-left split IS the card here — it
     cannot read as a table row, which is what the grid was protecting against. */
  .vip-grid { grid-template-columns: 1fr; gap: 8px; }
  .vip-card { grid-template-columns: 84px 1fr; }
  .vip-card-media { min-height: 104px; }
  .vip-name { font-size: 16px; }
  .vip-input { min-width: 0; width: 100%; }
  .vip-ctl { flex: 1 1 140px; }
  .vip-modal.is-open { align-items: end; padding: 0; }
  /* A bottom sheet has to clear the home indicator, or its last row sits under it. */
  .vip-modal-sheet { width: 100%; max-height: 88vh; border-radius: 18px 18px 0 0;
                     padding-bottom: calc(16px + env(safe-area-inset-bottom)); }
  .vip-modal-grid { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px 14px; }
}
