/*
 * The player page — the way out, the hero, a tab row, and behind it the
 * cards that describe one footballer. Structurally the competition page's
 * layout (league-details.css), which is itself the club page's: same
 * two-layer fade/rise shell, same bar, same identity block over a sticky tab
 * row, same scrolling body, same panel cross-fade.
 *
 * What is new here is `.player-card`, the block every section on this page is
 * built from. It is deliberately not `.club-overview__card`: that class belongs
 * to one tab of another page and carries that tab's vertical compression, and a
 * page reaching across into another page's stylesheet is how two surfaces end
 * up unable to change independently. The values it shares with it — surface,
 * hairline — are tokens, which is the sharing that was meant to happen.
 *
 * **Under the tabs the page is a sheet, not a stack of cards.** The class is
 * still called a card, because seven stylesheets and six components say so,
 * but what it draws is a full-bleed section of one white surface that begins
 * at the tab row and runs to the bottom of whichever tab is open. Sections
 * are separated by a thin band of the page ground rather than by a gutter
 * with a rounded, shadowed box either side of it. The cards went for the
 * reason the summary card's own note gives about why three of them became
 * one: a card is always the page's width, so every one of them read as a
 * wide box with something small in it, and a page of eight such boxes read
 * as a collection of widgets rather than one page. A sheet has no boxes to
 * be empty. What holds it together instead is one voice for every section
 * — a small tracked eyebrow for the title (`.player-card__title`), the
 * same voice the Stats picker already used for "Season" and "Competition"
 * — and one ledger for every grid of figures (`.player-facts`,
 * `.player-season__figures`): hairline cells on the surface rather than grey
 * tiles floating in white.
 */

/*
 * The page sizes itself from the universal scale (tokens.css), like every
 * other screen. It ran through a `--player-scale` knob (0.915, settled by
 * eye) until 19 Sep 2026; what that tuning found still holds and is worth
 * keeping in mind when a card here looks loose: a card is always the page's
 * width, so shrinking the type alone leaves a wide flat box with small
 * print in it — a hexagon 80px tall floating in a 340px card. What makes
 * these cards look *proportioned* is graphics drawn tall and type large
 * enough to sit against them, which is the reference's arrangement too.
 * Tighten a card by choosing smaller spacing steps, not smaller type.
 */

/*
 * The page wears the club's colour wherever the rest of the app wears the
 * accent. `--club-rgb` is sampled from the crest at runtime (core/team-colours.js)
 * and falls back to the accent itself, so a player with no crest behind them
 * gets the app's own blue and every other player gets theirs — on the pressed
 * chips, the Career tabs, the position marker, the follow star, the player of
 * the match rating. Re-pointing the tokens here rather than restyling each
 * control is what keeps this to one rule: the controls keep saying `--accent`,
 * and inside this page that word means the club.
 *
 * Each derived token is restated, not just `--accent-rgb`: a custom property
 * is resolved where it is declared, so `--accent-soft` computed on `:root` has
 * already baked the root's blue in and would not follow a change made here.
 * The portrait ring, the shirt badge, the traits shape, the value line and the
 * shot markers read `--club-rgb` directly and were already the club's.
 *
 * `--club-rgb` itself is picked here from the two samples team-colours.js
 * writes — the light theme's and the dark theme's — falling back to the app's
 * accent, the same arrangement tokens.css makes for a fixture's pair. Its
 * fallback is `--club-fallback-rgb`, not `--accent-rgb`: this rule points
 * `--accent-rgb` at `--club-rgb`, so the plain name would be a cycle.
 */
.player-details {
  --club-rgb: var(--club-sample-rgb, var(--club-fallback-rgb));
  --accent-rgb: var(--club-rgb);
  --accent: rgb(var(--club-rgb));
  --accent-soft: rgb(var(--club-rgb) / 0.1);
  --shadow-accent: 0 calc(6px * var(--scale)) calc(18px * var(--scale)) calc(-8px * var(--scale)) rgb(var(--club-rgb) / 0.55);
  /* The focus ring too: the back button is focused the moment the page opens,
     and a blue ring beside a claret band is the one thing on screen still
     wearing the app's colour rather than the club's. */
  --ring: rgb(var(--club-rgb));
}

