/* Components. Each exists once, works in both themes, and styles every state:
   rest, hover, focus, active, disabled, loading, empty, error. Tokens only.

   The look: a newsroom data desk. Flat. Rules instead of boxes, text instead of
   pills, one accent used only where the reader can act. Nothing floats except
   the tooltip and the search results. */

/* Forced states for the styleguide: same look as :hover / :focus-visible. */
.is-focus { outline: 2px solid var(--accent); outline-offset: 2px; }

/* =========================================================================
   Masthead: wordmark, navigation, search, theme toggle. Oxford rule below.
   ========================================================================= */
.site-header {
  position: sticky; top: 0; z-index: var(--z-sticky);
  background: var(--bg); border-bottom: 2px solid var(--text-1);
}
.site-header::after { content: ""; position: absolute; left: 0; right: 0; bottom: -4px; height: 1px; background: var(--text-1); }
.site-header__inner {
  display: flex; align-items: center; gap: var(--sp-3) var(--sp-6); flex-wrap: wrap;
  min-height: var(--header-h); padding-block: var(--sp-3);
}
/* Wordmark: the mark (the position track with the ball on the better side), the name in the display face,
   the sub-line in small capitals. On hover the ball takes a step to the right, where better is. */
.wordmark {
  display: inline-flex; align-items: center; column-gap: 10px;
  text-decoration: none; color: var(--text-1);
}
.wordmark:hover { color: var(--text-1); }
.wordmark__mark { width: 34px; height: 34px; }
.wordmark__track { fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.wordmark__ball { transform-box: fill-box; transform-origin: center; transition: transform var(--dur-state) var(--ease); }
/* A football on the track: paper face, outline and panels in the wordmark's colour, no seams (they read as a wheel
   at 34 px). The ball rolls (rotate) on hover and on arrival. */
.wordmark__face { fill: var(--bg); stroke: currentColor; stroke-width: 1.6; }
.wordmark__panel { fill: currentColor; }
/* Hover: the ball rolls one step to the right, where better is. */
.wordmark:hover .wordmark__ball { transform: translateX(2px) rotate(40deg); }
/* The ball's light: a highlight up left, the edge darker down right, drawn over face and panels so the ball reads as a
   sphere. It does not turn with the ball (the light stays where it comes from), only travels with it. */
.wordmark__light { pointer-events: none; transition: transform var(--dur-state) var(--ease); }
.wordmark:hover .wordmark__light { transform: translateX(2px); }
/* First view of a session: the track draws itself, then the ball rolls in from the left and lands past the median. */
:root[data-mark="draw"] .wordmark__track { stroke-dasharray: 100; animation: mark-draw 400ms var(--ease) both; }
:root[data-mark="draw"] .wordmark__ball { animation: mark-roll 600ms var(--ease-arrive) 300ms backwards; }
:root[data-mark="draw"] .wordmark__light { animation: mark-slide 600ms var(--ease-arrive) 300ms backwards; }
@keyframes mark-slide { from { transform: translateX(-18px); } to { transform: none; } }
@keyframes mark-draw { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
@keyframes mark-roll { from { transform: translateX(-18px) rotate(-540deg); } to { transform: none; } }
/* Judgement arrives: the dot on a position track slides from the median to its place; a sparkline draws itself. */
.track__dot { animation: track-slide var(--dur-chart) var(--ease) both; }
@keyframes track-slide { from { transform: translateX(var(--from, 0)); } to { transform: none; } }
/* Sparklines do not draw themselves: a dozen at once read as flicker, not as information. */
.wordmark__name { font-family: var(--font-display); font-size: 30px; line-height: 34px; letter-spacing: var(--display-tracking); white-space: nowrap; }
@media (max-width: 480px) {
  /* Phones: the name one step smaller, the sub-line may wrap, the mark a touch smaller. */
  .wordmark { column-gap: 8px; }
  .wordmark__mark { width: 28px; height: 28px; }
  .wordmark__name { font-size: 26px; line-height: 28px; }
}
.nav { display: flex; gap: var(--sp-5); margin-right: auto; }
.nav a {
  position: relative; display: inline-flex; align-items: center; min-height: var(--touch);
  font-size: var(--fs-14); font-weight: 500; color: var(--text-2); text-decoration: none;
  transition: color var(--dur-hover) var(--ease);
}
.nav a::after { content: ""; position: absolute; left: 0; right: 0; bottom: 8px; height: 2px; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform var(--dur-hover) var(--ease); }
.nav a:hover, .nav a.is-hover { color: var(--text-1); }
.nav a:hover::after, .nav a.is-hover::after { transform: scaleX(1); }
.nav a[aria-current="page"] { color: var(--text-1); }
.nav a[aria-current="page"]::after { transform: scaleX(1); }
/* Dateline: which season the numbers describe and when they were published. */
/* Season picker: a label and the season menu; the same on every width. */
.season-pick { display: inline-flex; align-items: center; gap: var(--sp-3); font: 500 var(--fs-12) / 1 var(--font-ui); letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-3); }
/* The season menu: a pill that opens a card of seasons, the same language as the look chooser. */
.season-dd { position: relative; display: inline-flex; }
.season-dd__open { display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 0 10px 0 14px; border: 1px solid var(--border); border-radius: 999px; background: var(--surface); color: var(--text-1); font: 600 var(--fs-14) / 1 var(--font-ui); letter-spacing: 0; font-variant-numeric: tabular-nums; cursor: pointer; transition: border-color var(--dur-hover) var(--ease), box-shadow var(--dur-hover) var(--ease); }
.season-dd__open:hover, .season-dd__open[aria-expanded="true"] { border-color: var(--text-2); }
.season-dd__open:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.season-dd__open .icon { width: 14px; height: 14px; color: var(--text-3); transition: transform var(--dur-state) var(--ease); }
.season-dd__open[aria-expanded="true"] .icon { transform: rotate(180deg); }
.season-dd__menu { position: absolute; left: 0; top: calc(100% + 6px); z-index: var(--z-overlay); min-width: 176px; padding: 6px; display: grid; gap: 2px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; box-shadow: var(--shadow-2); transform-origin: top left; animation: season-menu-in var(--dur-state) var(--ease); }
.season-dd__menu[hidden] { display: none; }
@keyframes season-menu-in { from { opacity: 0; transform: translateY(-4px) scale(0.98); } to { opacity: 1; transform: none; } }
.season-dd__menu button { display: flex; align-items: center; justify-content: space-between; gap: 18px; width: 100%; min-height: 36px; padding: 0 10px; background: none; border: 0; border-radius: 5px; color: var(--text-1); font: 500 var(--fs-14) / 1 var(--font-ui); letter-spacing: 0; font-variant-numeric: tabular-nums; text-align: left; cursor: pointer; }
.season-dd__menu button:hover, .season-dd__menu button:focus-visible { background: var(--surface-2); outline: none; }
.season-dd__menu button[aria-selected="true"] { background: var(--surface-2); box-shadow: inset 2px 0 0 var(--text-1); font-weight: 600; }
.season-dd__menu button .icon { width: 14px; height: 14px; color: var(--text-1); opacity: 0; }
.season-dd__menu button[aria-selected="true"] .icon { opacity: 1; }
/* Sidebar (phones): the menu button in the masthead opens the sections and the club search from the left. */
.season-bar { display: none; }
.site-header .menu-open { display: none; }
.sidebar { position: fixed; inset: 0; z-index: var(--z-overlay); visibility: hidden; }
.sidebar.is-open { visibility: visible; }
.sidebar__backdrop { position: absolute; inset: 0; background: rgb(0 0 0 / 0.45); opacity: 0; transition: opacity var(--dur-chart) var(--ease); }
.sidebar.is-open .sidebar__backdrop { opacity: 1; }
.sidebar__panel {
  position: absolute; top: 0; bottom: 0; left: 0; width: min(320px, 86vw); display: flex; flex-direction: column; gap: var(--sp-5);
  padding: var(--sp-3) var(--sp-4) var(--sp-5); background: var(--bg); border-right: var(--rule); overflow-y: auto;
  transform: translateX(-100%); transition: transform var(--dur-chart) var(--ease);
}
.sidebar.is-open .sidebar__panel { transform: none; }
.sidebar__head { display: flex; align-items: center; justify-content: space-between; }
.sidebar__nav { display: grid; }
.sidebar__nav a {
  display: flex; align-items: center; min-height: 48px; padding: 0 var(--sp-2); border-bottom: var(--hairline);
  font: 500 var(--fs-16) / 1 var(--font-ui); color: var(--text-2); text-decoration: none;
}
.sidebar__nav a:hover { color: var(--text-1); }
.sidebar__nav a[aria-current="page"] { color: var(--text-1); box-shadow: inset 3px 0 0 var(--accent); }
html.has-menu { overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .sidebar__backdrop, .sidebar__panel { transition: none; } }
@media (max-width: 760px) {
  /* Phones: the section links live in the sidebar; the menu button takes their place. The season picker has a row of its own. */
  .site-header .menu-open { display: inline-grid; }
  .site-header .nav { display: none; }
  .site-header .site-header__tools .search__open { display: none; }
  .season-pick { order: 3; flex: 0 0 100%; padding-bottom: var(--sp-2); }
  /* Phones: the masthead scrolls away, so the picker also sits in a bar that sticks to the top while you read. */
  .site-header .season-pick { display: none; }
  .season-bar { display: block; position: sticky; top: 0; z-index: var(--z-sticky); background: var(--bg); border-bottom: var(--hairline); padding: var(--sp-2) var(--sp-4); }
  .season-bar .season-pick { padding-bottom: 0; }
}
.site-header__tools { display: flex; align-items: center; gap: var(--sp-3); }
/* The search icon exists for phones only; the selector outweighs .btn--icon's display. */
.site-header__tools .search__open { display: none; }
@media (max-width: 760px) {
  /* Phones: the masthead scrolls away instead of eating a quarter of the screen. It stays positioned so its thin
     second rule (::after) sits under it and not one screen height down, through the content. */
  .site-header { position: relative; z-index: var(--z-overlay); } /* above the sticky season bar, so the masthead's menus open over it */
  .nav { order: 3; flex: 1 1 200px; min-width: 0; margin-right: 0; gap: var(--sp-4); overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
  .nav::-webkit-scrollbar { display: none; }
  /* Row one: wordmark, then the search icon and the theme toggle at the right; row two: the nav. The search field
     appears as its own row only while searching. */
  .site-header__tools { flex: 0 0 auto; margin-left: auto; order: 1; }
  .site-header .search { display: none; flex-basis: 100%; order: 2; }
  .site-header.is-searching .search { display: block; }
  .site-header__tools .search__open { display: inline-grid; }
  .data-table th { top: 0; }
}

/* =========================================================================
   Buttons: ink, outline, text. Square corners. No gradients, no shadows.
   ========================================================================= */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  min-height: var(--touch); padding: 0 var(--sp-4);
  font: 500 var(--fs-14) / 1 var(--font-ui); text-decoration: none; white-space: nowrap;
  border: 1px solid transparent; border-radius: var(--radius-control); cursor: pointer;
  transition: background-color var(--dur-hover) var(--ease), border-color var(--dur-hover) var(--ease), color var(--dur-hover) var(--ease);
}
.btn .icon { width: 18px; height: 18px; }
.btn--primary { background: var(--text-1); color: var(--bg); }
.btn--primary:hover, .btn--primary.is-hover { background: var(--accent-strong); color: var(--on-accent); }
.btn--secondary { background: transparent; color: var(--text-1); border-color: var(--text-1); }
.btn--secondary:hover, .btn--secondary.is-hover { background: var(--surface-2); }
.btn--ghost { background: transparent; color: var(--accent); padding-inline: var(--sp-1); text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 4px; }
.btn--ghost:hover, .btn--ghost.is-hover { color: var(--accent-strong); text-decoration-color: currentColor; }
.btn--icon { width: var(--touch); padding: 0; color: var(--text-2); background: transparent; }
.btn--icon:hover, .btn--icon.is-hover { background: var(--surface-2); color: var(--text-1); }
.btn:active, .btn.is-active { transform: translateY(1px); }
.btn:disabled, .btn[aria-disabled="true"] {
  cursor: not-allowed; transform: none; text-decoration: none;
  background: transparent; color: var(--text-3); border-color: var(--border);
}
.btn--ghost:disabled, .btn--icon:disabled { border-color: transparent; }
/* Loading: no spinner. The label says what happens and the button holds its width. */
.btn[aria-busy="true"] { cursor: progress; color: transparent; position: relative; }
.btn[aria-busy="true"]::after {
  content: attr(data-busy); position: absolute; inset: 0; display: grid; place-items: center;
  color: var(--text-2); animation: pulse 1.2s var(--ease) infinite alternate;
}
.btn--primary[aria-busy="true"]::after { color: var(--bg); }

/* =========================================================================
   Tabs (segmented): text on a hairline, the chosen one underlined in accent.
   ========================================================================= */
.segmented {
  display: inline-flex; flex-wrap: wrap; gap: 0 var(--sp-5);
  border-bottom: var(--hairline);
}
.segmented button {
  position: relative; min-height: 40px; padding: 0;
  font: 500 var(--fs-14) / 1 var(--font-ui); color: var(--text-2);
  background: transparent; border: 0; cursor: pointer;
  transition: color var(--dur-hover) var(--ease);
}
.segmented button::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform var(--dur-hover) var(--ease); }
.segmented button:hover, .segmented button.is-hover { color: var(--text-1); }
.segmented button[aria-checked="true"] { color: var(--text-1); }
.segmented button[aria-checked="true"]::after { transform: scaleX(1); }
.segmented button:disabled { color: var(--text-3); cursor: not-allowed; }
.segmented button:disabled::after { display: none; }
.segmented--compact { gap: 0 var(--sp-4); }
.segmented--compact button { min-height: 32px; font-size: var(--fs-12); }
/* The league tabs of every page are the same: links look like these buttons (text, the chosen one underlined). */
.segmented a { position: relative; display: inline-flex; align-items: center; min-height: 40px; font: 500 var(--fs-14) / 1 var(--font-ui); color: var(--text-2); text-decoration: none; }
.segmented a::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 2px; background: var(--accent); transform: scaleX(0); transform-origin: left; transition: transform var(--dur-hover) var(--ease); }
.segmented a:hover { color: var(--text-1); }
.segmented a[aria-current="page"] { color: var(--text-1); }
.segmented a[aria-current="page"]::after { transform: scaleX(1); }
.segmented--compact a { min-height: 32px; font-size: var(--fs-12); }

