/* Player-detail window ("провалиться в игрока") - the ONE stylesheet for
   this panel, shared by the website and the Telegram Mini App (served from
   /shared/, loaded by both pages alongside shared_static/player_detail.js,
   which owns its markup and behaviour). See that file's docstring for why
   this component - unlike the player card underneath it - is shared rather
   than duplicated per surface.

   Every colour goes through a var(...) with a literal fallback: the site
   defines a full light/dark palette, the Mini App only defines
   --bg/--text/--accent/--accent-text (frontend/styles.css's :root, which
   follows the user's real Telegram theme), so the fallbacks cover the
   tokens the Mini App has no other use for.
   Opened by tapping a player anywhere - a filled squad slot, or a picker
   row while no slot is active (see each frontend's own tap wiring).
   Deliberately a centered overlay panel rather than a third workspace
   column: it has to work identically on a 390px phone, on desktop, and
   inside Telegram, and it's a "look, then go back" surface, not somewhere
   you stay.

   Scroll containment: the panel itself is capped at 85vh and only .pd-body
   scrolls, so a long career (18 seasons) never pushes the identity block or
   the mode switcher off-screen - those stay pinned while the table moves. */
#player-detail {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
#player-detail.hidden { display: none; }

.pd-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
}

.pd-panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 560px;
  /* Height is intrinsic (sum of head + modes + season-row + .pd-body), NOT
     a viewport fraction - a flat 88vh read as excessively tall on desktop,
     where every tab had far more empty space than content. player_detail.js's
     lockHeightToCalendar() pins an explicit px height (via inline style,
     overriding this) equal to what the Календарь tab needs - always
     exactly 5 weeks, so a stable, modest reference size - the same height
     then applies to every tab (Матчи/По сезонам scroll inside .pd-body
     instead of growing the window). max-height below is only a safety cap
     for before that JS runs / if it can't. */
  max-height: 85vh;
  background: var(--surface, var(--bg, #fff));
  border: 1px solid var(--border, #e3e6ec);
  border-radius: 14px;
  overflow: hidden;
}

.pd-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 50%;
  background: var(--surface-alt, #eef1f6);
  color: var(--text-dim, #888);
  font-size: 0.9rem;
  line-height: 28px;
  padding: 0;
  cursor: pointer;
  z-index: 1;
}

.pd-head {
  display: flex;
  align-items: center;
  gap: 0.8rem;
  padding: 0.9rem 2.4rem 0.9rem 0.9rem; /* right reserve keeps .pd-close off the price */
  border-bottom: 1px solid var(--border, #e3e6ec);
}

/* Initials on the club's own stripe colour - the placeholder standing in
   for a real headshot. No photo has been downloaded or id-mapped yet
   (data/raw/images/KHL is empty, player_external_ids carries no khl_ru id),
   so PlayerDetailOut.photo_url is always None today; when it isn't, an
   <img> replaces this element's text and the same box holds it. */
.pd-photo {
  flex: 0 0 auto;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: "Oswald", sans-serif;
  font-weight: 600;
  font-size: 1.3rem;
  color: #fff;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);
  overflow: hidden;
}
.pd-photo img { width: 100%; height: 100%; object-fit: cover; }

.pd-ident { flex: 1; min-width: 0; }
.pd-name {
  margin: 0;
  font-family: "Oswald", sans-serif;
  font-weight: 600;
  font-size: 1.15rem;
  line-height: 1.25;
}
.pd-sub { font-size: 0.8rem; color: var(--text-dim, #888); margin-top: 2px; }
.pd-params { font-size: 0.78rem; color: var(--text-dim, #888); margin-top: 4px; }
/* First Pro-only perk (docs/subscription_pro.md) - understated by design
   (2026-08-20, replaced a spelled-out disclaimer): a small pixelated
   "censor bar" standing in for the withheld age/height/weight/shoots,
   plus a tiny gold "Pro" label. Not a button - no purchase flow exists
   yet (growth.md's Pro perks are still "one perk at a time", see
   entitlements.py's docstring). */
.pd-pro-lock { display: inline-flex; align-items: center; gap: 4px; vertical-align: middle; }
/* Irregular pixel-noise mosaic (user's ask, 2026-08-24: "не шахматкой, а
   более рандомно") with an actual blur filter on top ("с эффектом
   реального блюра") - three repeating-linear-gradient layers at
   different angles/pitches (not aligned into one uniform checkerboard
   grid) approximate randomized noise purely in CSS, no image asset
   needed; blur(1px) then softens those hard gradient edges into the
   "blurred TV broadcast" look without literally blurring the real text
   underneath (there IS no real text under this element - see
   .pd-pro-lock's own comment - so there's nothing for the blur to leak).
   Theme-adaptive via var(--text-dim)/color-mix, same as before. */
.pd-pro-pixels {
  display: inline-block;
  width: 76px;
  height: 0.78rem;
  border-radius: 2px;
  overflow: hidden;
  background-color: color-mix(in srgb, var(--text-dim, #888) 35%, transparent);
  background-image:
    repeating-linear-gradient(115deg, color-mix(in srgb, var(--text-dim, #888) 60%, transparent) 0 3px, transparent 3px 5px),
    repeating-linear-gradient(25deg, color-mix(in srgb, var(--text-dim, #888) 45%, transparent) 0 2px, transparent 2px 6px),
    repeating-linear-gradient(70deg, color-mix(in srgb, var(--text-dim, #888) 50%, transparent) 0 4px, transparent 4px 7px);
  filter: blur(1px);
}
.pd-pro-label { font-size: 0.68rem; font-weight: 700; letter-spacing: 0.03em; color: #d4a017; }
.pd-flag {
  width: 1.05em;
  height: auto;
  vertical-align: -2px;
  border-radius: 2px;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
}
.pd-price {
  flex: 0 0 auto;
  align-self: flex-start;
  font-family: "JetBrains Mono", monospace;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 1.3rem;
  color: var(--success, #1a9e5c);
}

.pd-modes {
  display: flex;
  gap: 0.4rem;
  padding: 0.6rem 0.9rem;
  border-bottom: 1px solid var(--border, #e3e6ec);
}
.pd-mode-btn {
  flex: 1;
  padding: 0.4rem 0.5rem;
  border: 1px solid var(--border, #e3e6ec);
  border-radius: 8px;
  background: var(--surface-alt, #eef1f6);
  color: var(--text-dim, #888);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  font-weight: 700;
  font-size: 0.78rem;
  cursor: pointer;
}
.pd-mode-btn.active { background: var(--accent, #1c7ed6); border-color: var(--accent, #1c7ed6); color: var(--accent-text, #fff); }

/* Only shown for the "Матчи" mode - Календарь/По сезонам aren't scoped by
   a single season (Календарь is always the current one; По сезонам lists
   all of them at once). */
.pd-season-row { padding: 0.5rem 0.9rem 0; }
.pd-season-row.hidden { display: none; }
.pd-season-select {
  width: 100%;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--border, #e3e6ec);
  border-radius: 8px;
  background: var(--surface, var(--bg, #fff));
  color: var(--text, #14171c);
  font-size: 0.82rem;
}

/* min-height: 0 overrides flexbox's default min-height:auto, which would
   otherwise let a long Матчи/По сезонам table push the flex item (and so
   the whole panel) taller than the locked height instead of scrolling
   inside it. */
.pd-body { flex: 1; min-height: 0; overflow-y: auto; padding: 0.4rem 0.9rem 0.9rem; }
.pd-empty { color: var(--text-dim, #888); text-align: center; padding: 1.5rem 0; font-size: 0.85rem; }

.pd-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
}
.pd-table th {
  position: sticky;
  top: 0;
  background: var(--surface, var(--bg, #fff));
  color: var(--text-dim, #888);
  font-size: 0.7rem;
  font-weight: 700;
  text-align: right;
  padding: 0.45rem 0.25rem;
  border-bottom: 2px solid var(--border, #e3e6ec);
  white-space: nowrap;
}
.pd-table td {
  text-align: right;
  padding: 0.4rem 0.25rem;
  border-bottom: 1px solid var(--border, #e3e6ec);
  white-space: nowrap;
}
/* First column (date / season) is the row's label, not a number - the only
   left-aligned one, and the one that keeps its width when the table has to
   scroll sideways on a narrow phone. */
.pd-table th:first-child, .pd-table td:first-child { text-align: left; }
/* Счёт (2nd column, "матчи" mode only) is short text with a trailing
   " ОТ"/" Б" marker, not a number to line up with the numeric columns
   after it - right-aligned it read badly, the OT/SO marker floating away
   from the score it modifies. */
.pd-table th:nth-child(2), .pd-table td.pd-col-score { text-align: left; }
/* Win/loss color, NOT a reordering of the digits - score always stays
   "his team : opponent" even on an away win (e.g. "1:3"), see
   player_detail.py's _score_label and scoreCell's comment. Picked to stay
   readable against both a light page and Telegram dark theme's near-black
   background, not just a plain "dark green/red" that would wash out there. */
.pd-score-win { color: #2f9e58; font-weight: 700; }
.pd-score-loss { color: #d1483f; font-weight: 700; }
/* Sits right after the season label in the same first cell (CLAUDE.md's
   UI layout priority 2: reclaim width from elsewhere before truncating) -
   deliberately not its own column, to leave room for future metric
   columns without the table growing wider still. */
.pd-table .pd-club { color: var(--text-dim, #888); font-weight: 400; }
.pd-table .pd-col-fp { font-weight: 700; color: var(--text, #14171c); }
.pd-table .pd-col-fp.neg { color: #c33; }
.pd-table tbody tr:last-child td { border-bottom: none; }
/* The one place a horizontal scrollbar is allowed (CLAUDE.md's UI layout
   priorities forbid the PAGE scrolling sideways, not a table): a goalie's
   or skater's full stat line has more columns than a 320px phone can hold,
   and dropping columns would make the panel worth less than the card it
   was opened from. */
.pd-scroll { overflow-x: auto; }

/* Календарь - a real wall-calendar grid, 7 columns, never wider than the
   panel (CLAUDE.md: the page must never scroll sideways - this is a grid
   of fractions, not a table, so it has no reason to). Deliberately no
   month-name divider row - see calendarTable's docstring for why one broke
   the grid's weekday alignment. */
.pd-cal-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 3px;
}
.pd-cal-weekdays { margin-bottom: 3px; }
/* Roughly half the ORIGINAL height (padding 2px top/bottom -> 0, smaller
   font, tight line-height - the first attempt only trimmed 2px of padding
   and left the font/line-height alone, so it barely moved - real bug,
   2026-08-20). Background is a small mix of black INTO the day cells'
   own theme-aware background (.pd-cal-cell below), not a fixed hex - the
   first attempt's #23262d read as flat near-black regardless of theme,
   especially jarring on the light theme's near-white cells; this stays
   "slightly darker", not "black", in both. */
.pd-cal-cell.pd-cal-wd {
  /* Compound selector, not just .pd-cal-wd - .pd-cal-cell (below) has the
     SAME specificity (one class) and comes later in the file, so it was
     silently winning the cascade regardless of what this rule said - the
     real reason every earlier padding/font/aspect-ratio tweak here had
     no visible effect at all (confirmed via getComputedStyle: this rule
     was contributing nothing). Two classes beats .pd-cal-cell's one,
     unconditionally, independent of source order. */
  aspect-ratio: auto;
  display: block;
  text-align: center;
  font-size: 0.62rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--text-dim, var(--tg-theme-hint-color, #888));
  background: color-mix(in srgb, black 12%, var(--surface-alt, var(--tg-theme-secondary-bg-color, #eef1f6)));
  border-radius: 4px;
  padding: 3px 0;
}
/* Shorter than a square date-picker cell - a day here only ever needs to
   carry a number and (sometimes) a short opponent tag - but not so short
   the opponent tag clips against the cell edge on a phone (1.6/1, eased
   back from an initial 2/1 for exactly that reason).

   Background: the site defines a real --surface-alt that already flips
   with [data-theme="dark"] (site_static/site.css), but the Mini App only
   ever exposes --bg/--text/--accent/--accent-text (frontend/styles.css's
   docstring) - so on Telegram's dark theme this used to fall straight
   through to the hardcoded LIGHT literal (#eef1f6), while the day number's
   text stayed unset and inherited the page's real (dark-theme-correct,
   light-colored) --text. Light text on a near-white cell read as "white on
   white". --tg-theme-secondary-bg-color is Telegram's own theme-aware
   background token (dark in dark theme, light in light theme) - putting it
   between --surface-alt and the literal fixes the Mini App without
   touching frontend/styles.css, and the day/opponent text still isn't
   given an explicit color, so it keeps tracking --text/--tg-theme-text-color
   correctly against whichever background this resolves to. */
.pd-cal-cell {
  aspect-ratio: 1.6 / 1;
  border-radius: 6px;
  background: var(--surface-alt, var(--tg-theme-secondary-bg-color, #eef1f6));
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  line-height: 1;
  font-size: 0.78rem;
  padding: 2px 4px;
  overflow: hidden;
}
/* Match cells: day number left, vs/@ pushed to the cell's far right edge
   on the same line (user's call, 2026-08-20 - was crammed right next to
   the day number instead). Non-match cells never render this wrapper -
   .pd-cal-day alone still aligns flush left via its own align-self. */
.pd-cal-top-row { display: flex; align-items: baseline; justify-content: space-between; }
.pd-cal-day { align-self: flex-start; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pd-cal-cell-match .pd-cal-day { font-size: 0.72rem; }
/* Sized up and no longer dimmed (was opacity 0.7, easy to miss at the old
   size right next to the day number - user's call, 2026-08-20). */
.pd-cal-arrow { font-weight: 700; font-size: 1.15em; }
.pd-cal-opp {
  align-self: flex-end;
  /* width:100% (not just max-width) - a column-flex item with no explicit
     width shrinks to its content's natural size regardless of max-width,
     so overflow/ellipsis had nothing real to clip against and the text
     rendered far narrower than the cell itself (down to a single
     character in testing). Forcing the full inner width first makes the
     ellipsis math work against the cell's REAL available space. */
  width: 100%;
  text-align: right;
  font-size: 0.86rem;
  font-weight: 700;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* The 4-letter edge case (see calendarTable's comment) - shrunk just
   enough to fit a phone's ~31px cell width without ellipsizing, rather
   than shrinking every cell's text for six clubs' sake. */
.pd-cal-opp-long { font-size: 0.66rem; }

/* Any cell that spills into the month after today's real one (user's
   call, 2026-08-20 - "September" vs "August" should read as visually
   distinct even with no month-divider row, see calendarTable's docstring
   on why there isn't one). Flat dark grey wins over both the plain
   .pd-cal-cell background AND a match day's own opponent-color inline
   style - calendarTable() skips writing that inline style at all for
   these cells rather than fighting it with !important here. */
/* Same theme-relative mix as .pd-cal-wd above, just a stronger 30% (vs
   the header's 12%) so "next month" still reads as clearly distinct from
   the current month - the old fixed #23262d read fine on the dark theme
   but was near-black-on-white on the light theme (real bug, 2026-08-20:
   the header row wasn't the only place a flat hex read as "too black"). */
.pd-cal-cell.pd-cal-next-month {
  background: color-mix(in srgb, black 30%, var(--surface-alt, var(--tg-theme-secondary-bg-color, #eef1f6)));
  color: var(--text-dim, var(--tg-theme-hint-color, #6b7280));
}

@media (max-width: 820px) {
  #player-detail { padding: 0.5rem; align-items: flex-end; }
  .pd-panel { max-height: 92vh; }
  .pd-head { padding: 0.7rem 2.6rem 0.7rem 0.7rem; gap: 0.6rem; }
  .pd-photo { width: 48px; height: 48px; font-size: 1.05rem; }
  .pd-body { padding: 0.3rem 0.5rem 0.7rem; }
  .pd-modes { padding: 0.5rem; }
}

/* Desktop has room to spare - a wider panel and a noticeably bigger
   calendar grid rather than the same compact phone sizing stretched
   across empty space. */
@media (min-width: 821px) {
  .pd-panel { max-width: 680px; }
  .pd-cal-cell.pd-cal-wd { font-size: 0.7rem; } /* matches the base rule's compound selector - see its comment on why a single .pd-cal-wd would lose here too */
  .pd-cal-day { font-size: 0.85rem; }
  .pd-cal-cell-match .pd-cal-day { font-size: 0.95rem; }
  .pd-cal-opp { font-size: 1.10rem; }
  /* Desktop's wider columns fit the 4-letter edge case at full size
     already - undo the mobile-only shrink from .pd-cal-opp-long. */
  .pd-cal-opp-long { font-size: 1.10rem; }
}