:root[data-theme="dark"] .player-details {
  --club-rgb: var(--club-sample-dark-rgb, var(--club-fallback-rgb));
}

.player-details {
  --enter-y: calc(12px * var(--scale));

  position: fixed;
  inset: 0;
  /*
   * Above the competition page's 97, the club page's 95, the search overlay's
   * 90 and the fixture page's 80 — this opens from all four, so a surface
   * opened from any of them has to win. Below the story viewer's 100, which
   * covers the strip it opens from and so cannot be up at the same time.
   */
  z-index: 98;
  display: flex;
  max-width: var(--app-max-width);
  margin-inline: auto;
  background: var(--bg);
  opacity: 0;
  transition: opacity var(--duration) var(--easing);
}

.player-details[hidden] {
  display: none;
}

.player-details[data-open="true"] {
  --enter-y: 0px;

  opacity: 1;
}

.player-details__sheet {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding-top: var(--safe-top);
  transform: translateY(var(--enter-y));
  transition: transform var(--duration) var(--easing);
}

/* --- Bar -------------------------------------------------------------------- */

/*
 * The app bar (app-bar.css) with this page's spacing above it. The card, the
 * wordmark and the 34px controls are the bar's own; this page adds nothing to
 * them but the room at the top, which is the same room the home header gives
 * itself.
 */
.player-details__bar {
  flex: none;
  margin-top: var(--space-4);
}

/*
 * The star, filled and tinted when this player is followed. It writes the same
 * slice the Squad tab's own star does (see PlayerDetails.js), so it wears the
 * same glyph — a bell here would be a second mark for one fact. Inside the app
 * bar the chip's own fill and border are already stripped, so the pressed
 * state is the one time it earns a fill back — the same deal the home bar's
 * filter button makes when it has filters on.
 */
.player-details__follow {
  transition:
    background-color var(--duration) var(--easing),
    color var(--duration) var(--easing);
}

.player-details__follow[aria-pressed="true"] {
  background: var(--accent-soft);
  color: var(--accent);
}

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

.player-details__body {
  flex: 1;
  display: flex;
  flex-direction: column;
  /* No gap of its own: the hero pads itself (`.player-identity`), and the tab
     row sits flush on the sheet it heads, so nothing here may push them
     apart. */
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: 0 0 var(--space-8);
}

/*
 * The tab row is the top edge of the sheet. `TabBar` paints itself in the
 * page ground so that, stuck at the top of a scrolling page of cards, it
 * reads as chrome the cards pass under; here the panel under it is one white
 * surface, and a grey strip between the hero and that surface would be a
 * gap in the sheet rather than the head of it. Its hairlines stay: the top
 * one is the sheet's edge, the bottom one rules under the row once the hero
 * has scrolled away behind it.
 */
.player-details__body > .tab-bar {
  background: var(--surface);
}

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

/*
 * One cell, every panel in it. The club and league pages lay their panels out
 * as flex siblings, which means that for the `PANEL_SETTLE_MS` a leaving
 * panel is still in layout, the arriving one sits *under* it and only jumps
 * into place once the old one is `hidden` — a fade out, a blank beat, then a
 * snap. Stacking them in a single grid cell is what turns that into the
 * cross-fade the JavaScript already describes: both panels occupy the same
 * box for the beat they overlap, the column is as tall as the taller of the
 * two until the leaving one is taken out, and the arriving one fades up
 * exactly where it will stay. `align-items: start` keeps a short panel from
 * being stretched to a long one's height while they share the cell.
 *
 * `isolation: isolate` for this column is in tab-bar.css with the other three
 * pages' — the rule that keeps a crest inside a panel from scrolling up over
 * the sticky row.
 */