/* Season switch: ‹ 2024/25 › with every season one step away in the select */
.season-switch { display: inline-flex; align-items: center; gap: var(--sp-1); }
.season-switch .btn--icon { width: 40px; min-height: 40px; }
.season-switch .btn--icon:disabled { background: transparent; color: var(--text-3); opacity: 0.5; }
.season-switch select {
  appearance: none; min-height: 40px; padding: 0 var(--sp-2); border: 0; border-bottom: var(--rule-axis); border-radius: 0;
  background: transparent; color: var(--text-1);
  font: 500 var(--fs-16) / 1 var(--font-ui); font-variant-numeric: tabular-nums; text-align: center; cursor: pointer;
}
.season-switch select:hover { border-bottom-color: var(--text-1); }

/* =========================================================================
   Search (combobox): an underlined field, results float
   ========================================================================= */
.search { position: relative; }
.search__field {
  display: flex; align-items: center; gap: var(--sp-2); min-height: var(--touch); padding: 0 2px;
  border-bottom: var(--rule-axis); color: var(--text-3);
  transition: border-color var(--dur-hover) var(--ease), box-shadow var(--dur-hover) var(--ease);
}
.search__field:hover, .search__field.is-hover { border-bottom-color: var(--text-1); }
.search__field:focus-within, .search__field.is-focus { border-bottom-color: var(--accent); box-shadow: 0 1px 0 var(--accent); }
.search__field.is-focus { outline: none; }
.search__input {
  width: 100%; min-width: 120px; border: 0; outline: 0; background: transparent; color: var(--text-1);
  font-size: var(--fs-16); /* 16px stops iOS zoom */
}
.search__input::placeholder { color: var(--text-3); }
.search__list {
  position: absolute; left: 0; right: 0; top: calc(100% + 6px); z-index: var(--z-overlay);
  min-width: 280px; max-height: 320px; overflow-y: auto; padding: var(--sp-1) 0;
  background: var(--surface); border-radius: var(--radius-control); box-shadow: var(--shadow-2);
}
.search__option {
  display: grid; grid-template-columns: 20px 1fr auto; align-items: center; gap: var(--sp-2);
  min-height: var(--touch); padding: 0 var(--sp-3); cursor: pointer; font-size: var(--fs-14);
  border-left: 2px solid transparent;
}
.search__option img { width: 20px; height: 20px; object-fit: contain; }
.search__option[aria-selected="true"] { background: var(--surface-2); border-left-color: var(--accent); }
.search__name { color: var(--text-1); }
.search__meta { color: var(--text-3); font-size: var(--fs-12); font-variant-numeric: tabular-nums; }
.search__empty { padding: var(--sp-3); color: var(--text-2); font-size: var(--fs-14); }

