/* ---- webfonts --------------------------------------------------------------
   Self-hosted, not loaded from Google: embedding fonts.googleapis.com would
   send every visitor's IP to Google, which is the thing maxoosterwegel.com is
   careful not to do. Both families are OFL (licences alongside the files).
   The declarations below are Google's own — same woff2 payloads, same
   unicode-range split, so latin-ext names (Szczęsny, Čech, Modrić) still get
   the real face instead of a fallback. IBM Plex Sans ships as ONE variable
   file per subset covering the whole 100–700 axis; Atkinson is static, so 400
   and 700 are separate files. Refresh with tools/fetch_fonts.py, which writes
   the files and prints this block (see public/fonts/README.md).
--------------------------------------------------------------------------- */
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 100 700;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-var-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Sans';
  font-style: normal;
  font-weight: 100 700;
  font-display: swap;
  src: url('fonts/ibm-plex-sans-var-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/atkinson-hyperlegible-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/atkinson-hyperlegible-400-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/atkinson-hyperlegible-700-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Atkinson Hyperlegible';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('fonts/atkinson-hyperlegible-700-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --canvas: #ffffff;     /* white main surface (beige felt overused post-Claude) */
  --rail:   #f3f4f6;     /* light cool gray, separates the rail from the canvas */
  --ink:    #16181d;     /* near-black */
  --ink-2:  #5c616b;     /* neutral secondary */
  --ink-3:  #989ea9;     /* neutral tertiary */
  --line:   #e7e8ec;     /* hairline */
  --line-2: #d9dbe1;
  --accent: #0f766e;     /* deep teal */
  --accent-soft: #0f766e1a;

  --goal:  #0f766e;      /* teal */
  --saved: #c0392b;      /* red */
  --post:  #d98a0b;      /* amber */
  --miss:  #a79f93;      /* warm gray */

  /* Typography echoes the blog (penalty-kicks-statistical-models): a humanist,
     hyperlegible display face for headings & big numbers, IBM Plex Sans for the
     body — deliberately away from the old Fraunces/Inter look. */
  --display: "Atkinson Hyperlegible", "Trebuchet MS", "Segoe UI", sans-serif;
  --sans: "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  font-family: var(--sans);
  background: var(--canvas);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
.hidden { display: none !important; }

/* country flags (self-hosted PNGs, see flags/) */
.flag {
  height: 12px; width: auto; margin-right: 5px; vertical-align: -1px;
  border-radius: 1.5px; box-shadow: 0 0 0 .5px rgba(0, 0, 0, .14);
}
.flag-name { height: 17px; margin-right: 7px; vertical-align: -2px; border-radius: 2px; }

/* ---- app shell -------------------------------------------------------- */
.app {
  height: 100vh;
  display: grid;
  /* minmax(0, 1fr): without the 0 minimum a 1fr track defaults to min-width
     auto = its content's min-content, so the top bar's tiles blow the column
     (and the whole page) wider than the viewport — the source of the scroll. */
  grid-template-columns: 264px minmax(0, 1fr);
  grid-template-rows: auto 1fr;
}
.rail {
  grid-row: 1 / 3;
  background: var(--rail);
  border-right: 1px solid var(--line);
  padding: 22px 20px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;   /* never a horizontal scrollbar in the rail */
}
/* Don't let the column flex-shrink its children: the nav / view-toggle segments
   are overflow:hidden (min-height 0), so once the rail content is tall enough to
   scroll they'd otherwise collapse to ~0px — the two thin "bars" under the brand.
   Keep them full height and let the rail scroll instead. */
.rail > * { flex-shrink: 0; }
.topbar { grid-column: 2; grid-row: 1; border-bottom: 1px solid var(--line); min-width: 0; }
.stage  { grid-column: 2; grid-row: 2; position: relative; min-height: 0; min-width: 0; }

/* ---- rail ------------------------------------------------------------- */
.brand {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.45rem;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.brand span { color: var(--accent); }
.brand a { color: inherit; text-decoration: none; }
.brand a:hover span { opacity: .8; }

/* role switch (Takers / Facers) */
.role-nav {
  display: inline-flex;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  overflow: hidden;
  width: 100%;
}
.role-nav a {
  flex: 1;
  padding: 8px 6px;
  text-align: center;
  font-size: .82rem;
  color: var(--ink-2);
  background: #fff;
  text-decoration: none;
  transition: background .15s, color .15s;
}
.role-nav a + a { border-left: 1px solid var(--line-2); }
.role-nav a:hover { background: var(--accent-soft); }
.role-nav a.active { background: var(--accent); color: #fff; font-weight: 500; }

.combo { position: relative; }
#search {
  width: 100%;
  padding: 11px 13px;
  font-size: .95rem;
  font-family: var(--sans);
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: 9px;
  transition: border-color .15s, box-shadow .15s;
}
#search::placeholder { color: var(--ink-3); }
#search:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }

.results {
  position: absolute;
  z-index: 30;
  left: 0; right: 0;
  margin: 6px 0 0;
  padding: 5px;
  list-style: none;
  max-height: 50vh;
  overflow-y: auto;
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: 10px;
  box-shadow: 0 14px 36px rgba(40, 32, 16, .14);
}
.results li {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 9px;
  border-radius: 7px;
  cursor: pointer;
  font-size: .9rem;
}
.results li:hover, .results li.active { background: var(--accent-soft); }
.results li .cnt { color: var(--ink-3); font-variant-numeric: tabular-nums; }

.rail-player { border-top: 1px solid var(--line); padding-top: 18px; }
.rp-name {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.5rem;
  line-height: 1.1;
  letter-spacing: -0.015em;
}
.rp-meta { margin-top: 5px; color: var(--ink-2); font-size: .82rem; }

/* ---- Transfermarkt player profile (rail) ------------------------------ */
.rail-profile { border-top: 1px solid var(--line); padding-top: 16px; }
.profile { margin: 8px 0 0; display: flex; flex-direction: column; gap: 6px; }
.profile > div { display: flex; justify-content: space-between; gap: 12px; font-size: .82rem; line-height: 1.3; }
.profile dt { color: var(--ink-3); flex: none; }
.profile dd { margin: 0; color: var(--ink); text-align: right; }
.profile-src { margin-top: 9px; font-size: .68rem; color: var(--ink-3); letter-spacing: .04em; }
.profile-badge {
  margin: 9px 0 2px; padding: 5px 10px; display: inline-block;
  font-size: .76rem; font-weight: 600; color: var(--accent);
  background: var(--accent-soft); border-radius: 999px;
}

/* ---- penalty-skill posterior (stat-row tile) -------------------------- */
.tile-skill { min-width: 120px; }
.skill-eye { margin: 4px 0 2px; }
.skill-eye .he { display: block; }
.skill-eye .he-x { font-size: 8.5px; fill: var(--ink-3); font-family: var(--sans); }
.tile-skill .t-sub .sk-good { color: #2f7d8a; }
.tile-skill .t-sub .sk-bad { color: #b23b2c; }

.view-toggle { margin-top: -6px; }

.btn-export {
  margin-top: 2px;
  padding: 9px 12px;
  font-family: var(--sans);
  font-size: .82rem;
  color: var(--ink-2);
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  cursor: pointer;
  transition: border-color .15s, color .15s, background .15s;
}
.btn-export:hover { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }

.rail-controls { display: flex; flex-direction: column; gap: 18px; }
.ctl-label {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--ink-3);
  margin-bottom: 8px;
}
.seg { display: inline-flex; border: 1px solid var(--line-2); border-radius: 8px; overflow: hidden; width: 100%; }
.seg button {
  flex: 1;
  padding: 8px 6px;
  font-family: var(--sans);
  font-size: .82rem;
  color: var(--ink-2);
  background: #fff;
  border: none;
  cursor: pointer;
  transition: background .15s, color .15s;
}
.seg button + button { border-left: 1px solid var(--line-2); }
.seg button.active { background: var(--accent); color: #fff; font-weight: 500; }

.switch { display: flex; align-items: center; gap: 9px; cursor: pointer; font-size: .86rem; color: var(--ink-2); }
.switch input { accent-color: var(--accent); width: 15px; height: 15px; }

.legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 7px; }
.legend li { display: flex; align-items: center; gap: 9px; font-size: .85rem; color: var(--ink); }
.legend .dot { width: 11px; height: 11px; border-radius: 50%; flex: none; box-shadow: 0 0 0 1.5px #fff; }
.legend .lcnt { margin-left: auto; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.legend li.off { opacity: .4; }
.ctl-note { margin-top: 9px; font-size: .72rem; line-height: 1.4; color: var(--ink-3); }

.rail-foot {
  margin-top: auto;
  font-size: .76rem;
  line-height: 1.5;
  color: var(--ink-3);
  border-top: 1px solid var(--line);
  padding-top: 16px;
}

/* ---- top stat band ---------------------------------------------------- */
.stat-row { display: flex; align-items: stretch; height: 100%; overflow-x: auto; }
.stat-empty { padding: 28px 26px; color: var(--ink-3); font-size: .95rem; align-self: center; }

.tile {
  padding: 16px 12px;
  /* share the top bar equally and wrap content instead of growing to fit the
     longest line — that growth (esp. the skill + placement tiles) is what
     overflowed the row. flex from a 0 basis => no horizontal scroll at any width.
     overflow:hidden so a too-long value clips at its own tile instead of
     painting over the neighbour. */
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 3px;
  border-right: 1px solid var(--line);
  min-width: 0;
  overflow: hidden;
}
.skill-eye svg { max-width: 100%; height: auto; }
/* short numeric tiles (count / rate / shoot-outs) don't need an equal share —
   grow less so the half-eye and split tiles get the width instead */
.tile-num { flex-grow: .65; }
.tile:last-child { border-right: none; }
.tile .t-label {
  font-size: .68rem;
  text-transform: uppercase;
  letter-spacing: .09em;
  color: var(--ink-3);
}
.tile .t-value {
  font-family: var(--display);
  font-weight: 600;
  font-size: 2rem;
  line-height: 1;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.tile .t-value .unit { font-size: 1rem; color: var(--ink-2); font-weight: 500; }
/* slimmer value for count/denominator tiles (Shoot-outs, Placement data) */
.tile .t-value.sm { font-size: 1.5rem; }
.tile .t-value.sm .unit { font-size: .85rem; }
.tile .t-sub { font-size: .8rem; color: var(--ink-2); font-variant-numeric: tabular-nums; }
.tile .t-sub b { color: var(--accent); font-weight: 600; }

/* side-split tile */
.split-bar { display: flex; height: 8px; border-radius: 5px; overflow: hidden; margin: 7px 0 6px; width: 116px; max-width: 100%; background: var(--line); }
.split-bar span { display: block; height: 100%; }
.split-legend { display: flex; gap: 12px; font-size: .72rem; color: var(--ink-2); }
.split-legend i { font-style: normal; font-variant-numeric: tabular-nums; }
.split-legend .sd { width: 8px; height: 8px; border-radius: 2px; display: inline-block; margin-right: 4px; vertical-align: middle; }
.tile .t-note { margin-top: 6px; font-size: .68rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.tile .t-empty { margin-top: 7px; font-size: .82rem; color: var(--ink-3); font-style: italic; }

/* clickable Penalties count -> opens the full list */
.tile .num-link {
  font-family: var(--display); font-weight: 600; font-size: 2rem; line-height: 1;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--ink);
  background: none; border: none; padding: 0; cursor: pointer;
  display: inline-flex; align-items: baseline; gap: 7px; transition: color .12s;
}
.tile .num-link:hover { color: var(--accent); }
.num-hint {
  font-family: var(--sans); font-size: .64rem; font-weight: 500; letter-spacing: .04em;
  text-transform: uppercase; color: var(--ink-3); transition: color .12s;
}
.tile .num-link:hover .num-hint { color: var(--accent); }

/* clickable tile sub-line (Chosen-to-take -> passed-over list) */
.tile .t-sub-link {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: var(--sans); font-size: .8rem; color: var(--ink-2);
  text-align: left; font-variant-numeric: tabular-nums; transition: color .12s;
}
.tile .t-sub-link:hover, .tile .t-sub-link:hover .num-hint { color: var(--accent); }

/* outcomes tile: compact two-up legend so it fits the top band */
.tile .legend { display: grid; grid-template-columns: 1fr 1fr; gap: 4px 14px; margin-top: 5px; }
.tile .legend li { font-size: .8rem; gap: 6px; }
.tile .legend .lcnt { margin-left: auto; }

/* ---- penalty detail card (on shot click) ------------------------------ */
.pk-info {
  position: absolute;
  top: 14px; right: 16px;
  z-index: 8;
  width: 232px;
  padding: 14px 16px 13px;
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: 11px;
  box-shadow: 0 14px 36px rgba(40, 32, 16, .16);
  animation: pk-pop .14s ease-out;
}
@keyframes pk-pop { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: none; } }
.pk-close {
  position: absolute; top: 8px; right: 10px;
  border: none; background: none; cursor: pointer;
  font-size: 1.2rem; line-height: 1; color: var(--ink-3); padding: 2px;
}
.pk-close:hover { color: var(--ink); }
.pk-oc { font-size: .68rem; text-transform: uppercase; letter-spacing: .09em; font-weight: 600; }
.pk-match {
  font-family: var(--display); font-weight: 600; font-size: 1.02rem;
  line-height: 1.2; margin: 2px 0 10px; letter-spacing: -0.01em;
}
.pk-match span { color: var(--ink-3); font-family: var(--sans); font-weight: 400; font-size: .8rem; }
.pk-info dl { margin: 0; display: flex; flex-direction: column; gap: 6px; }
.pk-info dl > div { display: flex; justify-content: space-between; gap: 12px; font-size: .8rem; }
.pk-info dt { color: var(--ink-3); }
.pk-info dd { margin: 0; color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }

/* ---- stage / plot ----------------------------------------------------- */
/* canvas size/left are set by JS; just centre it vertically in the stage */
#goalCanvas { position: absolute; top: 50%; transform: translateY(-50%); display: block; }

/* hover tooltip that floats by the cursor over the goal canvas */
.chart-tip {
  position: absolute;
  z-index: 7;
  pointer-events: none;
  max-width: 230px;
  padding: 7px 10px;
  font-size: .8rem;
  line-height: 1.35;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: 8px;
  box-shadow: 0 8px 22px rgba(40, 32, 16, .14);
}
.chart-tip .tip-hint { display: block; margin-top: 2px; font-size: .72rem; color: var(--ink-3); }

.empty {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  color: var(--ink-3);
  text-align: center;
  padding: 24px;
}
.empty-mark { font-size: 2.6rem; opacity: .35; }
.empty p { max-width: 320px; font-size: .95rem; margin: 0; }

.no-data {
  position: absolute;
  top: 14px; left: 0; right: 0;
  z-index: 5;
  text-align: center;
  font-size: .82rem;
  color: var(--ink-2);
  pointer-events: none;
}

/* ---- full penalty list (modal) ---------------------------------------- */
.modal {
  position: fixed; inset: 0; z-index: 50;
  display: flex; align-items: center; justify-content: center;
  padding: 32px;
  background: rgba(17, 19, 24, .34);
  animation: pk-pop .12s ease-out;
}
.modal-card {
  display: flex; flex-direction: column;
  width: min(840px, 100%); max-height: 100%;
  background: #fff; border: 1px solid var(--line-2); border-radius: 14px;
  box-shadow: 0 24px 60px rgba(40, 32, 16, .26); overflow: hidden;
}
.modal-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 16px; padding: 18px 22px 14px; border-bottom: 1px solid var(--line);
}
.modal-title { font-family: var(--display); font-weight: 600; font-size: 1.3rem; letter-spacing: -0.015em; }
.modal-sub { margin-top: 3px; font-size: .8rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.modal-close {
  border: none; background: none; cursor: pointer; padding: 2px;
  font-size: 1.5rem; line-height: 1; color: var(--ink-3);
}
.modal-close:hover { color: var(--ink); }
.modal-body { overflow-y: auto; padding: 4px 0 6px; }
.modal-empty { padding: 30px; text-align: center; color: var(--ink-3); }

.pk-table { width: 100%; border-collapse: collapse; font-size: .84rem; }
.pk-table th {
  position: sticky; top: 0; z-index: 1;
  text-align: left; font-weight: 500; font-size: .68rem; text-transform: uppercase;
  letter-spacing: .07em; color: var(--ink-3);
  padding: 9px 14px; background: #fff; border-bottom: 1px solid var(--line);
}
.pk-table td { padding: 9px 14px; border-bottom: 1px solid var(--line); color: var(--ink); }
.pk-table tbody tr:hover { background: var(--accent-soft); }
.pk-table td.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pk-table .vs { color: var(--ink-3); }
.pk-table .oc-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: 7px; vertical-align: middle; }

/* ---- aggregate table view --------------------------------------------- */
.table-view {
  grid-column: 2;
  grid-row: 1 / 3;
  min-height: 0;
  display: flex;
  flex-direction: column;
  background: var(--canvas);
}
.table-loading { padding: 40px; color: var(--ink-3); }
.table-head {
  display: flex; align-items: baseline; gap: 14px;
  padding: 16px 22px 14px; border-bottom: 1px solid var(--line);
}
.table-title { font-family: var(--display); font-weight: 600; font-size: 1.25rem; letter-spacing: -0.015em; }
.table-sub { font-size: .8rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.table-export { margin-top: 0; margin-left: auto; align-self: center; white-space: nowrap; }
.table-scroll { flex: 1; min-height: 0; overflow: auto; }

.agg-table { width: 100%; border-collapse: collapse; font-size: .84rem; }
.agg-table th, .agg-table td { white-space: nowrap; }
.agg-table thead th {
  position: sticky; z-index: 2; background: var(--rail);
  text-align: right; font-weight: 500; color: var(--ink-2);
  padding: 8px 12px;
}
.agg-table thead .th-sort th {
  top: 0; cursor: pointer; user-select: none;
  font-size: .68rem; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3);
  border-bottom: 1px solid var(--line);
}
.agg-table thead .th-sort th:hover { color: var(--accent); }
.agg-table thead .th-filter th {
  top: 31px; padding: 5px 8px; border-bottom: 1px solid var(--line);
}
.agg-table th.l, .agg-table td:first-child { text-align: left; }
.agg-table .th-sort th .sort { color: var(--accent); font-weight: 600; }

.agg-table .th-filter input[type="text"],
.agg-table .th-filter input[type="number"],
.agg-table .th-filter select {
  width: 100%; min-width: 56px; box-sizing: border-box;
  padding: 4px 6px; font-family: var(--sans); font-size: .76rem;
  color: var(--ink); background: #fff;
  border: 1px solid var(--line-2); border-radius: 6px;
}
.agg-table .th-filter input:focus,
.agg-table .th-filter select:focus { outline: none; border-color: var(--accent); }
.wc-chk { display: inline-flex; align-items: center; gap: 4px; font-size: .72rem; color: var(--ink-2); cursor: pointer; }
.wc-chk input { accent-color: var(--accent); }

.agg-table tbody td {
  padding: 7px 12px; border-bottom: 1px solid var(--line);
  color: var(--ink); text-align: right;
}
.agg-table tbody td.num { font-variant-numeric: tabular-nums; }
/* numeric columns are slim, and the skill stats slimmer still, so the inline
   distribution + median/q2.5/q97.5 fit without crowding the text columns */
.agg-table th.num, .agg-table td.num { padding-left: 6px; padding-right: 6px; }
.agg-table th.skill, .agg-table td.skill { padding-left: 3px; padding-right: 3px; }
.agg-table tbody td.skill { color: var(--ink-2); font-size: .76rem; }
.agg-table .th-filter th.num input[type="number"] { min-width: 30px; padding-left: 4px; padding-right: 4px; }
.agg-table .th-filter th.skill input[type="number"] { min-width: 24px; }
/* inline half-eye: shrink the cell to the glyph and centre it */
.agg-table td.dist { width: 1%; text-align: center; padding-top: 3px; padding-bottom: 3px; }
.agg-table td.dist .he { display: block; }
.agg-table tbody td.c { text-align: center; }
.agg-table tbody td:first-child { font-weight: 500; }
.agg-table tbody tr { cursor: pointer; }
.agg-table tbody tr:hover { background: var(--accent-soft); }

/* ---- landing / start screen ------------------------------------------- */
.landing-body { overflow: auto; }
.landing {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  background:
    radial-gradient(120% 80% at 50% -10%, #eef1f6 0%, var(--canvas) 60%);
}
.landing-inner { width: 100%; max-width: 760px; text-align: center; }
.landing-brand {
  font-family: var(--display);
  font-weight: 600;
  font-size: 2.6rem;
  letter-spacing: -0.02em;
  color: var(--ink);
}
.landing-brand span { color: var(--accent); }
.landing-tagline {
  margin: 10px 0 36px;
  font-size: 1.05rem;
  color: var(--ink-2);
}
.landing-cards {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}
@media (max-width: 620px) { .landing-cards { grid-template-columns: 1fr; } }
.lc {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  gap: 8px;
  padding: 26px 24px 22px;
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: 16px;
  text-decoration: none;
  color: var(--ink);
  box-shadow: 0 10px 30px rgba(40, 32, 16, .06);
  transition: transform .15s, box-shadow .15s, border-color .15s;
}
.lc:hover {
  transform: translateY(-3px);
  border-color: var(--accent);
  box-shadow: 0 18px 44px rgba(40, 32, 16, .14);
}
.lc-emoji { font-size: 2.4rem; line-height: 1; }
.lc-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.5rem;
  letter-spacing: -0.015em;
}
.lc-desc { font-size: .9rem; line-height: 1.5; color: var(--ink-2); }
.lc-go {
  margin-top: 8px;
  font-size: .82rem;
  font-weight: 600;
  color: var(--accent);
}
.landing-foot {
  margin-top: 30px;
  font-size: .76rem;
  letter-spacing: .04em;
  color: var(--ink-3);
}

/* latest-penalties freshness panel (what the most recent scrape captured) */
.landing-recent {
  margin-top: 20px;
  padding: 18px 22px 12px;
  background: #fff;
  border: 1px solid var(--line-2);
  border-radius: 16px;
  text-align: left;
  box-shadow: 0 10px 30px rgba(40, 32, 16, .06);
}
.lr-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; margin-bottom: 8px; }
.lr-title { font-family: var(--display); font-weight: 600; font-size: 1.05rem; letter-spacing: -0.01em; }
.lr-meta { margin-left: auto; font-size: .72rem; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.lr-table { width: 100%; border-collapse: collapse; font-size: .8rem; }
.lr-table td {
  padding: 5px 10px 5px 0; border-top: 1px solid var(--line);
  color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 200px;
}
.lr-date, .lr-min { color: var(--ink-3); font-variant-numeric: tabular-nums; }
.lr-filt { color: var(--accent); font-size: .72rem; white-space: nowrap; }
.lr-comp { color: var(--ink-2); }
.lr-taker { font-weight: 500; }
.lr-oc { text-align: right; padding-right: 0 !important; }
.lr-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px; }

/* ==== public static site additions ==================================== */
/* Table-first layout: a slim header (title, nav, search) over a full-height
   table; picking a row swaps the table for the player card in place. */
.page { height: 100vh; display: flex; flex-direction: column; min-width: 0; }
.page-head {
  flex: none;
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 22px;
  padding: 12px 20px;
  border-bottom: 1px solid var(--line);
  font-family: var(--sans);
  /* Height is pinned to the tallest case — the table pages, whose search input
     is taller than the nav pills. Without this the nav sits 5px lower there
     than on the pages that carry no search, and it visibly hops as you move
     between them. */
  min-height: 62px;
}
.ph-title a {
  font-family: var(--display); font-weight: 700; font-size: 1.15rem;
  color: var(--ink); text-decoration: none; letter-spacing: -0.01em;
}
/* min-height matches the search input, so the nav's flex line is the same
   height whether or not the search shares it — on a narrow window the search
   wraps to a second line, and without this the links would ride 5px higher on
   the pages that have one. */
.ph-nav { display: flex; flex-wrap: wrap; align-items: center; gap: 2px; min-height: 38px; }
.ph-nav a {
  color: var(--ink-2); text-decoration: none; font-size: .86rem;
  padding: 5px 10px; border-radius: 7px;
}
.ph-nav a:hover { background: var(--accent-soft); color: var(--ink); }
.ph-nav a.active { background: var(--accent); color: #fff; }
.ph-search { margin-left: auto; width: min(280px, 100%); }
.ph-search #search { padding: 8px 12px; font-size: .9rem; }

.page .table-view { flex: 1 1 0; min-height: 0; }
.stage.stage-card { flex: 1 1 0; min-height: 0; overflow-y: auto; position: relative; }

.card-head { padding: 18px 20px 0; }
.back-link {
  border: none; background: none; padding: 0; cursor: pointer;
  font: inherit; font-size: .84rem; color: var(--ink-2); font-family: var(--sans);
}
.back-link:hover { color: var(--accent); }
.card-head .rp-name { margin-top: 8px; font-size: 1.7rem; }

.stat-row.card {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(235px, 1fr));
  gap: 12px;
  align-content: flex-start;
  padding: 16px 20px 24px;
  height: auto;
  box-sizing: border-box;
  overflow: visible;
}
.stat-row.card .tile {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #fff;
  padding: 16px 16px 14px;
  justify-content: flex-start;
}
.tile-profile .profile dd { text-align: right; }

/* tighter numeric columns: two skill-column families share the row, and the
   keeper table adds two dive columns — headers set the widths, so shrink the
   header font and padding along with the cells */
.page .agg-table { font-size: .8rem; }
.page .agg-table thead th { padding: 8px 8px; }
.page .agg-table thead .th-sort th { font-size: .66rem; letter-spacing: .03em; }
.page .agg-table tbody td { padding: 6px 8px; }
.page .agg-table th.num, .page .agg-table td.num { padding-left: 3px; padding-right: 3px; }
.page .agg-table th.skill, .page .agg-table td.skill { padding-left: 2px; padding-right: 2px; }
.page .agg-table .th-filter th.num input[type="number"] { min-width: 22px; padding-left: 3px; padding-right: 3px; }
.page .agg-table .th-filter th.num, .page .agg-table .th-filter th.skill { padding-left: 2px; padding-right: 2px; }

/* grouped header (descriptives | model estimates) + model-family separators:
   the group row is sticky on top, so the sort/filter rows shift down by its
   fixed 22px height */
.page .agg-table thead .th-group th {
  position: sticky; top: 0; z-index: 2; background: var(--rail);
  height: 22px; box-sizing: border-box; padding: 5px 8px; line-height: 1;
  text-align: center; font-size: .62rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em; color: var(--ink-3);
  border-bottom: 1px solid var(--line);
}
.page .agg-table thead .th-sort th { top: 22px; }
.page .agg-table thead .th-filter th { top: 53px; }
.page .agg-table th.fam, .page .agg-table td.fam { border-left: 2px solid var(--line-2); }
.page .agg-table thead th.c { text-align: center; }
/* club names: trimmed tokens + hard ellipsis, full name in the tooltip */
.page .agg-table td.ell {
  max-width: 150px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; text-align: left;
}

/* data-version note in the navbar; pushed right next to the search box */
.ph-meta { margin-left: auto; font-size: .74rem; color: var(--ink-3); white-space: nowrap; }
.ph-meta + .ph-search { margin-left: 0; }