.player-details__panels {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

.player-panel {
  grid-area: 1 / 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  /* The band of page ground between two sections of the sheet. Narrower than
     a gutter between cards, because it is a seam rather than a margin — wide
     enough to read as a break, not wide enough to make the section above it
     a box of its own again. Nothing above the first section: it starts on
     the tab row's own hairline. */
  gap: var(--space-2);
  opacity: 1;
  transition: opacity var(--duration) var(--easing);
}

/* A class beats the UA [hidden] rule, so display has to be turned off by hand
   — the same note every other panel in the app carries. */
.player-panel[hidden] {
  display: none;
}

/* The cross-fade PlayerDetails.js drives on a tab switch. No taps while it is
   on its way out: it still shares the cell with the panel that is arriving. */
.player-panel[data-open="false"] {
  opacity: 0;
  pointer-events: none;
}

/* --- The section every part of the sheet is built from ----------------------- */

/*
 * Full bleed, ruled top and bottom, no radius and no shadow: a section of the
 * sheet rather than a card on the page. The side padding is the page gutter
 * at this page's scale, so type inside a section lines up with the hero's
 * portrait above the tabs; the block padding is a step more than it was as a
 * card, because a section has no edge of its own to hold its contents in and
 * needs the air to do it instead.
 */
.player-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5) var(--space-5);
  background: var(--surface);
  border-block: 1px solid var(--border);
}

/* The first section's top rule is the tab row's bottom hairline, which it
   sits directly on; a second line there would be a double rule. */
.player-panel > .player-card:first-child {
  border-top: 0;
}

.player-card[hidden] {
  display: none;
}

.player-card__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/*
 * The eyebrow. Every section opens in this one voice — small, tracked, in
 * capitals, in the secondary colour — so the sheet reads as one document with
 * headed parts rather than as eight components that each brought a title. It
 * is the voice the Stats picker already spoke in for its two row labels, now
 * made the page's. A bold sentence-case title at body size, which is what
 * these were, is a card's voice: it announces a box. An eyebrow labels what
 * follows and gets out of its way, which is right for a section whose
 * content is the point — a hexagon, a pitch, a list of seasons.
 */
.player-card__title {
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: var(--tracking-caps);
  text-transform: uppercase;
  color: var(--text-secondary);
}

/* Sentence case under the eyebrow, in the muted colour: a qualifier ("Stats
   compared to other forwards", "Touches: 144"), not a second heading. */
.player-card__subtitle {
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
  color: var(--text-muted);
}

.player-card__subtitle[hidden] {
  display: none;
}

.player-card__empty {
  padding-block: var(--space-4);
  text-align: center;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.player-card__empty[hidden] {
  display: none;
}

/* --- The summary card ------------------------------------------------------
 *
 * The fact tiles and Position in one card at the top of the Overview tab,
 * divided by a hairline — see the note in PlayerDetails.js for why they are
 * one and not two.
 *
 * The card carries no padding of its own: each section pads itself, so the
 * hairline between them runs the card's full width rather than stopping at an
 * inset. `flex: none` because the card is a flex item in a scroller, and the
 * scroller must never be allowed to squash the page's first card.
 */
.player-summary {
  flex: none;
  gap: 0;
  padding: 0;
}

.player-summary > * + * {
  border-top: 1px solid var(--border);
}

/* --- Identity: the hero ------------------------------------------------------ */

/*
 * The hero sits on the page's own ground above the tab row, in the seat the
 * club and competition pages give their crest and name (`.league-identity`),
 * and it stays there while the tabs under it change. The same side gutter as
 * the cards, so the portrait lines up with their edge.
 *
 * No band, and no card either. The club's colour — sampled from its crest at
 * runtime (core/team-colours.js), the accent when there is no crest — is
 * worn as a ring around the portrait and as the shirt badge hung on its
 * corner. A slab of sampled colour behind the name meant white type on a
 * colour nobody chose, checked against a luminance cap so that it stayed
 * legible, and every player page opening on the same shape in a different
 * paint. Type on the page needs no such check, and the colour goes where the
 * identity is.
 */
.player-identity {
  flex: none;
  /* The same room above and below: the bar's own margin-top is what separates
     it from the bar, and this is what separates it from the sheet's edge. */
  padding: var(--space-4);
}

/* --- Bio: the fact tiles ------------------------------------------------------ */

/* The top section of the summary card. It pads itself, like Position under
   it, so the hairline between them runs the card's full width. */
.player-bio {
  display: flex;
  flex-direction: column;
  padding: var(--space-5) var(--space-5)
    var(--space-4);
}

.player-hero {
  display: flex;
  align-items: center;
  gap: var(--space-4);
}

/*
 * The ring. A 2px stroke with a 3px gap of surface between it and the photo —
 * the story strip's own treatment, which is what a ring around a face already
 * means in this app. The gap is what keeps it a ring rather than a border: a
 * stroke flush against the photo reads as the photo's edge.
 */
.player-hero__portrait {
  position: relative;
  flex: none;
  padding: var(--space-05);
  border: 2px solid rgb(var(--club-rgb));
  border-radius: var(--radius-full);
  transition: border-color var(--duration) var(--easing);
}

.player-hero__photo {
  display: flex;
}

.player-hero__photo .logo {
  border-radius: var(--radius-full);
  background: var(--surface-sunken);
  object-fit: cover;
}

/* The monogram a player with no photo gets is sized for a 22px disc; at 84 it
   is a speck in a plate, so the letters come up to the portrait. */
.player-hero__photo .logo--monogram {
  font-size: var(--text-xl);
}

/*
 * The shirt number, hung on the ring's bottom-right corner the way the match
 * player sheet hangs a rating on its portrait. Bordered in the page ground —
 * the hero sits on `--bg`, not on a card — so it reads as sitting *on* the
 * ring rather than cut into it.
 */
.player-hero__number {
  position: absolute;
  right: calc(-4px * var(--scale));
  bottom: calc(-4px * var(--scale));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: calc(28px * var(--scale));
  height: calc(28px * var(--scale));
  padding-inline: var(--space-2);
  background: rgb(var(--club-rgb));
  border: 2px solid var(--bg);
  border-radius: var(--radius-full);
  color: var(--text-inverse);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  line-height: var(--leading-none);
  transition: background-color var(--duration) var(--easing);
}

.player-hero__number[hidden] {
  display: none;
}

.player-hero__text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-2);
}