/* =========================================================================
   Club: chip, card, head
   ========================================================================= */
.chip {
  --chip-key: var(--text-3);
  display: inline-flex; align-items: center; gap: 6px; min-height: 32px; padding: 0 var(--sp-2) 0 6px;
  font: 500 var(--fs-14) / 1 var(--font-ui); color: var(--text-1);
  background: transparent; border: 1px solid var(--border); border-radius: var(--radius-chip); cursor: pointer;
  transition: border-color var(--dur-hover) var(--ease), box-shadow var(--dur-hover) var(--ease);
}
.chip img { width: 18px; height: 18px; object-fit: contain; }
/* Hover: the club color as a fine rim, the logo stays still. */
.chip:hover, .chip.is-hover { border-color: var(--club, var(--text-1)); }
/* Selected: rim and key in the series color; text stays ink (filled chips miss 4.5:1). */
.chip[aria-pressed="true"] { border-color: var(--chip-key); box-shadow: inset 0 0 0 1px var(--chip-key); }
.chip__key { display: none; width: 12px; height: 3px; background: var(--chip-key); }
.chip[aria-pressed="true"] .chip__key { display: block; }
.chip:disabled { cursor: not-allowed; opacity: 0.45; }
.chip__remove { display: grid; place-items: center; width: 20px; height: 20px; margin-right: -4px; color: var(--text-3); }
.chip:hover .chip__remove { color: var(--text-1); }

.club-card {
  display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 2px var(--sp-3); align-items: center;
  min-height: 64px; padding: var(--sp-3) 0; text-decoration: none; color: var(--text-1);
  border-top: 1px solid var(--axis);
  transition: border-color var(--dur-hover) var(--ease), box-shadow var(--dur-hover) var(--ease);
}
.club-card:hover, .club-card.is-hover { color: var(--text-1); border-top-color: var(--club, var(--text-1)); box-shadow: inset 0 1px 0 var(--club, var(--text-1)); }
.club-card img { width: 36px; height: 36px; object-fit: contain; grid-row: span 2; }
.club-card__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; font-size: var(--fs-16); line-height: 20px; }
.club-card__meta { font-size: var(--fs-12); line-height: var(--lh-12); color: var(--text-3); font-variant-numeric: tabular-nums; }
/* A club-published value for the season the DFL has not covered: hollow dot, same word everywhere. */
.club-card__prov { grid-column: 1 / -1; display: inline-flex; align-items: center; gap: 6px; margin-top: 2px; color: var(--text-2); white-space: nowrap; }
.club-card__prov::before { content: ""; width: 8px; height: 8px; border-radius: 50%; border: 1.5px solid var(--accent); box-sizing: border-box; }

.league-tag { display: inline-flex; align-items: center; gap: 6px; font-weight: 500; color: var(--text-1); }
.league-tag::before { content: ""; width: 10px; height: 3px; background: var(--league-1); }
.league-tag--2::before { background: var(--league-2); }
.league-tag--0::before { background: transparent; box-shadow: inset 0 0 0 1px var(--text-3); }

.club-head { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-2) var(--sp-4); align-items: center; }
.club-head__logo { width: 56px; height: 56px; object-fit: contain; grid-row: span 2; }
.club-head__meta { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); font-size: var(--fs-14); line-height: var(--lh-14); color: var(--text-2); }
.club-head__context { grid-column: 1 / -1; max-width: var(--text-max); }

/* =========================================================================
   KPI tile: rule, label, value, delta, rank, sparkline
   ========================================================================= */
.kpis { display: grid; gap: var(--sp-5) var(--sp-5); grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.kpi { display: grid; gap: 2px; align-content: start; min-height: 168px; padding-top: var(--sp-2); border-top: var(--rule); }
.kpi__label { font: 500 var(--fs-14) / var(--lh-14) var(--font-ui); color: var(--text-2); }
.kpi__value { margin-top: var(--sp-1); font-family: var(--font-display); font-size: calc(var(--fs-40) * var(--display-scale)); line-height: var(--lh-40); letter-spacing: var(--display-tracking); }
.kpi__value .figure__unit { font-size: 0.4em; }
.kpi__delta { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; margin-top: var(--sp-1); font-size: var(--fs-14); line-height: var(--lh-14); color: var(--text-2); }
.kpi__delta .icon { width: 14px; height: 14px; }
.delta { display: inline-flex; align-items: center; gap: 2px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text-1); }
.delta--up { color: var(--positive); }
.delta--down { color: var(--negative); }
.kpi__rank { font-size: var(--fs-12); line-height: var(--lh-12); color: var(--text-3); font-variant-numeric: tabular-nums; }
/* Position track: right is always better, the middle stroke is the median, the dot carries the tone. */
.track { display: inline-block; vertical-align: middle; overflow: visible; }
.track__line { stroke: var(--axis); stroke-width: 1; }
.track__mid { stroke: var(--text-3); stroke-width: 1; }
.track__head { fill: none; stroke: var(--axis); stroke-width: 1; stroke-linejoin: round; }
.track__dot { fill: var(--text-1); stroke: var(--bg); stroke-width: 1.5; }
.track__dot--pos { fill: var(--positive); }
.track__dot--neg { fill: var(--negative); }
.track__dot--open { fill: var(--bg); stroke: var(--text-2); }
.kpi__rank { display: flex; justify-content: space-between; align-items: center; gap: var(--sp-2); }
.kpi__rank .track { flex: none; }
.kpi__spark { height: 32px; margin-top: auto; }
.kpi.is-gap .kpi__value { color: var(--text-3); font-size: var(--fs-28); }
@media (max-width: 480px) {
  /* Two columns that may shrink below the figure's width; the figure itself steps down to fit. */
  .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--sp-5) var(--sp-4); }
  .kpi { min-width: 0; }
  .kpi__value { font-size: var(--fs-28); line-height: var(--lh-28); }
  .kpi__value .figure__unit { font-size: 0.5em; }
}

/* =========================================================================
   Chart frame: rule, title, subtitle, chart, source, table, export
   ========================================================================= */
.chart-frame { display: flex; flex-direction: column; gap: var(--sp-4); min-width: 0; padding-top: var(--sp-3); border-top: var(--rule); }
.chart-frame__head { display: grid; gap: var(--sp-1); }
.chart-frame__title { font-family: var(--font-display); font-size: calc(var(--fs-22) * var(--display-scale)); line-height: var(--lh-22); letter-spacing: var(--display-tracking); text-wrap: balance; }
.chart-frame__sub { font-size: var(--fs-14); line-height: var(--lh-14); color: var(--text-2); }
.chart-frame__controls { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-6); align-items: center; }
.chart-frame__body { position: relative; min-height: 240px; }
.chart-frame__foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--sp-2) var(--sp-4); padding-top: var(--sp-2); border-top: var(--hairline); }
.chart-frame__source { font-size: var(--fs-12); line-height: var(--lh-12); color: var(--text-3); }
.chart-frame__actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); }
.chart-frame__actions .btn { min-height: 32px; padding-inline: 0; font-size: var(--fs-12); }
.chart-frame__actions .btn .icon { width: 14px; height: 14px; }
/* Loading: axes first, then data. Holds its height, no layout jump. */
.chart-frame.is-loading .chart-frame__body { background:
  linear-gradient(var(--grid), var(--grid)) 0 0 / 100% 1px no-repeat,
  linear-gradient(var(--grid), var(--grid)) 0 25% / 100% 1px no-repeat,
  linear-gradient(var(--grid), var(--grid)) 0 50% / 100% 1px no-repeat,
  linear-gradient(var(--grid), var(--grid)) 0 75% / 100% 1px no-repeat,
  linear-gradient(var(--axis), var(--axis)) 0 100% / 100% 1px no-repeat;
  animation: pulse 1.2s var(--ease) infinite alternate; }