/*
 * The name is the page's title and is set like one: the largest type on the
 * page, tight, and wrapping rather than truncating — "Borussia Mönchengla…" at
 * the top of that club's own page has told you less than the crest beside it
 * did, and the same goes for a surname.
 */
.player-hero__name {
  font-size: var(--text-4xl);
  font-weight: var(--weight-bold);
  line-height: var(--leading-none);
  letter-spacing: var(--tracking-tight);
  color: var(--text);
  text-wrap: balance;
}

/*
 * The club, as a chip: crest, name, and a chevron when there is a page to
 * open. A filled chip is what "this is a thing you can go to" looks like in
 * this app, and it is the one control in the hero, so it is the one thing
 * drawn as one. Disabled — a preview club with no page — keeps the fill and
 * loses the chevron and the press, so the hero does not change shape depending
 * on where the page was opened from.
 */
.player-hero__club {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 100%;
  min-width: 0;
  padding: var(--space-05) var(--space-3)
    var(--space-05) var(--space-05);
  background: var(--surface-sunken);
  border-radius: var(--radius-full);
  color: var(--text);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  text-align: left;
}

.player-hero__club:disabled {
  cursor: default;
}

.player-hero__crest {
  flex: none;
  display: flex;
}

.player-hero__arrow {
  flex: none;
  display: flex;
  margin-left: calc(-1 * var(--space-05));
  color: var(--text-muted);
}

.player-hero__arrow[hidden] {
  display: none;
}

/*
 * The market value, as a pill directly under the club chip. It was the
 * Overview's last card, a headline in the club's colour over a chart; the
 * figure keeps the colour and gives up the headline size — it is one fact
 * among the hero's, not the page's subject. The tint is the same soft accent
 * a pressed chip wears on this page, which inside `.player-details` is the
 * club's (see the top of this file), so the pill and the ring above it are
 * visibly the same colour at two strengths. The label is set lighter than the
 * figure so the money reads first and the word says what it is.
 */
.player-hero__value {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  max-width: 100%;
  min-width: 0;
  padding: var(--space-05) var(--space-2)
    var(--space-05) var(--space-15);
  background: var(--accent-soft);
  border-radius: var(--radius-full);
  color: var(--accent);
  font-size: var(--text-xs);
  font-weight: var(--weight-medium);
  line-height: var(--leading-tight);
  transition: background-color var(--duration) var(--easing), color var(--duration) var(--easing);
}