.chart-frame.is-loading .chart-frame__title { color: var(--text-3); }

/* Percentage width: the SVG never holds its container open, so a shrinking viewport triggers a redraw. */
.chart__svg { overflow: visible; width: 100%; height: auto; }
.chart__svg:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }
.chart__grid { stroke: var(--grid); stroke-width: 1; shape-rendering: crispEdges; }
.chart__zero { stroke: var(--text-2); stroke-width: 1; shape-rendering: crispEdges; }
/* Tick labels sit inside the plot, so they wear a paper halo and lines pass under them. */
.chart__tick { font: 400 var(--fs-12) var(--font-ui); fill: var(--text-3); font-variant-numeric: tabular-nums; paint-order: stroke; stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round; }
.chart__line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart__line--ref { stroke-width: 1.5; stroke-dasharray: 4 4; }
.chart__line--thin { stroke-width: 1.25; opacity: 0.9; }
.chart__line--muted { stroke-width: 1.25; opacity: 0.45; } /* context: a whole league behind the compared clubs */
.chart__axis { font: 500 var(--fs-12) var(--font-ui); fill: var(--text-2); }
.chart__ratio { stroke: var(--axis); stroke-width: 1; stroke-dasharray: 2 3; }
.chart__ratio-label { font: italic 400 var(--fs-12) var(--font-ui); fill: var(--text-3); }
.chart__scatter-dot { fill: var(--text-2); stroke: var(--bg); stroke-width: 2; }
.chart__mark--muted .chart__scatter-dot { fill: var(--mark-muted); }
.chart__mark.is-active .chart__crest-ring, .chart__mark.is-on .chart__crest-ring { stroke: var(--accent); stroke-width: 2; }
.chart__mark.is-active .chart__scatter-dot { fill: var(--accent); }
.chart__mark.is-on .chart__end { font-weight: 600; }
.chart__trail { fill: none; stroke: var(--accent); stroke-width: 1.5; stroke-linejoin: round; }
.chart__trail-dot { fill: var(--bg); stroke: var(--accent); stroke-width: 1.5; }
.chart__trail-label { font: 400 var(--fs-12) var(--font-ui); fill: var(--text-3); font-variant-numeric: tabular-nums; paint-order: stroke; stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round; }
.chart__stack { shape-rendering: crispEdges; }
.legend__key--swatch { width: 10px; height: 10px; border-radius: 2px; }
.multiples { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--sp-2) var(--sp-5); margin: 0; padding: 0; list-style: none; }
.multiples > li { min-width: 0; }
.multiples__cell { display: grid; gap: 2px; padding: var(--sp-2) 0 var(--sp-1); border-top: var(--hairline); color: inherit; text-decoration: none; min-width: 0; }
a.multiples__cell:hover .multiples__name { text-decoration: underline; text-decoration-color: var(--accent); text-underline-offset: 3px; }
.multiples__head { display: flex; align-items: center; gap: 6px; font: 500 var(--fs-12) var(--font-ui); color: var(--text-1); min-width: 0; }
.multiples__head img { width: 16px; height: 16px; object-fit: contain; flex: none; }
.multiples__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.multiples__value { margin-left: auto; flex: none; font-weight: 400; color: var(--text-2); font-variant-numeric: tabular-nums; }
.multiples__svg { display: block; width: 100%; height: auto; }
.multiples__line { fill: none; stroke: var(--key, var(--text-1)); stroke-width: 1.5; stroke-linejoin: round; stroke-linecap: round; }
.multiples__dot { fill: var(--key, var(--text-1)); }
.multiples__cell.is-on .multiples__line, .multiples__cell.is-on .multiples__dot { stroke: var(--accent); }
.multiples__cell.is-on .multiples__dot { fill: var(--accent); }
.multiples__cell.is-on .multiples__name { font-weight: 600; }
/* Focus from the comparison's legend: the lit tile strong with a rule in its colour, the others faded. */
.multiples[data-focus] .multiples__cell:not(.is-lit) { opacity: 0.3; transition: opacity 0.15s; }
.multiples__cell.is-lit { border-top: 2px solid var(--key, var(--text-1)); }
.multiples__cell.is-lit .multiples__line { stroke-width: 2.5; }
.multiples__cell.is-lit .multiples__name { font-weight: 600; }
/* Provisional: club-published, not yet in a DFL file. Hollow point, dotted connector, labelled. */
.chart__line--prov { stroke-width: 2; stroke-dasharray: 1 5; stroke-linecap: round; }
.chart__dot--prov { fill: var(--bg); stroke-width: 2; }
.chart__end-prov { font: italic 400 var(--fs-12) var(--font-ui); fill: var(--text-3); }
.chart__dot { stroke: var(--bg); stroke-width: 2; }
.chart__end { font: 500 var(--fs-12) var(--font-ui); fill: var(--text-1); }
.chart__end-value { font-weight: 400; fill: var(--text-2); font-variant-numeric: tabular-nums; }
/* The readout in the plot: a tag beside each point of the hovered season, the season as a pill on the tick row. */
.chart__hover { pointer-events: none; }
.chart__tag { fill: var(--panel); stroke-width: 1; }
.chart__tag-text { font: 500 var(--fs-12) var(--font-ui); fill: var(--text-1); font-variant-numeric: tabular-nums; }
.chart__season { fill: var(--text-1); }
.chart__season-text { font: 500 var(--fs-12) var(--font-ui); fill: var(--bg); font-variant-numeric: tabular-nums; }
/* The crest at the end of a line is the house signature: a reader sees the club before the name. */
.chart__crest-ring { fill: var(--bg); }
.chart__leader { stroke: var(--text-3); stroke-width: 1; fill: none; }
.chart__crosshair { stroke: var(--text-2); stroke-width: 1; shape-rendering: crispEdges; }
.chart__brush { fill: var(--accent); fill-opacity: 0.12; stroke: var(--accent); stroke-width: 1; pointer-events: none; }
.chart__overlay--zoom { cursor: crosshair; touch-action: manipulation; } /* a finger pans and pinches the page as everywhere else */
.chart__band { fill: var(--surface-2); }
.chart__bar { fill: var(--accent); }
.chart__bar-label { font: 400 var(--fs-12) var(--font-ui); fill: var(--text-2); font-variant-numeric: tabular-nums; }
.chart__gap { font: italic 400 var(--fs-12) var(--font-ui); fill: var(--text-3); }
.chart__better { font: italic 400 var(--fs-12) var(--font-ui); fill: var(--text-3); }
.chart__annotation { font: 500 var(--fs-12) var(--font-ui); fill: var(--text-2); }
.chart__annotation-rule { stroke: var(--axis); stroke-width: 1; shape-rendering: crispEdges; }
.chart__annotation-dot { fill: var(--text-2); stroke: var(--bg); stroke-width: 2; }
.chart__annotation-badge { fill: var(--text-1); }
.chart__annotation-num { font: 600 var(--fs-12) var(--font-ui); fill: var(--bg); }
.chart__notes { display: grid; gap: 2px; margin-top: var(--sp-2); padding-left: 0; counter-reset: note; font-size: var(--fs-12); line-height: var(--lh-12); color: var(--text-2); }
.chart__notes li { counter-increment: note; display: flex; gap: var(--sp-2); }
.chart__notes li::before { content: counter(note); display: inline-grid; place-items: center; flex: none; width: 18px; height: 18px; border-radius: 50%; background: var(--text-1); color: var(--bg); font-weight: 600; font-size: var(--fs-12); }
/* The lead chart of a page: one size up, so a page has a first chart. */
/* League bands: the colour is the tier's, the same in every country. */
.chart__league--1, .chart__league--3, .chart__league--5 { fill: var(--league-1); }
.chart__league--2, .chart__league--4, .chart__league--6 { fill: var(--league-2); }
.chart__league--0 { fill: var(--grid); }
.league-key { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-3); font-size: var(--fs-12); line-height: var(--lh-12); color: var(--text-2); }
.league-key span { display: inline-flex; align-items: center; gap: 6px; }
.league-key span::before { content: ""; width: 14px; height: 3px; background: var(--league-1); }
.league-key .is-2::before { background: var(--league-2); }
.league-key .is-0::before { background: var(--grid); }
.chart__fade { animation: fade var(--dur-chart) var(--ease) both; }
.sparkline__line { fill: none; stroke: var(--text-2); stroke-width: 1.75; stroke-linejoin: round; stroke-linecap: round; }
.sparkline__dot { fill: var(--accent); stroke: var(--bg); stroke-width: 2; }
.sparkline__zero { stroke: var(--grid); stroke-width: 1; shape-rendering: crispEdges; }