.player-hero__value-label {
  flex: none;
}

.player-hero__value-figure {
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}

.player-hero__value[hidden] {
  display: none;
}

/*
 * Position · flag country, and an injury when there is one. Descriptive text,
 * not a control. Wraps rather than truncates: the country is the one part that
 * can be long, and it gets the second line rather than an ellipsis.
 */
.player-hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  max-width: 100%;
  color: var(--text-secondary);
  font-size: var(--text-sm);
  font-weight: var(--weight-medium);
}

.player-hero__position {
  flex: none;
}

.player-hero__dot {
  flex: none;
  width: calc(3px * var(--scale));
  height: calc(3px * var(--scale));
  background: var(--text-muted);
  border-radius: var(--radius-full);
}

.player-hero__flag {
  flex: none;
  display: flex;
}

.player-hero__flag[hidden] {
  display: none;
}

.player-hero__country {
  min-width: 0;
}

/* The one fact that comes and goes, as a pill in the injury colour rather than
   a tile that would leave a hole in the grid when it is absent. */
.player-hero__status {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-05) var(--space-2);
  background: var(--injury-soft);
  border-radius: var(--radius-full);
  color: var(--injury);
  font-size: var(--text-2xs);
  font-weight: var(--weight-semibold);
}

.player-hero__status[hidden] {
  display: none;
}

/*
 * Six facts, three across, as a ledger: one hairline frame, hairline cells,
 * the surface showing through. The cells are drawn by a 1px gap over a
 * border-coloured grid rather than by borders on the tiles, so no line is
 * ever doubled where two cells meet and the outer frame is the only edge
 * drawn twice. They were sunken tiles — six grey pills in a white card — and
 * on the sheet that was six small boxes in a page that had just given up its
 * big ones. A ledger is a set of facts read together, which is what these
 * are, and it is the same ledger the season line below uses, which is what
 * makes the two read as one page.
 */