/* Legend: logo, line key, name. Plain text, no pills. Order = selection order = color order. */
.legend { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-4); }
.legend li { display: inline-flex; align-items: center; gap: 6px; min-height: 24px; font-size: var(--fs-12); color: var(--text-1); }
.legend img { width: 16px; height: 16px; object-fit: contain; }
.legend__key { width: 14px; height: 3px; background: var(--key); }
.legend__key--dash { background: repeating-linear-gradient(90deg, var(--text-3) 0 4px, transparent 4px 7px); }
.legend__key--ring { width: 8px; height: 8px; background: none; border: 1.5px solid var(--key, var(--accent)); border-radius: 50%; box-sizing: border-box; } /* a club's provisional point: its colour */
.legend__key--thin { height: 1px; background: var(--text-3); }
.legend__key--dot { width: 8px; height: 8px; border-radius: 50%; background: var(--key, var(--text-3)); }
.legend__key--hollow { width: 8px; height: 8px; border-radius: 50%; background: none; border: 1.5px solid var(--key, var(--text-3)); box-sizing: border-box; }
.legend__key--diamond { width: 7px; height: 7px; margin-inline: 1px; border-radius: 1px; background: var(--key, var(--text-1)); transform: rotate(45deg); }
.legend__key--none { display: none; }
.chart-frame__legend { color: var(--text-2); }
.chart-frame__legend li { color: var(--text-2); }

/* Ranking: logo left, value right, the club in focus highlighted */
.ranking { display: grid; }
.ranking__row {
  display: grid; grid-template-columns: 20px 20px minmax(84px, 136px) 1fr 48px; align-items: center; gap: var(--sp-2);
  min-height: 30px; padding: 0 var(--sp-1); border-bottom: var(--hairline); font-size: var(--fs-14); line-height: var(--lh-14);
  transition: background-color var(--dur-hover) var(--ease);
}
.ranking__row:hover { background: var(--surface-2); }
.ranking__rank { font-size: var(--fs-12); color: var(--text-3); text-align: right; font-variant-numeric: tabular-nums; }
.ranking__logo { width: 20px; height: 20px; object-fit: contain; }
.ranking__name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ranking__track { height: 10px; }
.ranking__bar { display: block; height: 100%; width: var(--w); min-width: 2px; background: var(--mark-muted); transform-origin: left; animation: grow-x var(--dur-chart) var(--ease) both; }
.ranking__row.is-highlight .ranking__bar { background: var(--accent); }
.ranking--diverging .ranking__track { position: relative; }
.ranking--diverging .ranking__track::before { content: ""; position: absolute; left: 50%; top: -3px; bottom: -3px; border-left: 1px solid var(--axis); }
.ranking--diverging .ranking__bar { position: absolute; top: 0; }
.ranking__bar--pos { background: var(--positive); }
.ranking__bar--neg { background: var(--negative); transform-origin: right; }
.ranking--diverging .ranking__row.is-highlight .ranking__bar { background: var(--accent); }
.ranking__row.is-highlight .ranking__name { font-weight: 600; }
.ranking__value { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* The name takes what it needs (a league label, a long club name); the bar yields first. */
.ranking--noted .ranking__row { grid-template-columns: 24px 20px minmax(96px, max-content) minmax(48px, 2fr) 88px minmax(0, 1fr); }
.ranking__note { font-size: var(--fs-12); color: var(--text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 480px) { .ranking--noted .ranking__row { grid-template-columns: 18px 18px minmax(72px, 1fr) minmax(48px, 1.2fr) auto; } .ranking__note { display: none; } }
@media (max-width: 480px) { .ranking__row { grid-template-columns: 18px 18px minmax(72px, 1fr) minmax(48px, 1.2fr) auto; gap: 6px; } }

/* =========================================================================
   Tooltip: one layout for every chart. Value leads, label follows.
   ========================================================================= */
.tooltip {
  position: absolute; z-index: var(--z-tooltip); pointer-events: none; min-width: 188px; max-width: 300px;
  padding: var(--sp-2) var(--sp-3); background: var(--surface); color: var(--text-1);
  border-radius: var(--radius-control); box-shadow: var(--shadow-2);
  font: 400 var(--fs-14) / var(--lh-14) var(--font-ui);
}
.tooltip--static { position: static; pointer-events: auto; display: inline-block; }
.tooltip__text { margin: 0; max-width: 36ch; color: var(--text-1); text-transform: none; letter-spacing: 0; font-weight: 400; }
/* Explanation on demand: a small i beside a label; hover, focus or tap opens the text as a tooltip. */
.info { display: inline-grid; place-items: center; width: 22px; height: 22px; margin-left: 2px; padding: 0; vertical-align: middle; color: var(--text-3); background: none; border: 0; border-radius: 50%; cursor: help; }
.info:hover, .info[aria-expanded="true"] { color: var(--text-1); background: var(--surface-2); }
.info .icon { width: 15px; height: 15px; }
.tooltip__head { font-weight: 600; margin-bottom: var(--sp-1); }
.tooltip__question { margin-bottom: var(--sp-2); }
.tooltip__frac { display: inline-grid; justify-items: center; margin: 0 0 var(--sp-2); padding: var(--sp-1) var(--sp-2); border-radius: 2px; background: color-mix(in oklab, var(--text-1) 6%, transparent); font-weight: 500; }
.tooltip__frac-top { padding: 0 var(--sp-1) 2px; }
.tooltip__frac-bottom { padding: 2px var(--sp-1) 0; border-top: 1.5px solid currentColor; justify-self: stretch; text-align: center; }
.tooltip__bands { display: grid; grid-template-columns: auto auto 1fr; align-items: center; gap: 4px var(--sp-2); font-variant-numeric: tabular-nums; }
.tooltip__band-points { text-align: right; }
.tooltip__band-label { color: var(--text-2); }
.tooltip__note { margin-top: var(--sp-2); color: var(--text-2); font-size: var(--fs-12); line-height: var(--lh-12); }
.tooltip__row { display: grid; grid-template-columns: 14px auto 1fr; align-items: center; gap: var(--sp-2); }
.tooltip__key { width: 14px; height: 2px; background: var(--key); }
.tooltip__key--dash { background: repeating-linear-gradient(90deg, var(--key) 0 4px, transparent 4px 7px); }
.tooltip__value { font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.tooltip__label { color: var(--text-2); }
.tooltip__foot { margin-top: var(--sp-1); padding-top: var(--sp-1); border-top: var(--hairline); color: var(--text-2); font-size: var(--fs-12); line-height: var(--lh-12); }

/* =========================================================================
   Data table: sortable, sticky head on an ink rule, hairline rows,
   in-cell bar for the sorted column
   ========================================================================= */
.data-table-wrap { container-type: inline-size; display: grid; gap: var(--sp-3); }
.data-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-14); line-height: var(--lh-14); }
.data-table caption { text-align: left; }
.data-table th {
  position: sticky; top: var(--sticky-top, var(--header-h)); z-index: 1; background: var(--bg);
  padding: var(--sp-2) var(--sp-3) var(--sp-2); text-align: right; vertical-align: bottom;
  border-bottom: 1px solid var(--text-1); font: 500 var(--fs-12) / var(--lh-12) var(--font-ui); letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-2); white-space: nowrap;
}
.data-table th:nth-child(-n+2), .data-table td:nth-child(-n+2) { text-align: left; }
.data-table th[aria-sort] { color: var(--text-1); }
.data-table .sort { all: unset; cursor: pointer; display: inline-grid; justify-items: inherit; gap: 2px; min-height: 36px; align-content: end; }
.data-table .sort:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.data-table .sort__label { display: inline-flex; align-items: center; gap: 2px; }
.data-table .sort__label .icon { width: 14px; height: 14px; color: var(--accent); }
.data-table .sort__unit { font-size: var(--fs-12); line-height: var(--lh-12); letter-spacing: 0; text-transform: none; color: var(--text-3); }
.data-table td { height: 40px; padding: 0 var(--sp-3); border-bottom: var(--hairline); text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.data-table tbody tr { transition: background-color var(--dur-hover) var(--ease); }
.data-table tbody tr:hover, .data-table tbody tr.is-hover { background: var(--surface-2); }
.data-table tbody tr.is-highlight td { font-weight: 600; }
.data-table tbody tr.is-highlight td:first-child { box-shadow: inset 2px 0 0 var(--accent); }
.data-table .pos { width: 36px; font-size: var(--fs-12); color: var(--text-3); }
.data-table .club-cell { display: inline-flex; align-items: center; gap: var(--sp-2); }
.data-table .club-cell img { width: 20px; height: 20px; object-fit: contain; }
.data-table .neg { color: var(--negative); }
.cell-bar { display: inline-block; position: relative; width: 56px; height: 6px; margin-right: var(--sp-3); vertical-align: middle; }
.cell-bar > span { position: absolute; top: 0; bottom: 0; background: var(--accent); }
.cell-bar--diverging::before { content: ""; position: absolute; left: 50%; top: -3px; bottom: -3px; width: 1px; background: var(--axis); }
.data-table__picker { display: none; }
@container (max-width: 720px) {
  .data-table .metric:not(.is-sorted) { display: none; }
  .data-table th, .data-table td { padding-inline: var(--sp-2); }
  /* minmax(0, 1fr): a select is as wide as its longest option and would otherwise widen the page. */
  .data-table__picker { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; font-size: var(--fs-12); color: var(--text-3); }
}

/* =========================================================================
   Notice: data gap, method note, error with action. A rule, not a box.
   ========================================================================= */
.notice {
  display: grid; grid-template-columns: 18px 1fr; gap: var(--sp-1) var(--sp-3); align-items: start;
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-4); border-left: 2px solid var(--text-3);
  font-size: var(--fs-14); line-height: var(--lh-14);
}
.notice .icon { width: 18px; height: 18px; margin-top: 1px; color: var(--text-2); }
.notice__title { font-weight: 600; }
.notice__body { grid-column: 2; color: var(--text-2); }
.notice__actions { grid-column: 2; display: flex; gap: var(--sp-2); margin-top: var(--sp-2); }
.notice--gap { border-left-color: var(--warning); }
.notice--gap .icon { color: var(--warning); }
.notice--error { border-left-color: var(--negative); }
.notice--error .icon { color: var(--negative); }