.player-facts,
.player-season__figures {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.player-facts__tile,
.player-season__figure {
  display: flex;
  flex-direction: column;
  gap: var(--space-05);
  min-width: 0;
  padding: var(--space-3) var(--space-3);
  background: var(--surface);
}

.player-facts__value {
  font-size: var(--text-md);
  font-weight: var(--weight-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.player-facts__label {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

/* --- Position --------------------------------------------------------------- */

/*
 * The text sits at the top, beside the pitch rather than centred against it.
 *
 * Centred was the right call while this was a card of its own — the leftover
 * room read as breathing rather than as a hole. Inside the summary card it is
 * not: "Position" is a section heading, and a heading that floats in the middle
 * of its section while every other title on the page sits at the top of one is
 * the odd one out. The room under the words is the pitch's, and the card
 * carries on past it either way.
 */
.player-position {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
}

.player-position__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.player-position__primary {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
  font-weight: var(--weight-semibold);
  color: var(--accent);
}

.player-position__role {
  font-size: var(--text-md);
  font-weight: var(--weight-medium);
  color: var(--text);
}

/*
 * The pitch. `PitchMarkings` stretches its model to whatever box it is given
 * (`preserveAspectRatio: none`), so the aspect ratio here is what decides how
 * true to scale it ends up — the same knob match-lineup.css and season-stats.css
 * turn. 2:3 is a little squarer than a real pitch's 68:105, which is what keeps
 * the marker legible in the width a card can spare.
 */
.player-position__pitch {
  position: relative;
  flex: none;
  /*
   * Sized from its *height*, not its width — see the note on --graphic-width
   * in player-performance.css for why no graphic on this page is sized from
   * the type.
   *
   * The height is what needed pinning: this card holds three short lines of type
   * beside a portrait pitch, so the pitch decides how tall the card is. 184 is
   * what the reference gives it, and the width follows from the ratio rather
   * than being chosen separately.
   *
   * 3:4 is a mild stretch on a real pitch's 68:105 — `PitchMarkings` stretches
   * its model to whatever box it is given, so the box's ratio is the only thing
   * deciding how true to scale the drawing comes out. Mild and deliberate is the
   * same call match-lineup.css and season-stats.css document making for the two
   * other pitches in the app; a true 2:3 box here is accurate and too tall to
   * put on this card.
   */
  height: calc(184px * var(--scale));
  aspect-ratio: 3 / 4;
  background: var(--pitch);
  /* The card's inner radius. This pitch is a diagram inset in a card, not a
     photograph of a ground, and a sharp-cornered block inside a rounded card is
     the one shape on the page that matches nothing around it — the heatmap
     below makes the same call. `overflow` still clips the marker when a
     position sits hard against an edge. */
  border-radius: var(--radius-md);
  overflow: hidden;
}

.player-position__pitch-lines {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/*
 * White markings on the grey ground rather than the darker `--pitch-line`: at
 * this size a dark line is a wire drawing and a light one is chalk, and chalk is
 * what reads as a pitch. The two pitches on this page — this and the heatmap's —
 * share the treatment; the shot map keeps shot-map.css's look because it is the
 * fixture page's graphic reused, not this page's.
 */
.player-position__pitch-line {
  fill: none;
  stroke: var(--surface);
  stroke-width: 0.9;
  opacity: 0.9;
}

.player-position__pitch-spot {
  fill: var(--surface);
  stroke: none;
  opacity: 0.9;
}

.player-position__marks {
  position: absolute;
  inset: 0;
}

/*
 * The marker, placed in percentages of the pitch box so it lands in the same
 * place whatever width the card gets — the same reason the value chart's club
 * marks are HTML over the canvas rather than shapes inside it.
 */
.player-position__mark {
  position: absolute;
  left: var(--x);
  top: var(--y);
  transform: translate(-50%, -50%);
  display: grid;
  place-items: center;
  min-width: calc(36px * var(--scale));
  padding: var(--space-1) var(--space-2);
  background: var(--accent);
  color: var(--accent-text);
  border-radius: var(--radius-full);
  font-size: var(--text-sm);
  font-weight: var(--weight-bold);
  box-shadow: var(--shadow-accent);
}

/* --- Season summary --------------------------------------------------------- */

.player-season__header {
  flex-direction: row;
  align-items: center;
  gap: var(--space-2);
}

.player-season__badge {
  flex: none;
  display: flex;
}

/* The ledger itself is declared with `.player-facts` above — the two are one
   grid. What differs is the alignment: a fact is read as a label with a
   value, left to right, and a season figure as a number with a caption,
   which centres. */
.player-season__figure {
  align-items: center;
  text-align: center;
}

.player-season__value {
  font-size: var(--text-lg);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.player-season__label {
  font-size: var(--text-xs);
  color: var(--text-muted);
}

/*
 * The rating is a chip where its neighbours are figures, because it is the one
 * judged number in the row — the solid treatment the squad lists use rather
 * than the pitch's tinted wash, for the reason MatchSquad.js gives: a wash is
 * for a mark sitting on a busy graphic, and this is the thing the eye is
 * travelling along the row to reach.
 */
.player-season__rating {
  padding: var(--space-05) var(--space-2);
  border-radius: var(--radius-sm);
  color: var(--text-inverse);
  font-size: var(--text-md);
  font-weight: var(--weight-bold);
  font-variant-numeric: tabular-nums;
}

.player-season__rating[data-tier="high"] {
  background: var(--rating-high-solid);
}

.player-season__rating[data-tier="mid"] {
  background: var(--rating-mid-solid);
}

.player-season__rating[data-tier="low"] {
  background: var(--rating-low-solid);
}

/* --- Page behind ------------------------------------------------------------ */

body[data-player-open] {
  overflow: hidden;
}

/* --- Since the backend (2026-09-17) ------------------------------------------ */

/* The Overview column's own sentence, when the profile could not be read. */
.player-overview-note[hidden],
.player-season[hidden],
.player-position[hidden],
.player-hero__club[hidden],
.player-hero__position[hidden],
.player-hero__dot[hidden],
.player-hero__country[hidden],
.player-season__badge[hidden] {
  display: none;
}

/* The match list's skeleton or sentence — see PlayerMatches.js. */
.player-matches__note[hidden] {
  display: none;
}