/* Empty state: says what's missing and offers the next step. No illustration. */
.empty { display: grid; justify-items: start; gap: var(--sp-2); padding: var(--sp-5) 0; border-top: var(--rule); border-bottom: var(--hairline); }
.empty__title { font-family: var(--font-display); font-size: calc(var(--fs-22) * var(--display-scale)); line-height: var(--lh-22); }
.empty__body { color: var(--text-2); max-width: 46ch; }

/* Skeleton: tile shapes, opacity only, no shimmer sweep */
.skeleton { display: block; background: var(--surface-2); animation: pulse 1.2s var(--ease) infinite alternate; }
.skeleton--text { height: 12px; }
.skeleton--value { height: 40px; width: 70%; }
@media (prefers-reduced-motion: reduce) {
  .skeleton, .chart-frame.is-loading .chart-frame__body, .btn[aria-busy="true"]::after { animation-name: pulse !important; }
  .chart__fade { animation-name: fade !important; }
}

/* =========================================================================
   Footer: Oxford rule, source, method
   ========================================================================= */
.site-footer { position: relative; margin-top: var(--sp-8); border-top: 1px solid var(--text-1); }
.site-footer::before { content: ""; position: absolute; left: 0; right: 0; top: 3px; height: 2px; background: var(--text-1); }
.site-footer__inner { display: grid; gap: var(--sp-2); padding-block: var(--sp-6) var(--sp-7); font-size: var(--fs-12); line-height: var(--lh-12); color: var(--text-3); }
.site-footer__inner p { max-width: var(--text-max); }
.site-footer a { color: var(--text-2); }

@keyframes pulse { from { opacity: 1; } to { opacity: 0.55; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes grow-x { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---------- Bump, waterfall, strip ---------- */
.chart__series { transition: opacity var(--dur-hover) var(--ease); }
.chart__svg--bump.has-active .chart__series:not(.is-active) { opacity: 0.35; }
.chart__svg--bump:not(.has-active) .chart__series:not(.is-on) .chart__bump { stroke: var(--mark-muted); }
.chart__bump { fill: none; stroke: var(--mark-muted); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; transition: stroke var(--dur-hover) var(--ease); }
.chart__series.is-on .chart__bump, .chart__series.is-active .chart__bump { stroke: var(--accent); }
.chart__bump--prov { stroke-dasharray: 1 5; stroke-linecap: round; }
.chart__bump-dot { fill: var(--mark-muted); stroke: var(--bg); stroke-width: 2; transition: fill var(--dur-hover) var(--ease); }
.chart__series.is-on .chart__bump-dot, .chart__series.is-active .chart__bump-dot { fill: var(--accent); }
.chart__bump-dot--prov, .chart__series.is-on .chart__bump-dot--prov, .chart__series.is-active .chart__bump-dot--prov { fill: var(--bg); stroke: var(--text-2); }
.chart__series.is-on .chart__bump-dot--prov, .chart__series.is-active .chart__bump-dot--prov { stroke: var(--accent); }
.chart__series.is-on .chart__end, .chart__series.is-active .chart__end { font-weight: 600; }
.chart__rank { font: 400 var(--fs-12) var(--font-ui); fill: var(--text-3); font-variant-numeric: tabular-nums; }
.chart__hit { fill: none; stroke: transparent; stroke-width: 14; cursor: pointer; }
.chart__wf--total { fill: var(--text-1); }
.chart__wf--up { fill: var(--positive); }
.chart__wf--down { fill: var(--negative); }
.chart__wf-label { font: 400 var(--fs-14) var(--font-ui); fill: var(--text-2); }
.chart__wf-label--total { font-weight: 600; fill: var(--text-1); }
.chart__wf-value { font: 400 var(--fs-12) var(--font-ui); fill: var(--text-2); font-variant-numeric: tabular-nums; }
.chart__wf-connector { stroke: var(--axis); stroke-width: 1; shape-rendering: crispEdges; }
.chart__strip-base { stroke: var(--axis); stroke-width: 1; shape-rendering: crispEdges; }
/* A focused series (cfg.focus): the others fade, its line thickens. */
.chart__svg[data-focus] [data-series]:not(.is-lit) { opacity: 0.16; transition: opacity 0.15s; }
.chart__svg[data-focus] .chart__bar:not(.is-lit), .chart__svg[data-focus] .chart__bar-logo:not(.is-lit) { opacity: 0.22; }
.chart__svg[data-focus] .chart__line.is-lit { stroke-width: 3.5; }
.chart__row-band { fill: color-mix(in oklab, var(--text-1) 3%, transparent); }
.chart__row-hover { fill: color-mix(in oklab, var(--accent) 8%, transparent); }
.chart__row-link .chart__end { fill: var(--text-1); }
.chart__row-link:hover .chart__end, .chart__row-link:focus-visible .chart__end { fill: var(--accent-strong); text-decoration: underline; }
.chart__more { margin-top: var(--sp-2); }
.chart__flow { stroke: var(--panel); stroke-width: 1.5; fill-opacity: 0.88; }
.chart__flow--open { fill: var(--panel); stroke-width: 1.5; }
.chart__flow.is-on { stroke: var(--text-1); stroke-width: 2; fill-opacity: 1; }
.chart__strip-dot { fill: var(--mark-muted); stroke: var(--bg); stroke-width: 2; }
.chart__strip-dot--on { fill: var(--accent); }
.chart__strip-dot--hover { fill: var(--text-1); }
/* While the next page is on its way (view transition), the ball rolls along the track; a quick page shows nothing. */
:root[data-loading] .wordmark__ball { animation: mark-roll 700ms var(--ease) 150ms infinite; }
:root[data-loading] .wordmark__light { animation: mark-slide 700ms var(--ease) 150ms infinite; }
@media (prefers-reduced-motion: reduce) { :root[data-loading] .wordmark__ball, :root[data-loading] .wordmark__light { animation: none; } }
